【发布时间】:2021-09-07 03:10:51
【问题描述】:
我一直在使用 client-go 测试 kubernetes pod 的 exec 功能。这是与 os.Stdin 完美配合的代码
{
// Prepare the API URL used to execute another process within the Pod. In
// this case, we'll run a remote shell.
req := coreclient.RESTClient().
Post().
Namespace(pod.Namespace).
Resource("pods").
Name(pod.Name).
SubResource("exec").
VersionedParams(&corev1.PodExecOptions{
Container: pod.Spec.Containers[0].Name,
Command: []string{"/bin/sh"},
Stdin: true,
Stdout: true,
Stderr: true,
TTY: true,
}, scheme.ParameterCodec)
exec, err := remotecommand.NewSPDYExecutor(restconfig, "POST", req.URL())
if err != nil {
panic(err)
}
// Put the terminal into raw mode to prevent it echoing characters twice.
oldState, err := terminal.MakeRaw(0)
if err != nil {
panic(err)
}
defer terminal.Restore(0, oldState)
// Connect this process' std{in,out,err} to the remote shell process.
err = exec.Stream(remotecommand.StreamOptions{
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
Tty: true,
})
if err != nil {
panic(err)
}
fmt.Println()
}
然后我开始使用 io.Pipe() 进行测试,这样我就可以在 os.Stdin 之外为其提供输入,基本上来自变量或任何其他来源。修改后的代码可以在这里找到
{
// Prepare the API URL used to execute another process within the Pod. In
// this case, we'll run a remote shell.
req := coreclient.RESTClient().
Post().
Namespace(pod.Namespace).
Resource("pods").
Name(pod.Name).
SubResource("exec").
VersionedParams(&corev1.PodExecOptions{
Container: pod.Spec.Containers[0].Name,
Command: []string{"/bin/sh"},
Stdin: true,
Stdout: true,
Stderr: true,
TTY: true,
}, scheme.ParameterCodec)
exec, err := remotecommand.NewSPDYExecutor(restconfig, "POST", req.URL())
if err != nil {
panic(err)
}
// Put the terminal into raw mode to prevent it echoing characters twice.
oldState, err := terminal.MakeRaw(0)
if err != nil {
panic(err)
}
defer terminal.Restore(0, oldState)
// Scanning for inputs from os.stdin
stdin, putStdin := io.Pipe()
go func() {
consolescanner := bufio.NewScanner(os.Stdin)
for consolescanner.Scan() {
input := consolescanner.Text()
fmt.Println("input:", input)
putStdin.Write([]byte(input))
}
if err := consolescanner.Err(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}()
// Connect this process' std{in,out,err} to the remote shell process.
err = exec.Stream(remotecommand.StreamOptions{
Stdin: stdin,
Stdout: os.Stdout,
Stderr: os.Stdout,
Tty: true,
})
if err != nil {
panic(err)
}
fmt.Println()
}
这奇怪地似乎挂了终端,有人可以指出我做错了什么吗?
【问题讨论】:
-
代码太多无法使用 - 如果您可以提供更精简的可生产代码会更好,但乍一看,我认为使用
bufio.Scanner和putStdin.Write,您正在删除输入中的换行符 (\n)。 -
@leafbebop 我已经编辑了重要的代码部分以使其最小化。这对现在有帮助吗?为了回答您以后的陈述,我不打算删除换行符,我想使用 io.pipe() 扩展 os.stdin
-
您是否尝试过添加换行符?
-
@leafbebop 是的,我确实尝试过,但没有帮助。问题是我在 STDIN 中输入的任何内容都不再反映在变量中。
-
你的意思是什么变量?你不能打印吗?
标签: go kubernetes exec client-go