package cluster import ( "bytes" "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/tools/remotecommand" "github.com/zalando-incubator/postgres-operator/pkg/spec" ) func (c *Cluster) 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, metav1.GetOptions{}) if err != nil { return "", fmt.Errorf("could not get pod info: %v", err) } if len(pod.Spec.Containers) != 1 { return "", fmt.Errorf("could not determine which container to use") } req := c.KubeClient.RESTClient.Post(). Resource("pods"). Name(podName.Name). Namespace(podName.Namespace). SubResource("exec") req.VersionedParams(&v1.PodExecOptions{ Container: pod.Spec.Containers[0].Name, Command: command, Stdout: true, Stderr: true, }, scheme.ParameterCodec) exec, err := remotecommand.NewExecutor(c.RestConfig, "POST", req.URL()) if err != nil { return "", fmt.Errorf("failed to init executor: %v", err) } err = exec.Stream(remotecommand.StreamOptions{ SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols, Stdout: &execOut, Stderr: &execErr, }) if err != nil { return "", fmt.Errorf("could not execute: %v", err) } if execErr.Len() > 0 { return "", fmt.Errorf("stderr: %v", execErr.String()) } return execOut.String(), nil }