Skip to content

Commit 4e271bf

Browse files
committed
Fix host directory mounts on Windows
On Windows, it is not possible to mount host directories to a subfolder of a non-C: drive. Due to this restriction, having a workspace on another drive will make the docker run execution fail since the plugin tries to map the workspace into the container. This fixes that by collecting all the non-C: drive volume mappings and handling those explicitly by mapping the entire drive into the container.
1 parent b174d46 commit 4e271bf

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

src/main/java/org/jenkinsci/plugins/docker/workflow/client/WindowsDockerClient.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
import javax.annotation.Nonnull;
1313
import java.io.*;
1414
import java.nio.charset.Charset;
15+
import java.nio.file.InvalidPathException;
16+
import java.nio.file.Path;
17+
import java.nio.file.Paths;
1518
import java.util.*;
1619
import java.util.concurrent.TimeUnit;
1720
import java.util.logging.Level;
@@ -39,8 +42,38 @@ public String run(@Nonnull EnvVars launchEnv, @Nonnull String image, @CheckForNu
3942
if (workdir != null) {
4043
argb.add("-w", workdir);
4144
}
45+
Set<String> drives = new HashSet<>();
4246
for (Map.Entry<String, String> volume : volumes.entrySet()) {
43-
argb.add("-v", volume.getKey() + ":" + volume.getValue());
47+
String driveName = null;
48+
49+
try {
50+
Path hostPath = Paths.get(volume.getKey());
51+
Path rootPath = hostPath.getRoot();
52+
// If we have a valid root we can check if we need to do our special root handling
53+
if (rootPath != null) {
54+
driveName = rootPath.toString();
55+
if (driveName.endsWith("\\")) {
56+
driveName = driveName.substring(0, driveName.length() - 1);
57+
}
58+
}
59+
} catch (InvalidPathException e) {
60+
// We got a value that is not a valid path. Keeping driveName at null allows us to gracefully handle this
61+
// and skip the special drive path handling for those cases
62+
}
63+
if (driveName == null || driveName.equals("C:")) {
64+
// C: path can be mapped directly
65+
argb.add("-v", volume.getKey() + ":" + volume.getValue());
66+
}
67+
else
68+
{
69+
// Non C: drive paths in the container can not be mapped due to Windows limitations. It is only possible
70+
// to map an entire drive so we collect the used drives and map the entire drive
71+
drives.add(driveName);
72+
}
73+
}
74+
for (String drive : drives) {
75+
// Windows requires that the host part is a directory but the container path must be an entire drive
76+
argb.add("-v", String.format("%s\\:%s", drive, drive));
4477
}
4578
for (String containerId : volumesFromContainers) {
4679
argb.add("--volumes-from", containerId);

0 commit comments

Comments
 (0)