diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index 3b558b6d9..3e31321ee 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -1,5 +1,7 @@ package com.github.dockerjava.api.command; +import java.util.Map; + import com.github.dockerjava.api.ConflictException; import com.github.dockerjava.api.NotFoundException; import com.github.dockerjava.api.model.Bind; @@ -173,6 +175,8 @@ public static interface Exec extends DockerCmdExec labels); + /** * Add link to another container. */ @@ -238,4 +242,9 @@ public static interface Exec extends DockerCmdExec getLabels(); + } diff --git a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java index 6d641f2e3..c2a116bed 100644 --- a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java @@ -3,6 +3,7 @@ import java.util.List; import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.api.model.Filters; /** * List containers @@ -31,6 +32,8 @@ public interface ListContainersCmd extends DockerCmd> { public String getBeforeId(); + public Filters getFilters(); + public ListContainersCmd withShowAll(boolean showAll); public ListContainersCmd withShowSize(boolean showSize); @@ -41,6 +44,8 @@ public interface ListContainersCmd extends DockerCmd> { public ListContainersCmd withBefore(String before); + public ListContainersCmd withFilters(Filters filters); + public static interface Exec extends DockerCmdExec> { } diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java index 8ea673a36..0478e5ef0 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java @@ -51,6 +51,9 @@ public class ContainerConfig { @JsonProperty("Image") private String image; + @JsonProperty("Labels") + private Map labels; + @JsonProperty("MacAddress") private String macAddress; @@ -184,6 +187,10 @@ public String[] getOnBuild() { return onBuild; } + public Map getLabels() { + return labels; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); diff --git a/src/main/java/com/github/dockerjava/api/model/Filters.java b/src/main/java/com/github/dockerjava/api/model/Filters.java new file mode 100644 index 000000000..a226c60c2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Filters.java @@ -0,0 +1,90 @@ +package com.github.dockerjava.api.model; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.MediaType; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; + +/** + * Representation of Docker filters. + * + * @author Carlos Sanchez + * + */ +public class Filters { + + private static ObjectMapper OBJECT_MAPPER = new JacksonJaxbJsonProvider().locateMapper(Map.class, + MediaType.APPLICATION_JSON_TYPE); + + private Map> filters = new HashMap>(); + + public Filters() { + } + + /** + * Constructor. + * + * @param image + * image to filter + * @param container + * container to filter + */ + public Filters(String image, String container) { + withImage(image); + withContainer(container); + } + + public Filters withFilter(String key, String... value) { + filters.put(key, Arrays.asList(value)); + return this; + } + + public List getFilter(String key) { + return filters.get(key); + } + + public Filters withImage(String... image) { + filters.put("image", Arrays.asList(image)); + return this; + } + + public List getImage() { + return getFilter("image"); + } + + public Filters withContainer(String... container) { + filters.put("container", Arrays.asList(container)); + return this; + } + + public List getContainer() { + return getFilter("container"); + } + + /** + * Filter by labels + * + * @param labels + * string array in the form ["key"] or ["key=value"] or a mix of both + * @return + */ + public Filters withLabel(String... labels) { + filters.put("label", Arrays.asList(labels)); + return this; + } + + @Override + public String toString() { + try { + return OBJECT_MAPPER.writeValueAsString(filters); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java index cc082b61f..3caf3c1bc 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java @@ -2,6 +2,8 @@ import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Map; + import org.apache.commons.lang.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -107,6 +109,9 @@ public class CreateContainerCmdImpl extends AbstrDockerCmd labels; + public CreateContainerCmdImpl(CreateContainerCmd.Exec exec, String image) { super(exec); checkNotNull(image, "image was not specified"); @@ -221,6 +226,12 @@ public Link[] getLinks() { return hostConfig.getLinks(); } + @Override + @JsonIgnore + public Map getLabels() { + return labels; + } + @Override @JsonIgnore public LxcConf[] getLxcConf() { @@ -471,6 +482,13 @@ public CreateContainerCmdImpl withImage(String image) { return this; } + @Override + public CreateContainerCmdImpl withLabels(Map labels) { + checkNotNull(labels, "labels was not specified"); + this.labels = labels; + return this; + } + @Override public CreateContainerCmdImpl withLinks(Link... links) { checkNotNull(links, "links was not specified"); diff --git a/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java index 13bb02cfb..b957a3bd6 100644 --- a/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java @@ -1,12 +1,12 @@ package com.github.dockerjava.core.command; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.*; import java.util.List; import com.github.dockerjava.api.command.ListContainersCmd; import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.api.model.Filters; /** * List containers @@ -32,6 +32,8 @@ public class ListContainersCmdImpl extends AbstrDockerCmd execute(ListContainersCmd command) { webResource = webResource.queryParam("limit", String.valueOf(command.getLimit())); } + if (command.getFilters() != null) { + webResource = webResource.queryParam("filters", + urlPathSegmentEscaper().escape(command.getFilters().toString())); + } + LOGGER.trace("GET: {}", webResource); List containers = webResource.request().accept(MediaType.APPLICATION_JSON) .get(new GenericType>() { diff --git a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java index a33cfddfe..efeed530a 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -13,6 +13,8 @@ import java.lang.reflect.Method; import java.security.SecureRandom; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; import static com.github.dockerjava.api.model.Capability.MKNOD; @@ -490,4 +492,24 @@ public void createContainerWithULimits() throws DockerException { } + @Test + public void createContainerWithLabels() throws DockerException { + + Map labels = new HashMap(); + labels.put("com.github.dockerjava.null", null); + labels.put("com.github.dockerjava.boolean", "true"); + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + .withLabels(labels).exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + + // null becomes empty string + labels.put("com.github.dockerjava.null", ""); + assertThat(inspectContainerResponse.getConfig().getLabels(), is(equalTo(labels))); + } } diff --git a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java index b074409bd..da049488b 100644 --- a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java @@ -26,7 +26,9 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.api.model.Filters; import com.github.dockerjava.client.AbstractDockerClientTest; +import com.google.common.collect.ImmutableMap; @Test(groups = "integration") public class ListContainersCmdImplTest extends AbstractDockerClientTest { @@ -96,7 +98,24 @@ public void testListContainers() throws DockerException { Container container2 = filteredContainers.get(0); assertThat(container2.getCommand(), not(isEmptyString())); - assertThat(container2.getImage(), startsWith(testImage + ":")); + assertThat(container2.getImage(), startsWith(testImage)); + + // list with filter by label + dockerClient.createContainerCmd(testImage).withCmd("echo").withLabels(ImmutableMap.of("test", "docker-java")) + .exec(); + filteredContainers = dockerClient.listContainersCmd().withShowAll(true) + .withFilters(new Filters().withLabel("test=docker-java")).exec(); + assertThat(filteredContainers.size(), is(equalTo(1))); + Container container3 = filteredContainers.get(0); + assertThat(container3.getCommand(), not(isEmptyString())); + assertThat(container3.getImage(), startsWith(testImage)); + + filteredContainers = dockerClient.listContainersCmd().withShowAll(true) + .withFilters(new Filters().withLabel("test")).exec(); + assertThat(filteredContainers.size(), is(equalTo(1))); + container3 = filteredContainers.get(0); + assertThat(container3.getCommand(), not(isEmptyString())); + assertThat(container3.getImage(), startsWith(testImage)); } }