mirror of https://github.com/apache/jclouds.git
support for docker 1.3.2
- update value objects (Container, Config) - add new value object (Resource, StatusCode) - add more options for ContainerApi - add support for pause/unpause, restart, kill, copy and attach APIs + Mock and Live tests - add *ParseTest - refactor MockTests - removed *Options.NONE - cleanup low-value javadoc - more coverage in LiveTests - removed useless DockerProperties - add comments for TLS issue - use Date where needed - fix listImages - add package-private constructor to value classes - remove KillOptions, RestartOptions, StopOptions in favour of @QueryParam - use PEM instead of PKCS12 format - update docker/pom.xml to use sshj dependencies - explicit usage of OkHttp driver - simplify DockerApiMetadata - add bouncycastle driver explicitly
This commit is contained in:
parent
6219b77dbc
commit
14da3d680a
|
@ -7,10 +7,16 @@ providers, it supports the same portable abstractions offered by jclouds.
|
||||||
Please follow these steps to configure your workstation for jclouds-docker:
|
Please follow these steps to configure your workstation for jclouds-docker:
|
||||||
|
|
||||||
- install the latest Docker release (please visit https://docs.docker.com/installation/)
|
- 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 create a p12 certificate using the following command:
|
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:
|
||||||
|
|
||||||
`openssl pkcs12 -export -out $HOME/.jclouds/docker.p12 -inkey $HOME/.boot2docker/certs/boot2docker-vm/key.pem -in $HOME/.boot2docker/certs/boot2docker-vm/cert.pem -certfile $HOME/.boot2docker/certs/boot2docker-vm/ca.pem`
|
` keytool -import -trustcacerts -file /Users/andrea/.boot2docker/certs/boot2docker-vm/ca.pem -alias BOOT2DOCKER -keystore $JAVA_HOME/jre/lib/security/cacerts`
|
||||||
|
|
||||||
|
by default the passoword is `changeit`
|
||||||
|
|
||||||
|
N.B.: From `Docker 1.3.2+` the server doesn't accept sslv3 protocol (https://github.com/docker/docker/pull/8588/files)
|
||||||
|
|
||||||
#How it works
|
#How it works
|
||||||
|
|
||||||
|
@ -45,8 +51,9 @@ then you need to create a p12 certificate using the following command:
|
||||||
As jclouds docker support is quite new, issues may occasionally arise. Please follow these steps to get things going again:
|
As jclouds docker support is quite new, issues may occasionally arise. Please follow these steps to get things going again:
|
||||||
|
|
||||||
1. Remove all containers
|
1. Remove all containers
|
||||||
|
|
||||||
`$ docker ps -aq | xargs docker rm -f`
|
$ docker rm `docker ps -a`
|
||||||
|
|
||||||
2. remove all the images
|
2. remove all the images
|
||||||
|
|
||||||
`$ docker images -q | xargs docker rmi -f`
|
$ docker rmi -f `docker images -q`
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<test.docker.endpoint>https://localhost:4243</test.docker.endpoint>
|
<test.docker.endpoint>https://localhost:4243</test.docker.endpoint>
|
||||||
<test.docker.api-version>1.10</test.docker.api-version>
|
<test.docker.api-version>1.15</test.docker.api-version>
|
||||||
<test.docker.identity>FIXME</test.docker.identity>
|
<test.docker.identity>FIXME</test.docker.identity>
|
||||||
<test.docker.credential>FIXME</test.docker.credential>
|
<test.docker.credential>FIXME</test.docker.credential>
|
||||||
<jclouds.osgi.export>org.jclouds.docker*;version="${project.version}"</jclouds.osgi.export>
|
<jclouds.osgi.export>org.jclouds.docker*;version="${project.version}"</jclouds.osgi.export>
|
||||||
|
@ -67,7 +67,16 @@
|
||||||
<groupId>org.apache.jclouds.driver</groupId>
|
<groupId>org.apache.jclouds.driver</groupId>
|
||||||
<artifactId>jclouds-sshj</artifactId>
|
<artifactId>jclouds-sshj</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>test</scope>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jclouds.driver</groupId>
|
||||||
|
<artifactId>jclouds-bouncycastle</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jclouds.driver</groupId>
|
||||||
|
<artifactId>jclouds-okhttp</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.jclouds</groupId>
|
<groupId>org.apache.jclouds</groupId>
|
||||||
|
|
|
@ -52,8 +52,6 @@ public class DockerApiMetadata extends BaseHttpApiMetadata<DockerApi> {
|
||||||
|
|
||||||
public static Properties defaultProperties() {
|
public static Properties defaultProperties() {
|
||||||
Properties properties = BaseHttpApiMetadata.defaultProperties();
|
Properties properties = BaseHttpApiMetadata.defaultProperties();
|
||||||
properties.setProperty(Constants.PROPERTY_MAX_RETRIES, "15");
|
|
||||||
properties.setProperty("jclouds.ssh.retry-auth", "true");
|
|
||||||
properties.setProperty(Constants.PROPERTY_CONNECTION_TIMEOUT, "1200000"); // 15 minutes
|
properties.setProperty(Constants.PROPERTY_CONNECTION_TIMEOUT, "1200000"); // 15 minutes
|
||||||
properties.setProperty(ComputeServiceProperties.IMAGE_LOGIN_USER, "root:password");
|
properties.setProperty(ComputeServiceProperties.IMAGE_LOGIN_USER, "root:password");
|
||||||
properties.setProperty(TEMPLATE, "osFamily=UBUNTU,os64Bit=true");
|
properties.setProperty(TEMPLATE, "osFamily=UBUNTU,os64Bit=true");
|
||||||
|
@ -66,8 +64,8 @@ public class DockerApiMetadata extends BaseHttpApiMetadata<DockerApi> {
|
||||||
super(DockerApi.class);
|
super(DockerApi.class);
|
||||||
id("docker")
|
id("docker")
|
||||||
.name("Docker API")
|
.name("Docker API")
|
||||||
.identityName("Path to Certificate .p12 file")
|
.identityName("Path to certificate .pem file")
|
||||||
.credentialName("Password to Certificate")
|
.credentialName("Password to key .pem file")
|
||||||
.documentation(URI.create("https://docs.docker.com/reference/api/docker_remote_api/"))
|
.documentation(URI.create("https://docs.docker.com/reference/api/docker_remote_api/"))
|
||||||
.version("1.15")
|
.version("1.15")
|
||||||
.defaultEndpoint("https://127.0.0.1:2376")
|
.defaultEndpoint("https://127.0.0.1:2376")
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.jclouds.docker.domain.Container;
|
||||||
import org.jclouds.docker.domain.ContainerSummary;
|
import org.jclouds.docker.domain.ContainerSummary;
|
||||||
import org.jclouds.docker.domain.HostConfig;
|
import org.jclouds.docker.domain.HostConfig;
|
||||||
import org.jclouds.docker.domain.Image;
|
import org.jclouds.docker.domain.Image;
|
||||||
|
import org.jclouds.docker.domain.ImageSummary;
|
||||||
import org.jclouds.docker.options.ListContainerOptions;
|
import org.jclouds.docker.options.ListContainerOptions;
|
||||||
import org.jclouds.docker.options.RemoveContainerOptions;
|
import org.jclouds.docker.options.RemoveContainerOptions;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
|
@ -170,14 +171,13 @@ public class DockerComputeServiceAdapter implements
|
||||||
@Override
|
@Override
|
||||||
public Set<Image> listImages() {
|
public Set<Image> listImages() {
|
||||||
Set<Image> images = Sets.newHashSet();
|
Set<Image> images = Sets.newHashSet();
|
||||||
for (Image image : api.getImageApi().listImages()) {
|
for (ImageSummary imageSummary : api.getImageApi().listImages()) {
|
||||||
// less efficient than just listImages but returns richer json that needs repoTags coming from listImages
|
// less efficient than just listImages but returns richer json that needs repoTags coming from listImages
|
||||||
Image inspected = api.getImageApi().inspectImage(image.id());
|
Image inspected = api.getImageApi().inspectImage(imageSummary.id());
|
||||||
if (inspected.repoTags().isEmpty()) {
|
inspected = Image.create(inspected.id(), inspected.author(), inspected.comment(), inspected.config(),
|
||||||
inspected = Image.create(inspected.id(), inspected.parent(), inspected.container(), inspected.created(),
|
inspected.containerConfig(), inspected.parent(), inspected.created(), inspected.container(),
|
||||||
inspected.dockerVersion(), inspected.architecture(), inspected.os(), inspected.size(),
|
inspected.dockerVersion(), inspected.architecture(), inspected.os(), inspected.size(),
|
||||||
inspected.virtualSize(), image.repoTags());
|
inspected.virtualSize(), imageSummary.repoTags());
|
||||||
}
|
|
||||||
images.add(inspected);
|
images.add(inspected);
|
||||||
}
|
}
|
||||||
return images;
|
return images;
|
||||||
|
@ -237,12 +237,12 @@ public class DockerComputeServiceAdapter implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resumeNode(String id) {
|
public void resumeNode(String id) {
|
||||||
throw new UnsupportedOperationException("resume not supported");
|
api.getContainerApi().unpause(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void suspendNode(String id) {
|
public void suspendNode(String id) {
|
||||||
throw new UnsupportedOperationException("suspend not supported");
|
api.getContainerApi().pause(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,28 +16,23 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.docker.config;
|
package org.jclouds.docker.config;
|
||||||
|
|
||||||
import java.security.KeyStore;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
|
|
||||||
import org.jclouds.docker.DockerApi;
|
import org.jclouds.docker.DockerApi;
|
||||||
import org.jclouds.docker.handlers.DockerErrorHandler;
|
import org.jclouds.docker.handlers.DockerErrorHandler;
|
||||||
import org.jclouds.docker.suppliers.KeyStoreSupplier;
|
|
||||||
import org.jclouds.docker.suppliers.SSLContextWithKeysSupplier;
|
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
|
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
||||||
|
import org.jclouds.http.okhttp.OkHttpClientSupplier;
|
||||||
|
import org.jclouds.http.okhttp.config.OkHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.rest.ConfiguresHttpApi;
|
import org.jclouds.rest.ConfiguresHttpApi;
|
||||||
import org.jclouds.rest.config.HttpApiModule;
|
import org.jclouds.rest.config.HttpApiModule;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.inject.TypeLiteral;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the Docker connection.
|
* Configures the Docker connection.
|
||||||
*/
|
*/
|
||||||
@ConfiguresHttpApi
|
@ConfiguresHttpApi
|
||||||
|
@ConfiguresHttpCommandExecutorService
|
||||||
public class DockerHttpApiModule extends HttpApiModule<DockerApi> {
|
public class DockerHttpApiModule extends HttpApiModule<DockerApi> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,11 +48,8 @@ public class DockerHttpApiModule extends HttpApiModule<DockerApi> {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(new TypeLiteral<Supplier<SSLContext>>() {
|
install(new OkHttpCommandExecutorServiceModule());
|
||||||
}).to(new TypeLiteral<SSLContextWithKeysSupplier>() {
|
bind(OkHttpClientSupplier.class).to(DockerOkHttpClientSupplier.class);
|
||||||
});
|
|
||||||
bind(new TypeLiteral<Supplier<KeyStore>>() {
|
|
||||||
}).to(new TypeLiteral<KeyStoreSupplier>() {
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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.config;
|
||||||
|
|
||||||
|
import org.jclouds.docker.suppliers.SSLContextWithKeysSupplier;
|
||||||
|
import org.jclouds.http.okhttp.OkHttpClientSupplier;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.squareup.okhttp.ConnectionSpec;
|
||||||
|
import com.squareup.okhttp.OkHttpClient;
|
||||||
|
import com.squareup.okhttp.TlsVersion;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@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 connectionSpecs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_0, TlsVersion.TLS_1_1, TlsVersion.TLS_1_2)
|
||||||
|
.build();
|
||||||
|
client.setConnectionSpecs(ImmutableList.of(connectionSpecs));
|
||||||
|
client.setSslSocketFactory(sslContextWithKeysSupplier.get().getSocketFactory());
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,7 +21,9 @@ import org.jclouds.json.config.GsonModule;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
|
|
||||||
public class DockerParserModule extends AbstractModule {
|
public class DockerParserModule extends AbstractModule {
|
||||||
|
|
||||||
@Override protected void configure() {
|
@Override protected void configure() {
|
||||||
bind(GsonModule.DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
|
bind(GsonModule.DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,8 @@ import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.json.SerializedNames;
|
import org.jclouds.json.SerializedNames;
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
import com.google.auto.value.AutoValue;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
@AutoValue
|
@AutoValue
|
||||||
public abstract class Config {
|
public abstract class Config {
|
||||||
|
@ -49,8 +49,6 @@ public abstract class Config {
|
||||||
|
|
||||||
public abstract boolean attachStderr();
|
public abstract boolean attachStderr();
|
||||||
|
|
||||||
public abstract Map<String, ?> exposedPorts();
|
|
||||||
|
|
||||||
public abstract boolean tty();
|
public abstract boolean tty();
|
||||||
|
|
||||||
public abstract boolean openStdin();
|
public abstract boolean openStdin();
|
||||||
|
@ -61,34 +59,75 @@ public abstract class Config {
|
||||||
|
|
||||||
public abstract List<String> cmd();
|
public abstract List<String> cmd();
|
||||||
|
|
||||||
public abstract List<String> dns();
|
public abstract List<String> entrypoint();
|
||||||
|
|
||||||
public abstract String image();
|
public abstract String image();
|
||||||
|
|
||||||
public abstract Map<String, ?> volumes();
|
public abstract Map<String, ?> volumes();
|
||||||
|
|
||||||
@Nullable public abstract String volumesFrom();
|
|
||||||
|
|
||||||
@Nullable public abstract String workingDir();
|
@Nullable public abstract String workingDir();
|
||||||
|
|
||||||
public abstract List<String> entrypoint();
|
|
||||||
|
|
||||||
public abstract boolean networkDisabled();
|
public abstract boolean networkDisabled();
|
||||||
|
|
||||||
public abstract List<String> onBuild();
|
public abstract Map<String, ?> exposedPorts();
|
||||||
|
|
||||||
|
public abstract List<String> securityOpts();
|
||||||
|
|
||||||
|
@Nullable public abstract HostConfig hostConfig();
|
||||||
|
|
||||||
|
public abstract List<String> binds();
|
||||||
|
|
||||||
|
public abstract List<String> links();
|
||||||
|
|
||||||
|
public abstract List<Map<String, String>> lxcConf();
|
||||||
|
|
||||||
|
public abstract Map<String, List<Map<String, String>>> portBindings();
|
||||||
|
|
||||||
|
public abstract boolean publishAllPorts();
|
||||||
|
|
||||||
|
public abstract boolean privileged();
|
||||||
|
|
||||||
|
@Nullable public abstract List<String> dns();
|
||||||
|
|
||||||
|
@Nullable public abstract String dnsSearch();
|
||||||
|
|
||||||
|
@Nullable public abstract String volumesFrom();
|
||||||
|
|
||||||
|
public abstract List<String> capAdd();
|
||||||
|
|
||||||
|
public abstract List<String> capDrop();
|
||||||
|
|
||||||
|
public abstract Map<String, String> restartPolicy();
|
||||||
|
|
||||||
|
@Nullable public abstract String networkMode();
|
||||||
|
|
||||||
|
public abstract Map<String, String> devices();
|
||||||
|
|
||||||
|
Config() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames(
|
@SerializedNames(
|
||||||
{ "Hostname", "Domainname", "User", "Memory", "MemorySwap", "CpuShares", "AttachStdin", "AttachStdout",
|
{
|
||||||
"AttachStderr", "ExposedPorts", "Tty", "OpenStdin", "StdinOnce", "Env", "Cmd", "Dns", "Image", "Volumes",
|
"Hostname", "Domainname", "User", "Memory", "MemorySwap", "CpuShares", "AttachStdin", "AttachStdout",
|
||||||
"VolumesFrom", "WorkingDir", "Entrypoint", "NetworkDisabled", "OnBuild" })
|
"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"
|
||||||
|
})
|
||||||
public static Config create(String hostname, String domainname, String user, int memory, int memorySwap,
|
public static Config create(String hostname, String domainname, String user, int memory, int memorySwap,
|
||||||
int cpuShares, boolean attachStdin, boolean attachStdout, boolean attachStderr, Map<String, ?> exposedPorts,
|
int cpuShares, boolean attachStdin, boolean attachStdout, boolean attachStderr, boolean tty,
|
||||||
boolean tty, boolean openStdin, boolean stdinOnce, List<String> env, List<String> cmd, List<String> dns,
|
boolean openStdin, boolean stdinOnce, List<String> env, List<String> cmd, List<String> entrypoint,
|
||||||
String image, Map<String, ?> volumes, String volumesFrom, String workingDir, List<String> entrypoint,
|
String image, Map<String, ?> volumes, String workingDir, boolean networkDisabled,
|
||||||
boolean networkDisabled, List<String> onBuild) {
|
Map<String, ?> exposedPorts, List<String> securityOpts, HostConfig hostConfig, List<String> binds,
|
||||||
return new AutoValue_Config(hostname, domainname, user, memory, memorySwap, cpuShares, attachStdin, attachStdout,
|
List<String> links, List<Map<String, String>> lxcConf, Map<String, List<Map<String, String>>> portBindings,
|
||||||
attachStderr, copyOf(exposedPorts), tty, openStdin, stdinOnce, copyOf(env), copyOf(cmd), copyOf(dns), image,
|
boolean publishAllPorts, boolean privileged, List<String> dns, String dnsSearch, String volumesFrom,
|
||||||
copyOf(volumes), volumesFrom, workingDir, copyOf(entrypoint), networkDisabled, copyOf(onBuild));
|
List<String> capAdd, List<String> capDrop, Map<String, String> restartPolicy, String networkMode, Map<String, String> devices) {
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
|
@ -109,21 +148,33 @@ public abstract class Config {
|
||||||
private boolean attachStdin;
|
private boolean attachStdin;
|
||||||
private boolean attachStdout;
|
private boolean attachStdout;
|
||||||
private boolean attachStderr;
|
private boolean attachStderr;
|
||||||
private Map<String, ?> exposedPorts = ImmutableMap.of();
|
|
||||||
private List<String> env = ImmutableList.of();
|
|
||||||
private boolean tty;
|
private boolean tty;
|
||||||
private boolean openStdin;
|
private boolean openStdin;
|
||||||
private boolean stdinOnce;
|
private boolean stdinOnce;
|
||||||
private List<String> cmd = ImmutableList.of();
|
private List<String> env = Lists.newArrayList();
|
||||||
private List<String> dns = ImmutableList.of();
|
private List<String> cmd = Lists.newArrayList();
|
||||||
|
private List<String> entrypoint = Lists.newArrayList();
|
||||||
private String image;
|
private String image;
|
||||||
private Map<String, ?> volumes = ImmutableMap.of();
|
private Map<String, ?> volumes = Maps.newHashMap();
|
||||||
private String volumesFrom;
|
|
||||||
private String workingDir;
|
private String workingDir;
|
||||||
private List<String> entrypoint = ImmutableList.of();
|
|
||||||
private boolean networkDisabled;
|
private boolean networkDisabled;
|
||||||
private List<String> onBuild = ImmutableList.of();
|
private Map<String, ?> exposedPorts = Maps.newHashMap();
|
||||||
private Map<String, String> restartPolicy = ImmutableMap.of();
|
private List<String> securityOpts = Lists.newArrayList();
|
||||||
|
private HostConfig hostConfig;
|
||||||
|
private List<String> binds = Lists.newArrayList();
|
||||||
|
private List<String> links = Lists.newArrayList();
|
||||||
|
private List<Map<String, String>> lxcConf = Lists.newArrayList();
|
||||||
|
private Map<String, List<Map<String, String>>> portBindings = Maps.newHashMap();
|
||||||
|
private boolean publishAllPorts;
|
||||||
|
private boolean privileged;
|
||||||
|
private List<String> dns;
|
||||||
|
private String dnsSearch;
|
||||||
|
private String volumesFrom;
|
||||||
|
private List<String> capAdd = Lists.newArrayList();
|
||||||
|
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) {
|
public Builder hostname(String hostname) {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
@ -170,11 +221,6 @@ public abstract class Config {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder exposedPorts(Map<String, ?> exposedPorts) {
|
|
||||||
this.exposedPorts = ImmutableMap.copyOf(checkNotNull(exposedPorts, "exposedPorts"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder tty(boolean tty) {
|
public Builder tty(boolean tty) {
|
||||||
this.tty = tty;
|
this.tty = tty;
|
||||||
return this;
|
return this;
|
||||||
|
@ -196,32 +242,7 @@ public abstract class Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder cmd(List<String> cmd) {
|
public Builder cmd(List<String> cmd) {
|
||||||
this.cmd = ImmutableList.copyOf(checkNotNull(cmd, "cmd"));
|
this.cmd = cmd;
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder dns(List<String> dns) {
|
|
||||||
this.dns = ImmutableList.copyOf(checkNotNull(dns, "dns"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder image(String image) {
|
|
||||||
this.image = image;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder volumes(Map<String, ?> volumes) {
|
|
||||||
this.volumes = ImmutableMap.copyOf(checkNotNull(volumes, "volumes"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder volumesFrom(String volumesFrom) {
|
|
||||||
this.volumesFrom = volumesFrom;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder workingDir(String workingDir) {
|
|
||||||
this.workingDir = workingDir;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,35 +251,129 @@ public abstract class Config {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder image(String image) {
|
||||||
|
this.image = checkNotNull(image, "image");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder volumes(Map<String, ?> volumes) {
|
||||||
|
this.volumes = volumes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder workingDir(String workingDir) {
|
||||||
|
this.workingDir = workingDir;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder networkDisabled(boolean networkDisabled) {
|
public Builder networkDisabled(boolean networkDisabled) {
|
||||||
this.networkDisabled = networkDisabled;
|
this.networkDisabled = networkDisabled;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder onBuild(List<String> onBuild) {
|
public Builder exposedPorts(Map<String, ?> exposedPorts) {
|
||||||
this.onBuild = ImmutableList.copyOf(checkNotNull(onBuild, "onBuild"));
|
this.exposedPorts = exposedPorts;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder securityOpts(List<String> securityOpts) {
|
||||||
|
this.securityOpts = securityOpts;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hostConfig(HostConfig hostConfig) {
|
||||||
|
this.hostConfig = checkNotNull(hostConfig, "hostConfig");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder binds(List<String> binds) {
|
||||||
|
this.binds = binds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder links(List<String> links) {
|
||||||
|
this.links = links;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder lxcConf(List<Map<String, String>> lxcConf) {
|
||||||
|
this.lxcConf = lxcConf;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder portBindings(Map<String, List<Map<String, String>>> portBindings) {
|
||||||
|
this.portBindings = portBindings;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder publishAllPorts(boolean publishAllPorts) {
|
||||||
|
this.publishAllPorts = publishAllPorts;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder privileged(boolean privileged) {
|
||||||
|
this.privileged = privileged;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder dns(List<String> dns) {
|
||||||
|
this.dns = dns;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder dnsSearch(String dnsSearch) {
|
||||||
|
this.dnsSearch = dnsSearch;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder volumesFrom(String volumesFrom) {
|
||||||
|
this.volumesFrom = volumesFrom;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder capAdd(List<String> capAdd) {
|
||||||
|
this.capAdd = capAdd;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder capDrop(List<String> capDrop) {
|
||||||
|
this.capDrop = capDrop;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder restartPolicy(Map<String, String> restartPolicy) {
|
public Builder restartPolicy(Map<String, String> restartPolicy) {
|
||||||
this.restartPolicy = ImmutableMap.copyOf(restartPolicy);
|
this.restartPolicy = restartPolicy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder networkMode(String networkMode) {
|
||||||
|
this.networkMode = networkMode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder devices(Map<String, String> devices) {
|
||||||
|
this.devices = devices;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Config build() {
|
public Config build() {
|
||||||
return Config.create(hostname, domainname, user, memory, memorySwap, cpuShares, attachStdin, attachStdout,
|
return Config.create(hostname, domainname, user, memory, memorySwap, cpuShares, attachStdin, attachStdout,
|
||||||
attachStderr, exposedPorts, tty, openStdin, stdinOnce, env, cmd, dns, image, volumes, volumesFrom,
|
attachStderr, tty, openStdin, stdinOnce, env, cmd, entrypoint, image, volumes, workingDir,
|
||||||
workingDir, entrypoint, networkDisabled, onBuild);
|
networkDisabled, exposedPorts, securityOpts, hostConfig, binds, links, lxcConf, portBindings,
|
||||||
|
publishAllPorts, privileged, dns, dnsSearch, volumesFrom, capAdd, capDrop, restartPolicy,
|
||||||
|
networkMode, devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder fromConfig(Config in) {
|
public Builder fromConfig(Config in) {
|
||||||
return hostname(in.hostname()).domainname(in.domainname()).user(in.user()).memory(in.memory())
|
return hostname(in.hostname()).domainname(in.domainname()).user(in.user()).memory(in.memory())
|
||||||
.memorySwap(in.memorySwap()).cpuShares(in.cpuShares()).attachStdin(in.attachStdin())
|
.memorySwap(in.memorySwap()).cpuShares(in.cpuShares()).attachStdin(in.attachStdin())
|
||||||
.attachStdout(in.attachStdout()).attachStderr(in.attachStderr()).exposedPorts(in.exposedPorts())
|
.attachStdout(in.attachStdout()).attachStderr(in.attachStderr()).tty(in.tty())
|
||||||
.tty(in.tty()).openStdin(in.openStdin()).stdinOnce(in.stdinOnce()).env(in.env()).cmd(in.cmd())
|
.image(in.image()).volumes(in.volumes()).workingDir(in.workingDir())
|
||||||
.dns(in.dns()).image(in.image()).volumes(in.volumes()).volumesFrom(in.volumesFrom())
|
.networkDisabled(in.networkDisabled()).exposedPorts(in.exposedPorts()).securityOpts(in.securityOpts())
|
||||||
.workingDir(in.workingDir()).entrypoint(in.entrypoint()).networkDisabled(in.networkDisabled())
|
.hostConfig(in.hostConfig()).binds(in.binds()).links(in.links()).lxcConf(in.lxcConf())
|
||||||
.onBuild(in.onBuild());
|
.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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.jclouds.docker.domain;
|
||||||
|
|
||||||
import static org.jclouds.docker.internal.NullSafeCopies.copyOf;
|
import static org.jclouds.docker.internal.NullSafeCopies.copyOf;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -32,12 +33,12 @@ import com.google.common.collect.ImmutableMap;
|
||||||
public abstract class Container {
|
public abstract class Container {
|
||||||
public abstract String id();
|
public abstract String id();
|
||||||
|
|
||||||
@Nullable public abstract String name();
|
@Nullable public abstract Date created();
|
||||||
|
|
||||||
@Nullable public abstract String created();
|
|
||||||
|
|
||||||
@Nullable public abstract String path();
|
@Nullable public abstract String path();
|
||||||
|
|
||||||
|
@Nullable public abstract String name();
|
||||||
|
|
||||||
public abstract List<String> args();
|
public abstract List<String> args();
|
||||||
|
|
||||||
@Nullable public abstract Config config();
|
@Nullable public abstract Config config();
|
||||||
|
@ -48,37 +49,52 @@ public abstract class Container {
|
||||||
|
|
||||||
@Nullable public abstract NetworkSettings networkSettings();
|
@Nullable public abstract NetworkSettings networkSettings();
|
||||||
|
|
||||||
|
@Nullable public abstract String sysInitPath();
|
||||||
|
|
||||||
@Nullable public abstract String resolvConfPath();
|
@Nullable public abstract String resolvConfPath();
|
||||||
|
|
||||||
|
public abstract Map<String, String> volumes();
|
||||||
|
|
||||||
|
@Nullable public abstract HostConfig hostConfig();
|
||||||
|
|
||||||
@Nullable public abstract String driver();
|
@Nullable public abstract String driver();
|
||||||
|
|
||||||
@Nullable public abstract String execDriver();
|
@Nullable public abstract String execDriver();
|
||||||
|
|
||||||
public abstract Map<String, String> volumes();
|
|
||||||
|
|
||||||
public abstract Map<String, Boolean> volumesRW();
|
public abstract Map<String, Boolean> volumesRW();
|
||||||
|
|
||||||
@Nullable public abstract String command();
|
@Nullable public abstract String command();
|
||||||
|
|
||||||
@Nullable public abstract String status();
|
@Nullable public abstract String status();
|
||||||
|
|
||||||
@Nullable public abstract HostConfig hostConfig();
|
|
||||||
|
|
||||||
public abstract List<Port> ports();
|
public abstract List<Port> ports();
|
||||||
|
|
||||||
@Nullable public abstract String hostnamePath();
|
@Nullable public abstract String hostnamePath();
|
||||||
|
|
||||||
|
@Nullable public abstract String hostsPath();
|
||||||
|
|
||||||
|
@Nullable public abstract String mountLabel();
|
||||||
|
|
||||||
|
@Nullable public abstract String processLabel();
|
||||||
|
|
||||||
|
Container() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames(
|
@SerializedNames(
|
||||||
{ "Id", "Name", "Created", "Path", "Args", "Config", "State", "Image", "NetworkSettings", "ResolvConfPath",
|
{
|
||||||
"Driver", "ExecDriver", "Volumes", "VolumesRW", "Command", "Status", "HostConfig", "Ports",
|
"Id", "Created", "Path", "Name", "Args", "Config", "State", "Image", "NetworkSettings", "SysInitPath",
|
||||||
"HostnamePath" })
|
"ResolvConfPath", "Volumes", "HostConfig", "Driver", "ExecDriver", "VolumesRW", "Command", "Status",
|
||||||
public static Container create(String id, String name, String created, String path, List<String> args, Config config,
|
"Ports", "HostnamePath", "HostsPath", "MountLabel", "ProcessLabel"
|
||||||
State state, String image, NetworkSettings networkSettings, String resolvConfPath, String driver,
|
})
|
||||||
String execDriver, Map<String, String> volumes, Map<String, Boolean> volumesRW, String command, String status,
|
public static Container create(String id, Date created, String path, String name, List<String> args, Config config,
|
||||||
HostConfig hostConfig, List<Port> ports, String hostnamePath) {
|
State state, String image, NetworkSettings networkSettings, String sysInitPath,
|
||||||
return new AutoValue_Container(id, name, created, path, copyOf(args), config, state, image, networkSettings,
|
String resolvConfPath, Map<String, String> volumes, HostConfig hostConfig,
|
||||||
resolvConfPath, driver, execDriver, copyOf(volumes), copyOf(volumesRW), command, status, hostConfig,
|
String driver, String execDriver, Map<String, Boolean> volumesRW, String command,
|
||||||
copyOf(ports), hostnamePath);
|
String status, List<Port> ports, String hostnamePath, String hostsPath,
|
||||||
|
String mountLabel, String processLabel) {
|
||||||
|
return new AutoValue_Container(id, created, path, name, copyOf(args), config, state, image, networkSettings,
|
||||||
|
sysInitPath, resolvConfPath, copyOf(volumes), hostConfig, driver, execDriver, copyOf(volumesRW), command,
|
||||||
|
status, copyOf(ports), hostnamePath, hostsPath, mountLabel, processLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
|
@ -92,36 +108,35 @@ public abstract class Container {
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private String name;
|
private Date created;
|
||||||
private String created;
|
|
||||||
private String path;
|
private String path;
|
||||||
|
private String name;
|
||||||
private List<String> args;
|
private List<String> args;
|
||||||
private Config config;
|
private Config config;
|
||||||
private State state;
|
private State state;
|
||||||
private String image;
|
private String image;
|
||||||
private NetworkSettings networkSettings;
|
private NetworkSettings networkSettings;
|
||||||
|
private String sysInitPath;
|
||||||
private String resolvConfPath;
|
private String resolvConfPath;
|
||||||
|
private Map<String, String> volumes = ImmutableMap.of();
|
||||||
|
private HostConfig hostConfig;
|
||||||
private String driver;
|
private String driver;
|
||||||
private String execDriver;
|
private String execDriver;
|
||||||
private Map<String, String> volumes = ImmutableMap.of();
|
|
||||||
private Map<String, Boolean> volumesRW = ImmutableMap.of();
|
private Map<String, Boolean> volumesRW = ImmutableMap.of();
|
||||||
private String command;
|
private String command;
|
||||||
private String status;
|
private String status;
|
||||||
private HostConfig hostConfig;
|
|
||||||
private List<Port> ports = ImmutableList.of();
|
private List<Port> ports = ImmutableList.of();
|
||||||
private String hostnamePath;
|
private String hostnamePath;
|
||||||
|
private String hostsPath;
|
||||||
|
private String mountLabel;
|
||||||
|
private String processLabel;
|
||||||
|
|
||||||
public Builder id(String id) {
|
public Builder id(String id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder name(String name) {
|
public Builder created(Date created) {
|
||||||
this.name = name;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder created(String created) {
|
|
||||||
this.created = created;
|
this.created = created;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -131,6 +146,11 @@ public abstract class Container {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder args(List<String> args) {
|
public Builder args(List<String> args) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
return this;
|
return this;
|
||||||
|
@ -156,11 +176,26 @@ public abstract class Container {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder sysInitPath(String sysInitPath) {
|
||||||
|
this.sysInitPath = sysInitPath;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder resolvConfPath(String resolvConfPath) {
|
public Builder resolvConfPath(String resolvConfPath) {
|
||||||
this.resolvConfPath = resolvConfPath;
|
this.resolvConfPath = resolvConfPath;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder volumes(Map<String, String> volumes) {
|
||||||
|
this.volumes = volumes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hostConfig(HostConfig hostConfig) {
|
||||||
|
this.hostConfig = hostConfig;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder driver(String driver) {
|
public Builder driver(String driver) {
|
||||||
this.driver = driver;
|
this.driver = driver;
|
||||||
return this;
|
return this;
|
||||||
|
@ -171,11 +206,6 @@ public abstract class Container {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder volumes(Map<String, String> volumes) {
|
|
||||||
this.volumes = volumes;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder volumesRW(Map<String, Boolean> volumesRW) {
|
public Builder volumesRW(Map<String, Boolean> volumesRW) {
|
||||||
this.volumesRW = volumesRW;
|
this.volumesRW = volumesRW;
|
||||||
return this;
|
return this;
|
||||||
|
@ -191,11 +221,6 @@ public abstract class Container {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder hostConfig(HostConfig hostConfig) {
|
|
||||||
this.hostConfig = hostConfig;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder ports(List<Port> ports) {
|
public Builder ports(List<Port> ports) {
|
||||||
this.ports = ports;
|
this.ports = ports;
|
||||||
return this;
|
return this;
|
||||||
|
@ -206,17 +231,34 @@ public abstract class Container {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder hostsPath(String hostsPath) {
|
||||||
|
this.hostsPath = hostsPath;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mountLabel(String mountLabel) {
|
||||||
|
this.mountLabel = mountLabel;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder processLabel(String processLabel) {
|
||||||
|
this.processLabel = processLabel;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Container build() {
|
public Container build() {
|
||||||
return Container.create(id, name, created, path, args, config, state, image, networkSettings, resolvConfPath,
|
return Container.create(id, created, path, name, args, config, state, image, networkSettings,
|
||||||
driver, execDriver, volumes, volumesRW, command, status, hostConfig, ports, hostnamePath);
|
sysInitPath, resolvConfPath, volumes, hostConfig, driver, execDriver, volumesRW, command, status,
|
||||||
|
ports, hostnamePath, hostsPath, mountLabel, processLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder fromContainer(Container in) {
|
public Builder fromContainer(Container in) {
|
||||||
return this.id(in.id()).name(in.name()).created(in.created()).path(in.path()).args(in.args())
|
return this.id(in.id()).name(in.name()).created(in.created()).path(in.path()).args(in.args())
|
||||||
.config(in.config()).state(in.state()).image(in.image()).networkSettings(in.networkSettings())
|
.config(in.config()).state(in.state()).image(in.image()).networkSettings(in.networkSettings())
|
||||||
.resolvConfPath(in.resolvConfPath()).driver(in.driver()).execDriver(in.execDriver())
|
.sysInitPath(in.sysInitPath()).resolvConfPath(in.resolvConfPath()).driver(in.driver())
|
||||||
.volumes(in.volumes()).volumesRW(in.volumesRW()).command(in.command()).status(in.status())
|
.execDriver(in.execDriver()).volumes(in.volumes()).hostConfig(in.hostConfig()).volumesRW(in.volumesRW())
|
||||||
.hostConfig(in.hostConfig()).ports(in.ports()).hostnamePath(in.hostnamePath());
|
.command(in.command()).status(in.status()).ports(in.ports()).hostnamePath(in.hostnamePath())
|
||||||
|
.hostsPath(in.hostsPath()).mountLabel(in.mountLabel()).processLabel(in.processLabel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,9 @@ public abstract class ContainerSummary {
|
||||||
|
|
||||||
public abstract String status();
|
public abstract String status();
|
||||||
|
|
||||||
|
ContainerSummary() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames({"Id", "Names", "Created", "Image", "Command", "Ports", "Status"})
|
@SerializedNames({"Id", "Names", "Created", "Image", "Command", "Ports", "Status"})
|
||||||
public static ContainerSummary create(String id, List<String> names, String created, String image, String command, List<Port> ports, String status) {
|
public static ContainerSummary create(String id, List<String> names, String created, String image, String command, List<Port> ports, String status) {
|
||||||
return new AutoValue_ContainerSummary(id, copyOf(names), created, image, command, copyOf(ports), status);
|
return new AutoValue_ContainerSummary(id, copyOf(names), created, image, command, copyOf(ports), status);
|
||||||
|
|
|
@ -30,6 +30,9 @@ public abstract class ExposedPorts {
|
||||||
|
|
||||||
public abstract List<String> hostPorts();
|
public abstract List<String> hostPorts();
|
||||||
|
|
||||||
|
ExposedPorts() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames({ "PortAndProtocol", "HostPorts" })
|
@SerializedNames({ "PortAndProtocol", "HostPorts" })
|
||||||
public static ExposedPorts create(String portAndProtocol, List<String> hostPorts) {
|
public static ExposedPorts create(String portAndProtocol, List<String> hostPorts) {
|
||||||
return new AutoValue_ExposedPorts(portAndProtocol, copyOf(hostPorts));
|
return new AutoValue_ExposedPorts(portAndProtocol, copyOf(hostPorts));
|
||||||
|
|
|
@ -51,6 +51,9 @@ public abstract class HostConfig {
|
||||||
|
|
||||||
public abstract List<String> volumesFrom();
|
public abstract List<String> volumesFrom();
|
||||||
|
|
||||||
|
HostConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames({ "ContainerIDFile", "Binds", "LxcConf", "Privileged", "Dns", "DnsSearch", "PortBindings",
|
@SerializedNames({ "ContainerIDFile", "Binds", "LxcConf", "Privileged", "Dns", "DnsSearch", "PortBindings",
|
||||||
"Links", "PublishAllPorts", "VolumesFrom" })
|
"Links", "PublishAllPorts", "VolumesFrom" })
|
||||||
public static HostConfig create(String containerIDFile, List<String> binds, List<Map<String, String>> lxcConf,
|
public static HostConfig create(String containerIDFile, List<String> binds, List<Map<String, String>> lxcConf,
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.jclouds.docker.domain;
|
||||||
|
|
||||||
import static org.jclouds.docker.internal.NullSafeCopies.copyOf;
|
import static org.jclouds.docker.internal.NullSafeCopies.copyOf;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
@ -27,32 +28,43 @@ import com.google.auto.value.AutoValue;
|
||||||
|
|
||||||
@AutoValue
|
@AutoValue
|
||||||
public abstract class Image {
|
public abstract class Image {
|
||||||
|
|
||||||
public abstract String id();
|
public abstract String id();
|
||||||
|
|
||||||
@Nullable public abstract String parent();
|
@Nullable public abstract String author();
|
||||||
|
|
||||||
@Nullable public abstract String created();
|
@Nullable public abstract String comment();
|
||||||
|
|
||||||
@Nullable public abstract String container();
|
@Nullable public abstract Config config();
|
||||||
|
|
||||||
@Nullable public abstract String dockerVersion();
|
@Nullable public abstract Config containerConfig();
|
||||||
|
|
||||||
@Nullable public abstract String architecture();
|
public abstract String parent();
|
||||||
|
|
||||||
@Nullable public abstract String os();
|
public abstract Date created();
|
||||||
|
|
||||||
|
public abstract String container();
|
||||||
|
|
||||||
|
public abstract String dockerVersion();
|
||||||
|
|
||||||
|
public abstract String architecture();
|
||||||
|
|
||||||
|
public abstract String os();
|
||||||
|
|
||||||
public abstract long size();
|
public abstract long size();
|
||||||
|
|
||||||
@Nullable public abstract long virtualSize();
|
public abstract long virtualSize();
|
||||||
|
|
||||||
public abstract List<String> repoTags();
|
@Nullable public abstract List<String> repoTags();
|
||||||
|
|
||||||
@SerializedNames({ "Id", "Parent", "Created", "Container", "DockerVersion", "Architecture", "Os", "Size",
|
Image() {
|
||||||
"VirtualSize", "RepoTags" })
|
}
|
||||||
public static Image create(String id, String parent, String created, String container, String dockerVersion,
|
|
||||||
String architecture, String os, long size, long virtualSize, List<String> repoTags) {
|
@SerializedNames({ "Id", "Author", "Comment", "Config", "ContainerConfig", "Parent", "Created",
|
||||||
return new AutoValue_Image(id, parent, created, container, dockerVersion, architecture, os, size, virtualSize,
|
"Container", "DockerVersion", "Architecture", "Os", "Size", "VirtualSize", "RepoTags" })
|
||||||
copyOf(repoTags));
|
public static Image create(String id, String author, String comment, Config config, Config containerConfig, String parent, Date created, String container, String dockerVersion, String architecture, String os, long size, long virtualSize, List<String> repoTags) {
|
||||||
|
return new AutoValue_Image(id, author, comment, config, containerConfig, parent, created, container,
|
||||||
|
dockerVersion, architecture, os, size, virtualSize, copyOf(repoTags));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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.domain;
|
||||||
|
|
||||||
|
import static org.jclouds.docker.internal.NullSafeCopies.copyOf;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jclouds.json.SerializedNames;
|
||||||
|
|
||||||
|
import com.google.auto.value.AutoValue;
|
||||||
|
|
||||||
|
// TODO it may be redundant (we already have Image value class)
|
||||||
|
@AutoValue
|
||||||
|
public abstract class ImageSummary {
|
||||||
|
|
||||||
|
public abstract String id();
|
||||||
|
|
||||||
|
public abstract long created();
|
||||||
|
|
||||||
|
public abstract String parentId();
|
||||||
|
|
||||||
|
public abstract int size();
|
||||||
|
|
||||||
|
public abstract int virtualSize();
|
||||||
|
|
||||||
|
public abstract List<String> repoTags();
|
||||||
|
|
||||||
|
ImageSummary() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedNames({"Id", "Created", "ParentId", "Size", "VirtualSize", "RepoTags"})
|
||||||
|
public static ImageSummary create(String id, long created, String parentId, int size, int virtualSize,
|
||||||
|
List<String> repoTags) {
|
||||||
|
return new AutoValue_ImageSummary(id, created, parentId, size, virtualSize, copyOf(repoTags));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.docker.domain;
|
package org.jclouds.docker.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.json.SerializedNames;
|
import org.jclouds.json.SerializedNames;
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
import com.google.auto.value.AutoValue;
|
||||||
|
@ -25,39 +27,52 @@ public abstract class Info {
|
||||||
|
|
||||||
public abstract int containers();
|
public abstract int containers();
|
||||||
|
|
||||||
public abstract int images();
|
public abstract int debug();
|
||||||
|
|
||||||
public abstract String driver();
|
public abstract String driver();
|
||||||
|
|
||||||
|
public abstract List<List<String>> driverStatus();
|
||||||
|
|
||||||
public abstract String executionDriver();
|
public abstract String executionDriver();
|
||||||
|
|
||||||
|
public abstract int iPv4Forwarding();
|
||||||
|
|
||||||
|
public abstract int images();
|
||||||
|
|
||||||
|
public abstract String indexServerAddress();
|
||||||
|
|
||||||
|
public abstract String initPath();
|
||||||
|
|
||||||
|
public abstract String initSha1();
|
||||||
|
|
||||||
public abstract String kernelVersion();
|
public abstract String kernelVersion();
|
||||||
|
|
||||||
public abstract int debug();
|
public abstract int memoryLimit();
|
||||||
|
|
||||||
|
public abstract int nEventsListener();
|
||||||
|
|
||||||
public abstract int nFd();
|
public abstract int nFd();
|
||||||
|
|
||||||
public abstract int nGoroutines();
|
public abstract int nGoroutines();
|
||||||
|
|
||||||
public abstract int nEventsListener();
|
public abstract String operatingSystem();
|
||||||
|
|
||||||
public abstract String initPath();
|
|
||||||
|
|
||||||
public abstract String indexServerAddress();
|
|
||||||
|
|
||||||
public abstract int memoryLimit();
|
|
||||||
|
|
||||||
public abstract int swapLimit();
|
public abstract int swapLimit();
|
||||||
|
|
||||||
public abstract int iPv4Forwarding();
|
Info() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames(
|
@SerializedNames({
|
||||||
{"Containers", "Images", "Driver", "ExecutionDriver", "KernelVersion", "Debug", "NFd", "NGoroutines",
|
"Containers", "Debug", "Driver", "DriverStatus", "ExecutionDriver", "IPv4Forwarding", "Images",
|
||||||
"NEventsListener", "InitPath", "IndexServerAddress", "MemoryLimit", "SwapLimit", "IPv4Forwarding"})
|
"IndexServerAddress", "InitPath", "InitSha1", "KernelVersion", "MemoryLimit", "NEventsListener",
|
||||||
public static Info create(int containers, int images, String driver, String executionDriver, String kernelVersion, int debug,
|
"NFd", "NGoroutines", "OperatingSystem", "SwapLimit"
|
||||||
int nFd, int nGoroutines, int nEventsListener, String initPath, String indexServerAddress,
|
})
|
||||||
int memoryLimit, int swapLimit, int iPv4Forwarding) {
|
public static Info create(int containers, int debug, String driver, List<List<String>> driverStatus,
|
||||||
return new AutoValue_Info(containers, images, driver, executionDriver, kernelVersion, debug, nFd, nGoroutines,
|
String executionDriver, int iPv4Forwarding, int images, String indexServerAddress,
|
||||||
nEventsListener, initPath, indexServerAddress, memoryLimit, swapLimit, iPv4Forwarding);
|
String initPath, String initSha1, String kernelVersion, int memoryLimit,
|
||||||
|
int nEventsListener, int nFd, int nGoroutines, String operatingSystem, int swapLimit) {
|
||||||
|
return new AutoValue_Info(containers, debug, driver, driverStatus, executionDriver, iPv4Forwarding, images,
|
||||||
|
indexServerAddress, initPath, initSha1, kernelVersion, memoryLimit, nEventsListener, nFd, nGoroutines,
|
||||||
|
operatingSystem, swapLimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@ public abstract class NetworkSettings {
|
||||||
|
|
||||||
public abstract Map<String, List<Map<String, String>>> ports();
|
public abstract Map<String, List<Map<String, String>>> ports();
|
||||||
|
|
||||||
|
NetworkSettings() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames({ "IPAddress", "IPPrefixLen", "Gateway", "Bridge", "PortMapping", "Ports" })
|
@SerializedNames({ "IPAddress", "IPPrefixLen", "Gateway", "Bridge", "PortMapping", "Ports" })
|
||||||
public static NetworkSettings create(String ipAddress, int ipPrefixLen, String gateway, String bridge,
|
public static NetworkSettings create(String ipAddress, int ipPrefixLen, String gateway, String bridge,
|
||||||
String portMapping, Map<String, List<Map<String, String>>> ports) {
|
String portMapping, Map<String, List<Map<String, String>>> ports) {
|
||||||
|
|
|
@ -30,6 +30,9 @@ public abstract class Port {
|
||||||
|
|
||||||
public abstract String type();
|
public abstract String type();
|
||||||
|
|
||||||
|
Port() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames({ "IP", "PrivatePort", "PublicPort", "Type" })
|
@SerializedNames({ "IP", "PrivatePort", "PublicPort", "Type" })
|
||||||
public static Port create(String ip, int privatePort, int publicPort, String type) {
|
public static Port create(String ip, int privatePort, int publicPort, String type) {
|
||||||
return new AutoValue_Port(ip, privatePort, publicPort, type);
|
return new AutoValue_Port(ip, privatePort, publicPort, type);
|
||||||
|
|
|
@ -14,13 +14,22 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.docker.config;
|
package org.jclouds.docker.domain;
|
||||||
|
|
||||||
public class DockerProperties {
|
import org.jclouds.json.SerializedNames;
|
||||||
|
|
||||||
/**
|
import com.google.auto.value.AutoValue;
|
||||||
* default Docker host password
|
|
||||||
*/
|
|
||||||
public static final String HOST_PASSWORD = "jclouds.docker.host.password";
|
|
||||||
|
|
||||||
|
@AutoValue
|
||||||
|
public abstract class Resource {
|
||||||
|
|
||||||
|
public abstract String resource();
|
||||||
|
|
||||||
|
Resource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedNames({ "Resource" })
|
||||||
|
public static Resource create(String resource) {
|
||||||
|
return new AutoValue_Resource(resource);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -32,11 +32,16 @@ public abstract class State {
|
||||||
|
|
||||||
public abstract String finishedAt();
|
public abstract String finishedAt();
|
||||||
|
|
||||||
public abstract boolean ghost();
|
public abstract boolean paused();
|
||||||
|
|
||||||
@SerializedNames({ "Pid", "Running", "ExitCode", "StartedAt", "FinishedAt", "Ghost" })
|
public abstract boolean restarting();
|
||||||
|
|
||||||
|
State() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedNames({ "Pid", "Running", "ExitCode", "StartedAt", "FinishedAt", "Paused", "Restarting" })
|
||||||
public static State create(int pid, boolean running, int exitCode, String startedAt, String finishedAt,
|
public static State create(int pid, boolean running, int exitCode, String startedAt, String finishedAt,
|
||||||
boolean ghost) {
|
boolean paused, boolean restarting) {
|
||||||
return new AutoValue_State(pid, running, exitCode, startedAt, finishedAt, ghost);
|
return new AutoValue_State(pid, running, exitCode, startedAt, finishedAt, paused, restarting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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.domain;
|
||||||
|
|
||||||
|
import org.jclouds.json.SerializedNames;
|
||||||
|
|
||||||
|
import com.google.auto.value.AutoValue;
|
||||||
|
|
||||||
|
@AutoValue
|
||||||
|
public abstract class StatusCode {
|
||||||
|
|
||||||
|
public abstract int statusCode();
|
||||||
|
|
||||||
|
StatusCode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedNames({ "StatusCode" })
|
||||||
|
public static StatusCode create(int statusCode) {
|
||||||
|
return new AutoValue_StatusCode(statusCode);
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,9 @@ public abstract class Version {
|
||||||
|
|
||||||
public abstract String version();
|
public abstract String version();
|
||||||
|
|
||||||
|
Version() {
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedNames({ "ApiVersion", "Arch", "GitCommit", "GoVersion", "KernelVersion", "Os", "Version" })
|
@SerializedNames({ "ApiVersion", "Arch", "GitCommit", "GoVersion", "KernelVersion", "Os", "Version" })
|
||||||
public static Version create(String apiVersion, String arch, String gitCommit, String goVersion,
|
public static Version create(String apiVersion, String arch, String gitCommit, String goVersion,
|
||||||
String kernelVersion, String os, String version) {
|
String kernelVersion, String os, String version) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.docker.features;
|
package org.jclouds.docker.features;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
@ -28,12 +29,16 @@ import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks;
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
import org.jclouds.docker.domain.Config;
|
import org.jclouds.docker.domain.Config;
|
||||||
import org.jclouds.docker.domain.Container;
|
import org.jclouds.docker.domain.Container;
|
||||||
import org.jclouds.docker.domain.ContainerSummary;
|
import org.jclouds.docker.domain.ContainerSummary;
|
||||||
import org.jclouds.docker.domain.HostConfig;
|
import org.jclouds.docker.domain.HostConfig;
|
||||||
import org.jclouds.docker.domain.Image;
|
import org.jclouds.docker.domain.Image;
|
||||||
|
import org.jclouds.docker.domain.Resource;
|
||||||
|
import org.jclouds.docker.domain.StatusCode;
|
||||||
|
import org.jclouds.docker.options.AttachOptions;
|
||||||
import org.jclouds.docker.options.CommitOptions;
|
import org.jclouds.docker.options.CommitOptions;
|
||||||
import org.jclouds.docker.options.ListContainerOptions;
|
import org.jclouds.docker.options.ListContainerOptions;
|
||||||
import org.jclouds.docker.options.RemoveContainerOptions;
|
import org.jclouds.docker.options.RemoveContainerOptions;
|
||||||
|
@ -42,34 +47,29 @@ import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/v{jclouds.api-version}")
|
||||||
public interface ContainerApi {
|
public interface ContainerApi {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all running containers
|
|
||||||
*
|
|
||||||
* @return a set of containers
|
* @return a set of containers
|
||||||
*/
|
*/
|
||||||
@Named("containers:list")
|
@Named("containers:list")
|
||||||
@GET
|
@GET
|
||||||
@Path("/containers/json")
|
@Path("/containers/json")
|
||||||
@Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
|
@Fallback(EmptyListOnNotFoundOr404.class)
|
||||||
List<ContainerSummary> listContainers();
|
List<ContainerSummary> listContainers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all running containers
|
|
||||||
*
|
|
||||||
* @param options the options to list the containers (@see ListContainerOptions)
|
* @param options the options to list the containers (@see ListContainerOptions)
|
||||||
* @return a set of containers
|
* @return a set of containers
|
||||||
*/
|
*/
|
||||||
@Named("containers:list")
|
@Named("containers:list")
|
||||||
@GET
|
@GET
|
||||||
@Path("/containers/json")
|
@Path("/containers/json")
|
||||||
@Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
|
@Fallback(EmptyListOnNotFoundOr404.class)
|
||||||
List<ContainerSummary> listContainers(ListContainerOptions options);
|
List<ContainerSummary> listContainers(ListContainerOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a container
|
|
||||||
*
|
|
||||||
* @param name the name for the new container. Must match /?[a-zA-Z0-9_-]+.
|
* @param name the name for the new container. Must match /?[a-zA-Z0-9_-]+.
|
||||||
* @param config the container’s configuration (@see BindToJsonPayload)
|
* @param config the container’s configuration (@see BindToJsonPayload)
|
||||||
* @return a new container
|
* @return a new container
|
||||||
|
@ -87,12 +87,10 @@ public interface ContainerApi {
|
||||||
@Named("container:inspect")
|
@Named("container:inspect")
|
||||||
@GET
|
@GET
|
||||||
@Path("/containers/{id}/json")
|
@Path("/containers/{id}/json")
|
||||||
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
|
@Fallback(NullOnNotFoundOr404.class)
|
||||||
Container inspectContainer(@PathParam("id") String containerId);
|
Container inspectContainer(@PathParam("id") String containerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the container by id from the filesystem
|
|
||||||
*
|
|
||||||
* @param containerId The id of the container to be removed.
|
* @param containerId The id of the container to be removed.
|
||||||
*/
|
*/
|
||||||
@Named("container:delete")
|
@Named("container:delete")
|
||||||
|
@ -101,8 +99,6 @@ public interface ContainerApi {
|
||||||
void removeContainer(@PathParam("id") String containerId);
|
void removeContainer(@PathParam("id") String containerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the container by id from the filesystem
|
|
||||||
*
|
|
||||||
* @param containerId The id of the container to be removed.
|
* @param containerId The id of the container to be removed.
|
||||||
* @param options the operation’s configuration (@see RemoveContainerOptions)
|
* @param options the operation’s configuration (@see RemoveContainerOptions)
|
||||||
*/
|
*/
|
||||||
|
@ -112,8 +108,6 @@ public interface ContainerApi {
|
||||||
void removeContainer(@PathParam("id") String containerId, RemoveContainerOptions options);
|
void removeContainer(@PathParam("id") String containerId, RemoveContainerOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a container by id.
|
|
||||||
*
|
|
||||||
* @param containerId The id of the container to be started.
|
* @param containerId The id of the container to be started.
|
||||||
*/
|
*/
|
||||||
@Named("container:start")
|
@Named("container:start")
|
||||||
|
@ -122,8 +116,6 @@ public interface ContainerApi {
|
||||||
void startContainer(@PathParam("id") String containerId);
|
void startContainer(@PathParam("id") String containerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a container.
|
|
||||||
*
|
|
||||||
* @param containerId The id of the container to be started.
|
* @param containerId The id of the container to be started.
|
||||||
* @param hostConfig the container’s host configuration
|
* @param hostConfig the container’s host configuration
|
||||||
*/
|
*/
|
||||||
|
@ -133,16 +125,28 @@ public interface ContainerApi {
|
||||||
void startContainer(@PathParam("id") String containerId, @BinderParam(BindToJsonPayload.class) HostConfig hostConfig);
|
void startContainer(@PathParam("id") String containerId, @BinderParam(BindToJsonPayload.class) HostConfig hostConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop a container by id.
|
|
||||||
*
|
|
||||||
* @param containerId The id of the container to be stopped.
|
* @param containerId The id of the container to be stopped.
|
||||||
* @return the stream of the stop execution.
|
|
||||||
*/
|
*/
|
||||||
@Named("container:stop")
|
@Named("container:stop")
|
||||||
@POST
|
@POST
|
||||||
@Path("/containers/{id}/stop")
|
@Path("/containers/{id}/stop")
|
||||||
void stopContainer(@PathParam("id") String containerId);
|
void stopContainer(@PathParam("id") String containerId);
|
||||||
|
|
||||||
|
@Named("container:stop")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/stop")
|
||||||
|
void stopContainer(@PathParam("id") String containerId, @QueryParam("t") int secondsToWait);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new image from a container’s changes
|
||||||
|
*
|
||||||
|
* @return a new image created from the current container's status.
|
||||||
|
*/
|
||||||
|
@Named("container:commit")
|
||||||
|
@POST
|
||||||
|
@Path("/commit")
|
||||||
|
Image commit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new image from a container’s changes
|
* Create a new image from a container’s changes
|
||||||
*
|
*
|
||||||
|
@ -154,4 +158,95 @@ public interface ContainerApi {
|
||||||
@Path("/commit")
|
@Path("/commit")
|
||||||
Image commit(CommitOptions options);
|
Image commit(CommitOptions options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId The id of the container to be paused.
|
||||||
|
*/
|
||||||
|
@Named("container:pause")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/pause")
|
||||||
|
void pause(@PathParam("id") String containerId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId The id of the container to be unpaused.
|
||||||
|
*/
|
||||||
|
@Named("container:unpause")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/unpause")
|
||||||
|
void unpause(@PathParam("id") String containerId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId The id of the container to be attached.
|
||||||
|
*/
|
||||||
|
@Named("container:attach")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/attach")
|
||||||
|
InputStream attach(@PathParam("id") String containerId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId The id of the container to be attached.
|
||||||
|
* @param options the attach options @see org.jclouds.docker.options.AttachOptions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Named("container:attach")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/attach")
|
||||||
|
InputStream attach(@PathParam("id") String containerId, AttachOptions options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block until container @param containerId stops, then returns the exit code
|
||||||
|
*/
|
||||||
|
@Named("container:wait")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/wait")
|
||||||
|
StatusCode wait(@PathParam("id") String containerId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId restarts
|
||||||
|
*/
|
||||||
|
@Named("container:restart")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/restart")
|
||||||
|
void restart(@PathParam("id") String containerId);
|
||||||
|
|
||||||
|
@Named("container:restart")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/restart")
|
||||||
|
void restart(@PathParam("id") String containerId, @QueryParam("t") int secondsToWait);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId to be killed
|
||||||
|
*/
|
||||||
|
@Named("container:kill")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/kill")
|
||||||
|
void kill(@PathParam("id") String containerId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId to be killed
|
||||||
|
* @param signal Signal to send to the container. When not set, SIGKILL is assumed and the call will waits for the
|
||||||
|
* container to exit.
|
||||||
|
*/
|
||||||
|
@Named("container:kill")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/kill")
|
||||||
|
void kill(@PathParam("id") String containerId, @QueryParam("signal") int signal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId to be killed
|
||||||
|
* @param signal Signal string like "SIGINT" to send to the container. When not set, SIGKILL is assumed and the call will waits for
|
||||||
|
* the container to exit.
|
||||||
|
*/
|
||||||
|
@Named("container:kill")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/kill")
|
||||||
|
void kill(@PathParam("id") String containerId, @QueryParam("signal") String signal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param containerId id of the container to copy files from
|
||||||
|
*/
|
||||||
|
@Named("container:copy")
|
||||||
|
@POST
|
||||||
|
@Path("/containers/{id}/copy")
|
||||||
|
InputStream copy(@PathParam("id") String containerId, @BinderParam(BindToJsonPayload.class) Resource resource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,49 +28,48 @@ import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks;
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
import org.jclouds.docker.domain.Image;
|
import org.jclouds.docker.domain.Image;
|
||||||
|
import org.jclouds.docker.domain.ImageSummary;
|
||||||
import org.jclouds.docker.options.CreateImageOptions;
|
import org.jclouds.docker.options.CreateImageOptions;
|
||||||
import org.jclouds.docker.options.DeleteImageOptions;
|
import org.jclouds.docker.options.DeleteImageOptions;
|
||||||
import org.jclouds.docker.options.ListImageOptions;
|
import org.jclouds.docker.options.ListImageOptions;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/v{jclouds.api-version}")
|
||||||
public interface ImageApi {
|
public interface ImageApi {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List images
|
|
||||||
*
|
|
||||||
* @return the images available.
|
* @return the images available.
|
||||||
*/
|
*/
|
||||||
@Named("images:list")
|
@Named("images:list")
|
||||||
@GET
|
@GET
|
||||||
@Path("/images/json")
|
@Path("/images/json")
|
||||||
@Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
|
@Fallback(EmptyListOnNotFoundOr404.class)
|
||||||
List<Image> listImages();
|
List<ImageSummary> listImages();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List images
|
|
||||||
*
|
|
||||||
* @param options the configuration to list images (@see ListImageOptions)
|
* @param options the configuration to list images (@see ListImageOptions)
|
||||||
* @return the images available.
|
* @return the images available.
|
||||||
*/
|
*/
|
||||||
@Named("images:list")
|
@Named("images:list")
|
||||||
@GET
|
@GET
|
||||||
@Path("/images/json")
|
@Path("/images/json")
|
||||||
@Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
|
@Fallback(EmptyListOnNotFoundOr404.class)
|
||||||
List<Image> listImages(ListImageOptions options);
|
List<ImageSummary> listImages(ListImageOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inspect an image
|
|
||||||
*
|
|
||||||
* @param imageName The id of the image to inspect.
|
* @param imageName The id of the image to inspect.
|
||||||
* @return low-level information on the image name
|
* @return low-level information on the image name
|
||||||
*/
|
*/
|
||||||
@Named("image:inspect")
|
@Named("image:inspect")
|
||||||
@GET
|
@GET
|
||||||
@Path("/images/{name}/json")
|
@Path("/images/{name}/json")
|
||||||
@Fallback(Fallbacks.VoidOnNotFoundOr404.class)
|
@Fallback(NullOnNotFoundOr404.class)
|
||||||
|
@Nullable
|
||||||
Image inspectImage(@PathParam("name") String imageName);
|
Image inspectImage(@PathParam("name") String imageName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,8 +84,6 @@ public interface ImageApi {
|
||||||
InputStream createImage(CreateImageOptions options);
|
InputStream createImage(CreateImageOptions options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete an image.
|
|
||||||
*
|
|
||||||
* @param name the image name to be deleted
|
* @param name the image name to be deleted
|
||||||
* @return the stream of the deletion execution.
|
* @return the stream of the deletion execution.
|
||||||
*/
|
*/
|
||||||
|
@ -96,8 +93,6 @@ public interface ImageApi {
|
||||||
InputStream deleteImage(@PathParam("name") String name);
|
InputStream deleteImage(@PathParam("name") String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the image from the filesystem by name
|
|
||||||
*
|
|
||||||
* @param name the name of the image to be removed
|
* @param name the name of the image to be removed
|
||||||
* @param options the image deletion's options (@see DeleteImageOptions)
|
* @param options the image deletion's options (@see DeleteImageOptions)
|
||||||
* @return the stream of the deletion execution.
|
* @return the stream of the deletion execution.
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.jclouds.io.Payload;
|
||||||
import org.jclouds.rest.annotations.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/v{jclouds.api-version}")
|
||||||
public interface MiscApi {
|
public interface MiscApi {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,6 +55,18 @@ public interface MiscApi {
|
||||||
@Path("/info")
|
@Path("/info")
|
||||||
Info getInfo();
|
Info getInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an image from Dockerfile via stdin
|
||||||
|
*
|
||||||
|
* @param inputStream The stream must be a tar archive compressed with one of the following algorithms: identity
|
||||||
|
* (no compression), gzip, bzip2, xz.
|
||||||
|
* @return a stream of the build execution
|
||||||
|
*/
|
||||||
|
@Named("image:build")
|
||||||
|
@POST
|
||||||
|
@Path("/build")
|
||||||
|
@Headers(keys = "Content-Type", values = "application/tar")
|
||||||
|
InputStream build(Payload inputStream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build an image from Dockerfile via stdin
|
* Build an image from Dockerfile via stdin
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* 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.options;
|
||||||
|
|
||||||
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
|
public class AttachOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stream When TTY is enabled, the stream is the raw data from the process PTY and client's stdin.
|
||||||
|
* When TTY is disabled, the stream is multiplexed to separate stdout and stderr.
|
||||||
|
* @return AttachOptions
|
||||||
|
*/
|
||||||
|
public AttachOptions stream(Boolean stream) {
|
||||||
|
this.queryParameters.put("stream", stream.toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param logs require logs to be attached. Default false.
|
||||||
|
* @return AttachOptions
|
||||||
|
*/
|
||||||
|
public AttachOptions logs(Boolean logs) {
|
||||||
|
this.queryParameters.put("logs", logs.toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stdin if stream=true, attach to stdin. Default false
|
||||||
|
* @return AttachOptions
|
||||||
|
*/
|
||||||
|
public AttachOptions stdin(Boolean stdin) {
|
||||||
|
this.queryParameters.put("stdin", stdin.toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stdout if logs=true, return stdout log, if stream=true, attach to stdout. Default false
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public AttachOptions stdout(Boolean stdout) {
|
||||||
|
this.queryParameters.put("stdout", stdout.toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param stderr if logs=true, return stderr log, if stream=true, attach to stderr. Default false
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public AttachOptions stderr(Boolean stderr) {
|
||||||
|
this.queryParameters.put("stderr", stderr.toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.docker.options.AttachOptions#stream
|
||||||
|
*/
|
||||||
|
public static AttachOptions stream(Boolean stream) {
|
||||||
|
AttachOptions options = new AttachOptions();
|
||||||
|
return options.stream(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.docker.options.AttachOptions#logs(Boolean)
|
||||||
|
*/
|
||||||
|
public static AttachOptions logs(Boolean logs) {
|
||||||
|
AttachOptions options = new AttachOptions();
|
||||||
|
return options.logs(logs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.docker.options.AttachOptions#stdin(Boolean)
|
||||||
|
*/
|
||||||
|
public static AttachOptions stdin(Boolean stdin) {
|
||||||
|
AttachOptions options = new AttachOptions();
|
||||||
|
return options.stdin(stdin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.docker.options.AttachOptions#stdout(Boolean)
|
||||||
|
*/
|
||||||
|
public static AttachOptions stdout(Boolean stdout) {
|
||||||
|
AttachOptions options = new AttachOptions();
|
||||||
|
return options.stdout(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.docker.options.AttachOptions#stderr(Boolean)
|
||||||
|
*/
|
||||||
|
public static AttachOptions stderr(Boolean stderr) {
|
||||||
|
AttachOptions options = new AttachOptions();
|
||||||
|
return options.stderr(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,13 +18,8 @@ package org.jclouds.docker.options;
|
||||||
|
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Options to customize image builder.
|
|
||||||
*/
|
|
||||||
public class BuildOptions extends BaseHttpRequestOptions {
|
public class BuildOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
public static final BuildOptions NONE = new BuildOptions();
|
|
||||||
|
|
||||||
public BuildOptions tag(String tag) {
|
public BuildOptions tag(String tag) {
|
||||||
this.queryParameters.put("tag", tag);
|
this.queryParameters.put("tag", tag);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -18,13 +18,8 @@ package org.jclouds.docker.options;
|
||||||
|
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Options to customize image commit.
|
|
||||||
*/
|
|
||||||
public class CommitOptions extends BaseHttpRequestOptions {
|
public class CommitOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
public static final CommitOptions NONE = new CommitOptions();
|
|
||||||
|
|
||||||
public CommitOptions containerId(String containerId) {
|
public CommitOptions containerId(String containerId) {
|
||||||
this.queryParameters.put("containerId", containerId);
|
this.queryParameters.put("containerId", containerId);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -18,13 +18,8 @@ package org.jclouds.docker.options;
|
||||||
|
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Options to customize container creation.
|
|
||||||
*/
|
|
||||||
public class CreateImageOptions extends BaseHttpRequestOptions {
|
public class CreateImageOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
public static final CreateImageOptions NONE = new CreateImageOptions();
|
|
||||||
|
|
||||||
public CreateImageOptions fromImage(String fromImage) {
|
public CreateImageOptions fromImage(String fromImage) {
|
||||||
this.queryParameters.put("fromImage", fromImage);
|
this.queryParameters.put("fromImage", fromImage);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -18,18 +18,18 @@ package org.jclouds.docker.options;
|
||||||
|
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Options to customize image deletion.
|
|
||||||
*/
|
|
||||||
public class DeleteImageOptions extends BaseHttpRequestOptions {
|
public class DeleteImageOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
public static final DeleteImageOptions NONE = new DeleteImageOptions();
|
|
||||||
|
|
||||||
public DeleteImageOptions force(Boolean force) {
|
public DeleteImageOptions force(Boolean force) {
|
||||||
this.queryParameters.put("force", force.toString());
|
this.queryParameters.put("force", force.toString());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DeleteImageOptions noPrune(Boolean noPrune) {
|
||||||
|
this.queryParameters.put("noPrune", noPrune.toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +39,14 @@ public class DeleteImageOptions extends BaseHttpRequestOptions {
|
||||||
DeleteImageOptions options = new DeleteImageOptions();
|
DeleteImageOptions options = new DeleteImageOptions();
|
||||||
return options.force(force);
|
return options.force(force);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DeleteImageOptions#noPrune
|
||||||
|
*/
|
||||||
|
public static DeleteImageOptions noPrune(Boolean noPrune) {
|
||||||
|
DeleteImageOptions options = new DeleteImageOptions();
|
||||||
|
return options.noPrune(noPrune);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,8 @@ package org.jclouds.docker.options;
|
||||||
|
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Options to customize container's listing.
|
|
||||||
*/
|
|
||||||
public class ListContainerOptions extends BaseHttpRequestOptions {
|
public class ListContainerOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
public static final ListContainerOptions NONE = new ListContainerOptions();
|
|
||||||
|
|
||||||
public ListContainerOptions all(Boolean all) {
|
public ListContainerOptions all(Boolean all) {
|
||||||
this.queryParameters.put("all", all.toString());
|
this.queryParameters.put("all", all.toString());
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -18,13 +18,8 @@ package org.jclouds.docker.options;
|
||||||
|
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Options to customize image's listing.
|
|
||||||
*/
|
|
||||||
public class ListImageOptions extends BaseHttpRequestOptions {
|
public class ListImageOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
public static final ListImageOptions NONE = new ListImageOptions();
|
|
||||||
|
|
||||||
public ListImageOptions all(Boolean all) {
|
public ListImageOptions all(Boolean all) {
|
||||||
this.queryParameters.put("all", all.toString());
|
this.queryParameters.put("all", all.toString());
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -18,13 +18,8 @@ package org.jclouds.docker.options;
|
||||||
|
|
||||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Options to customize container removal.
|
|
||||||
*/
|
|
||||||
public class RemoveContainerOptions extends BaseHttpRequestOptions {
|
public class RemoveContainerOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
public static final RemoveContainerOptions NONE = new RemoveContainerOptions();
|
|
||||||
|
|
||||||
public RemoveContainerOptions verbose(Boolean verbose) {
|
public RemoveContainerOptions verbose(Boolean verbose) {
|
||||||
this.queryParameters.put("verbose", verbose.toString());
|
this.queryParameters.put("verbose", verbose.toString());
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -1,130 +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.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.security.KeyStoreException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.cert.Certificate;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.CertificateFactory;
|
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.KeySpec;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.crypto.Crypto;
|
|
||||||
import org.jclouds.crypto.Pems;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.location.Provider;
|
|
||||||
import org.jclouds.rest.AuthorizationException;
|
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.common.io.ByteSource;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class KeyStoreSupplier implements Supplier<KeyStore> {
|
|
||||||
private final Crypto crypto;
|
|
||||||
private final Supplier<Credentials> creds;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
KeyStoreSupplier(Crypto crypto, @Provider Supplier<Credentials> creds) {
|
|
||||||
this.crypto = crypto;
|
|
||||||
this.creds = creds;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public KeyStore get() {
|
|
||||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
|
||||||
String cert = checkNotNull(currentCreds.identity, "credential supplier returned null identity (should be cert)");
|
|
||||||
String keyStorePassword = checkNotNull(currentCreds.credential,
|
|
||||||
"credential supplier returned null credential (should be keyStorePassword)");
|
|
||||||
try {
|
|
||||||
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
|
||||||
|
|
||||||
File certFile = new File(checkNotNull(cert));
|
|
||||||
if (certFile.isFile()) { // cert is path to pkcs12 file
|
|
||||||
FileInputStream stream = new FileInputStream(certFile);
|
|
||||||
try {
|
|
||||||
keyStore.load(stream, keyStorePassword.toCharArray());
|
|
||||||
} finally {
|
|
||||||
stream.close();
|
|
||||||
}
|
|
||||||
} else { // cert is PEM encoded, containing private key and certs
|
|
||||||
|
|
||||||
// split in private key and certs
|
|
||||||
int privateKeyBeginIdx = cert.indexOf("-----BEGIN PRIVATE KEY");
|
|
||||||
int privateKeyEndIdx = cert.indexOf("-----END PRIVATE KEY");
|
|
||||||
if (privateKeyBeginIdx != -1) {
|
|
||||||
String pemPrivateKey = cert.substring(privateKeyBeginIdx, privateKeyEndIdx + 26);
|
|
||||||
|
|
||||||
StringBuilder pemCerts = new StringBuilder();
|
|
||||||
int certsBeginIdx = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
certsBeginIdx = cert.indexOf("-----BEGIN CERTIFICATE", certsBeginIdx);
|
|
||||||
|
|
||||||
if (certsBeginIdx >= 0) {
|
|
||||||
int certsEndIdx = cert.indexOf("-----END CERTIFICATE", certsBeginIdx) + 26;
|
|
||||||
pemCerts.append(cert.substring(certsBeginIdx, certsEndIdx));
|
|
||||||
certsBeginIdx = certsEndIdx;
|
|
||||||
}
|
|
||||||
} while (certsBeginIdx != -1);
|
|
||||||
|
|
||||||
// parse private key
|
|
||||||
KeySpec keySpec = Pems.privateKeySpec(ByteSource.wrap(pemPrivateKey.getBytes(Charsets.UTF_8)));
|
|
||||||
PrivateKey privateKey = crypto.rsaKeyFactory().generatePrivate(keySpec);
|
|
||||||
|
|
||||||
// populate keystore with private key and certs
|
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Collection<Certificate> certs = (Collection<Certificate>) cf.generateCertificates(new ByteArrayInputStream(
|
|
||||||
pemCerts.toString().getBytes(Charsets.UTF_8)));
|
|
||||||
keyStore.load(null);
|
|
||||||
keyStore.setKeyEntry("dummy", privateKey, keyStorePassword.toCharArray(),
|
|
||||||
certs.toArray(new Certificate[0]));
|
|
||||||
} else {
|
|
||||||
throw new AuthorizationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keyStore;
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (KeyStoreException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (CertificateException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (InvalidKeySpecException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,60 +18,146 @@ package org.jclouds.docker.suppliers;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Throwables.propagate;
|
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.KeyManagementException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyStoreException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.security.PrivateKey;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.UnrecoverableKeyException;
|
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.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManager;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.TrustManager;
|
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.domain.Credentials;
|
||||||
import org.jclouds.http.HttpUtils;
|
import org.jclouds.http.HttpUtils;
|
||||||
import org.jclouds.http.config.SSLModule.TrustAllCerts;
|
import org.jclouds.http.config.SSLModule.TrustAllCerts;
|
||||||
import org.jclouds.location.Provider;
|
import org.jclouds.location.Provider;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class SSLContextWithKeysSupplier implements Supplier<SSLContext> {
|
public class SSLContextWithKeysSupplier implements Supplier<SSLContext> {
|
||||||
private final Supplier<KeyStore> keyStore;
|
|
||||||
private final TrustManager[] trustManager;
|
private final TrustManager[] trustManager;
|
||||||
private final Supplier<Credentials> creds;
|
private final Supplier<Credentials> creds;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SSLContextWithKeysSupplier(Supplier<KeyStore> keyStore, @Provider Supplier<Credentials> creds, HttpUtils utils,
|
SSLContextWithKeysSupplier(@Provider Supplier<Credentials> creds, HttpUtils utils, TrustAllCerts trustAllCerts) {
|
||||||
TrustAllCerts trustAllCerts) {
|
this.trustManager = utils.trustAllCerts() ? new TrustManager[]{trustAllCerts} : null;
|
||||||
this.keyStore = keyStore;
|
|
||||||
this.trustManager = utils.trustAllCerts() ? new TrustManager[] { trustAllCerts } : null;
|
|
||||||
this.creds = creds;
|
this.creds = creds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SSLContext get() {
|
public SSLContext get() {
|
||||||
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null");
|
||||||
String keyStorePassword = checkNotNull(currentCreds.credential,
|
|
||||||
"credential supplier returned null credential (should be keyStorePassword)");
|
|
||||||
KeyManagerFactory kmf;
|
|
||||||
try {
|
try {
|
||||||
kmf = KeyManagerFactory.getInstance("SunX509");
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
kmf.init(keyStore.get(), keyStorePassword.toCharArray());
|
X509Certificate certificate = getCertificate(loadFile(currentCreds.identity));
|
||||||
SSLContext sc = SSLContext.getInstance("TLS");
|
PrivateKey privateKey = getKey(loadFile(currentCreds.credential));
|
||||||
sc.init(kmf.getKeyManagers(), trustManager, new SecureRandom());
|
sslContext.init(new KeyManager[]{new InMemoryKeyManager(certificate, privateKey)}, trustManager, new SecureRandom());
|
||||||
return sc;
|
return sslContext;
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
throw propagate(e);
|
throw propagate(e);
|
||||||
} catch (UnrecoverableKeyException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (KeyStoreException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (KeyManagementException e) {
|
} catch (KeyManagementException e) {
|
||||||
throw propagate(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) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
PEMParser pemParser = new PEMParser(new StringReader(privateKey));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import org.jboss.shrinkwrap.api.GenericArchive;
|
||||||
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||||
import org.jboss.shrinkwrap.api.asset.ClassLoaderAsset;
|
import org.jboss.shrinkwrap.api.asset.ClassLoaderAsset;
|
||||||
import org.jboss.shrinkwrap.api.exporter.TarExporter;
|
import org.jboss.shrinkwrap.api.exporter.TarExporter;
|
||||||
import org.jclouds.Constants;
|
|
||||||
import org.jclouds.apis.BaseApiLiveTest;
|
import org.jclouds.apis.BaseApiLiveTest;
|
||||||
import org.jclouds.compute.config.ComputeServiceProperties;
|
import org.jclouds.compute.config.ComputeServiceProperties;
|
||||||
import org.jclouds.docker.DockerApi;
|
import org.jclouds.docker.DockerApi;
|
||||||
|
@ -57,8 +56,7 @@ public class BaseDockerApiLiveTest extends BaseApiLiveTest<DockerApi> {
|
||||||
@Override
|
@Override
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
Properties overrides = super.setupProperties();
|
Properties overrides = super.setupProperties();
|
||||||
overrides.setProperty(Constants.PROPERTY_MAX_RETRIES, "15");
|
overrides.setProperty("jclouds.trust-all-certs", "false");
|
||||||
overrides.setProperty("jclouds.ssh.retry-auth", "true");
|
|
||||||
overrides.setProperty(ComputeServiceProperties.IMAGE_LOGIN_USER, "root:password");
|
overrides.setProperty(ComputeServiceProperties.IMAGE_LOGIN_USER, "root:password");
|
||||||
return overrides;
|
return overrides;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,10 +116,4 @@ public class DockerComputeServiceAdapterLiveTest extends BaseDockerApiLiveTest {
|
||||||
return ImmutableSet.<Module>of(getLoggingModule(), new SshjSshClientModule());
|
return ImmutableSet.<Module>of(getLoggingModule(), new SshjSshClientModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Properties setupProperties() {
|
|
||||||
Properties properties = super.setupProperties();
|
|
||||||
properties.setProperty("jclouds.ssh.max-retries", "10");
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.OperatingSystem;
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
import org.jclouds.docker.domain.Config;
|
import org.jclouds.docker.domain.Config;
|
||||||
import org.jclouds.docker.domain.Container;
|
import org.jclouds.docker.domain.Container;
|
||||||
import org.jclouds.docker.domain.HostConfig;
|
import org.jclouds.docker.domain.HostConfig;
|
||||||
|
@ -97,12 +98,13 @@ public class ContainerToNodeMetadataTest {
|
||||||
0, // exitCode
|
0, // exitCode
|
||||||
"2014-03-24T20:28:37.537659054Z", // startedAt
|
"2014-03-24T20:28:37.537659054Z", // startedAt
|
||||||
"0001-01-01T00:00:00Z", // finishedAt
|
"0001-01-01T00:00:00Z", // finishedAt
|
||||||
false // ghost
|
false, // paused
|
||||||
|
false // restarting
|
||||||
);
|
);
|
||||||
container = Container.builder()
|
container = Container.builder()
|
||||||
.id("6d35806c1bd2b25cd92bba2d2c2c5169dc2156f53ab45c2b62d76e2d2fee14a9")
|
.id("6d35806c1bd2b25cd92bba2d2c2c5169dc2156f53ab45c2b62d76e2d2fee14a9")
|
||||||
.name("/hopeful_mclean")
|
.name("/hopeful_mclean")
|
||||||
.created("2014-03-22T07:16:45.784120972Z")
|
.created(new SimpleDateFormatDateService().iso8601DateParse("2014-03-22T07:16:45.784120972Z"))
|
||||||
.path("/usr/sbin/sshd")
|
.path("/usr/sbin/sshd")
|
||||||
.args(Arrays.asList("-D"))
|
.args(Arrays.asList("-D"))
|
||||||
.config(containerConfig)
|
.config(containerConfig)
|
||||||
|
|
|
@ -21,8 +21,11 @@ import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.EasyMock.verify;
|
import static org.easymock.EasyMock.verify;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.easymock.EasyMock;
|
import org.easymock.EasyMock;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.docker.domain.Config;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -41,16 +44,24 @@ public class ImageToImageTest {
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
public void setup() {
|
public void setup() {
|
||||||
image = org.jclouds.docker.domain.Image.create(
|
image = org.jclouds.docker.domain.Image.create(
|
||||||
"id", // id
|
"id", // id
|
||||||
"parent", // parent
|
"author",
|
||||||
"created", // created
|
"comment",
|
||||||
null, // container
|
Config.builder()
|
||||||
null, // dockerVersion
|
.image("imageId")
|
||||||
"x86_64", // architecture
|
.build(),
|
||||||
null, // os
|
Config.builder()
|
||||||
0l, // size
|
.image("imageId")
|
||||||
0l, // virtualSize
|
.build(),
|
||||||
ImmutableList.of("repoTag1:version") // repoTags
|
"parent", // parent
|
||||||
|
new Date(), // created
|
||||||
|
"containerId", // container
|
||||||
|
"1.3.1", // dockerVersion
|
||||||
|
"x86_64", // architecture
|
||||||
|
"os", // os
|
||||||
|
0l, // size
|
||||||
|
0l, // virtualSize
|
||||||
|
ImmutableList.of("repoTag1:version") // repoTags
|
||||||
);
|
);
|
||||||
function = new ImageToImage();
|
function = new ImageToImage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.docker.features;
|
package org.jclouds.docker.features;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -29,8 +32,11 @@ import org.jclouds.docker.domain.Config;
|
||||||
import org.jclouds.docker.domain.Container;
|
import org.jclouds.docker.domain.Container;
|
||||||
import org.jclouds.docker.domain.ContainerSummary;
|
import org.jclouds.docker.domain.ContainerSummary;
|
||||||
import org.jclouds.docker.domain.Image;
|
import org.jclouds.docker.domain.Image;
|
||||||
|
import org.jclouds.docker.domain.Resource;
|
||||||
|
import org.jclouds.docker.options.AttachOptions;
|
||||||
import org.jclouds.docker.options.CreateImageOptions;
|
import org.jclouds.docker.options.CreateImageOptions;
|
||||||
import org.jclouds.docker.options.ListContainerOptions;
|
import org.jclouds.docker.options.ListContainerOptions;
|
||||||
|
import org.jclouds.docker.options.RemoveContainerOptions;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -57,6 +63,11 @@ public class ContainerApiLiveTest extends BaseDockerApiLiveTest {
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
protected void tearDown() {
|
protected void tearDown() {
|
||||||
|
if (container != null) {
|
||||||
|
if (api.getContainerApi().inspectContainer(container.id()) != null) {
|
||||||
|
api.getContainerApi().removeContainer(container.id(), RemoveContainerOptions.Builder.force(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
api.getImageApi().deleteImage(BUSYBOX_IMAGE_TAG);
|
api.getImageApi().deleteImage(BUSYBOX_IMAGE_TAG);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +75,7 @@ public class ContainerApiLiveTest extends BaseDockerApiLiveTest {
|
||||||
|
|
||||||
public void testCreateContainer() throws IOException, InterruptedException {
|
public void testCreateContainer() throws IOException, InterruptedException {
|
||||||
Config containerConfig = Config.builder().image(image.id())
|
Config containerConfig = Config.builder().image(image.id())
|
||||||
.cmd(ImmutableList.of("/bin/sh", "-c", "while true; do echo hello world; sleep 1; done"))
|
.cmd(ImmutableList.of("/bin/sh", "-c", "touch hello; while true; do echo hello world; sleep 1; done"))
|
||||||
.build();
|
.build();
|
||||||
container = api().createContainer("testCreateContainer", containerConfig);
|
container = api().createContainer("testCreateContainer", containerConfig);
|
||||||
assertNotNull(container);
|
assertNotNull(container);
|
||||||
|
@ -78,11 +89,54 @@ public class ContainerApiLiveTest extends BaseDockerApiLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testStartContainer")
|
@Test(dependsOnMethods = "testStartContainer")
|
||||||
|
public void testAttachContainer() {
|
||||||
|
InputStream attachStream = api().attach(container.id(), AttachOptions.Builder.logs(true).stream(false).stdout(true));
|
||||||
|
String stream = consumeStream(attachStream);
|
||||||
|
assertThat(stream.trim()).contains("hello world");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testAttachContainer")
|
||||||
|
public void testCopyFileFromContainer() {
|
||||||
|
InputStream tarredStream = api().copy(container.id(), Resource.create("hello"));
|
||||||
|
assertNotNull(consumeStream(tarredStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCopyFileFromContainer")
|
||||||
|
public void testPauseContainer() {
|
||||||
|
api().pause(container.id());
|
||||||
|
assertTrue(api().inspectContainer(container.id()).state().paused());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testPauseContainer")
|
||||||
|
public void testUnpauseContainer() {
|
||||||
|
api().unpause(container.id());
|
||||||
|
assertFalse(api().inspectContainer(container.id()).state().paused());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testUnpauseContainer")
|
||||||
public void testStopContainer() {
|
public void testStopContainer() {
|
||||||
api().stopContainer(container.id());
|
api().stopContainer(container.id());
|
||||||
assertFalse(api().inspectContainer(container.id()).state().running());
|
assertFalse(api().inspectContainer(container.id()).state().running());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testStopContainer")
|
||||||
|
public void testRestartContainer() {
|
||||||
|
api().restart(container.id());
|
||||||
|
assertTrue(api().inspectContainer(container.id()).state().running());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testRestartContainer")
|
||||||
|
public void testWaitContainer() {
|
||||||
|
api().stopContainer(container.id(), 1);
|
||||||
|
assertEquals(api().wait(container.id()).statusCode(), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testWaitContainer")
|
||||||
|
public void testRemoveContainer() {
|
||||||
|
api().removeContainer(container.id());
|
||||||
|
assertNull(api().inspectContainer(container.id()));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListContainers() {
|
public void testListContainers() {
|
||||||
List<ContainerSummary> containerSummaries = api().listContainers(ListContainerOptions.Builder.all(true));
|
List<ContainerSummary> containerSummaries = api().listContainers(ListContainerOptions.Builder.all(true));
|
||||||
|
@ -93,12 +147,6 @@ public class ContainerApiLiveTest extends BaseDockerApiLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testStopContainer", expectedExceptions = NullPointerException.class)
|
|
||||||
public void testRemoveContainer() {
|
|
||||||
api().removeContainer(container.id());
|
|
||||||
assertFalse(api().inspectContainer(container.id()).state().running());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContainerApi api() {
|
private ContainerApi api() {
|
||||||
return api.getContainerApi();
|
return api.getContainerApi();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,23 +16,22 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.docker.features;
|
package org.jclouds.docker.features;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
import static org.testng.Assert.fail;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.jclouds.docker.DockerApi;
|
import org.jclouds.docker.DockerApi;
|
||||||
|
import org.jclouds.docker.config.DockerParserModule;
|
||||||
import org.jclouds.docker.domain.Config;
|
import org.jclouds.docker.domain.Config;
|
||||||
import org.jclouds.docker.domain.Container;
|
import org.jclouds.docker.domain.Container;
|
||||||
import org.jclouds.docker.domain.ContainerSummary;
|
import org.jclouds.docker.domain.Resource;
|
||||||
import org.jclouds.docker.internal.BaseDockerMockTest;
|
import org.jclouds.docker.internal.BaseDockerMockTest;
|
||||||
import org.jclouds.docker.options.ListContainerOptions;
|
import org.jclouds.docker.options.ListContainerOptions;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.docker.parse.ContainerParseTest;
|
||||||
|
import org.jclouds.docker.parse.ContainersParseTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
|
||||||
import com.squareup.okhttp.mockwebserver.MockResponse;
|
import com.squareup.okhttp.mockwebserver.MockResponse;
|
||||||
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
||||||
|
|
||||||
|
@ -43,96 +42,56 @@ import com.squareup.okhttp.mockwebserver.MockWebServer;
|
||||||
public class ContainerApiMockTest extends BaseDockerMockTest {
|
public class ContainerApiMockTest extends BaseDockerMockTest {
|
||||||
|
|
||||||
public void testListContainers() throws Exception {
|
public void testListContainers() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/containers.json")));
|
||||||
server.enqueue(new MockResponse().setBody(payloadFromResource("/containers.json")));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
|
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<ContainerSummary> containerSummaries = api.listContainers();
|
assertEquals(api.listContainers(), new ContainersParseTest().expected());
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "/containers/json");
|
assertSent(server, "GET", "/containers/json");
|
||||||
assertEquals(containerSummaries.size(), 1);
|
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListNonexistentContainers() throws Exception {
|
public void testListNonexistentContainers() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(404));
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
try {
|
try {
|
||||||
List<ContainerSummary> containerSummaries = api.listContainers();
|
assertEquals(api.listContainers(), ImmutableList.of());
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "/containers/json");
|
assertSent(server, "GET", "/containers/json");
|
||||||
assertTrue(containerSummaries.isEmpty());
|
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test(timeOut = 10000l)
|
@Test(timeOut = 10000l)
|
||||||
public void testListAllContainers() throws Exception {
|
public void testListAllContainers() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/containers.json")));
|
||||||
server.enqueue(new MockResponse().setBody(payloadFromResource("/containers.json")));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
try {
|
try {
|
||||||
List<ContainerSummary> containerSummaries = api.listContainers(ListContainerOptions.Builder.all(true));
|
assertEquals(api.listContainers(ListContainerOptions.Builder.all(true)), new ContainersParseTest().expected());
|
||||||
assertRequestHasParameters(server.takeRequest(), "/containers/json", ImmutableMultimap.of("all", "true"));
|
assertSent(server, "GET", "/containers/json?all=true");
|
||||||
assertEquals(containerSummaries.size(), 1);
|
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetContainer() throws Exception {
|
public void testGetContainer() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/container.json")));
|
||||||
server.enqueue(new MockResponse().setBody(payloadFromResource("/container.json")));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString(), new DockerParserModule()).getContainerApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
String containerId = "b03d4cd15b76f8876110615cdeed15eadf77c9beb408d62f1687dcc69192cd6d";
|
String containerId = "b03d4cd15b76f8876110615cdeed15eadf77c9beb408d62f1687dcc69192cd6d";
|
||||||
try {
|
try {
|
||||||
Container container = api.inspectContainer(containerId);
|
assertEquals(api.inspectContainer(containerId), new ContainerParseTest().expected());
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "/containers/" + containerId + "/json");
|
assertSent(server, "GET", "/containers/" + containerId + "/json");
|
||||||
assertNotNull(container);
|
|
||||||
assertNotNull(container.id(), containerId);
|
|
||||||
assertNotNull(container.config());
|
|
||||||
assertNotNull(container.hostConfig());
|
|
||||||
assertTrue(container.name().contains("/weave"));
|
|
||||||
assertEquals(container.state().running(), true);
|
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetNonExistingContainer() throws Exception {
|
|
||||||
MockWebServer server = mockWebServer();
|
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
String containerId = "notExisting";
|
|
||||||
try {
|
|
||||||
Container container = api.inspectContainer(containerId);
|
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "/containers/" + containerId + "/json");
|
|
||||||
} finally {
|
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateContainer() throws Exception {
|
public void testCreateContainer() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/container-creation.json")));
|
||||||
server.enqueue(new MockResponse().setBody(payloadFromResource("/container-creation.json")));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
Config containerConfig = Config.builder()
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
.cmd(ImmutableList.of("date"))
|
||||||
Config containerConfig = Config.builder().cmd(ImmutableList.of("date"))
|
|
||||||
.attachStdin(false)
|
.attachStdin(false)
|
||||||
.attachStderr(true)
|
.attachStderr(true)
|
||||||
.attachStdout(true)
|
.attachStdout(true)
|
||||||
|
@ -141,106 +100,135 @@ public class ContainerApiMockTest extends BaseDockerMockTest {
|
||||||
.build();
|
.build();
|
||||||
try {
|
try {
|
||||||
Container container = api.createContainer("test", containerConfig);
|
Container container = api.createContainer("test", containerConfig);
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "POST", "/containers/create?name=test");
|
assertSent(server, "POST", "/containers/create?name=test");
|
||||||
assertNotNull(container);
|
assertNotNull(container);
|
||||||
assertEquals(container.id(), "c6c74153ae4b1d1633d68890a68d89c40aa5e284a1ea016cbc6ef0e634ee37b2");
|
assertThat(container.id()).isEqualTo("c6c74153ae4b1d1633d68890a68d89c40aa5e284a1ea016cbc6ef0e634ee37b2");
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRemoveContainer() throws Exception {
|
public void testRemoveContainer() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(204));
|
||||||
server.enqueue(new MockResponse().setResponseCode(204));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
String containerId = "6d35806c1bd2b25cd92bba2d2c2c5169dc2156f53ab45c2b62d76e2d2fee14a9";
|
String containerId = "6d35806c1bd2b25cd92bba2d2c2c5169dc2156f53ab45c2b62d76e2d2fee14a9";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
api.removeContainer(containerId);
|
api.removeContainer(containerId);
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "DELETE", "/containers/" + containerId);
|
assertSent(server, "DELETE", "/containers/" + containerId);
|
||||||
} finally {
|
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRemoveNonExistingContainer() throws Exception {
|
|
||||||
MockWebServer server = mockWebServer();
|
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
String containerId = "nonExisting";
|
|
||||||
try {
|
|
||||||
api.removeContainer(containerId);
|
|
||||||
fail("Remove container must fail on 404");
|
|
||||||
} catch (ResourceNotFoundException ex) {
|
|
||||||
// Expected exception
|
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStartContainer() throws Exception {
|
public void testStartContainer() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
|
||||||
server.enqueue(new MockResponse().setResponseCode(200));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
try {
|
try {
|
||||||
api.startContainer("1");
|
api.startContainer("1");
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "POST", "/containers/1/start");
|
assertSent(server, "POST", "/containers/1/start");
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testStartNonExistingContainer() throws Exception {
|
|
||||||
MockWebServer server = mockWebServer();
|
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
api.startContainer("1");
|
|
||||||
fail("Start container must fail on 404");
|
|
||||||
} catch (ResourceNotFoundException ex) {
|
|
||||||
// Expected exception
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStopContainer() throws Exception {
|
public void testStopContainer() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
|
||||||
server.enqueue(new MockResponse().setResponseCode(200));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
try {
|
try {
|
||||||
api.stopContainer("1");
|
api.stopContainer("1");
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "POST", "/containers/1/stop");
|
assertSent(server, "POST", "/containers/1/stop");
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStopNonExistingContainer() throws Exception {
|
|
||||||
MockWebServer server = mockWebServer();
|
public void testCommitContainer() throws Exception {
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(201));
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
ContainerApi api = dockerApi.getContainerApi();
|
|
||||||
try {
|
try {
|
||||||
api.stopContainer("1");
|
api.commit();
|
||||||
fail("Stop container must fail on 404");
|
assertSent(server, "POST", "/commit");
|
||||||
} catch (ResourceNotFoundException ex) {
|
} finally {
|
||||||
// Expected exception
|
server.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPauseContainer() throws Exception {
|
||||||
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(204));
|
||||||
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
|
try {
|
||||||
|
api.pause("1");
|
||||||
|
assertSent(server, "POST", "/containers/1/pause");
|
||||||
|
} finally {
|
||||||
|
server.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUnpauseContainer() throws Exception {
|
||||||
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(204));
|
||||||
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
|
try {
|
||||||
|
api.unpause("1");
|
||||||
|
assertSent(server, "POST", "/containers/1/unpause");
|
||||||
|
} finally {
|
||||||
|
server.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAttachContainer() throws Exception {
|
||||||
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
|
||||||
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
|
try {
|
||||||
|
api.attach("1");
|
||||||
|
assertSent(server, "POST", "/containers/1/attach");
|
||||||
|
} finally {
|
||||||
|
server.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWaitContainer() throws Exception {
|
||||||
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
|
||||||
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
|
try {
|
||||||
|
api.wait("1");
|
||||||
|
assertSent(server, "POST", "/containers/1/wait");
|
||||||
|
} finally {
|
||||||
|
server.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRestartContainer() throws Exception {
|
||||||
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(204));
|
||||||
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
|
try {
|
||||||
|
api.restart("1");
|
||||||
|
assertSent(server, "POST", "/containers/1/restart");
|
||||||
|
} finally {
|
||||||
|
server.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testKillContainer() throws Exception {
|
||||||
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(204));
|
||||||
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
|
try {
|
||||||
|
api.kill("1");
|
||||||
|
assertSent(server, "POST", "/containers/1/kill");
|
||||||
|
} finally {
|
||||||
|
server.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCopyFileFromContainer() throws Exception {
|
||||||
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(204));
|
||||||
|
ContainerApi api = api(DockerApi.class, server.getUrl("/").toString()).getContainerApi();
|
||||||
|
try {
|
||||||
|
api.copy("1", Resource.create("test"));
|
||||||
|
assertSent(server, "POST", "/containers/1/copy");
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,16 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.docker.features;
|
package org.jclouds.docker.features;
|
||||||
|
|
||||||
import static org.testng.Assert.fail;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import org.jclouds.docker.DockerApi;
|
import org.jclouds.docker.DockerApi;
|
||||||
|
import org.jclouds.docker.config.DockerParserModule;
|
||||||
import org.jclouds.docker.internal.BaseDockerMockTest;
|
import org.jclouds.docker.internal.BaseDockerMockTest;
|
||||||
import org.jclouds.docker.options.CreateImageOptions;
|
import org.jclouds.docker.options.CreateImageOptions;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.docker.parse.ImageParseTest;
|
||||||
|
import org.jclouds.docker.parse.ImagesParseTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
|
||||||
import com.squareup.okhttp.mockwebserver.MockResponse;
|
import com.squareup.okhttp.mockwebserver.MockResponse;
|
||||||
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
||||||
|
|
||||||
|
@ -35,61 +36,47 @@ import com.squareup.okhttp.mockwebserver.MockWebServer;
|
||||||
public class ImageApiMockTest extends BaseDockerMockTest {
|
public class ImageApiMockTest extends BaseDockerMockTest {
|
||||||
|
|
||||||
public void testCreateImage() throws Exception {
|
public void testCreateImage() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
|
||||||
server.enqueue(new MockResponse().setResponseCode(200));
|
ImageApi api = api(DockerApi.class, server.getUrl("/").toString()).getImageApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ImageApi api = dockerApi.getImageApi();
|
|
||||||
try {
|
try {
|
||||||
api.createImage(CreateImageOptions.Builder.fromImage("base"));
|
api.createImage(CreateImageOptions.Builder.fromImage("base"));
|
||||||
assertRequestHasParameters(server.takeRequest(), "POST", "/images/create", ImmutableMultimap.of("fromImage", "base"));
|
assertSent(server, "POST", "/images/create?fromImage=base");
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateImageFailure() throws Exception {
|
public void testGetImage() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/image.json")));
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
ImageApi api = api(DockerApi.class, server.getUrl("/").toString(), new DockerParserModule()).getImageApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ImageApi api = dockerApi.getImageApi();
|
|
||||||
try {
|
try {
|
||||||
api.createImage(CreateImageOptions.Builder.fromImage("base"));
|
String imageId = "cbba6639a342646deed70d7ea6162fa2a0acea9300f911f4e014555fe37d3456";
|
||||||
fail("Create image must fail on 404");
|
assertEquals(api.inspectImage(imageId), new ImageParseTest().expected());
|
||||||
} catch (ResourceNotFoundException ex) {
|
assertSent(server, "GET", "/images/" + imageId + "/json");
|
||||||
// Expected exception
|
} finally {
|
||||||
|
server.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListImages() throws Exception {
|
||||||
|
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/images.json")));
|
||||||
|
ImageApi api = api(DockerApi.class, server.getUrl("/").toString()).getImageApi();
|
||||||
|
try {
|
||||||
|
assertEquals(api.listImages(), new ImagesParseTest().expected());
|
||||||
|
assertSent(server, "GET", "/images/json");
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteImage() throws Exception {
|
public void testDeleteImage() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(204));
|
||||||
server.enqueue(new MockResponse().setResponseCode(204));
|
ImageApi api = api(DockerApi.class, server.getUrl("/").toString()).getImageApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ImageApi api = dockerApi.getImageApi();
|
|
||||||
try {
|
try {
|
||||||
api.deleteImage("1");
|
api.deleteImage("1");
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "DELETE", "/images/1");
|
assertSent(server, "DELETE", "/images/1");
|
||||||
} finally {
|
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDeleteNotExistingImage() throws Exception {
|
|
||||||
MockWebServer server = mockWebServer();
|
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
ImageApi api = dockerApi.getImageApi();
|
|
||||||
try {
|
|
||||||
api.deleteImage("1");
|
|
||||||
fail("Delete image must fail on 404");
|
|
||||||
} catch (ResourceNotFoundException ex) {
|
|
||||||
// Expected exception
|
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.jclouds.docker.features;
|
||||||
|
|
||||||
import org.jclouds.docker.compute.BaseDockerApiLiveTest;
|
import org.jclouds.docker.compute.BaseDockerApiLiveTest;
|
||||||
import org.jclouds.docker.options.BuildOptions;
|
import org.jclouds.docker.options.BuildOptions;
|
||||||
import org.testng.annotations.AfterClass;
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
@ -34,10 +33,10 @@ import com.google.common.collect.Iterables;
|
||||||
public class MiscApiLiveTest extends BaseDockerApiLiveTest {
|
public class MiscApiLiveTest extends BaseDockerApiLiveTest {
|
||||||
|
|
||||||
private static final String API_VERSION = "1.15";
|
private static final String API_VERSION = "1.15";
|
||||||
private static final String VERSION = "1.3.0";
|
private static final String VERSION = "1.3.2";
|
||||||
private static final String GIT_COMMIT = "c78088f";
|
private static final String GIT_COMMIT = "39fa2fa";
|
||||||
private static final String GO_VERSION = "go1.3.3";
|
private static final String GO_VERSION = "go1.3.3";
|
||||||
private static final String KERNEL_VERSION = "3.16.4-tinycore64";
|
private static final String KERNEL_VERSION = "3.16.7-tinycore64";
|
||||||
private static final String ARCH = "amd64";
|
private static final String ARCH = "amd64";
|
||||||
private static final String OS = "linux";
|
private static final String OS = "linux";
|
||||||
|
|
||||||
|
@ -71,13 +70,6 @@ public class MiscApiLiveTest extends BaseDockerApiLiveTest {
|
||||||
assertNotNull(imageId);
|
assertNotNull(imageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
protected void tearDown() {
|
|
||||||
if (imageId != null) {
|
|
||||||
consumeStream(api.getImageApi().deleteImage(imageId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MiscApi api() {
|
private MiscApi api() {
|
||||||
return api.getMiscApi();
|
return api.getMiscApi();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,19 +19,15 @@ package org.jclouds.docker.features;
|
||||||
import com.squareup.okhttp.mockwebserver.MockResponse;
|
import com.squareup.okhttp.mockwebserver.MockResponse;
|
||||||
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
||||||
import org.jclouds.docker.DockerApi;
|
import org.jclouds.docker.DockerApi;
|
||||||
import org.jclouds.docker.domain.Info;
|
|
||||||
import org.jclouds.docker.domain.Version;
|
|
||||||
import org.jclouds.docker.internal.BaseDockerMockTest;
|
import org.jclouds.docker.internal.BaseDockerMockTest;
|
||||||
import org.jclouds.docker.options.BuildOptions;
|
import org.jclouds.docker.parse.InfoParseTest;
|
||||||
|
import org.jclouds.docker.parse.VersionParseTest;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
import org.jclouds.io.Payloads;
|
import org.jclouds.io.Payloads;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import static org.jclouds.docker.compute.BaseDockerApiLiveTest.tarredDockerfile;
|
import static org.jclouds.docker.compute.BaseDockerApiLiveTest.tarredDockerfile;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.Assert.fail;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
|
@ -41,117 +37,50 @@ import java.io.FileInputStream;
|
||||||
@Test(groups = "unit", testName = "MiscApiMockTest")
|
@Test(groups = "unit", testName = "MiscApiMockTest")
|
||||||
public class MiscApiMockTest extends BaseDockerMockTest {
|
public class MiscApiMockTest extends BaseDockerMockTest {
|
||||||
|
|
||||||
private static final String API_VERSION = "1.15";
|
|
||||||
private static final String VERSION = "1.3.0";
|
|
||||||
private static final String GIT_COMMIT = "c78088f";
|
|
||||||
private static final String GO_VERSION = "go1.3.3";
|
|
||||||
private static final String KERNEL_VERSION = "3.16.4-tinycore64";
|
|
||||||
private static final String ARCH = "amd64";
|
|
||||||
private static final String OS = "linux";
|
|
||||||
|
|
||||||
public void testGetVersion() throws Exception {
|
public void testGetVersion() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/version.json")));
|
||||||
server.enqueue(new MockResponse().setBody(payloadFromResource("/version.json")));
|
MiscApi api = api(DockerApi.class, server.getUrl("/").toString()).getMiscApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
MiscApi api = dockerApi.getMiscApi();
|
|
||||||
try {
|
try {
|
||||||
Version version = api.getVersion();
|
assertEquals(api.getVersion(), new VersionParseTest().expected());
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "/version");
|
assertSent(server, "GET", "/version");
|
||||||
assertNotNull(version);
|
|
||||||
assertEquals(version.version(), VERSION);
|
|
||||||
assertEquals(version.gitCommit(), GIT_COMMIT);
|
|
||||||
assertEquals(version.apiVersion(), API_VERSION);
|
|
||||||
assertEquals(version.goVersion(), GO_VERSION);
|
|
||||||
assertEquals(version.kernelVersion(), KERNEL_VERSION);
|
|
||||||
assertEquals(version.arch(), ARCH);
|
|
||||||
assertEquals(version.os(), OS);
|
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetInfo() throws Exception {
|
public void testGetInfo() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setBody(payloadFromResource("/info.json")));
|
||||||
server.enqueue(new MockResponse().setBody(payloadFromResource("/info.json")));
|
MiscApi api = api(DockerApi.class, server.getUrl("/").toString()).getMiscApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
MiscApi api = dockerApi.getMiscApi();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Info info = api.getInfo();
|
assertEquals(api.getInfo(), new InfoParseTest().expected());
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "/info");
|
assertSent(server, "GET", "/info");
|
||||||
assertNotNull(info);
|
|
||||||
assertNotNull(info.containers());
|
|
||||||
assertNotNull(info.debug());
|
|
||||||
assertNotNull(info.driver());
|
|
||||||
assertNotNull(info.executionDriver());
|
|
||||||
assertNotNull(info.images());
|
|
||||||
assertNotNull(info.indexServerAddress());
|
|
||||||
assertNotNull(info.initPath());
|
|
||||||
assertNotNull(info.iPv4Forwarding());
|
|
||||||
assertNotNull(info.kernelVersion());
|
|
||||||
assertNotNull(info.memoryLimit());
|
|
||||||
assertNotNull(info.nEventsListener());
|
|
||||||
assertNotNull(info.nFd());
|
|
||||||
assertNotNull(info.nGoroutines());
|
|
||||||
assertNotNull(info.swapLimit());
|
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBuildContainer() throws Exception {
|
public void testBuildContainer() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
|
||||||
server.enqueue(new MockResponse().setResponseCode(200));
|
MiscApi api = api(DockerApi.class, server.getUrl("/").toString()).getMiscApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
MiscApi api = dockerApi.getMiscApi();
|
|
||||||
File dockerFile = File.createTempFile("docker", "tmp");
|
|
||||||
try {
|
try {
|
||||||
api.build(tarredDockerfile(), BuildOptions.NONE);
|
api.build(tarredDockerfile());
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "POST", "/build");
|
assertSent(server, "POST", "/build");
|
||||||
} finally {
|
} finally {
|
||||||
dockerFile.delete();
|
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBuildContainerUsingPayload() throws Exception {
|
public void testBuildContainerUsingPayload() throws Exception {
|
||||||
MockWebServer server = mockWebServer();
|
MockWebServer server = mockWebServer(new MockResponse().setResponseCode(200));
|
||||||
server.enqueue(new MockResponse().setResponseCode(200));
|
MiscApi api = api(DockerApi.class, server.getUrl("/").toString()).getMiscApi();
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
MiscApi api = dockerApi.getMiscApi();
|
|
||||||
File file = File.createTempFile("docker", "tmp");
|
File file = File.createTempFile("docker", "tmp");
|
||||||
FileInputStream data = new FileInputStream(file);
|
FileInputStream data = new FileInputStream(file);
|
||||||
Payload payload = Payloads.newInputStreamPayload(data);
|
Payload payload = Payloads.newInputStreamPayload(data);
|
||||||
payload.getContentMetadata().setContentLength(file.length());
|
payload.getContentMetadata().setContentLength(file.length());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
api.build(payload, BuildOptions.NONE);
|
api.build(payload);
|
||||||
assertRequestHasCommonFields(server.takeRequest(), "POST", "/build");
|
assertSent(server, "POST", "/build");
|
||||||
} finally {
|
} finally {
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testBuildNonexistentContainer() throws Exception {
|
|
||||||
MockWebServer server = mockWebServer();
|
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
|
||||||
DockerApi dockerApi = api(server.getUrl("/"));
|
|
||||||
MiscApi api = dockerApi.getMiscApi();
|
|
||||||
File dockerFile = File.createTempFile("docker", "tmp");
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
api.build(tarredDockerfile(), BuildOptions.NONE);
|
|
||||||
fail("Build container must fail on 404");
|
|
||||||
} catch (ResourceNotFoundException ex) {
|
|
||||||
// Expected exception
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
dockerFile.delete();
|
|
||||||
dockerApi.close();
|
|
||||||
server.shutdown();
|
server.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,27 +16,19 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.docker.internal;
|
package org.jclouds.docker.internal;
|
||||||
|
|
||||||
import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.jclouds.http.utils.Queries.encodeQueryLine;
|
|
||||||
import static org.jclouds.util.Strings2.toStringAndClose;
|
import static org.jclouds.util.Strings2.toStringAndClose;
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.ContextBuilder;
|
import org.jclouds.http.BaseMockWebServerTest;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.http.okhttp.config.OkHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.docker.DockerApi;
|
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
||||||
import com.squareup.okhttp.mockwebserver.RecordedRequest;
|
import com.squareup.okhttp.mockwebserver.RecordedRequest;
|
||||||
|
@ -44,33 +36,18 @@ import com.squareup.okhttp.mockwebserver.RecordedRequest;
|
||||||
/**
|
/**
|
||||||
* Base class for all Docker mock tests.
|
* Base class for all Docker mock tests.
|
||||||
*/
|
*/
|
||||||
public class BaseDockerMockTest {
|
public class BaseDockerMockTest extends BaseMockWebServerTest {
|
||||||
private final Set<Module> modules = ImmutableSet.<Module> of(new ExecutorServiceModule(sameThreadExecutor(),
|
|
||||||
sameThreadExecutor()));
|
|
||||||
|
|
||||||
protected String provider;
|
protected static final String API_VERSION = "1.15";
|
||||||
|
|
||||||
public BaseDockerMockTest() {
|
@Override
|
||||||
provider = "docker";
|
protected void addOverrideProperties(Properties properties) {
|
||||||
|
properties.setProperty("jclouds.api-version", API_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DockerApi api(URL url) {
|
@Override
|
||||||
return ContextBuilder.newBuilder(provider)
|
protected Module createConnectionModule() {
|
||||||
.credentials("clientid", "apikey")
|
return new OkHttpCommandExecutorServiceModule();
|
||||||
.endpoint(url.toString())
|
|
||||||
.modules(modules)
|
|
||||||
.overrides(setupProperties())
|
|
||||||
.buildApi(DockerApi.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Properties setupProperties() {
|
|
||||||
return new Properties();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MockWebServer mockWebServer() throws IOException {
|
|
||||||
MockWebServer server = new MockWebServer();
|
|
||||||
server.play();
|
|
||||||
return server;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] payloadFromResource(String resource) {
|
public byte[] payloadFromResource(String resource) {
|
||||||
|
@ -81,38 +58,12 @@ public class BaseDockerMockTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void assertRequestHasCommonFields(final RecordedRequest request, final String path)
|
protected RecordedRequest assertSent(MockWebServer server, String method, String path) throws InterruptedException {
|
||||||
throws InterruptedException {
|
RecordedRequest request = server.takeRequest();
|
||||||
assertRequestHasParameters(request, "GET", path, ImmutableMultimap.<String, String> of());
|
assertThat(request.getMethod()).isEqualTo(method);
|
||||||
}
|
assertThat(request.getPath()).isEqualTo("/v" + API_VERSION + path);
|
||||||
|
assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON);
|
||||||
protected static void assertRequestHasCommonFields(final RecordedRequest request,
|
return request;
|
||||||
final String verb, final String path)
|
|
||||||
throws InterruptedException {
|
|
||||||
assertRequestHasParameters(request, verb, path, ImmutableMultimap.<String, String> of());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void assertRequestHasParameters(final RecordedRequest request, final String path,
|
|
||||||
Multimap<String, String> parameters) throws InterruptedException {
|
|
||||||
assertRequestHasParameters(request, "GET", path, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void assertRequestHasParameters(final RecordedRequest request, String verb, final String path,
|
|
||||||
Multimap<String, String> parameters) throws InterruptedException {
|
|
||||||
String queryParameters = "";
|
|
||||||
if (!parameters.isEmpty()) {
|
|
||||||
Multimap<String, String> allparams = ImmutableMultimap.<String, String>builder()
|
|
||||||
.putAll(parameters)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertRequestHasAcceptHeader(request);
|
|
||||||
queryParameters = "?" + encodeQueryLine(allparams);
|
|
||||||
}
|
|
||||||
assertEquals(request.getRequestLine(), verb + " " + path + queryParameters + " HTTP/1.1");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void assertRequestHasAcceptHeader(final RecordedRequest request) throws InterruptedException {
|
|
||||||
assertEquals(request.getHeader(HttpHeaders.ACCEPT), MediaType.APPLICATION_JSON);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import org.jclouds.docker.config.DockerParserModule;
|
||||||
|
import org.jclouds.json.BaseItemParserTest;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
public abstract class BaseDockerParseTest<T> extends BaseItemParserTest<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Injector injector() {
|
||||||
|
return Guice.createInjector(new GsonModule(), new DockerParserModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* 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.parse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.docker.domain.Config;
|
||||||
|
import org.jclouds.docker.domain.Container;
|
||||||
|
import org.jclouds.docker.domain.HostConfig;
|
||||||
|
import org.jclouds.docker.domain.NetworkSettings;
|
||||||
|
import org.jclouds.docker.domain.State;
|
||||||
|
import org.jclouds.docker.internal.BaseDockerParseTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ContainerParseTest extends BaseDockerParseTest<Container> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/container.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Container expected() {
|
||||||
|
return Container.builder()
|
||||||
|
.id("6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524")
|
||||||
|
.created(new SimpleDateFormatDateService().iso8601DateParse("2014-10-31T17:00:21.544197943Z"))
|
||||||
|
.path("/home/weave/weaver")
|
||||||
|
.name("/weave")
|
||||||
|
.args(ImmutableList.of("-iface", "ethwe", "-wait", "5", "-name", "7a:63:a2:39:7b:0f"))
|
||||||
|
.config(Config.builder()
|
||||||
|
.hostname("6c9932f478bd")
|
||||||
|
.env(ImmutableList.of("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"))
|
||||||
|
.image("57e570db16baba1e8c0d6f3c15868ddb400f64ff76ec948e65c3ca3f15fb3587")
|
||||||
|
.domainname("")
|
||||||
|
.user("")
|
||||||
|
.cmd(ImmutableList.of("-name", "7a:63:a2:39:7b:0f"))
|
||||||
|
.entrypoint(ImmutableList.of("/home/weave/weaver", "-iface", "ethwe", "-wait", "5"))
|
||||||
|
.image("zettio/weave")
|
||||||
|
.workingDir("/home/weave")
|
||||||
|
.exposedPorts(ImmutableMap.of("6783/tcp", ImmutableMap.of(), "6783/udp", ImmutableMap.of()))
|
||||||
|
.build())
|
||||||
|
.state(State.create(3939, true, 0, "2014-10-31T17:00:21.802008706Z", "0001-01-01T00:00:00Z", false, false))
|
||||||
|
.image("57e570db16baba1e8c0d6f3c15868ddb400f64ff76ec948e65c3ca3f15fb3587")
|
||||||
|
.networkSettings(NetworkSettings.builder()
|
||||||
|
.ipAddress("172.17.0.7")
|
||||||
|
.ipPrefixLen(16)
|
||||||
|
.gateway("172.17.42.1")
|
||||||
|
.bridge("docker0")
|
||||||
|
.ports(ImmutableMap.<String, List<Map<String, String>>>of(
|
||||||
|
"6783/tcp", ImmutableList.<Map<String, String>>of(ImmutableMap.of("HostIp", "0.0.0.0", "HostPort", "6783")),
|
||||||
|
"6783/udp", ImmutableList.<Map<String, String>>of(ImmutableMap.of("HostIp", "0.0.0.0", "HostPort", "6783")))
|
||||||
|
)
|
||||||
|
.build())
|
||||||
|
.resolvConfPath("/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/resolv.conf")
|
||||||
|
.hostConfig(HostConfig.builder()
|
||||||
|
.containerIDFile("")
|
||||||
|
.portBindings(ImmutableMap.<String, List<Map<String, String>>>of(
|
||||||
|
"6783/tcp", ImmutableList.<Map<String, String>>of(ImmutableMap.of("HostIp", "", "HostPort", "6783")),
|
||||||
|
"6783/udp", ImmutableList.<Map<String, String>>of(ImmutableMap.of("HostIp", "", "HostPort", "6783")))
|
||||||
|
)
|
||||||
|
.privileged(true)
|
||||||
|
.build())
|
||||||
|
.driver("aufs")
|
||||||
|
.execDriver("native-0.2")
|
||||||
|
.hostnamePath("/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/hostname")
|
||||||
|
.hostsPath("/var/lib/docker/containers/6c9932f478bd761f32ddb54ed28ab42ab6fac6f2a279f561ea31503ee9d39524/hosts")
|
||||||
|
.mountLabel("")
|
||||||
|
.processLabel("")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.parse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.docker.domain.ContainerSummary;
|
||||||
|
import org.jclouds.docker.domain.Port;
|
||||||
|
import org.jclouds.docker.internal.BaseDockerParseTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ContainersParseTest extends BaseDockerParseTest<List<ContainerSummary>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/containers.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public List<ContainerSummary> expected() {
|
||||||
|
return ImmutableList.of(
|
||||||
|
ContainerSummary.create("6d35806c1bd2b25cd92bba2d2c2c5169dc2156f53ab45c2b62d76e2d2fee14a9",
|
||||||
|
ImmutableList.of("/hopeful_mclean"),
|
||||||
|
"1395472605",
|
||||||
|
"jclouds/ubuntu:latest",
|
||||||
|
"/usr/sbin/sshd -D",
|
||||||
|
ImmutableList.of(Port.create("0.0.0.0", 22, 49231, "tcp")),
|
||||||
|
"Up 55 seconds")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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.parse;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.docker.domain.Config;
|
||||||
|
import org.jclouds.docker.domain.Image;
|
||||||
|
import org.jclouds.docker.internal.BaseDockerParseTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.beust.jcommander.internal.Maps;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ImageParseTest extends BaseDockerParseTest<Image> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/image.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Image expected() {
|
||||||
|
return Image.create("cbba6639a342646deed70d7ea6162fa2a0acea9300f911f4e014555fe37d3456",
|
||||||
|
"author",
|
||||||
|
"comment",
|
||||||
|
Config.builder().cmd(ImmutableList.of("/bin/sh", "-c", "echo hello world"))
|
||||||
|
.env(ImmutableList.of(
|
||||||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
"HOME=/root",
|
||||||
|
"JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.exposedPorts(ImmutableMap.of("8081/tcp", Maps.newHashMap()))
|
||||||
|
.hostname("f22711318734")
|
||||||
|
.domainname("")
|
||||||
|
.user("user")
|
||||||
|
.image("05794515afd5724df1cdf0e674ae932455fce7dea3c70a94d77119ad1fa954ba")
|
||||||
|
.workingDir("/home/user")
|
||||||
|
.build(),
|
||||||
|
Config.builder().cmd(ImmutableList.of("/bin/sh", "-c", "echo hello world"))
|
||||||
|
.env(ImmutableList.of(
|
||||||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
"HOME=/root",
|
||||||
|
"JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64")
|
||||||
|
)
|
||||||
|
.exposedPorts(ImmutableMap.of("8081/tcp", Maps.newHashMap()))
|
||||||
|
.hostname("f22711318734")
|
||||||
|
.domainname("")
|
||||||
|
.user("user")
|
||||||
|
.image("05794515afd5724df1cdf0e674ae932455fce7dea3c70a94d77119ad1fa954ba")
|
||||||
|
.workingDir("/home/user")
|
||||||
|
.build(),
|
||||||
|
"05794515afd5724df1cdf0e674ae932455fce7dea3c70a94d77119ad1fa954ba",
|
||||||
|
new SimpleDateFormatDateService().iso8601DateParse("2014-11-24T11:09:20.310023104Z"),
|
||||||
|
"0d14967353dbbd2ee78abe209f026f71654da49692fa2b044296ec3c810027b3",
|
||||||
|
"1.3.1",
|
||||||
|
"amd64",
|
||||||
|
"linux",
|
||||||
|
0,
|
||||||
|
808709069,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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.parse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.docker.domain.ImageSummary;
|
||||||
|
import org.jclouds.docker.internal.BaseDockerParseTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ImagesParseTest extends BaseDockerParseTest<List<ImageSummary>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/images.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public List<ImageSummary> expected() {
|
||||||
|
return ImmutableList.of(
|
||||||
|
ImageSummary.create("cbba6639a342646deed70d7ea6162fa2a0acea9300f911f4e014555fe37d3456",
|
||||||
|
1416827360,
|
||||||
|
"05794515afd5724df1cdf0e674ae932455fce7dea3c70a94d77119ad1fa954ba",
|
||||||
|
0,
|
||||||
|
808709069,
|
||||||
|
ImmutableList.of("test:latest")),
|
||||||
|
ImageSummary.create("e1e548b03259ae30ba12232b6c16ef5205cf71b0363848e78b0394e1ecba4f57",
|
||||||
|
1416826851,
|
||||||
|
"6f36bec79c7f184ceebf7000cfb7244c4bc9b397b6659ac7f420a53d114250d9",
|
||||||
|
0,
|
||||||
|
5609404,
|
||||||
|
ImmutableList.of("<none>:<none>")),
|
||||||
|
ImageSummary.create("8201388d2b288539aab6aabf5d3b15ec269eba95c6baa9d6771f16540abf3a3f",
|
||||||
|
1414247273,
|
||||||
|
"4671e2c549c5b60063e349f520c801dc73b53d2226a5a8e5501845ebe94761ca",
|
||||||
|
0,
|
||||||
|
755313702,
|
||||||
|
ImmutableList.of("dockerfile/java:openjdk-7-jdk")),
|
||||||
|
ImageSummary.create("5506de2b643be1e6febbf3b8a240760c6843244c41e12aa2f60ccbb7153d17f5",
|
||||||
|
1414108439,
|
||||||
|
"22093c35d77bb609b9257ffb2640845ec05018e3d96cb939f68d0e19127f1723",
|
||||||
|
0,
|
||||||
|
199257566,
|
||||||
|
ImmutableList.of("ubuntu:14.04"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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.parse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.docker.domain.Info;
|
||||||
|
import org.jclouds.docker.internal.BaseDockerParseTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class InfoParseTest extends BaseDockerParseTest<Info> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/info.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Info expected() {
|
||||||
|
return Info.create(0,
|
||||||
|
1,
|
||||||
|
"aufs",
|
||||||
|
ImmutableList.<List<String>>of(
|
||||||
|
ImmutableList.of("Root Dir", "/mnt/sda1/var/lib/docker/aufs"),
|
||||||
|
ImmutableList.of("Dirs", "15")
|
||||||
|
),
|
||||||
|
"native-0.2",
|
||||||
|
1,
|
||||||
|
15,
|
||||||
|
"https://index.docker.io/v1/",
|
||||||
|
"/usr/local/bin/docker",
|
||||||
|
"",
|
||||||
|
"3.16.4-tinycore64",
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
"Boot2Docker 1.3.0 (TCL 5.4); master : a083df4 - Thu Oct 16 17:05:03 UTC 2014",
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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.parse;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.docker.domain.Version;
|
||||||
|
import org.jclouds.docker.internal.BaseDockerParseTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class VersionParseTest extends BaseDockerParseTest<Version> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/version.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Version expected() {
|
||||||
|
return Version.create(
|
||||||
|
"1.15",
|
||||||
|
"amd64",
|
||||||
|
"c78088f",
|
||||||
|
"go1.3.3",
|
||||||
|
"3.16.4-tinycore64",
|
||||||
|
"linux",
|
||||||
|
"1.3.0");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDtTCCAp2gAwIBAgIJAL/TuOknjSR5MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
||||||
|
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
|
||||||
|
aWRnaXRzIFB0eSBMdGQwHhcNMTQxMjEyMTYwMDEyWhcNMjQxMjA5MTYwMDEyWjBF
|
||||||
|
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
|
||||||
|
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||||
|
CgKCAQEAuUQcWlhrMXmzLSLiHUADdF98IHKRde7I1eDT91NndOtx4pKfvVc3WPei
|
||||||
|
REIMksrU8F1r4A086h5++xxDf27LxR4EC9ry0Q6GgJ9Un9RB9clCWRhLw8awHAS7
|
||||||
|
HgAEN8YOSCeF3qP+78muxyMkIKQbYn3TqqOzRZcK576hX+a6URNJDhbHHAzq2fxm
|
||||||
|
rOSRVdPXzKLl48ABfmqJ6+KiXc6e7mQSgmwBLfh51zxmJNNwZ5e+6sfZ8oz4yM4y
|
||||||
|
Kzek53GRSFj+VFNp5nS/x2072fUak2i6DGut5LibFfh1kqskIm+Iq5WwO15RbojZ
|
||||||
|
CR6fkktCl5QOtea5p8SETZpwWfaddQIDAQABo4GnMIGkMB0GA1UdDgQWBBQtOc1g
|
||||||
|
1gxisDQ7VTmRYI1U9WHVMDB1BgNVHSMEbjBsgBQtOc1g1gxisDQ7VTmRYI1U9WHV
|
||||||
|
MKFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
|
||||||
|
BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAL/TuOknjSR5MAwGA1UdEwQF
|
||||||
|
MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABxYn5JdJYC8FUITqymJeNZ72/a2GVf8
|
||||||
|
+gGlWH+DuiyviEAGMGpv7O4GXfS/6UiUBO7zMe2z15fUvNgd5RQBh4T+l5bA9aS0
|
||||||
|
5JhENIpEApiIcEII4ISIk6pTLmAZjWvqq2kStiiFPNvdKFclYqFuKHv847EA8kGz
|
||||||
|
9u6MuUyFrJipWZ3g8zeYiwLWaAzvimbHomO7HU4pcvYaCSl7O5BQTToKwLfHcx5y
|
||||||
|
UG6uRf+0auC5QbotiXpYNdXhIbSD/2xXbjxGwYy4yRWHINcbwfK8iVRhR4eSvtBC
|
||||||
|
WvF3Vp8xLJxp6ujBd+a27AOWEiE1XM8oAoUpEzdIINY1GtUSbXzNboc=
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"Architecture": "amd64",
|
||||||
|
"Author": "author",
|
||||||
|
"Comment": "comment",
|
||||||
|
"Config": {
|
||||||
|
"AttachStderr": false,
|
||||||
|
"AttachStdin": false,
|
||||||
|
"AttachStdout": false,
|
||||||
|
"Cmd": [
|
||||||
|
"/bin/sh",
|
||||||
|
"-c",
|
||||||
|
"echo hello world"
|
||||||
|
],
|
||||||
|
"CpuShares": 0,
|
||||||
|
"Cpuset": "",
|
||||||
|
"Domainname": "",
|
||||||
|
"Entrypoint": null,
|
||||||
|
"Env": [
|
||||||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
"HOME=/root",
|
||||||
|
"JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64"
|
||||||
|
],
|
||||||
|
"ExposedPorts": {
|
||||||
|
"8081/tcp": {}
|
||||||
|
},
|
||||||
|
"Hostname": "f22711318734",
|
||||||
|
"Image": "05794515afd5724df1cdf0e674ae932455fce7dea3c70a94d77119ad1fa954ba",
|
||||||
|
"Memory": 0,
|
||||||
|
"MemorySwap": 0,
|
||||||
|
"NetworkDisabled": false,
|
||||||
|
"OnBuild": [],
|
||||||
|
"OpenStdin": false,
|
||||||
|
"PortSpecs": null,
|
||||||
|
"StdinOnce": false,
|
||||||
|
"Tty": false,
|
||||||
|
"User": "user",
|
||||||
|
"Volumes": null,
|
||||||
|
"WorkingDir": "/home/user"
|
||||||
|
},
|
||||||
|
"Container": "0d14967353dbbd2ee78abe209f026f71654da49692fa2b044296ec3c810027b3",
|
||||||
|
"ContainerConfig": {
|
||||||
|
"AttachStderr": false,
|
||||||
|
"AttachStdin": false,
|
||||||
|
"AttachStdout": false,
|
||||||
|
"Cmd": [
|
||||||
|
"/bin/sh",
|
||||||
|
"-c",
|
||||||
|
"echo hello world"
|
||||||
|
],
|
||||||
|
"CpuShares": 0,
|
||||||
|
"Cpuset": "",
|
||||||
|
"Domainname": "",
|
||||||
|
"Entrypoint": null,
|
||||||
|
"Env": [
|
||||||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
"HOME=/root",
|
||||||
|
"JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64"
|
||||||
|
],
|
||||||
|
"ExposedPorts": {
|
||||||
|
"8081/tcp": {}
|
||||||
|
},
|
||||||
|
"Hostname": "f22711318734",
|
||||||
|
"Image": "05794515afd5724df1cdf0e674ae932455fce7dea3c70a94d77119ad1fa954ba",
|
||||||
|
"Memory": 0,
|
||||||
|
"MemorySwap": 0,
|
||||||
|
"NetworkDisabled": false,
|
||||||
|
"OnBuild": [],
|
||||||
|
"OpenStdin": false,
|
||||||
|
"PortSpecs": null,
|
||||||
|
"StdinOnce": false,
|
||||||
|
"Tty": false,
|
||||||
|
"User": "user",
|
||||||
|
"Volumes": null,
|
||||||
|
"WorkingDir": "/home/user"
|
||||||
|
},
|
||||||
|
"Created": "2014-11-24T11:09:20.310023104Z",
|
||||||
|
"DockerVersion": "1.3.1",
|
||||||
|
"Id": "cbba6639a342646deed70d7ea6162fa2a0acea9300f911f4e014555fe37d3456",
|
||||||
|
"Os": "linux",
|
||||||
|
"Parent": "05794515afd5724df1cdf0e674ae932455fce7dea3c70a94d77119ad1fa954ba",
|
||||||
|
"Size": 0,
|
||||||
|
"VirtualSize": 808709069
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"Created": 1416827360,
|
||||||
|
"Id": "cbba6639a342646deed70d7ea6162fa2a0acea9300f911f4e014555fe37d3456",
|
||||||
|
"ParentId": "05794515afd5724df1cdf0e674ae932455fce7dea3c70a94d77119ad1fa954ba",
|
||||||
|
"RepoTags": [
|
||||||
|
"test:latest"
|
||||||
|
],
|
||||||
|
"Size": 0,
|
||||||
|
"VirtualSize": 808709069
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Created": 1416826851,
|
||||||
|
"Id": "e1e548b03259ae30ba12232b6c16ef5205cf71b0363848e78b0394e1ecba4f57",
|
||||||
|
"ParentId": "6f36bec79c7f184ceebf7000cfb7244c4bc9b397b6659ac7f420a53d114250d9",
|
||||||
|
"RepoTags": [
|
||||||
|
"<none>:<none>"
|
||||||
|
],
|
||||||
|
"Size": 0,
|
||||||
|
"VirtualSize": 5609404
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Created": 1414247273,
|
||||||
|
"Id": "8201388d2b288539aab6aabf5d3b15ec269eba95c6baa9d6771f16540abf3a3f",
|
||||||
|
"ParentId": "4671e2c549c5b60063e349f520c801dc73b53d2226a5a8e5501845ebe94761ca",
|
||||||
|
"RepoTags": [
|
||||||
|
"dockerfile/java:openjdk-7-jdk"
|
||||||
|
],
|
||||||
|
"Size": 0,
|
||||||
|
"VirtualSize": 755313702
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Created": 1414108439,
|
||||||
|
"Id": "5506de2b643be1e6febbf3b8a240760c6843244c41e12aa2f60ccbb7153d17f5",
|
||||||
|
"ParentId": "22093c35d77bb609b9257ffb2640845ec05018e3d96cb939f68d0e19127f1723",
|
||||||
|
"RepoTags": [
|
||||||
|
"ubuntu:14.04"
|
||||||
|
],
|
||||||
|
"Size": 0,
|
||||||
|
"VirtualSize": 199257566
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEogIBAAKCAQEAuUQcWlhrMXmzLSLiHUADdF98IHKRde7I1eDT91NndOtx4pKf
|
||||||
|
vVc3WPeiREIMksrU8F1r4A086h5++xxDf27LxR4EC9ry0Q6GgJ9Un9RB9clCWRhL
|
||||||
|
w8awHAS7HgAEN8YOSCeF3qP+78muxyMkIKQbYn3TqqOzRZcK576hX+a6URNJDhbH
|
||||||
|
HAzq2fxmrOSRVdPXzKLl48ABfmqJ6+KiXc6e7mQSgmwBLfh51zxmJNNwZ5e+6sfZ
|
||||||
|
8oz4yM4yKzek53GRSFj+VFNp5nS/x2072fUak2i6DGut5LibFfh1kqskIm+Iq5Ww
|
||||||
|
O15RbojZCR6fkktCl5QOtea5p8SETZpwWfaddQIDAQABAoIBAAoj2zVqr3tGwPLQ
|
||||||
|
fPXC4i2FaGLSQnnk9uMV6iQYUYpJtLME+W9Ajcv1ydDYmJ2UMnFxe40IzHO39ZVC
|
||||||
|
58LaypZgXTJU6oNcuynhDp2s3WtZd6MuvD7b6hmufJtYvuJamb+DQkV8TmDLdiB6
|
||||||
|
IOkUcldCscoeKZq+eJ9UhLqeA0aaosVUa2cfxJM2seGhF6iJmrJChvaKlc0xfqxG
|
||||||
|
l3Y+w01YNQgFBT7vxMzfXHZkVjY8jrrsxhhfyVKiheyaBZ0G3hQCZkBywR6h2bns
|
||||||
|
2rWM2mOcaWL7+lJiMB0d9el58HzTxFVxuPENbE2Li1SqTG1pn+Fif0VwG3Te0lPo
|
||||||
|
xz7EL8UCgYEA3wJLL2nfVqS73yf5k2w1+uiBHK4RVHaJeQgxv1QlgeunCwOWZ0dp
|
||||||
|
MDPQVi9CfWhEQUZKYr118V3ikecOYh+o8ruStz9fNTeA+7IXtBaE1cAbqU9ZgeS2
|
||||||
|
vcAIfEzQmN9JtSiFsywJKLON4/aDYXGR1NZDSaXouFQ7T0F/SaL/CUsCgYEA1Kxu
|
||||||
|
1QjOwFC1tdB/2MF9Fn7X+YWBQsdE66a5HO30FTlMmLb/ecmngB5OxvdvpfMRMQeD
|
||||||
|
mhifSzAfnTBAzBcuz9/il6sKygfhQX6PyxtTJ5o4XlwOArkaBew8H0gBXwfAL33G
|
||||||
|
816rNF2kCfgDJisj9iPrl+QAgrg3sJsfIwk5fD8CgYAx075eyqYHIumDM9hUsyHg
|
||||||
|
fOCUOuROXenbbBRJbpCu1atOD7AkRVVgWsNa7lZJ1OkjOIRYSYK3ukVsWhbhn7dM
|
||||||
|
/NIMNZGdP1iHZERdjYaCh9jmXH9gQWz/Oo/qzfLxpTo/yt0MqnMlb/DtFWBHfmua
|
||||||
|
BYGlS/eSb+eMjtLU7iFTvwKBgDiGuFKhK6rMCPARQdnP27p97lOg23FvW28y+iKp
|
||||||
|
UGXPu/8fLJonMgEIjTGvFJrMFzar45uyjaxDVzPFXoOgac3QmP5s9Mor/AAXboqy
|
||||||
|
cZCmGfNijkrE/hiy6Gv8DHlAqyE0Ugvfjqu1c+M+az/a2Y0TkQvnCwezhQHIySbb
|
||||||
|
zc6rAoGAcg9GZnYk64V2c4uzaeTekkLkZhPTv4F7xFWb0JmTurL5BR//TDDk9Oy8
|
||||||
|
pd5VoiBnKyCRTo2oC8J8COobxJXbl5qUxEeapjtKlQeBiROWE51K2DHacD2SDgKu
|
||||||
|
nzn5qonnU2659Aw95bfv+rGljttOu8ySZXVhs4UUKgrQvXErXhU=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
Loading…
Reference in New Issue