Skip to content

Commit

Permalink
Merge pull request #1366 from salemove/fix-null-pointer-exception
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlatombe authored Oct 10, 2023
2 parents e41422f + 0bc0aad commit 2da8e27
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ public void onClose(int i, String s) {

LOGGER.log(Level.INFO, "Created process inside pod: [" + getPodName() + "], container: ["
+ containerName + "]" + "[" + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startMethod) + " ms]");
ContainerExecProc proc = new ContainerExecProc(watch, alive, finished, stdin);
ContainerExecProc proc = new ContainerExecProc(watch, alive, finished, stdin, printStream);
closables.add(proc);
return proc;
} catch (InterruptedException ie) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
package org.csanchez.jenkins.plugins.kubernetes.pipeline;


import hudson.Proc;
import io.fabric8.kubernetes.client.dsl.ExecWatch;
import org.apache.commons.io.output.NullPrintStream;
import jenkins.util.Timer;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;

import hudson.Proc;
import io.fabric8.kubernetes.client.dsl.ExecWatch;
import jenkins.util.Timer;
import static org.csanchez.jenkins.plugins.kubernetes.pipeline.Constants.CTRL_C;
import static org.csanchez.jenkins.plugins.kubernetes.pipeline.Constants.EXIT;
import static org.csanchez.jenkins.plugins.kubernetes.pipeline.Constants.NEWLINE;
import static org.csanchez.jenkins.plugins.kubernetes.pipeline.Constants.*;

/**
* Handle the liveness of the processes executed in containers, wait for them to finish and process exit codes.
Expand All @@ -34,29 +37,32 @@ public class ContainerExecProc extends Proc implements Closeable, Runnable {
private final ExecWatch watch;
private final OutputStream stdin;

private final PrintStream printStream;

@Deprecated
public ContainerExecProc(ExecWatch watch, AtomicBoolean alive, CountDownLatch finished,
Callable<Integer> exitCode) {
this(watch, alive, finished, (OutputStream) null);
this(watch, alive, finished, (OutputStream) null, (PrintStream) null);
}

@Deprecated
public ContainerExecProc(ExecWatch watch, AtomicBoolean alive, CountDownLatch finished,
ByteArrayOutputStream error) {
this(watch, alive, finished, (OutputStream) null);
this(watch, alive, finished, (OutputStream) null, (PrintStream) null);
}

@Deprecated
public ContainerExecProc(ExecWatch watch, AtomicBoolean alive, CountDownLatch finished, OutputStream stdin,
ByteArrayOutputStream error) {
this(watch, alive, finished, stdin);
this(watch, alive, finished, stdin, (PrintStream) null);
}

public ContainerExecProc(ExecWatch watch, AtomicBoolean alive, CountDownLatch finished, OutputStream stdin) {
public ContainerExecProc(ExecWatch watch, AtomicBoolean alive, CountDownLatch finished, OutputStream stdin, PrintStream printStream) {
this.watch = watch;
this.stdin = stdin == null ? watch.getInput() : stdin;
this.alive = alive;
this.finished = finished;
this.printStream = printStream == null ? NullPrintStream.NULL_PRINT_STREAM : printStream;
Timer.get().schedule(this, 1, TimeUnit.MINUTES);
}

Expand Down Expand Up @@ -86,7 +92,33 @@ public int join() throws IOException, InterruptedException {
LOGGER.log(Level.FINEST, "Waiting for websocket to close on command finish ({0})", finished);
finished.await();
LOGGER.log(Level.FINEST, "Command is finished ({0})", finished);
return watch.exitCode().join();

CompletableFuture<Integer> exitCodeFuture = watch.exitCode();

if (exitCodeFuture == null) {
LOGGER.log(Level.FINEST, "exitCodeFuture is null.");
printStream.print("exitCodeFuture is null.");
return -1;
}

Integer exitCode = exitCodeFuture.get();

if (exitCode == null) {
LOGGER.log(Level.FINEST, "The container exec watch was closed before it could obtain an exit code from the process.");
printStream.print("The container exec watch was closed before it could obtain an exit code from the process.");
return -1;
}
return exitCode;
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause != null) {
LOGGER.log(Level.FINEST, "ExecutionException occurred while waiting for exit code", cause);
printStream.printf("ExecutionException occurred while waiting for exit code: %s%n", cause);
} else {
LOGGER.log(Level.FINEST, "ExecutionException occurred while waiting for exit code", e);
printStream.printf("ExecutionException occurred while waiting for exit code: %s%n", e);
}
return -1;
} finally {
close();
}
Expand Down

0 comments on commit 2da8e27

Please sign in to comment.