Skip to content

Commit

Permalink
Set --user on exec
Browse files Browse the repository at this point in the history
  • Loading branch information
ndeloof authored and diorcety committed May 27, 2021
1 parent b174d46 commit 1ec100b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
package org.jenkinsci.plugins.docker.workflow;

import com.google.common.base.Optional;
import hudson.util.ArgumentListBuilder;
import com.google.inject.Inject;
import hudson.AbortException;
import hudson.EnvVars;
Expand Down Expand Up @@ -194,8 +195,9 @@ public Execution() {
volumes.put(tmp, tmp);
}

final String userId = dockerClient.whoAmI();
String command = launcher.isUnix() ? "cat" : "cmd.exe";
container = dockerClient.run(env, step.image, step.args, ws, volumes, volumesFromContainers, envReduced, dockerClient.whoAmI(), /* expected to hang until killed */ command);
container = dockerClient.run(env, step.image, step.args, ws, volumes, volumesFromContainers, envReduced, userId, /* expected to hang until killed */ command);
final List<String> ps = dockerClient.listProcess(env, container);
if (!ps.contains(command)) {
listener.error(
Expand All @@ -207,7 +209,7 @@ public Execution() {

ImageAction.add(step.image, run);
getContext().newBodyInvoker().
withContext(BodyInvoker.mergeLauncherDecorators(getContext().get(LauncherDecorator.class), new Decorator(container, envHost, ws, toolName, dockerVersion))).
withContext(BodyInvoker.mergeLauncherDecorators(getContext().get(LauncherDecorator.class), new Decorator(container, envHost, ws, userId, toolName, dockerVersion))).
withCallback(new Callback(container, toolName)).
start();
return false;
Expand Down Expand Up @@ -242,17 +244,19 @@ private static class Decorator extends LauncherDecorator implements Serializable
private final String container;
private final String[] envHost;
private final String ws;
private final String user;
private final @CheckForNull String toolName;
private final boolean hasEnv;
private final boolean hasWorkdir;

Decorator(String container, EnvVars envHost, String ws, String toolName, VersionNumber dockerVersion) {
Decorator(String container, EnvVars envHost, String ws, String user, String toolName, VersionNumber dockerVersion) {
this.container = container;
this.envHost = Util.mapToEnv(envHost);
this.ws = ws;
this.toolName = toolName;
this.hasEnv = dockerVersion != null && dockerVersion.compareTo(new VersionNumber("1.13.0")) >= 0;
this.hasWorkdir = dockerVersion != null && dockerVersion.compareTo(new VersionNumber("17.12")) >= 0;
this.user = user;
}

@Override public Launcher decorate(final Launcher launcher, final Node node) {
Expand All @@ -264,8 +268,15 @@ private static class Decorator extends LauncherDecorator implements Serializable
} catch (InterruptedException x) {
throw new IOException(x);
}

List<String> prefix = new ArrayList<>(Arrays.asList(executable, "exec"));
List<Boolean> masksPrefixList = new ArrayList<>(Arrays.asList(false, false));
if (user != null) {
prefix.add("-u");
masksPrefixList.add(false);
prefix.add(user);
masksPrefixList.add(false);
}
if (ws != null) {
FilePath cwd = starter.pwd();
if (cwd != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public DockerClient(@Nonnull Launcher launcher, @CheckForNull Node node, @CheckF
* @param command The command to execute in the image container being run.
* @return The container ID.
*/
public String run(@Nonnull EnvVars launchEnv, @Nonnull String image, @CheckForNull String args, @CheckForNull String workdir, @Nonnull Map<String, String> volumes, @Nonnull Collection<String> volumesFromContainers, @Nonnull EnvVars containerEnv, @Nonnull String user, @Nonnull String... command) throws IOException, InterruptedException {
public String run(@Nonnull EnvVars launchEnv, @Nonnull String image, @CheckForNull String args, @CheckForNull String workdir, @Nonnull Map<String, String> volumes, @Nonnull Collection<String> volumesFromContainers, @Nonnull EnvVars containerEnv, @CheckForNull String user, @Nonnull String... command) throws IOException, InterruptedException {
ArgumentListBuilder argb = new ArgumentListBuilder();

argb.add("run", "-t", "-d");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ public WindowsDockerClient(@Nonnull Launcher launcher, @CheckForNull Node node,
}

@Override
public String run(@Nonnull EnvVars launchEnv, @Nonnull String image, @CheckForNull String args, @CheckForNull String workdir, @Nonnull Map<String, String> volumes, @Nonnull Collection<String> volumesFromContainers, @Nonnull EnvVars containerEnv, @Nonnull String user, @Nonnull String... command) throws IOException, InterruptedException {
public String run(@Nonnull EnvVars launchEnv, @Nonnull String image, @CheckForNull String args, @CheckForNull String workdir, @Nonnull Map<String, String> volumes, @Nonnull Collection<String> volumesFromContainers, @Nonnull EnvVars containerEnv, @CheckForNull String user, @Nonnull String... command) throws IOException, InterruptedException {
ArgumentListBuilder argb = new ArgumentListBuilder("docker", "run", "-d", "-t");
if (args != null) {
argb.addTokenized(args);
}

if (workdir != null) {
argb.add("-w", workdir);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,52 @@ public class WithContainerStepTest {
});
}

@Test public void withInitAndExecAsUser() throws Exception {
story.addStep(new Statement() {
@Override
public void evaluate() throws Throwable {
DockerTestUtil.assumeDocker();
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "prj");
p.setDefinition(new CpsFlowDefinition(
"node {\n" +
" def gid = sh(script: 'id -g', returnStdout: true).trim()\n" +
" def uid = sh(script: 'id -u', returnStdout: true).trim()\n" +
" def gname = sh(script: 'id -g -n', returnStdout: true).trim()\n" +
" def uname = sh(script: 'id -u -n', returnStdout: true).trim()\n" +
" def args = \"-e BUILDER_UID=${uid} -e BUILDER_GID=${gid} -e BUILDER_USER=${uname} -e BUILDER_GROUP=${gname} -e HOME=${HOME}\"\n" +
" withDockerContainer(args: args, image: 'dockcross/base:latest') {\n" +
" sh 'sleep 2 && touch ${HOME}/test && id'\n" +
" }\n" +
"}", true));
WorkflowRun b = story.j.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0));
}
});
}

@Test public void withInitAsRootAndExecAsUser() throws Exception {
story.addStep(new Statement() {
@Override
public void evaluate() throws Throwable {
DockerTestUtil.assumeDocker();
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "prj");
p.setDefinition(new CpsFlowDefinition(
"node {\n" +
" def gid = sh(script: 'id -g', returnStdout: true).trim()\n" +
" def uid = sh(script: 'id -u', returnStdout: true).trim()\n" +
" def gname = sh(script: 'id -g -n', returnStdout: true).trim()\n" +
" def uname = sh(script: 'id -u -n', returnStdout: true).trim()\n" +
" def args = \"-u root:root -e BUILDER_UID=${uid} -e BUILDER_GID=${gid} -e BUILDER_USER=${uname} -e BUILDER_GROUP=${gname} -e HOME=${HOME}\"\n" +
" withDockerContainer(args: args, image: 'dockcross/base:latest') {\n" +
" sh 'sleep 2 && touch ${HOME}/test && id'\n" +
" }\n" +
"}", true));
WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0).get());
story.j.assertLogContains("uid=1000", b);
}
});
}


@Issue("JENKINS-27152")
@Test public void configFile() throws Exception {
story.addStep(new Statement() {
Expand Down

0 comments on commit 1ec100b

Please sign in to comment.