Skip to content

Commit e1e475e

Browse files
committed
support pull image
1 parent ab3e58a commit e1e475e

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

docker/src/main/java/com/flowci/docker/DockerManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ public interface DockerManager {
55
String DockerLocalHost = "unix:///var/run/docker.sock";
66

77
ContainerManager getContainerManager();
8+
9+
ImageManager getImageManager();
810
}

docker/src/main/java/com/flowci/docker/DockerSDKManager.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,31 @@
11
package com.flowci.docker;
22

3+
import com.flowci.docker.domain.DockerCallback;
34
import com.flowci.docker.domain.DockerStartOption;
45
import com.flowci.util.ObjectsHelper;
56
import com.github.dockerjava.api.DockerClient;
67
import com.github.dockerjava.api.command.*;
8+
import com.github.dockerjava.api.exception.DockerException;
79
import com.github.dockerjava.api.model.Container;
10+
import com.github.dockerjava.api.model.Image;
11+
import com.github.dockerjava.api.model.PullResponseItem;
812
import com.github.dockerjava.core.DefaultDockerClientConfig;
913
import com.github.dockerjava.core.DockerClientBuilder;
14+
import lombok.extern.log4j.Log4j2;
1015

1116
import java.util.List;
17+
import java.util.concurrent.TimeUnit;
18+
import java.util.function.Consumer;
1219

20+
@Log4j2
1321
public class DockerSDKManager implements DockerManager {
1422

1523
private final String dockerHost;
1624

1725
private final ContainerManager containerManager = new ContainerManagerImpl();
1826

27+
private final ImageManager imageManager = new ImageMangerImpl();
28+
1929
public DockerSDKManager(String dockerHost) {
2030
this.dockerHost = dockerHost;
2131
}
@@ -25,6 +35,59 @@ public ContainerManager getContainerManager() {
2535
return containerManager;
2636
}
2737

38+
@Override
39+
public ImageManager getImageManager() {
40+
return imageManager;
41+
}
42+
43+
private class ImageMangerImpl implements ImageManager {
44+
45+
@Override
46+
public void pull(String image, int timeoutInSeconds, Consumer<PullResponseItem> progress) throws Exception {
47+
String imageUrl = "docker.io/library/" + image;
48+
if (image.contains("/")) {
49+
imageUrl = "docker.io/" + image;
50+
}
51+
52+
try (DockerClient client = newClient()) {
53+
if (findImage(client, image).size() >= 1) {
54+
return;
55+
}
56+
57+
PullImageCallback callback = client.pullImageCmd(imageUrl).exec(new PullImageCallback(progress));
58+
boolean await = callback.getCounter().await(timeoutInSeconds, TimeUnit.SECONDS);
59+
60+
if (!await) {
61+
throw new DockerException(String.format("Timeout when pull image %s", image), 0);
62+
}
63+
64+
if (findImage(client, image).isEmpty()) {
65+
throw new DockerException(String.format("Failed on pull image %s", image), 0);
66+
}
67+
}
68+
}
69+
70+
private List<Image> findImage(DockerClient client, String image) {
71+
return client.listImagesCmd().withImageNameFilter(image).exec();
72+
}
73+
}
74+
75+
private static class PullImageCallback extends DockerCallback<PullResponseItem> {
76+
77+
private final Consumer<PullResponseItem> progress;
78+
79+
private PullImageCallback(Consumer<PullResponseItem> progress) {
80+
this.progress = progress;
81+
}
82+
83+
@Override
84+
public void onNext(PullResponseItem item) {
85+
if (progress != null && item != null) {
86+
progress.accept(item);
87+
}
88+
}
89+
}
90+
2891
private class ContainerManagerImpl implements ContainerManager {
2992

3093
@Override
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.flowci.docker;
2+
3+
import com.github.dockerjava.api.model.PullResponseItem;
4+
5+
import java.util.function.Consumer;
6+
7+
public interface ImageManager {
8+
9+
/**
10+
* Sync call
11+
*/
12+
void pull(String image, int timeoutInSeconds, Consumer<PullResponseItem> progress) throws Exception;
13+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.flowci.docker.domain;
2+
3+
import com.github.dockerjava.api.async.ResultCallback;
4+
import lombok.Getter;
5+
6+
import java.io.Closeable;
7+
import java.io.IOException;
8+
import java.util.concurrent.CountDownLatch;
9+
10+
public abstract class DockerCallback<T> implements ResultCallback<T> {
11+
12+
@Getter
13+
protected final CountDownLatch counter = new CountDownLatch(1);
14+
15+
@Override
16+
public void onStart(Closeable closeable) {
17+
18+
}
19+
20+
@Override
21+
public void onError(Throwable throwable) {
22+
23+
}
24+
25+
@Override
26+
public void onComplete() {
27+
counter.countDown();
28+
}
29+
30+
@Override
31+
public void close() throws IOException {
32+
33+
}
34+
}

docker/src/test/java/com/flowci/docker/test/DockerSDKManagerTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.flowci.docker.DockerManager;
55
import com.flowci.docker.DockerSDKManager;
66
import com.flowci.docker.domain.DockerStartOption;
7+
import com.github.dockerjava.api.exception.NotFoundException;
78
import com.github.dockerjava.api.model.Container;
89
import org.junit.After;
910
import org.junit.Assert;
@@ -26,6 +27,13 @@ public void clean() {
2627
manager = null;
2728
}
2829

30+
@Test
31+
public void should_pull_image() throws Exception {
32+
manager.getImageManager().pull("hello-world", 60, (item) -> {
33+
System.out.println(item.getStatus());
34+
});
35+
}
36+
2937
@Test
3038
public void should_list_container() throws Exception {
3139
List<Container> containers = manager.getContainerManager().list(null, null);
@@ -45,4 +53,19 @@ public void should_create_and_start_container() throws Exception {
4553
cm.stop(cid);
4654
cm.delete(cid);
4755
}
56+
57+
@Test(expected = NotFoundException.class)
58+
public void should_throw_exception_when_resume_cid_not_exist() throws Exception {
59+
manager.getContainerManager().resume("1231231");
60+
}
61+
62+
@Test(expected = NotFoundException.class)
63+
public void should_throw_exception_when_stop_cid_not_exist() throws Exception {
64+
manager.getContainerManager().stop("1231231");
65+
}
66+
67+
@Test(expected = NotFoundException.class)
68+
public void should_throw_exception_when_delete_cid_not_exist() throws Exception {
69+
manager.getContainerManager().delete("1231231");
70+
}
4871
}

0 commit comments

Comments
 (0)