diff --git a/apis/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java b/apis/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java index 8a42253bad..1ff4b44b51 100644 --- a/apis/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java +++ b/apis/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java @@ -95,6 +95,7 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable protected Map extraHosts = ImmutableMap.of(); protected List volumesFrom = ImmutableList.of(); protected boolean privileged; + protected boolean openStdin; protected Config.Builder configBuilder; @Override @@ -122,6 +123,7 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable eTo.extraHosts(extraHosts); eTo.volumesFrom(volumesFrom); eTo.privileged(privileged); + eTo.openStdin(openStdin); eTo.configBuilder(configBuilder); } } @@ -147,6 +149,7 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable equal(this.extraHosts, that.extraHosts) && equal(this.volumesFrom, that.volumesFrom) && equal(this.privileged, that.privileged) && + equal(this.openStdin, that.openStdin) && buildersEqual(this.configBuilder, that.configBuilder); } @@ -161,7 +164,7 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable @Override public int hashCode() { return Objects.hashCode(super.hashCode(), volumes, hostname, dns, memory, entrypoint, commands, cpuShares, env, - portBindings, extraHosts, configBuilder); + portBindings, extraHosts, volumesFrom, privileged, openStdin, configBuilder); } @Override @@ -179,6 +182,8 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable .add("networkMode", networkMode) .add("extraHosts", extraHosts) .add("volumesFrom", volumesFrom) + .add("privileged", privileged) + .add("openStdin", openStdin) .add("configBuilder", configBuilder) .toString(); } @@ -304,6 +309,17 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable return this; } + /** + * Keep {@code STDIN} open when running interactive workloads in the container. + * + * @param openStdin Whether the container should keep STDIN open + * @return this instance + */ + public DockerTemplateOptions openStdin(boolean openStdin) { + this.openStdin = openStdin; + return this; + } + /** * This method sets Config.Builder configuration object, which can be used as * a replacement for all the other settings from this class. Some values in @@ -347,6 +363,8 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable public boolean getPrivileged() { return privileged; } + public boolean getOpenStdin() { return openStdin; } + public Config.Builder getConfigBuilder() { return configBuilder; } public static class Builder { @@ -479,6 +497,14 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable return options.privileged(privileged); } + /** + * @see DockerTemplateOptions#openStdin(boolean) + */ + public static DockerTemplateOptions openStdin(boolean openStdin) { + DockerTemplateOptions options = new DockerTemplateOptions(); + return options.openStdin(openStdin); + } + /** * @see DockerTemplateOptions#configBuilder(Config.Builder) */ diff --git a/apis/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java b/apis/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java index ebd7f5b57b..a1c9caea60 100644 --- a/apis/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java +++ b/apis/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java @@ -98,6 +98,7 @@ public class DockerComputeServiceAdapter implements containerConfigBuilder.memory(templateOptions.getMemory()); containerConfigBuilder.hostname(templateOptions.getHostname()); containerConfigBuilder.cpuShares(templateOptions.getCpuShares()); + containerConfigBuilder.openStdin(templateOptions.getOpenStdin()); containerConfigBuilder.env(templateOptions.getEnv()); if (!templateOptions.getVolumes().isEmpty()) { @@ -110,13 +111,13 @@ public class DockerComputeServiceAdapter implements HostConfig.Builder hostConfigBuilder = HostConfig.builder() .publishAllPorts(true) - .privileged( templateOptions.getPrivileged() ); + .privileged(templateOptions.getPrivileged()); if (!templateOptions.getPortBindings().isEmpty()) { Map>> portBindings = Maps.newHashMap(); for (Map.Entry entry : templateOptions.getPortBindings().entrySet()) { portBindings.put(entry.getValue() + "/tcp", - Lists.>newArrayList(ImmutableMap.of("HostPort", Integer.toString(entry.getKey())))); + Lists.>newArrayList(ImmutableMap.of("HostIp", "0.0.0.0", "HostPort", Integer.toString(entry.getKey())))); } hostConfigBuilder.portBindings(portBindings); } @@ -167,6 +168,22 @@ public class DockerComputeServiceAdapter implements // build once more after setting inboundPorts containerConfig = containerConfigBuilder.build(); + // finally update port bindings + Map>> portBindings = Maps.newHashMap(); + Map>> existingBindings = containerConfig.hostConfig().portBindings(); + if (existingBindings != null) { + portBindings.putAll(existingBindings); + } + for (String exposedPort : containerConfig.exposedPorts().keySet()) { + if (!portBindings.containsKey(exposedPort)) { + portBindings.put(exposedPort, Lists.>newArrayList(ImmutableMap.of("HostIp", "0.0.0.0"))); + } + } + HostConfig.Builder hostConfigBuilder = HostConfig.builder().fromHostConfig(containerConfig.hostConfig()); + hostConfigBuilder.portBindings(portBindings); + containerConfigBuilder.hostConfig(hostConfigBuilder.build()); + containerConfig = containerConfigBuilder.build(); + logger.debug(">> creating new container with containerConfig(%s)", containerConfig); Container container = api.getContainerApi().createContainer(name, containerConfig); logger.trace("<< container(%s)", container.id());