Skip to content

Commit 5ca4754

Browse files
author
xianyanYang
committed
添加远程镜像下载功能
1 parent 8a1e84a commit 5ca4754

25 files changed

+386
-533
lines changed

pom.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
</parent>
1212

1313
<groupId>com.learn.docker</groupId>
14-
<artifactId>docker-java-tutorials</artifactId>
15-
<version>1.1.2-SNAPSHOT</version>
14+
<artifactId>docker-java-api</artifactId>
15+
<version>2.0.0-SNAPSHOT</version>
16+
17+
<description>Docker Java API</description>
1618

1719
<properties>
1820
<docker-java.version>3.1.0-rc-3</docker-java.version>

src/main/java/com/docker/AppConfig.java

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,115 @@
11
package com.docker.infrastructure.service;
22

33
import com.docker.service.DockerClientConnection;
4+
import com.docker.service.DockerContainerOperations;
5+
import com.docker.service.DockerImageOperations;
6+
import com.docker.service.DockerNetworkOperations;
47
import com.github.dockerjava.api.DockerClient;
58
import com.github.dockerjava.core.DefaultDockerClientConfig;
69
import com.github.dockerjava.core.DockerClientBuilder;
7-
import org.springframework.beans.factory.annotation.Autowired;
8-
import org.springframework.stereotype.Service;
10+
import com.github.dockerjava.core.DockerClientConfig;
11+
import org.springframework.beans.factory.annotation.Value;
12+
13+
import javax.annotation.PostConstruct;
914

1015
/**
1116
* @author sofia
1217
*/
13-
@Service("dockerClient.dockerClientConnection")
1418
public class InternalDockerClientConnection implements DockerClientConnection {
1519

16-
@Autowired
17-
private DockerClient dockerClient;
20+
@Value("${docker.host:}")
21+
private String dockerHost;
22+
23+
@Value("${docker.config:}")
24+
private String dockerConfig;
25+
26+
@Value("${docker.certPath:}")
27+
private String dockerCertPath;
28+
29+
@Value("${docker.tlsVerify:0}")
30+
private Boolean dockerTlsVerify;
31+
32+
@Value("${api.version:1.23}")
33+
private String apiVersion;
34+
35+
@Value("${registry.username:}")
36+
private String registryUsername;
37+
38+
@Value("${registry.password:}")
39+
private String registryPassword;
40+
41+
@Value("${registry.email:}")
42+
private String registryEmail;
43+
44+
@Value("${registry.url:}")
45+
private String registryUrl;
46+
47+
/**
48+
* 推送镜像延迟时间(单位:秒)
49+
*/
50+
@Value("${dockerClient.pushImagesAwaitCompletionSeconds:30}")
51+
private int pushImagesAwaitSeconds;
52+
53+
/**
54+
* 获取镜像延迟时间(单位:秒)
55+
*/
56+
@Value("${dockerClient.pullImagesAwaitCompletionSeconds:30}")
57+
private int pullImagesAwaitSeconds;
1858

19-
public InternalDockerClientConnection() {
20-
DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().build();
21-
dockerClient = DockerClientBuilder.getInstance(config).build();
59+
/**
60+
* 镜像仓库地址,用于镜像的推送存储,
61+
* 如 : docker login xxx.xxx.xxx.xxx:xxxx或者放置域名
62+
*/
63+
@Value("${registryRepository:localhost:9005}")
64+
private String registryRepository;
65+
66+
/**
67+
* 容器启动间隔时间
68+
*/
69+
@Value("${dockerContainer.intervalSecond:15}")
70+
private int intervalSecond = 15;
71+
72+
private DockerContainerOperations dockerContainerOperations;
73+
74+
private DockerImageOperations dockerImageOperations;
75+
76+
private DockerNetworkOperations dockerNetworkOperations;
77+
78+
@PostConstruct
79+
public void init() {
80+
DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
81+
.withDockerHost(dockerHost)
82+
.withDockerTlsVerify(dockerTlsVerify)
83+
.withDockerCertPath(dockerCertPath)
84+
.withDockerConfig(dockerConfig)
85+
.withApiVersion(apiVersion)
86+
.withRegistryUrl(registryUrl)
87+
.withRegistryUsername(registryUsername)
88+
.withRegistryPassword(registryPassword)
89+
.withRegistryEmail(registryEmail)
90+
.build();
91+
DockerClient dockerClient = DockerClientBuilder.getInstance(config).build();
92+
dockerImageOperations = new InternalDockerImageOperations(dockerClient).
93+
setPullImagesAwaitSeconds(pullImagesAwaitSeconds).
94+
setPushImagesAwaitSeconds(pushImagesAwaitSeconds).
95+
setRegistryRepository(registryRepository);
96+
dockerNetworkOperations = new InternalDockerNetworkOperations(dockerClient);
97+
dockerContainerOperations = new InternalDockerContainerOperations(dockerClient, dockerNetworkOperations, dockerImageOperations).
98+
setIntervalSecond(intervalSecond);
99+
}
100+
101+
@Override
102+
public DockerContainerOperations getDockerContainerOperations() {
103+
return dockerContainerOperations;
104+
}
105+
106+
@Override
107+
public DockerImageOperations getDockerImageOperations() {
108+
return dockerImageOperations;
22109
}
23110

24111
@Override
25-
public DockerClient connect() {
26-
return this.dockerClient;
112+
public DockerNetworkOperations getDockerNetworkOperations() {
113+
return dockerNetworkOperations;
27114
}
28115
}

src/main/java/com/docker/infrastructure/service/InternalDockerContainerOperations.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,48 +7,50 @@
77
import com.docker.model.DockerContainerState;
88
import com.docker.model.DockerPort;
99
import com.docker.model.DockerProtocol;
10-
import com.docker.service.DockerContainerBuilder;
11-
import com.docker.service.DockerContainerOperations;
12-
import com.docker.service.DockerCreateContainerCommand;
13-
import com.docker.service.DockerNetworkOperations;
10+
import com.docker.service.*;
1411
import com.github.dockerjava.api.DockerClient;
1512
import com.github.dockerjava.api.command.*;
1613
import com.github.dockerjava.api.exception.ConflictException;
1714
import com.github.dockerjava.api.exception.NotFoundException;
1815
import com.github.dockerjava.api.exception.NotModifiedException;
1916
import com.github.dockerjava.api.model.*;
20-
import com.github.dockerjava.core.command.PullImageResultCallback;
2117
import org.apache.commons.lang.StringUtils;
2218
import org.slf4j.Logger;
2319
import org.slf4j.LoggerFactory;
24-
import org.springframework.beans.factory.annotation.Autowired;
2520
import org.springframework.beans.factory.annotation.Value;
26-
import org.springframework.stereotype.Service;
2721
import org.springframework.util.CollectionUtils;
2822

2923
import java.util.ArrayList;
3024
import java.util.HashMap;
3125
import java.util.List;
3226
import java.util.Map;
33-
import java.util.concurrent.TimeUnit;
3427

3528
/**
3629
* @author sofia
3730
*/
38-
@Service("dockerClient.dockerContainerOperations")
3931
public class InternalDockerContainerOperations implements DockerContainerOperations {
4032

4133
private static final Logger logger = LoggerFactory.getLogger(InternalDockerContainerOperations.class);
4234

43-
@Autowired
4435
private DockerClient dockerClient;
4536

46-
@Autowired
4737
private DockerNetworkOperations dockerNetworkOperations;
4838

49-
@Value("${dockerContainer.intervalSecond:15}")
39+
private DockerImageOperations dockerImageOperations;
40+
5041
private int intervalSecond = 15;
5142

43+
public InternalDockerContainerOperations setIntervalSecond(int intervalSecond) {
44+
this.intervalSecond = intervalSecond;
45+
return this;
46+
}
47+
48+
public InternalDockerContainerOperations(DockerClient dockerClient, DockerNetworkOperations dockerNetworkOperations, DockerImageOperations dockerImageOperations) {
49+
this.dockerClient = dockerClient;
50+
this.dockerNetworkOperations = dockerNetworkOperations;
51+
this.dockerImageOperations = dockerImageOperations;
52+
}
53+
5254
/**
5355
* 新建容器
5456
*
@@ -185,14 +187,7 @@ private void pullImage(String imageName) {
185187
logger.info(String.format("开始下载镜像 %s 。", imageName));
186188
}
187189

188-
try {
189-
dockerClient.pullImageCmd(imageName)
190-
.exec(new PullImageResultCallback())
191-
.awaitCompletion(30, TimeUnit.SECONDS);
192-
} catch (InterruptedException e) {
193-
e.printStackTrace();
194-
}
195-
190+
this.dockerImageOperations.pullImage(imageName);
196191

197192
if (logger.isDebugEnabled()) {
198193
logger.info(String.format("下载镜像 %s 完毕 。", imageName));

src/main/java/com/docker/infrastructure/service/InternalDockerImageOperations.java

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44
import com.docker.service.DockerImageOperations;
55
import com.github.dockerjava.api.DockerClient;
66
import com.github.dockerjava.api.command.BuildImageCmd;
7+
import com.github.dockerjava.api.model.AuthConfig;
78
import com.github.dockerjava.core.command.BuildImageResultCallback;
9+
import com.github.dockerjava.core.command.PullImageResultCallback;
810
import com.github.dockerjava.core.command.PushImageResultCallback;
911
import com.github.dockerjava.core.util.CompressArchiveUtil;
1012
import org.apache.commons.io.FileUtils;
1113
import org.apache.commons.io.filefilter.TrueFileFilter;
1214
import org.apache.commons.lang.StringUtils;
1315
import org.slf4j.Logger;
1416
import org.slf4j.LoggerFactory;
15-
import org.springframework.beans.factory.annotation.Autowired;
16-
import org.springframework.beans.factory.annotation.Value;
17-
import org.springframework.stereotype.Service;
1817
import org.springframework.util.CollectionUtils;
1918

2019
import java.io.File;
@@ -27,26 +26,86 @@
2726
import java.util.UUID;
2827
import java.util.concurrent.TimeUnit;
2928

30-
@Service("dockerClient.dockerImageOperations")
29+
/**
30+
* Docker镜像操作服务
31+
*/
3132
public class InternalDockerImageOperations implements DockerImageOperations {
3233

33-
@Value("${dockerClient.pushImagesAwaitCompletionSeconds:30}")
34-
private int pushImagesAwaitCompletionSeconds = 30;
35-
3634
private static final Logger logger = LoggerFactory.getLogger(InternalDockerImageOperations.class);
3735

38-
@Autowired
3936
private DockerClient dockerClient;
37+
private String registryRepository = "localhost:8081";
38+
private long pullImagesAwaitSeconds = 30;
39+
private long pushImagesAwaitSeconds = 30;
40+
41+
public InternalDockerImageOperations setRegistryRepository(String registryRepository) {
42+
if (StringUtils.isBlank(registryRepository)) {
43+
throw new DockerImageException("pullImage-init", String.format("镜像仓库地址不能为NULL或者空字符串。", pullImagesAwaitSeconds));
44+
}
45+
this.registryRepository = registryRepository;
46+
return this;
47+
}
48+
49+
public InternalDockerImageOperations setPullImagesAwaitSeconds(long pullImagesAwaitSeconds) {
50+
if (pullImagesAwaitSeconds <= 0) {
51+
throw new DockerImageException("pullImage-init", String.format("镜像拉取延迟时间(%秒)不合法。", pullImagesAwaitSeconds));
52+
}
53+
this.pullImagesAwaitSeconds = pullImagesAwaitSeconds;
54+
return this;
55+
}
56+
57+
public InternalDockerImageOperations setPushImagesAwaitSeconds(long pushImagesAwaitSeconds) {
58+
if (pullImagesAwaitSeconds <= 0) {
59+
throw new DockerImageException("pullImage-init", String.format("镜像推动延迟时间(%秒)不合法。", pushImagesAwaitSeconds));
60+
}
61+
this.pushImagesAwaitSeconds = pushImagesAwaitSeconds;
62+
return this;
63+
}
64+
65+
public InternalDockerImageOperations(DockerClient dockerClient) {
66+
if (dockerClient == null) {
67+
throw new DockerImageException("pullImage-init", String.format("docker连接器不能为NULL或空字符串。"));
68+
}
69+
this.dockerClient = dockerClient;
70+
}
71+
72+
@Override
73+
public void pullImageFrom(String imageRepository, AuthConfig authConfig) throws DockerImageException {
74+
if (StringUtils.isBlank(imageRepository)) {
75+
throw new DockerImageException("pullImage-001", "镜像地址不能为NULL或者空字符串。");
76+
}
77+
try {
78+
dockerClient.pullImageCmd(imageRepository).
79+
withAuthConfig(authConfig).
80+
exec(new PullImageResultCallback()).
81+
awaitCompletion(pullImagesAwaitSeconds, TimeUnit.SECONDS);
82+
} catch (InterruptedException e) {
83+
throw new DockerImageException("pullImage-004", String.format("下载镜像 %s 失败。", imageRepository));
84+
}
85+
}
4086

41-
@Value("${registryRepository:localhost:9005}")
42-
private String registryRepository = "localhost:9005";
87+
@Override
88+
public void pullImage(String imageRepository) throws DockerImageException {
89+
if (StringUtils.isBlank(imageRepository)) {
90+
throw new DockerImageException("pullImage-001", "镜像地址不能为NULL或者空字符串。");
91+
}
92+
try {
93+
dockerClient
94+
.pullImageCmd(imageRepository)
95+
.exec(new PullImageResultCallback())
96+
.awaitCompletion(pullImagesAwaitSeconds, TimeUnit.SECONDS);
97+
} catch (InterruptedException e) {
98+
throw new DockerImageException("pullImage-004", String.format("下载镜像 %s 失败。", imageRepository));
99+
}
100+
}
43101

44102
/**
45103
* @param dockerFilePath
46104
* @param imageRepository 仓库名为两段式路径,比如 jwilder/nginx-proxy
47105
* @param tag
48106
* @return
49107
*/
108+
@Override
50109
public String buildImage(String dockerFilePath, String imageRepository, String tag) throws DockerImageException {
51110
if (StringUtils.isBlank(imageRepository)) {
52111
throw new DockerImageException("buildImage-002", "镜像仓库名不能为NULL或者空字符串。");
@@ -68,18 +127,21 @@ public void pushImage(String imageRepository, String tag) throws DockerImageExce
68127
dockerClient.pushImageCmd(imageName)
69128
.withAuthConfig(dockerClient.authConfig())
70129
.exec(new PushImageResultCallback())
71-
.awaitCompletion(30, TimeUnit.SECONDS);
130+
.awaitCompletion(pushImagesAwaitSeconds, TimeUnit.SECONDS);
72131
} catch (InterruptedException e) {
73132
logger.error("推送镜像失败。", e);
74-
throw new DockerImageException("buildImage-006", "镜像制作文件读取失败。");
133+
throw new DockerImageException("pushImage-001", "镜像制作文件读取失败。");
134+
} catch (Exception e) {
135+
logger.error("推送镜像失败。", e);
136+
throw new DockerImageException("pushImage-002", "推送镜像失败。");
75137
}
76138
}
77139

78140
private InputStream fetchImageBuildFilesToTarFile(String dockerFilePath) {
79141
if (StringUtils.isBlank(dockerFilePath)) {
80142
throw new DockerImageException("buildImage-001", "镜像制作文件目录不能为NULL或者空字符串。");
81143
}
82-
File dockerFile = new File(dockerFilePath);
144+
File dockerFile = FileUtils.getFile(dockerFilePath);
83145
if (dockerFile.exists() == false) {
84146
throw new DockerImageException("buildImage-004", "镜像制作文件目录不存在。");
85147
}
@@ -99,7 +161,7 @@ private InputStream fetchImageBuildFilesToTarFile(String dockerFilePath) {
99161
private String dockerfileBuild(InputStream inputStream, String imageName) {
100162
BuildImageCmd buildImageCmd = dockerClient
101163
.buildImageCmd()
102-
.withTags(new HashSet<String>(Arrays.asList(imageName)))
164+
.withTags(new HashSet(Arrays.asList(imageName)))
103165
.withTarInputStream(inputStream);
104166
return buildImageCmd.withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId();
105167
}

0 commit comments

Comments
 (0)