11package org .csanchez .jenkins .plugins .kubernetes .pipeline ;
22
33
4+ import hudson .Proc ;
5+ import io .fabric8 .kubernetes .client .dsl .ExecWatch ;
6+ import org .apache .commons .io .output .NullPrintStream ;
7+ import jenkins .util .Timer ;
8+
49import java .io .ByteArrayOutputStream ;
510import java .io .Closeable ;
611import java .io .IOException ;
712import java .io .InputStream ;
813import java .io .OutputStream ;
14+ import java .io .PrintStream ;
915import java .nio .charset .StandardCharsets ;
1016import java .util .concurrent .Callable ;
17+ import java .util .concurrent .CompletableFuture ;
1118import java .util .concurrent .CountDownLatch ;
19+ import java .util .concurrent .ExecutionException ;
1220import java .util .concurrent .TimeUnit ;
1321import java .util .concurrent .atomic .AtomicBoolean ;
1422import java .util .logging .Level ;
1523import java .util .logging .Logger ;
1624
17- import hudson .Proc ;
18- import io .fabric8 .kubernetes .client .dsl .ExecWatch ;
19- import jenkins .util .Timer ;
20- import static org .csanchez .jenkins .plugins .kubernetes .pipeline .Constants .CTRL_C ;
21- import static org .csanchez .jenkins .plugins .kubernetes .pipeline .Constants .EXIT ;
22- import static org .csanchez .jenkins .plugins .kubernetes .pipeline .Constants .NEWLINE ;
25+ import static org .csanchez .jenkins .plugins .kubernetes .pipeline .Constants .*;
2326
2427/**
2528 * Handle the liveness of the processes executed in containers, wait for them to finish and process exit codes.
@@ -34,29 +37,32 @@ public class ContainerExecProc extends Proc implements Closeable, Runnable {
3437 private final ExecWatch watch ;
3538 private final OutputStream stdin ;
3639
40+ private final PrintStream printStream ;
41+
3742 @ Deprecated
3843 public ContainerExecProc (ExecWatch watch , AtomicBoolean alive , CountDownLatch finished ,
3944 Callable <Integer > exitCode ) {
40- this (watch , alive , finished , (OutputStream ) null );
45+ this (watch , alive , finished , (OutputStream ) null , ( PrintStream ) null );
4146 }
4247
4348 @ Deprecated
4449 public ContainerExecProc (ExecWatch watch , AtomicBoolean alive , CountDownLatch finished ,
4550 ByteArrayOutputStream error ) {
46- this (watch , alive , finished , (OutputStream ) null );
51+ this (watch , alive , finished , (OutputStream ) null , ( PrintStream ) null );
4752 }
4853
4954 @ Deprecated
5055 public ContainerExecProc (ExecWatch watch , AtomicBoolean alive , CountDownLatch finished , OutputStream stdin ,
5156 ByteArrayOutputStream error ) {
52- this (watch , alive , finished , stdin );
57+ this (watch , alive , finished , stdin , ( PrintStream ) null );
5358 }
5459
55- public ContainerExecProc (ExecWatch watch , AtomicBoolean alive , CountDownLatch finished , OutputStream stdin ) {
60+ public ContainerExecProc (ExecWatch watch , AtomicBoolean alive , CountDownLatch finished , OutputStream stdin , PrintStream printStream ) {
5661 this .watch = watch ;
5762 this .stdin = stdin == null ? watch .getInput () : stdin ;
5863 this .alive = alive ;
5964 this .finished = finished ;
65+ this .printStream = printStream == null ? NullPrintStream .NULL_PRINT_STREAM : printStream ;
6066 Timer .get ().schedule (this , 1 , TimeUnit .MINUTES );
6167 }
6268
@@ -86,7 +92,33 @@ public int join() throws IOException, InterruptedException {
8692 LOGGER .log (Level .FINEST , "Waiting for websocket to close on command finish ({0})" , finished );
8793 finished .await ();
8894 LOGGER .log (Level .FINEST , "Command is finished ({0})" , finished );
89- return watch .exitCode ().join ();
95+
96+ CompletableFuture <Integer > exitCodeFuture = watch .exitCode ();
97+
98+ if (exitCodeFuture == null ) {
99+ LOGGER .log (Level .FINEST , "exitCodeFuture is null." );
100+ printStream .print ("exitCodeFuture is null." );
101+ return -1 ;
102+ }
103+
104+ Integer exitCode = exitCodeFuture .get ();
105+
106+ if (exitCode == null ) {
107+ LOGGER .log (Level .FINEST , "The container exec watch was closed before it could obtain an exit code from the process." );
108+ printStream .print ("The container exec watch was closed before it could obtain an exit code from the process." );
109+ return -1 ;
110+ }
111+ return exitCode ;
112+ } catch (ExecutionException e ) {
113+ Throwable cause = e .getCause ();
114+ if (cause != null ) {
115+ LOGGER .log (Level .FINEST , "ExecutionException occurred while waiting for exit code" , cause );
116+ printStream .printf ("ExecutionException occurred while waiting for exit code: %s%n" , cause );
117+ } else {
118+ LOGGER .log (Level .FINEST , "ExecutionException occurred while waiting for exit code" , e );
119+ printStream .printf ("ExecutionException occurred while waiting for exit code: %s%n" , e );
120+ }
121+ return -1 ;
90122 } finally {
91123 close ();
92124 }
0 commit comments