Skip to content
This repository was archived by the owner on Jan 17, 2024. It is now read-only.

Commit 60c669b

Browse files
authored
Merge pull request #27 from raydouglass/docker-19
[REVIEW] Detect and use gpu flag
2 parents a70ea9a + 662a590 commit 60c669b

File tree

4 files changed

+163
-7
lines changed

4 files changed

+163
-7
lines changed

src/main/java/com/gpuopenanalytics/jenkins/remotedocker/DockerLauncher.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public class DockerLauncher extends Launcher {
6060
private TaskListener listener;
6161
private RemoteDockerBuildWrapper buildWrapper;
6262
private AbstractBuild build;
63+
private DockerVersion version;
6364

6465
private transient Optional<DockerNetwork> network = Optional.empty();
6566
private transient List<String> containerIds = new ArrayList<>();
@@ -84,6 +85,12 @@ public DockerLauncher(boolean debug,
8485
this.delegate = delegate;
8586
this.listener = listener;
8687
this.buildWrapper = buildWrapper;
88+
try {
89+
this.version = parseVersion();
90+
getListener().getLogger().println(this.version);
91+
} catch (IOException | InterruptedException e) {
92+
throw new RuntimeException(e);
93+
}
8794
}
8895

8996
@Override
@@ -339,4 +346,32 @@ public AbstractBuild getBuild() {
339346
public boolean isDebug() {
340347
return debug;
341348
}
349+
350+
public DockerVersion getVersion() {
351+
return version;
352+
}
353+
354+
private DockerVersion parseVersion() throws IOException, InterruptedException {
355+
ArgumentListBuilder args = new ArgumentListBuilder("docker",
356+
"--version");
357+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
358+
int status = executeCommand(args)
359+
.stdout(baos)
360+
.stderr(getListener().getLogger())
361+
.join();
362+
363+
if (status != 0) {
364+
throw new IOException("Could not get docker version");
365+
}
366+
String versionString = baos.toString(StandardCharsets.UTF_8.name())
367+
.trim();
368+
try {
369+
return DockerVersion.fromVersionString(versionString);
370+
} catch (DockerVersion.VersionParseException e) {
371+
getListener().getLogger().println(
372+
"WARN - Could not parse docker version");
373+
e.printStackTrace(getListener().getLogger());
374+
return DockerVersion.DEFAULT;
375+
}
376+
}
342377
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2020, NVIDIA CORPORATION.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
package com.gpuopenanalytics.jenkins.remotedocker;
26+
27+
import java.io.Serializable;
28+
29+
public class DockerVersion implements Serializable {
30+
31+
public static final DockerVersion DEFAULT = new DockerVersion(0, 0, 0, null,
32+
"0");
33+
34+
private int major;
35+
private int minor;
36+
private int patch;
37+
private String extra;
38+
private String build;
39+
40+
private DockerVersion(int major,
41+
int minor,
42+
int patch,
43+
String extra,
44+
String build) {
45+
this.major = major;
46+
this.minor = minor;
47+
this.patch = patch;
48+
this.extra = extra;
49+
this.build = build;
50+
}
51+
52+
/**
53+
* Parse from output of <code>docker --version</code> such as <code>Docker
54+
* version 19.03.5, build 633a0ea</code>
55+
*
56+
* @return
57+
*/
58+
public static DockerVersion fromVersionString(String versionString) throws VersionParseException {
59+
try {
60+
String[] split = versionString.split("\\s");
61+
String build = split[split.length - 1];
62+
String[] version = split[2].substring(0, split[2].length() - 1)
63+
.split(
64+
"\\.");
65+
int major = Integer.parseInt(version[0]);
66+
int minor = Integer.parseInt(version[1]);
67+
int patch = 0;
68+
String extra = null;
69+
if (version[2].contains("-")) {
70+
patch = Integer.parseInt(
71+
version[2].substring(0, version[2].indexOf('-')));
72+
extra = version[2].substring(version[2].indexOf('-') + 1);
73+
} else {
74+
patch = Integer.parseInt(version[2]);
75+
}
76+
return new DockerVersion(major, minor, patch, extra, build);
77+
} catch (Exception e) {
78+
throw new VersionParseException(versionString, e);
79+
}
80+
}
81+
82+
public String getVersionString() {
83+
return String.format("%02d.%02d.%d", major, minor, patch);
84+
}
85+
86+
public boolean hasGpuFlag() {
87+
return "19.03.0".compareTo(getVersionString()) < 0;
88+
}
89+
90+
public String toString() {
91+
if (extra != null) {
92+
return String.format("Docker version %s-%s, build %s",
93+
getVersionString(),
94+
extra,
95+
build);
96+
} else {
97+
return String.format("Docker version %s, build %s",
98+
getVersionString(),
99+
build);
100+
}
101+
}
102+
103+
public static class VersionParseException extends Exception {
104+
105+
public VersionParseException(String version, Throwable cause) {
106+
super(String.format("Could not parse '%s'", version), cause);
107+
}
108+
}
109+
}

src/main/java/com/gpuopenanalytics/jenkins/remotedocker/config/DockerRuntimeConfigItem.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,15 @@ public void validate() throws Descriptor.FormException {
6161
public void addCreateArgs(DockerLauncher launcher,
6262
ArgumentListBuilder args,
6363
AbstractBuild build) {
64-
args.addKeyValuePair("", "--runtime", getResolvedValue(launcher), false);
64+
String runtime = getResolvedValue(launcher);
65+
if (!launcher.getVersion().hasGpuFlag() || !"nvidia".equals(runtime)) {
66+
//If the runtime is nvidia, but the version supports --gpus, ignore the runtime
67+
args.addKeyValuePair("", "--runtime", runtime,
68+
false);
69+
} else {
70+
launcher.getListener().getLogger().println(
71+
"WARN Runtime is 'nvidia', but docker version supports --gpus. Ignoring 'nvidia' runtime.");
72+
}
6573
}
6674

6775
@Extension

src/main/java/com/gpuopenanalytics/jenkins/remotedocker/config/NvidiaGpuDevicesConfigItem.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,23 @@ public void validate() throws Descriptor.FormException {
7070
public void addCreateArgs(DockerLauncher launcher,
7171
ArgumentListBuilder args,
7272
AbstractBuild build) {
73-
args.add("-e");
73+
String value;
7474
if ("executor".equals(getValue())) {
7575
try {
76-
String index = build.getEnvironment(launcher.getListener())
76+
value = build.getEnvironment(launcher.getListener())
7777
.get("EXECUTOR_NUMBER", null);
78-
args.addKeyValuePair("", ENV_VAR_NAME, index,
79-
false);
8078
} catch (IOException | InterruptedException e) {
8179
throw new RuntimeException(e);
8280
}
8381
} else {
84-
args.addKeyValuePair("", ENV_VAR_NAME, getResolvedValue(launcher),
85-
false);
82+
value = getResolvedValue(launcher);
83+
}
84+
85+
if (launcher.getVersion().hasGpuFlag()) {
86+
args.add("--gpus", value);
87+
} else {
88+
args.add("-e");
89+
args.addKeyValuePair("", ENV_VAR_NAME, value, false);
8690
}
8791
}
8892

0 commit comments

Comments
 (0)