mirror of https://github.com/k3s-io/k3s
Merge pull request #6574 from ncdc/exec-portforward-no-command-pipes
Don't use command pipes for exec/port forwardpull/6/head
commit
fce3e5a2bb
|
@ -221,6 +221,11 @@ func (d *dockerContainerCommandRunner) RunInContainer(containerID string, cmd []
|
||||||
// - should we support nsenter in a container, running with elevated privs and --pid=host?
|
// - should we support nsenter in a container, running with elevated privs and --pid=host?
|
||||||
// - use strong type for containerId
|
// - use strong type for containerId
|
||||||
func (d *dockerContainerCommandRunner) ExecInContainer(containerId string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
|
func (d *dockerContainerCommandRunner) ExecInContainer(containerId string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
|
||||||
|
nsenter, err := exec.LookPath("nsenter")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("exec unavailable - unable to locate nsenter")
|
||||||
|
}
|
||||||
|
|
||||||
container, err := d.client.InspectContainer(containerId)
|
container, err := d.client.InspectContainer(containerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -237,8 +242,7 @@ func (d *dockerContainerCommandRunner) ExecInContainer(containerId string, cmd [
|
||||||
args = append(args, fmt.Sprintf("HOSTNAME=%s", container.Config.Hostname))
|
args = append(args, fmt.Sprintf("HOSTNAME=%s", container.Config.Hostname))
|
||||||
args = append(args, container.Config.Env...)
|
args = append(args, container.Config.Env...)
|
||||||
args = append(args, cmd...)
|
args = append(args, cmd...)
|
||||||
command := exec.Command("nsenter", args...)
|
command := exec.Command(nsenter, args...)
|
||||||
// TODO use exec.LookPath
|
|
||||||
if tty {
|
if tty {
|
||||||
p, err := StartPty(command)
|
p, err := StartPty(command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -259,39 +263,24 @@ func (d *dockerContainerCommandRunner) ExecInContainer(containerId string, cmd [
|
||||||
|
|
||||||
return command.Wait()
|
return command.Wait()
|
||||||
} else {
|
} else {
|
||||||
cp := func(dst io.WriteCloser, src io.Reader, closeDst bool) {
|
|
||||||
defer func() {
|
|
||||||
if closeDst {
|
|
||||||
dst.Close()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
io.Copy(dst, src)
|
|
||||||
}
|
|
||||||
if stdin != nil {
|
if stdin != nil {
|
||||||
inPipe, err := command.StdinPipe()
|
// Use an os.Pipe here as it returns true *os.File objects.
|
||||||
|
// This way, if you run 'kubectl exec -p <pod> -i bash' (no tty) and type 'exit',
|
||||||
|
// the call below to command.Run() can unblock because its Stdin is the read half
|
||||||
|
// of the pipe.
|
||||||
|
r, w, err := os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go func() {
|
go io.Copy(w, stdin)
|
||||||
cp(inPipe, stdin, false)
|
|
||||||
inPipe.Close()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
command.Stdin = r
|
||||||
|
}
|
||||||
if stdout != nil {
|
if stdout != nil {
|
||||||
outPipe, err := command.StdoutPipe()
|
command.Stdout = stdout
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
go cp(stdout, outPipe, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if stderr != nil {
|
if stderr != nil {
|
||||||
errPipe, err := command.StderrPipe()
|
command.Stderr = stderr
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
go cp(stderr, errPipe, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return command.Run()
|
return command.Run()
|
||||||
|
@ -325,16 +314,8 @@ func (d *dockerContainerCommandRunner) PortForward(pod *kubecontainer.Pod, port
|
||||||
args := []string{"-t", fmt.Sprintf("%d", containerPid), "-n", "socat", "-", fmt.Sprintf("TCP4:localhost:%d", port)}
|
args := []string{"-t", fmt.Sprintf("%d", containerPid), "-n", "socat", "-", fmt.Sprintf("TCP4:localhost:%d", port)}
|
||||||
// TODO use exec.LookPath
|
// TODO use exec.LookPath
|
||||||
command := exec.Command("nsenter", args...)
|
command := exec.Command("nsenter", args...)
|
||||||
in, err := command.StdinPipe()
|
command.Stdin = stream
|
||||||
if err != nil {
|
command.Stdout = stream
|
||||||
return err
|
|
||||||
}
|
|
||||||
out, err := command.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
go io.Copy(in, stream)
|
|
||||||
go io.Copy(stream, out)
|
|
||||||
return command.Run()
|
return command.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue