[docker] upgrade to docker 1.7 and refactor TLS support

Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/55a7d8ce
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/55a7d8ce
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/55a7d8ce

Branch: refs/heads/master
Commit: 55a7d8ce3cdd293667202515e52c25691ac83759
Parents: 4edaf18
Author: Csaba Palfi <[email protected]>
Authored: Mon Jul 13 22:26:26 2015 +0200
Committer: Ignasi Barrera <[email protected]>
Committed: Wed Jul 22 10:22:36 2015 +0200

----------------------------------------------------------------------
 apis/docker/README.md                           |  10 +-
 apis/docker/pom.xml                             |  33 +++-
 .../org/jclouds/docker/DockerApiMetadata.java   |   3 +
 .../docker/config/DockerHttpApiModule.java      |  17 +-
 .../config/DockerOkHttpClientSupplier.java      |  40 ++---
 .../java/org/jclouds/docker/domain/Config.java  |  37 ++--
 .../java/org/jclouds/docker/domain/Info.java    |  16 +-
 .../suppliers/DockerSSLContextSupplier.java     |  64 +++++++
 .../DockerUntrustedSSLContextSupplier.java      |  60 +++++++
 .../docker/suppliers/SSLContextBuilder.java     | 174 +++++++++++++++++++
 .../suppliers/SSLContextWithKeysSupplier.java   | 166 ------------------
 .../docker/compute/BaseDockerApiLiveTest.java   |   4 +-
 .../docker/features/ContainerApiLiveTest.java   |   2 +-
 .../org/jclouds/docker/parse/InfoParseTest.java |   8 +-
 apis/docker/src/test/resources/info.json        |   8 +-
 15 files changed, 404 insertions(+), 238 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/README.md
----------------------------------------------------------------------
diff --git a/apis/docker/README.md b/apis/docker/README.md
index b3c51a1..c5080e6 100644
--- a/apis/docker/README.md
+++ b/apis/docker/README.md
@@ -8,15 +8,11 @@ Please follow these steps to configure your workstation for 
jclouds-docker:
 
 - install the latest Docker release (please visit 
https://docs.docker.com/installation/)
 
-If you are using `boot2docker`, notice that from version v1.3.0 the Docker 
daemon is set to use an encrypted TCP
-socket (--tls, or --tlsverify),
-then you need to import CA certificate into Trusted Certs:
-      
-      `keytool -import -trustcacerts -file 
/Users/andrea/.boot2docker/certs/boot2docker-vm/ca.pem -alias BOOT2DOCKER 
-keystore $JAVA_HOME/jre/lib/security/cacerts`
+If you are using `boot2docker` then it can also manage certificates and help 
you setup `DOCKER_CERT_PATH` and `DOCKER_HOST` environment variables. (See 
`boot2docker shellinit`)
 
-by default the passoword is `changeit`
+Assuming these environment variables are setup correctly there are no further 
setups steps are required.
 
-N.B.: From `Docker 1.3.2+` the server doesn't accept sslv3 protocol 
(https://github.com/docker/docker/pull/8588/files)
+Live tests then can now be run: `mvn -Plive integration-test`
 
 #How it works
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/pom.xml
----------------------------------------------------------------------
diff --git a/apis/docker/pom.xml b/apis/docker/pom.xml
index aebfce3..d93d43b 100644
--- a/apis/docker/pom.xml
+++ b/apis/docker/pom.xml
@@ -34,10 +34,11 @@
   <packaging>bundle</packaging>
 
   <properties>
-    <test.docker.endpoint>https://localhost:4243</test.docker.endpoint>
-    <test.docker.api-version>1.15</test.docker.api-version>
-    <test.docker.identity>FIXME</test.docker.identity>
-    <test.docker.credential>FIXME</test.docker.credential>
+    <test.docker.api-version>1.19</test.docker.api-version>
+    
<test.docker.identity>${env.DOCKER_CERT_PATH}/cert.pem</test.docker.identity>
+    
<test.docker.credential>${env.DOCKER_CERT_PATH}/key.pem</test.docker.credential>
+    
<test.docker.cacert.path>${env.DOCKER_CERT_PATH}/ca.pem</test.docker.cacert.path>
+    <test.jclouds.trust-all-certs>false</test.jclouds.trust-all-certs>
     
<jclouds.osgi.export>org.jclouds.docker*;version="${project.version}"</jclouds.osgi.export>
     <jclouds.osgi.import>
       org.jclouds.compute.internal;version="${project.version}",
@@ -135,6 +136,26 @@
       <build>
         <plugins>
           <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>build-helper-maven-plugin</artifactId>
+            <version>1.9.1</version>
+            <executions>
+              <execution>
+                <id>regex-property</id>
+                <goals>
+                  <goal>regex-property</goal>
+                </goals>
+                <configuration>
+                  <name>test.docker.endpoint</name>
+                  <value>${env.DOCKER_HOST}</value>
+                  <regex>tcp</regex>
+                  <replacement>https</replacement>
+                  <failIfNoMatch>false</failIfNoMatch>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-surefire-plugin</artifactId>
             <executions>
@@ -149,8 +170,10 @@
                   <systemPropertyVariables>
                     
<test.docker.endpoint>${test.docker.endpoint}</test.docker.endpoint>
                     
<test.docker.api-version>${test.docker.api-version}</test.docker.api-version>
-                    
<test.docker.credential>${test.docker.identity}</test.docker.credential>
+                    
<test.docker.identity>${test.docker.identity}</test.docker.identity>
                     
<test.docker.credential>${test.docker.credential}</test.docker.credential>
+                    
<test.docker.cacert.path>${test.docker.cacert.path}</test.docker.cacert.path>
+                    
<test.jclouds.trust-all-certs>${test.jclouds.trust-all-certs}</test.jclouds.trust-all-certs>
                   </systemPropertyVariables>
                 </configuration>
               </execution>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java 
b/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java
index ea10c70..6585541 100644
--- a/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java
+++ b/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java
@@ -37,6 +37,8 @@ import static org.jclouds.reflect.Reflection2.typeToken;
 @AutoService(ApiMetadata.class)
 public class DockerApiMetadata extends BaseHttpApiMetadata<DockerApi> {
 
+    public static final String DOCKER_CA_CERT_PATH = "docker.cacert.path";
+
    @Override
    public Builder toBuilder() {
       return new Builder().fromApiMetadata(this);
@@ -55,6 +57,7 @@ public class DockerApiMetadata extends 
BaseHttpApiMetadata<DockerApi> {
       properties.setProperty(Constants.PROPERTY_CONNECTION_TIMEOUT, 
"1200000"); // 15 minutes
       properties.setProperty(ComputeServiceProperties.IMAGE_LOGIN_USER, 
"root:password");
       properties.setProperty(TEMPLATE, "osFamily=UBUNTU,os64Bit=true");
+      properties.setProperty(DOCKER_CA_CERT_PATH, "");
       return properties;
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/config/DockerHttpApiModule.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/main/java/org/jclouds/docker/config/DockerHttpApiModule.java 
b/apis/docker/src/main/java/org/jclouds/docker/config/DockerHttpApiModule.java
index ed23d79..afd8e36 100644
--- 
a/apis/docker/src/main/java/org/jclouds/docker/config/DockerHttpApiModule.java
+++ 
b/apis/docker/src/main/java/org/jclouds/docker/config/DockerHttpApiModule.java
@@ -16,8 +16,14 @@
  */
 package org.jclouds.docker.config;
 
+import com.google.common.base.Supplier;
+import com.google.inject.AbstractModule;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+import com.google.inject.util.Modules;
 import org.jclouds.docker.DockerApi;
 import org.jclouds.docker.handlers.DockerErrorHandler;
+import org.jclouds.docker.suppliers.DockerUntrustedSSLContextSupplier;
 import org.jclouds.http.HttpErrorHandler;
 import org.jclouds.http.annotation.ClientError;
 import org.jclouds.http.annotation.Redirection;
@@ -28,6 +34,8 @@ import 
org.jclouds.http.okhttp.config.OkHttpCommandExecutorServiceModule;
 import org.jclouds.rest.ConfiguresHttpApi;
 import org.jclouds.rest.config.HttpApiModule;
 
+import javax.net.ssl.SSLContext;
+
 /**
  * Configures the Docker connection.
  */
@@ -48,8 +56,13 @@ public class DockerHttpApiModule extends 
HttpApiModule<DockerApi> {
    @Override
    protected void configure() {
       super.configure();
-      install(new OkHttpCommandExecutorServiceModule());
+      install(Modules.override(new 
OkHttpCommandExecutorServiceModule()).with(new AbstractModule() {
+         @Override
+         protected void configure() {
+            bind(new TypeLiteral<Supplier<SSLContext>>() 
{}).annotatedWith(Names.named("untrusted")).to(DockerUntrustedSSLContextSupplier.class);
+         }
+      }));
       bind(OkHttpClientSupplier.class).to(DockerOkHttpClientSupplier.class);
-   }
 
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/config/DockerOkHttpClientSupplier.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/main/java/org/jclouds/docker/config/DockerOkHttpClientSupplier.java
 
b/apis/docker/src/main/java/org/jclouds/docker/config/DockerOkHttpClientSupplier.java
index 3888b98..6bc171f 100644
--- 
a/apis/docker/src/main/java/org/jclouds/docker/config/DockerOkHttpClientSupplier.java
+++ 
b/apis/docker/src/main/java/org/jclouds/docker/config/DockerOkHttpClientSupplier.java
@@ -19,7 +19,7 @@ package org.jclouds.docker.config;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import org.jclouds.docker.suppliers.SSLContextWithKeysSupplier;
+import org.jclouds.docker.suppliers.DockerSSLContextSupplier;
 import org.jclouds.http.okhttp.OkHttpClientSupplier;
 
 import com.google.common.collect.ImmutableList;
@@ -30,24 +30,24 @@ import com.squareup.okhttp.TlsVersion;
 @Singleton
 public class DockerOkHttpClientSupplier implements OkHttpClientSupplier {
 
-   private final SSLContextWithKeysSupplier sslContextWithKeysSupplier;
-
-   @Inject
-   DockerOkHttpClientSupplier(SSLContextWithKeysSupplier 
sslContextWithKeysSupplier) {
-      this.sslContextWithKeysSupplier = sslContextWithKeysSupplier;
-   }
-
-   @Override
-   public OkHttpClient get() {
-      OkHttpClient client = new OkHttpClient();
-      ConnectionSpec tlsSpec = new 
ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
-              .tlsVersions(TlsVersion.TLS_1_0, TlsVersion.TLS_1_1, 
TlsVersion.TLS_1_2)
-              .build();
-      ConnectionSpec cleartextSpec = new 
ConnectionSpec.Builder(ConnectionSpec.CLEARTEXT)
-              .build();
-      client.setConnectionSpecs(ImmutableList.of(tlsSpec, cleartextSpec));
-      
client.setSslSocketFactory(sslContextWithKeysSupplier.get().getSocketFactory());
-      return client;
-   }
+    private final DockerSSLContextSupplier dockerSSLContextSupplier;
+
+    @Inject
+    DockerOkHttpClientSupplier(DockerSSLContextSupplier 
dockerSSLContextSupplier) {
+        this.dockerSSLContextSupplier = dockerSSLContextSupplier;
+    }
+
+    @Override
+    public OkHttpClient get() {
+        OkHttpClient client = new OkHttpClient();
+        ConnectionSpec tlsSpec = new 
ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
+                .tlsVersions(TlsVersion.TLS_1_0, TlsVersion.TLS_1_1, 
TlsVersion.TLS_1_2)
+                .build();
+        ConnectionSpec cleartextSpec = new 
ConnectionSpec.Builder(ConnectionSpec.CLEARTEXT)
+                .build();
+        client.setConnectionSpecs(ImmutableList.of(tlsSpec, cleartextSpec));
+        
client.setSslSocketFactory(dockerSSLContextSupplier.get().getSocketFactory());
+        return client;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/domain/Config.java
----------------------------------------------------------------------
diff --git a/apis/docker/src/main/java/org/jclouds/docker/domain/Config.java 
b/apis/docker/src/main/java/org/jclouds/docker/domain/Config.java
index 05dcc48..464f562 100644
--- a/apis/docker/src/main/java/org/jclouds/docker/domain/Config.java
+++ b/apis/docker/src/main/java/org/jclouds/docker/domain/Config.java
@@ -101,8 +101,6 @@ public abstract class Config {
 
    @Nullable public abstract String networkMode();
 
-   public abstract Map<String, String> devices();
-
    Config() {
    }
 
@@ -112,7 +110,7 @@ public abstract class Config {
                  "AttachStderr", "Tty", "OpenStdin", "StdinOnce", "Env", 
"Cmd", "Entrypoint", "Image", "Volumes",
                  "WorkingDir", "NetworkDisabled", "ExposedPorts", 
"SecurityOpts", "HostConfig", "Binds", "Links",
                  "LxcConf", "PortBindings", "PublishAllPorts", "Privileged", 
"Dns", "DnsSearch", "VolumesFrom",
-                 "CapAdd", "CapDrop", "RestartPolicy", "NetworkMode", "Devices"
+                 "CapAdd", "CapDrop", "RestartPolicy", "NetworkMode"
          })
    public static Config create(String hostname, String domainname, String 
user, int memory, int memorySwap,
          int cpuShares, boolean attachStdin, boolean attachStdout, boolean 
attachStderr, boolean tty,
@@ -121,13 +119,12 @@ public abstract class Config {
          Map<String, ?> exposedPorts, List<String> securityOpts, HostConfig 
hostConfig, List<String> binds,
          List<String> links, List<Map<String, String>> lxcConf, Map<String, 
List<Map<String, String>>> portBindings,
          boolean publishAllPorts, boolean privileged, List<String> dns, String 
dnsSearch, String volumesFrom,
-         List<String> capAdd, List<String> capDrop, Map<String, String> 
restartPolicy, String networkMode, Map<String, String> devices) {
+         List<String> capAdd, List<String> capDrop, Map<String, String> 
restartPolicy, String networkMode) {
       return new AutoValue_Config(hostname, domainname, user, memory, 
memorySwap, cpuShares, attachStdin,
               attachStdout, attachStderr, tty, openStdin, stdinOnce, 
copyOf(env), copyOf(cmd), copyOf(entrypoint),
               image, copyOf(volumes), workingDir, networkDisabled, 
copyOf(exposedPorts), copyOf(securityOpts), hostConfig,
               copyOf(binds), copyOf(links), copyOf(lxcConf), 
copyOf(portBindings), publishAllPorts, privileged,
-              copyOf(dns), dnsSearch, volumesFrom, copyOf(capAdd), 
copyOf(capDrop), copyOf(restartPolicy), networkMode,
-              copyOf(devices));
+              copyOf(dns), dnsSearch, volumesFrom, copyOf(capAdd), 
copyOf(capDrop), copyOf(restartPolicy), networkMode);
    }
 
    public static Builder builder() {
@@ -174,7 +171,6 @@ public abstract class Config {
       private List<String> capDrop = Lists.newArrayList();
       private Map<String, String> restartPolicy = Maps.newHashMap();
       private String networkMode;
-      private Map<String, String> devices = Maps.newHashMap();
 
       public Builder hostname(String hostname) {
          this.hostname = hostname;
@@ -191,18 +187,24 @@ public abstract class Config {
          return this;
       }
 
-      public Builder memory(int memory) {
-         this.memory = memory;
+      public Builder memory(Integer memory) {
+         if (memory != null) {
+            this.memory = memory;
+         }
          return this;
       }
 
-      public Builder memorySwap(int memorySwap) {
-         this.memorySwap = memorySwap;
+      public Builder memorySwap(Integer memorySwap) {
+         if (memorySwap != null) {
+            this.memorySwap = memorySwap;
+         }
          return this;
       }
 
-      public Builder cpuShares(int cpuShares) {
-         this.cpuShares = cpuShares;
+      public Builder cpuShares(Integer cpuShares) {
+         if (cpuShares != null) {
+            this.cpuShares = cpuShares;
+         }
          return this;
       }
 
@@ -351,17 +353,12 @@ public abstract class Config {
          return this;
       }
 
-      public Builder devices(Map<String, String> devices) {
-         this.devices = devices;
-         return this;
-      }
-
       public Config build() {
          return Config.create(hostname, domainname, user, memory, memorySwap, 
cpuShares, attachStdin, attachStdout,
                  attachStderr, tty, openStdin, stdinOnce, env, cmd, 
entrypoint, image, volumes, workingDir,
                  networkDisabled, exposedPorts, securityOpts, hostConfig, 
binds, links, lxcConf, portBindings,
                  publishAllPorts, privileged, dns, dnsSearch, volumesFrom, 
capAdd, capDrop, restartPolicy,
-                 networkMode, devices);
+                 networkMode);
       }
 
       public Builder fromConfig(Config in) {
@@ -373,7 +370,7 @@ public abstract class Config {
                  
.hostConfig(in.hostConfig()).binds(in.binds()).links(in.links()).lxcConf(in.lxcConf())
                  
.portBindings(in.portBindings()).publishAllPorts(in.publishAllPorts()).privileged(in.privileged())
                  
.dns(in.dns()).dnsSearch(in.dnsSearch()).volumesFrom(in.volumesFrom()).capAdd(in.capAdd())
-                 
.capDrop(in.capDrop()).restartPolicy(in.restartPolicy()).networkMode(in.networkMode()).devices(in.devices());
+                 
.capDrop(in.capDrop()).restartPolicy(in.restartPolicy()).networkMode(in.networkMode());
       }
 
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/domain/Info.java
----------------------------------------------------------------------
diff --git a/apis/docker/src/main/java/org/jclouds/docker/domain/Info.java 
b/apis/docker/src/main/java/org/jclouds/docker/domain/Info.java
index c0e2ac7..e2b51ca 100644
--- a/apis/docker/src/main/java/org/jclouds/docker/domain/Info.java
+++ b/apis/docker/src/main/java/org/jclouds/docker/domain/Info.java
@@ -28,7 +28,7 @@ public abstract class Info {
 
    public abstract int containers();
 
-   public abstract int debug();
+   public abstract boolean debug();
 
    public abstract String driver();
 
@@ -36,7 +36,7 @@ public abstract class Info {
 
    public abstract String executionDriver();
 
-   public abstract int iPv4Forwarding();
+   public abstract boolean iPv4Forwarding();
 
    public abstract int images();
 
@@ -48,7 +48,7 @@ public abstract class Info {
 
    public abstract String kernelVersion();
 
-   public abstract int memoryLimit();
+   public abstract boolean memoryLimit();
 
    public abstract int nEventsListener();
 
@@ -58,7 +58,7 @@ public abstract class Info {
 
    public abstract String operatingSystem();
 
-   public abstract int swapLimit();
+   public abstract boolean swapLimit();
 
    public abstract String dockerRootDir();
 
@@ -96,10 +96,10 @@ public abstract class Info {
                    "NFd", "NGoroutines", "OperatingSystem", "SwapLimit", 
"DockerRootDir", "Labels", "MemTotal", "NCPU",
                    "ID", "Name"
    })
-   public static Info create(int containers, int debug, String driver, 
List<List<String>> driverStatus,
-                             String executionDriver, int iPv4Forwarding, int 
images, String indexServerAddress,
-                             String initPath, String initSha1, String 
kernelVersion, int memoryLimit,
-                             int nEventsListener, int nFd, int nGoroutines, 
String operatingSystem, int swapLimit,
+   public static Info create(int containers, boolean debug, String driver, 
List<List<String>> driverStatus,
+                             String executionDriver, boolean iPv4Forwarding, 
int images, String indexServerAddress,
+                             String initPath, String initSha1, String 
kernelVersion, boolean memoryLimit,
+                             int nEventsListener, int nFd, int nGoroutines, 
String operatingSystem, boolean swapLimit,
                              String dockerRootDir, List<String> labels, long 
memTotal, int ncpu, String id, String name) {
       return new AutoValue_Info(containers, debug, driver, driverStatus, 
executionDriver, iPv4Forwarding, images,
               indexServerAddress, initPath, initSha1, kernelVersion, 
memoryLimit, nEventsListener, nFd, nGoroutines,

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java
 
b/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java
new file mode 100644
index 0000000..ed901f3
--- /dev/null
+++ 
b/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.docker.suppliers;
+
+import com.google.common.base.Strings;
+import com.google.common.base.Supplier;
+import org.jclouds.docker.DockerApiMetadata;
+import org.jclouds.domain.Credentials;
+import org.jclouds.location.Provider;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Throwables.propagate;
+
+@Singleton
+public class DockerSSLContextSupplier implements Supplier<SSLContext> {
+   private final Supplier<Credentials> creds;
+   private final String caCertPath;
+
+
+   @Inject
+   DockerSSLContextSupplier(@Provider Supplier<Credentials> creds, 
@Named(DockerApiMetadata.DOCKER_CA_CERT_PATH) String caCertPath) {
+      this.creds = creds;
+      this.caCertPath = caCertPath;
+   }
+
+   @Override
+   public SSLContext get() {
+      Credentials currentCreds = checkNotNull(creds.get(), "credential 
supplier returned null");
+      try {
+         SSLContextBuilder builder = new SSLContextBuilder();
+         builder.clientKeyAndCertificate(currentCreds.credential, 
currentCreds.identity);
+         if (!Strings.isNullOrEmpty(caCertPath)) {
+            builder.caCertificate(caCertPath);
+         }
+         return builder.build();
+      } catch (GeneralSecurityException e) {
+         throw propagate(e);
+      } catch (IOException e) {
+         throw propagate(e);
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java
 
b/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java
new file mode 100644
index 0000000..d0c9077
--- /dev/null
+++ 
b/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.docker.suppliers;
+
+import com.google.common.base.Supplier;
+import org.jclouds.domain.Credentials;
+import org.jclouds.http.config.SSLModule;
+import org.jclouds.location.Provider;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Throwables.propagate;
+
+@Singleton
+public class DockerUntrustedSSLContextSupplier implements Supplier<SSLContext> 
{
+    private final Supplier<Credentials> creds;
+    private final SSLModule.TrustAllCerts insecureTrustManager;
+
+
+    @Inject
+    DockerUntrustedSSLContextSupplier(@Provider Supplier<Credentials> creds, 
SSLModule.TrustAllCerts insecureTrustManager) {
+        this.creds = creds;
+        this.insecureTrustManager = insecureTrustManager;
+    }
+
+    @Override
+    public SSLContext get() {
+        Credentials currentCreds = checkNotNull(creds.get(), "credential 
supplier returned null");
+        try {
+            SSLContextBuilder builder = new SSLContextBuilder();
+            builder.clientKeyAndCertificate(currentCreds.credential, 
currentCreds.identity);
+            builder.trustManager(insecureTrustManager);
+            return builder.build();
+        } catch (GeneralSecurityException e) {
+            throw propagate(e);
+        } catch (IOException e) {
+            throw propagate(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java 
b/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java
new file mode 100644
index 0000000..6030def
--- /dev/null
+++ 
b/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.docker.suppliers;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMKeyPair;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.jclouds.util.Closeables2;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509ExtendedKeyManager;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import static com.google.common.base.Throwables.propagate;
+
+public class SSLContextBuilder {
+
+    private KeyManager[] keyManagers;
+    private TrustManager[] trustManagers;
+
+    public SSLContextBuilder() { }
+
+    public SSLContextBuilder clientKeyAndCertificate(String keyPath, String 
certPath) throws IOException, CertificateException {
+        X509Certificate certificate = getCertificate(loadFile(certPath));
+        PrivateKey privateKey = getKey(loadFile(keyPath));
+        keyManagers = new KeyManager[]{new InMemoryKeyManager(certificate, 
privateKey)};
+        return this;
+    }
+
+    public SSLContextBuilder caCertificate(String caCertPath){
+        trustManagers = getTrustManagerWithCaCert(caCertPath);
+        return this;
+    }
+
+    public SSLContextBuilder trustManager(TrustManager trustManager) {
+        trustManagers = new TrustManager[]{trustManager};
+        return this;
+    }
+
+    public SSLContext build() throws NoSuchAlgorithmException, 
KeyManagementException {
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(keyManagers, trustManagers, new SecureRandom());
+        return sslContext;
+    }
+
+    private TrustManager[] getTrustManagerWithCaCert(String caCertPath) {
+        try {
+            X509Certificate caCert = getCertificate(loadFile(caCertPath));
+            KeyStore trustStore = 
KeyStore.getInstance(KeyStore.getDefaultType());
+            trustStore.load(null, null);
+            trustStore.setCertificateEntry("ca", caCert);
+            TrustManagerFactory tmf = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(trustStore);
+            return tmf.getTrustManagers();
+        } catch (GeneralSecurityException e) {
+            throw propagate(e);
+        } catch (IOException e) {
+            throw propagate(e);
+        }
+    }
+
+    private static X509Certificate getCertificate(String certificate) {
+        try {
+            return (X509Certificate) 
CertificateFactory.getInstance("X.509").generateCertificate(
+                    new 
ByteArrayInputStream(certificate.getBytes(Charsets.UTF_8)));
+        } catch (CertificateException ex) {
+            throw new RuntimeException("Invalid certificate", ex);
+        }
+    }
+
+    private static PrivateKey getKey(String privateKey) {
+        PEMParser pemParser = new PEMParser(new StringReader(privateKey));
+        try {
+            Object object = pemParser.readObject();
+            if (Security.getProvider("BC") == null) {
+                Security.addProvider(new BouncyCastleProvider());
+            }
+            JcaPEMKeyConverter converter = new 
JcaPEMKeyConverter().setProvider("BC");
+            KeyPair keyPair = converter.getKeyPair((PEMKeyPair) object);
+            return keyPair.getPrivate();
+        } catch (IOException ex) {
+            throw new RuntimeException("Invalid private key", ex);
+        } finally {
+            Closeables2.closeQuietly(pemParser);
+        }
+    }
+
+    private static String loadFile(final String filePath) throws IOException {
+        return Files.toString(new File(filePath), Charsets.UTF_8);
+    }
+
+    private static class InMemoryKeyManager extends X509ExtendedKeyManager {
+        private static final String DEFAULT_ALIAS = "docker";
+
+        private final X509Certificate certificate;
+
+        private final PrivateKey privateKey;
+
+        public InMemoryKeyManager(final X509Certificate certificate, final 
PrivateKey privateKey)
+                throws IOException, CertificateException {
+            this.certificate = certificate;
+            this.privateKey = privateKey;
+        }
+
+        @Override
+        public String chooseClientAlias(final String[] keyType, final 
Principal[] issuers,
+                                        final Socket socket) {
+            return DEFAULT_ALIAS;
+        }
+
+        @Override
+        public String chooseServerAlias(final String keyType, final 
Principal[] issuers,
+                                        final Socket socket) {
+            return DEFAULT_ALIAS;
+        }
+
+        @Override
+        public X509Certificate[] getCertificateChain(final String alias) {
+            return new X509Certificate[]{certificate};
+        }
+
+        @Override
+        public String[] getClientAliases(final String keyType, final 
Principal[] issuers) {
+            return new String[]{DEFAULT_ALIAS};
+        }
+
+        @Override
+        public PrivateKey getPrivateKey(final String alias) {
+            return privateKey;
+        }
+
+        @Override
+        public String[] getServerAliases(final String keyType, final 
Principal[] issuers) {
+            return new String[]{DEFAULT_ALIAS};
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextWithKeysSupplier.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextWithKeysSupplier.java
 
b/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextWithKeysSupplier.java
deleted file mode 100644
index 83ccacd..0000000
--- 
a/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextWithKeysSupplier.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.docker.suppliers;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Throwables.propagate;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.net.Socket;
-import java.security.KeyManagementException;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509ExtendedKeyManager;
-
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.openssl.PEMKeyPair;
-import org.bouncycastle.openssl.PEMParser;
-import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
-import org.jclouds.domain.Credentials;
-import org.jclouds.http.HttpUtils;
-import org.jclouds.http.config.SSLModule.TrustAllCerts;
-import org.jclouds.location.Provider;
-import org.jclouds.util.Closeables2;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Supplier;
-import com.google.common.io.Files;
-
-@Singleton
-public class SSLContextWithKeysSupplier implements Supplier<SSLContext> {
-   private final TrustManager[] trustManager;
-   private final Supplier<Credentials> creds;
-
-   @Inject
-   SSLContextWithKeysSupplier(@Provider Supplier<Credentials> creds, HttpUtils 
utils, TrustAllCerts trustAllCerts) {
-      this.trustManager = utils.trustAllCerts() ? new 
TrustManager[]{trustAllCerts} : null;
-      this.creds = creds;
-   }
-
-   @Override
-   public SSLContext get() {
-      Credentials currentCreds = checkNotNull(creds.get(), "credential 
supplier returned null");
-      try {
-         SSLContext sslContext = SSLContext.getInstance("TLS");
-         X509Certificate certificate = 
getCertificate(loadFile(currentCreds.identity));
-         PrivateKey privateKey = getKey(loadFile(currentCreds.credential));
-         sslContext.init(new KeyManager[]{new InMemoryKeyManager(certificate, 
privateKey)}, trustManager, new SecureRandom());
-         return sslContext;
-      } catch (NoSuchAlgorithmException e) {
-         throw propagate(e);
-      } catch (KeyManagementException e) {
-         throw propagate(e);
-      } catch (CertificateException e) {
-         throw propagate(e);
-      } catch (IOException e) {
-         throw propagate(e);
-      }
-   }
-
-   private static X509Certificate getCertificate(String certificate) {
-      try {
-         return (X509Certificate) 
CertificateFactory.getInstance("X.509").generateCertificate(
-                 new 
ByteArrayInputStream(certificate.getBytes(Charsets.UTF_8)));
-      } catch (CertificateException ex) {
-         throw new RuntimeException("Invalid certificate", ex);
-      }
-   }
-
-   private static PrivateKey getKey(String privateKey) {
-      PEMParser pemParser = new PEMParser(new StringReader(privateKey));
-      try {
-         Object object = pemParser.readObject();
-         if (Security.getProvider("BC") == null) {
-            Security.addProvider(new BouncyCastleProvider());
-         }
-         JcaPEMKeyConverter converter = new 
JcaPEMKeyConverter().setProvider("BC");
-         KeyPair keyPair = converter.getKeyPair((PEMKeyPair) object);
-         return keyPair.getPrivate();
-      } catch (IOException ex) {
-         throw new RuntimeException("Invalid private key", ex);
-      } finally {
-          Closeables2.closeQuietly(pemParser);
-      }
-   }
-
-   private static String loadFile(final String filePath) throws IOException {
-      return Files.toString(new File(filePath), Charsets.UTF_8);
-   }
-
-   private static class InMemoryKeyManager extends X509ExtendedKeyManager {
-      private static final String DEFAULT_ALIAS = "docker";
-
-      private final X509Certificate certificate;
-
-      private final PrivateKey privateKey;
-
-      public InMemoryKeyManager(final X509Certificate certificate, final 
PrivateKey privateKey)
-              throws IOException, CertificateException {
-         this.certificate = certificate;
-         this.privateKey = privateKey;
-      }
-
-      @Override
-      public String chooseClientAlias(final String[] keyType, final 
Principal[] issuers,
-                                      final Socket socket) {
-         return DEFAULT_ALIAS;
-      }
-
-      @Override
-      public String chooseServerAlias(final String keyType, final Principal[] 
issuers,
-                                      final Socket socket) {
-         return DEFAULT_ALIAS;
-      }
-
-      @Override
-      public X509Certificate[] getCertificateChain(final String alias) {
-         return new X509Certificate[]{certificate};
-      }
-
-      @Override
-      public String[] getClientAliases(final String keyType, final Principal[] 
issuers) {
-         return new String[]{DEFAULT_ALIAS};
-      }
-
-      @Override
-      public PrivateKey getPrivateKey(final String alias) {
-         return privateKey;
-      }
-
-      @Override
-      public String[] getServerAliases(final String keyType, final Principal[] 
issuers) {
-         return new String[]{DEFAULT_ALIAS};
-      }
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/test/java/org/jclouds/docker/compute/BaseDockerApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/test/java/org/jclouds/docker/compute/BaseDockerApiLiveTest.java
 
b/apis/docker/src/test/java/org/jclouds/docker/compute/BaseDockerApiLiveTest.java
index 447c9e4..5778d9a 100644
--- 
a/apis/docker/src/test/java/org/jclouds/docker/compute/BaseDockerApiLiveTest.java
+++ 
b/apis/docker/src/test/java/org/jclouds/docker/compute/BaseDockerApiLiveTest.java
@@ -29,6 +29,7 @@ import org.jboss.shrinkwrap.api.GenericArchive;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.asset.ClassLoaderAsset;
 import org.jboss.shrinkwrap.api.exporter.TarExporter;
+import org.jclouds.Constants;
 import org.jclouds.apis.BaseApiLiveTest;
 import org.jclouds.compute.config.ComputeServiceProperties;
 import org.jclouds.docker.DockerApi;
@@ -56,8 +57,9 @@ public class BaseDockerApiLiveTest extends 
BaseApiLiveTest<DockerApi> {
    @Override
    protected Properties setupProperties() {
       Properties overrides = super.setupProperties();
-      overrides.setProperty("jclouds.trust-all-certs", "false");
       overrides.setProperty(ComputeServiceProperties.IMAGE_LOGIN_USER, 
"root:password");
+      setIfTestSystemPropertyPresent(overrides,  provider + ".cacert.path");
+      setIfTestSystemPropertyPresent(overrides, 
Constants.PROPERTY_TRUST_ALL_CERTS);
       return overrides;
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/test/java/org/jclouds/docker/features/ContainerApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/test/java/org/jclouds/docker/features/ContainerApiLiveTest.java
 
b/apis/docker/src/test/java/org/jclouds/docker/features/ContainerApiLiveTest.java
index 684f5de..23e7e7b 100644
--- 
a/apis/docker/src/test/java/org/jclouds/docker/features/ContainerApiLiveTest.java
+++ 
b/apis/docker/src/test/java/org/jclouds/docker/features/ContainerApiLiveTest.java
@@ -128,7 +128,7 @@ public class ContainerApiLiveTest extends 
BaseDockerApiLiveTest {
    @Test(dependsOnMethods = "testRestartContainer")
    public void testWaitContainer() {
       api().stopContainer(container.id(), 1);
-      assertEquals(api().wait(container.id()).statusCode(), -1);
+      assertEquals(api().wait(container.id()).statusCode(), 137);
    }
 
    @Test(dependsOnMethods = "testWaitContainer")

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/test/java/org/jclouds/docker/parse/InfoParseTest.java
----------------------------------------------------------------------
diff --git 
a/apis/docker/src/test/java/org/jclouds/docker/parse/InfoParseTest.java 
b/apis/docker/src/test/java/org/jclouds/docker/parse/InfoParseTest.java
index fa31c8b..87d149c 100644
--- a/apis/docker/src/test/java/org/jclouds/docker/parse/InfoParseTest.java
+++ b/apis/docker/src/test/java/org/jclouds/docker/parse/InfoParseTest.java
@@ -40,25 +40,25 @@ public class InfoParseTest extends 
BaseDockerParseTest<Info> {
    public Info expected() {
       return Info.create(
               0, // containers
-              1, // debug
+              true, // debug
               "aufs", // driver
               ImmutableList.<List<String>>of(
                       ImmutableList.of("Root Dir", 
"/mnt/sda1/var/lib/docker/aufs"),
                       ImmutableList.of("Dirs", "46")
               ), // driverStatus
               "native-0.2", // ExecutionDriver
-              1, // IPv4Forwarding
+              true, // IPv4Forwarding
               46, // Images
               "https://index.docker.io/v1/";, // IndexServerAddress
               "/usr/local/bin/docker", // InitPath
               "", // InitSha1
               "3.16.7-tinycore64", // KernelVersion
-              1, // MemoryLimit
+              true, // MemoryLimit
               0, // NEventsListener
               10, // NFd
               11, // NGoroutines
               "Boot2Docker 1.4.1 (TCL 5.4); master : 86f7ec8 - Tue Dec 16 
23:11:29 UTC 2014", // OperatingSystem
-              1, // SwapLimit
+              true, // SwapLimit
               "/mnt/sda1/var/lib/docker", // DockerRootDir
               null, // Labels
               2105585664, // MemTotal

http://git-wip-us.apache.org/repos/asf/jclouds/blob/55a7d8ce/apis/docker/src/test/resources/info.json
----------------------------------------------------------------------
diff --git a/apis/docker/src/test/resources/info.json 
b/apis/docker/src/test/resources/info.json
index e869382..4c67e6a 100644
--- a/apis/docker/src/test/resources/info.json
+++ b/apis/docker/src/test/resources/info.json
@@ -1,6 +1,6 @@
 {
     "Containers": 0,
-    "Debug": 1,
+    "Debug": true,
     "DockerRootDir": "/mnt/sda1/var/lib/docker",
     "Driver": "aufs",
     "DriverStatus": [
@@ -15,7 +15,7 @@
     ],
     "ExecutionDriver": "native-0.2",
     "ID": "7V5Y:IQ2M:HWIL:AZJV:HKRD:Q7OZ:3EQA:ZHMO:4LAD:OSIY:YBAA:BSX6",
-    "IPv4Forwarding": 1,
+    "IPv4Forwarding": true,
     "Images": 46,
     "IndexServerAddress": "https://index.docker.io/v1/";,
     "InitPath": "/usr/local/bin/docker",
@@ -23,12 +23,12 @@
     "KernelVersion": "3.16.7-tinycore64",
     "Labels": null,
     "MemTotal": 2105585664,
-    "MemoryLimit": 1,
+    "MemoryLimit": true,
     "NCPU": 8,
     "NEventsListener": 0,
     "NFd": 10,
     "NGoroutines": 11,
     "Name": "boot2docker",
     "OperatingSystem": "Boot2Docker 1.4.1 (TCL 5.4); master : 86f7ec8 - Tue 
Dec 16 23:11:29 UTC 2014",
-    "SwapLimit": 1
+    "SwapLimit": true
 }
\ No newline at end of file

Reply via email to