<docker.version>3.2.13</docker.version>
<fastjson.version>1.2.75</fastjson.version>
<dependencies>
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java-core</artifactId>
<version>${docker.version}</version>
</dependency>
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java-transport-httpclient5</artifactId>
<version>${docker.version}</version>
</dependency>
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<exclusions>
<exclusion>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-apache-connector</artifactId>
</exclusion>
</exclusions>
<version>${docker.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
import com.alibaba.fastjson.JSON;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.command.BuildImageCmd;
import com.github.dockerjava.api.command.BuildImageResultCallback;
import com.github.dockerjava.api.command.LoadImageCmd;
import com.github.dockerjava.api.command.TagImageCmd;
import com.github.dockerjava.api.model.*;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.github.dockerjava.transport.DockerHttpClient;
import com.sunyard.staging.starter.harbor.properties.HarborProperties;
import com.sunyard.staging.starter.harbor.utils.AesCbcUtil;
import com.sunyard.staging.starter.harbor.utils.UnCompress;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class HarborApiClient {
@Autowired
private HarborProperties harborProperties;
public DockerClient getDocekrClient() throws Exception {
DefaultDockerClientConfig dockerClientConfig = null;
if (harborProperties.isDockertlsverify()) {
dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost(harborProperties.getDockerhost())
.withDockerTlsVerify(true)
.withDockerCertPath(harborProperties.getDockerCertPath())
.withRegistryUsername(harborProperties.getRegistryusername())
.withRegistryPassword(AesCbcUtil.Decrypt(harborProperties.getRegistrypassword()))
.withRegistryUrl(harborProperties.getRegistryurl())
.build();
} else {
dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost(harborProperties.getDockerhost())
.withDockerTlsVerify(false)
.withDockerCertPath(harborProperties.getDockerCertPath())
.withRegistryUsername(harborProperties.getRegistryusername())
.withRegistryPassword(AesCbcUtil.Decrypt(harborProperties.getRegistrypassword()))
.withRegistryUrl(harborProperties.getRegistryurl())
.build();
}
DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
.dockerHost(dockerClientConfig.getDockerHost())
.sslConfig(dockerClientConfig.getSSLConfig())
.build();
return DockerClientImpl.getInstance(dockerClientConfig, httpClient);
}
public DockerClient getDockerClient(String dockerIpPort, String dockerCertPath, boolean dockerTlsVerify) throws Exception {
DefaultDockerClientConfig dockerClientConfig = null;
if (dockerTlsVerify) {
dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost(StringUtils.isNotBlank(dockerIpPort) ? dockerIpPort : harborProperties.getDockerhost())
.withDockerTlsVerify(true)
.withDockerCertPath(StringUtils.isNotBlank(dockerCertPath) ? dockerCertPath : harborProperties.getDockerCertPath())
.withRegistryUsername(harborProperties.getRegistryusername())
.withRegistryPassword(AesCbcUtil.Decrypt(harborProperties.getRegistrypassword()))
.withRegistryUrl(harborProperties.getRegistryurl())
.build();
} else {
dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost(StringUtils.isNotBlank(dockerIpPort) ? dockerIpPort : harborProperties.getDockerhost())
.withDockerTlsVerify(false)
.withDockerCertPath(StringUtils.isNotBlank(dockerCertPath) ? dockerCertPath : harborProperties.getDockerCertPath())
.withRegistryUsername(harborProperties.getRegistryusername())
.withRegistryPassword(AesCbcUtil.Decrypt(harborProperties.getRegistrypassword()))
.withRegistryUrl(harborProperties.getRegistryurl())
.build();
}
DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
.dockerHost(dockerClientConfig.getDockerHost())
.sslConfig(dockerClientConfig.getSSLConfig())
.build();
return DockerClientImpl.getInstance(dockerClientConfig, httpClient);
}
public static String getDockerInfo(DockerClient dockerClient) {
Info info = dockerClient.infoCmd().exec();
return JSON.toJSONString(info);
}
public static void tagImage(DockerClient dockerClient, String imageIdOrFullName, String respository, String tag) {
TagImageCmd tagImageCmd = dockerClient.tagImageCmd(imageIdOrFullName, respository, tag);
tagImageCmd.exec();
}
public static void loadImage(DockerClient dockerClient, InputStream inputStream) {
LoadImageCmd loadImageCmd = dockerClient.loadImageCmd(inputStream);
loadImageCmd.exec();
}
private boolean harborImagePull(String dockerIpPort, String dockerCertPath, boolean dockerTlsVerify, String imagePathInHarbor) {
try {
DockerClient dockerClient = harborApiClient.getDockerClient(dockerIpPort, dockerCertPath, dockerTlsVerify);
PullImageResultCallback exec = new PullImageResultCallback() {
@Override
public void onNext(PullResponseItem item) {
}
};
AuthConfig authConfig = new AuthConfig()
.withRegistryAddress(harborProperties.getRegistryurl() + ":" + harborProperties.getPort())
.withUsername(harborProperties.getRegistryusername())
.withPassword(AesCbcUtil.Decrypt(harborProperties.getRegistrypassword()));
dockerClient.pullImageCmd(imagePathInHarbor).withAuthConfig(authConfig).exec(exec)
.awaitCompletion(30, TimeUnit.MINUTES);
exec.close();
return true;
} catch (Exception e) {
logger.error("harbor镜像拉取失败:", e);
return false;
}
}
public static Boolean pushImage(DockerClient dockerClient, String imageName) throws InterruptedException {
final Boolean[] result = {true};
ResultCallback.Adapter<PushResponseItem> callBack = new ResultCallback.Adapter<PushResponseItem>() {
@Override
public void onNext(PushResponseItem pushResponseItem) {
if (pushResponseItem != null) {
ResponseItem.ErrorDetail errorDetail = pushResponseItem.getErrorDetail();
if (errorDetail != null) {
result[0] = false;
log.error(errorDetail.getMessage(), errorDetail);
}
}
super.onNext(pushResponseItem);
}
};
dockerClient.pushImageCmd(imageName).exec(callBack).awaitCompletion();
return result[0];
}
public void uploadImage(DockerClient dockerClient, MultipartFile file, String imageName) throws Exception {
InputStream inputStream = null;
String uploadImageName = "";
try {
inputStream = file.getInputStream();
String password = AesCbcUtil.Decrypt(harborProperties.getRegistrypassword());
AuthConfig autoConfig =
new AuthConfig().withRegistryAddress(harborProperties.getRegistryurl()).
withUsername(harborProperties.getRegistryusername()).withPassword(password);
dockerClient.loadImageCmd(inputStream).exec();
String imageFile = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));
String imageId = imageFile.substring(imageFile.lastIndexOf("_") + 1);
List<Image> list = dockerClient.listImagesCmd().exec();
for (Image image : list) {
if (image.getId().contains(imageId)) {
uploadImageName = image.getRepoTags()[0];
break;
}
}
dockerClient.tagImageCmd(uploadImageName, imageName, imageName.split(":")[2]).exec();
dockerClient.pushImageCmd(imageName).withAuthConfig(autoConfig).start().awaitCompletion(30, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("上传镜像出现异常", e);
} finally {
dockerClient.removeImageCmd(imageName).exec();
dockerClient.removeImageCmd(uploadImageName).exec();
if (inputStream != null) {
inputStream.close();
}
}
}
public static String getImageName(String imagePath) {
try {
return UnCompress.getImageName(imagePath);
} catch (Exception e) {
log.error("从镜像的tar文件中获取镜像名称出现异常!", e);
return null;
}
}
public static String buildImage(DockerClient dockerClient, File dockerFile) {
BuildImageCmd buildImageCmd = dockerClient.buildImageCmd(dockerFile);
BuildImageResultCallback buildImageResultCallback = new BuildImageResultCallback() {
@Override
public void onNext(BuildResponseItem item) {
log.info("{}", item);
super.onNext(item);
}
};
return buildImageCmd.exec(buildImageResultCallback).awaitImageId();
}
public static List<Image> imageList(DockerClient dockerClient) {
List<Image> imageList = dockerClient.listImagesCmd().withShowAll(true).exec();
return imageList;
}
}
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Setter
@Getter
@Configuration
@ConfigurationProperties(prefix = "spring.harbor")
public class HarborProperties {
public String dockerhost = "tcp://127.0.0.1:2375";
public String dockerCertPath = "";
public boolean dockertlsverify = false;
public String registryurl = "127.0.0.1:80";
public String registryusername = "sungrid";
public String registrypassword = "h8Wj3V01WWbBotV72XFJ38Js2nUD3Jj6Mc9K";
public String dockerservicemachine = "172.1.0.154:22";
public String dockerservicemachineusername = "root";
public String dockerservicemachinepassword = "Xydxnj220406!";
public int port = 80;
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@Slf4j
public class UnCompress {
private static final String BASE_DIR = "";
private static final String PATH = File.separator;
private static final int BUFFER = 1024;
private static final String EXT = ".tar";
public static void archive(String srcPath, String destPath) throws Exception {
File srcFile = new File(srcPath);
archive(srcFile, destPath);
}
public static void archive(File srcFile, File destFile) throws Exception {
TarArchiveOutputStream taos = new TarArchiveOutputStream(new FileOutputStream(destFile));
archive(srcFile, taos, BASE_DIR);
taos.flush();
taos.close();
}
public static void archive(File srcFile) throws Exception {
String name = srcFile.getName();
String basePath = srcFile.getParent();
String destPath = basePath+File.separator + name + EXT;
archive(srcFile, destPath);
}
public static void archive(File srcFile, String destPath) throws Exception {
archive(srcFile, new File(destPath));
}
public static void archive(String srcPath) throws Exception {
File srcFile = new File(srcPath);
archive(srcFile);
}
private static void archive(File srcFile, TarArchiveOutputStream taos, String basePath) throws Exception {
if (srcFile.isDirectory()) {
archiveDir(srcFile, taos, basePath);
} else {
archiveFile(srcFile, taos, basePath);
}
}
private static void archiveDir(File dir, TarArchiveOutputStream taos, String basePath) throws Exception {
File[] files = dir.listFiles();
if (files.length < 1) {
TarArchiveEntry entry = new TarArchiveEntry(basePath + dir.getName() + PATH);
taos.putArchiveEntry(entry);
taos.closeArchiveEntry();
}
for (File file : files) {
archive(file, taos, basePath + dir.getName() + PATH);
}
}
private static void archiveFile(File file, TarArchiveOutputStream taos, String dir) throws Exception {
TarArchiveEntry entry = new TarArchiveEntry(dir + file.getName());
entry.setSize(file.length());
taos.putArchiveEntry(entry);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
int count;
byte data[] = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
taos.write(data, 0, count);
}
bis.close();
taos.closeArchiveEntry();
}
public static void dearchive(File srcFile) throws Exception {
String basePath = srcFile.getParent();
dearchive(srcFile, basePath);
}
public static void dearchive(File srcFile, File destFile) throws Exception {
TarArchiveInputStream tais = new TarArchiveInputStream(new FileInputStream(srcFile));
dearchive(destFile, tais);
tais.close();
}
public static void dearchive(File srcFile, String destPath) throws Exception {
dearchive(srcFile, new File(destPath));
}
private static void dearchive(File destFile, TarArchiveInputStream tais) throws Exception {
TarArchiveEntry entry = null;
while ((entry = tais.getNextTarEntry()) != null) {
String dir = destFile.getPath() + File.separator + entry.getName();
File dirFile = new File(dir);
fileProber(dirFile);
if (entry.isDirectory()) {
dirFile.mkdirs();
} else {
dearchiveFile(dirFile, tais);
}
}
}
public static void dearchive(String srcPath) throws Exception {
File srcFile = new File(srcPath);
dearchive(srcFile);
}
public static void dearchive(String srcPath, String destPath) throws Exception {
File srcFile = new File(srcPath);
dearchive(srcFile, destPath);
}
private static void dearchiveFile(File destFile, TarArchiveInputStream tais) throws Exception {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
int count;
byte data[] = new byte[BUFFER];
while ((count = tais.read(data, 0, BUFFER)) != -1) {
bos.write(data, 0, count);
}
bos.close();
}
private static void fileProber(File dirFile) {
File parentFile = dirFile.getParentFile();
if (!parentFile.exists()) {
fileProber(parentFile);
parentFile.mkdir();
}
}
public static String getImageName(String tempFilePath) throws Exception{
String dirPath = tempFilePath.substring(0, tempFilePath.lastIndexOf("."));
File dirFile = new File(dirPath);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
UnCompress.dearchive(tempFilePath, dirPath);
if (!dirPath.endsWith(File.separator)) {
dirPath += File.separator;
}
String destFilePath = dirPath + "manifest.json";
File destFile = new File(destFilePath);
if (!destFile.exists()) {
return null;
}
StringBuilder sb = new StringBuilder("");
InputStream io = new FileInputStream(new File(destFilePath));
byte[] bytes = new byte[1024];
int len = 0;
while ((len = io.read(bytes)) > 0) {
sb.append(new String(bytes, 0, len));
}
String content = sb.toString();
List<JSONObject> jsonList = (List<JSONObject>) JSONArray.parse(content);
System.out.println("jsonList = " + jsonList);
return ((List<String>)jsonList.get(0).get("RepoTags")).get(0);
}
}