Skip to content

Commit

Permalink
Merge pull request #922 from jglick/SimpleCommandLauncher
Browse files Browse the repository at this point in the history
Implement `afterDisconnect` in `SimpleCommandLauncher`
  • Loading branch information
jglick authored Feb 19, 2025
2 parents f25ef8c + 86a2bc9 commit 256947e
Showing 1 changed file with 23 additions and 14 deletions.
37 changes: 23 additions & 14 deletions src/main/java/org/jvnet/hudson/test/SimpleCommandLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,18 @@

package org.jvnet.hudson.test;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.AbortException;
import hudson.EnvVars;
import hudson.Extension;
import hudson.Util;
import hudson.model.Descriptor;
import hudson.model.Slave;
import hudson.model.TaskListener;
import hudson.remoting.Channel;
import hudson.slaves.ComputerLauncher;
import hudson.slaves.SlaveComputer;
import hudson.util.ProcessTree;
import hudson.util.StreamCopyThread;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
Expand All @@ -52,6 +51,8 @@ public class SimpleCommandLauncher extends ComputerLauncher {

public final String cmd;
private final Map<String, String> env;
private transient Process proc;
private transient EnvVars cookie;

@DataBoundConstructor // in case anyone needs to configRoundtrip such a node
public SimpleCommandLauncher(String cmd) {
Expand All @@ -72,29 +73,37 @@ public void launch(SlaveComputer computer, final TaskListener listener) {
}
listener.getLogger().println("$ " + cmd);
ProcessBuilder pb = new ProcessBuilder(Util.tokenize(cmd));
final EnvVars cookie = EnvVars.createCookie();
cookie = EnvVars.createCookie();
pb.environment().putAll(cookie);
if (env != null) {
pb.environment().putAll(env);
}
final Process proc = pb.start();
proc = pb.start();
new StreamCopyThread("stderr copier for remote agent on " + computer.getDisplayName(), proc.getErrorStream(), listener.getLogger()).start();
computer.setChannel(proc.getInputStream(), proc.getOutputStream(), listener.getLogger(), new Channel.Listener() {
@Override
public void onClosed(Channel channel, IOException cause) {
try {
ProcessTree.get().killAll(proc, cookie);
} catch (Exception x) {
LOGGER.log(Level.WARNING, null, x);
}
}
});
computer.setChannel(proc.getInputStream(), proc.getOutputStream(), listener, null);
LOGGER.log(Level.INFO, "agent launched for {0}", computer.getName());
} catch (Exception x) {
LOGGER.log(Level.WARNING, null, x);
}
}

@SuppressFBWarnings(value = "IS2_INCONSISTENT_SYNC", justification = "test code, close enough")
@Override
public synchronized void afterDisconnect(SlaveComputer computer, TaskListener listener) {
if (proc != null) {
try {
ProcessTree.get().killAll(proc, cookie);
LOGGER.info(() -> "killed " + proc + " with " + cookie + " for " + computer.getName());
} catch (Exception x) {
LOGGER.log(Level.WARNING, "failed to kill " + proc + " with " + cookie + " for " + computer.getName(), x);
}
proc = null;
cookie = null;
} else {
LOGGER.info(() -> "no process for " + computer.getName());
}
}

@Extension
public static class DescriptorImpl extends Descriptor<ComputerLauncher> {}
}

0 comments on commit 256947e

Please sign in to comment.