Quellcode durchsuchen

添加使用 Docker 镜像编译源码功能

reghao vor 1 Jahr
Ursprung
Commit
2501b31b7a

+ 1 - 0
common/src/main/java/cn/reghao/devops/common/docker/Docker.java

@@ -21,6 +21,7 @@ public interface Docker {
     void pull(String repoTag) throws Exception;
     void stopAndDelete(String containerName) throws Exception;
     InspectContainerResponse createAndRun(String containerName, Config containerConfig) throws Exception;
+    void runAndRm(Config containerConfig) throws Exception;
     InspectContainerResponse start(String containerName);
     InspectContainerResponse stop(String containerName);
     InspectContainerResponse restart(String containerName);

+ 90 - 0
common/src/main/java/cn/reghao/devops/common/docker/DockerImpl.java

@@ -14,7 +14,9 @@ import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
 import com.github.dockerjava.transport.DockerHttpClient;
 import lombok.extern.slf4j.Slf4j;
 
+import java.io.Closeable;
 import java.io.File;
+import java.io.IOException;
 import java.time.Duration;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
@@ -219,6 +221,94 @@ public class DockerImpl implements Docker {
         return dockerClient.inspectContainerCmd(containerId).exec();
     }
 
+    public void runAndRm(cn.reghao.devops.common.docker.model.Config containerConfig) throws Exception {
+        String image = containerConfig.getImage();
+        CreateContainerCmd createContainerCmd = dockerClient.createContainerCmd(image).withCmd("rm");
+
+        List<String> env = containerConfig.getEnv();
+        if (env != null) {
+            createContainerCmd.withEnv(env);
+        }
+
+        HostConfig hostConfig = HostConfig.newHostConfig()
+                .withNetworkMode("host")
+                .withRestartPolicy(RestartPolicy.noRestart());
+        if (containerConfig.getVolumes() != null) {
+            Map<String, String> map = containerConfig.getVolumes().getMap();
+            List<Bind> list = new ArrayList<>();
+            for (Map.Entry<String, String> entry : map.entrySet()) {
+                String key = entry.getKey();
+                String value = entry.getValue();
+                Volume volume2 = new Volume(value);
+                Bind bind = new Bind(key, volume2);
+                list.add(bind);
+            }
+            hostConfig.withBinds(list);
+        }
+
+        if (containerConfig.getCmd() != null) {
+            createContainerCmd.withCmd(containerConfig.getCmd());
+        }
+
+        createContainerCmd.withHostConfig(hostConfig);
+        CreateContainerResponse response = createContainerCmd.exec();
+        String containerId = response.getId();
+        dockerClient.startContainerCmd(containerId).exec();
+
+        List<String> list = new ArrayList<>();
+        LogContainerCmd logContainerCmd = dockerClient.logContainerCmd(containerId);
+        logContainerCmd.withStdOut(true).withStdErr(true).withFollowStream(true);
+        logContainerCmd.exec(new ResultCallback<Frame>() {
+            @Override
+            public void onStart(Closeable closeable) {
+            }
+
+            @Override
+            public void onNext(Frame object) {
+                if (object.getStreamType().equals(StreamType.STDERR)) {
+                    if (list.size() > 100) {
+                        list.clear();
+                    }
+                    list.add(object.toString());
+                }
+            }
+
+            @Override
+            public void onError(Throwable throwable) {
+                log.info(throwable.toString());
+            }
+
+            @Override
+            public void onComplete() {
+            }
+
+            @Override
+            public void close() throws IOException {
+            }
+        });
+
+        dockerClient.waitContainerCmd(containerId).exec(new ResultCallback.Adapter<>())
+                .awaitCompletion(300, TimeUnit.SECONDS);
+
+        InspectContainerResponse response1 = dockerClient.inspectContainerCmd(containerId).exec();
+        InspectContainerResponse.ContainerState state = response1.getState();
+        Long exitCode = state.getExitCodeLong();
+        if (Boolean.TRUE.equals(state.getRunning())) {
+            dockerClient.stopContainerCmd(containerId).exec();
+            dockerClient.removeContainerCmd(containerId).exec();
+            throw new Exception("docker build timeout");
+        } else if (exitCode != null && exitCode == 0) {
+            dockerClient.removeContainerCmd(containerId).exec();
+        } else {
+            dockerClient.removeContainerCmd(containerId).exec();
+            StringBuilder sb = new StringBuilder();
+            list.forEach(line -> {
+                sb.append(line).append(System.lineSeparator());
+            });
+            throw new Exception("docker build failed:\n" + sb.toString());
+        }
+    }
+
     @Override
     public InspectContainerResponse start(String containerName) {
         String containerId = getContainerIdByName(containerName);

+ 2 - 1
common/src/main/java/cn/reghao/devops/common/docker/model/Volumes.java

@@ -2,6 +2,7 @@ package cn.reghao.devops.common.docker.model;
 
 import lombok.Data;
 
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -10,5 +11,5 @@ import java.util.Map;
  */
 @Data
 public class Volumes {
-    private Map<String, String> map;
+    private Map<String, String> map = new HashMap<>();
 }

+ 15 - 4
web/src/main/java/cn/reghao/devops/web/mgr/build/chain/BuildTools.java

@@ -1,17 +1,16 @@
 package cn.reghao.devops.web.mgr.build.chain;
 
+import cn.reghao.devops.common.docker.model.Config;
 import cn.reghao.devops.common.docker.model.DockerAuth;
+import cn.reghao.devops.common.docker.model.Volumes;
 import cn.reghao.devops.web.mgr.build.model.AppDto;
 import cn.reghao.devops.web.mgr.build.model.CompilerDto;
 import cn.reghao.devops.web.mgr.build.model.PackerDto;
 import cn.reghao.devops.web.mgr.build.model.RepoAuth;
 import cn.reghao.devops.web.mgr.build.model.constant.CompileType;
 import cn.reghao.devops.web.mgr.build.model.constant.RepoType;
-import cn.reghao.devops.web.mgr.build.tool.compiler.EmptyCompiler;
-import cn.reghao.devops.web.mgr.build.tool.compiler.MavenCompiler;
-import cn.reghao.devops.web.mgr.build.tool.compiler.ShellCompiler;
+import cn.reghao.devops.web.mgr.build.tool.compiler.*;
 import cn.reghao.devops.common.msg.constant.PackType;
-import cn.reghao.devops.web.mgr.build.tool.compiler.CodeCompiler;
 import cn.reghao.devops.web.mgr.build.tool.packer.CodePacker;
 import cn.reghao.devops.web.mgr.build.tool.packer.DockerPack;
 import cn.reghao.devops.web.mgr.build.tool.packer.ZipPack;
@@ -19,6 +18,7 @@ import cn.reghao.devops.web.mgr.build.tool.repo.CodeUpdater;
 import cn.reghao.devops.web.mgr.build.tool.repo.GitImpl;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -94,6 +94,17 @@ public class BuildTools {
                     codeCompiler = new MavenCompiler(compilerDto.getHomePath());
                     break;
                 case docker:
+                    String compilerImage = compilerDto.getCompilerImage();
+                    String compileCmd = compilerDto.getCompileCmd();
+                    Config config = new Config(compilerImage);
+                    config.setVolumes(new Volumes());
+                    config.setCmd(List.of("sh", "-c", "cd /app && " + compileCmd));
+
+                    String nodeModulesDir = "/home/reghao/Downloads/0/node_modules";
+                    String containerPath = "/app/node_modules";
+                    config.getVolumes().getMap().put(nodeModulesDir, containerPath);
+                    codeCompiler = new DockerCompiler(config);
+                    break;
                 case none:
                     codeCompiler = new EmptyCompiler();
                     break;

+ 1 - 0
web/src/main/java/cn/reghao/devops/web/mgr/build/model/CompilerDto.java

@@ -18,4 +18,5 @@ public class CompilerDto implements Serializable {
     private String name;
     private String homePath;
     private String compileCmd;
+    private String compilerImage;
 }

+ 25 - 0
web/src/main/java/cn/reghao/devops/web/mgr/build/tool/compiler/DockerCompiler.java

@@ -0,0 +1,25 @@
+package cn.reghao.devops.web.mgr.build.tool.compiler;
+
+import cn.reghao.devops.common.docker.Docker;
+import cn.reghao.devops.common.docker.DockerImpl;
+import cn.reghao.devops.common.docker.model.Config;
+
+/**
+ * @author reghao
+ * @date 2024-08-09 09:49:11
+ */
+public class DockerCompiler implements CodeCompiler {
+    private final Docker docker;
+    private final Config config;
+
+    public DockerCompiler(Config config) {
+        this.docker = new DockerImpl();
+        this.config = config;
+    }
+
+    @Override
+    public void compile(String appId, String appCompileHome) throws Exception {
+        config.getVolumes().getMap().put(appCompileHome, "/app");
+        docker.runAndRm(config);
+    }
+}

+ 1 - 1
web/src/main/java/cn/reghao/devops/web/mgr/builds/model/po/CompilerConfig.java

@@ -57,6 +57,6 @@ public class CompilerConfig extends BaseEntity {
     }
 
     public CompilerDto getCompilerDto() {
-        return new CompilerDto(this.type, this.name, this.homePath, this.compileCmd);
+        return new CompilerDto(this.type, this.name, this.homePath, this.compileCmd, this.compilerImage);
     }
 }