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) {