Merge remote-tracking branch 'origin/dev-czh' into dev
# Conflicts: # react-ui/src/pages/Dataset/components/ResourceItem/index.less # react-ui/src/pages/Dataset/components/ResourceItem/index.tsx
This commit is contained in:
commit
c80f965e7b
|
@ -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: '';
|
||||
}
|
||||
}
|
|
@ -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 (
|
||||
<div className={styles['resource-item']} onClick={() => onClick(item)}>
|
||||
<Flex justify="space-between" align="center" style={{ marginBottom: '20px', height: '32px' }}>
|
||||
<Typography.Paragraph
|
||||
className={styles['resource-item__name']}
|
||||
ellipsis={{ tooltip: item.name }}
|
||||
>
|
||||
{item.name}
|
||||
</Typography.Paragraph>
|
||||
{!isPublic && (
|
||||
<Button
|
||||
type="text"
|
||||
shape="circle"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onRemove(item);
|
||||
}}
|
||||
>
|
||||
<KFIcon type="icon-shanchu" font={17} />
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
<div className={styles['resource-item__description']}>{item.description}</div>
|
||||
<Flex justify="space-between">
|
||||
<div className={styles['resource-item__time']}>
|
||||
<img style={{ width: '17px', marginRight: '6px' }} src={creatByImg} alt="" />
|
||||
<span>{item.create_by}</span>
|
||||
</div>
|
||||
<div className={styles['resource-item__time']}>
|
||||
<img style={{ width: '12px', marginRight: '5px' }} src={clock} alt="" />
|
||||
<span>最近更新: {formatDate(item.update_time, 'YYYY-MM-DD')}</span>
|
||||
</div>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ResourceItem;
|
|
@ -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<ImageVersion> 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<String, String> 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<String, String> 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<ImageVersion> 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<String, String> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,4 +106,9 @@ public class DockerClientUtil {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public void removeImage(String imageName, String hostIp){
|
||||
DockerClient dockerClient = getDockerClient(hostIp);
|
||||
dockerClient.removeImageCmd(imageName).withForce(true).exec();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue