我正在使用 golang kubernetes 客户端创建 kubernetes pod 并在其中执行远程命令。但是,我发现在远程执行完成之前我无法获得有关远程执行状态的反馈,因为我无法弄清楚如何流式传输远程命令的日志。这是我当前执行远程命令的实现:
func (k *KubernetesClient) RunCommand(ctx context.Context, args *RunCommandArgs) (string, int, error) {
req := k.clientset.CoreV1().RESTClient().Post().Resource("pods").Name(args.ContainerId).Namespace(k.namespace).SubResource("exec").Param("container", CONTAINER_NAME)
scheme := runtime.NewScheme()
if err := v1.AddToScheme(scheme); err != nil {
return "", 0, fmt.Errorf("could not add to scheme: %w", err)
}
parameterCodec := runtime.NewParameterCodec(scheme)
req.VersionedParams(&v1.PodExecOptions{
Stdin: false,
Stdout: true,
Stderr: true,
TTY: false,
Container: args.ContainerId,
Command: []string{"sh", "-c", args.Command},
}, parameterCodec)
exec, err := remotecommand.NewSPDYExecutor(k.config, "POST", req.URL())
if err != nil {
return "", 0, fmt.Errorf("could not exec command: %w", err)
}
var stdout, stderr bytes.Buffer
var streamErr error
streamErr = exec.Stream(remotecommand.StreamOptions{
Stdin: nil,
Stdout: &stdout,
Stderr: &stderr,
Tty: false,
})
if streamErr != nil {
if strings.Contains(streamErr.Error(), "command terminated with exit code") {
return stderr.String(), 1, nil
} else {
return "", 0, fmt.Errorf("could not stream results: %w", streamErr)
}
}
return stdout.String(), 0, nil
}
在这个实现中,我不知道远程命令的状态,直到它完成执行,此时我一次获得所有输出日志。
有没有办法在通过调用来读取stdout
/stderr
时读取它们exec.Stream
?在理想的世界中,我希望能够逐行打印远程命令行的输出。我注意到bytes.Buffer
有一个ReadString
接受分隔符的方法。这看起来像是一个有用的方法,但我无法弄清楚如何使用它。