Backport: Fix exec parameter parsing (#580) (#604)

* Fix exec parameter parsing (#580)

Exec seems to be broken by ad6fbba806
This change basically copies what's in remotecommand.NewOptions, just
without the logging.

(cherry picked from commit 449eb3bb7d)

* Don't set cancel function to nil on error

Backported from ceb9b16c5c
This commit is contained in:
Brian Goff
2019-05-06 11:32:34 -07:00
committed by GitHub
parent 686cdb8b36
commit 7b92d1eee2
3 changed files with 33 additions and 23 deletions

1
Gopkg.lock generated
View File

@@ -1905,6 +1905,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/fieldpath",
"k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2",

View File

@@ -44,9 +44,9 @@ func loadTLSConfig(certPath, keyPath string) (*tls.Config, error) {
}, nil
}
func setupHTTPServer(ctx context.Context, cfg *apiServerConfig) (cancel func(), retErr error) {
func setupHTTPServer(ctx context.Context, cfg *apiServerConfig) (_ func(), retErr error) {
var closers []io.Closer
cancel = func() {
cancel := func() {
for _, c := range closers {
c.Close()
}

View File

@@ -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
}