|
|
@@ -0,0 +1,92 @@
|
|
|
+package seecoder.devcloud.core.pipeline.handler;
|
|
|
+
|
|
|
+import com.spotify.docker.client.ProgressHandler;
|
|
|
+import com.spotify.docker.client.exceptions.DockerException;
|
|
|
+import com.spotify.docker.client.messages.ProgressMessage;
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+import org.apache.http.HttpStatus;
|
|
|
+import org.eclipse.jgit.api.Git;
|
|
|
+import seecoder.devcloud.api.docker.DockerApi;
|
|
|
+import seecoder.devcloud.api.git.GitApi;
|
|
|
+import seecoder.devcloud.common.util.SpringUtil;
|
|
|
+import seecoder.devcloud.core.pipeline.Context;
|
|
|
+import seecoder.devcloud.core.pipeline.PipelineException;
|
|
|
+import seecoder.devcloud.core.pipeline.template.PipelineTemplateTable;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author PuHong Weng
|
|
|
+ * @date 2021/3/24
|
|
|
+ * @description:
|
|
|
+ */
|
|
|
+public class NodeImageBuildHandler extends AbstractHandler{
|
|
|
+ public final DockerApi dockerApi;
|
|
|
+
|
|
|
+ public final GitApi gitApi;
|
|
|
+
|
|
|
+ public NodeImageBuildHandler() {
|
|
|
+ dockerApi = SpringUtil.getBean(DockerApi.class);
|
|
|
+ gitApi = SpringUtil.getBean(GitApi.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void process(Context context) throws PipelineException {
|
|
|
+ //0. 变量准备
|
|
|
+ String repoUrl = context.getConfigs().get("repoUrl");
|
|
|
+ String branchName = context.getConfigs().getOrDefault("branchName","master");
|
|
|
+ String templateName = context.getTemplateName();
|
|
|
+ String imageName = context.getNamespace() + "-" + context.getProjectName();
|
|
|
+
|
|
|
+ // 1. 有git从git拿到地址仓库
|
|
|
+ Path directory;
|
|
|
+ try {
|
|
|
+ //注:temp文件/目录系统会定时删,实际文件名喂 prefix + 它生成的suffix随机数,所以不会命名冲突
|
|
|
+ directory = Files.createTempDirectory("seecoder-devcloud-");
|
|
|
+ Git git = gitApi.clone(repoUrl, directory.toString());
|
|
|
+ git.checkout().setName(branchName).call();
|
|
|
+ } catch (Exception e) {
|
|
|
+ context.appendErrorResult(PipelineException.GIT_CLONE_ERROR,e);
|
|
|
+ throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE, PipelineException.GIT_CLONE_ERROR,e);
|
|
|
+ }
|
|
|
+ //2. 帮助学生创建dockerfile
|
|
|
+ Path dockerfile = Paths.get(directory.toString(), "Dockerfile");
|
|
|
+ try {
|
|
|
+ PipelineTemplateTable.copyTemplateDockerfile(templateName,dockerfile);
|
|
|
+ } catch (IOException e) {
|
|
|
+ context.appendErrorResult(PipelineException.DOCKERFILE_CREATE_ERROR,e);
|
|
|
+ throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.DOCKERFILE_CREATE_ERROR,e);
|
|
|
+ }
|
|
|
+ //3. 镜像构建
|
|
|
+ String imageTag = String.valueOf(new Date().getTime());
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ try {
|
|
|
+ dockerApi.buildAndPush(directory.toString(), "seecoder-devcloud-" + imageName, imageTag, new ProgressHandler() {
|
|
|
+ @Override
|
|
|
+ public void progress(ProgressMessage message) throws DockerException {
|
|
|
+ String value = message.stream();
|
|
|
+ if (value == null) {
|
|
|
+ value = "";
|
|
|
+ }
|
|
|
+ if (!StringUtils.isEmpty(message.error())) {
|
|
|
+ value += "\n" + message.error();
|
|
|
+ sb.append(value);
|
|
|
+ System.out.println(sb.toString());
|
|
|
+ }
|
|
|
+ context.setResult(context.getResult() + sb.toString());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (Exception e) {
|
|
|
+ context.appendErrorResult(PipelineException.IMAGE_BUILD_ERROR,e);
|
|
|
+ throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE, PipelineException.IMAGE_BUILD_ERROR ,e);
|
|
|
+ }
|
|
|
+ //6. 将镜像名字加入context
|
|
|
+ context.getConfigs().put("imageName", imageName);
|
|
|
+ context.getConfigs().put("imageTag", imageTag);
|
|
|
+ context.appendSuccessResult("镜像构建成功,已推送进仓库");
|
|
|
+ }
|
|
|
+}
|