package com.github.dockerjava.core.command;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.command.StartContainerCmd;
import com.github.dockerjava.api.exception.DockerException;
import com.github.dockerjava.api.exception.InternalServerErrorException;
import com.github.dockerjava.api.exception.NotFoundException;
import com.github.dockerjava.api.model.Bind;
import com.github.dockerjava.api.model.Device;
import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.Link;
import com.github.dockerjava.api.model.Ports;
import com.github.dockerjava.api.model.RestartPolicy;
import com.github.dockerjava.api.model.Volume;
import com.github.dockerjava.api.model.VolumesFrom;
import com.github.dockerjava.api.model.Ports.Binding;
import com.github.dockerjava.client.AbstractDockerClientTest;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import static com.github.dockerjava.api.model.AccessMode.ro;
import static com.github.dockerjava.api.model.Capability.MKNOD;
import static com.github.dockerjava.api.model.Capability.NET_ADMIN;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.startsWith;
@Test(groups = "integration")
public class StartContainerCmdImplTest extends AbstractDockerClientTest {
@BeforeTest
public void beforeTest() throws Exception {
super.beforeTest();
}
@AfterTest
public void afterTest() {
super.afterTest();
}
@BeforeMethod
public void beforeMethod(Method method) {
super.beforeMethod(method);
}
@AfterMethod
public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
@Test
public void startContainerWithVolumes() throws DockerException {
// see http://docs.docker.io/use/working_with_volumes/
Volume volume1 = new Volume("/opt/webapp1");
Volume volume2 = new Volume("/opt/webapp2");
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withVolumes(volume1, volume2)
.withCmd("true").withBinds(new Bind("/src/webapp1", volume1, ro), new Bind("/src/webapp2", volume2))
.exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(inspectContainerResponse.getConfig().getVolumes().keySet(), contains("/opt/webapp1", "/opt/webapp2"));
dockerClient.startContainerCmd(container.getId()).exec();
dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()).awaitStatusCode();
inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(inspectContainerResponse, mountedVolumes(containsInAnyOrder(volume1, volume2)));
final List<InspectContainerResponse.Mount> mounts = inspectContainerResponse.getMounts();
assertThat(mounts, hasSize(2));
final InspectContainerResponse.Mount mount1 = new InspectContainerResponse.Mount()
.withRw(false).withMode("ro").withDestination(volume1).withSource("/src/webapp1");
final InspectContainerResponse.Mount mount2 = new InspectContainerResponse.Mount()
.withRw(true).withMode("rw").withDestination(volume2).withSource("/src/webapp2");
assertThat(mounts, containsInAnyOrder(mount1, mount2));
}
@Test
public void startContainerWithVolumesFrom() throws DockerException {
Volume volume1 = new Volume("/opt/webapp1");
Volume volume2 = new Volume("/opt/webapp2");
String container1Name = UUID.randomUUID().toString();
CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withName(container1Name)
.withBinds(new Bind("/src/webapp1", volume1), new Bind("/src/webapp2", volume2)).exec();
LOG.info("Created container1 {}", container1.toString());
dockerClient.startContainerCmd(container1.getId()).exec();
LOG.info("Started container1 {}", container1.toString());
InspectContainerResponse inspectContainerResponse1 = dockerClient.inspectContainerCmd(container1.getId())
.exec();
assertThat(inspectContainerResponse1, mountedVolumes(containsInAnyOrder(volume1, volume2)));
CreateContainerResponse container2 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withVolumesFrom(new VolumesFrom(container1Name)).exec();
LOG.info("Created container2 {}", container2.toString());
dockerClient.startContainerCmd(container2.getId()).exec();
LOG.info("Started container2 {}", container2.toString());
InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container2.getId())
.exec();
assertThat(inspectContainerResponse2, mountedVolumes(containsInAnyOrder(volume1, volume2)));
}
@Test
public void startContainerWithDns() throws DockerException {
String aDnsServer = "8.8.8.8";
String anotherDnsServer = "8.8.4.4";
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true")
.withDns(aDnsServer, anotherDnsServer).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getDns()),
contains(aDnsServer, anotherDnsServer));
}
@Test
public void startContainerWithDnsSearch() throws DockerException {
String dnsSearch = "example.com";
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true")
.withDnsSearch(dnsSearch).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
dockerClient.startContainerCmd(container.getId()).exec();
inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getDnsSearch()), contains(dnsSearch));
}
@Test
public void startContainerWithPortBindings() throws DockerException {
ExposedPort tcp22 = ExposedPort.tcp(22);
ExposedPort tcp23 = ExposedPort.tcp(23);
Ports portBindings = new Ports();
portBindings.bind(tcp22, Binding.bindPort(11022));
portBindings.bind(tcp23, Binding.bindPort(11023));
portBindings.bind(tcp23, Binding.bindPort(11024));
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true")
.withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
dockerClient.startContainerCmd(container.getId()).exec();
inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23));
assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0],
is(equalTo(Binding.bindPort(11022))));
assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0],
is(equalTo(Binding.bindPort(11023))));
assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1],
is(equalTo(Binding.bindPort(11024))));
}
@Test
public void startContainerWithRandomPortBindings() throws DockerException {
ExposedPort tcp22 = ExposedPort.tcp(22);
ExposedPort tcp23 = ExposedPort.tcp(23);
Ports portBindings = new Ports();
portBindings.bind(tcp22, Binding.empty());
portBindings.bind(tcp23, Binding.empty());
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).withPublishAllPorts(true).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23));
assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp22)[0].getHostPortSpec(),
is(not(equalTo(String.valueOf(tcp22.getPort())))));
assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp23)[0].getHostPortSpec(),
is(not(equalTo(String.valueOf(tcp23.getPort())))));
}
@Test(expectedExceptions = InternalServerErrorException.class)
public void startContainerWithConflictingPortBindings() throws DockerException {
ExposedPort tcp22 = ExposedPort.tcp(22);
ExposedPort tcp23 = ExposedPort.tcp(23);
Ports portBindings = new Ports();
portBindings.bind(tcp22, Binding.bindPort(11022));
portBindings.bind(tcp23, Binding.bindPort(11022));
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true")
.withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
}
@Test
public void startContainerWithLinkingDeprecated() throws DockerException {
CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withName("container1").exec();
LOG.info("Created container1 {}", container1.toString());
assertThat(container1.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container1.getId()).exec();
InspectContainerResponse inspectContainerResponse1 = dockerClient.inspectContainerCmd(container1.getId())
.exec();
LOG.info("Container1 Inspect: {}", inspectContainerResponse1.toString());
assertThat(inspectContainerResponse1.getConfig(), is(notNullValue()));
assertThat(inspectContainerResponse1.getId(), not(isEmptyString()));
assertThat(inspectContainerResponse1.getId(), startsWith(container1.getId()));
assertThat(inspectContainerResponse1.getName(), equalTo("/container1"));
assertThat(inspectContainerResponse1.getImageId(), not(isEmptyString()));
assertThat(inspectContainerResponse1.getState(), is(notNullValue()));
assertThat(inspectContainerResponse1.getState().getRunning(), is(true));
if (!inspectContainerResponse1.getState().getRunning()) {
assertThat(inspectContainerResponse1.getState().getExitCode(), is(equalTo(0)));
}
CreateContainerResponse container2 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withName("container2").withLinks(new Link("container1", "container1Link")).exec();
LOG.info("Created container2 {}", container2.toString());
assertThat(container2.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container2.getId()).exec();
InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container2.getId())
.exec();
LOG.info("Container2 Inspect: {}", inspectContainerResponse2.toString());
assertThat(inspectContainerResponse2.getConfig(), is(notNullValue()));
assertThat(inspectContainerResponse2.getId(), not(isEmptyString()));
assertThat(inspectContainerResponse2.getHostConfig(), is(notNullValue()));
assertThat(inspectContainerResponse2.getHostConfig().getLinks(), is(notNullValue()));
assertThat(inspectContainerResponse2.getHostConfig().getLinks(), equalTo(new Link[] {new Link("container1",
"container1Link")}));
assertThat(inspectContainerResponse2.getId(), startsWith(container2.getId()));
assertThat(inspectContainerResponse2.getName(), equalTo("/container2"));
assertThat(inspectContainerResponse2.getImageId(), not(isEmptyString()));
assertThat(inspectContainerResponse2.getState(), is(notNullValue()));
assertThat(inspectContainerResponse2.getState().getRunning(), is(true));
}
@Test
public void startContainerWithLinking() throws DockerException {
CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withName("container1").exec();
LOG.info("Created container1 {}", container1.toString());
assertThat(container1.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container1.getId()).exec();
InspectContainerResponse inspectContainerResponse1 = dockerClient.inspectContainerCmd(container1.getId())
.exec();
LOG.info("Container1 Inspect: {}", inspectContainerResponse1.toString());
assertThat(inspectContainerResponse1.getConfig(), is(notNullValue()));
assertThat(inspectContainerResponse1.getId(), not(isEmptyString()));
assertThat(inspectContainerResponse1.getId(), startsWith(container1.getId()));
assertThat(inspectContainerResponse1.getName(), equalTo("/container1"));
assertThat(inspectContainerResponse1.getImageId(), not(isEmptyString()));
assertThat(inspectContainerResponse1.getState(), is(notNullValue()));
assertThat(inspectContainerResponse1.getState().getRunning(), is(true));
if (!inspectContainerResponse1.getState().getRunning()) {
assertThat(inspectContainerResponse1.getState().getExitCode(), is(equalTo(0)));
}
CreateContainerResponse container2 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withName("container2").withLinks(new Link("container1", "container1Link")).exec();
LOG.info("Created container2 {}", container2.toString());
assertThat(container2.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container2.getId()).exec();
InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container2.getId())
.exec();
LOG.info("Container2 Inspect: {}", inspectContainerResponse2.toString());
assertThat(inspectContainerResponse2.getConfig(), is(notNullValue()));
assertThat(inspectContainerResponse2.getId(), not(isEmptyString()));
assertThat(inspectContainerResponse2.getHostConfig(), is(notNullValue()));
assertThat(inspectContainerResponse2.getHostConfig().getLinks(), is(notNullValue()));
assertThat(inspectContainerResponse2.getHostConfig().getLinks(), equalTo(new Link[] {new Link("container1",
"container1Link")}));
assertThat(inspectContainerResponse2.getId(), startsWith(container2.getId()));
assertThat(inspectContainerResponse2.getName(), equalTo("/container2"));
assertThat(inspectContainerResponse2.getImageId(), not(isEmptyString()));
assertThat(inspectContainerResponse2.getState(), is(notNullValue()));
assertThat(inspectContainerResponse2.getState().getRunning(), is(true));
}
@Test
public void startContainer() throws DockerException {
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd(new String[] {"top"})
.exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
LOG.info("Container Inspect: {}", inspectContainerResponse.toString());
assertThat(inspectContainerResponse.getConfig(), is(notNullValue()));
assertThat(inspectContainerResponse.getId(), not(isEmptyString()));
assertThat(inspectContainerResponse.getId(), startsWith(container.getId()));
assertThat(inspectContainerResponse.getImageId(), not(isEmptyString()));
assertThat(inspectContainerResponse.getState(), is(notNullValue()));
assertThat(inspectContainerResponse.getState().getRunning(), is(true));
if (!inspectContainerResponse.getState().getRunning()) {
assertThat(inspectContainerResponse.getState().getExitCode(), is(equalTo(0)));
}
}
@Test(expectedExceptions = NotFoundException.class)
public void testStartNonExistingContainer() throws DockerException {
dockerClient.startContainerCmd("non-existing").exec();
}
/**
* This tests support for --net option for the docker run command: --net="bridge" Set the Network mode for the container 'bridge':
* creates a new network stack for the container on the docker bridge 'none': no networking for this container 'container:': reuses
* another container network stack 'host': use the host network stack inside the container. Note: the host mode gives the container full
* access to local system services such as D-bus and is therefore considered insecure.
*/
@Test
public void startContainerWithNetworkMode() throws DockerException {
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true")
.withNetworkMode("host").exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
dockerClient.startContainerCmd(container.getId()).exec();
inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(inspectContainerResponse.getHostConfig().getNetworkMode(), is(equalTo("host")));
}
@Test
public void startContainerWithCapAddAndCapDrop() throws DockerException {
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withCapAdd(NET_ADMIN).withCapDrop(MKNOD).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(inspectContainerResponse.getState().getRunning(), is(true));
assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getCapAdd()), contains(NET_ADMIN));
assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getCapDrop()), contains(MKNOD));
}
@Test
public void startContainerWithDevices() throws DockerException {
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withDevices(new Device("rwm", "/dev/nulo", "/dev/zero")).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(inspectContainerResponse.getState().getRunning(), is(true));
assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getDevices()), contains(new Device("rwm",
"/dev/nulo", "/dev/zero")));
}
@Test
public void startContainerWithExtraHosts() throws DockerException {
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withExtraHosts("dockerhost:127.0.0.1").exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(inspectContainerResponse.getState().getRunning(), is(true));
assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getExtraHosts()),
contains("dockerhost:127.0.0.1"));
}
@Test
public void startContainerWithRestartPolicy() throws DockerException {
RestartPolicy restartPolicy = RestartPolicy.onFailureRestart(5);
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
.withRestartPolicy(restartPolicy).exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
dockerClient.startContainerCmd(container.getId()).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
assertThat(inspectContainerResponse.getState().getRunning(), is(true));
assertThat(inspectContainerResponse.getHostConfig().getRestartPolicy(), is(equalTo(restartPolicy)));
}
@Test
public void existingHostConfigIsPreservedByBlankStartCmd() throws DockerException {
String dnsServer = "8.8.8.8";
// prepare a container with custom DNS
CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withDns(dnsServer)
.withCmd("true").exec();
LOG.info("Created container {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
// start container _without_any_customization_ (important!)
dockerClient.startContainerCmd(container.getId()).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
// The DNS setting survived.
assertThat(inspectContainerResponse.getHostConfig().getDns(), is(notNullValue()));
assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getDns()), contains(dnsServer));
}
@Test
public void anUnconfiguredCommandSerializesToEmptyJson() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
StartContainerCmd command = dockerClient.startContainerCmd("");
assertThat(objectMapper.writeValueAsString(command), is("{}"));
}
}