Search in sources :

Example 1 with IOTrio

use of io.kubernetes.client.custom.IOTrio in project java by kubernetes-client.

the class Exec method exec.

/**
 * A convenience method. Executes a command remotely on a pod and monitors for events in that
 * execution. The monitored events are: <br>
 * - connection established (onOpen) <br>
 * - connection closed (onClosed) <br>
 * - execution error occurred (onError) <br>
 * This method also allows to specify a MAX timeout for the execution and returns a future in
 * order to monitor the execution flow. <br>
 * onError and onClosed callbacks are invoked asynchronously, in a separate thread. <br>
 *
 * @param namespace a namespace the target pod "lives" in
 * @param podName a name of the pod to exec the command on
 * @param onOpen a callback invoked upon the connection established event.
 * @param onClosed a callback invoked upon the process termination. Return code might not always
 *     be there. N.B. this callback is invoked before the returned {@link Future} is completed.
 * @param onError a callback to handle k8s errors (NOT the command errors/stderr!)
 * @param timeoutMs timeout in milliseconds for the execution. I.e. the execution will take this
 *     many ms or less. If the timeout command is running longer than the allowed timeout, the
 *     command will be "asked" to terminate gracefully. If the command is still running after the
 *     grace period, the sigkill will be issued. If null is passed, the timeout will not be used
 *     and will wait for process to exit itself.
 * @param tty whether you need tty to pipe the data. TTY mode will trim some binary data in order
 *     to make it possible to show on screen (tty)
 * @param command a tokenized command to run on the pod
 * @return a {@link Future} promise representing this execution. Unless something goes south, the
 *     promise will contain the process return exit code. If the timeoutMs is non-null and the
 *     timeout expires before the process exits, promise will contain {@link Integer#MAX_VALUE}.
 * @throws IOException
 */
public Future<Integer> exec(String namespace, String podName, Consumer<IOTrio> onOpen, BiConsumer<Integer, IOTrio> onClosed, BiConsumer<Throwable, IOTrio> onError, Long timeoutMs, boolean tty, String... command) throws IOException {
    CompletableFuture<Integer> future = new CompletableFuture<>();
    IOTrio io = new IOTrio();
    String cmdStr = Arrays.toString(command);
    BiConsumer<Throwable, IOTrio> errHandler = (err, errIO) -> {
        if (onError != null) {
            onError.accept(err, errIO);
        }
    };
    try {
        Process process = exec(namespace, podName, command, null, true, tty);
        io.onClose((code, timeout) -> {
            process.destroy();
            waitForProcessToExit(process, timeout, cmdStr, err -> errHandler.accept(err, io));
        // processWaitingThread will handle the rest
        });
        io.setStdin(process.getOutputStream());
        io.setStdout(process.getInputStream());
        io.setStderr(process.getErrorStream());
        runAsync("Process-Waiting-Thread-" + command[0] + "-" + podName, () -> {
            Supplier<Integer> returnCode = process::exitValue;
            try {
                log.debug("Waiting for process to close in {} ms: {}", timeoutMs, cmdStr);
                boolean beforeTimout = waitForProcessToExit(process, timeoutMs, cmdStr, err -> errHandler.accept(err, io));
                if (!beforeTimout) {
                    returnCode = () -> Integer.MAX_VALUE;
                }
            } catch (Exception e) {
                errHandler.accept(e, io);
            }
            log.debug("process.onExit({}): {}", returnCode.get(), cmdStr);
            if (onClosed != null) {
                onClosed.accept(returnCode.get(), io);
            }
            future.complete(returnCode.get());
        });
        if (onOpen != null) {
            onOpen.accept(io);
        }
    } catch (ApiException e) {
        errHandler.accept(e, io);
        future.completeExceptionally(e);
    }
    return future;
}
Also used : Arrays(java.util.Arrays) TypeToken(com.google.gson.reflect.TypeToken) IOTrio(io.kubernetes.client.custom.IOTrio) LoggerFactory(org.slf4j.LoggerFactory) KubernetesConstants(io.kubernetes.client.KubernetesConstants) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Supplier(java.util.function.Supplier) StringUtils(org.apache.commons.lang3.StringUtils) ApiClient(io.kubernetes.client.openapi.ApiClient) WebSockets(io.kubernetes.client.util.WebSockets) ApiException(io.kubernetes.client.openapi.ApiException) Future(java.util.concurrent.Future) Configuration(io.kubernetes.client.openapi.Configuration) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) OutputStream(java.io.OutputStream) Logger(org.slf4j.Logger) IOException(java.io.IOException) CoreV1Api(io.kubernetes.client.openapi.apis.CoreV1Api) Reader(java.io.Reader) V1Status(io.kubernetes.client.openapi.models.V1Status) InputStreamReader(java.io.InputStreamReader) Streams(io.kubernetes.client.util.Streams) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CountDownLatch(java.util.concurrent.CountDownLatch) URLEncoder(java.net.URLEncoder) List(java.util.List) V1StatusCause(io.kubernetes.client.openapi.models.V1StatusCause) Type(java.lang.reflect.Type) WebSocketStreamHandler(io.kubernetes.client.util.WebSocketStreamHandler) UnsupportedEncodingException(java.io.UnsupportedEncodingException) V1StatusDetails(io.kubernetes.client.openapi.models.V1StatusDetails) V1Pod(io.kubernetes.client.openapi.models.V1Pod) InputStream(java.io.InputStream) ApiException(io.kubernetes.client.openapi.ApiException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CompletableFuture(java.util.concurrent.CompletableFuture) IOTrio(io.kubernetes.client.custom.IOTrio) ApiException(io.kubernetes.client.openapi.ApiException)

Aggregations

TypeToken (com.google.gson.reflect.TypeToken)1 KubernetesConstants (io.kubernetes.client.KubernetesConstants)1 IOTrio (io.kubernetes.client.custom.IOTrio)1 ApiClient (io.kubernetes.client.openapi.ApiClient)1 ApiException (io.kubernetes.client.openapi.ApiException)1 Configuration (io.kubernetes.client.openapi.Configuration)1 CoreV1Api (io.kubernetes.client.openapi.apis.CoreV1Api)1 V1Pod (io.kubernetes.client.openapi.models.V1Pod)1 V1Status (io.kubernetes.client.openapi.models.V1Status)1 V1StatusCause (io.kubernetes.client.openapi.models.V1StatusCause)1 V1StatusDetails (io.kubernetes.client.openapi.models.V1StatusDetails)1 Streams (io.kubernetes.client.util.Streams)1 WebSocketStreamHandler (io.kubernetes.client.util.WebSocketStreamHandler)1 WebSockets (io.kubernetes.client.util.WebSockets)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 OutputStream (java.io.OutputStream)1 Reader (java.io.Reader)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1