From 0f997aade423fe2612250096cf87015d040d7099 Mon Sep 17 00:00:00 2001 From: Ilya Kuznetsov Date: Thu, 18 Aug 2022 13:26:01 +0300 Subject: [PATCH] docs: Add examples of "attach to pod" functionality --- README.md | 1 + .../kubernetes/examples/AttachExample.java | 88 +++++++++++++++++++ .../equivalents/PodAttachEquivalent.java | 84 ++++++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/AttachExample.java create mode 100644 kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodAttachEquivalent.java diff --git a/README.md b/README.md index 1cd383c78b..0e7b1a3511 100644 --- a/README.md +++ b/README.md @@ -666,6 +666,7 @@ operations. However, some might require slightly more code to achieve same resul | `kubectl run` | [PodRunEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodRunEquivalent.java) | | `kubectl create -f test-pod.yaml` | [PodCreateYamlEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodCreateYamlEquivalent.java) | | `kubectl exec my-pod -- ls /` | [PodExecEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodExecEquivalent.java) | +| `kubectl attach my-pod` | [PodAttachEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodAttachEquivalent.java) | | `kubectl delete pod my-pod` | [PodDelete.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodDelete.java) | | `kubectl delete -f test-pod.yaml` | [PodDeleteViaYaml.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodDeleteViaYaml.java) | | `kubectl cp /foo_dir my-pod:/bar_dir` | [UploadDirectoryToPod.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/UploadDirectoryToPod.java) | diff --git a/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/AttachExample.java b/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/AttachExample.java new file mode 100644 index 0000000000..234af959cb --- /dev/null +++ b/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/AttachExample.java @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.kubernetes.examples; + +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientBuilder; +import io.fabric8.kubernetes.client.dsl.ExecListener; +import io.fabric8.kubernetes.client.dsl.ExecWatch; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; + +/** + * This is an example of attaching to pod to access stdin, stdout, stderr + */ +public class AttachExample { + + public static void main(String[] args) throws IOException { + if (args.length < 1) { + System.out.println("Usage: podName [namespace]"); + return; + } + + String podName = args[0]; + String namespace = "default"; + + if (args.length > 1) { + namespace = args[1]; + } + + CompletableFuture sessionFuture = new CompletableFuture<>(); + try ( + KubernetesClient client = new KubernetesClientBuilder().build(); + ExecWatch watch = attach(client, namespace, podName, sessionFuture)) { + System.out.println("Type 'exit' to detach"); + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + while (true) { + String input = reader.readLine(); + if (input.equals("exit")) { + return; + } + watch.getInput().write((input + "\n").getBytes(StandardCharsets.UTF_8)); + watch.getInput().flush(); + if (sessionFuture.isDone()) { + System.out.println("Session closed"); + return; + } + } + } + } + + private static ExecWatch attach(KubernetesClient client, String namespace, String podName, + CompletableFuture sessionFuture) { + return client.pods().inNamespace(namespace).withName(podName) + .redirectingInput() + .writingOutput(System.out) + .writingError(System.err) + .withTTY() + .usingListener(new ExecListener() { + @Override + public void onFailure(Throwable t, Response failureResponse) { + sessionFuture.complete(null); + } + + @Override + public void onClose(int code, String reason) { + sessionFuture.complete(null); + } + }) + .attach(); + } +} diff --git a/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodAttachEquivalent.java b/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodAttachEquivalent.java new file mode 100644 index 0000000000..46c5fceb9b --- /dev/null +++ b/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodAttachEquivalent.java @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.kubernetes.examples.kubectl.equivalents; + +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientBuilder; +import io.fabric8.kubernetes.client.dsl.ExecListener; +import io.fabric8.kubernetes.client.dsl.ExecWatch; +import lombok.Getter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; + +/** + * This sample code is Java equivalent to `kubectl attach my-pod`. It assumes that + * a Pod with specified name exists in the cluster. + */ +public class PodAttachEquivalent { + + private static final Logger logger = LoggerFactory.getLogger(PodAttachEquivalent.class); + + public static void main(String[] args) throws IOException { + try (KubernetesClient client = new KubernetesClientBuilder().build()) { + MyAttachListener listener = new MyAttachListener(); + ExecWatch watch = client.pods().inNamespace("default").withName("my-pod") + .redirectingInput() + .writingOutput(System.out) + .writingError(System.err) + .withTTY() + .usingListener(listener) + .attach(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + while (!listener.getSessionCompletionFuture().isDone()) { + String input = reader.readLine(); + watch.getInput().write((input + "\n").getBytes(StandardCharsets.UTF_8)); + watch.getInput().flush(); + } + + watch.close(); + } + } + + private static class MyAttachListener implements ExecListener { + + @Getter + private final CompletableFuture sessionCompletionFuture = new CompletableFuture<>(); + + @Override + public void onOpen() { + logger.info("Attached to the pod"); + } + + @Override + public void onFailure(Throwable t, Response failureResponse) { + logger.warn("Error encountered", t); + sessionCompletionFuture.complete(null); + } + + @Override + public void onClose(int i, String s) { + logger.info("Session closed"); + sessionCompletionFuture.complete(null); + } + } +}