diff --git a/react-ui/src/pages/Dataset/components/ResourceItem/index.less b/react-ui/src/pages/Dataset/components/ResourceItem/index.less
deleted file mode 100644
index edd97f85..00000000
--- a/react-ui/src/pages/Dataset/components/ResourceItem/index.less
+++ /dev/null
@@ -1,61 +0,0 @@
-.resource-item {
- position: relative;
- width: calc(25% - 15px);
- padding: 20px;
- background: white;
- border: 1px solid #eaeaea;
- border-radius: 4px;
- cursor: pointer;
-
- @media screen and (max-width: 1860px) {
- & {
- width: calc(33.33% - 13.33px);
- }
- }
-
- &__name {
- position: relative;
- display: inline-block;
- height: 24px;
- margin: 0 10px 0 0 !important;
- color: @text-color;
- font-size: 16px;
- }
-
- &__description {
- height: 44px;
- margin-bottom: 20px;
- color: @text-color-secondary;
- font-size: 14px;
- .multiLine(2);
- }
- &__time {
- display: flex;
- flex: 0 1 content;
- align-items: center;
- width: 100%;
- color: #808080;
- font-size: 13px;
- }
-
- &:hover {
- border-color: @primary-color;
- box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.1);
-
- .resource-item__name {
- color: @primary-color;
- }
- }
-}
-
-.resource-item__name {
- &::after {
- position: absolute;
- top: 14px;
- left: 0;
- width: 100%;
- height: 6px;
- background: linear-gradient(to right, rgba(22, 100, 255, 0.3) 0, rgba(22, 100, 255, 0) 100%);
- content: '';
- }
-}
diff --git a/react-ui/src/pages/Dataset/components/ResourceItem/index.tsx b/react-ui/src/pages/Dataset/components/ResourceItem/index.tsx
deleted file mode 100644
index 3b517184..00000000
--- a/react-ui/src/pages/Dataset/components/ResourceItem/index.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import clock from '@/assets/img/clock.png';
-import creatByImg from '@/assets/img/creatBy.png';
-import KFIcon from '@/components/KFIcon';
-import { formatDate } from '@/utils/date';
-import { Button, Flex, Typography } from 'antd';
-import { ResourceData } from '../../config';
-import styles from './index.less';
-
-type ResourceItemProps = {
- item: ResourceData;
- isPublic: boolean;
- onRemove: (item: ResourceData) => void;
- onClick: (item: ResourceData) => void;
-};
-
-function ResourceItem({ item, isPublic, onClick, onRemove }: ResourceItemProps) {
- return (
-
onClick(item)}>
-
-
- {item.name}
-
- {!isPublic && (
-
- )}
-
-
{item.description}
-
-
-

-
{item.create_by}
-
-
-

-
最近更新: {formatDate(item.update_time, 'YYYY-MM-DD')}
-
-
-
- );
-}
-
-export default ResourceItem;
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 b13c414d..591628a9 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
@@ -32,6 +32,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -85,6 +86,7 @@ public class ImageServiceImpl implements ImageService {
private String pvcName;
@Value("${jupyter.namespace}")
private String namespace;
+
/**
* 通过ID查询单条数据
*
@@ -99,8 +101,8 @@ public class ImageServiceImpl implements ImageService {
/**
* 分页查询
*
- * @param image 筛选条件
- * @param pageRequest 分页对象
+ * @param image 筛选条件
+ * @param pageRequest 分页对象
* @return 查询结果
*/
@Override
@@ -110,7 +112,6 @@ public class ImageServiceImpl implements ImageService {
}
-
/**
* 新增数据
*
@@ -138,7 +139,7 @@ public class ImageServiceImpl implements ImageService {
@Override
public Image update(Image image) {
int currentState = image.getState();
- if(currentState == 0){
+ if (currentState == 0) {
throw new RuntimeException("镜像已被删除,无法更新。");
}
LoginUser loginUser = SecurityUtils.getLoginUser();
@@ -163,7 +164,7 @@ public class ImageServiceImpl implements ImageService {
@Override
public String removeById(Integer id) throws Exception {
Image image = this.imageDao.queryById(id);
- if (image == null){
+ if (image == null) {
throw new Exception("镜像不存在");
}
@@ -173,14 +174,20 @@ public class ImageServiceImpl implements ImageService {
String createdBy = image.getCreateBy();
- if (!(StringUtils.equals(username,"admin") || !StringUtils.equals(username,createdBy))){
+ if (!(StringUtils.equals(username, "admin") || !StringUtils.equals(username, createdBy))) {
throw new Exception("无权限删除该镜像");
}
- if (!imageVersionService.queryByImageId(id).isEmpty()){
- throw new Exception("请先删除该镜像下的版本文件");
+// if (!imageVersionService.queryByImageId(id).isEmpty()){
+// throw new Exception("请先删除该镜像下的版本文件");
+// }
+ List imageVersions = imageVersionService.queryByImageId(id);
+
+ for (ImageVersion imageVersion : imageVersions) {
+ dockerClientUtil.removeImage(imageVersion.getUrl(), imageVersion.getHostIp());
}
+
image.setState(0);
- return this.imageDao.update(image)>0?"删除成功":"删除失败";
+ return this.imageDao.update(image) > 0 ? "删除成功" : "删除失败";
}
@@ -207,7 +214,7 @@ public class ImageServiceImpl implements ImageService {
public String insertImageAndVersion(ImageVo imageVo) throws Exception {
Image existingImage = getByName(imageVo.getName());
Image imageToUse;
- if(existingImage == null) {
+ if (existingImage == null) {
// 如果不存在相同名称的镜像,则创建新的镜像记录
Image newImage = new Image();
newImage.setName(imageVo.getName());
@@ -217,7 +224,7 @@ public class ImageServiceImpl implements ImageService {
if (imageToUse == null) {
throw new Exception("新增镜像失败");
}
- }else{
+ } else {
// 如果已存在相同名称的镜像,使用已存在的镜像
imageToUse = existingImage;
}
@@ -235,9 +242,9 @@ public class ImageServiceImpl implements ImageService {
CompletableFuture.supplyAsync(() -> {
Map resultMap = new HashMap<>();
try {
- if(imageVo.getUploadType()==0){
- resultMap = createImageFromNet(imageVo.getName(), imageVo.getTagName(), imageVo.getPath());
- }else{
+ if (imageVo.getUploadType() == 0) {
+ resultMap = createImageFromNet(imageVo.getName(), imageVo.getTagName(), imageVo.getPath());
+ } else {
resultMap = createImageFromLocal(imageVo.getName(), imageVo.getTagName(), imageVo.getPath());
}
} catch (Exception e) {
@@ -246,7 +253,7 @@ public class ImageServiceImpl implements ImageService {
throw new RuntimeException("镜像构建失败: " + e.getMessage(), e);
}
return resultMap;
- }).thenAccept(resultMap ->{
+ }).thenAccept(resultMap -> {
try {
String imageUrl = resultMap.get("url");
String fileSize = resultMap.get("fileSize");
@@ -272,27 +279,27 @@ public class ImageServiceImpl implements ImageService {
// 得到容器
V1Pod pod = k8sClientUtil.getNSPodList(serviceNS, deploymentName);
if (pod == null) {
- String podName = deploymentName+"-"+ DateUtils.formatYMD10(new Date());
- pod = k8sClientUtil.createPodWithEnv(podName,serviceNS,proxyUrl,mountPath,pvcName,image);
+ String podName = deploymentName + "-" + DateUtils.formatYMD10(new Date());
+ pod = k8sClientUtil.createPodWithEnv(podName, serviceNS, proxyUrl, mountPath, pvcName, image);
}
- String loginCmd = "docker login -u " + harborUser +" -p "+harborpassword+" "+harborUrl;
+ String loginCmd = "docker login -u " + harborUser + " -p " + harborpassword + " " + harborUrl;
// 执行命令 docker login -u admin -p Harbor12345 172.20.32.187
- String loginlog = k8sClientUtil.executeCommand(pod,loginCmd);
+ String loginlog = k8sClientUtil.executeCommand(pod, loginCmd);
// 在这个容器的/data/admin 目录下执行命令 docker load -i fileName 得到返回的镜像名字name:tag
String username = SecurityUtils.getLoginUser().getUsername();
//
- String logs2 = k8sClientUtil.executeCommand(pod,"docker pull "+ netPath);
+ String logs2 = k8sClientUtil.executeCommand(pod, "docker pull " + netPath);
// 在容器里执行 docker tag name:tag nexus3.kube-system.svc:8083/imageName:imageTag
- if (StringUtils.isNoneBlank(logs2)){
+ if (StringUtils.isNoneBlank(logs2)) {
String[] lines = logs2.split("\n");
String lastLine = lines[lines.length - 1].trim();
String tagCmd = "docker tag " + lastLine + " " + harborUrl + "/" + repository + "/" + username + "/" + imageName + ":" + imageTag;
String imageUrl = harborUrl + "/" + repository + "/" + username + "/" + imageName + ":" + imageTag;
- String pushCmd = "docker push " + imageUrl;
+ String pushCmd = "docker push " + imageUrl;
String sizeCmd = "docker inspect --format='{{.Size}}' " + imageUrl;
String s = k8sClientUtil.executeCommand(pod, tagCmd);
- if (StringUtils.isNotEmpty(k8sClientUtil.executeCommand(pod, pushCmd))){
+ if (StringUtils.isNotEmpty(k8sClientUtil.executeCommand(pod, pushCmd))) {
resultMap.put("url", imageUrl);
//得到镜像文件大小
String imageSizeStr = k8sClientUtil.executeCommand(pod, sizeCmd);
@@ -301,10 +308,10 @@ public class ImageServiceImpl implements ImageService {
resultMap.put("fileSize", formattedImageSize);
return resultMap;
- }else {
+ } else {
throw new Exception("拉取公网镜像失败,请检查网络或者镜像地址");
}
- }else {
+ } else {
throw new Exception("拉取公网镜像失败,请检查网络或者镜像地址");
}
}
@@ -315,27 +322,27 @@ public class ImageServiceImpl implements ImageService {
// 得到容器
V1Pod pod = k8sClientUtil.getNSPodList(serviceNS, deploymentName);
if (pod == null) {
- String podName = deploymentName+"-"+ DateUtils.formatYMD10(new Date());
- pod = k8sClientUtil.createPodWithEnv(podName,serviceNS,proxyUrl,mountPath,pvcName,image);
+ String podName = deploymentName + "-" + DateUtils.formatYMD10(new Date());
+ pod = k8sClientUtil.createPodWithEnv(podName, serviceNS, proxyUrl, mountPath, pvcName, image);
}
- String loginCmd = "docker login -u " + harborUser +" -p "+harborpassword+" "+harborUrl;
+ String loginCmd = "docker login -u " + harborUser + " -p " + harborpassword + " " + harborUrl;
// 执行命令 docker login -u admin -p Harbor12345 172.20.32.187
- String loginlog = k8sClientUtil.executeCommand(pod,loginCmd);
+ String loginlog = k8sClientUtil.executeCommand(pod, loginCmd);
// 在这个容器的/data/admin 目录下执行命令 docker load -i fileName 得到返回的镜像名字name:tag
String username = SecurityUtils.getLoginUser().getUsername();
//
- String filePath = "/data/argo-workflow/" + bucketName + "/" +path;
- String logs2 = k8sClientUtil.executeCommand(pod,"docker load -i "+filePath);
+ String filePath = "/data/argo-workflow/" + bucketName + "/" + path;
+ String logs2 = k8sClientUtil.executeCommand(pod, "docker load -i " + filePath);
// 在容器里执行 docker tag name:tag nexus3.kube-system.svc:8083/imageName:imageTag
- if (StringUtils.isNoneBlank(logs2)){
- String substring = logs2.substring(logs2.indexOf(":")+1).trim();
+ if (StringUtils.isNoneBlank(logs2)) {
+ String substring = logs2.substring(logs2.indexOf(":") + 1).trim();
String tagCmd = "docker tag " + substring + " " + harborUrl + "/" + repository + "/" + username + "/" + imageName + ":" + imageTag;
String imageUrl = harborUrl + "/" + repository + "/" + username + "/" + imageName + ":" + imageTag;
- String pushCmd = "docker push " + imageUrl;
+ String pushCmd = "docker push " + imageUrl;
String sizeCmd = "docker inspect --format='{{.Size}}' " + imageUrl;
String s = k8sClientUtil.executeCommand(pod, tagCmd);
- if (StringUtils.isNotEmpty(k8sClientUtil.executeCommand(pod, pushCmd))){
+ if (StringUtils.isNotEmpty(k8sClientUtil.executeCommand(pod, pushCmd))) {
resultMap.put("url", imageUrl);
//得到镜像文件大小
String imageSizeStr = k8sClientUtil.executeCommand(pod, sizeCmd);
@@ -343,43 +350,49 @@ public class ImageServiceImpl implements ImageService {
String formattedImageSize = FileUtil.formatFileSize(sizeInBytes); // 格式化镜像文件大小
resultMap.put("fileSize", formattedImageSize);
return resultMap;
- }else {
+ } else {
throw new Exception("解析镜像压缩包失败,请检查镜像文件");
}
- }else {
+ } else {
throw new Exception("解析镜像压缩包失败,请检查镜像文件");
}
}
-
-
@Override
public Map uploadImageFiles(MultipartFile file) throws Exception {
LoginUser loginUser = SecurityUtils.getLoginUser();
- String path = loginUser.getUsername()+"/"+file.getOriginalFilename();
+ String path = loginUser.getUsername() + "/" + file.getOriginalFilename();
return minioService.uploadFile(bucketName, path, file);
}
@Override
@Transactional
+ @Async
public String saveImage(ImageVo imageVo) {
- if(imageDao.getByName(imageVo.getName()) != null){
- throw new IllegalStateException("镜像名称已存在");
+ Image oldImage = imageDao.getByName(imageVo.getName());
+ if (oldImage != null) {
+ List oldImageVersions = imageVersionDao.queryByImageId(oldImage.getId());
+ for (ImageVersion oldImageVersion : oldImageVersions) {
+ if(oldImageVersion.getTagName().equals(imageVo.getTagName())){
+ throw new IllegalStateException("镜像tag不能重复");
+ }
+ }
}
+
LoginUser loginUser = SecurityUtils.getLoginUser();
String username = loginUser.getUsername().toLowerCase();
- String podName = username +"-editor-pod" + "-" + imageVo.getDevEnvironmentId().toString();
+ String podName = username + "-editor-pod" + "-" + imageVo.getDevEnvironmentId().toString();
try {
String containerId = k8sClientUtil.getPodContainerId(podName, namespace);
String hostIp = k8sClientUtil.getHostIp(podName, namespace);
- dockerClientUtil.commitImage(imageVo,containerId,hostIp,username);
+ dockerClientUtil.commitImage(imageVo, containerId, hostIp, username);
HashMap resultMap = dockerClientUtil.pushImageToHorbor(imageVo, hostIp);
Image image = new Image();
- BeanUtils.copyProperties(imageVo,image);
+ BeanUtils.copyProperties(imageVo, image);
image.setImageType(Constant.Image_Type_Pri);
image.setCreateBy(username);
image.setUpdateBy(username);
@@ -396,6 +409,7 @@ public class ImageServiceImpl implements ImageService {
imageVersion.setFileSize(resultMap.get("size"));
imageVersion.setCreateBy(username);
imageVersion.setUpdateBy(username);
+ imageVersion.setHostIp(hostIp);
imageVersion.setUpdateTime(new Date());
imageVersion.setCreateTime(new Date());
imageVersion.setState(1);
@@ -410,7 +424,7 @@ public class ImageServiceImpl implements ImageService {
return "保存镜像成功";
} catch (Exception e) {
- throw new RuntimeException("保存镜像失败:" +e);
+ throw new RuntimeException("保存镜像失败:" + e);
}
}
}
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 b20fa077..552b025a 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
@@ -106,4 +106,9 @@ public class DockerClientUtil {
}
}
+
+ public void removeImage(String imageName, String hostIp){
+ DockerClient dockerClient = getDockerClient(hostIp);
+ dockerClient.removeImageCmd(imageName).withForce(true).exec();
+ }
}
\ No newline at end of file