24
24
25
25
package org .jvnet .hudson .test ;
26
26
27
+ import edu .umd .cs .findbugs .annotations .SuppressFBWarnings ;
27
28
import hudson .AbortException ;
28
29
import hudson .EnvVars ;
29
30
import hudson .Extension ;
30
31
import hudson .Util ;
31
32
import hudson .model .Descriptor ;
32
33
import hudson .model .Slave ;
33
34
import hudson .model .TaskListener ;
34
- import hudson .remoting .Channel ;
35
35
import hudson .slaves .ComputerLauncher ;
36
36
import hudson .slaves .SlaveComputer ;
37
37
import hudson .util .ProcessTree ;
38
38
import hudson .util .StreamCopyThread ;
39
- import java .io .IOException ;
40
39
import java .util .HashMap ;
41
40
import java .util .Map ;
42
41
import java .util .logging .Level ;
@@ -52,6 +51,8 @@ public class SimpleCommandLauncher extends ComputerLauncher {
52
51
53
52
public final String cmd ;
54
53
private final Map <String , String > env ;
54
+ private transient Process proc ;
55
+ private transient EnvVars cookie ;
55
56
56
57
@ DataBoundConstructor // in case anyone needs to configRoundtrip such a node
57
58
public SimpleCommandLauncher (String cmd ) {
@@ -72,29 +73,37 @@ public void launch(SlaveComputer computer, final TaskListener listener) {
72
73
}
73
74
listener .getLogger ().println ("$ " + cmd );
74
75
ProcessBuilder pb = new ProcessBuilder (Util .tokenize (cmd ));
75
- final EnvVars cookie = EnvVars .createCookie ();
76
+ cookie = EnvVars .createCookie ();
76
77
pb .environment ().putAll (cookie );
77
78
if (env != null ) {
78
79
pb .environment ().putAll (env );
79
80
}
80
- final Process proc = pb .start ();
81
+ proc = pb .start ();
81
82
new StreamCopyThread ("stderr copier for remote agent on " + computer .getDisplayName (), proc .getErrorStream (), listener .getLogger ()).start ();
82
- computer .setChannel (proc .getInputStream (), proc .getOutputStream (), listener .getLogger (), new Channel .Listener () {
83
- @ Override
84
- public void onClosed (Channel channel , IOException cause ) {
85
- try {
86
- ProcessTree .get ().killAll (proc , cookie );
87
- } catch (Exception x ) {
88
- LOGGER .log (Level .WARNING , null , x );
89
- }
90
- }
91
- });
83
+ computer .setChannel (proc .getInputStream (), proc .getOutputStream (), listener , null );
92
84
LOGGER .log (Level .INFO , "agent launched for {0}" , computer .getName ());
93
85
} catch (Exception x ) {
94
86
LOGGER .log (Level .WARNING , null , x );
95
87
}
96
88
}
97
89
90
+ @ SuppressFBWarnings (value = "IS2_INCONSISTENT_SYNC" , justification = "test code, close enough" )
91
+ @ Override
92
+ public synchronized void afterDisconnect (SlaveComputer computer , TaskListener listener ) {
93
+ if (proc != null ) {
94
+ try {
95
+ ProcessTree .get ().killAll (proc , cookie );
96
+ LOGGER .info (() -> "killed " + proc + " with " + cookie + " for " + computer .getName ());
97
+ } catch (Exception x ) {
98
+ LOGGER .log (Level .WARNING , "failed to kill " + proc + " with " + cookie + " for " + computer .getName (), x );
99
+ }
100
+ proc = null ;
101
+ cookie = null ;
102
+ } else {
103
+ LOGGER .info (() -> "no process for " + computer .getName ());
104
+ }
105
+ }
106
+
98
107
@ Extension
99
108
public static class DescriptorImpl extends Descriptor <ComputerLauncher > {}
100
109
}
0 commit comments