Fix for docker strategy GID clash.
Fixes https://github.com/bazelbuild/bazel/issues/17535
PiperOrigin-RevId: 516200807
Change-Id: I29888a79869a7a0a6b404a2c689e9d608978ce4e
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
index 3e7dbc3..ef01b76 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
@@ -335,34 +335,47 @@
.getRelative(execRoot.getBaseName())
.getPathString();
StringBuilder dockerfile = new StringBuilder();
- dockerfile.append(String.format("FROM %s\n", image));
- dockerfile.append(String.format("RUN [\"mkdir\", \"-p\", \"%s\"]\n", workDir));
- // TODO(philwo) this will fail if a user / group with the given uid / gid already
- // exists
- // in the container. For now this seems reasonably unlikely, but we'll have to come up
- // with a better way.
- if (gid > 0) {
- dockerfile.append(
- String.format("RUN [\"groupadd\", \"-g\", \"%d\", \"bazelbuild\"]\n", gid));
- }
- if (uid > 0) {
- dockerfile.append(
- String.format(
- "RUN [\"useradd\", \"-l\", \"-m\", \"-g\", \"%d\", \"-d\", \"%s\", \"-N\","
- + " \"-u\", \"%d\", \"bazelbuild\"]\n",
- gid, workDir, uid));
- }
+ dockerfile.append("ARG image\n");
+ dockerfile.append("FROM $image\n");
+ dockerfile.append("ARG work_dir\n");
+ dockerfile.append("RUN mkdir --parents $work_dir\n"); // could this be a VOLUME?
+ dockerfile.append("ARG group_name\n");
+ dockerfile.append("ARG gid\n");
+ dockerfile.append("RUN groupadd --non-unique --gid $gid $group_name\n");
+ dockerfile.append("ARG user_name\n");
+ dockerfile.append("ARG uid\n");
dockerfile.append(
- String.format("RUN [\"chown\", \"-R\", \"%d:%d\", \"%s\"]\n", uid, gid, workDir));
- dockerfile.append(String.format("USER %d:%d\n", uid, gid));
- dockerfile.append(String.format("ENV HOME %s\n", workDir));
- if (uid > 0) {
- dockerfile.append(String.format("ENV USER bazelbuild\n"));
- }
- dockerfile.append(String.format("WORKDIR %s\n", workDir));
+ "RUN useradd --non-unique --no-log-init --create-home --gid $gid --home-dir"
+ + " $work_dir --no-user-group --uid"
+ + " $uid"
+ + " $user_name\n"); // we've already created home above?
+ dockerfile.append(
+ "RUN chown --recursive $uid:$gid $work_dir\n"); // if we create home with useradd
+ // it'd already have the right
+ // ownership
+ dockerfile.append("USER $user_name:$group_name\n");
+ dockerfile.append("ENV HOME $work_dir\n");
+ dockerfile.append("ENV USER $user_name\n");
+ dockerfile.append("WORKDIR $work_dir\n");
try {
return executeCommand(
- ImmutableList.of(dockerClient.getPathString(), "build", "-q", "-"),
+ ImmutableList.of(
+ dockerClient.getPathString(),
+ "build",
+ "--build-arg",
+ String.format("image=%s", image),
+ "--build-arg",
+ String.format("work_dir=%s", workDir),
+ "--build-arg",
+ String.format("group_name=%s", "bazelbuild"),
+ "--build-arg",
+ String.format("gid=%d", gid),
+ "--build-arg",
+ String.format("user_name=%s", "bazelbuild"),
+ "--build-arg",
+ String.format("uid=%d", uid),
+ "-q",
+ "-"),
new ByteArrayInputStream(
dockerfile.toString().getBytes(Charset.defaultCharset())));
} catch (UserExecException e) {