KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > Launcher


1 package hudson;
2
3 import hudson.model.Hudson;
4 import hudson.model.TaskListener;
5 import hudson.model.Computer;
6 import hudson.remoting.VirtualChannel;
7 import hudson.remoting.Channel;
8 import hudson.Proc.LocalProc;
9 import hudson.util.StreamCopyThread;
10
11 import java.io.File JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.InputStream JavaDoc;
14 import java.io.OutputStream JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Map JavaDoc;
17
18 /**
19  * Starts a process.
20  *
21  * <p>
22  * This hides the difference between running programs locally vs remotely.
23  *
24  *
25  * <h2>'env' parameter</h2>
26  * <p>
27  * To allow important environment variables to be copied over to the remote machine,
28  * the 'env' parameter shouldn't contain default inherited environment variables
29  * (which often contains machine-specific information, like PATH, TIMEZONE, etc.)
30  *
31  * <p>
32  * {@link Launcher} is responsible for inheriting environment variables.
33  *
34  *
35  * @author Kohsuke Kawaguchi
36  */

37 public abstract class Launcher {
38
39     protected final TaskListener listener;
40
41     protected final VirtualChannel channel;
42
43     public Launcher(TaskListener listener, VirtualChannel channel) {
44         this.listener = listener;
45         this.channel = channel;
46     }
47
48     /**
49      * Gets the channel that can be used to run a program remotely.
50      *
51      * @return
52      * null if the target node is not configured to support this.
53      * this is a transitional measure.
54      * Note that a launcher for the master is always non-null.
55      */

56     public VirtualChannel getChannel() {
57         return channel;
58     }
59
60     public final Proc launch(String JavaDoc cmd, Map JavaDoc<String JavaDoc,String JavaDoc> env, OutputStream JavaDoc out, FilePath workDir) throws IOException JavaDoc {
61         return launch(cmd,Util.mapToEnv(env),out,workDir);
62     }
63
64     public final Proc launch(String JavaDoc[] cmd, Map JavaDoc<String JavaDoc,String JavaDoc> env, OutputStream JavaDoc out, FilePath workDir) throws IOException JavaDoc {
65         return launch(cmd,Util.mapToEnv(env),out,workDir);
66     }
67
68     public final Proc launch(String JavaDoc[] cmd, Map JavaDoc<String JavaDoc,String JavaDoc> env, InputStream JavaDoc in, OutputStream JavaDoc out) throws IOException JavaDoc {
69         return launch(cmd,Util.mapToEnv(env),in,out);
70     }
71
72     public final Proc launch(String JavaDoc cmd,String JavaDoc[] env,OutputStream JavaDoc out, FilePath workDir) throws IOException JavaDoc {
73         return launch(Util.tokenize(cmd),env,out,workDir);
74     }
75
76     public final Proc launch(String JavaDoc[] cmd,String JavaDoc[] env,OutputStream JavaDoc out, FilePath workDir) throws IOException JavaDoc {
77         return launch(cmd,env,null,out,workDir);
78     }
79
80     public final Proc launch(String JavaDoc[] cmd,String JavaDoc[] env,InputStream JavaDoc in,OutputStream JavaDoc out) throws IOException JavaDoc {
81         return launch(cmd,env,in,out,null);
82     }
83
84     /**
85      * @param in
86      * null if there's no input.
87      * @param workDir
88      * null if the working directory could be anything.
89      * @param out
90      * stdout and stderr of the process will be sent to this stream.
91      * the stream won't be closed.
92      */

93     public abstract Proc launch(String JavaDoc[] cmd,String JavaDoc[] env,InputStream JavaDoc in,OutputStream JavaDoc out, FilePath workDir) throws IOException JavaDoc;
94
95     /**
96      * Launches a specified process and connects its input/output to a {@link Channel}, then
97      * return it.
98      *
99      * @param out
100      * Where the stderr from the launched process will be sent.
101      */

102     public abstract Channel launchChannel(String JavaDoc[] cmd, OutputStream JavaDoc out, FilePath workDir) throws IOException JavaDoc, InterruptedException JavaDoc;
103
104     /**
105      * Returns true if this {@link Launcher} is going to launch on Unix.
106      */

107     public boolean isUnix() {
108         return File.pathSeparatorChar==':';
109     }
110
111     /**
112      * Prints out the command line to the listener so that users know what we are doing.
113      */

114     protected final void printCommandLine(String JavaDoc[] cmd, FilePath workDir) {
115         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
116         if (workDir != null) {
117             buf.append('[');
118             if(showFullPath)
119                 buf.append(workDir.getRemote());
120             else
121                 buf.append(workDir.getRemote().replaceFirst("^.+[/\\\\]", ""));
122             buf.append("] ");
123         }
124         buf.append('$');
125         for (String JavaDoc c : cmd) {
126             buf.append(' ');
127             if(c.indexOf(' ')>=0) {
128                 if(c.indexOf('"')>=0)
129                     buf.append('\'').append(c).append('\'');
130                 else
131                     buf.append('"').append(c).append('"');
132             } else
133                 buf.append(c);
134         }
135         listener.getLogger().println(buf.toString());
136     }
137
138     public static class LocalLauncher extends Launcher {
139         public LocalLauncher(TaskListener listener) {
140             this(listener,Hudson.MasterComputer.localChannel);
141         }
142
143         public LocalLauncher(TaskListener listener, VirtualChannel channel) {
144             super(listener, channel);
145         }
146
147         public Proc launch(String JavaDoc[] cmd,String JavaDoc[] env,InputStream JavaDoc in,OutputStream JavaDoc out, FilePath workDir) throws IOException JavaDoc {
148             printCommandLine(cmd, workDir);
149             return new LocalProc(cmd,Util.mapToEnv(inherit(env)),in,out, toFile(workDir));
150         }
151
152         private File JavaDoc toFile(FilePath f) {
153             return f==null ? null : new File JavaDoc(f.getRemote());
154         }
155
156         public Channel launchChannel(String JavaDoc[] cmd, OutputStream JavaDoc out, FilePath workDir) throws IOException JavaDoc {
157             printCommandLine(cmd, workDir);
158
159             Process JavaDoc proc = Runtime.getRuntime().exec(cmd, null, toFile(workDir));
160
161             // TODO: don't we need the equivalent of 'Proc' here? to abort it
162

163             Thread JavaDoc t2 = new StreamCopyThread(cmd+": stderr copier", proc.getErrorStream(), out);
164             t2.start();
165
166             return new Channel("locally launched channel on "+cmd,
167                 Computer.threadPoolForRemoting, proc.getInputStream(), proc.getOutputStream(), out);
168         }
169
170         /**
171          * Expands the list of environment variables by inheriting current env variables.
172          */

173         private Map JavaDoc<String JavaDoc,String JavaDoc> inherit(String JavaDoc[] env) {
174             Map JavaDoc<String JavaDoc,String JavaDoc> m = new HashMap JavaDoc<String JavaDoc,String JavaDoc>(EnvVars.masterEnvVars);
175             for (String JavaDoc e : env) {
176                 int index = e.indexOf('=');
177                 String JavaDoc key = e.substring(0,index);
178                 String JavaDoc value = e.substring(index+1);
179                 if(value.length()==0)
180                     m.remove(key);
181                 else
182                     m.put(key,value);
183             }
184             return m;
185         }
186     }
187
188     /**
189      * Debug option to display full current path instead of just the last token.
190      */

191     public static boolean showFullPath = false;
192 }
193
Popular Tags