package hudson.os.windows;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Proc;
import hudson.Util;
import hudson.model.Computer;
import hudson.model.TaskListener;
import hudson.remoting.Channel;
import hudson.util.IOException2;
import hudson.util.StreamCopyThread;
import org.jinterop.dcom.common.JIException;
import org.jvnet.hudson.remcom.WindowsRemoteProcessLauncher;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import static java.util.Arrays.asList;
/**
* Pseudo-{@link Launcher} implementation that uses {@link WindowsRemoteProcessLauncher}
*
* @author Kohsuke Kawaguchi
*/
public class WindowsRemoteLauncher extends Launcher {
private final WindowsRemoteProcessLauncher launcher;
public WindowsRemoteLauncher(TaskListener listener, WindowsRemoteProcessLauncher launcher) {
super(listener,null);
this.launcher = launcher;
}
private String buildCommandLine(ProcStarter ps) {
StringBuilder b = new StringBuilder();
for (String cmd : ps.cmds()) {
if (b.length()>0) b.append(' ');
if (cmd.indexOf(' ')>=0)
b.append('"').append(cmd).append('"');
else
b.append(cmd);
}
return b.toString();
}
public Proc launch(ProcStarter ps) throws IOException {
maskedPrintCommandLine(ps.cmds(), ps.masks(), ps.pwd());
// TODO: environment variable handling
String name = ps.cmds().toString();
final Process proc;
try {
proc = launcher.launch(buildCommandLine(ps), ps.pwd().getRemote());
} catch (JIException e) {
throw new IOException2(e);
} catch (InterruptedException e) {
throw new IOException2(e);
}
final Thread t1 = new StreamCopyThread("stdout copier: "+name, proc.getInputStream(), ps.stdout(),false);
t1.start();
final Thread t2 = new StreamCopyThread("stdin copier: "+name,ps.stdin(), proc.getOutputStream(),true);
t2.start();
return new Proc() {
public boolean isAlive() throws IOException, InterruptedException {
try {
proc.exitValue();
return false;
} catch (IllegalThreadStateException e) {
return true;
}
}
public void kill() throws IOException, InterruptedException {
t1.interrupt();
t2.interrupt();
proc.destroy();
}
public int join() throws IOException, InterruptedException {
try {
t1.join();
t2.join();
return proc.waitFor();
} finally {
proc.destroy();
}
}
};
}
public Channel launchChannel(String[] cmd, OutputStream out, FilePath _workDir, Map<String, String> envVars) throws IOException, InterruptedException {
printCommandLine(cmd, _workDir);
try {
Process proc = launcher.launch(Util.join(asList(cmd), " "), _workDir.getRemote());
return new Channel("channel over named pipe to "+launcher.getHostName(),
Computer.threadPoolForRemoting, proc.getInputStream(), new BufferedOutputStream(proc.getOutputStream()));
} catch (JIException e) {
throw new IOException2(e);
}
}
public void kill(Map<String, String> modelEnvVars) throws IOException, InterruptedException {
// no way to do this
}
}