Skip to content

Commit c2e8329

Browse files
authored
Merge branch 'main' into dont-trash-ioexception
2 parents d82d9be + 97579e5 commit c2e8329

File tree

153 files changed

+753
-671
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+753
-671
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* @docker-java/team
2+

.github/workflows/ci.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,27 @@ name: CI
22

33
on:
44
pull_request: {}
5-
push: { branches: [ master ] }
5+
push: { branches: [ main ] }
66

77
jobs:
88
build:
9-
runs-on: ubuntu-18.04
9+
runs-on: ubuntu-20.04
1010
strategy:
1111
fail-fast: false
1212
matrix:
1313
include:
1414
- { name: "default", javaVersion: 8 }
1515
- { name: "default", javaVersion: 17 }
1616
- { name: "over TCP", dockerHost: "tcp://127.0.0.1:2375", javaVersion: 8 }
17-
- { name: "Docker 18.06.3", dockerVersion: "18.06.3~ce~3-0~ubuntu", javaVersion: 8 }
17+
- { name: "Docker 19.03.9", dockerVersion: "5:19.03.9~3-0~ubuntu-focal", javaVersion: 8 }
1818

1919
steps:
20-
- uses: actions/checkout@v2
20+
- uses: actions/checkout@v3
2121
- name: Set up JDK
22-
uses: actions/setup-java@v1
22+
uses: actions/setup-java@v3
2323
with:
2424
java-version: ${{matrix.javaVersion}}
25+
distribution: temurin
2526
- name: Configure Docker
2627
env:
2728
DOCKER_VERSION: ${{matrix.dockerVersion}}

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
push:
55
# branches to consider in the event; optional, defaults to all
66
branches:
7-
- master
7+
- main
88

99
jobs:
1010
update_release_draft:

.github/workflows/release.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ on:
88

99
jobs:
1010
build:
11-
runs-on: ubuntu-18.04
11+
runs-on: ubuntu-22.04
1212
steps:
13-
- uses: actions/checkout@v1
13+
- uses: actions/checkout@v3
1414
- name: Set up JDK 8
15-
uses: actions/setup-java@v1
15+
uses: actions/setup-java@v3
1616
with:
1717
java-version: 8
18+
distribution: temurin
1819
- name: Set version
1920
run: ./mvnw versions:set -DnewVersion="${{github.event.release.tag_name}}"
20-
# TODO check master's CI status
21+
# TODO check main's CI status
2122
- name: Deploy with Maven
2223
env:
2324
MAVEN_DEPLOYMENT_REPOSITORY: ${{ secrets.MAVEN_DEPLOYMENT_REPOSITORY }}

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ v2.0.0
301301
Release notes
302302

303303
* Some commands APIs has been changed to be callback-driven now to simplify the processing of the result streams for the client application. This affects namely the events, stats, log, attach, build, push and pull commands. Look at the Wiki how to [process events](https://github.com/docker-java/docker-java/wiki#handle-events) or how to [build an image](https://github.com/docker-java/docker-java/wiki#build-image-from-dockerfile) from dockerfile for example.
304-
* The `DockerClientConfig` API has changed to free it from implementation specific configuration options like `readTimeout`, `maxTotalConnections`, `maxPerRouteConnections` and `enableLoggingFilter`. Most options can be configured via `DockerCmdExecFactoryImpl` [programmatically](https://github.com/docker-java/docker-java/wiki#intialize-docker-client-advanced) now. Logging is configurable via [logback](https://github.com/docker-java/docker-java/blob/master/src/test/resources/logback.xml) configuration file in the classpath.
304+
* The `DockerClientConfig` API has changed to free it from implementation specific configuration options like `readTimeout`, `maxTotalConnections`, `maxPerRouteConnections` and `enableLoggingFilter`. Most options can be configured via `DockerCmdExecFactoryImpl` [programmatically](https://github.com/docker-java/docker-java/wiki#intialize-docker-client-advanced) now. Logging is configurable via [logback](https://github.com/docker-java/docker-java/blob/main/src/test/resources/logback.xml) configuration file in the classpath.
305305

306306
All changes
307307

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[![Join the chat at https://gitter.im/docker-java/docker-java](https://badges.gitter.im/docker-java/docker-java.svg)](https://gitter.im/docker-java/docker-java?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
22
[![Maven Central](https://img.shields.io/maven-central/v/com.github.docker-java/docker-java.svg)](https://mvnrepository.com/artifact/com.github.docker-java/docker-java)
3-
[![codecov.io](http://codecov.io/github/docker-java/docker-java/coverage.svg?branch=master)](http://codecov.io/github/docker-java/docker-java?branch=master)
4-
[![License](http://img.shields.io/:license-apache-blue.svg?style=flat)](https://github.com/docker-java/docker-java/blob/master/LICENSE)
3+
[![codecov.io](http://codecov.io/github/docker-java/docker-java/coverage.svg?branch=main)](http://codecov.io/github/docker-java/docker-java?branch=master)
4+
[![License](http://img.shields.io/:license-apache-blue.svg?style=flat)](https://github.com/docker-java/docker-java/blob/main/LICENSE)
55
# docker-java
66

77
Java API client for [Docker](http://docs.docker.io/ "Docker")
88

9-
# [Read the documentation here](docs/README.md)
9+
# [Read the documentation here](docs/README.md)

docker-java-core/src/main/java/com/github/dockerjava/core/AbstractDockerCmdExecFactory.java

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

3+
import java.util.Objects;
4+
35
import com.github.dockerjava.api.command.AttachContainerCmd;
46
import com.github.dockerjava.api.command.AuthCmd;
57
import com.github.dockerjava.api.command.BuildImageCmd;
@@ -160,8 +162,6 @@
160162
import com.github.dockerjava.core.exec.VersionCmdExec;
161163
import com.github.dockerjava.core.exec.WaitContainerCmdExec;
162164

163-
import static com.google.common.base.Preconditions.checkNotNull;
164-
165165
public abstract class AbstractDockerCmdExecFactory implements DockerCmdExecFactory, DockerClientConfigAware {
166166

167167
private DockerClientConfig dockerClientConfig;
@@ -170,15 +170,14 @@ public abstract class AbstractDockerCmdExecFactory implements DockerCmdExecFacto
170170
protected Integer readTimeout;
171171

172172
protected DockerClientConfig getDockerClientConfig() {
173-
checkNotNull(dockerClientConfig,
173+
Objects.requireNonNull(dockerClientConfig,
174174
"Factor not initialized, dockerClientConfig not set. You probably forgot to call init()!");
175175
return dockerClientConfig;
176176
}
177177

178178
@Override
179179
public void init(DockerClientConfig dockerClientConfig) {
180-
checkNotNull(dockerClientConfig, "config was not specified");
181-
this.dockerClientConfig = dockerClientConfig;
180+
this.dockerClientConfig = Objects.requireNonNull(dockerClientConfig, "config was not specified");
182181
}
183182

184183
@Override

docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.github.dockerjava.api.model.AuthConfigurations;
66
import com.github.dockerjava.core.NameParser.HostnameReposName;
77
import com.github.dockerjava.core.NameParser.ReposTag;
8+
import java.util.Optional;
89
import org.apache.commons.lang3.StringUtils;
910
import org.apache.commons.lang3.SystemUtils;
1011
import org.apache.commons.lang3.builder.EqualsBuilder;
@@ -22,10 +23,10 @@
2223
import java.net.URI;
2324
import java.util.HashSet;
2425
import java.util.Map;
26+
import java.util.Objects;
2527
import java.util.Properties;
2628
import java.util.Set;
2729

28-
import static com.google.common.base.Preconditions.checkNotNull;
2930
import static org.apache.commons.lang3.BooleanUtils.isTrue;
3031

3132
/**
@@ -37,6 +38,8 @@ public class DefaultDockerClientConfig implements Serializable, DockerClientConf
3738

3839
public static final String DOCKER_HOST = "DOCKER_HOST";
3940

41+
public static final String DOCKER_CONTEXT = "DOCKER_CONTEXT";
42+
4043
public static final String DOCKER_TLS_VERIFY = "DOCKER_TLS_VERIFY";
4144

4245
public static final String DOCKER_CONFIG = "DOCKER_CONFIG";
@@ -87,11 +90,13 @@ public class DefaultDockerClientConfig implements Serializable, DockerClientConf
8790

8891
private final RemoteApiVersion apiVersion;
8992

90-
private DockerConfigFile dockerConfig = null;
93+
private final DockerConfigFile dockerConfig;
9194

92-
DefaultDockerClientConfig(URI dockerHost, String dockerConfigPath, String apiVersion, String registryUrl,
93-
String registryUsername, String registryPassword, String registryEmail, SSLConfig sslConfig) {
95+
DefaultDockerClientConfig(URI dockerHost, DockerConfigFile dockerConfigFile, String dockerConfigPath, String apiVersion,
96+
String registryUrl, String registryUsername, String registryPassword, String registryEmail,
97+
SSLConfig sslConfig) {
9498
this.dockerHost = checkDockerHostScheme(dockerHost);
99+
this.dockerConfig = dockerConfigFile;
95100
this.dockerConfigPath = dockerConfigPath;
96101
this.apiVersion = RemoteApiVersion.parseConfigWithDefault(apiVersion);
97102
this.sslConfig = sslConfig;
@@ -174,6 +179,13 @@ private static Properties overrideDockerPropertiesWithEnv(Properties properties,
174179
}
175180
}
176181

182+
if (env.containsKey(DOCKER_CONTEXT)) {
183+
String value = env.get(DOCKER_CONTEXT);
184+
if (value != null && value.trim().length() != 0) {
185+
overriddenProperties.setProperty(DOCKER_CONTEXT, value);
186+
}
187+
}
188+
177189
for (Map.Entry<String, String> envEntry : env.entrySet()) {
178190
String envKey = envEntry.getKey();
179191
if (CONFIG_KEYS.contains(envKey)) {
@@ -258,13 +270,6 @@ public String getDockerConfigPath() {
258270

259271
@Nonnull
260272
public DockerConfigFile getDockerConfig() {
261-
if (dockerConfig == null) {
262-
try {
263-
dockerConfig = DockerConfigFile.loadConfig(getObjectMapper(), getDockerConfigPath());
264-
} catch (IOException e) {
265-
throw new DockerClientException("Failed to parse docker configuration file", e);
266-
}
267-
}
268273
return dockerConfig;
269274
}
270275

@@ -325,7 +330,7 @@ public static class Builder {
325330
private URI dockerHost;
326331

327332
private String apiVersion, registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig,
328-
dockerCertPath;
333+
dockerCertPath, dockerContext;
329334

330335
private Boolean dockerTlsVerify;
331336

@@ -343,6 +348,7 @@ public Builder withProperties(Properties p) {
343348
}
344349

345350
return withDockerTlsVerify(p.getProperty(DOCKER_TLS_VERIFY))
351+
.withDockerContext(p.getProperty(DOCKER_CONTEXT))
346352
.withDockerConfig(p.getProperty(DOCKER_CONFIG))
347353
.withDockerCertPath(p.getProperty(DOCKER_CERT_PATH))
348354
.withApiVersion(p.getProperty(API_VERSION))
@@ -356,7 +362,7 @@ public Builder withProperties(Properties p) {
356362
* configure DOCKER_HOST
357363
*/
358364
public final Builder withDockerHost(String dockerHost) {
359-
checkNotNull(dockerHost, "uri was not specified");
365+
Objects.requireNonNull(dockerHost, "uri was not specified");
360366
this.dockerHost = URI.create(dockerHost);
361367
return this;
362368
}
@@ -401,6 +407,11 @@ public final Builder withDockerConfig(String dockerConfig) {
401407
return this;
402408
}
403409

410+
public final Builder withDockerContext(String dockerContext) {
411+
this.dockerContext = dockerContext;
412+
return this;
413+
}
414+
404415
public final Builder withDockerTlsVerify(String dockerTlsVerify) {
405416
if (dockerTlsVerify != null) {
406417
String trimmed = dockerTlsVerify.trim();
@@ -443,14 +454,33 @@ public DefaultDockerClientConfig build() {
443454
sslConfig = customSslConfig;
444455
}
445456

457+
final DockerConfigFile dockerConfigFile = readDockerConfig();
458+
459+
final String context = (dockerContext != null) ? dockerContext : dockerConfigFile.getCurrentContext();
446460
URI dockerHostUri = dockerHost != null
447461
? dockerHost
448-
: URI.create(SystemUtils.IS_OS_WINDOWS ? WINDOWS_DEFAULT_DOCKER_HOST : DEFAULT_DOCKER_HOST);
462+
: resolveDockerHost(context);
449463

450-
return new DefaultDockerClientConfig(dockerHostUri, dockerConfig, apiVersion, registryUrl, registryUsername,
464+
return new DefaultDockerClientConfig(dockerHostUri, dockerConfigFile, dockerConfig, apiVersion, registryUrl, registryUsername,
451465
registryPassword, registryEmail, sslConfig);
452466
}
453467

468+
private DockerConfigFile readDockerConfig() {
469+
try {
470+
return DockerConfigFile.loadConfig(DockerClientConfig.getDefaultObjectMapper(), dockerConfig);
471+
} catch (IOException e) {
472+
throw new DockerClientException("Failed to parse docker configuration file", e);
473+
}
474+
}
475+
476+
private URI resolveDockerHost(String dockerContext) {
477+
return URI.create(Optional.ofNullable(dockerContext)
478+
.flatMap(context -> DockerContextMetaFile.resolveContextMetaFile(
479+
DockerClientConfig.getDefaultObjectMapper(), new File(dockerConfig), context))
480+
.flatMap(DockerContextMetaFile::host)
481+
.orElse(SystemUtils.IS_OS_WINDOWS ? WINDOWS_DEFAULT_DOCKER_HOST : DEFAULT_DOCKER_HOST));
482+
}
483+
454484
private String checkDockerCertPath(String dockerCertPath) {
455485
if (StringUtils.isEmpty(dockerCertPath)) {
456486
throw new DockerClientException(

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@
172172
import java.io.File;
173173
import java.io.IOException;
174174
import java.io.InputStream;
175-
176-
import static com.google.common.base.Preconditions.checkNotNull;
175+
import java.util.Objects;
177176

178177
/**
179178
* @author Konstantin Pelykh (kpelykh@gmail.com)
@@ -186,8 +185,7 @@ public class DockerClientImpl implements Closeable, DockerClient {
186185
DockerCmdExecFactory dockerCmdExecFactory;
187186

188187
DockerClientImpl(DockerClientConfig dockerClientConfig) {
189-
checkNotNull(dockerClientConfig, "config was not specified");
190-
this.dockerClientConfig = dockerClientConfig;
188+
this.dockerClientConfig = Objects.requireNonNull(dockerClientConfig, "config was not specified");
191189
}
192190

193191
/**
@@ -248,7 +246,7 @@ public DockerHttpClient getHttpClient() {
248246
*/
249247
@Deprecated
250248
public DockerClientImpl withDockerCmdExecFactory(DockerCmdExecFactory dockerCmdExecFactory) {
251-
checkNotNull(dockerCmdExecFactory, "dockerCmdExecFactory was not specified");
249+
Objects.requireNonNull(dockerCmdExecFactory, "dockerCmdExecFactory was not specified");
252250
this.dockerCmdExecFactory = dockerCmdExecFactory;
253251
if (dockerCmdExecFactory instanceof DockerClientConfigAware) {
254252
((DockerClientConfigAware) dockerCmdExecFactory).init(dockerClientConfig);
@@ -258,14 +256,14 @@ public DockerClientImpl withDockerCmdExecFactory(DockerCmdExecFactory dockerCmdE
258256

259257
@Deprecated
260258
private DockerCmdExecFactory getDockerCmdExecFactory() {
261-
checkNotNull(dockerCmdExecFactory, "dockerCmdExecFactory was not specified");
259+
Objects.requireNonNull(dockerCmdExecFactory, "dockerCmdExecFactory was not specified");
262260
return dockerCmdExecFactory;
263261
}
264262

265263
@Override
266264
public AuthConfig authConfig() {
267-
checkNotNull(dockerClientConfig.getRegistryUsername(), "Configured username is null.");
268-
checkNotNull(dockerClientConfig.getRegistryUrl(), "Configured serverAddress is null.");
265+
Objects.requireNonNull(dockerClientConfig.getRegistryUsername(), "Configured username is null.");
266+
Objects.requireNonNull(dockerClientConfig.getRegistryUrl(), "Configured serverAddress is null.");
269267

270268
return new AuthConfig()
271269
.withUsername(dockerClientConfig.getRegistryUsername())

docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.fasterxml.jackson.databind.ObjectMapper;
66
import com.github.dockerjava.api.model.AuthConfig;
77
import com.github.dockerjava.api.model.AuthConfigurations;
8+
import java.util.Objects;
89
import org.apache.commons.io.FileUtils;
910
import org.apache.commons.lang3.StringUtils;
1011

@@ -29,6 +30,9 @@ public class DockerConfigFile {
2930
@JsonProperty
3031
private final Map<String, AuthConfig> auths;
3132

33+
@JsonProperty
34+
private String currentContext;
35+
3236
public DockerConfigFile() {
3337
this(new HashMap<>());
3438
}
@@ -46,6 +50,14 @@ void addAuthConfig(AuthConfig config) {
4650
auths.put(config.getRegistryAddress(), config);
4751
}
4852

53+
void setCurrentContext(String currentContext) {
54+
this.currentContext = currentContext;
55+
}
56+
57+
public String getCurrentContext() {
58+
return currentContext;
59+
}
60+
4961
@CheckForNull
5062
public AuthConfig resolveAuthConfig(@CheckForNull String hostname) {
5163
if (StringUtils.isEmpty(hostname) || AuthConfig.DEFAULT_SERVER_ADDRESS.equals(hostname)) {
@@ -104,14 +116,17 @@ public boolean equals(Object obj) {
104116
return false;
105117
} else if (!auths.equals(other.auths))
106118
return false;
119+
if (!Objects.equals(currentContext, other.currentContext)) {
120+
return false;
121+
}
107122
return true;
108123
}
109124

110125
// CHECKSTYLE:ON
111126

112127
@Override
113128
public String toString() {
114-
return "DockerConfigFile [auths=" + auths + "]";
129+
return "DockerConfigFile [auths=" + auths + ", currentContext='" + currentContext + "']";
115130
}
116131

117132
@Nonnull

0 commit comments

Comments
 (0)