From 2114d0e368cfe457d55dfa6e5c7dc9f116743fbe Mon Sep 17 00:00:00 2001 From: Alex Collins Date: Sun, 26 Oct 2014 11:28:39 +0000 Subject: [PATCH 1/2] Updated DockerClientConfig so that environment properties can be used to configure Docker. Made a couple of public methods private. --- README.md | 24 +- .../dockerjava/core/DockerClientConfig.java | 289 ++++++++--- .../jaxrs/DockerCmdExecFactoryImpl.java | 470 ++++++++---------- src/main/resources/docker.io.properties | 2 +- .../core/DockerClientConfigTest.java | 125 +++++ 5 files changed, 565 insertions(+), 345 deletions(-) create mode 100644 src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java diff --git a/README.md b/README.md index f97ce15bb..8eff82a21 100644 --- a/README.md +++ b/README.md @@ -86,17 +86,17 @@ There are a couple of configuration items, all of which have sensible defaults: There are three ways to configure, in descending order of precedence: -#### Programatic: +#### Programmatic: In your application, e.g. - DockerClientConfigBuilder configBuilder = DockerClientConfig.createDefaultConfigBuilder(); - configBuilder.withVersion("1.15"); - configBuilder.withUri("https://my-docker-host.tld:2376"); - configBuilder.withUsername("dockeruser"); - configBuilder.withPassword("ilovedocker"); - configBuilder.withEmail("dockeruser@github.com"); - configBuilder.withDockerCertPath("/home/user/.docker"); - DockerClientConfig config = configBuilder.build(); + DockerClientConfig config = DockerClientConfig.createDefaultConfigBuilder() + .withVersion("1.15") + .withUri("https://my-docker-host.tld:2376") + .withUsername("dockeruser") + .withPassword("ilovedocker") + .withEmail("dockeruser@github.com") + .withDockerCertPath("/home/user/.docker") + .build(); DockerClient docker = DockerClientBuilder.getInstance(config).build(); #### Properties @@ -113,6 +113,12 @@ In your application, e.g. java -Ddocker.io.username=dockeruser pkg.Main +##### System Environment + + export DOCKER_URL=http://localhost:2376 + +Note: we also auto-detect defaults. If you use `DOCKER_HOST` we use that value, and if `DOCKER_CERT_PATH` is set, we switch to SSL. + ##### File System In `$HOME/.docker.io.properties` diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index 6e3795e97..8ed9a3fa0 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -1,82 +1,96 @@ package com.github.dockerjava.core; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.URI; -import java.util.Properties; + import com.google.common.base.Preconditions; + import com.google.common.collect.ImmutableMap; -import com.google.common.base.Preconditions; + import java.io.File; + import java.io.FileInputStream; + import java.io.IOException; + import java.net.URI; + import java.util.Map; + import java.util.Properties; public class DockerClientConfig { + private static final String DOCKER_HOST_PROPERTY = "DOCKER_HOST"; + private static final String DOCKER_CERT_PATH_PROPERTY = "DOCKER_CERT_PATH"; + private static final String DOCKER_IO_URL_PROPERTY = "docker.io.url"; + private static final String DOCKER_IO_VERSION_PROPERTY = "docker.io.version"; + private static final String DOCKER_IO_USERNAME_PROPERTY = "docker.io.username"; + private static final String DOCKER_IO_PASSWORD_PROPERTY = "docker.io.password"; + private static final String DOCKER_IO_EMAIL_PROPERTY = "docker.io.email"; + private static final String DOCKER_IO_READ_TIMEOUT_PROPERTY = "docker.io.readTimeout"; + // this is really confusing, as there are two ways to spell it + private static final String DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY = "docker.io.enableLoggingFilter"; + private static final String DOCKER_IO_DOCKER_CERT_PATH_PROPERTY = "docker.io.dockerCertPath"; + /** + * A map from the environment name to the interval name. + */ + private static final Map ENV_NAME_TO_IO_NAME = ImmutableMap.builder() + .put("DOCKER_URL", DOCKER_IO_URL_PROPERTY) + .put("DOCKER_VERSION", DOCKER_IO_VERSION_PROPERTY) + .put("DOCKER_USERNAME", DOCKER_IO_USERNAME_PROPERTY) + .put("DOCKER_PASSWORD", DOCKER_IO_PASSWORD_PROPERTY) + .put("DOCKER_EMAIL", DOCKER_IO_EMAIL_PROPERTY) + .put("DOCKER_READ_TIMEOUT", DOCKER_IO_READ_TIMEOUT_PROPERTY) + .put("DOCKER_LOGGING_FILTER_ENABLED", DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY) + .put(DOCKER_CERT_PATH_PROPERTY, DOCKER_IO_DOCKER_CERT_PATH_PROPERTY) + .build(); + private static final String DOCKER_IO_PROPERTIES_PROPERTY = "docker.io.properties"; private final URI uri; private final String version, username, password, email, dockerCertPath; private final Integer readTimeout; private final boolean loggingFilterEnabled; - private DockerClientConfig(DockerClientConfigBuilder builder) { - this.uri = builder.uri; - this.version = builder.version; - this.username = builder.username; - this.password = builder.password; - this.email = builder.email; - this.readTimeout = builder.readTimeout; - this.loggingFilterEnabled = builder.loggingFilterEnabled; - this.dockerCertPath = builder.dockerCertPath; - } - - public URI getUri() { - return uri; - } - - public String getVersion() { - return version; - } - - public String getUsername() { - return username; - } - - public String getPassword() { - return password; - } - - public String getEmail() { - return email; - } - - public Integer getReadTimeout() { - return readTimeout; - } - - public boolean isLoggingFilterEnabled() { - return loggingFilterEnabled; - } - - public String getDockerCertPath() { - return dockerCertPath; + DockerClientConfig(URI uri, String version, String username, String password, String email, String dockerCertPath, Integer readTimeout, boolean loggingFilterEnabled) { + this.uri = uri; + this.version = version; + this.username = username; + this.password = password; + this.email = email; + this.dockerCertPath = dockerCertPath; + this.readTimeout = readTimeout; + this.loggingFilterEnabled = loggingFilterEnabled; } - public static Properties loadIncludedDockerProperties() { + private static Properties loadIncludedDockerProperties(Properties systemProperties) { try { Properties p = new Properties(); - p.load(DockerClientConfig.class.getResourceAsStream("/docker.io.properties")); + p.load(DockerClientConfig.class.getResourceAsStream("/" + DOCKER_IO_PROPERTIES_PROPERTY)); + replaceProperties(p, systemProperties); return p; } catch (IOException e) { throw new RuntimeException(e); } } + private static void replaceProperties(Properties properties, Properties replacements) { + for (Object objectKey : properties.keySet()) { + String key = objectKey.toString(); + properties.setProperty(key, replaceProperties(properties.getProperty(key), replacements)); + } + } + + private static String replaceProperties(String s, Properties replacements) { + for (Map.Entry entry : replacements.entrySet()) { + String key = "${" + entry.getKey() + "}"; + while (s.contains(key)) { + s = s.replace(key, String.valueOf(entry.getValue())); + } + } + return s; + } + /** * Creates a new Properties object containing values overridden from ${user.home}/.docker.io.properties + * * @param p The original set of properties to override * @return A copy of the original Properties with overridden values */ - public static Properties overrideDockerPropertiesWithSettingsFromUserHome(Properties p) { + private static Properties overrideDockerPropertiesWithSettingsFromUserHome(Properties p, Properties systemProperties) { Properties overriddenProperties = new Properties(); overriddenProperties.putAll(p); - final File usersDockerPropertiesFile = new File(System.getProperty("user.home"), ".docker.io.properties"); + final File usersDockerPropertiesFile = new File(systemProperties.getProperty("user.home"), "." + DOCKER_IO_PROPERTIES_PROPERTY); if (usersDockerPropertiesFile.isFile()) { try { final FileInputStream in = new FileInputStream(usersDockerPropertiesFile); @@ -92,39 +106,158 @@ public static Properties overrideDockerPropertiesWithSettingsFromUserHome(Proper return overriddenProperties; } + private static Properties overrideDockerPropertiesWithEnv(Properties properties, Map env) { + Properties overriddenProperties = new Properties(); + overriddenProperties.putAll(properties); + + // special case which is a sensible default + if (env.containsKey(DOCKER_HOST_PROPERTY)) { + overriddenProperties.setProperty(DOCKER_IO_URL_PROPERTY, env.get(DOCKER_HOST_PROPERTY).replace("tcp", protocol(env))); + } + + for (Map.Entry envEntry : env.entrySet()) { + String envKey = envEntry.getKey(); + if (ENV_NAME_TO_IO_NAME.containsKey(envKey)) { + overriddenProperties.setProperty(ENV_NAME_TO_IO_NAME.get(envKey), envEntry.getValue()); + } + } + + return overriddenProperties; + } + + private static String protocol(Map env) { + // if this is set, we assume we need SSL + return env.containsKey(DOCKER_CERT_PATH_PROPERTY) ? "https" : "http"; + } + /** * Creates a new Properties object containing values overridden from the System properties + * * @param p The original set of properties to override * @return A copy of the original Properties with overridden values */ - public static Properties overrideDockerPropertiesWithSystemProperties(Properties p) { + private static Properties overrideDockerPropertiesWithSystemProperties(Properties p, Properties systemProperties) { Properties overriddenProperties = new Properties(); overriddenProperties.putAll(p); - // TODO Add all values from system properties that begin with docker.io.* - for (String s : new String[]{ "url", "version", "username", "password", "email", "readTimeout", "enableLoggingFilter", "dockerCertPath"}) { - final String key = "docker.io." + s; - if (System.getProperties().containsKey(key)) { - overriddenProperties.setProperty(key, System.getProperty(key)); - } - } + for (String key : new String[]{ + DOCKER_IO_URL_PROPERTY, + DOCKER_IO_VERSION_PROPERTY, + DOCKER_IO_USERNAME_PROPERTY, + DOCKER_IO_PASSWORD_PROPERTY, + DOCKER_IO_EMAIL_PROPERTY, + DOCKER_IO_READ_TIMEOUT_PROPERTY, + DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY, + DOCKER_IO_DOCKER_CERT_PATH_PROPERTY, + }) { + if (systemProperties.containsKey(key)) { + overriddenProperties.setProperty(key, systemProperties.getProperty(key)); + } + } return overriddenProperties; } public static DockerClientConfigBuilder createDefaultConfigBuilder() { - Properties properties = loadIncludedDockerProperties(); - properties = overrideDockerPropertiesWithSettingsFromUserHome(properties); - properties = overrideDockerPropertiesWithSystemProperties(properties); + return createDefaultConfigBuilder(System.getenv(), System.getProperties()); + } + + /** + * Allows you to build the config without system environment interfering for more robust testing + */ + static DockerClientConfigBuilder createDefaultConfigBuilder(Map env, Properties systemProperties) { + Properties properties = loadIncludedDockerProperties(systemProperties); + properties = overrideDockerPropertiesWithSettingsFromUserHome(properties, systemProperties); + properties = overrideDockerPropertiesWithEnv(properties, env); + properties = overrideDockerPropertiesWithSystemProperties(properties, systemProperties); return new DockerClientConfigBuilder().withProperties(properties); } + public URI getUri() { + return uri; + } + + public String getVersion() { + return version; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getEmail() { + return email; + } + + public Integer getReadTimeout() { + return readTimeout; + } + + public boolean isLoggingFilterEnabled() { + return loggingFilterEnabled; + } + + public String getDockerCertPath() { + return dockerCertPath; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DockerClientConfig that = (DockerClientConfig) o; + + if (loggingFilterEnabled != that.loggingFilterEnabled) return false; + if (dockerCertPath != null ? !dockerCertPath.equals(that.dockerCertPath) : that.dockerCertPath != null) + return false; + if (email != null ? !email.equals(that.email) : that.email != null) return false; + if (password != null ? !password.equals(that.password) : that.password != null) return false; + if (readTimeout != null ? !readTimeout.equals(that.readTimeout) : that.readTimeout != null) return false; + if (uri != null ? !uri.equals(that.uri) : that.uri != null) return false; + if (username != null ? !username.equals(that.username) : that.username != null) return false; + if (version != null ? !version.equals(that.version) : that.version != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = uri != null ? uri.hashCode() : 0; + result = 31 * result + (version != null ? version.hashCode() : 0); + result = 31 * result + (username != null ? username.hashCode() : 0); + result = 31 * result + (password != null ? password.hashCode() : 0); + result = 31 * result + (email != null ? email.hashCode() : 0); + result = 31 * result + (dockerCertPath != null ? dockerCertPath.hashCode() : 0); + result = 31 * result + (readTimeout != null ? readTimeout.hashCode() : 0); + result = 31 * result + (loggingFilterEnabled ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "DockerClientConfig{" + + "uri=" + uri + + ", version='" + version + '\'' + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", email='" + email + '\'' + + ", dockerCertPath='" + dockerCertPath + '\'' + + ", readTimeout=" + readTimeout + + ", loggingFilterEnabled=" + loggingFilterEnabled + + '}'; + } + public static class DockerClientConfigBuilder { private URI uri; private String version, username, password, email, dockerCertPath; private Integer readTimeout; private boolean loggingFilterEnabled; - public DockerClientConfigBuilder() { + private DockerClientConfigBuilder() { } /** @@ -132,19 +265,16 @@ public DockerClientConfigBuilder() { * should contain the following docker.io.* keys: url, version, username, password, email, and dockerCertPath. If * docker.io.readTimeout or docker.io.enableLoggingFilter are not contained, they will be set to 1000 and true, * respectively. - * - * @param p - * @return */ public DockerClientConfigBuilder withProperties(Properties p) { - return withUri(p.getProperty("docker.io.url")) - .withVersion(p.getProperty("docker.io.version")) - .withUsername(p.getProperty("docker.io.username")) - .withPassword(p.getProperty("docker.io.password")) - .withEmail(p.getProperty("docker.io.email")) - .withReadTimeout(Integer.valueOf(p.getProperty("docker.io.readTimeout", "0"))) - .withLoggingFilter(Boolean.valueOf(p.getProperty("docker.io.enableLoggingFilter", "true"))) - .withDockerCertPath(p.getProperty("docker.io.dockerCertPath")); + return withUri(p.getProperty(DOCKER_IO_URL_PROPERTY)) + .withVersion(p.getProperty(DOCKER_IO_VERSION_PROPERTY)) + .withUsername(p.getProperty(DOCKER_IO_USERNAME_PROPERTY)) + .withPassword(p.getProperty(DOCKER_IO_PASSWORD_PROPERTY)) + .withEmail(p.getProperty(DOCKER_IO_EMAIL_PROPERTY)) + .withReadTimeout(Integer.valueOf(p.getProperty(DOCKER_IO_READ_TIMEOUT_PROPERTY, "0"))) + .withLoggingFilter(Boolean.valueOf(p.getProperty(DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY, "true"))) + .withDockerCertPath(p.getProperty(DOCKER_IO_DOCKER_CERT_PATH_PROPERTY)); } public final DockerClientConfigBuilder withUri(String uri) { @@ -181,7 +311,16 @@ public final DockerClientConfigBuilder withDockerCertPath(String dockerCertPath) return this; } public DockerClientConfig build() { - return new DockerClientConfig(this); + return new DockerClientConfig( + uri, + version, + username, + password, + email, + dockerCertPath, + readTimeout, + loggingFilterEnabled + ); } } } diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index cb912873d..862824fcc 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -2,74 +2,37 @@ import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import com.github.dockerjava.api.DockerClientException; -import com.github.dockerjava.api.command.AttachContainerCmd; -import com.github.dockerjava.api.command.AuthCmd; -import com.github.dockerjava.api.command.BuildImageCmd; -import com.github.dockerjava.api.command.CommitCmd; -import com.github.dockerjava.api.command.ContainerDiffCmd; -import com.github.dockerjava.api.command.CopyFileFromContainerCmd; -import com.github.dockerjava.api.command.CreateContainerCmd; -import com.github.dockerjava.api.command.CreateImageCmd; -import com.github.dockerjava.api.command.DockerCmdExecFactory; -import com.github.dockerjava.api.command.EventsCmd; -import com.github.dockerjava.api.command.InfoCmd; -import com.github.dockerjava.api.command.InspectContainerCmd; -import com.github.dockerjava.api.command.InspectImageCmd; -import com.github.dockerjava.api.command.KillContainerCmd; -import com.github.dockerjava.api.command.ListContainersCmd; -import com.github.dockerjava.api.command.ListImagesCmd; -import com.github.dockerjava.api.command.LogContainerCmd; -import com.github.dockerjava.api.command.PauseContainerCmd; -import com.github.dockerjava.api.command.PingCmd; -import com.github.dockerjava.api.command.PullImageCmd; -import com.github.dockerjava.api.command.PushImageCmd; -import com.github.dockerjava.api.command.RemoveContainerCmd; -import com.github.dockerjava.api.command.RemoveImageCmd; -import com.github.dockerjava.api.command.RestartContainerCmd; -import com.github.dockerjava.api.command.SearchImagesCmd; -import com.github.dockerjava.api.command.StartContainerCmd; -import com.github.dockerjava.api.command.StopContainerCmd; -import com.github.dockerjava.api.command.TagImageCmd; -import com.github.dockerjava.api.command.TopContainerCmd; -import com.github.dockerjava.api.command.UnpauseContainerCmd; -import com.github.dockerjava.api.command.VersionCmd; -import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.*; import com.github.dockerjava.core.CertificateUtils; import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.jaxrs.util.JsonClientFilter; import com.github.dockerjava.jaxrs.util.ResponseStatusExceptionFilter; import com.github.dockerjava.jaxrs.util.SelectiveLoggingFilter; import com.google.common.base.Preconditions; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.glassfish.jersey.CommonProperties; +import org.glassfish.jersey.SslConfigurator; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; -import java.io.File; +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; import java.io.IOException; import java.security.KeyStore; import java.security.Security; import java.util.logging.Logger; -import javax.net.ssl.SSLContext; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; +public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.glassfish.jersey.CommonProperties; -import org.glassfish.jersey.SslConfigurator; -import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.client.ClientProperties; + private static final Logger LOGGER = Logger.getLogger(DockerCmdExecFactoryImpl.class.getName()); + private Client client; + private WebTarget baseResource; -public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { - - private Client client; - - private WebTarget baseResource; - - private static final Logger LOGGER = Logger.getLogger(DockerCmdExecFactoryImpl.class.getName()); - - - @Override - public void init(DockerClientConfig dockerClientConfig) { - Preconditions.checkNotNull(dockerClientConfig, "config was not specified"); + @Override + public void init(DockerClientConfig dockerClientConfig) { + Preconditions.checkNotNull(dockerClientConfig, "config was not specified"); ClientConfig clientConfig = new ClientConfig(); clientConfig.property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); @@ -81,240 +44,227 @@ public void init(DockerClientConfig dockerClientConfig) { if (dockerClientConfig.isLoggingFilterEnabled()) { clientConfig.register(new SelectiveLoggingFilter(LOGGER, true)); } - + if (dockerClientConfig.getReadTimeout() != null) { - int readTimeout = dockerClientConfig.getReadTimeout(); - clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout); + int readTimeout = dockerClientConfig.getReadTimeout(); + clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout); } - + ClientBuilder clientBuilder = ClientBuilder.newBuilder().withConfig(clientConfig); - - // Attempt to load Docker SSL certificates from location in following order: - // 1. User Defined - // 2. Environment Variable - // 3. User Home Directory + String dockerCertPath = dockerClientConfig.getDockerCertPath(); - - if(dockerCertPath == null) { - dockerCertPath = System.getenv("DOCKER_CERT_PATH"); - } - - if(dockerCertPath == null) { - dockerCertPath = System.getProperty("USER_HOME") + File.separator + ".docker"; - } - - if(dockerCertPath != null) { + + if (dockerCertPath != null) { boolean certificatesExist = CertificateUtils.verifyCertificatesExist(dockerCertPath); - - if(certificatesExist) { - + + if (certificatesExist) { + try { - + Security.addProvider(new BouncyCastleProvider()); - + KeyStore keyStore = CertificateUtils.createKeyStore(dockerCertPath); KeyStore trustStore = CertificateUtils.createTrustStore(dockerCertPath); - + // properties acrobatics not needed for java > 1.6 String httpProtocols = System.getProperty("https.protocols"); System.setProperty("https.protocols", "TLSv1"); SslConfigurator sslConfig = SslConfigurator.newInstance(true); - if(httpProtocols != null ) System.setProperty("https.protocols", httpProtocols); - + if (httpProtocols != null) System.setProperty("https.protocols", httpProtocols); + sslConfig.keyStore(keyStore); sslConfig.keyStorePassword("docker"); sslConfig.trustStore(trustStore); - + SSLContext sslContext = sslConfig.createSSLContext(); - - - clientBuilder.sslContext(sslContext); - } - catch(Exception e) { + + clientBuilder.sslContext(sslContext); + + } catch (Exception e) { throw new DockerClientException(e.getMessage(), e); } - + } } - + client = clientBuilder.build(); - + WebTarget webResource = client.target(dockerClientConfig.getUri()); if (dockerClientConfig.getVersion() == null || dockerClientConfig.getVersion().isEmpty()) { - baseResource = webResource; + baseResource = webResource; } else { - baseResource = webResource.path("v" + dockerClientConfig.getVersion()); + baseResource = webResource.path("v" + dockerClientConfig.getVersion()); } - - } - - protected WebTarget getBaseResource() { - Preconditions.checkNotNull(baseResource, "Factory not initialized. You probably forgot to call init()!"); - return baseResource; - } - - @Override - public AuthCmd.Exec createAuthCmdExec() { - return new AuthCmdExec(getBaseResource()); - } - - @Override - public InfoCmd.Exec createInfoCmdExec() { - return new InfoCmdExec(getBaseResource()); - } - - @Override - public PingCmd.Exec createPingCmdExec() { - return new PingCmdExec(getBaseResource()); - } - - @Override - public VersionCmd.Exec createVersionCmdExec() { - return new VersionCmdExec(getBaseResource()); - } - - @Override - public PullImageCmd.Exec createPullImageCmdExec() { - return new PullImageCmdExec(getBaseResource()); - } - - @Override - public PushImageCmd.Exec createPushImageCmdExec() { - return new PushImageCmdExec(getBaseResource()); - } - - @Override - public CreateImageCmd.Exec createCreateImageCmdExec() { - return new CreateImageCmdExec(getBaseResource()); - } - - @Override - public SearchImagesCmd.Exec createSearchImagesCmdExec() { - return new SearchImagesCmdExec(getBaseResource()); - } - - @Override - public RemoveImageCmd.Exec createRemoveImageCmdExec() { - return new RemoveImageCmdExec(getBaseResource()); - } - - @Override - public ListImagesCmd.Exec createListImagesCmdExec() { - return new ListImagesCmdExec(getBaseResource()); - } - - @Override - public InspectImageCmd.Exec createInspectImageCmdExec() { - return new InspectImageCmdExec(getBaseResource()); - } - - @Override - public ListContainersCmd.Exec createListContainersCmdExec() { - return new ListContainersCmdExec(getBaseResource()); - } - - @Override - public CreateContainerCmd.Exec createCreateContainerCmdExec() { - return new CreateContainerCmdExec(getBaseResource()); - } - - @Override - public StartContainerCmd.Exec createStartContainerCmdExec() { - return new StartContainerCmdExec(getBaseResource()); - } - - @Override - public InspectContainerCmd.Exec createInspectContainerCmdExec() { - return new InspectContainerCmdExec(getBaseResource()); - } - - @Override - public RemoveContainerCmd.Exec createRemoveContainerCmdExec() { - return new RemoveContainerCmdExec(getBaseResource()); - } - - @Override - public WaitContainerCmd.Exec createWaitContainerCmdExec() { - return new WaitContainerCmdExec(getBaseResource()); - } - - @Override - public AttachContainerCmd.Exec createAttachContainerCmdExec() { - return new AttachContainerCmdExec(getBaseResource()); - } - - @Override - public LogContainerCmd.Exec createLogContainerCmdExec() { - return new LogContainerCmdExec(getBaseResource()); - } - - @Override - public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() { - return new CopyFileFromContainerCmdExec(getBaseResource()); - } - - @Override - public StopContainerCmd.Exec createStopContainerCmdExec() { - return new StopContainerCmdExec(getBaseResource()); - } - - @Override - public ContainerDiffCmd.Exec createContainerDiffCmdExec() { - return new ContainerDiffCmdExec(getBaseResource()); - } - - @Override - public KillContainerCmd.Exec createKillContainerCmdExec() { - return new KillContainerCmdExec(getBaseResource()); - } - - @Override - public RestartContainerCmd.Exec createRestartContainerCmdExec() { - return new RestartContainerCmdExec(getBaseResource()); - } - - @Override - public CommitCmd.Exec createCommitCmdExec() { - return new CommitCmdExec(getBaseResource()); - } - - @Override - public BuildImageCmd.Exec createBuildImageCmdExec() { - return new BuildImageCmdExec(getBaseResource()); - } - - @Override - public TopContainerCmd.Exec createTopContainerCmdExec() { - return new TopContainerCmdExec(getBaseResource()); - } - - @Override - public TagImageCmd.Exec createTagImageCmdExec() { - return new TagImageCmdExec(getBaseResource()); - } - - @Override - public PauseContainerCmd.Exec createPauseContainerCmdExec() { - return new PauseContainerCmdExec(getBaseResource()); - } - - @Override - public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() { - return new UnpauseContainerCmdExec(baseResource); - } - - @Override - public EventsCmd.Exec createEventsCmdExec() { - return new EventsCmdExec(getBaseResource()); - } - - @Override - public void close() throws IOException { - Preconditions.checkNotNull(client, "Factory not initialized. You probably forgot to call init()!"); - client.close(); - } + + } + + protected WebTarget getBaseResource() { + Preconditions.checkNotNull(baseResource, "Factory not initialized. You probably forgot to call init()!"); + return baseResource; + } + + @Override + public AuthCmd.Exec createAuthCmdExec() { + return new AuthCmdExec(getBaseResource()); + } + + @Override + public InfoCmd.Exec createInfoCmdExec() { + return new InfoCmdExec(getBaseResource()); + } + + @Override + public PingCmd.Exec createPingCmdExec() { + return new PingCmdExec(getBaseResource()); + } + + @Override + public VersionCmd.Exec createVersionCmdExec() { + return new VersionCmdExec(getBaseResource()); + } + + @Override + public PullImageCmd.Exec createPullImageCmdExec() { + return new PullImageCmdExec(getBaseResource()); + } + + @Override + public PushImageCmd.Exec createPushImageCmdExec() { + return new PushImageCmdExec(getBaseResource()); + } + + @Override + public CreateImageCmd.Exec createCreateImageCmdExec() { + return new CreateImageCmdExec(getBaseResource()); + } + + @Override + public SearchImagesCmd.Exec createSearchImagesCmdExec() { + return new SearchImagesCmdExec(getBaseResource()); + } + + @Override + public RemoveImageCmd.Exec createRemoveImageCmdExec() { + return new RemoveImageCmdExec(getBaseResource()); + } + + @Override + public ListImagesCmd.Exec createListImagesCmdExec() { + return new ListImagesCmdExec(getBaseResource()); + } + + @Override + public InspectImageCmd.Exec createInspectImageCmdExec() { + return new InspectImageCmdExec(getBaseResource()); + } + + @Override + public ListContainersCmd.Exec createListContainersCmdExec() { + return new ListContainersCmdExec(getBaseResource()); + } + + @Override + public CreateContainerCmd.Exec createCreateContainerCmdExec() { + return new CreateContainerCmdExec(getBaseResource()); + } + + @Override + public StartContainerCmd.Exec createStartContainerCmdExec() { + return new StartContainerCmdExec(getBaseResource()); + } + + @Override + public InspectContainerCmd.Exec createInspectContainerCmdExec() { + return new InspectContainerCmdExec(getBaseResource()); + } + + @Override + public RemoveContainerCmd.Exec createRemoveContainerCmdExec() { + return new RemoveContainerCmdExec(getBaseResource()); + } + + @Override + public WaitContainerCmd.Exec createWaitContainerCmdExec() { + return new WaitContainerCmdExec(getBaseResource()); + } + + @Override + public AttachContainerCmd.Exec createAttachContainerCmdExec() { + return new AttachContainerCmdExec(getBaseResource()); + } + + @Override + public LogContainerCmd.Exec createLogContainerCmdExec() { + return new LogContainerCmdExec(getBaseResource()); + } + + @Override + public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() { + return new CopyFileFromContainerCmdExec(getBaseResource()); + } + + @Override + public StopContainerCmd.Exec createStopContainerCmdExec() { + return new StopContainerCmdExec(getBaseResource()); + } + + @Override + public ContainerDiffCmd.Exec createContainerDiffCmdExec() { + return new ContainerDiffCmdExec(getBaseResource()); + } + + @Override + public KillContainerCmd.Exec createKillContainerCmdExec() { + return new KillContainerCmdExec(getBaseResource()); + } + + @Override + public RestartContainerCmd.Exec createRestartContainerCmdExec() { + return new RestartContainerCmdExec(getBaseResource()); + } + + @Override + public CommitCmd.Exec createCommitCmdExec() { + return new CommitCmdExec(getBaseResource()); + } + + @Override + public BuildImageCmd.Exec createBuildImageCmdExec() { + return new BuildImageCmdExec(getBaseResource()); + } + + @Override + public TopContainerCmd.Exec createTopContainerCmdExec() { + return new TopContainerCmdExec(getBaseResource()); + } + + @Override + public TagImageCmd.Exec createTagImageCmdExec() { + return new TagImageCmdExec(getBaseResource()); + } + + @Override + public PauseContainerCmd.Exec createPauseContainerCmdExec() { + return new PauseContainerCmdExec(getBaseResource()); + } + + @Override + public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() { + return new UnpauseContainerCmdExec(baseResource); + } + + @Override + public EventsCmd.Exec createEventsCmdExec() { + return new EventsCmdExec(getBaseResource()); + } + + @Override + public void close() throws IOException { + Preconditions.checkNotNull(client, "Factory not initialized. You probably forgot to call init()!"); + client.close(); + } } diff --git a/src/main/resources/docker.io.properties b/src/main/resources/docker.io.properties index ea8ce7edf..f4d699537 100644 --- a/src/main/resources/docker.io.properties +++ b/src/main/resources/docker.io.properties @@ -1,4 +1,4 @@ docker.io.url=https://localhost:2376 docker.io.version=1.15 docker.io.enableLoggingFilter=true -#docker.io.dockerCertPath= \ No newline at end of file +docker.io.dockerCertPath=${user.home}/.docker \ No newline at end of file diff --git a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java new file mode 100644 index 000000000..b0747e68e --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java @@ -0,0 +1,125 @@ +package com.github.dockerjava.core; + +import org.testng.annotations.Test; + +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import static org.testng.Assert.assertEquals; + +public class DockerClientConfigTest { + + public static final DockerClientConfig EXAMPLE_CONFIG = newExampleConfig(); + + private static DockerClientConfig newExampleConfig() { + return new DockerClientConfig(URI.create("http://foo"), "bar", "baz", "qux", "blam", "flim", 877, false); + } + + @Test + public void string() throws Exception { + assertEquals("DockerClientConfig{uri=http://foo, version='bar', username='baz', password='qux', email='blam', dockerCertPath='flim', readTimeout=877, loggingFilterEnabled=false}", + EXAMPLE_CONFIG.toString()); + } + + @Test + public void equals() throws Exception { + assertEquals(EXAMPLE_CONFIG, newExampleConfig()); + } + + @Test + public void environmentDockerHost() throws Exception { + + // given docker host in env + Map env = new HashMap(System.getenv()); + env.put("DOCKER_HOST", "tcp://baz:8768"); + + // when you build a config + DockerClientConfig config = buildConfig(env, new Properties()); + + // then the URL is that value with "http" instead of "tcp" + assertEquals(config.getUri(), URI.create("http://baz:8768")); + } + + @Test + public void environmentDockerHostHttpsAutoDetect() throws Exception { + + // given docker host in env + Map env = new HashMap(System.getenv()); + env.put("DOCKER_HOST", "tcp://bar:8768"); + // and it looks to be SSL enabled + env.put("DOCKER_CERT_PATH", "any value"); + + // when you build a config + DockerClientConfig config = buildConfig(env, new Properties()); + + // then the URL is that value with "tcp" changed to "https" + assertEquals(config.getUri(), URI.create("https://bar:8768")); + } + + @Test + public void environment() throws Exception { + + // given a default config in env properties + Map env = new HashMap(); + env.put("DOCKER_URL", "http://foo"); + env.put("DOCKER_VERSION", "bar"); + env.put("DOCKER_USERNAME", "baz"); + env.put("DOCKER_PASSWORD", "qux"); + env.put("DOCKER_EMAIL", "blam"); + env.put("DOCKER_CERT_PATH", "flim"); + env.put("DOCKER_READ_TIMEOUT", "877"); + env.put("DOCKER_LOGGING_FILTER_ENABLED", "false"); + + // when you build a config + DockerClientConfig config = buildConfig(env, new Properties()); + + // then we get the example object + assertEquals(config, EXAMPLE_CONFIG); + } + + private DockerClientConfig buildConfig(Map env, Properties systemProperties) { + return DockerClientConfig.createDefaultConfigBuilder(env, systemProperties).build(); + } + + @Test + public void defaults() throws Exception { + + // given default cert path + Properties systemProperties = new Properties(); + systemProperties.setProperty("user.home", "someHomeDir"); + + // when you build config + DockerClientConfig config = buildConfig(Collections.emptyMap(), systemProperties); + + // then the cert path is as expected + assertEquals(config.getUri(), URI.create("https://localhost:2376")); + assertEquals(config.getVersion(), "1.15"); + assertEquals(config.isLoggingFilterEnabled(), true); + assertEquals(config.getDockerCertPath(), "someHomeDir/.docker"); + } + + @Test + public void systemProperties() throws Exception { + + // given system properties based on the example + Properties systemProperties = new Properties(); + systemProperties.setProperty("docker.io.url", "http://foo"); + systemProperties.setProperty("docker.io.version", "bar"); + systemProperties.setProperty("docker.io.username", "baz"); + systemProperties.setProperty("docker.io.password", "qux"); + systemProperties.setProperty("docker.io.email", "blam"); + systemProperties.setProperty("docker.io.dockerCertPath", "flim"); + systemProperties.setProperty("docker.io.readTimeout", "877"); + systemProperties.setProperty("docker.io.enableLoggingFilter", "false"); + + // when you build new config + DockerClientConfig config = buildConfig(Collections.emptyMap(), systemProperties); + + // then it is the same as the example + assertEquals(config, EXAMPLE_CONFIG); + + } +} \ No newline at end of file From 80d1a3d3d8b84b69cd7aa62aee1811a2da9c0bb3 Mon Sep 17 00:00:00 2001 From: Alex Collins Date: Sun, 26 Oct 2014 13:38:54 +0000 Subject: [PATCH 2/2] made method public --- .../dockerjava/core/DockerClientConfig.java | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index 8ed9a3fa0..c12585a54 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -1,14 +1,14 @@ - package com.github.dockerjava.core; +package com.github.dockerjava.core; - import com.google.common.base.Preconditions; - import com.google.common.collect.ImmutableMap; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; - import java.io.File; - import java.io.FileInputStream; - import java.io.IOException; - import java.net.URI; - import java.util.Map; - import java.util.Properties; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Properties; public class DockerClientConfig { private static final String DOCKER_HOST_PROPERTY = "DOCKER_HOST"; @@ -257,9 +257,6 @@ public static class DockerClientConfigBuilder { private Integer readTimeout; private boolean loggingFilterEnabled; - private DockerClientConfigBuilder() { - } - /** * This will set all fields in the builder to those contained in the Properties object. The Properties object * should contain the following docker.io.* keys: url, version, username, password, email, and dockerCertPath. If @@ -278,38 +275,46 @@ public DockerClientConfigBuilder withProperties(Properties p) { } public final DockerClientConfigBuilder withUri(String uri) { - Preconditions.checkNotNull(uri, "uri was not specified"); + Preconditions.checkNotNull(uri, "uri was not specified"); this.uri = URI.create(uri); return this; } + public final DockerClientConfigBuilder withVersion(String version) { - this.version = version; + this.version = version; return this; } + public final DockerClientConfigBuilder withUsername(String username) { - this.username = username; + this.username = username; return this; } + public final DockerClientConfigBuilder withPassword(String password) { - this.password = password; + this.password = password; return this; } + public final DockerClientConfigBuilder withEmail(String email) { - this.email = email; + this.email = email; return this; } + public final DockerClientConfigBuilder withReadTimeout(Integer readTimeout) { - this.readTimeout = readTimeout; + this.readTimeout = readTimeout; return this; } + public final DockerClientConfigBuilder withLoggingFilter(boolean loggingFilterEnabled) { this.loggingFilterEnabled = loggingFilterEnabled; return this; } + public final DockerClientConfigBuilder withDockerCertPath(String dockerCertPath) { this.dockerCertPath = dockerCertPath; return this; } + public DockerClientConfig build() { return new DockerClientConfig( uri,