Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 466de94

Browse filesBrowse files
authored
#1005: Added command to download multiple images. (#1343)
Tried to mimic existing patterns as much as possible. Stick to Java 7. Rely on the "busybox" image in tests since the test for the single image command does so, too.
1 parent 1f2aa6d commit 466de94
Copy full SHA for 466de94

File tree

10 files changed

+229
-0
lines changed
Filter options

10 files changed

+229
-0
lines changed

‎docker-java-api/src/main/java/com/github/dockerjava/api/DockerClient.java

Copy file name to clipboardExpand all lines: docker-java-api/src/main/java/com/github/dockerjava/api/DockerClient.java
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import com.github.dockerjava.api.command.RenameContainerCmd;
5757
import com.github.dockerjava.api.command.RestartContainerCmd;
5858
import com.github.dockerjava.api.command.SaveImageCmd;
59+
import com.github.dockerjava.api.command.SaveImagesCmd;
5960
import com.github.dockerjava.api.command.SearchImagesCmd;
6061
import com.github.dockerjava.api.command.StartContainerCmd;
6162
import com.github.dockerjava.api.command.StatsCmd;
@@ -137,6 +138,12 @@ public interface DockerClient extends Closeable {
137138
*/
138139
SaveImageCmd saveImageCmd(@Nonnull String name);
139140

141+
/**
142+
* Command to download multiple images at once.
143+
* @return command (builder)
144+
*/
145+
SaveImagesCmd saveImagesCmd();
146+
140147
/**
141148
* * CONTAINER API *
142149
*/

‎docker-java-api/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java

Copy file name to clipboardExpand all lines: docker-java-api/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public interface DockerCmdExecFactory extends Closeable {
2121

2222
SaveImageCmd.Exec createSaveImageCmdExec();
2323

24+
SaveImagesCmd.Exec createSaveImagesCmdExec();
25+
2426
CreateImageCmd.Exec createCreateImageCmdExec();
2527

2628
LoadImageCmd.Exec createLoadImageCmdExec();
+47Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.github.dockerjava.api.command;
2+
3+
import com.github.dockerjava.api.exception.NotFoundException;
4+
5+
import javax.annotation.Nonnull;
6+
import java.io.InputStream;
7+
import java.util.List;
8+
9+
/** Command for downloading multiple images at once. */
10+
public interface SaveImagesCmd extends SyncDockerCmd<InputStream> {
11+
12+
/** Image name and tag. */
13+
interface TaggedImage {
14+
15+
/**
16+
* The (tagged) image name.
17+
* @return "name:tag" if a tag was specified, otherwise "name"
18+
*/
19+
String asString();
20+
}
21+
22+
/**
23+
* Adds an image to the list of images to download.
24+
* @param name image name (not null)
25+
* @param tag tag
26+
* @return this
27+
*/
28+
SaveImagesCmd withImage(@Nonnull String name, @Nonnull String tag);
29+
30+
31+
/**
32+
* Gets the images that were added by {@link #withImage(String, String)}.
33+
* @return images to be downloaded
34+
*/
35+
List<TaggedImage> getImages();
36+
37+
/**
38+
* Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent connection leaks.
39+
*
40+
* @throws NotFoundException no such image
41+
*/
42+
InputStream exec() throws NotFoundException;
43+
44+
interface Exec extends DockerCmdSyncExec<SaveImagesCmd, InputStream> {
45+
}
46+
47+
}

‎docker-java-core/src/main/java/com/github/dockerjava/core/AbstractDockerCmdExecFactory.java

Copy file name to clipboardExpand all lines: docker-java-core/src/main/java/com/github/dockerjava/core/AbstractDockerCmdExecFactory.java
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import com.github.dockerjava.api.command.RenameContainerCmd;
6060
import com.github.dockerjava.api.command.RestartContainerCmd;
6161
import com.github.dockerjava.api.command.SaveImageCmd;
62+
import com.github.dockerjava.api.command.SaveImagesCmd;
6263
import com.github.dockerjava.api.command.SearchImagesCmd;
6364
import com.github.dockerjava.api.command.StartContainerCmd;
6465
import com.github.dockerjava.api.command.StatsCmd;
@@ -130,6 +131,7 @@
130131
import com.github.dockerjava.core.exec.RenameContainerCmdExec;
131132
import com.github.dockerjava.core.exec.RestartContainerCmdExec;
132133
import com.github.dockerjava.core.exec.SaveImageCmdExec;
134+
import com.github.dockerjava.core.exec.SaveImagesCmdExec;
133135
import com.github.dockerjava.core.exec.SearchImagesCmdExec;
134136
import com.github.dockerjava.core.exec.StartContainerCmdExec;
135137
import com.github.dockerjava.core.exec.StatsCmdExec;
@@ -226,6 +228,11 @@ public SaveImageCmd.Exec createSaveImageCmdExec() {
226228
return new SaveImageCmdExec(getBaseResource(), getDockerClientConfig());
227229
}
228230

231+
@Override
232+
public SaveImagesCmd.Exec createSaveImagesCmdExec() {
233+
return new SaveImagesCmdExec(getBaseResource(), getDockerClientConfig());
234+
}
235+
229236
@Override
230237
public CreateImageCmd.Exec createCreateImageCmdExec() {
231238
return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig());

‎docker-java-core/src/main/java/com/github/dockerjava/core/DockerClientImpl.java

Copy file name to clipboardExpand all lines: docker-java-core/src/main/java/com/github/dockerjava/core/DockerClientImpl.java
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import com.github.dockerjava.api.command.RenameContainerCmd;
5959
import com.github.dockerjava.api.command.RestartContainerCmd;
6060
import com.github.dockerjava.api.command.SaveImageCmd;
61+
import com.github.dockerjava.api.command.SaveImagesCmd;
6162
import com.github.dockerjava.api.command.SearchImagesCmd;
6263
import com.github.dockerjava.api.command.StartContainerCmd;
6364
import com.github.dockerjava.api.command.StatsCmd;
@@ -133,6 +134,7 @@
133134
import com.github.dockerjava.core.command.RenameContainerCmdImpl;
134135
import com.github.dockerjava.core.command.RestartContainerCmdImpl;
135136
import com.github.dockerjava.core.command.SaveImageCmdImpl;
137+
import com.github.dockerjava.core.command.SaveImagesCmdImpl;
136138
import com.github.dockerjava.core.command.SearchImagesCmdImpl;
137139
import com.github.dockerjava.core.command.StartContainerCmdImpl;
138140
import com.github.dockerjava.core.command.StatsCmdImpl;
@@ -283,6 +285,11 @@ public SaveImageCmd saveImageCmd(String name) {
283285
return new SaveImageCmdImpl(getDockerCmdExecFactory().createSaveImageCmdExec(), name);
284286
}
285287

288+
@Override
289+
public SaveImagesCmd saveImagesCmd() {
290+
return new SaveImagesCmdImpl(getDockerCmdExecFactory().createSaveImagesCmdExec());
291+
}
292+
286293
@Override
287294
public CreateImageCmd createImageCmd(String repository, InputStream imageStream) {
288295
return new CreateImageCmdImpl(getDockerCmdExecFactory().createCreateImageCmdExec(), repository, imageStream);
+63Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.github.dockerjava.core.command;
2+
3+
import com.github.dockerjava.api.command.SaveImagesCmd;
4+
import com.github.dockerjava.api.exception.NotFoundException;
5+
import com.google.common.collect.ImmutableList;
6+
7+
import javax.annotation.Nonnull;
8+
import java.io.InputStream;
9+
import java.util.List;
10+
11+
import static com.google.common.base.Preconditions.checkNotNull;
12+
13+
public class SaveImagesCmdImpl extends AbstrDockerCmd<SaveImagesCmd, InputStream> implements SaveImagesCmd {
14+
15+
private static class TaggedImageImpl implements TaggedImage {
16+
private final String name;
17+
private final String tag;
18+
19+
private TaggedImageImpl(String name, String tag) {
20+
checkNotNull(name, "image name was not specified");
21+
checkNotNull(tag, "image tag was not specified");
22+
this.name = name;
23+
this.tag = tag;
24+
}
25+
26+
@Override
27+
public String asString() {
28+
return name + ":" + tag;
29+
}
30+
31+
@Override
32+
public String toString() {
33+
return asString();
34+
}
35+
}
36+
37+
private final ImmutableList.Builder<TaggedImage> taggedImages = ImmutableList.builder();
38+
39+
public SaveImagesCmdImpl(final SaveImagesCmd.Exec exec) {
40+
super(exec);
41+
}
42+
43+
@Override
44+
public SaveImagesCmd withImage(@Nonnull final String name, @Nonnull final String tag) {
45+
taggedImages.add(new TaggedImageImpl(name, tag));
46+
return this;
47+
}
48+
49+
50+
51+
@Override
52+
public List<TaggedImage> getImages() {
53+
return taggedImages.build();
54+
}
55+
56+
/**
57+
* @throws NotFoundException No such images
58+
*/
59+
@Override
60+
public InputStream exec() throws NotFoundException {
61+
return super.exec();
62+
}
63+
}
+39Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.github.dockerjava.core.exec;
2+
3+
import com.github.dockerjava.api.command.SaveImagesCmd;
4+
import com.github.dockerjava.core.DockerClientConfig;
5+
import com.github.dockerjava.core.MediaType;
6+
import com.github.dockerjava.core.WebTarget;
7+
import com.google.common.collect.ImmutableSet;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
import java.io.InputStream;
12+
import java.util.List;
13+
14+
public class SaveImagesCmdExec extends AbstrSyncDockerCmdExec<SaveImagesCmd, InputStream> implements SaveImagesCmd.Exec {
15+
private static final Logger LOGGER = LoggerFactory.getLogger(SaveImagesCmdExec.class);
16+
17+
public SaveImagesCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) {
18+
super(baseResource, dockerClientConfig);
19+
}
20+
21+
@Override
22+
protected InputStream execute(SaveImagesCmd command) {
23+
24+
final List<SaveImagesCmd.TaggedImage> images = command.getImages();
25+
if (images.isEmpty()) {
26+
LOGGER.warn("No images specified for " + SaveImagesCmd.class.getName() + ".");
27+
}
28+
final ImmutableSet.Builder<String> queryParamSet = ImmutableSet.builder();
29+
for (SaveImagesCmd.TaggedImage image : images) {
30+
queryParamSet.add(image.asString());
31+
}
32+
final WebTarget webResource = getBaseResource()
33+
.path("/images/get")
34+
.queryParamsSet("names", queryParamSet.build());
35+
36+
LOGGER.trace("GET: {}", webResource);
37+
return webResource.request().accept(MediaType.APPLICATION_JSON).get();
38+
}
39+
}
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.github.dockerjava.cmd;
2+
3+
import org.apache.commons.io.IOUtils;
4+
import org.junit.Test;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
import java.io.InputStream;
9+
10+
import static org.hamcrest.MatcherAssert.assertThat;
11+
import static org.hamcrest.Matchers.not;
12+
13+
public class SaveImagesCmdIT extends CmdIT {
14+
public static final Logger LOG = LoggerFactory.getLogger(SaveImagesCmdIT.class);
15+
16+
@Test
17+
public void saveNoImages() throws Exception {
18+
try(final InputStream image = IOUtils.toBufferedInputStream(dockerRule.getClient().saveImagesCmd().exec())){
19+
assertThat(image.read(), not(-1));
20+
}
21+
22+
}
23+
24+
@Test
25+
public void saveImagesWithNameAndTag() throws Exception {
26+
27+
try(final InputStream image = IOUtils.toBufferedInputStream(dockerRule.getClient().saveImagesCmd().withImage("busybox", "latest").exec())) {
28+
assertThat(image.read(), not(-1));
29+
}
30+
31+
}
32+
33+
@Test
34+
public void saveMultipleImages() throws Exception {
35+
36+
try(final InputStream image = IOUtils.toBufferedInputStream(dockerRule.getClient().saveImagesCmd()
37+
// Not a real life use-case but "busybox" is the only one I dare to assume is really there.
38+
.withImage("busybox", "latest")
39+
.withImage("busybox", "latest")
40+
.exec())) {
41+
assertThat(image.read(), not(-1));
42+
}
43+
}
44+
45+
}

‎docker-java/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java

Copy file name to clipboardExpand all lines: docker-java/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import com.github.dockerjava.api.command.RenameContainerCmd;
6464
import com.github.dockerjava.api.command.RestartContainerCmd;
6565
import com.github.dockerjava.api.command.SaveImageCmd;
66+
import com.github.dockerjava.api.command.SaveImagesCmd;
6667
import com.github.dockerjava.api.command.SearchImagesCmd;
6768
import com.github.dockerjava.api.command.StartContainerCmd;
6869
import com.github.dockerjava.api.command.StatsCmd;
@@ -215,6 +216,11 @@ public SaveImageCmd.Exec createSaveImageCmdExec() {
215216
return delegate.createSaveImageCmdExec();
216217
}
217218

219+
@Override
220+
public SaveImagesCmd.Exec createSaveImagesCmdExec() {
221+
return delegate.createSaveImagesCmdExec();
222+
}
223+
218224
@Override
219225
public SearchImagesCmd.Exec createSearchImagesCmdExec() {
220226
return delegate.createSearchImagesCmdExec();

‎docker-java/src/test/java/com/github/dockerjava/junit/DockerCmdExecFactoryDelegate.java

Copy file name to clipboardExpand all lines: docker-java/src/test/java/com/github/dockerjava/junit/DockerCmdExecFactoryDelegate.java
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.github.dockerjava.api.command.RenameContainerCmd;
6161
import com.github.dockerjava.api.command.RestartContainerCmd;
6262
import com.github.dockerjava.api.command.SaveImageCmd;
63+
import com.github.dockerjava.api.command.SaveImagesCmd;
6364
import com.github.dockerjava.api.command.SearchImagesCmd;
6465
import com.github.dockerjava.api.command.StartContainerCmd;
6566
import com.github.dockerjava.api.command.StatsCmd;
@@ -133,6 +134,11 @@ public SaveImageCmd.Exec createSaveImageCmdExec() {
133134
return delegate.createSaveImageCmdExec();
134135
}
135136

137+
@Override
138+
public SaveImagesCmd.Exec createSaveImagesCmdExec() {
139+
return delegate.createSaveImagesCmdExec();
140+
}
141+
136142
@Override
137143
public CreateImageCmd.Exec createCreateImageCmdExec() {
138144
return delegate.createCreateImageCmdExec();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.