Skip to content

Commit

Permalink
[FIXED JENKINS-41118] Rewrote to make it an agent option
Browse files Browse the repository at this point in the history
Needed because we need SCM checkout to happen *after* the ws() call,
while with the initial implementation, SCM checkout happened before
the ws() call. As a bonus, we now can do this for any agent building
off of Label, so that's nice!
  • Loading branch information
abayer committed Mar 4, 2017
1 parent be0509c commit bd2b9a6
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 67 deletions.
Expand Up @@ -34,6 +34,7 @@ public abstract class AbstractDockerAgent<D extends AbstractDockerAgent<D>> exte
protected String args = "";
protected String registryUrl;
protected String registryCredentialsId;
protected String customWorkspace;
protected boolean reuseNode;

public @Nullable
Expand Down Expand Up @@ -74,6 +75,15 @@ public void setLabel(String label) {
this.label = label;
}

public @CheckForNull String getCustomWorkspace() {
return customWorkspace;
}

@DataBoundSetter
public void setCustomWorkspace(String customWorkspace) {
this.customWorkspace = customWorkspace;
}

public @CheckForNull String getArgs() {
return args;
}
Expand Down
Expand Up @@ -29,11 +29,14 @@
import org.jenkinsci.plugins.pipeline.modeldefinition.agent.DeclarativeAgent;
import org.jenkinsci.plugins.pipeline.modeldefinition.agent.DeclarativeAgentDescriptor;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;

public class Label extends DeclarativeAgent<Label> {
private String label;
private String customWorkspace;

@DataBoundConstructor
public Label(String label) {
Expand All @@ -45,6 +48,16 @@ public Label(String label) {
return label;
}

public @CheckForNull
String getCustomWorkspace() {
return customWorkspace;
}

@DataBoundSetter
public void setCustomWorkspace(String customWorkspace) {
this.customWorkspace = customWorkspace;
}

@Extension(ordinal = -800) @Symbol("label")
public static class DescriptorImpl extends DeclarativeAgentDescriptor<Label> {
}
Expand Down
Expand Up @@ -29,8 +29,6 @@ import hudson.FilePath
import hudson.Launcher
import hudson.model.Result
import org.jenkinsci.plugins.pipeline.modeldefinition.model.*
import org.jenkinsci.plugins.pipeline.modeldefinition.options.impl.SkipStagesAfterUnstable
import org.jenkinsci.plugins.pipeline.modeldefinition.options.impl.WorkspaceDir
import org.jenkinsci.plugins.pipeline.modeldefinition.steps.CredentialWrapper
import org.jenkinsci.plugins.pipeline.modeldefinition.when.DeclarativeStageConditional
import org.jenkinsci.plugins.workflow.cps.CpsScript
Expand Down Expand Up @@ -320,38 +318,11 @@ public class ModelInterpreter implements Serializable {
}.call()
} else {
return agent.getDeclarativeAgent(root, context).getScript(script).run {
inWorkspace(context) {
body.call()
}
body.call()
}.call()
}
}

/**
* Allocates a new workspace if the {@link WorkspaceDir} option is set.
*
* @param context Either a stage or root object, the context we're running in.
* @param body The closure to execute
* @return The return of the resulting executed closure
*/
def inWorkspace(Object context, Closure body) {
// This may change later to allow per-stage workspace dir configuration.
if (context instanceof Root) {
WorkspaceDir dirOpt = (WorkspaceDir)((Root)context).options?.options?.get("workspaceDir")
if (dirOpt != null) {
return {
script.ws(dirOpt.dir) {
body.call()
}
}.call()
}
}

return {
body.call()
}.call()
}

/**
* Executes the given closure inside 0 or more wrapper blocks if appropriate
* @param options The options configuration we're executing in
Expand Down
Expand Up @@ -48,6 +48,7 @@ public abstract class AbstractDockerPipelineScript<A extends AbstractDockerAgent
Label l = (Label) Label.DescriptorImpl.instanceForName("label", [label: targetLabel])
l.inStage = describable.inStage
l.doCheckout = describable.doCheckout
l.customWorkspace = describable.customWorkspace
LabelScript labelScript = (LabelScript) l.getScript(script)
return labelScript.run {
configureRegistry(body).call()
Expand Down
Expand Up @@ -41,22 +41,34 @@ public class LabelScript extends DeclarativeAgentScript<Label> {
return {
try {
script.node(describable?.label) {
if (describable.isDoCheckout() && describable.hasScmContext(script)) {
if (!describable.inStage) {
script.stage(SyntheticStageNames.checkout()) {
script.checkout script.scm
}
} else {
// No stage when we're in a nested stage already
script.checkout script.scm
if (describable.customWorkspace != null && describable.customWorkspace != "") {
script.ws(describable.customWorkspace) {
checkoutAndRun(body).call()
}
} else {
checkoutAndRun(body).call()
}
body.call()
}
} catch (Exception e) {
script.getProperty("currentBuild").result = Result.FAILURE
throw e
}
}
}

private Closure checkoutAndRun(Closure body) {
return {
if (describable.isDoCheckout() && describable.hasScmContext(script)) {
if (!describable.inStage) {
script.stage(SyntheticStageNames.checkout()) {
script.checkout script.scm
}
} else {
// No stage when we're in a nested stage already
script.checkout script.scm
}
}
body.call()
}
}
}
Expand Up @@ -595,8 +595,16 @@ public void booleanParamBuildStep() throws Exception {

@Issue("JENKINS-41118")
@Test
public void inWorkspace() throws Exception {
expect("inWorkspace")
public void inCustomWorkspace() throws Exception {
expect("inCustomWorkspace")
.logMatches("Workspace dir is .*some-sub-dir")
.go();
}

@Issue("JENKINS-41118")
@Test
public void inCustomWorkspaceInStage() throws Exception {
expect("inCustomWorkspaceInStage")
.logMatches("Workspace dir is .*some-sub-dir")
.go();
}
Expand Down
Expand Up @@ -23,9 +23,11 @@
*/

pipeline {
agent any
options {
workspaceDir("some-sub-dir")
agent {
label {
label ""
customWorkspace "some-sub-dir"
}
}
stages {
stage("foo") {
Expand Down
Expand Up @@ -22,30 +22,22 @@
* THE SOFTWARE.
*/

package org.jenkinsci.plugins.pipeline.modeldefinition.options.impl;

import hudson.Extension;
import org.jenkinsci.Symbol;
import org.jenkinsci.plugins.pipeline.modeldefinition.options.DeclarativeOption;
import org.jenkinsci.plugins.pipeline.modeldefinition.options.DeclarativeOptionDescriptor;
import org.kohsuke.stapler.DataBoundConstructor;

import javax.annotation.Nullable;

public class WorkspaceDir extends DeclarativeOption {
private String dir;

@DataBoundConstructor
public WorkspaceDir(String dir) {
this.dir = dir;
pipeline {
agent none
stages {
stage("foo") {
agent {
label {
label ""
customWorkspace "some-sub-dir"
}
}
steps {
echo "Workspace dir is ${pwd()}"
}
}
}
}

public String getDir() {
return dir;
}

@Extension @Symbol("workspaceDir")
public static class DescriptorImpl extends DeclarativeOptionDescriptor {

}
}

0 comments on commit bd2b9a6

Please sign in to comment.