diff --git a/core/src/main/java/hudson/Launcher.java b/core/src/main/java/hudson/Launcher.java index 5932cef9ef09..5151014f2725 100644 --- a/core/src/main/java/hudson/Launcher.java +++ b/core/src/main/java/hudson/Launcher.java @@ -25,7 +25,9 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Proc.LocalProc; +import hudson.model.BuildListener; import hudson.model.Computer; +import hudson.model.Run; import hudson.util.QuotedStringTokenizer; import jenkins.model.Jenkins; import hudson.model.TaskListener; @@ -807,6 +809,22 @@ public final Launcher decorateFor(@Nonnull Node node) { return l; } + /** + * Returns a decorated {@link Launcher} for the given {@link hudson.model.Run}. + * + * @param run Run for which this launcher is created. + * @param listener Task listener + * @return Decorated instance of the Launcher. + * @since TODO + */ + @Nonnull + public final Launcher decorateFor(@Nonnull Run run, @Nonnull BuildListener listener) { + Launcher l = this; + for (LauncherDecorator d : LauncherDecorator.all()) + l = d.decorate(l, run, listener); + return l; + } + /** * Returns a decorated {@link Launcher} that puts the given set of arguments as a prefix to any commands * that it invokes. diff --git a/core/src/main/java/hudson/LauncherDecorator.java b/core/src/main/java/hudson/LauncherDecorator.java index 62e56f56d390..002cd4984d90 100644 --- a/core/src/main/java/hudson/LauncherDecorator.java +++ b/core/src/main/java/hudson/LauncherDecorator.java @@ -1,7 +1,10 @@ package hudson; +import hudson.model.BuildListener; import hudson.model.Node; import hudson.model.Executor; +import hudson.model.Run; +import hudson.model.TaskListener; import hudson.tasks.BuildWrapper; import javax.annotation.Nonnull; @@ -40,7 +43,22 @@ public abstract class LauncherDecorator implements ExtensionPoint { * @see Launcher#decorateByPrefix(String[]) */ @Nonnull - public abstract Launcher decorate(@Nonnull Launcher launcher, @Nonnull Node node); + public Launcher decorate(@Nonnull Launcher launcher, @Nonnull Node node) { + return launcher; + } + + /** + * Decorates Launcher by Run + * @param launcher Launcher to be decorated + * @param run Run + * @param listener Event Listener + * @return Decorated launcher or the passed launcher if not documented + * @since TODO + */ + @Nonnull + public Launcher decorate(@Nonnull Launcher launcher, @Nonnull Run run, BuildListener listener) { + return launcher; + } /** * Returns all the registered {@link LauncherDecorator}s. diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java index 0f49ac47f36c..f57738efbb8d 100644 --- a/core/src/main/java/hudson/model/AbstractBuild.java +++ b/core/src/main/java/hudson/model/AbstractBuild.java @@ -368,6 +368,43 @@ public String getHudsonVersion() { return hudsonVersion; } + @Override + protected Launcher createLauncher(@Nonnull Node node, @Nonnull BuildListener listener) + throws IOException, InterruptedException { + Launcher l = super.createLauncher(node, listener); + + if (project instanceof BuildableItemWithBuildWrappers) { + BuildableItemWithBuildWrappers biwbw = (BuildableItemWithBuildWrappers) project; + for (BuildWrapper bw : biwbw.getBuildWrappersList()) + l = bw.decorateLauncher(AbstractBuild.this,l,listener); + } + + buildEnvironments = new ArrayList(); + + for (RunListener rl: RunListener.all()) { + Environment environment = rl.setUpEnvironment(AbstractBuild.this, l, listener); + if (environment != null) { + buildEnvironments.add(environment); + } + } + + for (NodeProperty nodeProperty: Jenkins.getInstance().getGlobalNodeProperties()) { + Environment environment = nodeProperty.setUp(AbstractBuild.this, l, listener); + if (environment != null) { + buildEnvironments.add(environment); + } + } + + for (NodeProperty nodeProperty: node.getNodeProperties()) { + Environment environment = nodeProperty.setUp(AbstractBuild.this, l, listener); + if (environment != null) { + buildEnvironments.add(environment); + } + } + + return l; + } + /** * @deprecated as of 1.467 * Please use {@link hudson.model.Run.RunExecution} @@ -518,6 +555,8 @@ public Result run(@Nonnull BuildListener listener) throws Exception { return result; } + + /** * Creates a {@link Launcher} that this build will use. This can be overridden by derived types * to decorate the resulting {@link Launcher}. @@ -527,39 +566,7 @@ public Result run(@Nonnull BuildListener listener) throws Exception { */ @Nonnull protected Launcher createLauncher(@Nonnull BuildListener listener) throws IOException, InterruptedException { - final Node currentNode = getCurrentNode(); - Launcher l = currentNode.createLauncher(listener); - - if (project instanceof BuildableItemWithBuildWrappers) { - BuildableItemWithBuildWrappers biwbw = (BuildableItemWithBuildWrappers) project; - for (BuildWrapper bw : biwbw.getBuildWrappersList()) - l = bw.decorateLauncher(AbstractBuild.this,l,listener); - } - - buildEnvironments = new ArrayList(); - - for (RunListener rl: RunListener.all()) { - Environment environment = rl.setUpEnvironment(AbstractBuild.this, l, listener); - if (environment != null) { - buildEnvironments.add(environment); - } - } - - for (NodeProperty nodeProperty: Jenkins.getInstance().getGlobalNodeProperties()) { - Environment environment = nodeProperty.setUp(AbstractBuild.this, l, listener); - if (environment != null) { - buildEnvironments.add(environment); - } - } - - for (NodeProperty nodeProperty: currentNode.getNodeProperties()) { - Environment environment = nodeProperty.setUp(AbstractBuild.this, l, listener); - if (environment != null) { - buildEnvironments.add(environment); - } - } - - return l; + return AbstractBuild.this.createLauncher(getCurrentNode(), listener); } public void defaultCheckout() throws IOException, InterruptedException { diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index e8c7965f30e4..ad8caa07dc0d 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -36,6 +36,8 @@ import hudson.ExtensionPoint; import hudson.FeedAdapter; import hudson.Functions; +import hudson.Launcher; +import hudson.LauncherDecorator; import hudson.console.AnnotatedLargeText; import hudson.console.ConsoleLogFilter; import hudson.console.ConsoleNote; @@ -44,6 +46,8 @@ import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.StandardOpenOption; + +import hudson.slaves.NodeProperty; import jenkins.util.SystemProperties; import hudson.Util; import hudson.XmlFile; @@ -2579,6 +2583,24 @@ public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) return returnedResult; } + /** + * Creates a {@link Launcher} that this build will use. This can be overridden by derived types + * to decorate the resulting {@link Launcher}. + * + * @param listener + * Always non-null. Connected to the main build output. + * @param node + * Node for which the launcher is created. + * @since TODO + */ + @Nonnull + protected Launcher createLauncher(@Nonnull Node node, @Nonnull BuildListener listener) + throws IOException, InterruptedException { + Launcher l = node.createLauncher(listener); + l.decorateFor(this, listener); + return l; + } + public static class RedirectUp { public void doDynamic(StaplerResponse rsp) throws IOException { // Compromise to handle both browsers (auto-redirect) and programmatic access