From 449eb3bb7d93dbc71c1f52f48a7de6f049c76074 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Thu, 25 Apr 2019 15:51:53 -0700 Subject: [PATCH] Fix exec parameter parsing (#580) Exec seems to be broken by ad6fbba806a9470fc6d3feef636ee339632c4ab8 This change basically copies what's in remotecommand.NewOptions, just without the logging. --- Gopkg.lock | 1 + vkubelet/api/exec.go | 51 ++++++++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 96bb9d92f..4db6c966c 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1849,6 +1849,7 @@ "k8s.io/client-go/tools/watch", "k8s.io/client-go/util/workqueue", "k8s.io/kubernetes/pkg/api/v1/pod", + "k8s.io/kubernetes/pkg/apis/core", "k8s.io/kubernetes/pkg/apis/core/pods", "k8s.io/kubernetes/pkg/apis/core/v1/helper", "k8s.io/kubernetes/pkg/fieldpath", diff --git a/vkubelet/api/exec.go b/vkubelet/api/exec.go index dd4aa5672..279a6dd74 100644 --- a/vkubelet/api/exec.go +++ b/vkubelet/api/exec.go @@ -6,7 +6,10 @@ import ( "strings" "time" + "github.com/cpuguy83/strongerrors" "github.com/gorilla/mux" + "github.com/pkg/errors" + api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" ) @@ -14,7 +17,7 @@ import ( // Note that this handler currently depends on gorrilla/mux to get url parts as variables. // TODO(@cpuguy83): don't force gorilla/mux on consumers of this function func PodExecHandlerFunc(backend remotecommand.Executor) http.HandlerFunc { - return func(w http.ResponseWriter, req *http.Request) { + return handleError(func(w http.ResponseWriter, req *http.Request) error { vars := mux.Vars(req) namespace := vars["namespace"] @@ -26,30 +29,36 @@ func PodExecHandlerFunc(backend remotecommand.Executor) http.HandlerFunc { q := req.URL.Query() command := q["command"] - var stdin, stdout, stderr, tty bool - if q.Get("stdin") == "true" { - stdin = true - } - if q.Get("stdout") == "true" { - stdout = true - } - if q.Get("stderr") == "true" { - stderr = true - } - if q.Get("tty") == "true" { - tty = true - } - - streamOpts := &remotecommand.Options{ - Stdin: stdin, - Stdout: stdout, - Stderr: stderr, - TTY: tty, + streamOpts, err := getExecOptions(req) + if err != nil { + return strongerrors.InvalidArgument(err) } idleTimeout := time.Second * 30 streamCreationTimeout := time.Second * 30 remotecommand.ServeExec(w, req, backend, fmt.Sprintf("%s-%s", namespace, pod), "", container, command, streamOpts, idleTimeout, streamCreationTimeout, supportedStreamProtocols) - } + return nil + }) +} + +func getExecOptions(req *http.Request) (*remotecommand.Options, error) { + tty := req.FormValue(api.ExecTTYParam) == "1" + stdin := req.FormValue(api.ExecStdinParam) == "1" + stdout := req.FormValue(api.ExecStdoutParam) == "1" + stderr := req.FormValue(api.ExecStderrParam) == "1" + if tty && stderr { + return nil, errors.New("cannot exec with tty and stderr") + } + + if !stdin && !stdout && !stderr { + return nil, errors.New("you must specify at least one of stdin, stdout, stderr") + } + return &remotecommand.Options{ + Stdin: stdin, + Stdout: stdout, + Stderr: stderr, + TTY: tty, + }, nil + }