Skip to content

Commit a2e1a8d

Browse files
author
Marcus Linke
committed
Merge branch 'alexec-config-spike'
2 parents 431306b + 81789ea commit a2e1a8d

File tree

8 files changed

+185
-98
lines changed

8 files changed

+185
-98
lines changed

README.md

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ listening on TCP port. To allow Docker server to use TCP add the following line
3131
More details setting up docket server can be found in official documentation: http://docs.docker.io/en/latest/use/basics/
3232

3333
Now make sure that docker is up:
34-
34+
3535
$ docker -H tcp://127.0.0.1:4243 version
3636

3737
Client version: 0.8.1
@@ -63,12 +63,12 @@ Run build with tests:
6363

6464
Info info = dockerClient.info();
6565
System.out.print(info);
66-
66+
6767
###### Search Docker repository:
6868

6969
List<SearchItem> dockerSearch = dockerClient.search("busybox");
7070
System.out.println("Search returned" + dockerSearch.toString());
71-
71+
7272
###### Create new Docker container, wait for its start and stop it:
7373

7474
ContainerConfig containerConfig = new ContainerConfig();
@@ -81,7 +81,7 @@ Run build with tests:
8181
dockerClient.waitContainer(container.id);
8282

8383
dockerClient.stopContainer(container.id);
84-
84+
8585

8686
##### Support for UNIX sockets:
8787

@@ -114,3 +114,36 @@ user dockerClient.build(baseDir), where baseDir is a path to folder containing D
114114

115115
For additional examples, please look at [DockerClientTest.java](https://github.com/kpelykh/docker-java/blob/master/src/test/java/com/kpelykh/docker/client/test/DockerClientTest.java "DockerClientTest.java")
116116

117+
## Configuration
118+
119+
There are a couple of configuration items, all of which have sensible defaults:
120+
121+
* `url` The Docker URL, e.g. `http://localhost:4243`.
122+
* `version` The API version, e.g. `1.11`.
123+
* `username` Your repository username (required to push containers).
124+
* `password` Your repository password.
125+
* `email` Your repository email.
126+
127+
There are three ways to configure, in descending order of precedence:
128+
129+
##### Programatic:
130+
In your application, e.g.
131+
132+
DockerClient docker = new DockerClient("http://localhost:4243");
133+
docker.setCredentials("dockeruser", "ilovedocker", "dockeruser@github.com");`
134+
135+
##### System Properties:
136+
E.g.
137+
138+
java -Ddocker.io.username=kpelykh pkg.Main
139+
140+
##### File System
141+
In `$HOME/.docker.io.properties`, e.g.:
142+
143+
docker.io.username=dockeruser
144+
145+
##### Class Path
146+
In the class path at `/docker.io.properties`, e.g.:
147+
148+
docker.io.url=http://localhost:4243
149+
docker.io.version=1.11
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.kpelykh.docker.client;
2+
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.IOException;
6+
import java.net.URI;
7+
import java.util.Properties;
8+
9+
class Config {
10+
URI url;
11+
String version, username, password, email;
12+
13+
private Config() {
14+
}
15+
16+
static Config createConfig() throws DockerException {
17+
final Properties p = new Properties();
18+
19+
try {
20+
p.load(Config.class.getResourceAsStream("/docker.io.properties"));
21+
} catch (IOException e) {
22+
throw new DockerException(e);
23+
}
24+
25+
for (String s : new String[]{"url", "version", "username", "password", "email"}) {
26+
final String key = "docker.io." + s;
27+
if (System.getProperties().keySet().contains(key)) {
28+
p.setProperty(key, System.getProperty(key));
29+
}
30+
}
31+
32+
final File file = new File(System.getProperty("user.name"), ".docker.io.properties");
33+
System.out.println(file);
34+
if (file.isFile()) {
35+
try {
36+
final FileInputStream in = new FileInputStream(file);
37+
try {
38+
p.load(in);
39+
} finally {
40+
in.close();
41+
}
42+
} catch (IOException e) {
43+
throw new DockerException(e);
44+
}
45+
}
46+
47+
final Config c = new Config();
48+
49+
c.url = URI.create(p.getProperty("docker.io.url"));
50+
c.version = p.getProperty("docker.io.version");
51+
c.username = p.getProperty("docker.io.username");
52+
c.password = p.getProperty("docker.io.password");
53+
c.email = p.getProperty("docker.io.email");
54+
55+
return c;
56+
}
57+
}

src/main/java/com/kpelykh/docker/client/DockerClient.java

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,31 @@ public class DockerClient {
5252

5353
private static final Logger LOGGER = LoggerFactory.getLogger(DockerClient.class);
5454

55-
private static DockerClient instance;
56-
private Client client;
55+
private Client client;
5756
private String restEndpointUrl;
5857
private AuthConfig authConfig;
5958

60-
public DockerClient() {
61-
this("http://localhost:4243");
59+
public DockerClient() throws DockerException {
60+
this(Config.createConfig());
6261
}
6362

64-
public DockerClient(String serverUrl) {
65-
restEndpointUrl = serverUrl + "/v1.11";
63+
public DockerClient(String serverUrl) throws DockerException {
64+
this(configWithServerUrl(serverUrl));
65+
}
66+
67+
private static Config configWithServerUrl(String serverUrl) throws DockerException {
68+
final Config c = Config.createConfig();
69+
c.url = URI.create(serverUrl);
70+
return c;
71+
}
72+
73+
private DockerClient(Config config) {
74+
restEndpointUrl = config.url + "/v" + config.version;
6675
ClientConfig clientConfig = new DefaultClientConfig();
6776
//clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
6877

6978
SchemeRegistry schemeRegistry = new SchemeRegistry();
70-
schemeRegistry.register(new Scheme("http", 4243, PlainSocketFactory.getSocketFactory()));
79+
schemeRegistry.register(new Scheme("http", config.url.getPort(), PlainSocketFactory.getSocketFactory()));
7180
schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
7281

7382
PoolingClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);
@@ -107,7 +116,6 @@ public void setCredentials(String username, String password, String email) {
107116
* Authenticate with the server, useful for checking authentication.
108117
*/
109118
public void auth() throws DockerException {
110-
checkAuthConfig();
111119
try {
112120
client.resource(restEndpointUrl + "/auth")
113121
.header("Content-Type", MediaType.APPLICATION_JSON)
@@ -126,18 +134,28 @@ private String registryAuth() throws DockerException {
126134
}
127135
}
128136

129-
private AuthConfig authConfig() throws DockerException {
130-
checkAuthConfig();
131-
return authConfig;
132-
}
137+
public AuthConfig authConfig() throws DockerException {
138+
return authConfig != null
139+
? authConfig
140+
: authConfigFromProperties();
141+
}
133142

134-
private void checkAuthConfig() throws DockerException {
135-
if (authConfig == null) {
136-
throw new DockerException("authentication credentials required");
137-
}
138-
}
143+
private static AuthConfig authConfigFromProperties() throws DockerException {
144+
final AuthConfig a = new AuthConfig();
139145

140-
/**
146+
a.setUsername(Config.createConfig().username);
147+
a.setPassword(Config.createConfig().password);
148+
a.setEmail(Config.createConfig().email);
149+
150+
if (a.getUsername() == null) {throw new IllegalStateException("username is null");}
151+
if (a.getPassword() == null) {throw new IllegalStateException("password is null");}
152+
if (a.getEmail() == null) {throw new IllegalStateException("email is null");}
153+
154+
return a;
155+
}
156+
157+
158+
/**
141159
* * MISC API
142160
* *
143161
*/
@@ -215,6 +233,9 @@ public ClientResponse pull(String repository, String tag, String registry) throw
215233
}
216234
}
217235
}
236+
237+
238+
218239

219240
/**
220241
* @return The output slurped into a string.

src/main/java/com/kpelykh/docker/client/model/ContainerConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ public String toString() {
285285
", privileged=" + privileged +
286286
", workingDir='" + workingDir + '\'' +
287287
", domainName='" + domainName + '\'' +
288-
", onBuild='" + onBuild + '\'' +
288+
", onBuild='" + Arrays.toString(onBuild) + '\'' +
289289
'}';
290290
}
291291
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
docker.io.url=http://localhost:4243
2+
docker.io.version=1.11

src/test/java/com/kpelykh/docker/client/test/AbstractDockerClientTest.java

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.kpelykh.docker.client.test;
22

3-
import java.io.IOException;
4-
import java.lang.reflect.Method;
5-
import java.util.ArrayList;
6-
import java.util.List;
7-
3+
import com.kpelykh.docker.client.DockerClient;
4+
import com.kpelykh.docker.client.DockerException;
5+
import com.sun.jersey.api.client.ClientResponse;
86
import org.slf4j.Logger;
97
import org.slf4j.LoggerFactory;
108
import org.testng.Assert;
119
import org.testng.ITestResult;
1210

13-
import com.kpelykh.docker.client.DockerClient;
14-
import com.kpelykh.docker.client.DockerException;
15-
import com.sun.jersey.api.client.ClientResponse;
11+
import java.io.IOException;
12+
import java.lang.reflect.Method;
13+
import java.util.ArrayList;
14+
import java.util.List;
1615

1716
public abstract class AbstractDockerClientTest extends Assert {
1817

@@ -32,7 +31,8 @@ public void beforeTest() throws DockerException {
3231
dockerClient = new DockerClient(url);
3332

3433
LOG.info("Creating image 'busybox'");
35-
dockerClient.pull("busybox");
34+
// need to block until image is pulled completely
35+
logResponseStream(dockerClient.pull("busybox"));
3636

3737
assertNotNull(dockerClient);
3838
LOG.info("======================= END OF BEFORETEST =======================\n\n");
@@ -76,28 +76,15 @@ public void afterMethod(ITestResult result) {
7676
result.getName());
7777
}
7878

79-
protected String logResponseStream(ClientResponse response) throws IOException {
80-
String responseString = DockerClient.asString(response);
79+
protected String logResponseStream(ClientResponse response) {
80+
String responseString;
81+
try {
82+
responseString = DockerClient.asString(response);
83+
} catch (IOException e) {
84+
throw new RuntimeException(e);
85+
}
8186
LOG.info("Container log: {}", responseString);
8287
return responseString;
8388
}
84-
85-
private String getProperty(String name) {
86-
String property = System.getProperty(name);
87-
if(property == null || property.isEmpty()) throw new RuntimeException("Need to configure '" + name + "' property to run the test. Use command line option -D"+ name +"=... to do so.");
88-
return property;
89-
}
90-
91-
protected String getUsername() {
92-
return getProperty("docker.io.username");
93-
}
94-
95-
protected String getPassword() {
96-
return getProperty("docker.io.password");
97-
}
98-
99-
protected String getEmail() {
100-
return getProperty("docker.io.email");
101-
}
10289

10390
}
Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
package com.kpelykh.docker.client.test;
22

3-
import static org.hamcrest.MatcherAssert.assertThat;
4-
5-
import java.lang.reflect.Method;
6-
import java.util.ArrayList;
3+
import com.kpelykh.docker.client.DockerException;
4+
import com.sun.jersey.api.client.UniformInterfaceException;
75

86
import org.hamcrest.Matchers;
97
import org.testng.ITestResult;
10-
import org.testng.annotations.AfterMethod;
11-
import org.testng.annotations.AfterTest;
12-
import org.testng.annotations.BeforeMethod;
13-
import org.testng.annotations.BeforeTest;
14-
import org.testng.annotations.Test;
8+
import org.testng.annotations.*;
159

16-
import com.kpelykh.docker.client.DockerException;
17-
import com.sun.jersey.api.client.UniformInterfaceException;
10+
import java.lang.reflect.Method;
11+
12+
import static org.hamcrest.MatcherAssert.assertThat;
1813

1914
public class DockerClientAuthTest extends AbstractDockerClientTest {
2015

2116
@BeforeTest
22-
public void beforeTest() throws DockerException {
17+
public void beforeTest() throws DockerException {
2318
super.beforeTest();
2419
}
2520
@AfterTest
@@ -36,21 +31,21 @@ public void beforeMethod(Method method) {
3631
public void afterMethod(ITestResult result) {
3732
super.afterMethod(result);
3833
}
39-
34+
4035
@Test
4136
public void testAuth() throws Exception {
42-
dockerClient.setCredentials(getUsername(), getPassword(), getEmail());
4337
dockerClient.auth();
4438
}
4539

4640
@Test
4741
public void testAuthInvalid() throws Exception {
48-
dockerClient.setCredentials(getUsername(), getPassword(), getEmail());
42+
System.setProperty("docker.io.password", "garbage");
4943
try {
5044
dockerClient.auth();
45+
fail();
5146
} catch (DockerException e) {
5247
assertThat(e.getCause(), Matchers.instanceOf(UniformInterfaceException.class));
53-
assertEquals(401, ((UniformInterfaceException) e.getCause()).getResponse().getStatus());
48+
assertEquals(((UniformInterfaceException) e.getCause()).getResponse().getStatus(), 401);
5449
}
5550
}
5651
}

0 commit comments

Comments
 (0)