File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\slaves\CommandLauncher.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.slaves;
25
26 import hudson.EnvVars;
27 import hudson.Util;
28 import hudson.Extension;
29 import hudson.model.Descriptor;
30 import jenkins.model.Jenkins;
31 import hudson.model.TaskListener;
32 import hudson.remoting.Channel;
33 import hudson.util.StreamCopyThread;
34 import hudson.util.FormValidation;
35 import hudson.util.ProcessTree;
36
37 import java.io.IOException;
38 import java.util.Date;
39 import java.util.logging.Level;
40 import java.util.logging.Logger;
41
42 import org.kohsuke.stapler.DataBoundConstructor;
43 import org.kohsuke.stapler.QueryParameter;
44
45 /**
46 * {@link ComputerLauncher} through a remote login mechanism like ssh/rsh.
47 *
48 * @author Stephen Connolly
49 * @author Kohsuke Kawaguchi
50 */
51 public class CommandLauncher extends ComputerLauncher {
52
53 /**
54 * Command line to launch the agent, like
55 * "ssh myslave java -jar /path/to/hudson-remoting.jar"
56 */
57 private final String agentCommand;
58
59 /**
60 * Optional environment variables to add to the current environment. Can be null.
61 */
62 private final EnvVars env;
63
64 @DataBoundConstructor
65 public CommandLauncher(String command) {
66 this(command, null);
67 }
68
69 public CommandLauncher(String command, EnvVars env) {
70 this.agentCommand = command;
71 this.env = env;
72 }
73
74 public String getCommand() {
75 return agentCommand;
76 }
77
78 /**
79 * Gets the formatted current time stamp.
80 */
81 private static String getTimestamp() {
82 return String.format("[%1$tD %1$tT]", new Date());
83 }
84
85 @Override
86 public void launch(SlaveComputer computer, final TaskListener listener) {
87 EnvVars _cookie = null;
88 Process _proc = null;
89 try {
90 listener.getLogger().println(hudson.model.Messages.Slave_Launching(getTimestamp()));
91 if(getCommand().trim().length()==0) {
92 listener.getLogger().println(Messages.CommandLauncher_NoLaunchCommand());
93 return;
94 }
95 listener.getLogger().println("$ " + getCommand());
96
97 ProcessBuilder pb = new ProcessBuilder(Util.tokenize(getCommand()));
98 final EnvVars cookie = _cookie = EnvVars.createCookie();
99 pb.environment().putAll(cookie);
100 pb.environment().put("WORKSPACE", computer.getNode().getRemoteFS()); //path for local slave log
101
102 {// system defined variables
103 String rootUrl = Jenkins.getInstance().getRootUrl();
104 if (rootUrl!=null) {
105 pb.environment().put("HUDSON_URL", rootUrl); // for backward compatibility
106 pb.environment().put("JENKINS_URL", rootUrl);
107 pb.environment().put("SLAVEJAR_URL", rootUrl+"/jnlpJars/slave.jar");
108 }
109 }
110
111 if (env != null) {
112 pb.environment().putAll(env);
113 }
114
115 final Process proc = _proc = pb.start();
116
117 // capture error information from stderr. this will terminate itself
118 // when the process is killed.
119 new StreamCopyThread("stderr copier for remote agent on " + computer.getDisplayName(),
120 proc.getErrorStream(), listener.getLogger()).start();
121
122 computer.setChannel(proc.getInputStream(), proc.getOutputStream(), listener.getLogger(), new Channel.Listener() {
123 @Override
124 public void onClosed(Channel channel, IOException cause) {
125 try {
126 int exitCode = proc.exitValue();
127 if (exitCode!=0) {
128 listener.error("Process terminated with exit code "+exitCode);
129 }
130 } catch (IllegalThreadStateException e) {
131 // hasn't terminated yet
132 }
133
134 try {
135 ProcessTree.get().killAll(proc, cookie);
136 } catch (InterruptedException e) {
137 LOGGER.log(Level.INFO, "interrupted", e);
138 }
139 }
140 });
141
142 LOGGER.info("slave agent launched for " + computer.getDisplayName());
143 } catch (InterruptedException e) {
144 e.printStackTrace(listener.error(Messages.ComputerLauncher_abortedLaunch()));
145 } catch (RuntimeException e) {
146 e.printStackTrace(listener.error(Messages.ComputerLauncher_unexpectedError()));
147 } catch (Error e) {
148 e.printStackTrace(listener.error(Messages.ComputerLauncher_unexpectedError()));
149 } catch (IOException e) {
150 Util.displayIOException(e, listener);
151
152 String msg = Util.getWin32ErrorMessage(e);
153 if (msg == null) {
154 msg = "";
155 } else {
156 msg = " : " + msg;
157 }
158 msg = hudson.model.Messages.Slave_UnableToLaunch(computer.getDisplayName(), msg);
159 LOGGER.log(Level.SEVERE, msg, e);
160 e.printStackTrace(listener.error(msg));
161
162 if(_proc!=null)
163 try {
164 ProcessTree.get().killAll(_proc, _cookie);
165 } catch (InterruptedException x) {
166 x.printStackTrace(listener.error(Messages.ComputerLauncher_abortedLaunch()));
167 }
168 }
169 }
170
171 private static final Logger LOGGER = Logger.getLogger(CommandLauncher.class.getName());
172
173 @Extension
174 public static class DescriptorImpl extends Descriptor<ComputerLauncher> {
175 public String getDisplayName() {
176 return Messages.CommandLauncher_displayName();
177 }
178
179 public FormValidation doCheckCommand(@QueryParameter String value) {
180 if(Util.fixEmptyAndTrim(value)==null)
181 return FormValidation.error(Messages.CommandLauncher_NoLaunchCommand());
182 else
183 return FormValidation.ok();
184 }
185 }
186 }
187