فهرست منبع

重构应用状态管理接口

reghao 5 سال پیش
والد
کامیت
d34a47d0d5
52فایلهای تغییر یافته به همراه630 افزوده شده و 368 حذف شده
  1. 4 4
      common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/AppStatus.java
  2. 1 0
      common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/deploy/AppDeployArgs.java
  3. 1 0
      common/src/main/java/cn/reghao/autodop/common/deploy/AppStatus.java
  4. 1 0
      common/src/main/java/cn/reghao/autodop/common/deploy/DeployConfig.java
  5. 22 14
      common/src/main/java/cn/reghao/autodop/common/dockerc/Docker.java
  6. 3 3
      common/src/main/java/cn/reghao/autodop/common/dockerc/api/ContainerOps.java
  7. 16 14
      common/src/main/java/cn/reghao/autodop/common/dockerc/api/DockerApi.java
  8. 25 27
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Config.java
  9. 0 17
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Container.java
  10. 0 30
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/ContainerInspect.java
  11. 17 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Health.java
  12. 15 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Healthcheck.java
  13. 5 2
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/HostConfig.java
  14. 3 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Labels.java
  15. 16 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Log.java
  16. 3 2
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/RestartPolicy.java
  17. 8 7
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/State.java
  18. 3 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Volumes.java
  19. 21 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Bridge.java
  20. 32 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Container.java
  21. 47 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/ContainerInfo.java
  22. 19 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Mount.java
  23. 13 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/NetworkSettings.java
  24. 13 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Networks.java
  25. 15 0
      common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Port.java
  26. 13 0
      common/src/main/java/cn/reghao/autodop/common/utils/DatetimeConverter.java
  27. 11 10
      dagent/src/main/java/cn/reghao/autodop/dagent/app/App.java
  28. 5 4
      dagent/src/main/java/cn/reghao/autodop/dagent/app/AppService.java
  29. 14 2
      dagent/src/main/java/cn/reghao/autodop/dagent/app/DockerAppServiceImpl.java
  30. 2 1
      dagent/src/main/java/cn/reghao/autodop/dagent/app/ZipAppServiceImpl.java
  31. 2 2
      dagent/src/main/java/cn/reghao/autodop/dagent/app/deploy/DockerAppStatusServiceImpl.java
  32. 2 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/constant/ConfigOptions.java
  33. 32 53
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/StatusController.java
  34. 3 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/BuildConfigCrudController.java
  35. 6 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/GlobalCrudController.java
  36. 22 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/log/AppStatus.java
  37. 0 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/log/BuildDeployApp.java
  38. 19 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/log/AppStatusRepository.java
  39. 49 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppStatusService.java
  40. 18 12
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/BuildDeployDispatcher.java
  41. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/BuildService.java
  42. 0 69
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/LogManager.java
  43. 0 71
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/StatusManager.java
  44. 0 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/build/AppIntegrate.java
  45. 3 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/build/BuildDirCrudService.java
  46. 57 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/log/AppStatusCrudService.java
  47. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/log/BuildDeployAppCrudService.java
  48. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/orchestarte/AppCrudService.java
  49. 15 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/deploy/AppDeployer.java
  50. 8 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/log/BuildDeployLogConsumer.java
  51. 11 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/log/BuildDeployLogService.java
  52. 32 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/notifier/NotifyService.java

+ 4 - 4
common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/AppStatus.java

@@ -3,16 +3,16 @@ package cn.reghao.autodop.common.dagent.app.api.data;
 import lombok.Data;
 
 /**
+ * 应用运行状态
+ *
  * @author reghao
  * @date 2021-02-22 16:24:08
  */
 @Data
 public class AppStatus {
-    private String packerType;
+    private String machineId;
     private String appId;
     private String commitId;
-    private String host;
-    private String status;
-    private String startedTime;
+    private long startTime;
     private int pid;
 }

+ 1 - 0
common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/deploy/AppDeployArgs.java

@@ -13,6 +13,7 @@ import lombok.Data;
 public class AppDeployArgs {
     private String packerType;
     private String appId;
+    private String commitId;
     private String packagePath;
     private String startHome;
     private String startScript;

+ 1 - 0
common/src/main/java/cn/reghao/autodop/common/deploy/AppStatus.java

@@ -6,6 +6,7 @@ import lombok.Data;
  * @author reghao
  * @date 2020-05-19 20:32:35
  */
+@Deprecated
 @Data
 public class AppStatus {
     private String appId;

+ 1 - 0
common/src/main/java/cn/reghao/autodop/common/deploy/DeployConfig.java

@@ -8,6 +8,7 @@ import lombok.Data;
  * @author reghao
  * @date 2020-01-03 08:43:03
  */
+@Deprecated
 @Data
 public class DeployConfig {
     private String appId;

+ 22 - 14
common/src/main/java/cn/reghao/autodop/common/dockerc/Docker.java

@@ -6,6 +6,8 @@ import cn.reghao.autodop.common.dockerc.api.DockerApi;
 import cn.reghao.autodop.common.dockerc.api.ImageOps;
 import cn.reghao.autodop.common.dockerc.exception.DockerException;
 import cn.reghao.autodop.common.dockerc.pojo.*;
+import cn.reghao.autodop.common.dockerc.pojo.result.Container;
+import cn.reghao.autodop.common.dockerc.pojo.result.ContainerInfo;
 import cn.reghao.autodop.common.dockerc.unixdomain.DockerAuth;
 import cn.reghao.autodop.common.dockerc.unixdomain.DockerHeader;
 import cn.reghao.autodop.common.dockerc.unixdomain.UnixSocketClient;
@@ -72,16 +74,22 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
         }
     }
 
+    /**
+     * 根据容器名字找出容器 ID
+     *
+     * @param
+     * @return
+     * @date 2021-02-25 上午10:31
+     */
     public String getIdByName(String name) throws DockerException {
         String wrappedName = "/" + name;
-        // 列出处于所有状态的容器
         List<Container> containers = ps(true);
         for (Container container : containers) {
-            if (container.getNames()[0].equals(wrappedName)) {
+            Set<String> names = new HashSet<>(container.getNames());
+            if (names.contains(wrappedName)) {
                 return container.getId();
             }
         }
-
         return null;
     }
 
@@ -192,7 +200,7 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
         String uri = DockerApi.createPost + "?name=" + name;
 
         RestartPolicy restartPolicy = new RestartPolicy("on-failure", 5);
-        HostConfig hostConfig = new HostConfig(restartPolicy, "host");
+        HostConfig hostConfig = new HostConfig("host", restartPolicy);
 
         Config config = new Config(image, hostConfig);
         String tmp = JsonConverter.objectToJson(config);
@@ -241,10 +249,10 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
                     throw new DockerException(result);
                 }
             }
-            return null;
         } catch (IOException | InterruptedException e) {
             throw new DockerException(ExceptionUtil.errorMsg(e));
         }
+        throw new DockerException("请求 " + uri + " 创建容器失败...");
     }
 
     @Override
@@ -260,9 +268,7 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
     public String run(String containerName, String repoTag, Config config) throws DockerException {
         stopAndDelete(containerName);
         String containerId = create(containerName, repoTag, config);
-        if (containerId != null) {
-            start(containerId);
-        }
+        start(containerId);
         return containerId;
     }
 
@@ -334,7 +340,8 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
         List<Container> containers = ps(true);
         String name = "/" + containerName;
         for (Container container : containers) {
-            if (container.getNames()[0].equals(name)) {
+            Set<String> names = new HashSet<>(container.getNames());
+            if (names.contains(name)) {
                 String id = container.getId();
                 // 匹配任意状态与名字相同的容器
                 if ("running".equals(container.getState())) {
@@ -418,13 +425,13 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
     }
 
     @Override
-    public ContainerInspect inspectContainer(String contianerId) throws DockerException {
+    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 (ContainerInspect) JsonConverter.jsonToObject(result, ContainerInspect.class);
+                return (ContainerInfo) JsonConverter.jsonToObject(result, ContainerInfo.class);
             } else {
                 throw new DockerException("请求 " + uri + " 的响应是 NULL...");
             }
@@ -435,14 +442,15 @@ public class Docker implements ImageOps, ContainerOps, AutoCloseable {
 
     @Override
     public String rootfs(String containerId) throws DockerException {
-        ContainerInspect containerInspect = inspectContainer(containerId);;
+        ContainerInfo containerInfo = inspectContainer(containerId);;
         // TODO 可能抛出 null 异常
-        return containerInspect.getGraphDriver().getData().getMergedDir();
+        return containerInfo.getGraphDriver().getData().getMergedDir();
     }
 
     public static void main(String[] args) {
         try (Docker docker = new Docker()) {
-            docker.pull("localhost:5000/iq3x/dnkt-mgr:dfc43519");
+            String id = docker.getIdByName("registry");
+            ContainerInfo containerInfo = docker.inspectContainer(id);
         } catch (DockerException e) {
             e.printStackTrace();
         }

+ 3 - 3
common/src/main/java/cn/reghao/autodop/common/dockerc/api/ContainerOps.java

@@ -1,8 +1,8 @@
 package cn.reghao.autodop.common.dockerc.api;
 
-import cn.reghao.autodop.common.dockerc.pojo.Container;
+import cn.reghao.autodop.common.dockerc.pojo.result.Container;
 import cn.reghao.autodop.common.dockerc.exception.DockerException;
-import cn.reghao.autodop.common.dockerc.pojo.ContainerInspect;
+import cn.reghao.autodop.common.dockerc.pojo.result.ContainerInfo;
 
 import java.util.List;
 
@@ -61,7 +61,7 @@ public interface ContainerOps {
      * @return 容器详细信息
      * @date 2020-01-19 下午1:39
      */
-    ContainerInspect inspectContainer(String containerId) throws DockerException;
+    ContainerInfo inspectContainer(String containerId) throws DockerException;
 
     /**
      * 容器映射到宿主机上的根目录

+ 16 - 14
common/src/main/java/cn/reghao/autodop/common/dockerc/api/DockerApi.java

@@ -8,21 +8,23 @@ package cn.reghao.autodop.common.dockerc.api;
  * @date 2020-01-13 15:59:16
  */
 public class DockerApi {
+    private static final String version = "/v1.40";
+
     // image
-    public static final String buildPost = "/v1.40/build";
-    public static final String tagPost = "/v1.40/images/{}/tag";
-    public static final String pushPost = "/v1.40/images/{}/push";
-    public static final String pullPost = "/v1.40/images/create";
-    public static final String inspectImageGet = "/v1.40/images/{}/json";
-    public static final String rmImageDelete = "/v1.40/images/{}";
+    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 rmImageDelete = version + "/images/{}";
 
     // container
-    public static final String createPost = "/containers/create";
-    public static final String logsGet = "/containers/{}/logs";
-    public static final String startPost = "/containers/{}/start";
-    public static final String stopPost = "/containers/{}/stop";
-    public static final String restartPost = "/containers/{}/restart";
-    public static final String rmContainerDelete = "/containers/{}";
-    public static final String psGet = "/containers/json";
-    public static final String inspectContainerGet = "/v1.40/containers/{}/json";
+    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";
 }

+ 25 - 27
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Config.java

@@ -1,5 +1,6 @@
 package cn.reghao.autodop.common.dockerc.pojo;
 
+import com.google.gson.annotations.SerializedName;
 import lombok.Data;
 
 import java.util.List;
@@ -12,34 +13,31 @@ import java.util.List;
  */
 @Data
 public class Config {
-    private String hostname;
-    private String domainname;
-    private String user;
-    private boolean attachStdin;
-    private boolean attachStdout;
-    private boolean attachStderr;
-    private boolean tty;
-    private boolean openStdin;
-    private boolean stdinOnce;
-    private List<String> env;
-    private List<String> cmd;
-    private String entrypoint;
-    private String image;
-    private Labels labels;
-    private Volumes volumes;
-    private String workingDir;
-    private boolean networkDisabled;
-    private String macAddress;
-    private ExposedPorts exposedPorts;
-    private String stopSignal;
-    private int stopTimeout;
-    private HostConfig hostConfig;
-    private NetworkingConfig networkingConfig;
+    @SerializedName("AttachStderr") private boolean attachStderr;
+    @SerializedName("AttachStdin") private boolean attachStdin;
+    @SerializedName("AttachStdout") private boolean attachStdout;
+    @SerializedName("Cmd") private List<String> cmd;
+    @SerializedName("Domainname") private String domainname;
+    @SerializedName("Env") private List<String> env;
+    @SerializedName("Healthcheck") private Healthcheck healthcheck;
+    @SerializedName("Hostname") private String hostname;
+    @SerializedName("Image") private String image;
+    @SerializedName("Labels") private Labels labels;
+    @SerializedName("MacAddress") private String macAddress;
+    @SerializedName("NetworkDisabled") private boolean networkDisabled;
+    @SerializedName("OpenStdin") private boolean openStdin;
+    @SerializedName("StdinOnce") private boolean stdinOnce;
+    @SerializedName("Tty") private boolean tty;
+    @SerializedName("User") private String user;
+    @SerializedName("Volumes") private Volumes volumes;
+    @SerializedName("WorkingDir") private String workingDir;
+    @SerializedName("StopSignal") private String stopSignal;
+    @SerializedName("StopTimeout") private int stopTimeout;
 
-    public Config(List<String> env, HostConfig hostConfig) {
-        this.env = env;
-        this.hostConfig = hostConfig;
-    }
+    @SerializedName("Entrypoint") private String entrypoint;
+    @SerializedName("ExposedPorts") private ExposedPorts exposedPorts;
+    @SerializedName("HostConfig") private HostConfig hostConfig;
+    @SerializedName("NetworkingConfig") private NetworkingConfig networkingConfig;
 
     public Config(String image, HostConfig hostConfig) {
         this.image = image;

+ 0 - 17
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Container.java

@@ -1,17 +0,0 @@
-package cn.reghao.autodop.common.dockerc.pojo;
-
-import com.google.gson.annotations.SerializedName;
-import lombok.Data;
-
-/**
- * @author reghao
- * @date 2019-12-10 18:30:02
- */
-@Data
-public class Container {
-    @SerializedName("Id") private String id;
-    @SerializedName("Names") private String[] names;
-    @SerializedName("Image") private String image;
-    @SerializedName("ImageID") private String imageId;
-    @SerializedName("State") private String state;
-}

+ 0 - 30
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/ContainerInspect.java

@@ -1,30 +0,0 @@
-package cn.reghao.autodop.common.dockerc.pojo;
-
-import com.google.gson.annotations.SerializedName;
-import lombok.Data;
-
-/**
- * docker inspect 的返回值(部分)
- *
- * @author reghao
- * @date 2019-12-10 18:30:02
- */
-@Data
-public class ContainerInspect {
-    @SerializedName("Id") private String id;
-    @SerializedName("Created") private String created;
-    @SerializedName("Path") private String path;
-    @SerializedName("State") private State state;
-    @SerializedName("Image") private String image;
-    @SerializedName("Name") private String name;
-    @SerializedName("RestartCount") private Long restartCount;
-    @SerializedName("HostConfig") private HostConfig hostConfig;
-    @SerializedName("GraphDriver") private GraphDriver graphDriver;
-    @SerializedName("Config") private Config config;
-
-    @Data
-    static public class Config {
-        @SerializedName("Image") private String image;
-        @SerializedName("StopSignal") private String stopSignal;
-    }
-}

+ 17 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Health.java

@@ -0,0 +1,17 @@
+package cn.reghao.autodop.common.dockerc.pojo;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 10:16:50
+ */
+@Data
+public class Health {
+    @SerializedName("Status") private String status;
+    @SerializedName("FailingStreak") private int failingStreak;
+    @SerializedName("Log") private List<Log> log;
+}

+ 15 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Healthcheck.java

@@ -0,0 +1,15 @@
+package cn.reghao.autodop.common.dockerc.pojo;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 10:02:59
+ */
+@Data
+public class Healthcheck {
+    @SerializedName("Test") private List<String> test;
+}

+ 5 - 2
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/HostConfig.java

@@ -1,15 +1,18 @@
 package cn.reghao.autodop.common.dockerc.pojo;
 
+import com.google.gson.annotations.SerializedName;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 
 /**
+ * TODO 部分
+ *
  * @author reghao
  * @date 2020-01-14 23:16:52
  */
 @AllArgsConstructor
 @Data
 public class HostConfig {
-    private RestartPolicy restartPolicy;
-    private String networkMode;
+    @SerializedName("NetworkMode") private String networkMode;
+    @SerializedName("RestartPolicy") private RestartPolicy restartPolicy;
 }

+ 3 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Labels.java

@@ -2,10 +2,13 @@ package cn.reghao.autodop.common.dockerc.pojo;
 
 import lombok.Data;
 
+import java.util.Map;
+
 /**
  * @author reghao
  * @date 2021-02-10 01:28:38
  */
 @Data
 public class Labels {
+    private Map<String, String> map;
 }

+ 16 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Log.java

@@ -0,0 +1,16 @@
+package cn.reghao.autodop.common.dockerc.pojo;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 10:19:45
+ */
+@Data
+public class Log {
+    @SerializedName("Start") private String start;
+    @SerializedName("End") private String end;
+    @SerializedName("ExitCode") private int exitCode;
+    @SerializedName("Output") private String output;
+}

+ 3 - 2
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/RestartPolicy.java

@@ -1,5 +1,6 @@
 package cn.reghao.autodop.common.dockerc.pojo;
 
+import com.google.gson.annotations.SerializedName;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 
@@ -10,6 +11,6 @@ import lombok.Data;
 @AllArgsConstructor
 @Data
 public class RestartPolicy {
-    private String name;
-    private int maximumRetryCount;
+    @SerializedName("Name") private String name;
+    @SerializedName("MaximumRetryCount") private int maximumRetryCount;
 }

+ 8 - 7
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/State.java

@@ -9,15 +9,16 @@ import lombok.Data;
  */
 @Data
 public class State {
-    @SerializedName("Status") private String status;
-    @SerializedName("Running") private boolean running;
-    @SerializedName("Paused") private boolean paused;
-    @SerializedName("Restarting") private boolean restarting;
+    @SerializedName("Error") private String error;
+    @SerializedName("ExitCode") private int exitCode;
+    @SerializedName("FinishedAt") private String finishedAt;
+    @SerializedName("Health") private Health health;
     @SerializedName("OOMKilled") private boolean oomKilled;
     @SerializedName("Dead") private boolean dead;
+    @SerializedName("Paused") private boolean paused;
     @SerializedName("Pid") private int pid;
-    @SerializedName("ExitCode") private int exitCode;
-    @SerializedName("Error") private String error;
+    @SerializedName("Running") private boolean running;
+    @SerializedName("Restarting") private boolean restarting;
     @SerializedName("StartedAt") private String startedAt;
-    @SerializedName("FinishedAt") private String finishedAt;
+    @SerializedName("Status") private String status;
 }

+ 3 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/Volumes.java

@@ -2,10 +2,13 @@ package cn.reghao.autodop.common.dockerc.pojo;
 
 import lombok.Data;
 
+import java.util.Map;
+
 /**
  * @author reghao
  * @date 2021-02-10 01:29:10
  */
 @Data
 public class Volumes {
+    private Map<String, Object> map;
 }

+ 21 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Bridge.java

@@ -0,0 +1,21 @@
+package cn.reghao.autodop.common.dockerc.pojo.result;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 09:37:50
+ */
+@Data
+public class Bridge {
+    @SerializedName("NetworkID") private String networkId;
+    @SerializedName("EndpointID") private String endpointId;
+    @SerializedName("Gateway") private String gateway;
+    @SerializedName("IPAddress") private String ipAddress;
+    @SerializedName("IPPrefixLen") private String ipPrefixLen;
+    @SerializedName("IPv6Gateway") private String ipv6Gateway;
+    @SerializedName("GlobalIPv6Address") private String globalIpv6Address;
+    @SerializedName("GlobalIPv6PrefixLen") private String globalIpv6PrefixLen;
+    @SerializedName("MacAddress") private String macAddress;
+}

+ 32 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Container.java

@@ -0,0 +1,32 @@
+package cn.reghao.autodop.common.dockerc.pojo.result;
+
+import cn.reghao.autodop.common.dockerc.pojo.*;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * docker ps 返回值
+ *
+ * @author reghao
+ * @date 2019-12-10 18:30:02
+ */
+@Data
+public class Container {
+    @SerializedName("Id") private String id;
+    @SerializedName("Names") private List<String> names;
+    @SerializedName("Image") private String image;
+    @SerializedName("ImageID") private String imageId;
+    @SerializedName("Command") private String command;
+    @SerializedName("Created") private long created;
+    @SerializedName("State") private String state;
+    @SerializedName("Status") private String status;
+    @SerializedName("Ports") private List<Port> ports;
+    @SerializedName("Labels") private Labels labels;
+    @SerializedName("SizeRw") private int sizeRw;
+    @SerializedName("SizeRootFs") private int sizeRootFs;
+    @SerializedName("HostConfig") private HostConfig hostConfig;
+    @SerializedName("NetworkSettings") private NetworkSettings networkSettings;
+    @SerializedName("Mounts") private List<Mount> mounts;
+}

+ 47 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/ContainerInfo.java

@@ -0,0 +1,47 @@
+package cn.reghao.autodop.common.dockerc.pojo.result;
+
+import cn.reghao.autodop.common.dockerc.pojo.GraphDriver;
+import cn.reghao.autodop.common.dockerc.pojo.HostConfig;
+import cn.reghao.autodop.common.dockerc.pojo.State;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * docker inspect 返回值
+ *
+ * @author reghao
+ * @date 2019-12-10 18:30:02
+ */
+@Data
+public class ContainerInfo {
+    @SerializedName("AppArmorProfile") private String appArmorProfile;
+    @SerializedName("Args") private List<String> args;
+    @SerializedName("Config") private Config config;
+    @SerializedName("Created") private String created;
+    @SerializedName("Driver") private String driver;
+    @SerializedName("ExecIDs") private List<String> execIds;
+    @SerializedName("GraphDriver") private GraphDriver graphDriver;
+    @SerializedName("HostConfig") private HostConfig hostConfig;
+    @SerializedName("HostnamePath") private String hostnamePath;
+    @SerializedName("HostsPath") private String hostsPath;
+    @SerializedName("LogPath") private String logPath;
+    @SerializedName("Id") private String id;
+    @SerializedName("Image") private String image;
+    @SerializedName("MountLabel") private String mountLabel;
+    @SerializedName("Name") private String name;
+    @SerializedName("NetworkSettings") private NetworkSettings networkSettings;
+    @SerializedName("Path") private String path;
+    @SerializedName("ProcessLabel") private String processLabel;
+    @SerializedName("ResolvConfPath") private String resolvConfPath;
+    @SerializedName("RestartCount") private int restartCount;
+    @SerializedName("State") private State state;
+    @SerializedName("Mounts") private List<Mount> mounts;
+
+    @Data
+    static public class Config {
+        @SerializedName("Image") private String image;
+        @SerializedName("StopSignal") private String stopSignal;
+    }
+}

+ 19 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Mount.java

@@ -0,0 +1,19 @@
+package cn.reghao.autodop.common.dockerc.pojo.result;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 09:43:58
+ */
+@Data
+public class Mount {
+    @SerializedName("Name") private String name;
+    @SerializedName("Source") private String source;
+    @SerializedName("Destination") private String destination;
+    @SerializedName("Driver") private String driver;
+    @SerializedName("Mode") private String mode;
+    @SerializedName("RW") private boolean rw;
+    @SerializedName("Propagation") private String propagation;
+}

+ 13 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/NetworkSettings.java

@@ -0,0 +1,13 @@
+package cn.reghao.autodop.common.dockerc.pojo.result;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 09:41:50
+ */
+@Data
+public class NetworkSettings {
+    @SerializedName("Networks") private Networks networks;
+}

+ 13 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Networks.java

@@ -0,0 +1,13 @@
+package cn.reghao.autodop.common.dockerc.pojo.result;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 09:41:10
+ */
+@Data
+public class Networks {
+    @SerializedName("bridge") private Bridge bridge;
+}

+ 15 - 0
common/src/main/java/cn/reghao/autodop/common/dockerc/pojo/result/Port.java

@@ -0,0 +1,15 @@
+package cn.reghao.autodop.common.dockerc.pojo.result;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 09:33:19
+ */
+@Data
+public class Port {
+    @SerializedName("PrivatePort") private int privatePort;
+    @SerializedName("PublicPort") private int publicPort;
+    @SerializedName("Type") private String type;
+}

+ 13 - 0
common/src/main/java/cn/reghao/autodop/common/utils/DatetimeConverter.java

@@ -34,6 +34,19 @@ public class DatetimeConverter {
         return format(zonedDateTime.toLocalDateTime());
     }
 
+    /**
+     * 2021-02-23T13:24:51.519422470Z
+     * 将日期时间转换为毫秒级时间戳
+     *
+     * @param
+     * @return
+     * @date 2021-02-25 上午11:00
+     */
+    public static long convertToTimestamp(String dateTime) {
+        Instant instant = Instant.parse(dateTime);
+        return instant.toEpochMilli();
+    }
+
     /**
      * 毫秒时间戳转换为日期时间
      *

+ 11 - 10
dagent/src/main/java/cn/reghao/autodop/dagent/app/App.java

@@ -2,6 +2,7 @@ package cn.reghao.autodop.dagent.app;
 
 import cn.reghao.autodop.common.amqp.RpcResult;
 import cn.reghao.autodop.common.dagent.app.api.data.AppIdArgs;
+import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
 import cn.reghao.autodop.common.dagent.app.api.data.deploy.AppDeployArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.deploy.PackerType;
 import cn.reghao.autodop.common.dagent.app.api.data.log.AppLogArgs;
@@ -28,27 +29,27 @@ public class App {
 
     public RpcResult deploy(String payload) {
         AppDeployArgs appDeployArgs = (AppDeployArgs) JsonConverter.jsonToObject(payload, AppDeployArgs.class);
+        AppStatus appStatus;
         switch (PackerType.valueOf(appDeployArgs.getPackerType())) {
             case docker:
                 try {
-                    dockerAppServiceImpl.deploy(appDeployArgs);
+                    appStatus = dockerAppServiceImpl.deploy(appDeployArgs);
                 } catch (DockerException e) {
                     return RpcResult.fail(ExceptionUtil.errorMsg(e));
                 }
                 break;
             case zip:
-                zipAppServiceImpl.deploy(appDeployArgs);
+                appStatus = zipAppServiceImpl.deploy(appDeployArgs);
                 break;
             default:
                 return RpcResult.error("没有这种打包类型...");
         }
-
-        return RpcResult.success("ok");
+        return RpcResult.success(JsonConverter.objectToJson(appStatus));
     }
 
-    public RpcResult log(String payload) {
-        AppLogArgs appLogArgs = (AppLogArgs) JsonConverter.jsonToObject(payload, AppLogArgs.class);
-        switch (PackerType.valueOf(appLogArgs.getPackerType())) {
+    public RpcResult status(String payload) {
+        AppIdArgs appIdArgs = (AppIdArgs) JsonConverter.jsonToObject(payload, AppIdArgs.class);
+        switch (PackerType.valueOf(appIdArgs.getPackerType())) {
             case docker:
                 break;
             case zip:
@@ -60,9 +61,9 @@ public class App {
         return RpcResult.success("ok");
     }
 
-    public RpcResult status(String payload) {
-        AppIdArgs appIdArgs = (AppIdArgs) JsonConverter.jsonToObject(payload, AppIdArgs.class);
-        switch (PackerType.valueOf(appIdArgs.getPackerType())) {
+    public RpcResult log(String payload) {
+        AppLogArgs appLogArgs = (AppLogArgs) JsonConverter.jsonToObject(payload, AppLogArgs.class);
+        switch (PackerType.valueOf(appLogArgs.getPackerType())) {
             case docker:
                 break;
             case zip:

+ 5 - 4
dagent/src/main/java/cn/reghao/autodop/dagent/app/AppService.java

@@ -12,11 +12,12 @@ import java.util.List;
  * @date 2021-02-22 16:21:28
  */
 public interface AppService {
-    void deploy(AppDeployArgs appDeployArgs) throws DockerException;
-    List<String> log(AppLogArgs appLogArgs);
+    AppStatus deploy(AppDeployArgs appDeployArgs) throws DockerException;
+    @Deprecated
     AppStatus status(String appId);
-    void start(String appId);
-    void stop(String appId);
+    List<String> log(AppLogArgs appLogArgs);
     void restart(String appId);
+    void stop(String appId);
+    void start(String appId);
     void run(String appId, String commitId);
 }

+ 14 - 2
dagent/src/main/java/cn/reghao/autodop/dagent/app/DockerAppServiceImpl.java

@@ -3,9 +3,12 @@ package cn.reghao.autodop.dagent.app;
 import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
 import cn.reghao.autodop.common.dagent.app.api.data.deploy.AppDeployArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.log.AppLogArgs;
+import cn.reghao.autodop.common.dagent.machine.Machine;
 import cn.reghao.autodop.common.dockerc.Docker;
 import cn.reghao.autodop.common.dockerc.exception.DockerException;
 import cn.reghao.autodop.common.dockerc.pojo.Config;
+import cn.reghao.autodop.common.dockerc.pojo.result.ContainerInfo;
+import cn.reghao.autodop.common.utils.DatetimeConverter;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -16,7 +19,7 @@ import java.util.List;
  */
 public class DockerAppServiceImpl implements AppService {
     @Override
-    public void deploy(AppDeployArgs appDeployArgs) throws DockerException {
+    public AppStatus deploy(AppDeployArgs appDeployArgs) throws DockerException {
         try (Docker docker = new Docker()) {
             String repoTag = appDeployArgs.getPackagePath();
             docker.pull(repoTag);
@@ -24,7 +27,16 @@ public class DockerAppServiceImpl implements AppService {
             String appId = appDeployArgs.getAppId();
             String packagePath = appDeployArgs.getPackagePath();
             Config dockerConfig = appDeployArgs.getDockerConfig();
-            docker.run(appId, packagePath, dockerConfig);
+            String containerId = docker.run(appId, packagePath, dockerConfig);
+            ContainerInfo containerInfo = docker.inspectContainer(containerId);
+
+            AppStatus appStatus = new AppStatus();
+            appStatus.setMachineId(Machine.machineId());
+            appStatus.setAppId(appDeployArgs.getAppId());
+            appStatus.setCommitId(appDeployArgs.getCommitId());
+            appStatus.setStartTime(DatetimeConverter.convertToTimestamp(containerInfo.getState().getStartedAt()));
+            appStatus.setPid(containerInfo.getState().getPid());
+            return appStatus;
         }
     }
 

+ 2 - 1
dagent/src/main/java/cn/reghao/autodop/dagent/app/ZipAppServiceImpl.java

@@ -15,8 +15,9 @@ import java.util.List;
 @Slf4j
 public class ZipAppServiceImpl implements AppService {
     @Override
-    public void deploy(AppDeployArgs appDeployArgs) {
+    public AppStatus deploy(AppDeployArgs appDeployArgs) {
         log.info("zip 部署...");
+        return null;
     }
 
     @Override

+ 2 - 2
dagent/src/main/java/cn/reghao/autodop/dagent/app/deploy/DockerAppStatusServiceImpl.java

@@ -3,7 +3,7 @@ package cn.reghao.autodop.dagent.app.deploy;
 import cn.reghao.autodop.common.deploy.AppStatus;
 import cn.reghao.autodop.common.dockerc.Docker;
 import cn.reghao.autodop.common.dockerc.exception.DockerException;
-import cn.reghao.autodop.common.dockerc.pojo.ContainerInspect;
+import cn.reghao.autodop.common.dockerc.pojo.result.ContainerInfo;
 import cn.reghao.autodop.common.dockerc.pojo.State;
 import cn.reghao.autodop.common.utils.DatetimeConverter;
 import lombok.extern.slf4j.Slf4j;
@@ -47,7 +47,7 @@ public class DockerAppStatusServiceImpl implements AppStatusService {
     public AppStatus status(String appId) throws DockerException {
         try (Docker docker = new Docker()) {
             String containerId = docker.getIdByName(appId);
-            ContainerInspect container = docker.inspectContainer(containerId);
+            ContainerInfo container = docker.inspectContainer(containerId);
             State state = container.getState();
             String status = state.getStatus();
             String startedAt = state.getStartedAt();

+ 2 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/constant/ConfigOptions.java

@@ -8,8 +8,8 @@ package cn.reghao.autodop.dmaster.app.constant;
  */
 public enum ConfigOptions {
     app, env,
-    localDir, notifier,
-    repo, compiler, packer,
+    notifier,
+    repo, compiler, packer, buildDir,
     repoAuth,
     proj
 }

+ 32 - 53
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/ManageController.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/StatusController.java

@@ -1,83 +1,42 @@
 package cn.reghao.autodop.dmaster.app.controller;
 
-import cn.reghao.autodop.common.deploy.AppStatus;
 import cn.reghao.autodop.common.dockerc.exception.DockerException;
-import cn.reghao.autodop.dmaster.app.constant.EnvType;
-import cn.reghao.autodop.dmaster.app.service.LogManager;
-import cn.reghao.autodop.dmaster.app.service.StatusManager;
-import cn.reghao.autodop.dmaster.app.vo.LogFile;
-import cn.reghao.autodop.dmaster.common.db.PageList;
+import cn.reghao.autodop.dmaster.app.service.AppStatusService;
 import cn.reghao.autodop.common.result.WebResult;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Sort;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-
 /**
  * @author reghao
  * @date 2020-02-28 11:33:23
  */
 @Slf4j
-@Api(tags = "应用管理接口")
+@Api(tags = "应用状态管理接口")
 @RestController
-@RequestMapping("/api/app/manage")
-public class ManageController {
-    private StatusManager statusManager;
-    private LogManager logManager;
+@RequestMapping("/api/app/status")
+public class StatusController {
+    private AppStatusService statusService;
     
-    public ManageController(StatusManager statusManager, LogManager logManager) {
-        this.statusManager = statusManager;
-        this.logManager = logManager;
-    }
-
-    @ApiOperation(value = "启动应用")
-    @PostMapping("/start/{appId}")
-    public ResponseEntity<String> start(@PathVariable("appId") String appId) throws DockerException {
-        statusManager.start(appId);
-        return ResponseEntity.ok().body("ok");
-    }
-
-    @ApiOperation(value = "停止应用")
-    @PostMapping("/stop/{appId}")
-    public ResponseEntity<String> stop(@PathVariable("appId") String appId) throws DockerException {
-        statusManager.stop(appId);
-        return ResponseEntity.ok().body("ok");
-    }
-
-    @ApiOperation(value = "重启应用")
-    @PostMapping("/restart/{appId}")
-    public ResponseEntity<String> restart(@PathVariable("appId") String appId) throws DockerException {
-        statusManager.restart(appId);
-        return ResponseEntity.ok().body("ok");
+    public StatusController(AppStatusService statusService) {
+        this.statusService = statusService;
     }
 
-    @ApiOperation(value = "获取所有已部署应用的运行状态")
+    @ApiOperation(value = "获取已部署应用的运行状态")
     @GetMapping("/status")
     public ResponseEntity<String> status(@RequestParam("env") String env,
                                          @RequestParam("page") int page,
                                          @RequestParam("size") int size) throws DockerException {
-        String env1 = EnvType.valueOf(env).name();
-        PageRequest pageRequest =
-                PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC, "updateTime"));
-        List<AppStatus> statusList = statusManager.status(env1, pageRequest);
-
-        PageList<AppStatus> pageList = new PageList<>();
-        pageList.setList(statusList);
-        pageList.setTotalSize(statusList.size());
-        return ResponseEntity.ok().body(WebResult.success(pageList));
+        return ResponseEntity.ok().body(WebResult.success("pageList"));
     }
 
     @ApiOperation(value = "获取指定主机上应用的所有日志文件")
     @GetMapping("/logs")
     public ResponseEntity<String> appLogs(@RequestParam("appId") String appId,
                                           @RequestParam("host") String host) throws Exception {
-        List<LogFile> list = logManager.logFiles(appId, host);
-        return ResponseEntity.ok().body(WebResult.success(list));
+        return ResponseEntity.ok().body("WebResult.success(logs)");
     }
 
     @ApiOperation(value = "获取应用日志内容")
@@ -86,7 +45,27 @@ public class ManageController {
                                          @RequestParam("logType") String logType,
                                          @RequestParam("logLevel") String logLevel,
                                          @RequestParam("logName") String logName) throws Exception {
-        List<String> logs = logManager.logContent(appId, logType, logLevel, logName);
-        return ResponseEntity.ok().body(WebResult.success(logs));
+        return ResponseEntity.ok().body("WebResult.success(logs)");
+    }
+
+    @ApiOperation(value = "重启应用")
+    @PostMapping("/restart/{appId}")
+    public ResponseEntity<String> restart(@PathVariable("appId") String appId) throws DockerException {
+        statusService.restart(appId);
+        return ResponseEntity.ok().body("ok");
+    }
+
+    @ApiOperation(value = "停止应用")
+    @PostMapping("/stop/{appId}")
+    public ResponseEntity<String> stop(@PathVariable("appId") String appId) throws DockerException {
+        statusService.stop(appId);
+        return ResponseEntity.ok().body("ok");
+    }
+
+    @ApiOperation(value = "启动应用")
+    @PostMapping("/start/{appId}")
+    public ResponseEntity<String> start(@PathVariable("appId") String appId) throws DockerException {
+        statusService.start(appId);
+        return ResponseEntity.ok().body("ok");
     }
 }

+ 3 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/BuildConfigCrudController.java

@@ -128,4 +128,7 @@ public class BuildConfigCrudController {
         packerConfigCrudService.delete(uniqueKey);
         return ResponseEntity.ok().body(WebResult.success("ok"));
     }
+
+    /* 构建目录配置 */
+
 }

+ 6 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/GlobalCrudController.java

@@ -5,7 +5,7 @@ import cn.reghao.autodop.dmaster.common.db.PageList;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dmaster.app.entity.BuildDir;
 import cn.reghao.autodop.dmaster.app.entity.config.NotifierConfig;
-import cn.reghao.autodop.dmaster.app.service.crud.global.LocalDirCrudService;
+import cn.reghao.autodop.dmaster.app.service.crud.build.BuildDirCrudService;
 import cn.reghao.autodop.dmaster.app.service.crud.global.NotifierCrudService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -22,11 +22,11 @@ import org.springframework.web.bind.annotation.*;
 @RestController
 @RequestMapping("/api/config/global")
 public class GlobalCrudController {
-    private LocalDirCrudService localDirCrudService;
+    private BuildDirCrudService buildDirCrudService;
     private NotifierCrudService notifierCrudService;
 
-    public GlobalCrudController(LocalDirCrudService localDirCrudService, NotifierCrudService notifierCrudService) {
-        this.localDirCrudService = localDirCrudService;
+    public GlobalCrudController(BuildDirCrudService buildDirCrudService, NotifierCrudService notifierCrudService) {
+        this.buildDirCrudService = buildDirCrudService;
         this.notifierCrudService = notifierCrudService;
     }
 
@@ -71,7 +71,7 @@ public class GlobalCrudController {
     @ApiOperation(value = "分页获取本地目录配置")
     @GetMapping("/localdir")
     public ResponseEntity<String> getLocalDirByPage(@RequestParam("page") int page, @RequestParam("size") int size) {
-        PageList<BuildDir> pageList = localDirCrudService.getByPage(page, size);
+        PageList<BuildDir> pageList = buildDirCrudService.getByPage(page, size);
         return ResponseEntity.ok().body(WebResult.success(pageList));
     }
 
@@ -79,7 +79,7 @@ public class GlobalCrudController {
     @PutMapping("/localdir")
     public ResponseEntity<String> modifyLocalDir(@RequestBody String json) throws Exception {
         BuildDir buildDir = (BuildDir) JsonConverter.jsonToObject(json, BuildDir.class);
-        localDirCrudService.addOrUpdate(buildDir);
+        buildDirCrudService.addOrUpdate(buildDir);
         return ResponseEntity.ok().body(WebResult.success("ok"));
     }
 

+ 22 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/log/AppStatus.java

@@ -0,0 +1,22 @@
+package cn.reghao.autodop.dmaster.app.entity.log;
+
+import cn.reghao.autodop.dmaster.common.db.orm.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.persistence.Entity;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 11:46:32
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Entity
+public class AppStatus extends BaseEntity {
+    private String machineId;
+    private String appId;
+    private String commitId;
+    private long startTime;
+    private int pid;
+}

+ 0 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/log/BuildDeployApp.java

@@ -1,6 +1,5 @@
 package cn.reghao.autodop.dmaster.app.entity.log;
 
-import cn.reghao.autodop.common.utils.DatetimeConverter;
 import cn.reghao.autodop.dmaster.common.db.orm.BaseEntity;
 import cn.reghao.autodop.dmaster.app.entity.config.orchestration.AppOrchestration;
 import lombok.Data;

+ 19 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/log/AppStatusRepository.java

@@ -0,0 +1,19 @@
+package cn.reghao.autodop.dmaster.app.repository.log;
+
+import cn.reghao.autodop.dmaster.app.entity.log.AppStatus;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @author reghao
+ * @date 2020-01-21 14:53:03
+ */
+public interface AppStatusRepository extends JpaRepository<AppStatus, Long> {
+    /**
+     * 找到唯一的 AppStatus 对象
+     *
+     * @param
+     * @return
+     * @date 2021-02-25 上午11:50
+     */
+    AppStatus findByAppIdAndCommitIdAndMachineId(String appId, String commitId, String machineId);
+}

+ 49 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppStatusService.java

@@ -0,0 +1,49 @@
+package cn.reghao.autodop.dmaster.app.service;
+
+import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
+import cn.reghao.autodop.dmaster.app.entity.log.AppStatus;
+import cn.reghao.autodop.dmaster.app.service.crud.log.AppStatusCrudService;
+import cn.reghao.autodop.dmaster.app.vo.LogFile;
+import cn.reghao.autodop.dmaster.common.db.PageList;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 应用状态管理
+ *
+ * @author reghao
+ * @date 2019-11-27 11:30:28
+ */
+@Service
+public class AppStatusService {
+    private BuildDeployCache caching;
+    private AppStatusCrudService statusCrudService;
+
+    public AppStatusService(BuildDeployCache caching, AppStatusCrudService statusCrudService) {
+        this.caching = caching;
+        this.statusCrudService = statusCrudService;
+    }
+
+    public List<AppStatus> status(int page, int size, String env) {
+        PageList<AppStatus> pageList = statusCrudService.getByPage(page, size);
+        return null;
+    }
+
+    public List<LogFile> logFiles() {
+        return null;
+    }
+
+    public List<String> logContent() {
+        return null;
+    }
+
+    public void restart(String appId) {
+    }
+
+    public void stop(String appId) {
+    }
+
+    public void start(String appId) {
+    }
+}

+ 18 - 12
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/BuildDeployDispatcher.java

@@ -1,5 +1,6 @@
 package cn.reghao.autodop.dmaster.app.service;
 
+import cn.reghao.autodop.common.amqp.RabbitProducer;
 import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
 import cn.reghao.autodop.dmaster.app.constant.BuildStage;
 import cn.reghao.autodop.dmaster.app.constant.NotifierType;
@@ -12,6 +13,7 @@ import cn.reghao.autodop.dmaster.app.entity.config.orchestration.AppOrchestratio
 import cn.reghao.autodop.dmaster.app.service.log.BuildDeployLogService;
 import cn.reghao.autodop.dmaster.app.service.log.BuildDeployLogConsumer;
 import cn.reghao.autodop.common.utils.ExceptionUtil;
+import cn.reghao.autodop.dmaster.utils.notifier.NotifyService;
 import cn.reghao.autodop.dmaster.common.thread.ThreadPoolWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -38,13 +40,16 @@ public class BuildDeployDispatcher {
     private AppDeployer appDeployer;
 
     private ExecutorService threadPool = ThreadPoolWrapper.threadPool("build-deploy");
-    private BuildDeployLogConsumer buildDeployLogConsumer;
-
-    public BuildDeployDispatcher(BuildDeployCache buildDeployCache, AppDeployer appDeployer, BuildDeployLogService logDAO) {
-        this.cache = buildDeployCache;
-        this.appDeployer = appDeployer;
-        this.buildDeployLogConsumer = new BuildDeployLogConsumer(logDAO);
-        threadPool.submit(buildDeployLogConsumer);
+    private BuildDeployLogConsumer logConsumer;
+    private NotifyService notifyService;
+
+    public BuildDeployDispatcher(BuildDeployCache cache, RabbitProducer producer, BuildDeployLogService logService) {
+        this.cache = cache;
+        this.logConsumer = new BuildDeployLogConsumer(logService);
+        this.appDeployer = new AppDeployer(producer, threadPool, logConsumer);
+        this.notifyService = new NotifyService();
+        threadPool.execute(logConsumer);
+        threadPool.execute(notifyService);
     }
 
     /**
@@ -74,7 +79,7 @@ public class BuildDeployDispatcher {
 
         // TODO 抛出异常时从 onBuilding 中移除当前应用
         BuildLog buildLog = buildPipeline(appIntegrate);
-        buildDeployLogConsumer.addBuildLog(buildLog);
+        logConsumer.addBuildLog(buildLog);
         onBuilding.remove(appId);
         BuildDeployApp buildDeployApp;
         if (buildLog.getStatusCode() == 0 && isDeploy) {
@@ -87,12 +92,13 @@ public class BuildDeployDispatcher {
             buildDeployApp = BuildDeployApp.of(buildLog);
         }
 
-        buildDeployLogConsumer.addBuildDeployApp(buildDeployApp);
+        logConsumer.addBuildDeployApp(buildDeployApp);
         return buildDeployApp;
     }
 
     /**
      * 更新 -> 编译 -> 打包 -> 构建流水线
+     * TODO 检测超时
      *
      * @date 2019-11-07 下午10:14
      */
@@ -109,7 +115,7 @@ public class BuildDeployDispatcher {
             buildLog.setCommitId(commitLog.getCommitId());
             buildLog.setCommitTime(commitLog.getCommitTime());
             buildLog.setUpdateTotalTime(System.currentTimeMillis()-start);
-            buildDeployLogConsumer.addCommitLog(commitLog);
+            logConsumer.addCommitLog(commitLog);
         } catch (Exception e) {
             buildException(buildLog, BuildStage.update, e);
             return buildLog;
@@ -163,7 +169,7 @@ public class BuildDeployDispatcher {
         DeployResult deployResult = appDeployer.deploy(buildLog, deployConfigs);
         // TODO 部署完成后发出通知
         onDeploying.remove(buildLog.getAppId());
-        buildDeployLogConsumer.addDeployLog(deployResult);
+        logConsumer.addDeployLog(deployResult);
         return deployResult;
     }
 
@@ -174,7 +180,7 @@ public class BuildDeployDispatcher {
             return BuildDeployApp.onDeploying(appId);
         }
         BuildDeployApp buildDeployApp = BuildDeployApp.of(deployResult);
-        buildDeployLogConsumer.addBuildDeployApp(buildDeployApp);
+        logConsumer.addBuildDeployApp(buildDeployApp);
         return buildDeployApp;
     }
 

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

@@ -11,7 +11,7 @@ import cn.reghao.autodop.dmaster.app.repository.log.CommitLogRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.DeployLogRepository;
 import cn.reghao.autodop.dmaster.app.entity.log.CommitLog;
 import cn.reghao.autodop.dmaster.common.db.PageList;
-import cn.reghao.autodop.dmaster.app.service.crud.BuildDeployAppCrudService;
+import cn.reghao.autodop.dmaster.app.service.crud.log.BuildDeployAppCrudService;
 import cn.reghao.autodop.dmaster.app.vo.CurrentRunningCommit;
 import cn.reghao.autodop.dmaster.app.vo.SuccessfullyBuildVO;
 import cn.reghao.autodop.dmaster.app.vo.log.*;

+ 0 - 69
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/LogManager.java

@@ -1,69 +0,0 @@
-package cn.reghao.autodop.dmaster.app.service;
-
-import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
-import cn.reghao.autodop.dmaster.app.entity.deploy.LogConfig;
-import cn.reghao.autodop.dmaster.app.entity.config.orchestration.AppOrchestration;
-import cn.reghao.autodop.dmaster.app.vo.LogFile;
-import org.springframework.stereotype.Service;
-
-import java.util.*;
-
-/**
- * 应用日志管理
- *
- * @author reghao
- * @date 2019-11-27 11:30:28
- */
-@Service
-public class LogManager {
-    private BuildDeployCache caching;
-
-    public LogManager(BuildDeployCache caching) {
-        this.caching = caching;
-    }
-
-    public List<LogFile> logFiles(String appId, String host) throws Exception {
-        AppOrchestration app = caching.findByAppId(appId);
-        //Set<LogConfig> logConfigs = app.getAppRunning().getLogs();
-        Set<LogConfig> logConfigs = new HashSet<>();
-        if (logConfigs.isEmpty()) {
-            throw new Exception("日志未配置");
-        }
-
-        List<LogFile> logFiles = new ArrayList<>();
-        for (LogConfig logConfig : logConfigs) {
-            /*String logType = logConfig.getLogType();
-            String logLevel = logConfig.getLogLevel();
-            LogFile logFile = new LogFile(logType, logLevel);
-            String logDir = app.getAppDeploy().getRunningDir() + logConfig.getLogDir();
-            logFiles.add(logFile);*/
-        }
-
-        return logFiles;
-    }
-
-    public List<String> logContent(String appId, String logType, String logLevel, String logName) throws Exception {
-        AppOrchestration app = caching.findByAppId(appId);
-        //Set<LogConfig> logConfigs = app.getAppRunning().getLogs();
-        Set<LogConfig> logConfigs = new HashSet<>();
-        if (logConfigs.isEmpty()) {
-            throw new Exception("日志未配置");
-        }
-
-        String runningDir = "app.getAppDeploy().getRunningDir()";
-        String logfilePath = null;
-        for (LogConfig logConfig : logConfigs) {
-            if (logConfig.getType().equals(logType) && logConfig.getLevel().equals(logLevel)) {
-                // TODO 只有控制台日志的 logPath 才为 null
-                //logfilePath = runningDir + logConfig.getLogDir() + "/" + logName;
-                break;
-            }
-        }
-
-        /*for (String host : app.getAppDeploy().getHosts()) {
-            return null;
-        }*/
-
-        return null;
-    }
-}

+ 0 - 71
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/StatusManager.java

@@ -1,71 +0,0 @@
-package cn.reghao.autodop.dmaster.app.service;
-
-import cn.reghao.autodop.common.deploy.AppStatus;
-import cn.reghao.autodop.common.dockerc.exception.DockerException;
-import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
-import cn.reghao.autodop.dmaster.app.entity.log.BuildDeployApp;
-import cn.reghao.autodop.dmaster.app.entity.config.orchestration.AppOrchestration;
-import cn.reghao.autodop.dmaster.app.repository.log.BuildDeployAppRepository;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.stereotype.Service;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 应用状态管理
- *
- * @author reghao
- * @date 2019-11-27 11:30:28
- */
-@Service
-public class StatusManager {
-    private BuildDeployAppRepository buildDeployAppRepository;
-    private BuildDeployCache caching;
-
-    public StatusManager(BuildDeployCache caching, BuildDeployAppRepository buildDeployAppRepository) {
-        this.buildDeployAppRepository = buildDeployAppRepository;
-        this.caching = caching;
-    }
-
-    public void run(String appId, String commitId) throws DockerException {
-        AppOrchestration app = caching.findByAppId(appId);
-        /*for (String host : app.getAppDeploy().getHosts()) {
-        }*/
-    }
-
-    public void start(String appId) throws DockerException {
-        AppOrchestration app = caching.findByAppId(appId);
-        /*for (String host : app.getAppDeploy().getHosts()) {
-        }*/
-    }
-
-    public void stop(String appId) throws DockerException {
-        AppOrchestration app = caching.findByAppId(appId);
-        /*for (String host : app.getAppDeploy().getHosts()) {
-        }*/
-    }
-
-    public void restart(String appId) throws DockerException {
-        AppOrchestration app = caching.findByAppId(appId);
-        /*for (String host : app.getAppDeploy().getHosts()) {
-        }*/
-    }
-
-    public List<AppStatus> status(String env, PageRequest pageRequest) {
-        //Page<BuildDeployApp> page = buildDeployAppRepository.findByIsDeleteFalseAndEnableIsTrueAndEnv(env, pageRequest);
-        List<AppStatus> appStatusList = new ArrayList<>();
-        // TODO 异步处理
-        /*try {
-            for (BuildDeployApp buildDeployApp : page.getContent()) {
-                for (String host : app.getApp().getAppDeploy().getHosts()) {
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }*/
-
-        return appStatusList;
-    }
-}

+ 0 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/build/AppIntegrate.java

@@ -182,7 +182,6 @@ public class AppIntegrate {
 
     public void compile() throws Exception {
         // TODO 通过脚本调用编译器时会卡住
-        // TODO 编译主目录分为项目中的应用和独立应用
         codeCompiler.compile(app.getAppId(), compileDir());
     }
 

+ 3 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/global/LocalDirCrudService.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/build/BuildDirCrudService.java

@@ -1,4 +1,4 @@
-package cn.reghao.autodop.dmaster.app.service.crud.global;
+package cn.reghao.autodop.dmaster.app.service.crud.build;
 
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
 import cn.reghao.autodop.dmaster.common.db.PageList;
@@ -19,10 +19,10 @@ import java.util.stream.Collectors;
  * @date 2020-11-10 21:58:00
  */
 @Service
-public class LocalDirCrudService implements CrudOps<BuildDir> {
+public class BuildDirCrudService implements CrudOps<BuildDir> {
     private BuildDirRepository buildDirRepository;
 
-    public LocalDirCrudService(BuildDirRepository buildDirRepository) {
+    public BuildDirCrudService(BuildDirRepository buildDirRepository) {
         this.buildDirRepository = buildDirRepository;
     }
 

+ 57 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/log/AppStatusCrudService.java

@@ -0,0 +1,57 @@
+package cn.reghao.autodop.dmaster.app.service.crud.log;
+
+import cn.reghao.autodop.dmaster.app.entity.log.AppStatus;
+import cn.reghao.autodop.dmaster.app.repository.log.AppStatusRepository;
+import cn.reghao.autodop.dmaster.common.db.CrudOps;
+import cn.reghao.autodop.dmaster.common.db.PageList;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author reghao
+ * @date 2021-02-19 16:39:29
+ */
+@Service
+public class AppStatusCrudService implements CrudOps<AppStatus> {
+    private AppStatusRepository statusRepository;
+
+    public AppStatusCrudService(AppStatusRepository statusRepository) {
+        this.statusRepository = statusRepository;
+    }
+
+    @Override
+    public void addOrUpdate(AppStatus appStatus) throws Exception {
+        String appId = appStatus.getAppId();
+        String commitId = appStatus.getCommitId();
+        String machineId = appStatus.getMachineId();
+        AppStatus entity = statusRepository.findByAppIdAndCommitIdAndMachineId(appId, commitId, machineId);
+        if (entity != null) {
+            appStatus.setId(entity.getId());
+            appStatus.setCreateTime(entity.getCreateTime());
+            appStatus.setUpdateTime(LocalDateTime.now());
+        }
+        appStatus.setIsDelete(false);
+        statusRepository.save(appStatus);
+    }
+
+    @Override
+    public PageList<AppStatus> getByPage(int page, int size, String env) {
+        // 默认按更新时间倒序
+        PageRequest pageRequest =
+                PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC, "updateTime"));
+        Page<AppStatus> page1 = statusRepository.findAll(pageRequest);
+        PageList<AppStatus> pageList = new PageList<>();
+        pageList.setTotalSize(page1.getTotalElements());
+        pageList.setTotalPages(page1.getTotalPages());
+        pageList.setList(page1.getContent());
+        return pageList;
+    }
+
+    @Override
+    public void delete(String uniqueKey) throws Exception {
+    }
+}

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/BuildDeployAppCrudService.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/log/BuildDeployAppCrudService.java

@@ -1,4 +1,4 @@
-package cn.reghao.autodop.dmaster.app.service.crud;
+package cn.reghao.autodop.dmaster.app.service.crud.log;
 
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
 import cn.reghao.autodop.dmaster.common.db.PageList;

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/crud/orchestarte/AppCrudService.java

@@ -5,7 +5,7 @@ import cn.reghao.autodop.dmaster.common.db.PageList;
 import cn.reghao.autodop.dmaster.app.entity.log.BuildDeployApp;
 import cn.reghao.autodop.dmaster.app.entity.config.orchestration.AppOrchestration;
 import cn.reghao.autodop.dmaster.app.repository.orchestration.AppOrchestrationRepository;
-import cn.reghao.autodop.dmaster.app.service.crud.BuildDeployAppCrudService;
+import cn.reghao.autodop.dmaster.app.service.crud.log.BuildDeployAppCrudService;
 import cn.reghao.autodop.dmaster.app.service.crud.SharedEntityChecker;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;

+ 15 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/deploy/AppDeployer.java

@@ -9,13 +9,13 @@ import cn.reghao.autodop.common.amqp.RabbitProducer;
 import cn.reghao.autodop.common.dockerc.pojo.Config;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dmaster.app.entity.deploy.DeployConfig;
+import cn.reghao.autodop.dmaster.app.entity.log.AppStatus;
 import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
 import cn.reghao.autodop.dmaster.app.entity.log.DeployLog;
 import cn.reghao.autodop.dmaster.app.entity.log.DeployResult;
 import cn.reghao.autodop.common.utils.ExceptionUtil;
-import cn.reghao.autodop.dmaster.common.thread.ThreadPoolWrapper;
+import cn.reghao.autodop.dmaster.app.service.log.BuildDeployLogConsumer;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
 
 import java.time.LocalDateTime;
 import java.util.*;
@@ -31,14 +31,16 @@ import java.util.concurrent.Future;
  * @date 2020-03-13 10:26:22
  */
 @Slf4j
-@Component
 public class AppDeployer {
     private final String exchange = "amq.direct";
     private RabbitProducer rabbitProducer;
-    private ExecutorService threadPool = ThreadPoolWrapper.threadPool("deploy");
+    private ExecutorService threadPool;
+    BuildDeployLogConsumer logConsumer;
 
-    public AppDeployer(RabbitProducer rabbitProducer) {
+    public AppDeployer(RabbitProducer rabbitProducer, ExecutorService threadPool, BuildDeployLogConsumer logConsumer) {
         this.rabbitProducer = rabbitProducer;
+        this.threadPool = threadPool;
+        this.logConsumer = logConsumer;
     }
 
     /**
@@ -53,6 +55,7 @@ public class AppDeployer {
         for (DeployConfig deployConfig : deployConfigs) {
             AppDeployArgs appDeployArgs = new AppDeployArgs();
             appDeployArgs.setAppId(buildLog.getAppId());
+            appDeployArgs.setCommitId(buildLog.getCommitId());
             appDeployArgs.setPackagePath(buildLog.getPackagePath());
             appDeployArgs.setPackerType(deployConfig.getPackerType());
             appDeployArgs.setStartHome(deployConfig.getStartHome());
@@ -92,7 +95,13 @@ public class AppDeployer {
                 if (rpcResult != null) {
                     deployLog.setDeployTime(deployTime);
                     deployLog.setStatusCode(rpcResult.getStatusCode());
-                    deployLog.setErrDetail(rpcResult.getResult());
+                    if (rpcResult.getStatusCode() == 0) {
+                        AppStatus appStatus =
+                                (AppStatus) JsonConverter.jsonToObject(rpcResult.getResult(), AppStatus.class);
+                        logConsumer.addAppStatus(appStatus);
+                    } else {
+                        deployLog.setErrDetail(rpcResult.getResult());
+                    }
                 } else {
                     deployLog.setStatusCode(1);
                     deployLog.setErrDetail("RPC 调用失败");

+ 8 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/log/BuildDeployLogConsumer.java

@@ -37,6 +37,10 @@ public class BuildDeployLogConsumer implements Runnable {
         logQueue.add(buildDeployApp);
     }
 
+    public void addAppStatus(AppStatus appStatus) {
+        logQueue.add(appStatus);
+    }
+
     @Override
     public void run() {
         log.info("日志持久化线程已启动...");
@@ -59,6 +63,10 @@ public class BuildDeployLogConsumer implements Runnable {
                     BuildDeployApp buildDeployApp = (BuildDeployApp) object;
                     logService.saveBuildDeployApp(buildDeployApp);
                     log.info("持久化 {} 构建部署日志完成...", buildDeployApp.getAppId());
+                } else if (object instanceof AppStatus) {
+                    AppStatus appStatus = (AppStatus) object;
+                    logService.saveAppStatus(appStatus);
+                    log.info("持久化 {} 应用运行状态完成...", appStatus.getAppId());
                 }
             } catch (InterruptedException e) {
                 // 中断线程

+ 11 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/log/BuildDeployLogService.java

@@ -4,7 +4,8 @@ import cn.reghao.autodop.dmaster.app.entity.log.*;
 import cn.reghao.autodop.dmaster.app.repository.log.BuildLogRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.CommitLogRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.DeployLogRepository;
-import cn.reghao.autodop.dmaster.app.service.crud.BuildDeployAppCrudService;
+import cn.reghao.autodop.dmaster.app.service.crud.log.AppStatusCrudService;
+import cn.reghao.autodop.dmaster.app.service.crud.log.BuildDeployAppCrudService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -22,15 +23,18 @@ public class BuildDeployLogService {
     private BuildLogRepository buildLogRepository;
     private DeployLogRepository deployLogRepository;
     private BuildDeployAppCrudService buildDeployAppCrudService;
+    private AppStatusCrudService statusCrudService;
 
     public BuildDeployLogService(CommitLogRepository commitLogRepository,
                                  BuildLogRepository buildLogRepository,
                                  DeployLogRepository deployLogRepository,
-                                 BuildDeployAppCrudService buildDeployAppCrudService) {
+                                 BuildDeployAppCrudService buildDeployAppCrudService,
+                                 AppStatusCrudService statusCrudService) {
         this.commitLogRepository = commitLogRepository;
         this.buildLogRepository = buildLogRepository;
         this.deployLogRepository = deployLogRepository;
         this.buildDeployAppCrudService = buildDeployAppCrudService;
+        this.statusCrudService = statusCrudService;
     }
 
     @Transactional(rollbackFor = {Exception.class})
@@ -52,4 +56,9 @@ public class BuildDeployLogService {
     public void saveBuildDeployApp(BuildDeployApp buildDeployApp) throws Exception {
         buildDeployAppCrudService.addOrUpdate(buildDeployApp);
     }
+
+    @Transactional(rollbackFor = {Exception.class})
+    public void saveAppStatus(AppStatus appStatus) throws Exception {
+        statusCrudService.addOrUpdate(appStatus);
+    }
 }

+ 32 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/notifier/NotifyService.java

@@ -0,0 +1,32 @@
+package cn.reghao.autodop.dmaster.utils.notifier;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * @author reghao
+ * @date 2021-02-25 00:10:17
+ */
+@Slf4j
+public class NotifyService implements Runnable {
+    private static BlockingQueue<Object> msgQueue = new LinkedBlockingQueue<>();
+
+    @Override
+    public void run() {
+        log.info("通知线程已启动...");
+        while (!Thread.interrupted()) {
+            try {
+                Object object = msgQueue.take();
+            } catch (InterruptedException e) {
+                // 中断线程
+                log.info("中断通知线程...");
+                Thread.currentThread().interrupt();
+            } catch (Exception e) {
+                log.info("通知异常...");
+                e.printStackTrace();
+            }
+        }
+    }
+}