Hello community,
I have the following code, leveraging the Kubernetes go client for executing a shell command in a pod programmatically:
// ExecuteRemoteCommand executes a remote shell command on the given pod
// returns the output from stdout and stderr
func ExecuteRemoteCommand(pod *v1.Pod, command string) (string, string, error) {
kubeCfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
clientcmd.NewDefaultClientConfigLoadingRules(),
&clientcmd.ConfigOverrides{},
)
restCfg, err := kubeCfg.ClientConfig()
if err != nil {
return "", "", err
}
coreClient, err := corev1client.NewForConfig(restCfg)
if err != nil {
return "", "", err
}
buf := &bytes.Buffer{}
errBuf := &bytes.Buffer{}
request := coreClient.RESTClient().
Post().
Namespace(pod.Namespace).
Resource("pods").
Name(pod.Name).
SubResource("exec").
VersionedParams(&k8s_corev1.PodExecOptions{
Command: []string{"/bin/sh", "-c", command},
Stdin: true,
Stdout: true,
Stderr: true,
TTY: true,
}, scheme.ParameterCodec)
exec, err := remotecommand.NewSPDYExecutor(restCfg, "POST", request.URL())
err = exec.Stream(remotecommand.StreamOptions{
Stdout: buf,
Stderr: errBuf,
})
if err != nil {
return "", "", errors.Wrapf(err, "Failed executing command %s on %v/%v", command, pod.Namespace, pod.Name)
}
return buf.String(), errBuf.String(), nil
}
I find there is some flakiness in this code - I sometimes get output from the shell command and I sometimes don’t. The command I’m using it ls
, so it should always return some output.
exec.Stream()
is synchronous, right?
Has anybody had any experience with similar functionality?