Kaynağa Gözat

删除 netty 实现的 docker 客户端
完成应用状态管理接口

reghao 4 yıl önce
ebeveyn
işleme
00259795e9
21 değiştirilmiş dosya ile 190 ekleme ve 719 silme
  1. 0 6
      common/pom.xml
  2. 15 209
      common/src/main/java/cn/reghao/autodop/common/docker/Docker.java
  3. 0 15
      common/src/main/java/cn/reghao/autodop/common/docker/DockerAuth.java
  4. 0 15
      common/src/main/java/cn/reghao/autodop/common/docker/DockerHeader.java
  5. 46 21
      common/src/main/java/cn/reghao/autodop/common/docker/DockerImpl.java
  6. 0 25
      common/src/main/java/cn/reghao/autodop/common/docker/api/Docker.java
  7. 0 31
      common/src/main/java/cn/reghao/autodop/common/docker/api/DockerApi.java
  8. 0 123
      common/src/main/java/cn/reghao/autodop/common/docker/unixdomain/HttpClient.java
  9. 0 66
      common/src/main/java/cn/reghao/autodop/common/docker/unixdomain/HttpClientHandler.java
  10. 0 90
      common/src/main/java/cn/reghao/autodop/common/docker/unixdomain/UnixSocketClient.java
  11. 0 2
      common/src/main/java/cn/reghao/autodop/common/msg/rpc/dto/app/StatusParam.java
  12. 43 41
      dagent/src/main/java/cn/reghao/autodop/dagent/app/DockerAppServiceImpl.java
  13. 9 9
      dagent/src/main/resources/application-dev.yml
  14. 11 10
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/AppStatusController.java
  15. 2 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/page/StatusPageController.java
  16. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/po/AppRunning.java
  17. 1 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppStatusService.java
  18. 40 22
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/impl/AppStatusServiceImpl.java
  19. 10 12
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/util/buildtool/packer/DockerPack.java
  20. 8 8
      dmaster/src/main/resources/application-dev.yml
  21. 4 4
      dmaster/src/main/resources/templates/app/stat/index.html

+ 0 - 6
common/pom.xml

@@ -24,12 +24,6 @@
             <version>3.2.12</version>
         </dependency>
 
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-all</artifactId>
-            <version>4.1.36.Final</version>
-        </dependency>
-
         <dependency>
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>

+ 15 - 209
common/src/main/java/cn/reghao/autodop/common/docker/Docker.java

@@ -1,219 +1,25 @@
 package cn.reghao.autodop.common.docker;
 
-import cn.reghao.autodop.common.docker.api.DockerApi;
-import cn.reghao.autodop.common.docker.po.*;
+import cn.reghao.autodop.common.docker.DockerException;
+import cn.reghao.autodop.common.docker.po.Config;
 import cn.reghao.autodop.common.docker.po.result.ContainerInfo;
-import cn.reghao.autodop.common.docker.unixdomain.UnixSocketClient;
-import cn.reghao.autodop.common.docker.unixdomain.HttpClient;
-import cn.reghao.autodop.common.util.ExceptionUtil;
-import cn.reghao.jdkutil.serializer.JsonConverter;
-import cn.reghao.jdkutil.security.Base64Util;
-import cn.reghao.autodop.common.util.compression.TarFiles;
-import cn.reghao.jdkutil.security.Md5Util;
-import cn.reghao.jdkutil.text.TextFile;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import io.netty.handler.codec.http.FullHttpResponse;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
+import com.github.dockerjava.api.command.InspectContainerResponse;
 
 /**
  * Docker 客户端
  *
  * @author reghao
- * @date 2020-01-13 14:16:38
+ * @date 2021-10-27 04:17:38
  */
-@Slf4j
-public class Docker implements AutoCloseable {
-    private HttpClient client = new HttpClient(new UnixSocketClient());
-    private TextFile textFile = new TextFile();
-
-    @Override
-    public void close() {
-        client.close();
-    }
-
-    private String checkResponse(FullHttpResponse response) throws DockerException {
-        if (response != null) {
-            int statusCode = response.status().code();
-            String result = response.content().toString(StandardCharsets.UTF_8);
-            if (statusCode >= 400) {
-                throw new DockerException(result);
-            }
-
-            String[] lines = result.split(System.lineSeparator());
-            for (String line : lines) {
-                if (line.contains("error") || line.contains("message")) {
-                    throw new DockerException("Docker 请求错误 -> " + line);
-                }
-            }
-            return result;
-        } else {
-            throw new DockerException("Docker 响应是 NULL");
-        }
-    }
-
-    public String getIdByName(String name) throws DockerException {
-        /*String wrappedName = "/" + name;
-        List<Container> containers = ps(true);
-        for (Container container : containers) {
-            Set<String> names = new HashSet<>(container.getNames());
-            if (names.contains(wrappedName)) {
-                return container.getId();
-            }
-        }*/
-        return null;
-    }
-
-    public void build(String repoTag, String compileHome, String dockerfile) throws Exception {
-        String uri = DockerApi.buildPost + "?t=" + repoTag;
-        if (dockerfile != null) {
-            String dockerfilePath = compileHome + "/Dockerfile1";
-            textFile.write(new File(dockerfilePath), dockerfile);
-            // dockerfile 参数指定的是 Dockerfile 文件在 tar 文件内的相对路径和名字
-            uri += "&dockerfile=Dockerfile1";
-        }
-
-        // Dockerfile 要包含在 tar 文件中
-        // TODO /tmp 目录内文件的删除策略
-        String dstPath = "/tmp/" + Md5Util.md5(compileHome) + ".tar";
-        TarFiles.tar(compileHome, dstPath);
-        File tarFile = new File(dstPath);
-
-        List<DockerHeader> headers = new ArrayList<>();
-        headers.add(new DockerHeader("Content-Type", "application/tar"));
-        headers.add(new DockerHeader("Expect", "100-continue"));
-
-        FullHttpResponse response = client.postFile(uri, headers, tarFile);
-        tarFile.delete();
-        checkResponse(response);
-    }
-
-    public void push(String image) throws DockerException {
-        String uri = DockerApi.pushPost.replace("{}", image);
-
-        DockerAuth auth = new DockerAuth();
-        auth.setUsername("reghao");
-        auth.setPassword("12345678");
-        auth.setEmail("reghaodev@gmail.com");
-        auth.setServeraddress("localhost");
-        String encodeAuth = Base64Util.encode(JsonConverter.objectToJson(auth));
-        List<DockerHeader> headers = new ArrayList<>();
-        headers.add(new DockerHeader("X-Registry-Auth", encodeAuth));
-
-        try {
-            FullHttpResponse response = client.post(uri, headers);
-            checkResponse(response);
-            String result = response.content().toString(StandardCharsets.UTF_8);
-            log.info("docker push 结果: {}", result);
-            // TODO push 完成后查找镜像是否存在
-        } catch (IOException | InterruptedException e) {
-            throw new DockerException(ExceptionUtil.errorMsg(e));
-        }
-    }
-
-    public void pull(String repoTag) throws DockerException, InterruptedException {
-        String params = "?fromImage=" + repoTag;
-        String uri = DockerApi.pullPost + params;
-
-        try {
-            FullHttpResponse response = client.post(uri, null);
-            checkResponse(response);
-        } catch (IOException | InterruptedException e) {
-            throw new DockerException(ExceptionUtil.errorMsg(e));
-        }
-    }
-
-    public String run(String containerName, Config config) throws DockerException {
-        stopAndDelete(containerName);
-        //config.setImage(repoTag);
-        String containerId = create(containerName, config);
-        start(containerId);
-        return containerId;
-    }
-
-    private void stopAndDelete(String containerName) throws DockerException {
-        /*List<Container> containers = ps(true);
-        String name = "/" + containerName;
-        for (Container container : containers) {
-            Set<String> names = new HashSet<>(container.getNames());
-            if (names.contains(name)) {
-                String id = container.getId();
-                // 匹配任意状态与名字相同的容器
-                if ("running".equals(container.getState())) {
-                    stop(id);
-                }
-                rmContainer(id);
-            }
-        }*/
-    }
-
-    private String create(String containerName, Config config) throws DockerException {
-        String uri = DockerApi.createPost + "?name=" + containerName;
-        String json = JsonConverter.objectToJson(config);
-        try {
-            FullHttpResponse response = client.postJson(uri, null, json);
-            if (response != null) {
-                int statusCode = response.status().code();
-                String result = response.content().toString(StandardCharsets.UTF_8);
-                if (statusCode == 201) {
-                    JsonObject jsonObject = new JsonParser().parse(result).getAsJsonObject();
-                    return jsonObject.get("Id").getAsString();
-                } else {
-                    throw new DockerException(result);
-                }
-            }
-        } catch (IOException | InterruptedException e) {
-            throw new DockerException(ExceptionUtil.errorMsg(e));
-        }
-        throw new DockerException("请求 " + uri + " 创建容器失败");
-    }
-
-    public void start(String containerId) throws DockerException {
-        String uri = DockerApi.startPost.replace("{}", containerId);
-        try {
-            FullHttpResponse response = client.post(uri, null);
-            checkResponse(response);
-        } catch (IOException | InterruptedException e) {
-            throw new DockerException(ExceptionUtil.errorMsg(e));
-        }
-    }
-
-    public void restart(String containerId) throws DockerException {
-        String uri = DockerApi.restartPost.replace("{}", containerId);
-        try {
-            FullHttpResponse response = client.post(uri, null);
-            checkResponse(response);
-        } catch (IOException | InterruptedException e) {
-            throw new DockerException(ExceptionUtil.errorMsg(e));
-        }
-    }
-
-    public void stop(String containerId) throws DockerException {
-        String uri = DockerApi.stopPost.replace("{}", containerId);
-        try {
-            FullHttpResponse response = client.post(uri, null);
-            checkResponse(response);
-        } catch (IOException | InterruptedException e) {
-            throw new DockerException(ExceptionUtil.errorMsg(e));
-        }
-    }
-
-    public ContainerInfo inspectContainer(String contianerId) throws DockerException {
-        String uri = DockerApi.inspectContainerGet.replace("{}", contianerId);
-        try {
-            FullHttpResponse response = client.get(uri, null);
-            if (response != null) {
-                String result =  response.content().toString(StandardCharsets.UTF_8);
-                return JsonConverter.jsonToObject(result, ContainerInfo.class);
-            } else {
-                throw new DockerException("请求 " + uri + " 的响应是 NULL");
-            }
-        } catch (IOException | InterruptedException e) {
-            throw new DockerException(ExceptionUtil.errorMsg(e));
-        }
-    }
+public interface Docker {
+    void build(String repoTag, String compileHome, String dockerfileContent) throws DockerException;
+    void push(String image) throws DockerException;
+    void pull(String repoTag) throws DockerException;
+    String getContainerIdByName(String containerName) throws DockerException;
+    void stopAndDelete(String containerName) throws DockerException;
+    String createAndRun(String containerName, Config config) throws DockerException;
+    void start(String containerId);
+    void restart(String containerId);
+    void stop(String containerId);
+    InspectContainerResponse inspectContainer(String containerId);
 }

+ 0 - 15
common/src/main/java/cn/reghao/autodop/common/docker/DockerAuth.java

@@ -1,15 +0,0 @@
-package cn.reghao.autodop.common.docker;
-
-import lombok.Data;
-
-/**
- * @author reghao
- * @date 2020-01-13 22:57:35
- */
-@Data
-public class DockerAuth {
-    private String username;
-    private String password;
-    private String email;
-    private String serveraddress;
-}

+ 0 - 15
common/src/main/java/cn/reghao/autodop/common/docker/DockerHeader.java

@@ -1,15 +0,0 @@
-package cn.reghao.autodop.common.docker;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-
-/**
- * @author reghao
- * @date 2020-01-14 09:10:35
- */
-@Data
-@AllArgsConstructor
-public class DockerHeader {
-    private String name;
-    private String value;
-}

+ 46 - 21
common/src/main/java/cn/reghao/autodop/common/docker/DockerImpl.java

@@ -1,6 +1,5 @@
 package cn.reghao.autodop.common.docker;
 
-import cn.reghao.autodop.common.docker.api.Docker;
 import cn.reghao.autodop.common.docker.po.Config;
 import cn.reghao.autodop.common.util.ExceptionUtil;
 import cn.reghao.jdkutil.text.TextFile;
@@ -54,20 +53,23 @@ public class DockerImpl implements Docker {
         this.dockerClient = DockerClientImpl.getInstance(config, httpClient);
     }
 
+    @Override
     public void build(String repoTag, String compileHome, String dockerfileContent) throws DockerException {
-        String dockerfilePath = compileHome + "/Dockerfile.tmp";
+        File dockerfile = new File(compileHome + "/Dockerfile.tmp");
+        String[] arr = repoTag.split(":");
         try {
-            textFile.write(new File(dockerfilePath), dockerfileContent);
-
+            textFile.write(dockerfile, dockerfileContent);
             dockerClient.buildImageCmd()
-                    .withDockerfilePath(dockerfilePath)
-                    .withTags(Set.of(repoTag.split(":")[1]))
+                    .withDockerfile(dockerfile)
+                    // 格式为 docker.reghao.cn/autodop/dmaster:12345678
+                    .withTags(Set.of(repoTag))
                     .exec(new BuildImageResultCallback()).awaitCompletion();
         } catch (IOException | InterruptedException e) {
             throw new DockerException(ExceptionUtil.errorMsg(e));
         }
     }
 
+    @Override
     public void push(String image) throws DockerException {
         try {
             dockerClient.pushImageCmd(image).exec(new PushImageResultCallback()).awaitCompletion();
@@ -102,6 +104,7 @@ public class DockerImpl implements Docker {
         }).onComplete();*/
     }
 
+    @Override
     public void pull(String image) throws DockerException {
         try {
             dockerClient.pullImageCmd(image).exec(new PullImageResultCallback()).awaitCompletion();
@@ -132,59 +135,81 @@ public class DockerImpl implements Docker {
         }).onComplete();*/
     }
 
+    @Override
     public String getContainerIdByName(String containerName) throws DockerException {
         List<Container> list = dockerClient.listContainersCmd()
+                .withShowAll(true)
                 .withNameFilter(List.of(containerName))
                 .exec();
-        if (list.size() != 1) {
-            String msg = String.format("名字为 %s 的容器不存在", containerName);
+        if (list.size() > 1) {
+            String msg = String.format("有多个名字为 %s 的容器不存在", containerName);
             throw new DockerException(msg);
+        } else if (list.size() == 1) {
+            return list.get(0).getId();
+        } else {
+            return null;
         }
-
-        return list.get(0).getId();
     }
 
+    @Override
     public void stopAndDelete(String containerName) throws DockerException {
         String containerId = getContainerIdByName(containerName);
-        dockerClient.stopContainerCmd(containerId).exec();
-        dockerClient.removeContainerCmd(containerId).exec();
+        if (containerId != null) {
+            dockerClient.stopContainerCmd(containerId).exec();
+            dockerClient.removeContainerCmd(containerId).exec();
+        }
     }
 
+    @Override
     public String createAndRun(String containerName, Config config) throws DockerException {
         stopAndDelete(containerName);
 
         HostConfig hostConfig = HostConfig.newHostConfig()
                 .withNetworkMode("host")
                 .withRestartPolicy(RestartPolicy.onFailureRestart(3));
-
-        CreateContainerResponse response = dockerClient.createContainerCmd(config.getImage())
+        String image = config.getImage();
+        CreateContainerCmd createContainerCmd = dockerClient.createContainerCmd(image)
                 .withName(containerName)
-                .withHostConfig(hostConfig)
-                .withEnv(config.getEnv())
-                .exec();
+                .withHostConfig(hostConfig);
+
+        List<String> env = config.getEnv();
+        if (env != null) {
+            createContainerCmd.withEnv(env);
+        }
 
+        CreateContainerResponse response = createContainerCmd.exec();
         String containerId1 = response.getId();
         dockerClient.startContainerCmd(containerId1).exec();
         return containerId1;
     }
 
+    @Override
     public InspectContainerResponse inspectContainer(String containerId) {
         return dockerClient.inspectContainerCmd(containerId).exec();
     }
 
+    @Override
     public void restart(String containerId) {
-        dockerClient.stopContainerCmd(containerId).exec();
+        dockerClient.restartContainerCmd(containerId).exec();
     }
 
+    @Override
     public void stop(String containerId) {
-        dockerClient.startContainerCmd(containerId).exec();
+        dockerClient.stopContainerCmd(containerId).exec();
     }
 
+    @Override
     public void start(String containerId) {
-        dockerClient.restartContainerCmd(containerId).exec();
+        dockerClient.startContainerCmd(containerId).exec();
     }
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws DockerException {
         Docker docker = new DockerImpl();
+        String appId = "dnkt-dev";
+        String containerId = docker.getContainerIdByName(appId);
+        if (containerId != null) {
+            InspectContainerResponse containerInfo = docker.inspectContainer(containerId);
+            System.out.println();
+        }
     }
 }

+ 0 - 25
common/src/main/java/cn/reghao/autodop/common/docker/api/Docker.java

@@ -1,25 +0,0 @@
-package cn.reghao.autodop.common.docker.api;
-
-import cn.reghao.autodop.common.docker.DockerException;
-import cn.reghao.autodop.common.docker.po.Config;
-import cn.reghao.autodop.common.docker.po.result.ContainerInfo;
-import com.github.dockerjava.api.command.InspectContainerResponse;
-
-/**
- * Docker 客户端
- *
- * @author reghao
- * @date 2021-10-27 04:17:38
- */
-public interface Docker {
-    void build(String repoTag, String compileHome, String dockerfileContent) throws DockerException;
-    void push(String image) throws DockerException;
-    void pull(String repoTag) throws DockerException;
-    String getContainerIdByName(String containerName) throws DockerException;
-    void stopAndDelete(String containerName) throws DockerException;
-    String createAndRun(String containerName, Config config) throws DockerException;
-    void start(String containerId);
-    void restart(String containerId);
-    void stop(String containerId);
-    InspectContainerResponse inspectContainer(String containerId);
-}

+ 0 - 31
common/src/main/java/cn/reghao/autodop/common/docker/api/DockerApi.java

@@ -1,31 +0,0 @@
-package cn.reghao.autodop.common.docker.api;
-
-/**
- * Docker v1.40
- * https://docs.docker.com/engine/api/v1.40/
- *
- * @author reghao
- * @date 2020-01-13 15:59:16
- */
-public class DockerApi {
-    private static final String version = "/v1.40";
-
-    // image
-    public static final String buildPost = version + "/build";
-    public static final String tagPost = version + "/images/{}/tag";
-    public static final String pushPost = version + "/images/{}/push";
-    public static final String pullPost = version + "/images/create";
-    public static final String inspectImageGet = version + "/images/{}/json";
-    public static final String searchImageGet = version + "/images/json";
-    public static final String rmImageDelete = version + "/images/{}";
-
-    // container
-    public static final String createPost = version + "/containers/create";
-    public static final String logsGet = version + "/containers/{}/logs";
-    public static final String startPost = version + "/containers/{}/start";
-    public static final String stopPost = version + "/containers/{}/stop";
-    public static final String restartPost = version + "/containers/{}/restart";
-    public static final String rmContainerDelete = version + "/containers/{}";
-    public static final String psGet = version + "/containers/json";
-    public static final String inspectContainerGet = version + "/containers/{}/json";
-}

+ 0 - 123
common/src/main/java/cn/reghao/autodop/common/docker/unixdomain/HttpClient.java

@@ -1,123 +0,0 @@
-package cn.reghao.autodop.common.docker.unixdomain;
-
-import cn.reghao.autodop.common.docker.DockerHeader;
-import cn.reghao.autodop.common.util.ExceptionUtil;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.handler.codec.http.*;
-
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-/**
- * @author reghao
- * @date 2020-01-15 10:13:21
- */
-public class HttpClient {
-    private UnixSocketClient unixSocketClient;
-
-    public HttpClient(UnixSocketClient unixSocketClient) {
-        this.unixSocketClient = unixSocketClient;
-    }
-
-    private FullHttpResponse errMsg(Exception e) {
-        FullHttpResponse httpResponse =
-                new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR);
-        ByteBuf errMsg = Unpooled.buffer(10);
-        errMsg.writeBytes(ExceptionUtil.errorMsg(e).getBytes(StandardCharsets.UTF_8));
-        httpResponse.replace(errMsg);
-        return httpResponse;
-    }
-
-    public FullHttpResponse get(String uri, List<DockerHeader> headers) throws IOException, InterruptedException {
-        FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri);
-        request.headers().set(HttpHeaderNames.HOST, "netty");
-        request.headers().set(HttpHeaderNames.ACCEPT, "Accept: */*");
-        if (headers != null) {
-            headers.forEach(header -> {
-                request.headers().set(header.getName(), header.getValue());
-            });
-        }
-
-        return unixSocketClient.syncSend(request);
-    }
-
-    public FullHttpResponse post(String uri, List<DockerHeader> headers) throws IOException, InterruptedException {
-        FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uri);
-        request.headers().set(HttpHeaderNames.HOST, "netty");
-        request.headers().set(HttpHeaderNames.ACCEPT, "Accept: */*");
-        if (headers != null) {
-            headers.forEach(header -> {
-                request.headers().set(header.getName(), header.getValue());
-            });
-        }
-
-        return unixSocketClient.syncSend(request);
-    }
-
-    public FullHttpResponse postJson(String uri, List<DockerHeader> headers, String json) throws IOException, InterruptedException {
-        ByteBuf byteBuf = Unpooled.copiedBuffer(json, StandardCharsets.UTF_8);
-
-        FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uri);
-        request.headers().set(HttpHeaderNames.HOST, "netty");
-        request.headers().set(HttpHeaderNames.ACCEPT, "Accept: */*");
-        request.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json");
-        request.headers().set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());
-        if (headers != null) {
-            headers.forEach(header -> {
-                request.headers().set(header.getName(), header.getValue());
-            });
-        }
-        request.content().clear().writeBytes(byteBuf);
-        return unixSocketClient.syncSend(request);
-    }
-
-    public FullHttpResponse postFile(String uri, List<DockerHeader> headers, File file) throws IOException, InterruptedException {
-        byte[] bytes = transfer(file);
-        long len = bytes.length;
-        ByteBuf content = Unpooled.wrappedBuffer(bytes);
-
-        FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uri, content);
-        request.headers().set(HttpHeaderNames.HOST, "netty");
-        request.headers().set(HttpHeaderNames.ACCEPT, "Accept: */*");
-        request.headers().set(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(len));
-        if (headers != null) {
-            headers.forEach(header -> {
-                request.headers().set(header.getName(), header.getValue());
-            });
-        }
-
-        return unixSocketClient.syncSend(request);
-    }
-
-    private byte[] transfer(File file) throws IOException {
-        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        byte[] buf = new byte[1024];
-        int len;
-        while ((len = in.read(buf)) != -1) {
-            bos.write(buf, 0, len);
-        }
-
-        bos.close();
-        return bos.toByteArray();
-    }
-
-    public FullHttpResponse delete(String uri, List<DockerHeader> headers) throws IOException, InterruptedException {
-        FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.DELETE, uri);
-        request.headers().set(HttpHeaderNames.HOST, "netty");
-        request.headers().set(HttpHeaderNames.ACCEPT, "Accept: */*");
-        if (headers != null) {
-            headers.forEach(header -> {
-                request.headers().set(header.getName(), header.getValue());
-            });
-        }
-
-        return unixSocketClient.syncSend(request);
-    }
-
-    public void close() {
-        unixSocketClient.close();
-    }
-}

+ 0 - 66
common/src/main/java/cn/reghao/autodop/common/docker/unixdomain/HttpClientHandler.java

@@ -1,66 +0,0 @@
-package cn.reghao.autodop.common.docker.unixdomain;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelPromise;
-import io.netty.handler.codec.http.FullHttpRequest;
-import io.netty.handler.codec.http.FullHttpResponse;
-import io.netty.handler.codec.http.HttpResponseStatus;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * @author reghao
- * @date 2020-01-14 22:32:58
- */
-@Slf4j
-public class HttpClientHandler extends ChannelInboundHandlerAdapter {
-    private ChannelHandlerContext context;
-    private ChannelPromise promise;
-    private FullHttpResponse response;
-
-    public ChannelPromise sendRequest(FullHttpRequest request) {
-        int count = 5;
-        // 禁止无限循环
-        while (context == null && count > 0) {
-            try {
-                // 等待 5s 建立 channel,超时则结束
-                Thread.sleep(1_000);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-            count--;
-        }
-
-        if (context == null) {
-            return null;
-        }
-
-        promise = context.newPromise();
-        context.writeAndFlush(request);
-        return promise;
-    }
-
-    public FullHttpResponse response() {
-        return response;
-    }
-
-    @Override
-    public void channelActive(ChannelHandlerContext ctx) throws Exception {
-        context = ctx;
-    }
-
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        if (msg instanceof FullHttpResponse) {
-            response = (FullHttpResponse) msg;
-            int statusCode = response.status().code();
-            // 不返回 1xx 响应
-            if (statusCode >= HttpResponseStatus.OK.code()) {
-                promise.setSuccess();
-            }
-        } else {
-            log.info("Not FullHttpResponse -> {}", msg.getClass());
-            System.out.println(msg.getClass());
-        }
-    }
-}

+ 0 - 90
common/src/main/java/cn/reghao/autodop/common/docker/unixdomain/UnixSocketClient.java

@@ -1,90 +0,0 @@
-package cn.reghao.autodop.common.docker.unixdomain;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.*;
-import io.netty.channel.epoll.EpollDomainSocketChannel;
-import io.netty.channel.epoll.EpollEventLoopGroup;
-import io.netty.channel.unix.DomainSocketAddress;
-import io.netty.channel.unix.UnixChannel;
-import io.netty.handler.codec.http.*;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author reghao
- * @date 2020-01-14 17:14:08
- */
-@Slf4j
-public class UnixSocketClient {
-    // TODO 在配置中指定
-    private final String DEFAULT_UNIX_ENDPOINT = "/run/docker.sock";
-    private EventLoopGroup group;
-    private Bootstrap bootstrap;
-    private DomainSocketAddress unixSock;
-    private Channel channel;
-    private HttpClientHandler clientHandler;
-
-    public UnixSocketClient() {
-        // TODO Unix Domain Socket 只能使用 EpollEventLoopGroup?
-        group = new EpollEventLoopGroup(2);
-        bootstrap = new Bootstrap();
-        unixSock = new DomainSocketAddress(DEFAULT_UNIX_ENDPOINT);
-        clientHandler = new HttpClientHandler();
-        init();
-    }
-
-    private void init() {
-        bootstrap.group(group)
-                .channel(EpollDomainSocketChannel.class)
-                .handler(new ChannelInitializer<UnixChannel>() {
-                    @Override
-                    public void initChannel(UnixChannel ch) throws Exception {
-                        ChannelPipeline pipeline = ch.pipeline();
-                        pipeline.addLast(new HttpClientCodec());
-                        pipeline.addLast(new HttpObjectAggregator(65536*8192));
-                        pipeline.addLast(clientHandler);
-                    }
-                });
-
-        ChannelFuture channelFuture = bootstrap.connect(unixSock);
-        channelFuture.addListener(future -> {
-           if (future.isSuccess()) {
-               log.info("已连接到 Unix Socket");
-               channel = channelFuture.channel();
-           } else {
-               log.error("Unix Socket 连接失败, 检查 " + DEFAULT_UNIX_ENDPOINT + " 是否存在");
-           }
-        });
-
-        // 注册 channel 关闭事件
-        channelFuture.channel().closeFuture().addListener(listener -> close());
-    }
-
-    public void close() {
-        if (channel != null) {
-            channel.close();
-        }
-
-        if (group != null) {
-            group.shutdownGracefully();
-        }
-    }
-
-    public FullHttpResponse syncSend(FullHttpRequest request) throws InterruptedException, IOException {
-        /*
-        错误用法,忽略了异步的本质
-        if (channel == null) {
-            throw new IOException("Unix Socket 连接失败, 检查 " + DEFAULT_UNIX_ENDPOINT + " 是否存在");
-        }*/
-
-        ChannelPromise promise = clientHandler.sendRequest(request);
-        if (promise == null) {
-            return null;
-        }
-
-        promise.await(30, TimeUnit.SECONDS);
-        return clientHandler.response();
-    }
-}

+ 0 - 2
common/src/main/java/cn/reghao/autodop/common/msg/rpc/dto/app/StatusParam.java

@@ -2,7 +2,6 @@ package cn.reghao.autodop.common.msg.rpc.dto.app;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;
-import lombok.NoArgsConstructor;
 
 import java.io.Serializable;
 
@@ -12,7 +11,6 @@ import java.io.Serializable;
  * @author reghao
  * @date 2020-12-25 19:01:15
  */
-@NoArgsConstructor
 @AllArgsConstructor
 @Data
 public class StatusParam implements Serializable {

+ 43 - 41
dagent/src/main/java/cn/reghao/autodop/dagent/app/DockerAppServiceImpl.java

@@ -1,5 +1,6 @@
 package cn.reghao.autodop.dagent.app;
 
+import cn.reghao.autodop.common.docker.DockerImpl;
 import cn.reghao.autodop.common.machine.Machine;
 import cn.reghao.autodop.common.msg.pub.dto.node.constant.NodeStatus;
 import cn.reghao.autodop.common.msg.rpc.dto.app.StatusResult;
@@ -8,11 +9,10 @@ import cn.reghao.autodop.common.docker.Docker;
 import cn.reghao.autodop.common.docker.DockerException;
 import cn.reghao.autodop.common.docker.po.Config;
 import cn.reghao.autodop.common.docker.po.HostConfig;
-import cn.reghao.autodop.common.docker.po.State;
-import cn.reghao.autodop.common.docker.po.result.ContainerInfo;
 import cn.reghao.autodop.common.util.ExceptionUtil;
 import cn.reghao.jdkutil.converter.DateTimeConverter;
 import cn.reghao.jdkutil.serializer.JsonConverter;
+import com.github.dockerjava.api.command.InspectContainerResponse;
 import org.springframework.stereotype.Service;
 
 /**
@@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
 @Service
 public class DockerAppServiceImpl implements AppService {
     private final long sleep = 10_000;
+    private final Docker docker = new DockerImpl();
 
     @Override
     public StatusResult deploy(DeployParam deployParam) throws DockerException {
@@ -37,87 +38,88 @@ public class DockerAppServiceImpl implements AppService {
             }
         }
 
-        try (Docker docker = new Docker()) {
-            docker.pull(packagePath);
-            String containerId = docker.run(appId, dockerConfig);
+        docker.pull(packagePath);
+        String containerId = docker.createAndRun(appId, dockerConfig);
+        try {
             Thread.sleep(sleep);
-
-            ContainerInfo containerInfo = docker.inspectContainer(containerId);
-            return getAppStatus(appId, containerInfo);
         } catch (InterruptedException e) {
             throw new DockerException(ExceptionUtil.errorMsg(e));
         }
+
+        InspectContainerResponse containerInfo = docker.inspectContainer(containerId);
+        return getAppStatus(appId, containerInfo);
     }
 
-    private StatusResult getAppStatus(String appId, ContainerInfo containerInfo) {
+    private StatusResult getAppStatus(String appId, InspectContainerResponse containerInfo) {
         StatusResult appStatus = new StatusResult();
         appStatus.setMachineId(Machine.ID);
         appStatus.setAppId(appId);
         String image = containerInfo.getConfig().getImage();
-        appStatus.setCommitId(image.split(":")[1]);
+        if (image != null) {
+            appStatus.setCommitId(image.split(":")[1]);
+        } else {
+            appStatus.setCommitId("N/A");
+        }
 
-        State state = containerInfo.getState();
-        boolean isRunning = state.isRunning();
-        if (isRunning) {
+        InspectContainerResponse.ContainerState state = containerInfo.getState();
+        boolean isRunning = state.getRunning() != null ? state.getRunning() : false;
+        String startedAt = state.getStartedAt();
+        if (isRunning && startedAt != null) {
             appStatus.setStatus(NodeStatus.Online.name());
-            appStatus.setStartTime(DateTimeConverter.localDateTime(state.getStartedAt()));
-            appStatus.setPid(state.getPid());
+            appStatus.setStartTime(DateTimeConverter.localDateTime(startedAt));
+            appStatus.setPid(state.getPidLong().intValue());
         } else {
             appStatus.setStatus(NodeStatus.Offline.name());
+            appStatus.setStartTime(null);
             appStatus.setPid(-1);
         }
-
         return appStatus;
     }
 
     @Override
     public StatusResult status(String appId) throws DockerException {
-        try (Docker docker = new Docker()) {
-            String containerId = docker.getIdByName(appId);
-            if (containerId == null) {
-                throw new DockerException("没有和 " + appId + " 应用 ID关联的容器");
-            }
-            ContainerInfo containerInfo = docker.inspectContainer(containerId);
-            return getAppStatus(appId, containerInfo);
+        String containerId = docker.getContainerIdByName(appId);
+        if (containerId == null) {
+            throw new DockerException("没有和 " + appId + " 应用 ID关联的容器");
         }
+        InspectContainerResponse containerInfo = docker.inspectContainer(containerId);
+        return getAppStatus(appId, containerInfo);
     }
 
     @Override
     public StatusResult restart(String appId) throws DockerException {
-        try (Docker docker = new Docker()) {
-            String containerId = docker.getIdByName(appId);
-            docker.restart(containerId);
+        String containerId = docker.getContainerIdByName(appId);
+        docker.restart(containerId);
+        try {
             Thread.sleep(sleep);
-
-            ContainerInfo containerInfo = docker.inspectContainer(containerId);
-            return getAppStatus(appId, containerInfo);
         } catch (InterruptedException e) {
             throw new DockerException(ExceptionUtil.errorMsg(e));
         }
+
+        InspectContainerResponse containerInfo = docker.inspectContainer(containerId);
+        return getAppStatus(appId, containerInfo);
     }
 
     @Override
     public StatusResult stop(String appId) throws DockerException {
-        try (Docker docker = new Docker()) {
-            String containerId = docker.getIdByName(appId);
-            docker.stop(containerId);
+        String containerId = docker.getContainerIdByName(appId);
+        docker.stop(containerId);
 
-            ContainerInfo containerInfo = docker.inspectContainer(containerId);
-            return getAppStatus(appId, containerInfo);
-        }
+        InspectContainerResponse containerInfo = docker.inspectContainer(containerId);
+        return getAppStatus(appId, containerInfo);
     }
 
     @Override
     public StatusResult start(String appId) throws DockerException {
-        try (Docker docker = new Docker()) {
-            String containerId = docker.getIdByName(appId);
-            docker.start(containerId);
+        String containerId = docker.getContainerIdByName(appId);
+        docker.start(containerId);
+        try {
             Thread.sleep(sleep);
-
-            ContainerInfo containerInfo = docker.inspectContainer(containerId);
-            return getAppStatus(appId, containerInfo);
         } catch (InterruptedException e) {
             throw new DockerException(ExceptionUtil.errorMsg(e));
         }
+
+        InspectContainerResponse containerInfo = docker.inspectContainer(containerId);
+        return getAppStatus(appId, containerInfo);
     }
 }

+ 9 - 9
dagent/src/main/resources/application-dev.yml

@@ -1,10 +1,10 @@
-#mosquitto:
-#  broker: tcp://localhost:1883
-#  username: dev
-#  password: Dev@123456
-#  clientId: dagent
 mosquitto:
-  broker: tcp://s75.iquizoo.com:1883
-  username: test
-  password: Test@123456
-  clientId: dagent
+  broker: tcp://localhost:1883
+  username: dev
+  password: Dev@123456
+  clientId: dagent
+#mosquitto:
+#  broker: tcp://s75.iquizoo.com:1883
+#  username: test
+#  password: Test@123456
+#  clientId: dagent

+ 11 - 10
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/AppStatusController.java

@@ -1,5 +1,7 @@
 package cn.reghao.autodop.dmaster.app.controller;
 
+import cn.reghao.jdkutil.result.Result;
+import cn.reghao.jdkutil.result.ResultStatus;
 import cn.reghao.jdkutil.result.WebBody;
 import cn.reghao.autodop.dmaster.app.model.constant.StatusOps;
 import cn.reghao.autodop.dmaster.app.service.AppStatusService;
@@ -8,7 +10,6 @@ import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.eclipse.paho.client.mqttv3.MqttException;
 import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 /**
@@ -28,25 +29,25 @@ public class AppStatusController {
 
     @ApiOperation(value = "重启应用")
     @PostMapping(value = "/restart/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> restart(@PathVariable("appId") String appId,
-                                          @PathVariable("machineId") String machineId) throws MqttException {
+    public String restart(@PathVariable("appId") String appId, @PathVariable("machineId") String machineId)
+            throws MqttException {
         statusService.changeStatus(appId, machineId, StatusOps.restart);
-        return ResponseEntity.ok().body(WebBody.success(appId + " 已重启"));
+        return WebBody.result(Result.result(ResultStatus.SUCCESS, appId + " 正在重启,请 10s 后刷新页面查看最新状态"));
     }
 
     @ApiOperation(value = "停止应用")
     @PostMapping(value = "/stop/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> stop(@PathVariable("appId") String appId,
-                                       @PathVariable("machineId") String machineId) throws MqttException {
+    public String stop(@PathVariable("appId") String appId, @PathVariable("machineId") String machineId)
+            throws MqttException {
         statusService.changeStatus(appId, machineId, StatusOps.stop);
-        return ResponseEntity.ok().body(WebBody.success(appId + " 已停止"));
+        return WebBody.result(Result.result(ResultStatus.SUCCESS, appId + " 正在停止,请稍后刷新页面"));
     }
 
     @ApiOperation(value = "启动应用")
     @PostMapping(value = "/start/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> start(@PathVariable("appId") String appId,
-                                        @PathVariable("machineId") String machineId) throws MqttException {
+    public String start(@PathVariable("appId") String appId, @PathVariable("machineId") String machineId)
+            throws MqttException {
         statusService.changeStatus(appId, machineId, StatusOps.start);
-        return ResponseEntity.ok().body(WebBody.success(appId + " 已启动"));
+        return WebBody.result(Result.result(ResultStatus.SUCCESS, appId + " 正在启动,请 10s 后刷新页面查看最新状态"));
     }
 }

+ 2 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/page/StatusPageController.java

@@ -72,9 +72,8 @@ public class StatusPageController {
     }
 
     @ApiOperation(value = "应用运行日志页面")
-    @GetMapping("/status/applog/{appId}/{machineId}")
-    public String appLogPage(@PathVariable("appId") String appId,
-                             @PathVariable("machineId") String machineId,
+    @GetMapping("/log/{appId}/{machineId}")
+    public String appLogPage(@PathVariable("appId") String appId, @PathVariable("machineId") String machineId,
                              Model model) {
         return "/app/stat/applog";
     }

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/po/AppRunning.java

@@ -34,7 +34,7 @@ public class AppRunning extends BaseEntity<Integer> {
     }
 
     public AppRunning update(StatusResult appStatus) {
-        this.setStatus(NodeStatus.Online.name());
+        this.setStatus(appStatus.getStatus());
         this.setStartTime(appStatus.getStartTime());
         this.setPid(appStatus.getPid());
         this.setLastCheck(LocalDateTime.now());

+ 1 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppStatusService.java

@@ -1,8 +1,6 @@
 package cn.reghao.autodop.dmaster.app.service;
 
 import cn.reghao.autodop.dmaster.app.model.constant.StatusOps;
-import cn.reghao.autodop.dmaster.app.model.po.AppRunning;
-import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
 
 /**
  * 应用状态管理
@@ -12,8 +10,5 @@ import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
  */
 public interface AppStatusService {
     void changeStatus(String appId, String machineId, StatusOps statusOps);
-    void refreshAppStatus();
-    void refreshAppStatus(String appId);
-    void refreshAppStatus(AppRunning appRunning);
-    void getStatus(AppConfig app, String machineId);
+    void getStatus(String appId, String machineId);
 }

+ 40 - 22
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/impl/AppStatusServiceImpl.java

@@ -1,17 +1,19 @@
 package cn.reghao.autodop.dmaster.app.service.impl;
 
 import cn.reghao.autodop.common.mqtt.DefaultMqttClient;
+import cn.reghao.autodop.common.msg.Message;
+import cn.reghao.autodop.common.msg.MsgQueue;
+import cn.reghao.autodop.common.msg.rpc.RpcMsg;
+import cn.reghao.autodop.common.msg.rpc.constant.AppRpcClazz;
+import cn.reghao.autodop.common.msg.rpc.dto.app.StatusParam;
 import cn.reghao.autodop.dmaster.app.db.query.config.AppConfigQuery;
-import cn.reghao.autodop.dmaster.app.db.repository.AppRunningRepository;
 import cn.reghao.autodop.dmaster.app.model.constant.StatusOps;
-import cn.reghao.autodop.dmaster.app.model.po.AppRunning;
 import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
 import cn.reghao.autodop.dmaster.app.service.AppStatusService;
+import cn.reghao.jdkutil.serializer.JsonConverter;
+import org.eclipse.paho.client.mqttv3.MqttException;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * 应用状态管理
  *
@@ -20,45 +22,61 @@ import java.util.List;
  */
 @Service
 public class AppStatusServiceImpl implements AppStatusService {
-    private DefaultMqttClient mqttClient;
-    private AppRunningRepository runningRepository;
-    private AppConfigQuery appConfigQuery;
+    private final DefaultMqttClient mqttClient;
+    private final AppConfigQuery appConfigQuery;
 
-    public AppStatusServiceImpl(DefaultMqttClient mqttClient, AppRunningRepository runningRepository,
-                                AppConfigQuery appConfigQuery) {
+    public AppStatusServiceImpl(DefaultMqttClient mqttClient, AppConfigQuery appConfigQuery) {
         this.mqttClient = mqttClient;
-        this.runningRepository = runningRepository;
         this.appConfigQuery = appConfigQuery;
     }
 
     @Override
     public void changeStatus(String appId, String machineId, StatusOps statusOps) {
-        AppConfig app = appConfigQuery.findByAppId(appId);
+        AppConfig appConfig = appConfigQuery.findByAppId(appId);
+        String packType = appConfig.getPackerConfig().getType();
+        StatusParam statusParam = new StatusParam(packType, appId);
+        RpcMsg rpcMsg = null;
         switch (statusOps) {
             case restart:
+                rpcMsg = RpcMsg.paramMsg(AppRpcClazz.class.getSimpleName(), AppRpcClazz.restart.name(),
+                        JsonConverter.objectToJson(statusParam));
                 break;
             case stop:
+                rpcMsg = RpcMsg.paramMsg(AppRpcClazz.class.getSimpleName(), AppRpcClazz.stop.name(),
+                        JsonConverter.objectToJson(statusParam));
                 break;
             case start:
+                rpcMsg = RpcMsg.paramMsg(AppRpcClazz.class.getSimpleName(), AppRpcClazz.start.name(),
+                        JsonConverter.objectToJson(statusParam));
                 break;
             default:
                 ;
         }
-    }
-
-    @Override
-    public void refreshAppStatus() {
-    }
 
-    @Override
-    public void refreshAppStatus(String appId) {
+        if (rpcMsg == null) {
+            return;
+        }
+        remoteCall(machineId, rpcMsg);
     }
 
-    @Override
-    public void refreshAppStatus(AppRunning appRunning) {
+    private void remoteCall(String machineId, RpcMsg rpcMsg) {
+        Message message = Message.rpcParamMsg(rpcMsg);
+        // TODO 对于需要返回值的 pub,需要做一个记录,pub 和 sub 一一对应
+        String topic = MsgQueue.dagentTopic(machineId);
+        try {
+            mqttClient.pubWithResult(topic, 1, message);
+        } catch (MqttException e) {
+            e.printStackTrace();
+        }
     }
 
     @Override
-    public void getStatus(AppConfig app, String machineId) {
+    public void getStatus(String appId, String machineId) {
+        AppConfig appConfig = appConfigQuery.findByAppId(appId);
+        String packType = appConfig.getPackerConfig().getType();
+        StatusParam statusParam = new StatusParam(packType, appId);
+        RpcMsg rpcMsg = RpcMsg.paramMsg(AppRpcClazz.class.getSimpleName(), AppRpcClazz.status.name(),
+                JsonConverter.objectToJson(statusParam));
+        remoteCall(machineId, rpcMsg);
     }
 }

+ 10 - 12
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/util/buildtool/packer/DockerPack.java

@@ -1,5 +1,6 @@
 package cn.reghao.autodop.dmaster.app.util.buildtool.packer;
 
+import cn.reghao.autodop.common.docker.DockerImpl;
 import cn.reghao.autodop.common.docker.Docker;
 import cn.reghao.autodop.common.docker.DockerException;
 import cn.reghao.autodop.dmaster.app.model.po.config.build.PackerConfig;
@@ -15,29 +16,26 @@ import lombok.extern.slf4j.Slf4j;
 public class DockerPack implements CodePacker {
     private final String dockerfile;
     private final String targetPath;
+    private final Docker docker;
 
     public DockerPack(PackerConfig packerConfig, String dockerfile) {
         this.dockerfile = dockerfile;
         this.targetPath = packerConfig.getTargetPath();
+        this.docker = new DockerImpl();
     }
 
     @Override
     public String pack(String appId, String commitId, String appCompileHome) throws Exception {
-        try (Docker docker = new Docker()) {
-            String repo = targetPath + "/" + appId;
-            String image = repo + ":" + commitId;
-
-            docker.build(image, appCompileHome, dockerfile);
-            return image;
-        }
+        String repo = targetPath + "/" + appId;
+        String image = repo + ":" + commitId;
+        docker.build(image, appCompileHome, dockerfile);
+        return image;
     }
 
     @Override
     public String push(String localPath) throws DockerException {
-        try (Docker docker = new Docker()) {
-            // TODO push 没有报错,但有时 pull 会提示 image 不存在
-            docker.push(localPath);
-            return localPath;
-        }
+        // TODO push 没有报错,但有时 pull 会提示 image 不存在
+        docker.push(localPath);
+        return localPath;
     }
 }

+ 8 - 8
dmaster/src/main/resources/application-dev.yml

@@ -10,16 +10,16 @@ spring:
       authentication-database: admin
       username: dev
       password: Dev@123456
-#mosquitto:
-#  broker: tcp://localhost:1883
-#  username: dev
-#  password: Dev@123456
-#  clientId: dmaster
 mosquitto:
-  broker: tcp://s75.iquizoo.com:1883
-  username: test
-  password: Test@123456
+  broker: tcp://localhost:1883
+  username: dev
+  password: Dev@123456
   clientId: dmaster
+#mosquitto:
+#  broker: tcp://s75.iquizoo.com:1883
+#  username: test
+#  password: Test@123456
+#  clientId: dmaster
 oss:
   host: http://static.reghao.icu
   key: minioadmin

+ 4 - 4
dmaster/src/main/resources/templates/app/stat/index.html

@@ -44,8 +44,8 @@
                     </th>
                     <th class="sortable" data-field="appName">应用</th>
                     <th class="sortable" data-field="machineIpv4">机器地址</th>
-                    <th class="sortable" data-field="httpPort">HTTP 端口</th>
-                    <th class="sortable" data-field="healthCheck">健康检查地址</th>
+                    <!--<th class="sortable" data-field="httpPort">HTTP 端口</th>
+                    <th class="sortable" data-field="healthCheck">健康检查地址</th>-->
                     <th class="sortable" data-field="packagePath">包路径</th>
                     <th class="sortable" data-field="status">运行状态</th>
                     <th class="sortable" data-field="startTime">启动时间</th>
@@ -63,8 +63,8 @@
                            th:text="${item.appName}" th:attr="data-url=@{'/app/config/app/detail/'+${item.appId}}"></a>
                     </td>
                     <td th:text="${item.machineIpv4}">机器地址</td>
-                    <td th:text="${item.httpPort}">HTTP 端口</td>
-                    <td th:text="${item.healthCheck}">健康检查地址</td>
+                    <!--<td th:text="${item.httpPort}">HTTP 端口</td>
+                    <td th:text="${item.healthCheck}">健康检查地址</td>-->
                     <td th:text="${item.packagePath}">包路径</td>
                     <td class="app-status" th:text="${item.status}">运行状态</td>
                     <td th:text="${item.startTime}">启动时间</td>