|
|
@@ -1,6 +1,7 @@
|
|
|
package cn.reghao.devops.mgr.ops.builder.tool;
|
|
|
|
|
|
import cn.reghao.devops.common.docker.DockerManager;
|
|
|
+import cn.reghao.devops.mgr.config.AppProperties;
|
|
|
import cn.reghao.devops.mgr.ops.build.model.po.CompilerBind;
|
|
|
import cn.reghao.devops.mgr.ops.builder.model.vo.KeyValue;
|
|
|
import cn.reghao.devops.mgr.ops.builder.service.PipelineContext;
|
|
|
@@ -12,10 +13,10 @@ import com.github.dockerjava.api.command.PullImageResultCallback;
|
|
|
import com.github.dockerjava.api.command.WaitContainerResultCallback;
|
|
|
import com.github.dockerjava.api.exception.NotFoundException;
|
|
|
import com.github.dockerjava.api.model.*;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
|
-import java.io.BufferedReader;
|
|
|
-import java.io.File;
|
|
|
-import java.io.InputStreamReader;
|
|
|
+import java.io.*;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Collections;
|
|
|
@@ -26,14 +27,25 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
* @author reghao
|
|
|
* @date 2026-02-26 13:21:42
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
public class DockerBuild {
|
|
|
private final DockerClient dockerClient;
|
|
|
+ private final AppProperties appProperties;
|
|
|
|
|
|
- public DockerBuild() {
|
|
|
+ public DockerBuild(AppProperties appProperties) {
|
|
|
this.dockerClient = DockerManager.getDocker().getDockerClient();
|
|
|
+ this.appProperties = appProperties;
|
|
|
}
|
|
|
|
|
|
- public void build(PipelineContext ctx, String repoTag, String sourceCodeDir, List<String> buildArgs) {
|
|
|
+ /**
|
|
|
+ * 采用 docker build 方式编译源码
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ * @date 2026-03-26 14:19:52
|
|
|
+ */
|
|
|
+ public void dockerBuildCompile(PipelineContext ctx, String repoTag, String sourceCodeDir, List<String> buildArgs) {
|
|
|
// 使用一个原子布尔值或自定义标记来记录回调中的失败
|
|
|
AtomicBoolean isFailed = new AtomicBoolean(false);
|
|
|
StringBuilder errorMsg = new StringBuilder();
|
|
|
@@ -104,25 +116,36 @@ public class DockerBuild {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void build(PipelineContext ctx, String repoTag, String sourceCodeDir,
|
|
|
- String image, String compileCmd, List<CompilerBind> compilerBinds, List<String> envs) {
|
|
|
+ /**
|
|
|
+ * 采用 docker run 方式编译源码
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ * @date 2026-03-26 14:20:15
|
|
|
+ */
|
|
|
+ public void dockerRunCompile(PipelineContext ctx, String sourceCodeDir, String compilerImage, String compileCmd,
|
|
|
+ List<CompilerBind> compilerBinds, List<String> compilerEnvs) {
|
|
|
+ if (appProperties.getHostRoot() != null && !appProperties.match()) {
|
|
|
+ sourceCodeDir = getHostPath(sourceCodeDir);
|
|
|
+ }
|
|
|
+
|
|
|
try {
|
|
|
// 1. 尝试查看镜像信息
|
|
|
- dockerClient.inspectImageCmd(image).exec();
|
|
|
+ dockerClient.inspectImageCmd(compilerImage).exec();
|
|
|
} catch (NotFoundException e) {
|
|
|
// 2. 如果镜像不存在,执行拉取
|
|
|
- ctx.log("镜像 " + image + " 不存在,正在从仓库拉取...");
|
|
|
+ ctx.log("镜像 " + compilerImage + " 不存在,正在从仓库拉取...");
|
|
|
try {
|
|
|
- dockerClient.pullImageCmd(image)
|
|
|
+ dockerClient.pullImageCmd(compilerImage)
|
|
|
.exec(new PullImageResultCallback())
|
|
|
.awaitCompletion(); // 这是一个阻塞操作,确保拉取完成后再继续
|
|
|
- ctx.log("镜像 " + image + " 拉取完成");
|
|
|
+ ctx.log("镜像 " + compilerImage + " 拉取完成");
|
|
|
} catch (InterruptedException ex) {
|
|
|
throw new RuntimeException(ex);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 这里的 workDir 会在 docker build 使用的 Dockerfile 中被引用
|
|
|
+ // TODO 这里的 workDir 会在 docker build 使用的 Dockerfile 中被引用
|
|
|
String workDir = "/app";
|
|
|
List<Bind> bindList = new ArrayList<>();
|
|
|
bindList.add(new Bind(sourceCodeDir, new Volume(workDir)));
|
|
|
@@ -131,9 +154,9 @@ public class DockerBuild {
|
|
|
});
|
|
|
|
|
|
String user = getCurrentUserMapping();
|
|
|
- CreateContainerResponse container = dockerClient.createContainerCmd(image)
|
|
|
+ CreateContainerResponse container = dockerClient.createContainerCmd(compilerImage)
|
|
|
.withUser(user)
|
|
|
- .withEnv(envs.toArray(new String[0]))
|
|
|
+ .withEnv(compilerEnvs.toArray(new String[0]))
|
|
|
.withHostConfig(HostConfig.newHostConfig()
|
|
|
.withCpuQuota(100000L)
|
|
|
.withCpuPeriod(100000L)
|
|
|
@@ -148,6 +171,20 @@ public class DockerBuild {
|
|
|
//pack(ctx, sourceCodeDir, repoTag);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * opsRoot 容器目录 /opt/data/devops_data0
|
|
|
+ * hostRoot 主机目录 /opt/data/devops_data1
|
|
|
+ * 将容器目录转化为主机目录, ops-mgr 运行在容器中, 并采用 docker build 或 docker run 编译源码时需要转换目录
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ * @date 2026-03-26 15:15:38
|
|
|
+ */
|
|
|
+ private String getHostPath(String currentPath) {
|
|
|
+ // 将 /opt/data/devops_data0 前缀转换为 /opt/data/devops_data1
|
|
|
+ return currentPath.replace(appProperties.getOpsRoot(), appProperties.getHostRoot());
|
|
|
+ }
|
|
|
+
|
|
|
private void runContainer(PipelineContext ctx, CreateContainerResponse container) {
|
|
|
// 3. 启动容器
|
|
|
dockerClient.startContainerCmd(container.getId()).exec();
|
|
|
@@ -419,7 +456,7 @@ public class DockerBuild {
|
|
|
}
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
- DockerBuild dockerBuild = new DockerBuild();
|
|
|
+ //DockerBuild dockerBuild = new DockerBuild();
|
|
|
//dockerBuild.executeDockerBuildFlow("");
|
|
|
//dockerBuild.build1();
|
|
|
//dockerBuild.build2();
|