diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java index 17bfdd48..2c2de8cc 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java @@ -14,14 +14,14 @@ import com.ruoyi.platform.utils.FileUtil; import com.ruoyi.platform.utils.K8sClientUtil; import com.ruoyi.platform.vo.ImageVo; import com.ruoyi.system.api.model.LoginUser; -import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim; import io.kubernetes.client.openapi.models.V1Pod; -import lombok.Synchronized; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -42,14 +42,12 @@ import java.util.concurrent.CompletableFuture; public class ImageServiceImpl implements ImageService { @Resource private ImageDao imageDao; - + @Resource + private ImageVersionDao imageVersionDao; @Resource private ImageVersionService imageVersionService; - - @Resource - private ImageVersionDao imageVersionDao; @Resource private K8sClientUtil k8sClientUtil; @Resource @@ -359,7 +357,8 @@ public class ImageServiceImpl implements ImageService { } @Override - @Synchronized + @Async + @Transactional public String saveImage(ImageVo imageVo) { if(imageDao.getByName(imageVo.getName()) != null){ throw new IllegalStateException("镜像名称已存在"); @@ -373,10 +372,34 @@ public class ImageServiceImpl implements ImageService { String hostIp = k8sClientUtil.getHostIp(podName, namespace); dockerClientUtil.commitImage(imageVo,containerId,hostIp,username); - dockerClientUtil.pushImageToHorbor(imageVo,hostIp); + HashMap resultMap = dockerClientUtil.pushImageToHorbor(imageVo, hostIp); + + Image image = new Image(); + BeanUtils.copyProperties(imageVo,image); + image.setCreateBy(username); + image.setUpdateBy(username); + image.setUpdateTime(new Date()); + image.setCreateTime(new Date()); + image.setState(1); + imageDao.insert(image); + + ImageVersion imageVersion = new ImageVersion(); + imageVersion.setImageId(image.getId()); + imageVersion.setVersion(imageVo.getVersion()); + imageVersion.setUrl(resultMap.get("imageName")); + imageVersion.setTagName(imageVo.getTagName()); + imageVersion.setFileSize(resultMap.get("size")); + imageVersion.setCreateBy(username); + imageVersion.setUpdateBy(username); + imageVersion.setUpdateTime(new Date()); + imageVersion.setCreateTime(new Date()); + imageVersion.setState(1); + imageVersion.setStatus("available"); + imageVersionDao.insert(imageVersion); + + return "保存镜像成功"; } catch (Exception e) { - throw new RuntimeException(e); + throw new RuntimeException("保存镜像失败:" +e); } - return null; } } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/DockerClientUtil.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/DockerClientUtil.java index 15a1134c..b20fa077 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/DockerClientUtil.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/DockerClientUtil.java @@ -2,6 +2,7 @@ package com.ruoyi.platform.utils; import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.CommitCmd; +import com.github.dockerjava.api.command.InspectImageResponse; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.core.DefaultDockerClientConfig; import com.github.dockerjava.core.DockerClientConfig; @@ -14,6 +15,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.time.Duration; +import java.util.HashMap; @Slf4j @Component @@ -35,7 +37,7 @@ public class DockerClientUtil { //创建DefaultDockerClientConfig(指定docker服务器的配置) DockerClientConfig config = DefaultDockerClientConfig .createDefaultConfigBuilder() - .withDockerHost("tcp://"+ dockerServerUrl +":2375") + .withDockerHost("tcp://" + dockerServerUrl + ":2375") .withDockerTlsVerify(false) .withApiVersion("1.40") // .withDockerCertPath(dcokerCertPath) @@ -62,18 +64,16 @@ public class DockerClientUtil { public String commitImage(ImageVo imageVo, String containerId, String hostIp, String userName) { DockerClient dockerClient = getDockerClient(hostIp); -// dockerClient.startContainerCmd(containerId).exec(); // 提交容器为镜像,这里的"new_image"和"new_tag"是新镜像的名字和标签 CommitCmd commitCmd = dockerClient.commitCmd(containerId) .withRepository(imageVo.getName()) .withTag(imageVo.getTagName()) .withAuthor(userName) .withMessage(imageVo.getDescription()); - String exec = commitCmd.exec(); - return exec; + return commitCmd.exec(); } - public void pushImageToHorbor(ImageVo imageVo, String hostIp) { + public HashMap pushImageToHorbor(ImageVo imageVo, String hostIp) { DockerClient dockerClient = getDockerClient(hostIp); //Harbor登录信息 @@ -90,8 +90,19 @@ public class DockerClientUtil { dockerClient.pushImageCmd(imageName).withAuthConfig(autoConfig).start().awaitCompletion(); //push成功后,删除本地加载的镜像 dockerClient.removeImageCmd(localImageName).exec(); + + String totalImageName = imageName + ":" + imageVo.getTagName(); + InspectImageResponse exec = dockerClient.inspectImageCmd(totalImageName).exec(); + + String size = String.format("%.1f GB", (float) exec.getSize() / 1073741824.0); + + HashMap resultMap = new HashMap<>(); + resultMap.put("imageName",totalImageName); + resultMap.put("size",size); + + return resultMap; } catch (InterruptedException e) { - throw new RuntimeException("推送镜像失败:"+e); + throw new RuntimeException("推送镜像失败:" + e); } } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java index e2f1f6ac..519a5038 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java @@ -405,8 +405,8 @@ public class K8sClientUtil { // 配置卷和卷挂载 List volumeMounts = new ArrayList<>(); volumeMounts.add(new V1VolumeMount().name("workspace").mountPath(mountPath)); - volumeMounts.add(new V1VolumeMount().name("minio-pvc").mountPath("/datasets").subPath(datasetPath).readOnly(true)); - volumeMounts.add(new V1VolumeMount().name("minio-pvc").mountPath("/model").subPath(modelPath).readOnly(true)); + volumeMounts.add(new V1VolumeMount().name("minio-pvc").mountPath("/opt/data").subPath(datasetPath).readOnly(true)); + volumeMounts.add(new V1VolumeMount().name("minio-pvc").mountPath("/opt/model").subPath(modelPath).readOnly(true)); List volumes = new ArrayList<>(); volumes.add(new V1Volume().name("workspace").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName()))); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/ImageVo.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/ImageVo.java index 6ee88868..1153b579 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/ImageVo.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/ImageVo.java @@ -24,7 +24,7 @@ public class ImageVo implements Serializable { * 镜像类型 */ - @ApiModelProperty(name = "image_type") + @ApiModelProperty(name = "imageType") private Integer imageType;