From 1b820091517aef34b744343a10593a0464a65de1 Mon Sep 17 00:00:00 2001 From: Murat Kabilov Date: Thu, 11 May 2017 16:01:21 +0200 Subject: [PATCH] Command exec inside the Pod method --- cmd/main.go | 1 + glide.lock | 6 ++-- glide.yaml | 1 + pkg/controller/controller.go | 1 + pkg/controller/exec.go | 61 ++++++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 pkg/controller/exec.go diff --git a/cmd/main.go b/cmd/main.go index 24263c73b..7ea626bd0 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -55,6 +55,7 @@ func ControllerConfig() *controller.Config { } return &controller.Config{ + RestConfig: restConfig, KubeClient: client, RestClient: restClient, } diff --git a/glide.lock b/glide.lock index 8b6564331..de52730df 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 5f99f20e4693c230cd709102e4bba350f87205bda86b2c6148ac79da05d7ae47 -updated: 2017-05-10T11:51:19.667157509+02:00 +hash: b2ea8a2133857a3860d2a63eec76a9eed71565f69723848ee17b77aacc49905b +updated: 2017-05-10T14:44:44.907924292+02:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -85,7 +85,7 @@ imports: - name: github.com/kr/text version: 7cafcd837844e784b526369c9bce262804aebc60 - name: github.com/lib/pq - version: 0477eb88c5ca4009cb281f13c90633375b6a9987 + version: 2704adc878c21e1329f46f6e56a1c387d788ff94 subpackages: - oid - name: github.com/mailru/easyjson diff --git a/glide.yaml b/glide.yaml index c366f1e5d..5917095a5 100644 --- a/glide.yaml +++ b/glide.yaml @@ -16,6 +16,7 @@ import: - package: k8s.io/apimachinery subpackages: - pkg/util/json + - pkg/util/remotecommand - package: k8s.io/client-go version: ^2.0.0 - package: k8s.io/kubernetes diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index b822be9d1..12372ce24 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -18,6 +18,7 @@ import ( ) type Config struct { + RestConfig *rest.Config KubeClient *kubernetes.Clientset RestClient *rest.RESTClient EtcdClient etcdclient.KeysAPI diff --git a/pkg/controller/exec.go b/pkg/controller/exec.go new file mode 100644 index 000000000..196912355 --- /dev/null +++ b/pkg/controller/exec.go @@ -0,0 +1,61 @@ +package controller + +import ( + "bytes" + "fmt" + + "k8s.io/client-go/pkg/api" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" + + "github.bus.zalan.do/acid/postgres-operator/pkg/spec" +) + +func (c *Controller) ExecCommand(podName spec.NamespacedName, command []string) (string, error) { + var ( + execOut bytes.Buffer + execErr bytes.Buffer + ) + + pod, err := c.KubeClient.Pods(podName.Namespace).Get(podName.Name) + if err != nil { + return "", fmt.Errorf("Can't get Pod info: %s", err) + } + + if len(pod.Spec.Containers) != 1 { + return "", fmt.Errorf("Can't determine which container to use") + } + + req := c.RestClient.Post(). + Resource("pods"). + Name(podName.Name). + Namespace(podName.Namespace). + SubResource("exec") + req.VersionedParams(&api.PodExecOptions{ + Container: pod.Spec.Containers[0].Name, + Command: command, + Stdout: true, + Stderr: true, + }, api.ParameterCodec) + + exec, err := remotecommand.NewExecutor(c.RestConfig, "POST", req.URL()) + if err != nil { + return "", fmt.Errorf("Failed to init executor: %s", err) + } + + err = exec.Stream(remotecommand.StreamOptions{ + SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols, + Stdout: &execOut, + Stderr: &execErr, + }) + + if err != nil { + return "", fmt.Errorf("Can't execute: %s", err) + } + + if execErr.Len() > 0 { + return "", fmt.Errorf("Stderr: %s", execErr.String()) + } + + return execOut.String(), nil +}