Browse Source

优化 BuildDeployService 接口

reghao 4 years ago
parent
commit
f3782f1dc0
22 changed files with 195 additions and 134 deletions
  1. 13 12
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/BuildDeployController.java
  2. 13 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/page/BuildDeployLogPageController.java
  3. 8 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/page/BuildDeployPageController.java
  4. 1 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/query/log/BuildLogQuery.java
  5. 16 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/query/log/BuildLogQueryImpl.java
  6. 2 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/repository/log/BuildLogRepository.java
  7. 7 20
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/po/AppBuilding.java
  8. 7 19
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/po/AppDeploying.java
  9. 11 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/vo/AppBuildingVO.java
  10. 9 4
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/vo/AppDeployingVO.java
  11. 7 4
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppBuilder.java
  12. 42 26
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppDeployer.java
  13. 2 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/BuildDeployService.java
  14. 1 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppBuildingService.java
  15. 5 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppBuildingServiceImpl.java
  16. 1 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppDeployingServiceImpl.java
  17. 27 18
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/impl/BuildDeployServiceImpl.java
  18. 18 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/util/buildtool/packer/ZipPack.java
  19. 0 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/db/query/MongoQuery.java
  20. 2 2
      dmaster/src/main/resources/static/js/main.js
  21. 1 1
      dmaster/src/main/resources/templates/app/bd/deploy.html
  22. 2 2
      dmaster/src/main/resources/templates/app/bd/index.html

+ 13 - 12
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/BuildDeployController.java

@@ -30,28 +30,29 @@ public class BuildDeployController {
     }
 
     @ApiOperation(value = "构建部署应用")
-    @ApiImplicitParams(@ApiImplicitParam(name="appId", value="应用 ID", paramType="query", dataType = "String"))
-    @PostMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String buildAndDeploy(@RequestParam("appId") String appId) throws Exception {
-        buildDeployService.buildAndDeploy(appId);
+    @ApiImplicitParams(@ApiImplicitParam(name="appId", value="应用 ID", paramType="path", dataType = "String"))
+    @PostMapping(value = "/update/{appId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String buildAndDeploy(@PathVariable("appId") String appId) throws Exception {
+        buildDeployService.buildAndDeploy(appId, true);
         return WebBody.success();
     }
 
     @ApiOperation(value = "构建应用")
-    @ApiImplicitParams(@ApiImplicitParam(name="appId", value="应用 ID", paramType="query", dataType = "String"))
-    @PostMapping(value = "/build", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String build(@RequestParam("appId") String appId) throws Exception {
-        buildDeployService.build(appId);
+    @ApiImplicitParams(@ApiImplicitParam(name="appId", value="应用 ID", paramType="path", dataType = "String"))
+    @PostMapping(value = "/build/{appId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String build(@PathVariable("appId") String appId) throws Exception {
+        buildDeployService.buildAndDeploy(appId, false);
         return WebBody.success();
     }
 
     @ApiOperation(value = "部署应用")
     @ApiImplicitParams({
-            @ApiImplicitParam(name="buildLogId", value="构建 ID", paramType="path", dataType = "String")
+            @ApiImplicitParam(name="buildLogId", value="构建 ID", paramType="path", dataType = "String"),
+            @ApiImplicitParam(name="machineId", value="机器 ID", paramType="path", dataType = "String")
     })
-    @PostMapping(value = "/deploy/{buildLogId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String deploy(@PathVariable("buildLogId") String buildLogId) {
-        buildDeployService.deploy(buildLogId);
+    @PostMapping(value = "/deploy/{buildLogId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deploy(@PathVariable("buildLogId") String buildLogId, @PathVariable("machineId") String machineId) {
+        buildDeployService.deploy(buildLogId, machineId);
         return WebBody.success();
     }
 

+ 13 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/page/BuildDeployLogPageController.java

@@ -21,7 +21,10 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author reghao
@@ -121,9 +124,16 @@ public class BuildDeployLogPageController {
     @ApiOperation(value = "构建日志结果页面")
     @GetMapping("/build/{buildLogId}/result")
     public String buildLogResultPage(@PathVariable("buildLogId") String buildLogId, Model model) {
-        BuildLog buildLog = buildDeployLogPage.findByBuildLogId(buildLogId);
-        String[] arr = buildLog.getResult().getMsg().split(System.lineSeparator());
-        model.addAttribute("list", arr);
+        List<String> list = new ArrayList<>();
+        if ("null".equals(buildLogId)) {
+            list.add("构建结果暂不可用");
+        } else {
+            BuildLog buildLog = buildDeployLogPage.findByBuildLogId(buildLogId);
+            list = Arrays.stream(buildLog.getResult().getMsg().split(System.lineSeparator()))
+                    .collect(Collectors.toList());
+        }
+
+        model.addAttribute("list", list);
         return "/app/bd/log/buildresult";
     }
 

+ 8 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/page/BuildDeployPageController.java

@@ -1,8 +1,10 @@
 package cn.reghao.autodop.dmaster.app.controller.page;
 
 import cn.reghao.autodop.dmaster.app.model.constant.EnvList;
+import cn.reghao.autodop.dmaster.app.model.po.log.BuildLog;
 import cn.reghao.autodop.dmaster.app.model.vo.AppBuildingVO;
 import cn.reghao.autodop.dmaster.app.model.vo.AppDeployingVO;
+import cn.reghao.autodop.dmaster.app.service.bd.AppBuildingService;
 import cn.reghao.autodop.dmaster.app.service.page.BuildDeployPage;
 import cn.reghao.autodop.dmaster.util.db.PageList;
 import cn.reghao.autodop.dmaster.util.db.PageSort;
@@ -26,9 +28,11 @@ import java.util.*;
 @RequestMapping("/app/bd")
 public class BuildDeployPageController {
     private final BuildDeployPage buildDeployPage;
+    private AppBuildingService buildingService;
 
-    public BuildDeployPageController(BuildDeployPage buildDeployPage) {
+    public BuildDeployPageController(BuildDeployPage buildDeployPage, AppBuildingService buildingService) {
         this.buildDeployPage = buildDeployPage;
+        this.buildingService = buildingService;
     }
 
     @ApiOperation(value = "构建部署页面")
@@ -57,10 +61,12 @@ public class BuildDeployPageController {
     @ApiOperation(value = "部署状态页面")
     @GetMapping("/deploy/{appId}")
     public String deployStatusPage(@PathVariable("appId") String appId, Model model) {
+        BuildLog buildLog = buildingService.latestBuilding(appId);
+        String buildLogId = buildLog != null ? buildLog.getId() : null;
         List<AppDeployingVO> list = buildDeployPage.deployStatus(appId);
 
         model.addAttribute("appId", appId);
-        model.addAttribute("buildLogId", "list");
+        model.addAttribute("buildLogId", buildLogId);
         model.addAttribute("list", list);
         return "/app/bd/deploy";
     }

+ 1 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/query/log/BuildLogQuery.java

@@ -10,5 +10,6 @@ import org.springframework.data.domain.Pageable;
  */
 public interface BuildLogQuery {
     Page<BuildLog> findByAppId(String appId, Pageable pageable);
+    BuildLog findLatestBuildingByAppId(String appId);
     BuildLog findById(String id);
 }

+ 16 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/query/log/BuildLogQueryImpl.java

@@ -4,6 +4,10 @@ import cn.reghao.autodop.dmaster.app.db.repository.log.BuildLogRepository;
 import cn.reghao.autodop.dmaster.app.model.po.log.BuildLog;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -15,9 +19,11 @@ import java.util.List;
 @Service
 public class BuildLogQueryImpl implements BuildLogQuery {
     private final BuildLogRepository buildLogRepository;
+    private final MongoTemplate mongoTemplate;
 
-    public BuildLogQueryImpl(BuildLogRepository buildLogRepository) {
+    public BuildLogQueryImpl(BuildLogRepository buildLogRepository, MongoTemplate mongoTemplate) {
         this.buildLogRepository = buildLogRepository;
+        this.mongoTemplate = mongoTemplate;
     }
 
     @Override
@@ -25,6 +31,15 @@ public class BuildLogQueryImpl implements BuildLogQuery {
         return buildLogRepository.findByAppId(appId, pageable);
     }
 
+    @Override
+    public BuildLog findLatestBuildingByAppId(String appId) {
+        Query query = new Query();
+        query.addCriteria(Criteria.where("appId").is(appId));
+        query.with(Sort.by(Sort.Order.desc("buildTime"))).limit(1);
+        List<BuildLog> list = mongoTemplate.find(query, BuildLog.class);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
     @Override
     public BuildLog findById(String id) {
         return buildLogRepository.findById(id).orElse(null);

+ 2 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/repository/log/BuildLogRepository.java

@@ -5,6 +5,8 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.mongodb.repository.MongoRepository;
 
+import java.util.List;
+
 /**
  * @author reghao
  * @date 2020-01-21 14:53:03

+ 7 - 20
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/po/AppBuilding.java

@@ -13,7 +13,6 @@ import lombok.*;
 import javax.persistence.Entity;
 import javax.persistence.JoinColumn;
 import javax.persistence.OneToOne;
-import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 
 /**
@@ -30,39 +29,27 @@ public class AppBuilding extends BaseEntity<Integer> {
     @JoinColumn(nullable = false, unique = true)
     @OneToOne
     private AppConfig appConfig;
-    @NotNull
     private String buildLogId;
-    @NotNull
     private String commitId;
-    @NotNull
     private LocalDateTime commitTime;
-    @NotNull
     private String buildResult;
-    @NotNull
     private LocalDateTime buildTime;
-    @NotNull
     private String packagePath;
-    @NotNull
     private String buildBy;
 
     public AppBuilding(AppConfig appConfig) {
         this.appConfig = appConfig;
-        this.commitId = NotAvailable.na.getDesc();
-        this.commitTime = LocalDateTime.MIN;
         this.buildResult = BuildStatus.neverBuild.getDesc();
-        this.buildTime = LocalDateTime.MIN;
-        this.packagePath = NotAvailable.na.getDesc();
-        this.buildBy = NotAvailable.na.getDesc();
     }
 
     public void beforeBuild(String buildBy) {
-        this.setCommitId(NotAvailable.na.getDesc());
-        this.setCommitTime(DateTimeConverter.localDateTime(0));
-        this.setBuildResult(BuildStatus.onBuilding.getDesc());
-        this.setBuildTime(LocalDateTime.MIN);
-        this.setPackagePath(NotAvailable.na.getDesc());
-        this.setBuildBy(buildBy);
-        this.setUpdateTime(LocalDateTime.now());
+        this.buildLogId = null;
+        this.commitId = null;
+        this.commitTime = null;
+        this.buildResult = BuildStatus.onBuilding.getDesc();
+        this.buildTime = null;
+        this.packagePath = null;
+        this.buildBy = buildBy;
     }
 
     public void afterBuild(BuildLog buildLog) {

+ 7 - 19
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/po/AppDeploying.java

@@ -2,8 +2,8 @@ package cn.reghao.autodop.dmaster.app.model.po;
 
 import cn.reghao.autodop.dmaster.app.model.constant.DeployStatus;
 import cn.reghao.autodop.dmaster.app.model.po.config.AppDeployConfig;
+import cn.reghao.autodop.dmaster.app.model.po.log.BuildLog;
 import cn.reghao.autodop.dmaster.app.model.po.log.DeployLog;
-import cn.reghao.autodop.common.util.NotAvailable;
 import cn.reghao.autodop.dmaster.util.db.BaseEntity;
 import cn.reghao.jdkutil.result.Result;
 import cn.reghao.jdkutil.result.ResultStatus;
@@ -12,7 +12,6 @@ import lombok.*;
 import javax.persistence.Entity;
 import javax.persistence.JoinColumn;
 import javax.persistence.OneToOne;
-import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 
 /**
@@ -29,35 +28,24 @@ public class AppDeploying extends BaseEntity<Integer> {
     @JoinColumn(nullable = false, unique = true)
     @OneToOne
     private AppDeployConfig appDeployConfig;
-    @NotNull
     private String buildLogId;
-    @NotNull
     private String commitId;
-    @NotNull
     private String packagePath;
-    @NotNull
     private String deployBy;
-    @NotNull
     private LocalDateTime deployTime;
-    @NotNull
     private String deployResult;
 
     public AppDeploying(AppDeployConfig appDeployConfig) {
         this.appDeployConfig = appDeployConfig;
-        this.buildLogId = NotAvailable.na.getDesc();
-        this.commitId = NotAvailable.na.getDesc();
-        this.packagePath = NotAvailable.na.getDesc();
-        this.deployBy = NotAvailable.na.getDesc();
-        this.deployTime = LocalDateTime.MIN;
         this.deployResult = DeployStatus.neverDeploy.getDesc();
     }
 
-    public void beforeDeploy(String buildLogId, String commitId, String packagePath, String deployBy) {
-        this.buildLogId = buildLogId;
-        this.commitId = commitId;
-        this.packagePath = packagePath;
-        this.deployBy = deployBy;
-        this.deployTime = LocalDateTime.MIN;
+    public void beforeDeploy(BuildLog buildLog) {
+        this.buildLogId = buildLog.getId();
+        this.commitId = buildLog.getCommitInfo().getCommitId();
+        this.packagePath = buildLog.getPackagePath();
+        this.deployBy = buildLog.getBuildBy();
+        this.deployTime = null;
         this.deployResult = DeployStatus.onDeploying.getDesc();
     }
 

+ 11 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/vo/AppBuildingVO.java

@@ -1,5 +1,6 @@
 package cn.reghao.autodop.dmaster.app.model.vo;
 
+import cn.reghao.autodop.common.util.NotAvailable;
 import cn.reghao.autodop.dmaster.app.model.po.AppBuilding;
 import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
 import cn.reghao.jdkutil.converter.DateTimeConverter;
@@ -33,14 +34,18 @@ public class AppBuildingVO {
         this.appType = appConfig.getAppType();
         this.env = appConfig.getEnv();
         this.repoBranch = appConfig.getRepoBranch();
-        this.httpPort = appConfig.getHttpPort() == null ? -1 : appConfig.getHttpPort();
+        this.httpPort = appConfig.getHttpPort() == null ? 0 : appConfig.getHttpPort();
 
+        //this.buildLogId = appBuilding.getBuildLogId() == null ? NotAvailable.na.getDesc() : appBuilding.getBuildLogId();
         this.buildLogId = appBuilding.getBuildLogId();
-        this.commitId = appBuilding.getCommitId();
-        this.commitTime = DateTimeConverter.format(appBuilding.getCommitTime());
+        this.commitId = appBuilding.getCommitId() == null ? NotAvailable.na.getDesc() : appBuilding.getCommitId();
+        this.commitTime = appBuilding.getCommitTime() == null ?
+                NotAvailable.na.getDesc() : DateTimeConverter.format(appBuilding.getCommitTime());
         this.buildResult = appBuilding.getBuildResult();
-        this.buildTime = DateTimeConverter.format(appBuilding.getBuildTime());
-        this.packagePath = appBuilding.getPackagePath();
-        this.buildBy = appBuilding.getBuildBy();
+        this.buildTime = appBuilding.getBuildTime() == null ?
+                NotAvailable.na.getDesc() : DateTimeConverter.format(appBuilding.getBuildTime());
+        this.packagePath = appBuilding.getPackagePath() == null ?
+                NotAvailable.na.getDesc() : appBuilding.getPackagePath();
+        this.buildBy = appBuilding.getBuildBy() == null ? NotAvailable.na.getDesc() : appBuilding.getBuildBy();
     }
 }

+ 9 - 4
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/model/vo/AppDeployingVO.java

@@ -1,5 +1,6 @@
 package cn.reghao.autodop.dmaster.app.model.vo;
 
+import cn.reghao.autodop.common.util.NotAvailable;
 import cn.reghao.autodop.dmaster.app.model.po.AppDeploying;
 import cn.reghao.jdkutil.converter.DateTimeConverter;
 import lombok.Data;
@@ -10,6 +11,7 @@ import lombok.Data;
  */
 @Data
 public class AppDeployingVO {
+    private String machineId;
     private String machineIpv4;
     private String commitId;
     private String packagePath;
@@ -18,11 +20,14 @@ public class AppDeployingVO {
     private String deployResult;
 
     public AppDeployingVO(AppDeploying appDeploying) {
+        this.machineId = appDeploying.getAppDeployConfig().getMachineHost().getMachineId();
         this.machineIpv4 = appDeploying.getAppDeployConfig().getMachineHost().getMachineIpv4();
-        this.commitId = appDeploying.getCommitId();
-        this.packagePath = appDeploying.getPackagePath();
-        this.deployBy = appDeploying.getDeployBy();
-        this.deployTime = DateTimeConverter.format(appDeploying.getDeployTime());
+        this.commitId = appDeploying.getCommitId() == null ? NotAvailable.na.getDesc() : appDeploying.getCommitId();
+        this.packagePath = appDeploying.getPackagePath() == null ?
+                NotAvailable.na.getDesc() : appDeploying.getPackagePath();
+        this.deployBy = appDeploying.getDeployBy() == null ? NotAvailable.na.getDesc() : appDeploying.getDeployBy();
+        this.deployTime = appDeploying.getDeployTime() == null ?
+                NotAvailable.na.getDesc() : DateTimeConverter.format(appDeploying.getDeployTime());
         this.deployResult = appDeploying.getDeployResult();
     }
 }

+ 7 - 4
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppBuilder.java

@@ -26,6 +26,7 @@ import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 
 import java.io.File;
+import java.io.IOException;
 
 /**
  * 应用构建部署,每个应用持有一个对象
@@ -48,7 +49,7 @@ public class AppBuilder {
     private CodeCompiler codeCompiler;
     private CodePacker codePacker;
 
-    public AppBuilder(AppConfig app) {
+    public AppBuilder(AppConfig app) throws IOException {
         this.app = app;
         init();
     }
@@ -64,12 +65,12 @@ public class AppBuilder {
      * @return
      * @date 2020-08-06 上午10:39
      */
-    public void reInit(AppConfig app) {
+    public void reInit(AppConfig app) throws IOException {
         this.app = app;
         init();
     }
 
-    private void init() {
+    private void init() throws IOException {
         initLocalDir();
         initBuildConfig();
     }
@@ -87,7 +88,7 @@ public class AppBuilder {
      * @return
      * @date 2021-02-05 下午11:01
      */
-    private void initBuildConfig() {
+    private void initBuildConfig() throws IOException {
         // 初始化更新配置
         RepoAuthConfig repoAuthConfig = app.getRepoAuthConfig();
         switch (RepoType.valueOf(repoAuthConfig.getType())) {
@@ -130,6 +131,8 @@ public class AppBuilder {
             case zip:
                 codePacker = new ZipPack(packerConfig, appPackDir);
                 break;
+            case zipHttp:
+                break;
             default:
         }
     }

+ 42 - 26
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppDeployer.java

@@ -17,6 +17,7 @@ import org.eclipse.paho.client.mqttv3.MqttException;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+import java.util.concurrent.ConcurrentSkipListSet;
 
 /**
  * 应用部署
@@ -27,6 +28,7 @@ import java.util.*;
 @Slf4j
 @Service
 public class AppDeployer {
+    private final Set<String> onDeploying = new ConcurrentSkipListSet<>();
     private final AsyncMqttClient mqttClient;
     private final AppDeployingService deployingService;
     private final AppDeployConfigQuery deployConfigQuery;
@@ -39,40 +41,27 @@ public class AppDeployer {
     }
 
     public void deploy(BuildLog buildLog) throws MqttException {
-        String buildLogId = buildLog.getId();
         String appId = buildLog.getAppId();
+        if (!onDeploying.add(appId)) {
+            return;
+        }
+
+        String buildLogId = buildLog.getId();
         String packagePath = buildLog.getPackagePath();
         String deployBy = buildLog.getBuildBy();
         String commitId = buildLog.getCommitInfo().getCommitId();
 
         List<AppDeployConfig> deployConfigs = deployConfigQuery.findByAppId(appId);
         // TODO 使用线程池并发执行
-        for (AppDeployConfig deployConfig : deployConfigs) {
-            String machineId = deployConfig.getMachineHost().getMachineId();
-            String machineIpv4 = deployConfig.getMachineHost().getMachineIpv4();
-            String packType = deployConfig.getPackType();
-            String startScript = deployConfig.getStartScript();
-            String startHome = deployConfig.getStartHome();
-            String unpackScript = deployConfig.getUnpackScript();
-
-            DeployParam deployParam = new DeployParam();
-            deployParam.setBuildLogId(buildLogId);
-            deployParam.setAppId(appId);
-            deployParam.setPackagePath(packagePath);
-            deployParam.setPackType(packType);
-            deployParam.setStartScript(startScript);
-            //deployParam.setStartHome(startHome);
-
-            RpcMsg rpcMsg = RpcMsg.paramMsg(AppRpcClazz.class.getSimpleName(), AppRpcClazz.deploy.name(),
-                    JsonConverter.objectToJson(deployParam));
-            Message message = Message.rpcParamMsg(rpcMsg);
-            // TODO 对于需要返回值的 pub,需要做一个记录,pub 和 sub 一一对应
-            String topic = MsgQueue.dagentTopic(machineId);
-            mqttClient.pubWithResult(topic, 1, message);
-
-            deployingService.refreshBeforeDeploy(deployConfig, buildLog);
+        for (AppDeployConfig appDeployConfig : deployConfigs) {
+            String machineId = appDeployConfig.getMachineHost().getMachineId();
+            String machineIpv4 = appDeployConfig.getMachineHost().getMachineIpv4();
+            deployingService.refreshBeforeDeploy(appDeployConfig, buildLog);
             deployingService.addDeployLog(new DeployLog(buildLogId, machineId, machineIpv4, deployBy));
+            deploy(buildLog, appDeployConfig);
         }
+
+        onDeploying.remove(appId);
     }
 
     /**
@@ -82,6 +71,33 @@ public class AppDeployer {
      * @return
      * @date 2020-03-13 下午1:00
      */
-    public void deploy(BuildLog buildLog, List<AppDeployConfig> deployConfigs) {
+    public void deploy(BuildLog buildLog, AppDeployConfig appDeployConfig) throws MqttException {
+        String buildLogId = buildLog.getId();
+        String appId = buildLog.getAppId();
+        String packagePath = buildLog.getPackagePath();
+        String deployBy = buildLog.getBuildBy();
+        String commitId = buildLog.getCommitInfo().getCommitId();
+
+        String machineId = appDeployConfig.getMachineHost().getMachineId();
+        String machineIpv4 = appDeployConfig.getMachineHost().getMachineIpv4();
+        String packType = appDeployConfig.getPackType();
+        String startScript = appDeployConfig.getStartScript();
+        String startHome = appDeployConfig.getStartHome();
+        String unpackScript = appDeployConfig.getUnpackScript();
+
+        DeployParam deployParam = new DeployParam();
+        deployParam.setBuildLogId(buildLogId);
+        deployParam.setAppId(appId);
+        deployParam.setPackagePath(packagePath);
+        deployParam.setPackType(packType);
+        deployParam.setStartScript(startScript);
+        deployParam.setStartHome(startHome);
+
+        RpcMsg rpcMsg = RpcMsg.paramMsg(AppRpcClazz.class.getSimpleName(), AppRpcClazz.deploy.name(),
+                JsonConverter.objectToJson(deployParam));
+        Message message = Message.rpcParamMsg(rpcMsg);
+        // TODO 对于需要返回值的 pub,需要做一个记录,pub 和 sub 一一对应
+        String topic = MsgQueue.dagentTopic(machineId);
+        mqttClient.pubWithResult(topic, 1, message);
     }
 }

+ 2 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/BuildDeployService.java

@@ -7,11 +7,10 @@ import java.util.List;
  * @date 2021-09-17 11:30:16
  */
 public interface BuildDeployService {
-    void buildAndDeploy(String appId) throws Exception;
-    void build(String appId);
+    void buildAndDeploy(String appId, boolean isDeploy) throws Exception;
     default void build(String appId, String commitId) {
     }
-    void deploy(String buildLogId);
+    void deploy(String buildLogId, String machineId);
     void downloadPackage(String buildLogId) throws Exception;
     List<String> currentlyBuilding();
     List<String> currentlyDeploying();

+ 1 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppBuildingService.java

@@ -13,5 +13,6 @@ public interface AppBuildingService {
     void refreshBeforeBuild(String appId);
     void refreshAfterBuild(BuildLog buildLog);
     BuildLog addBuildLog(BuildLog buildLog);
+    BuildLog latestBuilding(String appId);
     void sendBuildNotify(BuildLog buildLog);
 }

+ 5 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppBuildingServiceImpl.java

@@ -7,7 +7,6 @@ import cn.reghao.autodop.dmaster.app.db.query.log.BuildLogQuery;
 import cn.reghao.autodop.dmaster.app.model.po.AppBuilding;
 import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
 import cn.reghao.autodop.dmaster.app.model.po.log.BuildLog;
-import cn.reghao.autodop.dmaster.app.service.bd.AppBuildingService;
 import cn.reghao.autodop.dmaster.rbac.UserContext;
 import org.springframework.stereotype.Service;
 
@@ -72,6 +71,11 @@ public class AppBuildingServiceImpl implements AppBuildingService {
         return buildLogCrud.save(buildLog);
     }
 
+    @Override
+    public BuildLog latestBuilding(String appId) {
+        return buildLogQuery.findLatestBuildingByAppId(appId);
+    }
+
     @Override
     public void sendBuildNotify(BuildLog buildLog) {
     }

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

@@ -69,13 +69,8 @@ public class AppDeployingServiceImpl implements AppDeployingService {
 
     @Override
     public void refreshBeforeDeploy(AppDeployConfig appDeployConfig, BuildLog buildLog) {
-        String buildLogId = buildLog.getId();
-        String commitId = buildLog.getCommitInfo().getCommitId();
-        String packagePath = buildLog.getPackagePath();
-        String deployBy = buildLog.getBuildBy();
-
         AppDeploying appDeploying = deployingQuery.findByAppDeployConfig(appDeployConfig);
-        appDeploying.beforeDeploy(buildLogId, commitId, packagePath, deployBy);
+        appDeploying.beforeDeploy(buildLog);
         deployingCrud.update(appDeploying);
     }
 

+ 27 - 18
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/impl/BuildDeployServiceImpl.java

@@ -4,6 +4,7 @@ import cn.reghao.autodop.common.mqtt.AsyncMqttClient;
 import cn.reghao.autodop.common.msg.rpc.constant.AppRpcClazz;
 import cn.reghao.autodop.common.msg.rpc.dto.app.DeployParam;
 import cn.reghao.autodop.common.msg.rpc.dto.app.PackType;
+import cn.reghao.autodop.common.util.ExceptionUtil;
 import cn.reghao.autodop.common.util.thread.ThreadPoolWrapper;
 import cn.reghao.autodop.dmaster.app.db.query.config.AppConfigQuery;
 import cn.reghao.autodop.dmaster.app.db.query.log.BuildLogQuery;
@@ -61,7 +62,7 @@ public class BuildDeployServiceImpl implements BuildDeployService {
     }
 
     @Override
-    public void buildAndDeploy(String appId) throws Exception {
+    public void buildAndDeploy(String appId, boolean isDeploy) throws Exception {
         if (!onBuilding.add(appId)) {
             return;
         }
@@ -78,38 +79,46 @@ public class BuildDeployServiceImpl implements BuildDeployService {
         buildingService.refreshBeforeBuild(appId);
         CompletableFuture.supplyAsync(supplier, threadPool)
                 .whenComplete((buildLog, throwable) -> {
-                    if (buildLog != null) {
-                        buildLog = buildingService.addBuildLog(buildLog);
-                        buildingService.refreshAfterBuild(buildLog);
-                    }
+                    try {
+                        if (buildLog != null) {
+                            buildLog = buildingService.addBuildLog(buildLog);
+                            buildingService.refreshAfterBuild(buildLog);
+                        }
 
-                    onBuilding.remove(appId);
-                    if (throwable != null) {
-                        String errMsg = throwable.getMessage();
-                        log.error("{} 构建错误: {}", appId, errMsg);
-                        return;
+                        if (throwable != null) {
+                            String errMsg = throwable.getMessage();
+                            log.error("{} 构建错误: {}", appId, errMsg);
+                            return;
+                        }
+                        log.info("{} 构建完成", appId);
+                        buildingService.sendBuildNotify(buildLog);
+                    } catch (Exception e) {
+                        log.error("构建后处理发生错误: {}", ExceptionUtil.errorMsg(e));
+                    } finally {
+                        onBuilding.remove(appId);
                     }
-                    log.info("{} 构建完成", appId);
-                    buildingService.sendBuildNotify(buildLog);
                 })
                 .thenAccept(buildLog -> {
-                    if (buildLog.getResult().getCode() == ResultStatus.SUCCESS.getCode()) {
+                    if (isDeploy && buildLog.getResult().getCode() == ResultStatus.SUCCESS.getCode()) {
                         log.info("开始部署 {}", appId);
                         try {
                             appDeployer.deploy(buildLog);
                         } catch (MqttException e) {
-                            e.printStackTrace();
+                            String errMsg = ExceptionUtil.errorMsg(e);
+                            log.error("部署 {} 时抛出异常: {}", appId, errMsg);
                         }
                     }
                 });
     }
 
     @Override
-    public void build(String appId) {
-    }
+    public void deploy(String buildLogId, String machineId) {
+        BuildLog buildLog = buildLogQuery.findById(buildLogId);
+        if (buildLog == null) {
+            return;
+        }
 
-    @Override
-    public void deploy(String buildLogId) {
+        String appId = buildLog.getAppId();
     }
 
     @Override

+ 18 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/util/buildtool/packer/ZipPack.java

@@ -5,8 +5,10 @@ import cn.reghao.autodop.common.util.compression.ZipFiles;
 import cn.reghao.autodop.dmaster.app.model.po.config.build.LocalBuildDir;
 import cn.reghao.autodop.dmaster.app.model.po.config.build.PackerConfig;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
 
 import java.io.File;
+import java.io.IOException;
 
 /**
  * @author reghao
@@ -17,10 +19,25 @@ public class ZipPack implements CodePacker {
     private final String targetPath;
     private final String binfilesDirname;
 
-    public ZipPack(PackerConfig packerConfig, String appPackDir) {
+    public ZipPack(PackerConfig packerConfig, String appPackDir) throws IOException {
         this.targetPath = packerConfig.getType().equals(PackType.zip.getName()) ?
                 appPackDir : packerConfig.getTargetPath();
         this.binfilesDirname = packerConfig.getBinfilesDirname();
+        createTargetDir(targetPath);
+    }
+
+    private void createTargetDir(String targetPath) throws IOException {
+        File dir = new File(targetPath);
+        if (dir.exists()) {
+            return;
+        }
+
+        try {
+            FileUtils.forceMkdir(new File(targetPath));
+        } catch (IOException e) {
+            String errMsg = String.format("无法创建 %s 目录", targetPath);
+            throw new IOException(errMsg);
+        }
     }
 
     @Override

+ 0 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/db/query/MongoQuery.java

@@ -3,9 +3,7 @@ package cn.reghao.autodop.dmaster.machine.db.query;
 import cn.reghao.autodop.dmaster.machine.model.po.NodeLog;
 import com.mongodb.BasicDBObject;
 import com.mongodb.client.AggregateIterable;
-import com.mongodb.client.model.Filters;
 import org.bson.Document;
-import org.bson.conversions.Bson;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.mongodb.core.MongoTemplate;
 import org.springframework.data.mongodb.core.query.Criteria;
@@ -88,7 +86,6 @@ public class MongoQuery {
         LocalDate localDate1 = localDate.plusDays(1);
         LocalDate localDate2 = LocalDate.now();
 
-
         Query query = new Query();
         query.addCriteria(Criteria.where("machineId").is(machineId));
         query.addCriteria(Criteria.where("appId").is(appId));

+ 2 - 2
dmaster/src/main/resources/static/js/main.js

@@ -114,7 +114,7 @@ layui.use(['element', 'form', 'layer', 'upload'], function () {
     /*  漂浮消息 */
     $.fn.Messager = function (result) {
         if (result.code === 0) {
-            layer.msg(result.msg, {offset: '15px', time: 3000, icon: 1});
+            layer.msg(result.msg, {offset: '15px', time: 5000, icon: 1});
             setTimeout(function () {
                 if (result.data === 'submit[refresh]') {
                     parent.location.reload();
@@ -127,7 +127,7 @@ layui.use(['element', 'form', 'layer', 'upload'], function () {
                 }
             }, 1000);
         } else {
-            layer.msg(result.msg, {offset: '15px', time: 3000, icon: 2});
+            layer.msg(result.msg, {offset: '15px', time: 5000, icon: 2});
         }
     };
 

+ 1 - 1
dmaster/src/main/resources/templates/app/bd/deploy.html

@@ -27,7 +27,7 @@
                     <td th:text="${item?.deployResult}">部署结果</td>
                     <td>
                         <a class="ajax-post"
-                           th:href="@{'/api/app/bd/deploy?appId='+${appId}+'&buildLogId='+${buildLogId}}">部署</a>
+                           th:href="@{'/api/app/bd/deploy/'+${buildLogId}+'/'+${item.machineId}}">部署</a>
                     </td>
                 </tr>
                 </tbody>

+ 2 - 2
dmaster/src/main/resources/templates/app/bd/index.html

@@ -73,8 +73,8 @@
                     <td th:text="${item.buildTime}">构建时间</td>
                     <td th:text="${item.buildBy}">构建用户</td>
                     <td>
-                        <a class="ajax-post" th:href="@{'/api/app/bd/update?appId='+${item.appId}}">更新</a>
-                        <a class="ajax-post" th:href="@{'/api/app/bd/build?appId='+${item.appId}}">构建</a>
+                        <a class="ajax-post" th:href="@{'/api/app/bd/update/'+${item.appId}}">更新</a>
+                        <a class="ajax-post" th:href="@{'/api/app/bd/build/'+${item.appId}}">构建</a>
                         <a class="ajax-get" th:href="@{'/api/app/bd/dl/'+${item.buildLogId}}">下载</a>
                         <a class="open-popup" data-title="应用部署状态" th:attr="data-url=@{'/app/bd/deploy/'+${item.appId}}"
                            data-size="1000,500" href="#">部署状态</a>