diff --git a/README.md b/README.md index 26ec653ac..0b519d0f3 100644 --- a/README.md +++ b/README.md @@ -85,13 +85,15 @@ For code examples, please look at the [Wiki](https://github.com/docker-java/dock There are a couple of configuration items, all of which have sensible defaults: -* `url` The Docker URL, e.g. `https://localhost:2376` or `unix:///var/run/docker.sock` -* `version` The API version, e.g. `1.16`. -* `username` Your registry username (required to push containers). -* `password` Your registry password. -* `email` Your registry email. -* `serverAddress` Your registry's address. -* `dockerCertPath` Path to the docker certs. +* `DOCKER_HOST` The Docker Host URL, e.g. `tcp://localhost:2376` or `unix:///var/run/docker.sock` +* `DOCKER_TLS_VERIFY` enable/disable TLS verification (switch between `http` and `https` protocol) +* `DOCKER_CERT_PATH` Path to the certificates needed for TLS verification +* `DOCKER_CONFIG` Path for additional docker configuration files (like `.dockercfg`) +* `api.version` The API version, e.g. `1.21`. +* `registry.url` Your registry's address. +* `registry.username` Your registry username (required to push containers). +* `registry.password` Your registry password. +* `registry.email` Your registry email. There are three ways to configure, in descending order of precedence: @@ -99,42 +101,46 @@ There are three ways to configure, in descending order of precedence: In your application, e.g. DockerClientConfig config = DockerClientConfig.createDefaultConfigBuilder() - .withVersion("1.16") - .withUri("https://my-docker-host.tld:2376") - .withUsername("dockeruser") - .withPassword("ilovedocker") - .withEmail("dockeruser@github.com") - .withServerAddress("https://index.docker.io/v1/") - .withDockerCertPath("/home/user/.docker") + .withDockerHost("tcp://my-docker-host.tld:2376") + .withDockerTlsVerify(true) + .withDockerCertPath("/home/user/.docker/certs") + .withDockerConfig("/home/user/.docker") + .withApiVersion("1.21") + .withRegistryUrl("https://index.docker.io/v1/") + .withRegistryUsername("dockeruser") + .withRegistryPassword("ilovedocker") + .withRegistryEmail("dockeruser@github.com") .build(); DockerClient docker = DockerClientBuilder.getInstance(config).build(); -#### Properties - - docker.io.url=https://localhost:2376 - docker.io.version=1.16 - docker.io.username=dockeruser - docker.io.password=ilovedocker - docker.io.email=dockeruser@github.com - docker.io.serverAddress=https://index.docker.io/v1/ - docker.io.dockerCertPath=/home/user/.docker +#### Properties (docker-java.properties) + DOCKER_HOST=tcp://localhost:2376 + DOCKER_TLS_VERIFY=1 + DOCKER_CERT_PATH=/home/user/.docker/certs + DOCKER_CONFIG=/home/user/.docker + api.version=1.21 + registry.url=https://index.docker.io/v1/ + registry.username=dockeruser + registry.password=ilovedocker + registry.email=dockeruser@github.com ##### System Properties: - java -Ddocker.io.username=dockeruser pkg.Main + java -Dregistry.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` or `DOCKER_TLS_VERIFY=1` is set, we switch to SSL. + export DOCKER_URL=tcp://localhost:2376 + export DOCKER_TLS_VERIFY=1 + export DOCKER_CERT_PATH=/home/user/.docker/certs + export DOCKER_CONFIG=/home/user/.docker ##### File System -In `$HOME/.docker.io.properties` +In `$HOME/.docker-java.properties` ##### Class Path -In the class path at `/docker.io.properties` +In the class path at `/docker-java.properties` diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java index fb1715e38..fc793558f 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -3,6 +3,8 @@ import java.io.Closeable; import java.io.IOException; +import javax.net.ssl.SSLContext; + import com.github.dockerjava.core.DockerClientConfig; public interface DockerCmdExecFactory extends Closeable { @@ -105,6 +107,8 @@ public interface DockerCmdExecFactory extends Closeable { public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec(); + public DockerCmdExecFactory withSSLContext(SSLContext sslContext); + @Override public void close() throws IOException; diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index fa5c77e6a..12d09664c 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -8,10 +8,17 @@ import java.io.InputStream; import java.io.Serializable; import java.net.URI; -import java.util.Collections; -import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Properties; +import java.util.Set; + +import org.apache.commons.lang.BooleanUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.model.AuthConfig; @@ -19,74 +26,107 @@ import com.github.dockerjava.core.NameParser.HostnameReposName; import com.github.dockerjava.core.NameParser.ReposTag; +/** + * Respects some of the docker CLI options. See https://docs.docker.com/engine/reference/commandline/cli/#environment-variables + */ public class DockerClientConfig implements Serializable { private static final long serialVersionUID = -4307357472441531489L; - private static final String DOCKER_HOST_PROPERTY = "DOCKER_HOST"; + public static final String DOCKER_HOST = "DOCKER_HOST"; - private static final String DOCKER_CERT_PATH_PROPERTY = "DOCKER_CERT_PATH"; + public static final String DOCKER_TLS_VERIFY = "DOCKER_TLS_VERIFY"; - private static final String DOCKER_VERIFY_TLS_PROPERTY = "DOCKER_TLS_VERIFY"; + public static final String DOCKER_CONFIG = "DOCKER_CONFIG"; - private static final String DOCKER_IO_URL_PROPERTY = "docker.io.url"; + public static final String DOCKER_CERT_PATH = "DOCKER_CERT_PATH"; - private static final String DOCKER_IO_VERSION_PROPERTY = "docker.io.version"; + public static final String API_VERSION = "api.version"; - private static final String DOCKER_IO_USERNAME_PROPERTY = "docker.io.username"; + public static final String REGISTRY_USERNAME = "registry.username"; - private static final String DOCKER_IO_PASSWORD_PROPERTY = "docker.io.password"; + public static final String REGISTRY_PASSWORD = "registry.password"; - private static final String DOCKER_IO_EMAIL_PROPERTY = "docker.io.email"; + public static final String REGISTRY_EMAIL = "registry.email"; - private static final String DOCKER_IO_SERVER_ADDRESS_PROPERTY = "docker.io.serverAddress"; + public static final String REGISTRY_URL = "registry.url"; - private static final String DOCKER_IO_DOCKER_CERT_PATH_PROPERTY = "docker.io.dockerCertPath"; + private static final String DOCKER_JAVA_PROPERTIES = "docker-java.properties"; - private static final String DOCKER_IO_DOCKER_CFG_PATH_PROPERTY = "docker.io.dockerCfgPath"; + private static final String DOCKER_CFG = ".dockercfg"; + + private static final Set configKeys = new HashSet(); - /** - * A map from the environment name to the interval name. - */ - // Immutable ish - private static final Map ENV_NAME_TO_IO_NAME; static { - Map m = new HashMap(); - m.put("DOCKER_URL", DOCKER_IO_URL_PROPERTY); - m.put("DOCKER_VERSION", DOCKER_IO_VERSION_PROPERTY); - m.put("DOCKER_USERNAME", DOCKER_IO_USERNAME_PROPERTY); - m.put("DOCKER_PASSWORD", DOCKER_IO_PASSWORD_PROPERTY); - m.put("DOCKER_EMAIL", DOCKER_IO_EMAIL_PROPERTY); - m.put("DOCKER_SERVER_ADDRESS", DOCKER_IO_SERVER_ADDRESS_PROPERTY); - m.put(DOCKER_CERT_PATH_PROPERTY, DOCKER_IO_DOCKER_CERT_PATH_PROPERTY); - m.put("DOCKER_CFG_PATH", DOCKER_IO_DOCKER_CFG_PATH_PROPERTY); - ENV_NAME_TO_IO_NAME = Collections.unmodifiableMap(m); + configKeys.add(DOCKER_HOST); + configKeys.add(DOCKER_TLS_VERIFY); + configKeys.add(DOCKER_CONFIG); + configKeys.add(DOCKER_CERT_PATH); + configKeys.add(API_VERSION); + configKeys.add(REGISTRY_USERNAME); + configKeys.add(REGISTRY_PASSWORD); + configKeys.add(REGISTRY_EMAIL); + configKeys.add(REGISTRY_URL); } - private static final String DOCKER_IO_PROPERTIES_PROPERTY = "docker.io.properties"; + private URI dockerHost; - private URI uri; + private final String registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, dockerCertPath; - private final String username, password, email, serverAddress, dockerCfgPath; + private boolean dockerTlsVerify; - private final RemoteApiVersion version; + private final RemoteApiVersion apiVersion; + + DockerClientConfig(URI dockerHost, String dockerConfig, String apiVersion, String registryUrl, + String registryUsername, String registryPassword, String registryEmail, String dockerCertPath, + boolean dockerTslVerify) { + this.dockerHost = checkDockerHostScheme(dockerHost); + this.dockerTlsVerify = dockerTslVerify; + this.dockerCertPath = checkDockerCertPath(dockerTslVerify, dockerCertPath); + this.dockerConfig = dockerConfig; + this.apiVersion = RemoteApiVersion.parseConfigWithDefault(apiVersion); + this.registryUsername = registryUsername; + this.registryPassword = registryPassword; + this.registryEmail = registryEmail; + this.registryUrl = registryUrl; + } + + private URI checkDockerHostScheme(URI dockerHost) { + if ("tcp".equals(dockerHost.getScheme()) || "unix".equals(dockerHost.getScheme())) { + return dockerHost; + } else { + throw new DockerClientException("Unsupported protocol scheme found: '" + dockerHost + + "'. Only 'tcp://' or 'unix://' supported."); + } + } - private final SSLConfig sslConfig; + private String checkDockerCertPath(boolean dockerTlsVerify, String dockerCertPath) { + if (dockerTlsVerify) { + if (StringUtils.isEmpty(dockerCertPath)) { + throw new DockerClientException( + "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certifate path (DOCKER_CERT_PATH) is not defined."); + } else { + File certPath = new File(dockerCertPath); + + if (!certPath.exists()) { + throw new DockerClientException( + "Certificate path (DOCKER_CERT_PATH) '" + dockerCertPath + "' doesn't exist."); + } - DockerClientConfig(URI uri, String version, String username, String password, String email, String serverAddress, - String dockerCfgPath, SSLConfig sslConfig) { - this.uri = uri; - this.version = RemoteApiVersion.parseConfigWithDefault(version); - this.username = username; - this.password = password; - this.email = email; - this.serverAddress = serverAddress; - this.dockerCfgPath = dockerCfgPath; - this.sslConfig = sslConfig; + if (certPath.isDirectory()) { + return dockerCertPath; + } else { + throw new DockerClientException( + "Certificate path (DOCKER_CERT_PATH) '" + dockerCertPath + "' doesn't point to a directory."); + } + } + } else { + return dockerCertPath; + } } private static Properties loadIncludedDockerProperties(Properties systemProperties) { - try (InputStream is = DockerClientConfig.class.getResourceAsStream("/" + DOCKER_IO_PROPERTIES_PROPERTY)) { + try (InputStream is = DockerClientConfig.class.getResourceAsStream("/" + DOCKER_JAVA_PROPERTIES)) { Properties p = new Properties(); p.load(is); replaceProperties(p, systemProperties); @@ -125,7 +165,7 @@ private static Properties overrideDockerPropertiesWithSettingsFromUserHome(Prope overriddenProperties.putAll(p); final File usersDockerPropertiesFile = new File(systemProperties.getProperty("user.home"), "." - + DOCKER_IO_PROPERTIES_PROPERTY); + + DOCKER_JAVA_PROPERTIES); if (usersDockerPropertiesFile.isFile()) { try { final FileInputStream in = new FileInputStream(usersDockerPropertiesFile); @@ -146,27 +186,20 @@ private static Properties overrideDockerPropertiesWithEnv(Properties 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))); + if (env.containsKey(DOCKER_HOST)) { + overriddenProperties.setProperty(DOCKER_HOST, env.get(DOCKER_HOST)); } 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()); + if (configKeys.contains(envKey)) { + overriddenProperties.setProperty(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) || "1".equals(env.get(DOCKER_VERIFY_TLS_PROPERTY)) ? "https" - : "http"; - } - /** * Creates a new Properties object containing values overridden from the System properties * @@ -178,10 +211,7 @@ private static Properties overrideDockerPropertiesWithSystemProperties(Propertie Properties overriddenProperties = new Properties(); overriddenProperties.putAll(p); - 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_SERVER_ADDRESS_PROPERTY, DOCKER_IO_DOCKER_CERT_PATH_PROPERTY, - DOCKER_IO_DOCKER_CFG_PATH_PROPERTY, }) { + for (String key : configKeys) { if (systemProperties.containsKey(key)) { overriddenProperties.setProperty(key, systemProperties.getProperty(key)); } @@ -204,50 +234,55 @@ static DockerClientConfigBuilder createDefaultConfigBuilder(Map return new DockerClientConfigBuilder().withProperties(properties); } - public URI getUri() { - return uri; + public URI getDockerHost() { + return dockerHost; + } + + public void setDockerHost(URI dockerHost) { + this.dockerHost = dockerHost; } - public void setUri(URI uri) { - this.uri = uri; + public RemoteApiVersion getApiVersion() { + return apiVersion; } - public RemoteApiVersion getVersion() { - return version; + public String getRegistryUsername() { + return registryUsername; } - public String getUsername() { - return username; + public String getRegistryPassword() { + return registryPassword; } - public String getPassword() { - return password; + public String getRegistryEmail() { + return registryEmail; } - public String getEmail() { - return email; + public String getRegistryUrl() { + return registryUrl; } - public String getServerAddress() { - return serverAddress; + public String getDockerConfig() { + return dockerConfig; } - public SSLConfig getSslConfig() { - return sslConfig; + public String getDockerCertPath() { + return dockerCertPath; } - public String getDockerCfgPath() { - return dockerCfgPath; + public boolean getDockerTlsVerify() { + return dockerTlsVerify; } private AuthConfig getAuthConfig() { AuthConfig authConfig = null; - if (getUsername() != null && getPassword() != null && getEmail() != null && getServerAddress() != null) { + if (getRegistryUsername() != null && getRegistryPassword() != null && getRegistryEmail() != null + && getRegistryUrl() != null) { authConfig = new AuthConfig(); - authConfig.setUsername(getUsername()); - authConfig.setPassword(getPassword()); - authConfig.setEmail(getEmail()); - authConfig.setServerAddress(getServerAddress()); + authConfig.setUsername(getRegistryUsername()); + authConfig.setPassword(getRegistryPassword()); + authConfig.setEmail(getRegistryEmail()); + authConfig.setServerAddress(getRegistryUrl()); } return authConfig; } @@ -255,12 +290,12 @@ private AuthConfig getAuthConfig() { public AuthConfig effectiveAuthConfig(String imageName) { AuthConfig authConfig = null; - String dockerCfgFile = getDockerCfgPath(); + File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG); - if (dockerCfgFile != null && imageName != null) { + if (dockerCfgFile.exists() && dockerCfgFile.isFile() && imageName != null) { AuthConfigFile authConfigFile; try { - authConfigFile = AuthConfigFile.loadConfig(new File(dockerCfgFile)); + authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile); } catch (IOException e) { throw new DockerClientException("Failed to parse dockerCfgFile", e); } @@ -279,11 +314,11 @@ public AuthConfig effectiveAuthConfig(String imageName) { } public AuthConfigurations getAuthConfigurations() { - String dockerCfgFile = getDockerCfgPath(); - if (dockerCfgFile != null) { + File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG); + if (dockerCfgFile.exists() && dockerCfgFile.isFile()) { AuthConfigFile authConfigFile; try { - authConfigFile = AuthConfigFile.loadConfig(new File(dockerCfgFile)); + authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile); } catch (IOException e) { throw new DockerClientException("Failed to parse dockerCfgFile", e); } @@ -303,121 +338,98 @@ public boolean equals(Object o) { DockerClientConfig that = (DockerClientConfig) o; - if (sslConfig != null ? !sslConfig.equals(that.sslConfig) : that.sslConfig != null) - return false; - if (dockerCfgPath != null ? !dockerCfgPath.equals(that.dockerCfgPath) : that.dockerCfgPath != 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 (serverAddress != null ? !serverAddress.equals(that.serverAddress) : that.serverAddress != 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; + return EqualsBuilder.reflectionEquals(this, that); } @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 + (serverAddress != null ? serverAddress.hashCode() : 0); - result = 31 * result + (dockerCfgPath != null ? dockerCfgPath.hashCode() : 0); - result = 31 * result + (sslConfig != null ? sslConfig.hashCode() : 0); - return result; + return HashCodeBuilder.reflectionHashCode(this); } @Override public String toString() { - return "DockerClientConfig{" + "uri=" + uri + ", version='" + version + '\'' + ", username='" + username + '\'' - + ", password='" + password + '\'' + ", email='" + email + '\'' + ", serverAddress='" + serverAddress - + '\'' + ", dockerCfgPath='" + dockerCfgPath + '\'' + ", sslConfig='" + sslConfig + '\'' + '}'; + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } public static class DockerClientConfigBuilder { - private URI uri; + private URI dockerHost; - private String version, username, password, email, serverAddress, dockerCfgPath; + private String apiVersion, registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, + dockerCertPath; - private SSLConfig sslConfig; + private boolean dockerTlsVerify; /** - * 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, dockerCertPath, and - * dockerCfgPath. If docker.io.readTimeout or docker.io.enableLoggingFilter are not contained, they will be set - * to 1000 and true, respectively. + * This will set all fields in the builder to those contained in the Properties object. The Properties object should contain the + * following docker-java configuration keys: DOCKER_HOST, DOCKER_TLS_VERIFY, api.version, registry.username, registry.password, + * registry.email, DOCKER_CERT_PATH, and DOCKER_CONFIG. */ public DockerClientConfigBuilder withProperties(Properties p) { - 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)) - .withServerAddress(p.getProperty(DOCKER_IO_SERVER_ADDRESS_PROPERTY)) - .withDockerCertPath(p.getProperty(DOCKER_IO_DOCKER_CERT_PATH_PROPERTY)) - .withDockerCfgPath(p.getProperty(DOCKER_IO_DOCKER_CFG_PATH_PROPERTY)); + return withDockerHost(p.getProperty(DOCKER_HOST)).withDockerTlsVerify(p.getProperty(DOCKER_TLS_VERIFY)) + .withDockerConfig(p.getProperty(DOCKER_CONFIG)).withDockerCertPath(p.getProperty(DOCKER_CERT_PATH)) + .withApiVersion(p.getProperty(API_VERSION)).withRegistryUsername(p.getProperty(REGISTRY_USERNAME)) + .withRegistryPassword(p.getProperty(REGISTRY_PASSWORD)) + .withRegistryEmail(p.getProperty(REGISTRY_EMAIL)).withRegistryUrl(p.getProperty(REGISTRY_URL)); } - public final DockerClientConfigBuilder withUri(String uri) { - checkNotNull(uri, "uri was not specified"); - this.uri = URI.create(uri); + /** + * configure DOCKER_HOST + */ + public final DockerClientConfigBuilder withDockerHost(String dockerHost) { + checkNotNull(dockerHost, "uri was not specified"); + this.dockerHost = URI.create(dockerHost); return this; } - public final DockerClientConfigBuilder withVersion(String version) { - this.version = version; + public final DockerClientConfigBuilder withApiVersion(String apiVersion) { + this.apiVersion = apiVersion; return this; } - public final DockerClientConfigBuilder withUsername(String username) { - this.username = username; + public final DockerClientConfigBuilder withRegistryUsername(String registryUsername) { + this.registryUsername = registryUsername; return this; } - public final DockerClientConfigBuilder withPassword(String password) { - this.password = password; + public final DockerClientConfigBuilder withRegistryPassword(String registryPassword) { + this.registryPassword = registryPassword; return this; } - public final DockerClientConfigBuilder withEmail(String email) { - this.email = email; + public final DockerClientConfigBuilder withRegistryEmail(String registryEmail) { + this.registryEmail = registryEmail; return this; } - public DockerClientConfigBuilder withServerAddress(String serverAddress) { - this.serverAddress = serverAddress; + public DockerClientConfigBuilder withRegistryUrl(String registryUrl) { + this.registryUrl = registryUrl; return this; } public final DockerClientConfigBuilder withDockerCertPath(String dockerCertPath) { - if (dockerCertPath != null) { - this.sslConfig = new LocalDirectorySSLConfig(dockerCertPath); - } + this.dockerCertPath = dockerCertPath; + return this; + } + + public final DockerClientConfigBuilder withDockerConfig(String dockerConfig) { + this.dockerConfig = dockerConfig; return this; } - public final DockerClientConfigBuilder withDockerCfgPath(String dockerCfgPath) { - this.dockerCfgPath = dockerCfgPath; + public final DockerClientConfigBuilder withDockerTlsVerify(String dockerTlsVerify) { + this.dockerTlsVerify = BooleanUtils.toBoolean(dockerTlsVerify.trim()) + || BooleanUtils.toBoolean(dockerTlsVerify.trim(), "1", "0"); return this; } - public final DockerClientConfigBuilder withSSLConfig(SSLConfig config) { - this.sslConfig = config; + public final DockerClientConfigBuilder withDockerTlsVerify(Boolean dockerTlsVerify) { + this.dockerTlsVerify = dockerTlsVerify; return this; } public DockerClientConfig build() { - return new DockerClientConfig(uri, version, username, password, email, serverAddress, dockerCfgPath, - sslConfig); + return new DockerClientConfig(dockerHost, dockerConfig, apiVersion, registryUrl, registryUsername, + registryPassword, registryEmail, dockerCertPath, dockerTlsVerify); } } diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index ede135613..0ee71909c 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -132,7 +132,7 @@ private DockerClientImpl(DockerClientConfig dockerClientConfig) { } private static DockerClientConfig configWithServerUrl(String serverUrl) { - return DockerClientConfig.createDefaultConfigBuilder().withUri(serverUrl).build(); + return DockerClientConfig.createDefaultConfigBuilder().withDockerHost(serverUrl).build(); } public static DockerClientImpl getInstance() { @@ -161,14 +161,14 @@ private DockerCmdExecFactory getDockerCmdExecFactory() { @Override public AuthConfig authConfig() { - checkNotNull(dockerClientConfig.getUsername(), "Configured username is null."); - checkNotNull(dockerClientConfig.getServerAddress(), "Configured serverAddress is null."); + checkNotNull(dockerClientConfig.getRegistryUsername(), "Configured username is null."); + checkNotNull(dockerClientConfig.getRegistryUrl(), "Configured serverAddress is null."); AuthConfig authConfig = new AuthConfig(); - authConfig.setUsername(dockerClientConfig.getUsername()); - authConfig.setPassword(dockerClientConfig.getPassword()); - authConfig.setEmail(dockerClientConfig.getEmail()); - authConfig.setServerAddress(dockerClientConfig.getServerAddress()); + authConfig.setUsername(dockerClientConfig.getRegistryUsername()); + authConfig.setPassword(dockerClientConfig.getRegistryPassword()); + authConfig.setEmail(dockerClientConfig.getRegistryEmail()); + authConfig.setServerAddress(dockerClientConfig.getRegistryUrl()); return authConfig; } diff --git a/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java index d8c84663c..750114b11 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java @@ -46,7 +46,7 @@ protected String registryAuth(AuthConfig authConfig) { protected String registryConfigs(AuthConfigurations authConfigs) { try { final String json; - if (dockerClientConfig.getVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) { + if (dockerClientConfig.getApiVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) { json = new ObjectMapper().writeValueAsString(authConfigs.getConfigs()); } else { json = new ObjectMapper().writeValueAsString(authConfigs); diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index bbd71ba38..337b3e790 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -2,6 +2,33 @@ import static com.google.common.base.Preconditions.checkNotNull; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.ClientRequestFilter; +import javax.ws.rs.client.ClientResponseFilter; +import javax.ws.rs.client.WebTarget; + +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.glassfish.jersey.CommonProperties; +import org.glassfish.jersey.apache.connector.ApacheClientProperties; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import com.github.dockerjava.api.command.AttachContainerCmd; import com.github.dockerjava.api.command.AuthCmd; @@ -54,34 +81,11 @@ import com.github.dockerjava.api.command.WaitContainerCmd; import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.LocalDirectorySSLConfig; import com.github.dockerjava.jaxrs.connector.ApacheConnectorProvider; import com.github.dockerjava.jaxrs.filter.JsonClientFilter; import com.github.dockerjava.jaxrs.filter.ResponseStatusExceptionFilter; import com.github.dockerjava.jaxrs.filter.SelectiveLoggingFilter; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.glassfish.jersey.CommonProperties; -import org.glassfish.jersey.apache.connector.ApacheClientProperties; -import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.client.ClientProperties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.SSLContext; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.ClientRequestFilter; -import javax.ws.rs.client.ClientResponseFilter; -import javax.ws.rs.client.WebTarget; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.URI; -import java.util.List; //import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; // see https://github.com/docker-java/docker-java/issues/196 @@ -108,6 +112,8 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { private DockerClientConfig dockerClientConfig; + SSLContext sslContext = null; + @Override public void init(DockerClientConfig dockerClientConfig) { checkNotNull(dockerClientConfig, "config was not specified"); @@ -146,15 +152,19 @@ public void init(DockerClientConfig dockerClientConfig) { } } - URI originalUri = dockerClientConfig.getUri(); + URI originalUri = dockerClientConfig.getDockerHost(); - SSLContext sslContext = null; String protocol = null; - if (dockerClientConfig.getSslConfig() != null) { + if (dockerClientConfig.getDockerTlsVerify()) { protocol = "https"; + try { - sslContext = dockerClientConfig.getSslConfig().getSSLContext(); + + if (sslContext == null) { + sslContext = new LocalDirectorySSLConfig(dockerClientConfig.getDockerCertPath()).getSSLContext(); + } + } catch (Exception ex) { throw new DockerClientException("Error in SSL Configuration", ex); } @@ -163,8 +173,13 @@ public void init(DockerClientConfig dockerClientConfig) { } if (originalUri.getScheme().equals("unix")) { - dockerClientConfig.setUri(UnixConnectionSocketFactory.sanitizeUri(originalUri)); + dockerClientConfig.setDockerHost(UnixConnectionSocketFactory.sanitizeUri(originalUri)); } else { + try { + originalUri = new URI(originalUri.toString().replaceFirst("tcp", protocol)); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } configureProxy(clientConfig, protocol); } @@ -190,12 +205,12 @@ public void init(DockerClientConfig dockerClientConfig) { client = clientBuilder.build(); - baseResource = client.target(dockerClientConfig.getUri()).path(dockerClientConfig.getVersion().asWebPathPart()); + baseResource = client.target(originalUri.toString()).path(dockerClientConfig.getApiVersion().asWebPathPart()); } private void configureProxy(ClientConfig clientConfig, String protocol) { - List proxies = ProxySelector.getDefault().select(dockerClientConfig.getUri()); + List proxies = ProxySelector.getDefault().select(dockerClientConfig.getDockerHost()); for (Proxy proxy : proxies) { InetSocketAddress address = (InetSocketAddress) proxy.address(); @@ -490,6 +505,12 @@ public void close() throws IOException { client.close(); } + @Override + public DockerCmdExecFactoryImpl withSSLContext(SSLContext sslContext) { + this.sslContext = sslContext; + return this; + } + public DockerCmdExecFactoryImpl withReadTimeout(Integer readTimeout) { this.readTimeout = readTimeout; return this; diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index ee3b50101..d26cf70c0 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -51,6 +51,7 @@ import com.github.dockerjava.api.command.WaitContainerCmd; import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.core.DockerClientImpl; +import com.github.dockerjava.core.LocalDirectorySSLConfig; import com.github.dockerjava.netty.exec.AttachContainerCmdExec; import com.github.dockerjava.netty.exec.AuthCmdExec; import com.github.dockerjava.netty.exec.BuildImageCmdExec; @@ -99,6 +100,7 @@ import com.github.dockerjava.netty.exec.UnpauseContainerCmdExec; import com.github.dockerjava.netty.exec.VersionCmdExec; import com.github.dockerjava.netty.exec.WaitContainerCmdExec; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; @@ -113,11 +115,13 @@ import io.netty.handler.codec.http.HttpClientCodec; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslHandler; + import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters; + import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -157,6 +161,8 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { private NettyInitializer nettyInitializer; + private SSLContext sslContext = null; + private ChannelProvider channelProvider = new ChannelProvider() { @Override public Channel getChannel() { @@ -173,11 +179,11 @@ public void init(DockerClientConfig dockerClientConfig) { bootstrap = new Bootstrap(); - String scheme = dockerClientConfig.getUri().getScheme(); + String scheme = dockerClientConfig.getDockerHost().getScheme(); if ("unix".equals(scheme)) { nettyInitializer = new UnixDomainSocketInitializer(); - } else if (scheme.startsWith("http")) { + } else if ("tcp".equals(scheme)) { nettyInitializer = new InetSocketInitializer(); } @@ -248,8 +254,8 @@ protected void initChannel(final SocketChannel channel) throws Exception { @Override public Channel connect(Bootstrap bootstrap) throws InterruptedException { - String host = dockerClientConfig.getUri().getHost(); - int port = dockerClientConfig.getUri().getPort(); + String host = dockerClientConfig.getDockerHost().getHost(); + int port = dockerClientConfig.getDockerHost().getPort(); if (port == -1) { throw new RuntimeException("no port configured for " + host); @@ -257,7 +263,7 @@ public Channel connect(Bootstrap bootstrap) throws InterruptedException { Channel channel = bootstrap.connect(host, port).sync().channel(); - if ("https".equals(dockerClientConfig.getUri().getScheme())) { + if (dockerClientConfig.getDockerTlsVerify()) { final SslHandler ssl = initSsl(dockerClientConfig); if (ssl != null) { @@ -272,10 +278,12 @@ private SslHandler initSsl(DockerClientConfig dockerClientConfig) { SslHandler ssl = null; try { - String host = dockerClientConfig.getUri().getHost(); - int port = dockerClientConfig.getUri().getPort(); + String host = dockerClientConfig.getDockerHost().getHost(); + int port = dockerClientConfig.getDockerHost().getPort(); - SSLContext sslContext = dockerClientConfig.getSslConfig().getSSLContext(); + if(sslContext == null) { + sslContext = new LocalDirectorySSLConfig(dockerClientConfig.getDockerCertPath()).getSSLContext(); + } SSLEngine engine = sslContext.createSSLEngine(host, port); engine.setUseClientMode(true); @@ -552,6 +560,13 @@ public void close() throws IOException { eventLoopGroup.shutdownGracefully(); } + @Override + public DockerCmdExecFactory withSSLContext(SSLContext sslContext) { + this.sslContext = sslContext; + return this; + } + + private WebTarget getBaseResource() { return new WebTarget(channelProvider); } diff --git a/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java index e8b3597c9..5cf36a0a4 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java @@ -45,7 +45,7 @@ protected String registryAuth(AuthConfig authConfig) { protected String registryConfigs(AuthConfigurations authConfigs) { try { final String json; - if (dockerClientConfig.getVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) { + if (dockerClientConfig.getApiVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) { json = new ObjectMapper().writeValueAsString(authConfigs.getConfigs()); } else { json = new ObjectMapper().writeValueAsString(authConfigs); diff --git a/src/main/resources/docker-java.properties b/src/main/resources/docker-java.properties new file mode 100644 index 000000000..ea85f6c01 --- /dev/null +++ b/src/main/resources/docker-java.properties @@ -0,0 +1,17 @@ +#docker.io.url=https://localhost:2376 +#docker.io.dockerCertPath=${user.home}/.docker +#docker.io.dockerCfgPath=${user.home}/.dockercfg +#docker.io.username=${user.name} +#docker.io.serverAddress=https://index.docker.io/v1/ +# +DOCKER_HOST=tcp://localhost:2376 +DOCKER_TLS_VERIFY=1 +DOCKER_CONFIG=${user.home}/.docker +DOCKER_CERT_PATH=${user.home}/.docker/certs + +api.version= +registry.url=https://index.docker.io/v1/ +registry.username=${user.name} +#registry.password= +#registry.email= + diff --git a/src/main/resources/docker.io.properties b/src/main/resources/docker.io.properties deleted file mode 100644 index 719500e24..000000000 --- a/src/main/resources/docker.io.properties +++ /dev/null @@ -1,5 +0,0 @@ -docker.io.url=https://localhost:2376 -docker.io.dockerCertPath=${user.home}/.docker -docker.io.dockerCfgPath=${user.home}/.dockercfg -docker.io.username=${user.name} -docker.io.serverAddress=https://index.docker.io/v1/ diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java index 074c19ad9..5f63207d1 100644 --- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -74,12 +74,12 @@ private DockerClientConfig config() { protected DockerClientConfig config(String password) { DockerClientConfig.DockerClientConfigBuilder builder = DockerClientConfig.createDefaultConfigBuilder() - .withServerAddress("https://index.docker.io/v1/"); + .withRegistryUrl("https://index.docker.io/v1/"); if (password != null) { - builder = builder.withPassword(password); + builder = builder.withRegistryPassword(password); } - return builder.withVersion(apiVersion).build(); + return builder.withApiVersion(apiVersion).build(); } public void afterTest() { diff --git a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java index 8bb1c3e39..e87254b88 100644 --- a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java +++ b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java @@ -1,8 +1,8 @@ package com.github.dockerjava.core; -import com.github.dockerjava.api.model.AuthConfig; -import org.apache.commons.lang.SerializationUtils; -import org.testng.annotations.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.testng.Assert.assertEquals; import java.net.URI; import java.util.Collections; @@ -10,113 +10,57 @@ import java.util.Map; import java.util.Properties; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.testng.Assert.assertEquals; +import org.apache.commons.lang.SerializationUtils; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.exception.DockerClientException; +import com.github.dockerjava.api.model.AuthConfig; 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", "wham", "flam", - new LocalDirectorySSLConfig("flim")); - } - @Test - public void string() throws Exception { - assertEquals( - EXAMPLE_CONFIG.toString(), - "DockerClientConfig{uri=http://foo, version='{UNKNOWN_VERSION}', username='baz', password='qux', email='blam', serverAddress='wham', dockerCfgPath='flam', sslConfig='LocalDirectorySSLConfig{dockerCertPath=flim}'}"); - } + String dockerCertPath = dockerCertPath(); - @Test - public void equals() throws Exception { - assertEquals(EXAMPLE_CONFIG, newExampleConfig()); + return new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + dockerCertPath, true); } - @Test - public void environmentDockerHost() throws Exception { - - // given docker host in env - Map env = new HashMap(); - env.put("DOCKER_HOST", "tcp://baz:8768"); - // and it looks to be SSL disabled - env.remove("DOCKER_CERT_PATH"); - - // 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")); + private static String homeDir() { + return "target/test-classes/someHomeDir"; } - @Test - public void environmentDockerHostHttpsAutoDetectByCertPath() 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")); + private static String dockerCertPath() { + return homeDir() + "/.docker"; } @Test - public void environmentDockerHostHttpsAutoDetectByTlsVerify() 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_TLS_VERIFY", "1"); - - // 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")); + public void equals() throws Exception { + assertEquals(EXAMPLE_CONFIG, newExampleConfig()); } @Test - public void environmentDockerHostWithInvalidTlsVerify() throws Exception { + public void environmentDockerHost() throws Exception { // given docker host in env - Map env = new HashMap(System.getenv()); - env.put("DOCKER_HOST", "tcp://bar:8768"); + Map env = new HashMap(); + env.put(DockerClientConfig.DOCKER_HOST, "tcp://baz:8768"); // and it looks to be SSL disabled env.remove("DOCKER_CERT_PATH"); - // and it has an invalid TLS_VERIFY value - env.put("DOCKER_TLS_VERIFY", "any value different from '1'"); - // 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("http://bar:8768")); - } - - @Test - public void environmentDockerHostWithInvalidTlsVerifyButWithCertPath() 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"); - // and it has an invalid TLS_VERIFY value - env.put("DOCKER_TLS_VERIFY", "any value different from '1'"); + // given default cert path + Properties systemProperties = new Properties(); + systemProperties.setProperty("user.name", "someUserName"); + systemProperties.setProperty("user.home", homeDir()); // when you build a config - DockerClientConfig config = buildConfig(env, new Properties()); + DockerClientConfig config = buildConfig(env, systemProperties); - // then the URL is that value with "tcp" changed to "https" - assertEquals(config.getUri(), URI.create("https://bar:8768")); + assertEquals(config.getDockerHost(), URI.create("tcp://baz:8768")); } @Test @@ -124,16 +68,16 @@ 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_SERVER_ADDRESS", "wham"); - env.put("DOCKER_CERT_PATH", "flim"); - env.put("DOCKER_CFG_PATH", "flam"); - env.put("DOCKER_READ_TIMEOUT", "877"); - env.put("DOCKER_LOGGING_FILTER_ENABLED", "false"); + env.put(DockerClientConfig.DOCKER_HOST, "tcp://foo"); + env.put(DockerClientConfig.API_VERSION, "apiVersion"); + env.put(DockerClientConfig.REGISTRY_USERNAME, "registryUsername"); + env.put(DockerClientConfig.REGISTRY_PASSWORD, "registryPassword"); + env.put(DockerClientConfig.REGISTRY_EMAIL, "registryEmail"); + env.put(DockerClientConfig.REGISTRY_URL, "registryUrl"); + env.put(DockerClientConfig.DOCKER_CONFIG, "dockerConfig"); + env.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath()); + env.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1"); + // when you build a config DockerClientConfig config = buildConfig(env, new Properties()); @@ -152,18 +96,18 @@ public void defaults() throws Exception { // given default cert path Properties systemProperties = new Properties(); systemProperties.setProperty("user.name", "someUserName"); - systemProperties.setProperty("user.home", "someHomeDir"); + systemProperties.setProperty("user.home", homeDir()); // 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.getUsername(), "someUserName"); - assertEquals(config.getServerAddress(), AuthConfig.DEFAULT_SERVER_ADDRESS); - assertEquals(config.getVersion(), RemoteApiVersion.unknown()); - assertEquals(config.getDockerCfgPath(), "someHomeDir/.dockercfg"); - assertEquals(((LocalDirectorySSLConfig) config.getSslConfig()).getDockerCertPath(), "someHomeDir/.docker"); + assertEquals(config.getDockerHost(), URI.create("tcp://localhost:2376")); + assertEquals(config.getRegistryUsername(), "someUserName"); + assertEquals(config.getRegistryUrl(), AuthConfig.DEFAULT_SERVER_ADDRESS); + assertEquals(config.getApiVersion(), RemoteApiVersion.unknown()); + assertEquals(config.getDockerConfig(), homeDir() + "/.docker"); + assertEquals(config.getDockerCertPath(), homeDir() + "/.docker/certs"); } @Test @@ -171,14 +115,15 @@ 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.serverAddress", "wham"); - systemProperties.setProperty("docker.io.dockerCertPath", "flim"); - systemProperties.setProperty("docker.io.dockerCfgPath", "flam"); + systemProperties.put(DockerClientConfig.DOCKER_HOST, "tcp://foo"); + systemProperties.put(DockerClientConfig.API_VERSION, "apiVersion"); + systemProperties.put(DockerClientConfig.REGISTRY_USERNAME, "registryUsername"); + systemProperties.put(DockerClientConfig.REGISTRY_PASSWORD, "registryPassword"); + systemProperties.put(DockerClientConfig.REGISTRY_EMAIL, "registryEmail"); + systemProperties.put(DockerClientConfig.REGISTRY_URL, "registryUrl"); + systemProperties.put(DockerClientConfig.DOCKER_CONFIG, "dockerConfig"); + systemProperties.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath()); + systemProperties.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1"); // when you build new config DockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties); @@ -195,4 +140,40 @@ public void serializableTest() { assertThat("Deserialized object mush match source object", deserialized, equalTo(EXAMPLE_CONFIG)); } + + @Test(expectedExceptions = DockerClientException.class) + public void testTlsVerifyAndCertPathNull() throws Exception { + new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + null, true); + } + + @Test(expectedExceptions = DockerClientException.class) + public void testTlsVerifyAndCertPathEmpty() throws Exception { + new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + "", true); + } + + @Test() + public void testTlsVerifyAndCertPath() throws Exception { + new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + dockerCertPath(), true); + } + + @Test(expectedExceptions = DockerClientException.class) + public void testWrongHostScheme() throws Exception { + new DockerClientConfig(URI.create("http://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + null, false); + } + + @Test() + public void testTcpHostScheme() throws Exception { + new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + null, false); + } + + @Test() + public void testUnixHostScheme() throws Exception { + new DockerClientConfig(URI.create("unix://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + null, false); + } } diff --git a/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java b/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java index c5a1e841c..62cfaa146 100644 --- a/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java +++ b/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java @@ -3,6 +3,8 @@ import static org.testng.Assert.assertEquals; import static org.testng.AssertJUnit.fail; +import java.net.URI; + import org.testng.annotations.Test; public class DockerClientImplTest { @@ -10,7 +12,7 @@ public class DockerClientImplTest { @Test public void configuredInstanceAuthConfig() throws Exception { // given a config with null serverAddress - DockerClientConfig dockerClientConfig = new DockerClientConfig(null, null, "", "", "", null, null, null); + DockerClientConfig dockerClientConfig = new DockerClientConfig(URI.create("tcp://foo"), null, null, null, "", "", "", null, false); DockerClientImpl dockerClient = DockerClientImpl.getInstance(dockerClientConfig); // when we get the auth config @@ -25,6 +27,9 @@ public void configuredInstanceAuthConfig() throws Exception { @Test public void defaultInstanceAuthConfig() throws Exception { + + System.setProperty("user.home", "target/test-classes/someHomeDir"); + // given a default client DockerClientImpl dockerClient = DockerClientImpl.getInstance(); diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java index 50860789b..a5dfcfbc5 100644 --- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -5,6 +5,8 @@ import java.util.ArrayList; import java.util.List; +import javax.net.ssl.SSLContext; + import com.github.dockerjava.api.async.ResultCallback; import com.github.dockerjava.api.command.*; import com.github.dockerjava.api.command.AuthCmd.Exec; @@ -367,4 +369,9 @@ public List getVolumeNames() { public List getNetworkIds() { return new ArrayList<>(networkIds); } + + @Override + public DockerCmdExecFactory withSSLContext(SSLContext sslContext) { + return delegate.withSSLContext(sslContext); + } } diff --git a/src/test/resources/someHomeDir/.docker/certs/dummy.txt b/src/test/resources/someHomeDir/.docker/certs/dummy.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/someHomeDir/.docker/config.json b/src/test/resources/someHomeDir/.docker/config.json new file mode 100644 index 000000000..630394039 --- /dev/null +++ b/src/test/resources/someHomeDir/.docker/config.json @@ -0,0 +1,9 @@ +{ + "auths":{ + "https://index.docker.io/v1/":{ + "auth":"XXXX=", + "email":"foo.bar@test.com" + } + + } +} \ No newline at end of file