2

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
}
Sirea
  • 53
  • 4
  • Have you checked if the output is in "errorCapture" (stderr) instead of "capture" (stdout) inside GitLab? – Daniel Vigueras Nov 09 '22 at 11:38
  • @DanielVigueras Not sure anymore but I probably didn't check that. My assumption was that with `err = exec. Stream(remotecommand.StreamOptions{ Stdin: os.Stdin, Stdout: capture, Stderr: errorCapture, Tty: false, })` stdout and stderr would be written to `logCapture`. – Sirea Nov 11 '22 at 10:00

0 Answers0