I'm trying to execute a command (e.g. curl
) in a pod and evaluate the stdout of that command on my client. This works perfectly fine on my machine, however not when executed in a GitLab pipeline. The command itself is executed in both cases, however in GitLab, the stdout of that command is not returned. I could verify that logCapture.Write()
is never called and thus logCapture.GetStdOut()
returns an empty string. Oddly enough, when I execute the program in GitLab using the Interactive Web Terminal, the program succeeds, i.e. stdout is returned to the client.
Hope someone has a good guess what the problem might be.
Here is the corresponding code:
func execCommandInPod(c *Client, pod corev1.Pod, cmd []string) (string, error) {
req := c.Clientset.CoreV1().RESTClient().Post().Resource("pods").Name(pod.Name).Namespace(pod.Namespace).SubResource("exec")
option := &corev1.PodExecOptions{
Command: cmd,
Stdin: true,
Stdout: true,
Stderr: true,
TTY: true,
}
req.VersionedParams(
option,
scheme.ParameterCodec,
)
exec, err := remotecommand.NewSPDYExecutor(c.Config, "POST", req.URL())
if err != nil {
return "", err
}
capture := &logCapture{}
errorCapture := &logCapture{}
err = exec.Stream(remotecommand.StreamOptions{
Stdin: os.Stdin,
Stdout: capture,
Stderr: errorCapture,
Tty: false,
})
cmdOutput := capture.GetStdOut()
return cmdOutput, err
}
type Client struct {
Config *restclient.Config
Clientset *kubernetes.Clientset
}
type logCapture struct {
buffer bytes.Buffer
}
func (capture *logCapture) GetStdOut() string {
log.Infof("Buffer length: %d", capture.buffer.Len())
return capture.buffer.String()
}
func (capture *logCapture) Write(p []byte) (n int, err error) {
log.Infof("Writing bytes of length %d.", len(p))
a := strings.TrimSpace(string(p))
capture.buffer.WriteString(a)
return len(p), nil
}