Skip to content
Permalink
Browse files

Merge pull request #33 from jglick/temp-dir-JENKINS-27152

[JENKINS-27152] Mount workspace@tmp
  • Loading branch information
jglick committed Mar 4, 2016
2 parents b60bb77 + 8721364 commit 2312931df9030b814fed6522e931762f1a93e433
34 pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.596.1</version>
<version>2.3</version>
</parent>
<artifactId>docker-workflow</artifactId>
<version>1.4-SNAPSHOT</version>
@@ -28,8 +28,9 @@
</scm>

<properties>
<workflow.version>1.7</workflow.version>
<maven-hpi-plugin.version>1.112</maven-hpi-plugin.version>
<jenkins.version>1.609.3</jenkins.version>
<java.level>6</java.level>
<workflow.version>1.13</workflow.version>
</properties>
<repositories>
<repository>
@@ -52,7 +53,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>script-security</artifactId>
<version>1.14</version>
<version>1.17</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
@@ -103,18 +104,17 @@
<version>${workflow.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials-binding</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>config-file-provider</artifactId>
<version>2.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<xmlOutput>true</xmlOutput>
<failOnError>false</failOnError>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -69,8 +69,7 @@

}

// TODO use BodyExecutionCallback.TailCall from https://github.com/jenkinsci/workflow-plugin/pull/168
private static class Callback extends BodyExecutionCallback {
private static class Callback extends BodyExecutionCallback.TailCall {

private static final long serialVersionUID = 1;
private final KeyMaterial material;
@@ -79,24 +78,14 @@
this.material = material;
}

private void close() {
@Override protected void finished(StepContext context) throws Exception {
try {
material.close();
} catch (IOException x) {
Logger.getLogger(AbstractEndpointStepExecution.class.getName()).log(Level.WARNING, null, x);
}
}

@Override public void onSuccess(StepContext context, Object result) {
close();
context.onSuccess(result);
}

@Override public void onFailure(StepContext context, Throwable t) {
close();
context.onFailure(t);
}

}

}
@@ -55,14 +55,7 @@ public MiscWhitelist() throws IOException {
super(new StaticWhitelist(
// TODO should docker-commons just get a script-security dependency and mark these things @Whitelisted?
"new org.jenkinsci.plugins.docker.commons.credentials.DockerRegistryEndpoint java.lang.String java.lang.String",
"method org.jenkinsci.plugins.docker.commons.credentials.DockerRegistryEndpoint imageName java.lang.String",
// TODO delete after using https://github.com/jenkinsci/script-security-plugin/pull/15
"method java.util.concurrent.Callable call",
"method groovy.lang.Closure call java.lang.Object",
"method java.lang.Object toString",
"method java.lang.String trim",
"staticMethod org.codehaus.groovy.runtime.ScriptBytecodeAdapter compareNotEqual java.lang.Object java.lang.Object",
"staticMethod org.codehaus.groovy.runtime.ScriptBytecodeAdapter compareEqual java.lang.Object java.lang.Object"));
"method org.jenkinsci.plugins.docker.commons.credentials.DockerRegistryEndpoint imageName java.lang.String"));
}
}

@@ -37,13 +37,13 @@
import hudson.model.Node;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.slaves.WorkspaceList;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -53,6 +53,7 @@
import javax.annotation.Nonnull;

import hudson.util.VersionNumber;
import java.util.LinkedHashMap;
import org.jenkinsci.plugins.docker.commons.fingerprint.DockerFingerprints;
import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractStepExecutionImpl;
@@ -135,7 +136,13 @@ private static void destroy(String container, Launcher launcher, Node node, EnvV
listener.error("Failed to parse docker version. Please note there is a minimum docker version requirement of v1.3.");
}

container = dockerClient.run(env, step.image, step.args, ws, Collections.singletonMap(ws, ws), envReduced, dockerClient.whoAmI(), /* expected to hang until killed */ "cat");
Map<String,String> volumes = new LinkedHashMap<String,String>();
volumes.put(ws, ws);
FilePath tempDir = tempDir(workspace);
tempDir.mkdirs();
String tmp = tempDir.getRemote();
volumes.put(tmp, tmp);
container = dockerClient.run(env, step.image, step.args, ws, volumes, envReduced, dockerClient.whoAmI(), /* expected to hang until killed */ "cat");
DockerFingerprints.addRunFacet(dockerClient.getContainerRecord(env, container), run);
ImageAction.add(step.image, run);
getContext().newBodyInvoker().
@@ -145,6 +152,11 @@ private static void destroy(String container, Launcher launcher, Node node, EnvV
return false;
}

// TODO use 1.652 use WorkspaceList.tempDir
private static FilePath tempDir(FilePath ws) {
return ws.sibling(ws.getName() + System.getProperty(WorkspaceList.class.getName(), "@") + "tmp");
}

@Override public void stop(@Nonnull Throwable cause) throws Exception {
if (container != null) {
LOGGER.log(Level.FINE, "stopping container " + container, cause);
@@ -45,8 +45,6 @@
import org.jenkinsci.plugins.docker.commons.fingerprint.DockerDescendantFingerprintFacet;
import org.jenkinsci.plugins.docker.commons.fingerprint.DockerFingerprints;
import org.jenkinsci.plugins.docker.commons.fingerprint.DockerRunFingerprintFacet;
import org.jenkinsci.plugins.workflow.BuildWatcher;
import org.jenkinsci.plugins.workflow.JenkinsRuleExt;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
@@ -57,6 +55,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.RestartableJenkinsRule;

public class DockerDSLTest {
@@ -80,7 +79,7 @@
WorkflowRun b = p.getLastBuild();
assertEquals(Collections.<String>emptySet(), grep(b.getRootDir(), "org.jenkinsci.plugins.docker.workflow.Docker"));
SemaphoreStep.success("wait/1", null);
story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b));
story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b));
}
});
}
@@ -126,7 +125,7 @@ private static void grep(File dir, String text, String prefix, Set<String> match
SemaphoreStep.success("wait/1", null);
WorkflowJob p = story.j.jenkins.getItemByFullName("prj", WorkflowJob.class);
WorkflowRun b = p.getLastBuild();
story.j.assertLogContains("Require method GET POST OPTIONS", story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b)));
story.j.assertLogContains("Require method GET POST OPTIONS", story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b)));
story.j.assertLogContains("the answer is 42", b);
DockerClient client = new DockerClient(new Launcher.LocalLauncher(StreamTaskListener.NULL), null, null);
String httpdIID = client.inspect(new EnvVars(), "httpd:2.4.12", ".Id");
@@ -162,7 +161,7 @@ private static void grep(File dir, String text, String prefix, Set<String> match
@Override public void evaluate() throws Throwable {
SemaphoreStep.success("wait/1", null);
WorkflowJob p = story.j.jenkins.getItemByFullName("prj", WorkflowJob.class);
WorkflowRun b = story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(p.getLastBuild()));
WorkflowRun b = story.j.assertBuildStatusSuccess(story.j.waitForCompletion(p.getLastBuild()));
story.j.assertLogContains("would be connecting to tcp://host:1234", b);
story.j.assertLogContains("image name is docker.my.com/whatever", b);
}
@@ -209,7 +208,7 @@ private static void grep(File dir, String text, String prefix, Set<String> match
SemaphoreStep.success("wait/1", null);
WorkflowJob p = story.j.jenkins.getItemByFullName("prj", WorkflowJob.class);
WorkflowRun b = p.getLastBuild();
story.j.assertLogContains("Require method GET POST OPTIONS", story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b)));
story.j.assertLogContains("Require method GET POST OPTIONS", story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b)));
story.j.assertLogContains("the answer is 42", b);
DockerClient client = new DockerClient(new Launcher.LocalLauncher(StreamTaskListener.NULL), null, null);
String httpdIID = client.inspect(new EnvVars(), "httpd:2.4.12", ".Id");
@@ -32,7 +32,6 @@
import java.util.Map;
import java.util.TreeMap;
import org.jenkinsci.plugins.docker.commons.credentials.DockerRegistryEndpoint;
import org.jenkinsci.plugins.workflow.BuildWatcher;
import org.jenkinsci.plugins.workflow.steps.StepConfigTester;
import org.jenkinsci.plugins.workflow.structs.DescribableHelper;
import static org.junit.Assert.assertEquals;
@@ -41,6 +40,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.RestartableJenkinsRule;

public class RegistryEndpointStepTest {
@@ -32,8 +32,6 @@
import java.util.TreeMap;
import org.jenkinsci.plugins.docker.commons.credentials.DockerServerCredentials;
import org.jenkinsci.plugins.docker.commons.credentials.DockerServerEndpoint;
import org.jenkinsci.plugins.workflow.BuildWatcher;
import org.jenkinsci.plugins.workflow.JenkinsRuleExt;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
@@ -45,6 +43,7 @@
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.RestartableJenkinsRule;

public class ServerEndpointStepTest {
@@ -93,7 +92,7 @@
SemaphoreStep.success("wait/1", null);
WorkflowJob p = story.j.jenkins.getItemByFullName("prj", WorkflowJob.class);
WorkflowRun b = p.getLastBuild();
story.j.assertLogContains("would be connecting to tcp://host:1234", story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b)));
story.j.assertLogContains("would be connecting to tcp://host:1234", story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b)));
}
});
}
@@ -23,27 +23,41 @@
*/
package org.jenkinsci.plugins.docker.workflow;

import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.CredentialsScope;
import com.cloudbees.plugins.credentials.domains.Domain;
import hudson.model.FileParameterValue;
import hudson.model.Result;
import hudson.tools.ToolProperty;
import java.io.File;
import java.util.Collections;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FileUtils;
import org.jenkinsci.lib.configprovider.ConfigProvider;
import org.jenkinsci.lib.configprovider.model.Config;
import org.jenkinsci.plugins.configfiles.custom.CustomConfig;
import org.jenkinsci.plugins.docker.commons.tools.DockerTool;
import org.jenkinsci.plugins.workflow.BuildWatcher;
import org.jenkinsci.plugins.workflow.JenkinsRuleExt;
import org.jenkinsci.plugins.plaincredentials.impl.FileCredentialsImpl;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.steps.StepConfigTester;
import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.RestartableJenkinsRule;

public class WithContainerStepTest {

@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public RestartableJenkinsRule story = new RestartableJenkinsRule();
@Rule public TemporaryFolder tmp = new TemporaryFolder();

@Test public void configRoundTrip() {
story.addStep(new Statement() {
@@ -88,9 +102,9 @@
" }\n" +
"}", true));
WorkflowRun b = p.scheduleBuild2(0).waitForStart();
JenkinsRuleExt.waitForMessage("sleeping now", b);
story.j.waitForMessage("sleeping now", b);
b.doStop();
story.j.assertBuildStatus(Result.ABORTED, JenkinsRuleExt.waitForCompletion(b));
story.j.assertBuildStatus(Result.ABORTED, story.j.waitForCompletion(b));
story.j.assertLogContains("script returned exit code 99", b);
}
});
@@ -134,7 +148,69 @@
SemaphoreStep.success("wait/1", null);
WorkflowJob p = story.j.jenkins.getItemByFullName("prj", WorkflowJob.class);
WorkflowRun b = p.getLastBuild();
story.j.assertLogContains("Require method GET POST OPTIONS", story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b)));
story.j.assertLogContains("Require method GET POST OPTIONS", story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b)));
}
});
}

@Issue("JENKINS-32943")
@Test public void fileCredentials() throws Exception {
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
DockerTestUtil.assumeDocker();
File f = tmp.newFile("some-file");
FileUtils.write(f, "some-content");
FileItem fi = new FileParameterValue.FileItemImpl(f);
FileCredentialsImpl fc = new FileCredentialsImpl(CredentialsScope.GLOBAL, "secretfile", "", fi, fi.getName(), null);
CredentialsProvider.lookupStores(story.j.jenkins).iterator().next().addCredentials(Domain.global(), fc);
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "prj");
p.setDefinition(new CpsFlowDefinition(
"node {\n" +
" withDockerContainer('ubuntu') {\n" +
" withCredentials([[$class: 'FileBinding', credentialsId: 'secretfile', variable: 'FILE']]) {\n" +
" sh 'cat $FILE'\n" +
" }\n" +
" }\n" +
" withCredentials([[$class: 'FileBinding', credentialsId: 'secretfile', variable: 'FILE']]) {\n" +
" withDockerContainer('ubuntu') {\n" +
" sh 'tr \"a-z\" \"A-Z\" < $FILE'\n" +
" }\n" +
" }\n" +
"}", true));
WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0));
story.j.assertLogContains("some-content", b);
story.j.assertLogContains("SOME-CONTENT", b);
}
});
}

@Ignore("TODO needs 2.10.1 release")
@Issue("JENKINS-27152")
@Test public void configFile() throws Exception {
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
DockerTestUtil.assumeDocker();
ConfigProvider configProvider = story.j.jenkins.getExtensionList(ConfigProvider.class).get(CustomConfig.CustomConfigProvider.class);
String id = configProvider.getProviderId() + "myfile";
Config config = new CustomConfig(id, "My File", "", "some-content");
configProvider.save(config);
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "prj");
p.setDefinition(new CpsFlowDefinition(
"node {\n" +
" withDockerContainer('ubuntu') {\n" +
" wrap([$class: 'ConfigFileBuildWrapper', managedFiles: [[fileId: '" + config.id + "', variable: 'FILE']]]) {\n" +
" sh 'cat $FILE'\n" +
" }\n" +
" }\n" +
" wrap([$class: 'ConfigFileBuildWrapper', managedFiles: [[fileId: '" + config.id + "', variable: 'FILE']]]) {\n" +
" withDockerContainer('ubuntu') {\n" +
" sh 'tr \"a-z\" \"A-Z\" < $FILE'\n" +
" }\n" +
" }\n" +
"}", true));
WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0));
story.j.assertLogContains("some-content", b);
story.j.assertLogContains("SOME-CONTENT", b);
}
});
}

0 comments on commit 2312931

Please sign in to comment.
You can’t perform that action at this time.