上传镜像到目标主机功能
This commit is contained in:
parent
6d6c2c8f58
commit
cb22cd43c6
@ -27,6 +27,10 @@
|
||||
<groupId>cd.casic.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cd.casic.boot</groupId>
|
||||
<artifactId>module-ci-machine</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.docker-java</groupId>
|
||||
<artifactId>docker-java</artifactId>
|
||||
@ -61,6 +65,10 @@
|
||||
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jsch</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -7,6 +7,8 @@ import cd.casic.module.execute.docker.dataobject.model.DockerImage;
|
||||
import cd.casic.module.execute.docker.dataobject.vo.DockerImagePageReqVO;
|
||||
import cd.casic.module.execute.docker.service.IImageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
@ -47,4 +49,14 @@ public class DockerImageController {
|
||||
return success(imageService.getLocalImagePage(pageVO));
|
||||
}
|
||||
|
||||
@GetMapping("/localImagePush")
|
||||
@Operation(summary = "镜像推送,或者部署到目标服务器")
|
||||
@Parameters({
|
||||
@Parameter(name = "imageId", description = "镜像id"),
|
||||
@Parameter(name = "machineId", description = "主机id")
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('docker:images:localImagePush')")
|
||||
public CommonResult localImagePush(@RequestParam(value = "imageId") String imageId, @RequestParam("machineId") String machineId) {
|
||||
return success(imageService.localImagePush(imageId,machineId));
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
package cd.casic.module.execute.docker.dataobject.convert;
|
||||
|
||||
import cd.casic.module.execute.docker.dataobject.dto.DockerImageDo;
|
||||
import cd.casic.module.execute.docker.dataobject.model.DockerImage;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Yuru Pu
|
||||
* @version 1.0
|
||||
* @since 2025/7/23 17:16
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface DockerImageConvert {
|
||||
DockerImageConvert INSTANCE = Mappers.getMapper(DockerImageConvert.class);
|
||||
|
||||
DockerImageDo convert(DockerImage dockerImage);
|
||||
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
package cd.casic.module.execute.docker.dataobject.model;
|
||||
|
||||
import cd.casic.framework.commons.dataobject.BaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 本地镜像
|
||||
@ -12,8 +10,7 @@ import lombok.experimental.Accessors;
|
||||
* @since 2025/7/23 16:22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DockerImage extends BaseDO {
|
||||
public class DockerImage {
|
||||
|
||||
private String id;
|
||||
|
||||
|
@ -109,4 +109,6 @@ public interface IImageService {
|
||||
int localImageUpload(DockerImage dockerImage);
|
||||
|
||||
PageResult<DockerImageDo> getLocalImagePage(DockerImagePageReqVO pageVO);
|
||||
|
||||
Object localImagePush(String imageId, String machineId);
|
||||
}
|
||||
|
@ -1,22 +1,33 @@
|
||||
package cd.casic.module.execute.docker.service.impl;
|
||||
|
||||
import cd.casic.ci.commons.properties.TargetFileUploadProperties;
|
||||
import cd.casic.framework.commons.pojo.PageResult;
|
||||
import cd.casic.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cd.casic.module.execute.docker.DockerClientFactory;
|
||||
import cd.casic.module.execute.docker.dao.DockerImageDao;
|
||||
import cd.casic.module.execute.docker.dataobject.convert.DockerImageConvert;
|
||||
import cd.casic.module.execute.docker.dataobject.dto.DockerImageDo;
|
||||
import cd.casic.module.execute.docker.dataobject.model.DockerImage;
|
||||
import cd.casic.module.execute.docker.dataobject.vo.DockerImagePageReqVO;
|
||||
import cd.casic.module.execute.docker.service.IImageService;
|
||||
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
||||
import cd.casic.module.machine.dal.dataobject.SecretKeyDO;
|
||||
import cd.casic.module.machine.dal.mysql.MachineInfoMapper;
|
||||
import cd.casic.module.machine.dal.mysql.SecretKeyMapper;
|
||||
import cd.casic.module.machine.enums.AuthenticationType;
|
||||
import cd.casic.module.machine.utils.CryptogramUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.extra.ftp.FtpConfig;
|
||||
import cn.hutool.extra.ssh.JschUtil;
|
||||
import cn.hutool.extra.ssh.Sftp;
|
||||
import com.github.dockerjava.api.DockerClient;
|
||||
import com.github.dockerjava.api.command.InspectImageResponse;
|
||||
import com.github.dockerjava.api.command.SaveImageCmd;
|
||||
import com.github.dockerjava.api.exception.NotFoundException;
|
||||
import com.github.dockerjava.api.model.Image;
|
||||
import com.github.dockerjava.api.model.PruneType;
|
||||
import com.jcraft.jsch.Session;
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -24,11 +35,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @description: 镜像的服务类
|
||||
@ -46,6 +57,15 @@ public class ImageService implements IImageService {
|
||||
@Resource
|
||||
private DockerImageDao dockerImageDao;
|
||||
|
||||
@Resource
|
||||
private MachineInfoMapper machineInfoMapper;
|
||||
|
||||
@Resource
|
||||
private TargetFileUploadProperties fileUploadProperties;
|
||||
|
||||
@Resource
|
||||
private SecretKeyMapper secretKeyMapper;
|
||||
|
||||
@Override
|
||||
public List<Image> list(@Nonnull String clientId) {
|
||||
DockerClient dockerClient = dockerClientFactory.getdockerClient(clientId);
|
||||
@ -144,7 +164,9 @@ public class ImageService implements IImageService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public int localImageUpload(DockerImage dockerImage) {
|
||||
return dockerImageDao.insert(DockerImageConvert.INSTANCE.convert(dockerImage));
|
||||
DockerImageDo imageDo = new DockerImageDo();
|
||||
BeanUtil.copyProperties(dockerImage,imageDo);
|
||||
return dockerImageDao.insert(imageDo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -153,4 +175,59 @@ public class ImageService implements IImageService {
|
||||
PageResult<DockerImageDo> page = dockerImageDao.selectPage(pageVO, queryWrapperX.likeIfPresent(DockerImageDo::getName, pageVO.getName()).orderByDesc(DockerImageDo::getCreateTime));
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 先下载后上传到目标主机
|
||||
* @param imageId
|
||||
* @param machineId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Object localImagePush(String imageId, String machineId) {
|
||||
if (Objects.isNull(imageId) || Objects.isNull(machineId)) {
|
||||
return null;
|
||||
}
|
||||
DockerImageDo imageDo = dockerImageDao.selectById(imageId);
|
||||
//1 远程下载
|
||||
// 1.1 建立连接 下载
|
||||
Sftp sftp = getSftp(FtpConfig.create().setHost(fileUploadProperties.getRemoteHost()).setPort(fileUploadProperties.getRemotePort()).setUser(fileUploadProperties.getUsername()).setPassword(fileUploadProperties.getPassword()));
|
||||
String srcPath = imageDo.getPath();
|
||||
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
|
||||
sftp.download(srcPath, byteOut); //远程下载到中间缓存区
|
||||
sftp.close();
|
||||
// 2 建立连接 区分密码还是秘钥
|
||||
MachineInfoDO machineInfoDO = machineInfoMapper.selectById(machineId);
|
||||
FtpConfig targetFtp = FtpConfig.create().setHost(machineInfoDO.getHostIp()).setPort(machineInfoDO.getSshPort()).setUser(machineInfoDO.getUsername()).setPassword(CryptogramUtil.doDecrypt(machineInfoDO.getPassword()));
|
||||
if (AuthenticationType.of(machineInfoDO.getAuthenticationType()).equals(AuthenticationType.SECRET_KEY)) {
|
||||
SecretKeyDO secretKeyDO = secretKeyMapper.selectById(machineInfoDO.getSecretKeyId());
|
||||
targetFtp.setSystemKey(CryptogramUtil.doDecrypt(secretKeyDO.getPrivateKey()));
|
||||
targetFtp.setPassword(CryptogramUtil.doDecrypt(secretKeyDO.getPassword()));
|
||||
}
|
||||
Sftp uploadSftp = getSftp(targetFtp);
|
||||
// 2.1 上传
|
||||
String suffix = FileUtil.getSuffix(srcPath);
|
||||
String fileName = imageDo.getName() + "." + suffix;
|
||||
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(byteOut.toByteArray()); //转换
|
||||
String romPath = "/home/image/" + UUID.randomUUID()+"/";
|
||||
uploadSftp.mkDirs(romPath);//递归创建
|
||||
uploadSftp.upload(romPath, fileName, arrayInputStream);
|
||||
uploadSftp.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 获取Sftp连接
|
||||
* @param config 连接配置
|
||||
* @return
|
||||
*/
|
||||
private Sftp getSftp(FtpConfig config){
|
||||
Session session;
|
||||
if (Objects.nonNull(config.getSystemKey())) {
|
||||
session = JschUtil.getSession(config.getHost(), config.getPort(), config.getUser(), config.getSystemKey().getBytes(StandardCharsets.UTF_8), config.getPassword().getBytes());
|
||||
} else {
|
||||
session = JschUtil.getSession(config.getHost(), config.getPort(), config.getUser(), config.getPassword());
|
||||
}
|
||||
return new Sftp(session);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user