Skip to content

Commit 0494737

Browse files
committed
Fix #12413: Docker: auto pull image + private registry support
1 parent e6de165 commit 0494737

3 files changed

Lines changed: 97 additions & 8 deletions

File tree

pom.xml

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,14 +240,29 @@
240240
</dependency>
241241
<!-- Jersey, a dependency of docker-client with wonky version constraints -->
242242
<dependency>
243-
<groupId>org.glassfish.jersey.inject</groupId>
244-
<artifactId>jersey-hk2</artifactId>
245-
<version>2.26</version>
243+
<groupId>org.glassfish.jersey.core</groupId>
244+
<artifactId>jersey-client</artifactId>
245+
<version>2.22</version>
246246
</dependency>
247247
<dependency>
248-
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
249-
<artifactId>jersey-guava</artifactId>
250-
<version>2.26-b03</version>
248+
<groupId>org.glassfish.jersey.core</groupId>
249+
<artifactId>jersey-common</artifactId>
250+
<version>2.22</version>
251+
</dependency>
252+
<dependency>
253+
<groupId>org.glassfish.jersey.connectors</groupId>
254+
<artifactId>jersey-apache-connector</artifactId>
255+
<version>2.22</version>
256+
</dependency>
257+
<dependency>
258+
<groupId>org.glassfish.jersey.media</groupId>
259+
<artifactId>jersey-media-json-jackson</artifactId>
260+
<version>2.22</version>
261+
</dependency>
262+
<dependency>
263+
<groupId>org.glassfish.hk2</groupId>
264+
<artifactId>hk2-api</artifactId>
265+
<version>2.4.0-b31</version>
251266
</dependency>
252267

253268
<!-- MonetDB, for gathering usage stats (optional) -->

src/main/java/eu/openanalytics/containerproxy/backend/docker/DockerEngineBackend.java

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@
2222

2323
import com.spotify.docker.client.DockerClient.ListContainersParam;
2424
import com.spotify.docker.client.DockerClient.RemoveContainerParam;
25+
import com.spotify.docker.client.ProgressHandler;
26+
import com.spotify.docker.client.exceptions.DockerException;
27+
import com.spotify.docker.client.exceptions.NotFoundException;
2528
import com.spotify.docker.client.messages.Container.PortMapping;
2629
import com.spotify.docker.client.messages.ContainerConfig;
2730
import com.spotify.docker.client.messages.ContainerCreation;
2831
import com.spotify.docker.client.messages.ContainerInfo;
2932
import com.spotify.docker.client.messages.HostConfig;
3033
import com.spotify.docker.client.messages.HostConfig.Builder;
3134
import com.spotify.docker.client.messages.PortBinding;
35+
import com.spotify.docker.client.messages.ProgressMessage;
36+
import com.spotify.docker.client.messages.RegistryAuth;
3237
import eu.openanalytics.containerproxy.model.runtime.Container;
3338
import eu.openanalytics.containerproxy.model.runtime.ExistingContainerInfo;
3439
import eu.openanalytics.containerproxy.model.runtime.Proxy;
@@ -37,6 +42,8 @@
3742
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.RuntimeValueKey;
3843
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.UserIdKey;
3944
import eu.openanalytics.containerproxy.model.spec.ContainerSpec;
45+
import org.slf4j.Logger;
46+
import org.slf4j.LoggerFactory;
4047

4148
import java.net.URI;
4249
import java.net.URL;
@@ -49,10 +56,27 @@
4956

5057
public class DockerEngineBackend extends AbstractDockerBackend {
5158

59+
private static final String PROPERTY_IMG_PULL_POLICY = "image-pull-policy";
60+
61+
private ImagePullPolicy imagePullPolicy;
62+
private final Logger logger = LoggerFactory.getLogger(getClass());
63+
64+
@Override
65+
public void initialize() {
66+
super.initialize();
67+
imagePullPolicy = environment.getProperty(getPropertyPrefix() + PROPERTY_IMG_PULL_POLICY, ImagePullPolicy.class, ImagePullPolicy.IfNotPresent);
68+
}
69+
5270
@Override
5371
protected Container startContainer(ContainerSpec spec, Proxy proxy) throws Exception {
5472
Builder hostConfigBuilder = HostConfig.builder();
55-
73+
74+
if (imagePullPolicy == ImagePullPolicy.Always
75+
|| (imagePullPolicy == ImagePullPolicy.IfNotPresent && !isImagePresent(spec))) {
76+
logger.info("Pulling image {}", spec.getImage());
77+
pullImage(spec);
78+
}
79+
5680
Map<String, List<PortBinding>> portBindings = new HashMap<>();
5781
if (isUseInternalNetwork()) {
5882
// In internal networking mode, we can access container ports directly, no need to bind on host.
@@ -203,6 +227,36 @@ public List<ExistingContainerInfo> scanExistingContainers() throws Exception {
203227

204228
return containers;
205229
}
206-
230+
231+
private boolean isImagePresent(ContainerSpec spec) throws DockerException, InterruptedException {
232+
try {
233+
dockerClient.inspectImage(spec.getImage());
234+
return true;
235+
} catch (NotFoundException ex) {
236+
return false;
237+
}
238+
}
239+
240+
private void pullImage(ContainerSpec spec) throws DockerException, InterruptedException {
241+
if (spec.getDockerSwarmRegistryDomain() != null
242+
&& spec.getDockerSwarmRegistryUsername() != null
243+
&& spec.getDockerSwarmRegistryPassword() != null) {
244+
245+
RegistryAuth registryAuth = RegistryAuth.builder()
246+
.serverAddress(spec.getDockerSwarmRegistryDomain())
247+
.username(spec.getDockerSwarmRegistryUsername())
248+
.password(spec.getDockerSwarmRegistryPassword())
249+
.build();
250+
dockerClient.pull(spec.getImage(), registryAuth, message -> {});
251+
} else {
252+
dockerClient.pull(spec.getImage(), message -> {});
253+
}
254+
}
255+
256+
public enum ImagePullPolicy {
257+
Never,
258+
Always,
259+
IfNotPresent
260+
}
207261

208262
}

src/test/java/eu/openanalytics/containerproxy/test/proxy/TestIntegrationOnSwarm.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2021 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
121
package eu.openanalytics.containerproxy.test.proxy;
222

323
import com.spotify.docker.client.DefaultDockerClient;

0 commit comments

Comments
 (0)