diff --git a/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java b/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java index 502af84c7..fad6d1da7 100644 --- a/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java @@ -8,18 +8,18 @@ * List images * * @param showAll - Show all images (by default filter out the intermediate images used to build) - * @param filter - TODO: undocumented in docker remote api reference + * @param filters - a json encoded value of the filters (a map[string][]string) to process on the images list. */ public interface ListImagesCmd extends DockerCmd> { - public String getFilter(); + public String getFilters(); public boolean hasShowAllEnabled(); public ListImagesCmd withShowAll(boolean showAll); - public ListImagesCmd withFilter(String filter); - + public ListImagesCmd withFilters(String filters); + public static interface Exec extends DockerCmdExec> { } diff --git a/src/main/java/com/github/dockerjava/core/command/ListImagesCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ListImagesCmdImpl.java index 95e36af83..451a0ac57 100644 --- a/src/main/java/com/github/dockerjava/core/command/ListImagesCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/ListImagesCmdImpl.java @@ -11,21 +11,21 @@ * List images * * @param showAll - Show all images (by default filter out the intermediate images used to build) - * @param filter - TODO: undocumented in docker remote api reference + * @param filters - a json encoded value of the filters (a map[string][]string) to process on the images list. */ public class ListImagesCmdImpl extends AbstrDockerCmd> implements ListImagesCmd { - private String filter; - + private String filters; + private boolean showAll = false; - + public ListImagesCmdImpl(ListImagesCmd.Exec exec) { super(exec); } @Override - public String getFilter() { - return filter; + public String getFilters() { + return filters; } @Override @@ -40,9 +40,9 @@ public ListImagesCmd withShowAll(boolean showAll) { } @Override - public ListImagesCmd withFilter(String filter) { - Preconditions.checkNotNull(filter, "filter was not specified"); - this.filter = filter; + public ListImagesCmd withFilters(String filter) { + Preconditions.checkNotNull(filter, "filters have not been specified"); + this.filters = filter; return this; } @@ -50,7 +50,7 @@ public ListImagesCmd withFilter(String filter) { public String toString() { return new StringBuilder("images ") .append(showAll ? "--all=true" : "") - .append(filter != null ? "--filter " + filter : "") + .append(filters != null ? "--filter " + filters : "") .toString(); } } diff --git a/src/main/java/com/github/dockerjava/jaxrs/ListImagesCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/ListImagesCmdExec.java index 5a000a294..1a50f0818 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/ListImagesCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/ListImagesCmdExec.java @@ -6,16 +6,19 @@ import javax.ws.rs.core.GenericType; import javax.ws.rs.core.MediaType; +import com.google.common.net.UrlEscapers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.dockerjava.api.command.ListImagesCmd; import com.github.dockerjava.api.model.Image; +import static com.google.common.net.UrlEscapers.urlPathSegmentEscaper; + public class ListImagesCmdExec extends AbstrDockerCmdExec> implements ListImagesCmd.Exec { - + private static final Logger LOGGER = LoggerFactory.getLogger(ListImagesCmdExec.class); - + public ListImagesCmdExec(WebTarget baseResource) { super(baseResource); } @@ -24,15 +27,17 @@ public ListImagesCmdExec(WebTarget baseResource) { protected List execute(ListImagesCmd command) { WebTarget webResource = getBaseResource() .path("/images/json") - .queryParam("filter", command.getFilter()) + .queryParam("filters", urlPathSegmentEscaper().escape(command.getFilters())) .queryParam("all", command.hasShowAllEnabled() ? "1" : "0"); LOGGER.trace("GET: {}", webResource); - - List images = webResource.request().accept(MediaType.APPLICATION_JSON).get(new GenericType>() { - }); + + List images = webResource.request() + .accept(MediaType.APPLICATION_JSON) + .get(new GenericType>() { + }); LOGGER.trace("Response: {}", images); - + return images; } diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java index 2e94f2302..4418a8d5f 100644 --- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -20,7 +20,7 @@ import java.net.ServerSocket; public abstract class AbstractDockerClientTest extends Assert { - + public static final Logger LOG = LoggerFactory .getLogger(AbstractDockerClientTest.class); public static final String DOCKER_JAVA = "dockerjava"; @@ -39,8 +39,8 @@ public void beforeTest() { LOG.info("Pulling image 'busybox'"); // need to block until image is pulled completely asString(dockerClient.pullImageCmd("busybox").withTag("latest").exec()); - - + + assertNotNull(dockerClient); LOG.info("======================= END OF BEFORETEST =======================\n\n"); @@ -75,7 +75,7 @@ public void afterMethod(ITestResult result) { for (String container : dockerCmdExecFactory.getContainerNames()) { LOG.info("Cleaning up temporary container {}", container); - + try { dockerClient.removeContainerCmd(container).withForce().exec(); } catch (DockerException ignore) { @@ -90,17 +90,17 @@ public void afterMethod(ITestResult result) { } catch (DockerException ignore) { ignore.printStackTrace(); } - } - + } + LOG.info( "################################## END OF {} ##################################\n", result.getName()); } protected String asString(InputStream response) { - + StringWriter logwriter = new StringWriter(); - + try { LineIterator itr = IOUtils.lineIterator( response, "UTF-8"); @@ -110,7 +110,7 @@ protected String asString(InputStream response) { logwriter.write(line + (itr.hasNext() ? "\n" : "")); //LOG.info("line: "+line); } - + return logwriter.toString(); } catch (IOException e) { throw new RuntimeException(e); @@ -118,12 +118,12 @@ protected String asString(InputStream response) { IOUtils.closeQuietly(response); } } - + // UTIL /** * Checks to see if a specific port is available. - * + * * @param port * the port to check for availability */ diff --git a/src/test/java/com/github/dockerjava/core/command/ListImagesCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ListImagesCmdImplTest.java index b2f3b88e9..34a5984d9 100644 --- a/src/test/java/com/github/dockerjava/core/command/ListImagesCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ListImagesCmdImplTest.java @@ -6,6 +6,7 @@ import java.lang.reflect.Method; import java.util.List; +import com.github.dockerjava.api.command.CreateContainerResponse; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -25,7 +26,7 @@ public class ListImagesCmdImplTest extends AbstractDockerClientTest { public void beforeTest() throws DockerException { super.beforeTest(); } - + @AfterTest public void afterTest() { super.afterTest(); @@ -40,7 +41,7 @@ public void beforeMethod(Method method) { public void afterMethod(ITestResult result) { super.afterMethod(result); } - + @Test public void listImages() throws DockerException { List images = dockerClient.listImagesCmd().withShowAll(true).exec(); @@ -57,5 +58,42 @@ public void listImages() throws DockerException { assertThat(img.getRepoTags(), not(emptyArray())); } + @Test + public void listDanglingImages() throws DockerException { + String imageId = createDanglingImage(); + List images = dockerClient.listImagesCmd() + .withFilters("{\"dangling\":[\"true\"]}") + .withShowAll(true).exec(); + assertThat(images, notNullValue()); + LOG.info("Images List: {}", images); + assertThat(images.size(), is(greaterThan(0))); + boolean imageInFilteredList = isImageInFilteredList(images, imageId); + assertTrue(imageInFilteredList); + } + private boolean isImageInFilteredList(List images, String expectedImageId) { + for (Image image : images) { + if (expectedImageId.equals(image.getId())) { + return true; + } + } + return false; + } + + private String createDanglingImage() { + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("sleep", "5").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + LOG.info("Committing container {}", container.toString()); + String imageId = dockerClient + .commitCmd(container.getId()).exec(); + + dockerClient.stopContainerCmd(container.getId()).exec(); + dockerClient.killContainerCmd(container.getId()).exec(); + dockerClient.removeContainerCmd(container.getId()).exec(); + return imageId; + } } diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java index ec6b6ec36..a2a190f6f 100644 --- a/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java @@ -59,11 +59,11 @@ public void removeImage() throws DockerException, InterruptedException { LOG.info("Created container: {}", container.toString()); assertThat(container.getId(), not(isEmptyString())); dockerClient.startContainerCmd(container.getId()).exec(); - - LOG.info("Commiting container {}", container.toString()); + + LOG.info("Committing container {}", container.toString()); String imageId = dockerClient .commitCmd(container.getId()).exec(); - + dockerClient.stopContainerCmd(container.getId()).exec(); dockerClient.killContainerCmd(container.getId()).exec(); dockerClient.removeContainerCmd(container.getId()).exec(); @@ -72,7 +72,7 @@ public void removeImage() throws DockerException, InterruptedException { dockerClient.removeImageCmd(imageId).exec(); List containers = dockerClient.listContainersCmd().withShowAll(true).exec(); - + Matcher matcher = not(hasItem(hasField("id", startsWith(imageId)))); assertThat(containers, matcher); }