提交 ba23c8b5 编写于 作者: K Kohsuke Kawaguchi

added methods to obtain node-scoped and job-scoped environment variables

上级 8ff2c0e4
......@@ -931,19 +931,7 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
FilePath ws = getWorkspace();
if (ws!=null) // if this is done very early on in the build, workspace may not be decided yet. see HUDSON-3997
env.put("WORKSPACE", ws.getRemote());
// servlet container may have set CLASSPATH in its launch script,
// so don't let that inherit to the new child process.
// see http://www.nabble.com/Run-Job-with-JDK-1.4.2-tf4468601.html
env.put("CLASSPATH","");
JDK jdk = project.getJDK();
if (jdk != null) {
Computer computer = Computer.currentComputer();
if (computer != null) { // just in case were not in a build
jdk = jdk.forNode(computer.getNode(), log);
}
jdk.buildEnvVars(env);
}
project.getScm().buildEnvVars(this,env);
if (buildEnvironments!=null)
......
......@@ -28,6 +28,7 @@
package hudson.model;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import hudson.EnvVars;
import hudson.Functions;
import antlr.ANTLRException;
import hudson.AbortException;
......@@ -299,6 +300,21 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
updateTransientActions();
}
@Override
public EnvVars getEnvironment(Node node, TaskListener listener) throws IOException, InterruptedException {
EnvVars env = super.getEnvironment(node, listener);
JDK jdk = getJDK();
if (jdk != null) {
if (node != null) { // just in case were not in a build
jdk = jdk.forNode(node, listener);
}
jdk.buildEnvVars(env);
}
return env;
}
@Override
protected void performDelete() throws IOException, InterruptedException {
// prevent a new build while a delete operation is in progress
......
......@@ -25,6 +25,9 @@
package hudson.model;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Launcher.ProcStarter;
import hudson.Util;
import hudson.cli.declarative.CLIMethod;
import hudson.cli.declarative.CLIResolver;
......@@ -45,6 +48,7 @@ import hudson.security.PermissionGroup;
import hudson.security.PermissionScope;
import hudson.slaves.ComputerLauncher;
import hudson.slaves.ComputerListener;
import hudson.slaves.NodeProperty;
import hudson.slaves.RetentionStrategy;
import hudson.slaves.WorkspaceList;
import hudson.slaves.OfflineCause;
......@@ -77,6 +81,7 @@ import javax.servlet.ServletException;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
......@@ -877,6 +882,36 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
return EnvVars.getRemote(getChannel());
}
/**
* Creates an environment variable override to be used for launching processes on this node.
*
* @see ProcStarter#envs(Map)
* @since 1.488
*/
public EnvVars buildEnvironment(TaskListener listener) throws IOException, InterruptedException {
EnvVars env = new EnvVars();
Node node = getNode();
if (node==null) return env; // bail out
for (NodeProperty nodeProperty: Jenkins.getInstance().getGlobalNodeProperties()) {
nodeProperty.buildEnvVars(env,listener);
}
for (NodeProperty nodeProperty: node.getNodeProperties()) {
nodeProperty.buildEnvVars(env,listener);
}
// TODO: hmm, they don't really belong
String rootUrl = Hudson.getInstance().getRootUrl();
if(rootUrl!=null) {
env.put("HUDSON_URL", rootUrl); // Legacy.
env.put("JENKINS_URL", rootUrl);
}
return env;
}
/**
* Gets the thread dump of the slave JVM.
* @return
......
......@@ -26,6 +26,7 @@ package hudson.model;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import hudson.EnvVars;
import hudson.Extension;
import hudson.ExtensionPoint;
import hudson.PermalinkList;
......@@ -51,6 +52,7 @@ import hudson.util.DataSetBuilder;
import hudson.util.DescribableList;
import hudson.util.FormApply;
import hudson.util.Graph;
import hudson.util.ProcessTree;
import hudson.util.RunList;
import hudson.util.ShiftedCategoryAxis;
import hudson.util.StackedAreaRenderer2;
......@@ -300,6 +302,47 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
return nextBuildNumber;
}
/**
* Builds up the environment variable map that's sufficient to identify a process
* as ours. This is used to kill run-away processes via {@link ProcessTree#killAll(Map)}.
*/
public EnvVars getCharacteristicEnvVars() {
EnvVars env = new EnvVars();
env.put("JENKINS_SERVER_COOKIE",Util.getDigestOf("ServerID:"+ Jenkins.getInstance().getSecretKey()));
env.put("HUDSON_SERVER_COOKIE",Util.getDigestOf("ServerID:"+ Jenkins.getInstance().getSecretKey())); // Legacy compatibility
env.put("JOB_NAME",getParent().getFullName());
return env;
}
/**
* Creates an environment variable override for launching processes for this project.
*
* <p>
* This is for process launching outside the build execution (such as polling, tagging, deployment, etc.)
* that happens in a context of a specific job.
*
* @param node
* Node to eventually run a process on. The implementation must cope with this parameter being null
* (in which case none of the node specific properties would be reflected in the resulting override.)
*/
public EnvVars getEnvironment(Node node, TaskListener listener) throws IOException, InterruptedException {
EnvVars env;
if (node!=null)
env = node.toComputer().buildEnvironment(listener);
else
env = new EnvVars();
env.putAll(getCharacteristicEnvVars());
// servlet container may have set CLASSPATH in its launch script,
// so don't let that inherit to the new child process.
// see http://www.nabble.com/Run-Job-with-JDK-1.4.2-tf4468601.html
env.put("CLASSPATH","");
return env;
}
/**
* Programatically updates the next build number.
*
......
......@@ -1958,12 +1958,16 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
* @return the map with the environmental variables. Never <code>null</code>.
* @since 1.305
*/
public EnvVars getEnvironment(TaskListener log) throws IOException, InterruptedException {
EnvVars env = getCharacteristicEnvVars();
public EnvVars getEnvironment(TaskListener listener) throws IOException, InterruptedException {
Computer c = Computer.currentComputer();
Node n = c==null ? null : c.getNode();
EnvVars env = getParent().getEnvironment(n,listener);
env.putAll(getCharacteristicEnvVars());
// apply them in a reverse order so that higher ordinal ones can modify values added by lower ordinal ones
for (EnvironmentContributor ec : EnvironmentContributor.all().reverseView())
ec.buildEnvironmentFor(this,env,log);
ec.buildEnvironmentFor(this,env,listener);
return env;
}
......@@ -1973,13 +1977,10 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
* as ours. This is used to kill run-away processes via {@link ProcessTree#killAll(Map)}.
*/
public final EnvVars getCharacteristicEnvVars() {
EnvVars env = new EnvVars();
env.put("JENKINS_SERVER_COOKIE",Util.getDigestOf("ServerID:"+ Jenkins.getInstance().getSecretKey()));
env.put("HUDSON_SERVER_COOKIE",Util.getDigestOf("ServerID:"+ Jenkins.getInstance().getSecretKey())); // Legacy compatibility
EnvVars env = getParent().getCharacteristicEnvVars();
env.put("BUILD_NUMBER",String.valueOf(number));
env.put("BUILD_ID",getId());
env.put("BUILD_TAG","jenkins-"+getParent().getFullName().replace('/', '-')+"-"+number);
env.put("JOB_NAME",getParent().getFullName());
return env;
}
......
......@@ -31,6 +31,7 @@ import hudson.model.BuildListener;
import hudson.model.ComputerSet;
import hudson.model.Environment;
import hudson.model.Node;
import hudson.model.TaskListener;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.Stapler;
......@@ -69,6 +70,11 @@ public class EnvironmentVariablesNodeProperty extends NodeProperty<Node> {
return Environment.create(envVars);
}
@Override
public void buildEnvVars(EnvVars env, TaskListener listener) throws IOException, InterruptedException {
env.putAll(envVars);
}
@Extension
public static class DescriptorImpl extends NodePropertyDescriptor {
......
......@@ -23,6 +23,7 @@
*/
package hudson.slaves;
import hudson.EnvVars;
import hudson.ExtensionPoint;
import hudson.FilePath;
import hudson.Launcher;
......@@ -30,6 +31,7 @@ import hudson.DescriptorExtensionList;
import hudson.model.Descriptor.FormException;
import hudson.model.Queue.BuildableItem;
import hudson.model.ReconfigurableDescribable;
import hudson.model.TaskListener;
import hudson.model.queue.CauseOfBlockage;
import hudson.scm.SCM;
import hudson.model.AbstractBuild;
......@@ -44,6 +46,7 @@ import org.kohsuke.stapler.StaplerRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* Extensible property of {@link Node}.
......@@ -129,6 +132,39 @@ public abstract class NodeProperty<N extends Node> implements ReconfigurableDesc
return new Environment() {};
}
/**
* Creates environment variable override for launching child processes in this node.
*
* <p>
* Whereas {@link #setUp(AbstractBuild, Launcher, BuildListener)} is used specifically for
* executing builds, this method is used for other process launch activities that happens
* outside the context of a build, such as polling, one time action (tagging, deployment, etc.)
*
* <p>
* Starting 1.488, this method and {@link #setUp(AbstractBuild, Launcher, BuildListener)} are
* layered properly. That is, for launching processes for a build, this method
* is called first and then {@link Environment#buildEnvVars(Map)} will be added on top.
* This allows implementations to put node-scoped environment variables here, then
* build scoped variables to {@link #setUp(AbstractBuild, Launcher, BuildListener)}.
*
* <p>
* Unfortunately, Jenkins core earlier than 1.488 only calls {@link #setUp(AbstractBuild, Launcher, BuildListener)},
* so if the backward compatibility with these earlier versions is important, implementations
* should invoke this method from {@link Environment#buildEnvVars(Map)}.
*
* @param env
* Manipulate this variable (normally by adding more entries.)
* Note that this is an override, so it doesn't contain environment variables that are
* currently set for the slave process itself.
* @param listener
* Can be used to send messages.
*
* @since 1.488
*/
public void buildEnvVars(EnvVars env, TaskListener listener) throws IOException,InterruptedException {
// default is no-op
}
public NodeProperty<?> reconfigure(StaplerRequest req, JSONObject form) throws FormException {
return form==null ? null : getDescriptor().newInstance(req, form);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册