Skip to content

Commit 7b42a5c

Browse files
committed
Merge pull request #88 from docker-java/serverAddress
Add support for private repositories and pull/push authentication
2 parents d74799e + 9503bc0 commit 7b42a5c

21 files changed

+322
-125
lines changed

README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ Developer forum for [docker-java](https://groups.google.com/forum/?hl=de#!forum/
1616
* Maven 3.0.5
1717
* Docker daemon running
1818

19-
The Maven build includes integration tests which are using a localhost instance of Docker and require manual setup. Make sure you have a local Docker daemon running and then provide your https://registry.hub.docker.com/account/login/ information via system properties:
19+
If you need SSL, then you'll need to put your `*.pem` file into `~/.docker/`, if you're using boot2docker, do this:
20+
21+
$ ln -s /Users/alex.collins/.boot2docker/certs/boot2docker-vm .docker
2022

21-
$ mvn clean install -Ddocker.io.username=... -Ddocker.io.password=... -Ddocker.io.email=...
23+
Build and run integration tests as follows:
2224

23-
_If your Docker server is remote, add its URL like this: `-Ddocker.io.url=https://...:2376`._
25+
$ mvn clean install
2426

2527
If you do not have access to a Docker server or just want to execute the build quickly, you can run the build without the integration tests:
2628

@@ -79,9 +81,10 @@ There are a couple of configuration items, all of which have sensible defaults:
7981

8082
* `url` The Docker URL, e.g. `https://localhost:2376`.
8183
* `version` The API version, e.g. `1.15`.
82-
* `username` Your repository username (required to push containers).
83-
* `password` Your repository password.
84-
* `email` Your repository email.
84+
* `username` Your registry username (required to push containers).
85+
* `password` Your registry password.
86+
* `email` Your registry email.
87+
* `serverAddress` Your registry's address.
8588
* `dockerCertPath` Path to the docker certs.
8689

8790
There are three ways to configure, in descending order of precedence:
@@ -95,6 +98,7 @@ In your application, e.g.
9598
.withUsername("dockeruser")
9699
.withPassword("ilovedocker")
97100
.withEmail("dockeruser@github.com")
101+
.withServerAddress("https://index.docker.io/v1/")
98102
.withDockerCertPath("/home/user/.docker")
99103
.build();
100104
DockerClient docker = DockerClientBuilder.getInstance(config).build();
@@ -106,6 +110,7 @@ In your application, e.g.
106110
docker.io.username=dockeruser
107111
docker.io.password=ilovedocker
108112
docker.io.email=dockeruser@github.com
113+
docker.io.serverAddress=https://index.docker.io/v1/
109114
docker.io.dockerCertPath=/home/user/.docker
110115

111116

src/main/java/com/github/dockerjava/api/command/AuthCmd.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,28 @@
22

33
import com.github.dockerjava.api.UnauthorizedException;
44
import com.github.dockerjava.api.model.AuthConfig;
5+
import com.github.dockerjava.api.model.AuthResponse;
56

67
/**
78
*
89
* Authenticate with the server, useful for checking authentication.
910
*
1011
*/
11-
public interface AuthCmd extends DockerCmd<Void> {
12+
public interface AuthCmd extends DockerCmd<AuthResponse> {
1213

1314
public AuthConfig getAuthConfig();
1415

1516
public AuthCmd withAuthConfig(AuthConfig authConfig);
16-
17+
18+
/**
19+
* @return The status. Based on it's value you may mean you need to authorise your account, e.g.:
20+
* "Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it."
21+
* @throws UnauthorizedException If you're not authorised (e.g. bad password).
22+
*/
1723
@Override
18-
public Void exec() throws UnauthorizedException;
24+
public AuthResponse exec() throws UnauthorizedException;
1925

20-
public static interface Exec extends DockerCmdExec<AuthCmd, Void> {
26+
public static interface Exec extends DockerCmdExec<AuthCmd, AuthResponse> {
2127
}
2228

2329
}

src/main/java/com/github/dockerjava/api/command/PullImageCmd.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.github.dockerjava.api.command;
22

3+
import com.github.dockerjava.api.model.AuthConfig;
4+
35
import java.io.InputStream;
46

57
/**
@@ -15,13 +17,17 @@ public interface PullImageCmd extends DockerCmd<InputStream>{
1517

1618
public String getRegistry();
1719

18-
public PullImageCmd withRepository(String repository);
20+
public AuthConfig getAuthConfig();
21+
22+
public PullImageCmd withRepository(String repository);
1923

2024
public PullImageCmd withTag(String tag);
2125

2226
public PullImageCmd withRegistry(String registry);
23-
24-
public static interface Exec extends DockerCmdExec<PullImageCmd, InputStream> {
27+
28+
public PullImageCmd withAuthConfig(AuthConfig authConfig);
29+
30+
public static interface Exec extends DockerCmdExec<PullImageCmd, InputStream> {
2531
}
2632

2733
}

src/main/java/com/github/dockerjava/api/model/AuthConfig.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@
33
import com.fasterxml.jackson.annotation.JsonProperty;
44

55
public class AuthConfig {
6-
7-
@JsonProperty
6+
7+
/**
8+
* For backwards compatibility. Make sure you update the properties if you change this.
9+
*
10+
* @see /docker.io.properties
11+
*/
12+
public static final String DEFAULT_SERVER_ADDRESS = "https://index.docker.io/v1/";
13+
14+
@JsonProperty
815
private String username;
916

1017
@JsonProperty
@@ -14,7 +21,7 @@ public class AuthConfig {
1421
private String email;
1522

1623
@JsonProperty("serveraddress")
17-
private String serverAddress = "https://index.docker.io/v1/";
24+
private String serverAddress = DEFAULT_SERVER_ADDRESS;
1825

1926
public String getUsername() {
2027
return username;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.github.dockerjava.api.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public class AuthResponse {
6+
@JsonProperty("Status")
7+
private String status;
8+
9+
public String getStatus() {
10+
return status;
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.github.dockerjava.api.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public class ErrorDetail {
6+
@JsonProperty
7+
private String message;
8+
9+
public String getMessage() {
10+
return message;
11+
}
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.github.dockerjava.api.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public class ErrorResponse {
6+
@JsonProperty
7+
private ErrorDetail errorDetail;
8+
@JsonProperty
9+
private String error;
10+
11+
public ErrorDetail getErrorDetail() {
12+
return errorDetail;
13+
}
14+
15+
public String getError() {
16+
return error;
17+
}
18+
}

src/main/java/com/github/dockerjava/core/DockerClientConfig.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class DockerClientConfig {
1818
private static final String DOCKER_IO_USERNAME_PROPERTY = "docker.io.username";
1919
private static final String DOCKER_IO_PASSWORD_PROPERTY = "docker.io.password";
2020
private static final String DOCKER_IO_EMAIL_PROPERTY = "docker.io.email";
21+
private static final String DOCKER_IO_SERVER_ADDRESS_PROPERTY = "docker.io.serverAddress";
2122
private static final String DOCKER_IO_READ_TIMEOUT_PROPERTY = "docker.io.readTimeout";
2223
// this is really confusing, as there are two ways to spell it
2324
private static final String DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY = "docker.io.enableLoggingFilter";
@@ -31,22 +32,24 @@ public class DockerClientConfig {
3132
.put("DOCKER_USERNAME", DOCKER_IO_USERNAME_PROPERTY)
3233
.put("DOCKER_PASSWORD", DOCKER_IO_PASSWORD_PROPERTY)
3334
.put("DOCKER_EMAIL", DOCKER_IO_EMAIL_PROPERTY)
35+
.put("DOCKER_SERVER_ADDRESS", DOCKER_IO_SERVER_ADDRESS_PROPERTY)
3436
.put("DOCKER_READ_TIMEOUT", DOCKER_IO_READ_TIMEOUT_PROPERTY)
3537
.put("DOCKER_LOGGING_FILTER_ENABLED", DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY)
3638
.put(DOCKER_CERT_PATH_PROPERTY, DOCKER_IO_DOCKER_CERT_PATH_PROPERTY)
3739
.build();
3840
private static final String DOCKER_IO_PROPERTIES_PROPERTY = "docker.io.properties";
3941
private final URI uri;
40-
private final String version, username, password, email, dockerCertPath;
42+
private final String version, username, password, email, serverAddress, dockerCertPath;
4143
private final Integer readTimeout;
4244
private final boolean loggingFilterEnabled;
4345

44-
DockerClientConfig(URI uri, String version, String username, String password, String email, String dockerCertPath, Integer readTimeout, boolean loggingFilterEnabled) {
46+
DockerClientConfig(URI uri, String version, String username, String password, String email, String serverAddress, String dockerCertPath, Integer readTimeout, boolean loggingFilterEnabled) {
4547
this.uri = uri;
4648
this.version = version;
4749
this.username = username;
4850
this.password = password;
4951
this.email = email;
52+
this.serverAddress = serverAddress;
5053
this.dockerCertPath = dockerCertPath;
5154
this.readTimeout = readTimeout;
5255
this.loggingFilterEnabled = loggingFilterEnabled;
@@ -146,6 +149,7 @@ private static Properties overrideDockerPropertiesWithSystemProperties(Propertie
146149
DOCKER_IO_USERNAME_PROPERTY,
147150
DOCKER_IO_PASSWORD_PROPERTY,
148151
DOCKER_IO_EMAIL_PROPERTY,
152+
DOCKER_IO_SERVER_ADDRESS_PROPERTY,
149153
DOCKER_IO_READ_TIMEOUT_PROPERTY,
150154
DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY,
151155
DOCKER_IO_DOCKER_CERT_PATH_PROPERTY,
@@ -192,6 +196,10 @@ public String getEmail() {
192196
return email;
193197
}
194198

199+
public String getServerAddress() {
200+
return serverAddress;
201+
}
202+
195203
public Integer getReadTimeout() {
196204
return readTimeout;
197205
}
@@ -217,6 +225,8 @@ public boolean equals(Object o) {
217225
if (email != null ? !email.equals(that.email) : that.email != null) return false;
218226
if (password != null ? !password.equals(that.password) : that.password != null) return false;
219227
if (readTimeout != null ? !readTimeout.equals(that.readTimeout) : that.readTimeout != null) return false;
228+
if (serverAddress != null ? !serverAddress.equals(that.serverAddress) : that.serverAddress != null)
229+
return false;
220230
if (uri != null ? !uri.equals(that.uri) : that.uri != null) return false;
221231
if (username != null ? !username.equals(that.username) : that.username != null) return false;
222232
if (version != null ? !version.equals(that.version) : that.version != null) return false;
@@ -231,6 +241,7 @@ public int hashCode() {
231241
result = 31 * result + (username != null ? username.hashCode() : 0);
232242
result = 31 * result + (password != null ? password.hashCode() : 0);
233243
result = 31 * result + (email != null ? email.hashCode() : 0);
244+
result = 31 * result + (serverAddress != null ? serverAddress.hashCode() : 0);
234245
result = 31 * result + (dockerCertPath != null ? dockerCertPath.hashCode() : 0);
235246
result = 31 * result + (readTimeout != null ? readTimeout.hashCode() : 0);
236247
result = 31 * result + (loggingFilterEnabled ? 1 : 0);
@@ -245,6 +256,7 @@ public String toString() {
245256
", username='" + username + '\'' +
246257
", password='" + password + '\'' +
247258
", email='" + email + '\'' +
259+
", serverAddress='" + serverAddress + '\'' +
248260
", dockerCertPath='" + dockerCertPath + '\'' +
249261
", readTimeout=" + readTimeout +
250262
", loggingFilterEnabled=" + loggingFilterEnabled +
@@ -253,7 +265,7 @@ public String toString() {
253265

254266
public static class DockerClientConfigBuilder {
255267
private URI uri;
256-
private String version, username, password, email, dockerCertPath;
268+
private String version, username, password, email, serverAddress, dockerCertPath;
257269
private Integer readTimeout;
258270
private boolean loggingFilterEnabled;
259271

@@ -269,6 +281,7 @@ public DockerClientConfigBuilder withProperties(Properties p) {
269281
.withUsername(p.getProperty(DOCKER_IO_USERNAME_PROPERTY))
270282
.withPassword(p.getProperty(DOCKER_IO_PASSWORD_PROPERTY))
271283
.withEmail(p.getProperty(DOCKER_IO_EMAIL_PROPERTY))
284+
.withServerAddress(p.getProperty(DOCKER_IO_SERVER_ADDRESS_PROPERTY))
272285
.withReadTimeout(Integer.valueOf(p.getProperty(DOCKER_IO_READ_TIMEOUT_PROPERTY, "0")))
273286
.withLoggingFilter(Boolean.valueOf(p.getProperty(DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY, "true")))
274287
.withDockerCertPath(p.getProperty(DOCKER_IO_DOCKER_CERT_PATH_PROPERTY));
@@ -300,6 +313,11 @@ public final DockerClientConfigBuilder withEmail(String email) {
300313
return this;
301314
}
302315

316+
public DockerClientConfigBuilder withServerAddress(String serverAddress) {
317+
this.serverAddress = serverAddress;
318+
return this;
319+
}
320+
303321
public final DockerClientConfigBuilder withReadTimeout(Integer readTimeout) {
304322
this.readTimeout = readTimeout;
305323
return this;
@@ -322,6 +340,7 @@ public DockerClientConfig build() {
322340
username,
323341
password,
324342
email,
343+
serverAddress,
325344
dockerCertPath,
326345
readTimeout,
327346
loggingFilterEnabled

src/main/java/com/github/dockerjava/core/DockerClientImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ private DockerCmdExecFactory getDockerCmdExecFactory() {
7171

7272
public AuthConfig authConfig() {
7373
checkNotNull(dockerClientConfig.getUsername(), "Configured username is null.");
74-
checkNotNull(dockerClientConfig.getPassword(), "Configured password is null.");
75-
checkNotNull(dockerClientConfig.getEmail(), "Configured email is null.");
74+
checkNotNull(dockerClientConfig.getServerAddress(), "Configured serverAddress is null.");
7675

7776
AuthConfig authConfig = new AuthConfig();
7877
authConfig.setUsername(dockerClientConfig.getUsername());
7978
authConfig.setPassword(dockerClientConfig.getPassword());
8079
authConfig.setEmail(dockerClientConfig.getEmail());
81-
// TODO Make the registry address configurable
80+
authConfig.setServerAddress(dockerClientConfig.getServerAddress());
81+
8282
return authConfig;
8383
}
8484

src/main/java/com/github/dockerjava/core/command/AuthCmdImpl.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,25 @@
33
import com.github.dockerjava.api.UnauthorizedException;
44
import com.github.dockerjava.api.command.AuthCmd;
55
import com.github.dockerjava.api.model.AuthConfig;
6+
import com.github.dockerjava.api.model.AuthResponse;
67

78
/**
89
*
910
* Authenticate with the server, useful for checking authentication.
1011
*
1112
*/
12-
public class AuthCmdImpl extends AbstrAuthCfgDockerCmd<AuthCmd, Void> implements AuthCmd {
13+
public class AuthCmdImpl extends AbstrAuthCfgDockerCmd<AuthCmd, AuthResponse> implements AuthCmd {
1314

1415
public AuthCmdImpl(AuthCmd.Exec exec, AuthConfig authConfig) {
1516
super(exec);
1617
withAuthConfig(authConfig);
1718
}
18-
19+
1920
@Override
20-
public Void exec() throws UnauthorizedException {
21+
public AuthResponse exec() throws UnauthorizedException {
2122
return super.exec();
2223
}
23-
24+
2425
@Override
2526
public String toString() {
2627
return "authenticate using " + this.getAuthConfig();

0 commit comments

Comments
 (0)