Ver Fonte

更新 DockerController 接口和实现

reghao há 3 meses atrás
pai
commit
f2f5e8312d

+ 0 - 33
web/src/main/java/cn/reghao/bnt/web/devops/build/service/DockerService.java

@@ -1,33 +0,0 @@
-package cn.reghao.bnt.web.devops.build.service;
-
-import cn.reghao.bnt.common.docker.DockerImpl;
-import cn.reghao.bnt.web.devops.build.model.vo.DockerContainer;
-import cn.reghao.bnt.web.devops.build.model.vo.DockerImage;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * @author reghao
- * @date 2025-12-09 11:01:17
- */
-@Service
-public class DockerService {
-    private final DockerImpl docker = new DockerImpl();
-
-    public List<DockerImage> getDockerImages() {
-        return docker.images().stream().map(DockerImage::new).collect(Collectors.toList());
-    }
-
-    public void rmDockerImage(String imageId) {
-        docker.imageRm(imageId);
-    }
-
-    public List<DockerContainer> getDockerContainers() {
-        return docker.psAll().stream().map(DockerContainer::new).collect(Collectors.toList());
-    }
-
-    public void rmDockerContainer(String containerId) {
-    }
-}

+ 20 - 10
web/src/main/java/cn/reghao/bnt/web/devops/build/controller/DockerController.java → web/src/main/java/cn/reghao/bnt/web/devops/machine/controller/DockerController.java

@@ -1,12 +1,16 @@
-package cn.reghao.bnt.web.devops.build.controller;
+package cn.reghao.bnt.web.devops.machine.controller;
 
-import cn.reghao.bnt.web.devops.build.model.vo.DockerContainer;
-import cn.reghao.bnt.web.devops.build.model.vo.DockerImage;
-import cn.reghao.bnt.web.devops.build.service.DockerService;
+import cn.reghao.bnt.web.devops.machine.model.vo.DockerContainer;
+import cn.reghao.bnt.web.devops.machine.model.vo.DockerImage;
+import cn.reghao.bnt.web.devops.machine.service.DockerService;
+import cn.reghao.bnt.web.devops.machine.model.dto.ContainerOps;
+import cn.reghao.bnt.web.devops.machine.model.dto.ImageDelete;
+import cn.reghao.bnt.web.devops.machine.model.dto.ImageQuery;
 import cn.reghao.jutil.web.WebResult;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -17,7 +21,7 @@ import java.util.List;
  */
 @Tag(name = "Docker 仓库接口")
 @RestController
-@RequestMapping("/api/devops/build/docker")
+@RequestMapping("/api/devops/machine/docker")
 public class DockerController {
     private final DockerService dockerService;
 
@@ -27,16 +31,15 @@ public class DockerController {
 
     @Operation(summary = "获取 docker 镜像列表", description = "N")
     @GetMapping(value = "/image/list", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String getDockerImage() {
-        List<DockerImage> list = dockerService.getDockerImages();
+    public String getDockerImage(ImageQuery imageQuery) {
+        List<DockerImage> list = dockerService.getDockerImages(imageQuery);
         return WebResult.success(list);
     }
 
     @Operation(summary = "删除 docker 镜像", description = "N")
     @PostMapping(value = "/image/delete", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String deleteDockerImage(String imageId) {
-        dockerService.rmDockerImage(imageId);
-        //dockerService.rmDockerContainer(imageId);
+    public String deleteDockerImage(@Validated ImageDelete imageDelete) {
+        dockerService.rmDockerImages(imageDelete);
         return WebResult.success();
     }
 
@@ -46,4 +49,11 @@ public class DockerController {
         List<DockerContainer> list = dockerService.getDockerContainers();
         return WebResult.success(list);
     }
+
+    @Operation(summary = "删除 docker 容器", description = "N")
+    @PostMapping(value = "/container/ops", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String opsDockerConatiner(ContainerOps containerOps) {
+        dockerService.handleDockerContainer(containerOps);
+        return WebResult.success();
+    }
 }

+ 20 - 0
web/src/main/java/cn/reghao/bnt/web/devops/machine/model/dto/ContainerOps.java

@@ -0,0 +1,20 @@
+package cn.reghao.bnt.web.devops.machine.model.dto;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author reghao
+ * @date 2025-12-16 16:03:13
+ */
+@Setter
+@Getter
+public class ContainerOps {
+    @NotNull(message = "操作类型不能为空")
+    private Integer opsType;
+    @NotBlank(message = "容器ID不能为空")
+    @NotNull(message = "容器ID不能为空")
+    private String containerId;
+}

+ 19 - 0
web/src/main/java/cn/reghao/bnt/web/devops/machine/model/dto/ImageDelete.java

@@ -0,0 +1,19 @@
+package cn.reghao.bnt.web.devops.machine.model.dto;
+
+import jakarta.validation.constraints.Size;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2025-12-16 15:20:24
+ */
+@Setter
+@Getter
+public class ImageDelete {
+    private String machineId;
+    @Size(min = 1, max = 10, message = "删除镜像数量范围在 1~10 之间")
+    private List<String> imageIds;
+}

+ 15 - 0
web/src/main/java/cn/reghao/bnt/web/devops/machine/model/dto/ImageQuery.java

@@ -0,0 +1,15 @@
+package cn.reghao.bnt.web.devops.machine.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author reghao
+ * @date 2025-12-16 14:47:01
+ */
+@Setter
+@Getter
+public class ImageQuery {
+    private int type;
+    private String keyword;
+}

+ 9 - 4
web/src/main/java/cn/reghao/bnt/web/devops/build/model/vo/DockerContainer.java → web/src/main/java/cn/reghao/bnt/web/devops/machine/model/vo/DockerContainer.java

@@ -1,23 +1,28 @@
-package cn.reghao.bnt.web.devops.build.model.vo;
+package cn.reghao.bnt.web.devops.machine.model.vo;
 
+import cn.reghao.jutil.jdk.converter.DateTimeConverter;
 import com.github.dockerjava.api.command.InspectContainerResponse;
+import lombok.Getter;
 
 /**
  * @author reghao
  * @date 2025-12-09 11:01:46
  */
+@Getter
 public class DockerContainer {
     private String containerId;
     private String name;
-    private String imageId;
     private String createdAt;
     private String status;
+    private String imageId;
+    private String repoTag;
 
-    public DockerContainer(InspectContainerResponse inspectContainerResponse) {
+    public DockerContainer(InspectContainerResponse inspectContainerResponse,String repoTag) {
         this.containerId = inspectContainerResponse.getId();
         this.name = inspectContainerResponse.getName();
         this.imageId = inspectContainerResponse.getImageId();
-        this.createdAt = inspectContainerResponse.getCreated();
+        this.createdAt = DateTimeConverter.format(inspectContainerResponse.getCreated());
         this.status = inspectContainerResponse.getState().getStatus();
+        this.repoTag = repoTag;
     }
 }

+ 7 - 3
web/src/main/java/cn/reghao/bnt/web/devops/build/model/vo/DockerImage.java → web/src/main/java/cn/reghao/bnt/web/devops/machine/model/vo/DockerImage.java

@@ -1,8 +1,10 @@
-package cn.reghao.bnt.web.devops.build.model.vo;
+package cn.reghao.bnt.web.devops.machine.model.vo;
 
 import cn.reghao.jutil.jdk.converter.DateTimeConverter;
 import com.github.dockerjava.api.model.Image;
 
+import java.util.List;
+
 /**
  * @author reghao
  * @date 2025-12-09 11:01:37
@@ -11,10 +13,12 @@ public class DockerImage {
     private String imageId;
     private String repoTag;
     private String createdAt;
+    private int totalContainers;
 
-    public DockerImage(Image image) {
+    public DockerImage(Image image, String repoTag, int totalContainers) {
         this.imageId = image.getId();
-        this.repoTag = image.getRepoTags().length > 0 ? image.getRepoTags()[0] : "<none>:<none>";
+        this.repoTag = repoTag;
         this.createdAt = DateTimeConverter.format(image.getCreated()*1000);
+        this.totalContainers = totalContainers;
     }
 }

+ 105 - 0
web/src/main/java/cn/reghao/bnt/web/devops/machine/service/DockerService.java

@@ -0,0 +1,105 @@
+package cn.reghao.bnt.web.devops.machine.service;
+
+import cn.reghao.bnt.common.docker.DockerImpl;
+import cn.reghao.bnt.web.devops.machine.model.vo.DockerContainer;
+import cn.reghao.bnt.web.devops.machine.model.vo.DockerImage;
+import cn.reghao.bnt.web.devops.machine.model.dto.ContainerOps;
+import cn.reghao.bnt.web.devops.machine.model.dto.ImageDelete;
+import cn.reghao.bnt.web.devops.machine.model.dto.ImageQuery;
+import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.github.dockerjava.api.model.Image;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @author reghao
+ * @date 2025-12-09 11:01:17
+ */
+@Slf4j
+@Service
+public class DockerService {
+    private final DockerImpl docker = new DockerImpl();
+
+    public List<DockerImage> getDockerImages(ImageQuery imageQuery) {
+        String keyword = imageQuery.getKeyword();
+        int type = imageQuery.getType();
+        // imageId -> container
+        Map<String, List<InspectContainerResponse>> containerMap = docker.psAll().stream()
+                .collect(Collectors.groupingBy(InspectContainerResponse::getImageId));
+        return docker.images().stream()
+                .map(image -> {
+                    String repoTag = image.getRepoTags().length > 0 ? image.getRepoTags()[0] : "<none>:<none>";
+                    boolean matched = false;
+                    if (keyword != null && !keyword.isBlank()) {
+                        if (type == 1) {
+                            // 关键字匹配
+                            matched = repoTag.contains(keyword);
+                        } else if (type == 2) {
+                            // 前缀匹配
+                            matched = repoTag.startsWith(keyword);
+                        }
+
+                        if (!matched) {
+                            return null;
+                        }
+                    }
+
+                    int totalContainers = 0;
+                    String imageId = image.getId();
+                    List<InspectContainerResponse> list = containerMap.get(imageId);
+                    if (list != null) {
+                        totalContainers = list.size();
+                    }
+                    return new DockerImage(image, repoTag, totalContainers);
+                })
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    public void rmDockerImages(ImageDelete imageDelete) {
+        List<String> imageIds = imageDelete.getImageIds();
+        imageIds.forEach(docker::imageRm);
+    }
+
+    public List<DockerContainer> getDockerContainers() {
+        Map<String, Image> imageMap = docker.images().stream()
+                .collect(Collectors.toMap(Image::getId, v -> v));
+        return docker.psAll().stream().map(inspectContainerResponse -> {
+            String imageId = inspectContainerResponse.getImageId();
+            Image image = imageMap.get(imageId);
+            String repoTag = image.getRepoTags().length > 0 ? image.getRepoTags()[0] : "<none>:<none>";
+            return new DockerContainer(inspectContainerResponse, repoTag);
+        }).collect(Collectors.toList());
+    }
+
+    public void handleDockerContainer(ContainerOps containerOps) {
+        int type = containerOps.getOpsType();
+        String containerId = containerOps.getContainerId();
+        // containerId -> InspectContainerResponse
+        Map<String, InspectContainerResponse> containerMap = docker.psAll().stream()
+                .collect(Collectors.groupingBy(
+                        InspectContainerResponse::getId,
+                        Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))
+                ));
+
+        InspectContainerResponse response = containerMap.get(containerId);
+        if (response == null) {
+            log.error("containerId {} not exist", containerId);
+            return;
+        }
+
+        String containerName = response.getName().replace("/", "");
+        if (type == 1) {
+            docker.start(containerName);
+        } else if (type == 2) {
+            docker.stop(containerName);
+        } else if (type == 3) {
+            docker.rm(containerId);
+        }
+    }
+}