diff --git a/pkg/client/tests/BUILD b/pkg/client/tests/BUILD index d31deb3f56..d6ccabed11 100644 --- a/pkg/client/tests/BUILD +++ b/pkg/client/tests/BUILD @@ -14,6 +14,7 @@ go_test( "fake_client_test.go", "listwatch_test.go", "portfoward_test.go", + "remotecommand_test.go", ], library = ":go_default_library", tags = ["automanaged"], @@ -26,10 +27,15 @@ go_test( "//pkg/client/clientset_generated/internalclientset/fake:go_default_library", "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubelet/server/portforward:go_default_library", + "//pkg/kubelet/server/remotecommand:go_default_library", + "//vendor:github.com/stretchr/testify/require", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/fields", "//vendor:k8s.io/apimachinery/pkg/runtime", + "//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/types", + "//vendor:k8s.io/apimachinery/pkg/util/httpstream", + "//vendor:k8s.io/apimachinery/pkg/util/remotecommand", "//vendor:k8s.io/apimachinery/pkg/watch", "//vendor:k8s.io/client-go/pkg/api/install", "//vendor:k8s.io/client-go/rest", diff --git a/pkg/client/unversioned/remotecommand/remotecommand_test.go b/pkg/client/tests/remotecommand_test.go similarity index 88% rename from pkg/client/unversioned/remotecommand/remotecommand_test.go rename to pkg/client/tests/remotecommand_test.go index 70929c4ed6..f30283a790 100644 --- a/pkg/client/unversioned/remotecommand/remotecommand_test.go +++ b/pkg/client/tests/remotecommand_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package remotecommand +package tests import ( "bytes" @@ -34,11 +34,12 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/httpstream" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + remoteclient "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" - "k8s.io/kubernetes/pkg/util/term" ) type fakeExecutor struct { @@ -55,11 +56,11 @@ type fakeExecutor struct { exec bool } -func (ex *fakeExecutor) ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (ex *fakeExecutor) ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remoteclient.TerminalSize, timeout time.Duration) error { return ex.run(name, uid, container, cmd, in, out, err, tty) } -func (ex *fakeExecutor) AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (ex *fakeExecutor) AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remoteclient.TerminalSize) error { return ex.run(name, uid, container, nil, in, out, err, tty) } @@ -151,8 +152,8 @@ func TestStream(t *testing.T) { TestName: "error", Error: "bail", Stdout: "a", - ClientProtocols: []string{remotecommand.StreamProtocolV2Name}, - ServerProtocols: []string{remotecommand.StreamProtocolV2Name}, + ClientProtocols: []string{remotecommandconsts.StreamProtocolV2Name}, + ServerProtocols: []string{remotecommandconsts.StreamProtocolV2Name}, }, { TestName: "in/out/err", @@ -160,8 +161,8 @@ func TestStream(t *testing.T) { Stdout: "b", Stderr: "c", MessageCount: 100, - ClientProtocols: []string{remotecommand.StreamProtocolV2Name}, - ServerProtocols: []string{remotecommand.StreamProtocolV2Name}, + ClientProtocols: []string{remotecommandconsts.StreamProtocolV2Name}, + ServerProtocols: []string{remotecommandconsts.StreamProtocolV2Name}, }, { TestName: "in/out/tty", @@ -169,8 +170,8 @@ func TestStream(t *testing.T) { Stdout: "b", Tty: true, MessageCount: 100, - ClientProtocols: []string{remotecommand.StreamProtocolV2Name}, - ServerProtocols: []string{remotecommand.StreamProtocolV2Name}, + ClientProtocols: []string{remotecommandconsts.StreamProtocolV2Name}, + ServerProtocols: []string{remotecommandconsts.StreamProtocolV2Name}, }, { // 1.0 kubectl, 1.0 kubelet @@ -188,7 +189,7 @@ func TestStream(t *testing.T) { Stderr: "c", MessageCount: 1, ClientProtocols: []string{}, - ServerProtocols: []string{remotecommand.StreamProtocolV2Name, remotecommand.StreamProtocolV1Name}, + ServerProtocols: []string{remotecommandconsts.StreamProtocolV2Name, remotecommandconsts.StreamProtocolV1Name}, }, { // 1.1+ kubectl, 1.0 kubelet @@ -196,7 +197,7 @@ func TestStream(t *testing.T) { Stdout: "b", Stderr: "c", MessageCount: 1, - ClientProtocols: []string{remotecommand.StreamProtocolV2Name, remotecommand.StreamProtocolV1Name}, + ClientProtocols: []string{remotecommandconsts.StreamProtocolV2Name, remotecommandconsts.StreamProtocolV1Name}, ServerProtocols: []string{}, }, } @@ -254,12 +255,12 @@ func TestStream(t *testing.T) { conf := &restclient.Config{ Host: server.URL, } - e, err := NewExecutor(conf, "POST", req.URL()) + e, err := remoteclient.NewExecutor(conf, "POST", req.URL()) if err != nil { t.Errorf("%s: unexpected error: %v", name, err) continue } - err = e.Stream(StreamOptions{ + err = e.Stream(remoteclient.StreamOptions{ SupportedProtocols: testCase.ClientProtocols, Stdin: streamIn, Stdout: streamOut, @@ -351,7 +352,7 @@ func TestDial(t *testing.T) { called = true return rt } - exec, err := NewStreamExecutor(upgrader, testFn, "POST", &url.URL{Host: "something.com", Scheme: "https"}) + exec, err := remoteclient.NewStreamExecutor(upgrader, testFn, "POST", &url.URL{Host: "something.com", Scheme: "https"}) if err != nil { t.Fatal(err) } diff --git a/pkg/client/unversioned/remotecommand/BUILD b/pkg/client/unversioned/remotecommand/BUILD index 840a3e23a6..0eb4172b97 100644 --- a/pkg/client/unversioned/remotecommand/BUILD +++ b/pkg/client/unversioned/remotecommand/BUILD @@ -14,6 +14,7 @@ go_library( "doc.go", "errorstream.go", "remotecommand.go", + "resize.go", "v1.go", "v2.go", "v3.go", @@ -22,13 +23,12 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", - "//pkg/kubelet/server/remotecommand:go_default_library", "//pkg/util/exec:go_default_library", - "//pkg/util/term:go_default_library", "//vendor:github.com/golang/glog", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/util/httpstream", "//vendor:k8s.io/apimachinery/pkg/util/httpstream/spdy", + "//vendor:k8s.io/apimachinery/pkg/util/remotecommand", "//vendor:k8s.io/apimachinery/pkg/util/runtime", "//vendor:k8s.io/client-go/rest", "//vendor:k8s.io/client-go/transport", @@ -38,7 +38,6 @@ go_library( go_test( name = "go_default_test", srcs = [ - "remotecommand_test.go", "v2_test.go", "v4_test.go", ], @@ -46,15 +45,8 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", - "//pkg/api/testapi:go_default_library", - "//pkg/kubelet/server/remotecommand:go_default_library", - "//pkg/util/term:go_default_library", - "//vendor:github.com/stretchr/testify/require", - "//vendor:k8s.io/apimachinery/pkg/runtime/schema", - "//vendor:k8s.io/apimachinery/pkg/types", "//vendor:k8s.io/apimachinery/pkg/util/httpstream", "//vendor:k8s.io/apimachinery/pkg/util/wait", - "//vendor:k8s.io/client-go/rest", ], ) diff --git a/pkg/client/unversioned/remotecommand/remotecommand.go b/pkg/client/unversioned/remotecommand/remotecommand.go index 1d713e2eab..f2422b4cf7 100644 --- a/pkg/client/unversioned/remotecommand/remotecommand.go +++ b/pkg/client/unversioned/remotecommand/remotecommand.go @@ -26,10 +26,9 @@ import ( "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/apimachinery/pkg/util/httpstream/spdy" + "k8s.io/apimachinery/pkg/util/remotecommand" restclient "k8s.io/client-go/rest" "k8s.io/client-go/transport" - "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" - "k8s.io/kubernetes/pkg/util/term" ) // StreamOptions holds information pertaining to the current streaming session: supported stream @@ -41,7 +40,7 @@ type StreamOptions struct { Stdout io.Writer Stderr io.Writer Tty bool - TerminalSizeQueue term.TerminalSizeQueue + TerminalSizeQueue TerminalSizeQueue } // Executor is an interface for transporting shell-style streams. diff --git a/pkg/client/unversioned/remotecommand/resize.go b/pkg/client/unversioned/remotecommand/resize.go new file mode 100644 index 0000000000..9fd121c962 --- /dev/null +++ b/pkg/client/unversioned/remotecommand/resize.go @@ -0,0 +1,33 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +// TermimanlSize and TerminalSizeQueue was a part of k8s.io/kubernetes/pkg/util/term +// and were moved in order to decouple client from other term dependencies + +// TerminalSize represents the width and height of a terminal. +type TerminalSize struct { + Width uint16 + Height uint16 +} + +// TerminalSizeQueue is capable of returning terminal resize events as they occur. +type TerminalSizeQueue interface { + // Next returns the new terminal size after the terminal has been resized. It returns nil when + // monitoring has been stopped. + Next() *TerminalSize +} diff --git a/pkg/client/unversioned/remotecommand/v3.go b/pkg/client/unversioned/remotecommand/v3.go index 24b609922c..923e8c4e60 100644 --- a/pkg/client/unversioned/remotecommand/v3.go +++ b/pkg/client/unversioned/remotecommand/v3.go @@ -66,7 +66,6 @@ func (p *streamProtocolV3) handleResizes() { if p.resizeStream == nil || p.TerminalSizeQueue == nil { return } - go func() { defer runtime.HandleCrash() diff --git a/pkg/client/unversioned/remotecommand/v4.go b/pkg/client/unversioned/remotecommand/v4.go index 73768a8feb..92d240c816 100644 --- a/pkg/client/unversioned/remotecommand/v4.go +++ b/pkg/client/unversioned/remotecommand/v4.go @@ -24,7 +24,7 @@ import ( "sync" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" + "k8s.io/apimachinery/pkg/util/remotecommand" "k8s.io/kubernetes/pkg/util/exec" ) diff --git a/pkg/kubectl/cmd/BUILD b/pkg/kubectl/cmd/BUILD index ef6f14f136..132c22db6f 100644 --- a/pkg/kubectl/cmd/BUILD +++ b/pkg/kubectl/cmd/BUILD @@ -92,7 +92,6 @@ go_library( "//pkg/kubectl/cmd/util/editor:go_default_library", "//pkg/kubectl/metricsutil:go_default_library", "//pkg/kubectl/resource:go_default_library", - "//pkg/kubelet/server/remotecommand:go_default_library", "//pkg/kubelet/types:go_default_library", "//pkg/printers:go_default_library", "//pkg/printers/internalversion:go_default_library", @@ -127,6 +126,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/json", "//vendor:k8s.io/apimachinery/pkg/util/jsonmergepatch", "//vendor:k8s.io/apimachinery/pkg/util/mergepatch", + "//vendor:k8s.io/apimachinery/pkg/util/remotecommand", "//vendor:k8s.io/apimachinery/pkg/util/sets", "//vendor:k8s.io/apimachinery/pkg/util/strategicpatch", "//vendor:k8s.io/apimachinery/pkg/util/validation", @@ -201,6 +201,7 @@ go_test( "//pkg/apis/extensions:go_default_library", "//pkg/apis/policy:go_default_library", "//pkg/apis/rbac:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubectl:go_default_library", "//pkg/kubectl/cmd/testing:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", diff --git a/pkg/kubectl/cmd/attach.go b/pkg/kubectl/cmd/attach.go index 71e5329282..0214f5df08 100644 --- a/pkg/kubectl/cmd/attach.go +++ b/pkg/kubectl/cmd/attach.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilerrors "k8s.io/apimachinery/pkg/util/errors" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/api" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" @@ -34,9 +35,7 @@ import ( "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" - remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" "k8s.io/kubernetes/pkg/util/i18n" - "k8s.io/kubernetes/pkg/util/term" ) var ( @@ -91,19 +90,19 @@ func NewCmdAttach(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) // RemoteAttach defines the interface accepted by the Attach command - provided for test stubbing type RemoteAttach interface { - Attach(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue term.TerminalSizeQueue) error + Attach(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error } // DefaultRemoteAttach is the standard implementation of attaching type DefaultRemoteAttach struct{} -func (*DefaultRemoteAttach) Attach(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue term.TerminalSizeQueue) error { +func (*DefaultRemoteAttach) Attach(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error { exec, err := remotecommand.NewExecutor(config, method, url) if err != nil { return err } return exec.Stream(remotecommand.StreamOptions{ - SupportedProtocols: remotecommandserver.SupportedStreamingProtocols, + SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols, Stdin: stdin, Stdout: stdout, Stderr: stderr, @@ -242,7 +241,7 @@ func (p *AttachOptions) Run() error { // save p.Err so we can print the command prompt message below stderr := p.Err - var sizeQueue term.TerminalSizeQueue + var sizeQueue remotecommand.TerminalSizeQueue if t.Raw { if size := t.GetSize(); size != nil { // fake resizing +1 and then back to normal so that attach-detach-reattach will result in the diff --git a/pkg/kubectl/cmd/attach_test.go b/pkg/kubectl/cmd/attach_test.go index 67ac71386d..49d80a4d06 100644 --- a/pkg/kubectl/cmd/attach_test.go +++ b/pkg/kubectl/cmd/attach_test.go @@ -34,9 +34,9 @@ import ( restclient "k8s.io/client-go/rest" "k8s.io/client-go/rest/fake" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" - "k8s.io/kubernetes/pkg/util/term" ) type fakeRemoteAttach struct { @@ -45,7 +45,7 @@ type fakeRemoteAttach struct { err error } -func (f *fakeRemoteAttach) Attach(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue term.TerminalSizeQueue) error { +func (f *fakeRemoteAttach) Attach(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error { f.method = method f.url = url return f.err diff --git a/pkg/kubectl/cmd/exec.go b/pkg/kubectl/cmd/exec.go index 341934b99b..0dc1cb58ab 100644 --- a/pkg/kubectl/cmd/exec.go +++ b/pkg/kubectl/cmd/exec.go @@ -25,13 +25,13 @@ import ( "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/api" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" - remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" "k8s.io/kubernetes/pkg/util/i18n" "k8s.io/kubernetes/pkg/util/interrupt" "k8s.io/kubernetes/pkg/util/term" @@ -86,19 +86,19 @@ func NewCmdExec(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *c // RemoteExecutor defines the interface accepted by the Exec command - provided for test stubbing type RemoteExecutor interface { - Execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue term.TerminalSizeQueue) error + Execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error } // DefaultRemoteExecutor is the standard implementation of remote command execution type DefaultRemoteExecutor struct{} -func (*DefaultRemoteExecutor) Execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue term.TerminalSizeQueue) error { +func (*DefaultRemoteExecutor) Execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error { exec, err := remotecommand.NewExecutor(config, method, url) if err != nil { return err } return exec.Stream(remotecommand.StreamOptions{ - SupportedProtocols: remotecommandserver.SupportedStreamingProtocols, + SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols, Stdin: stdin, Stdout: stdout, Stderr: stderr, @@ -284,7 +284,7 @@ func (p *ExecOptions) Run() error { // ensure we can recover the terminal while attached t := p.setupTTY() - var sizeQueue term.TerminalSizeQueue + var sizeQueue remotecommand.TerminalSizeQueue if t.Raw { // this call spawns a goroutine to monitor/update the terminal size sizeQueue = t.MonitorSize(t.GetSize()) diff --git a/pkg/kubectl/cmd/exec_test.go b/pkg/kubectl/cmd/exec_test.go index 72f4b9b912..6ba9410cdd 100644 --- a/pkg/kubectl/cmd/exec_test.go +++ b/pkg/kubectl/cmd/exec_test.go @@ -33,6 +33,7 @@ import ( restclient "k8s.io/client-go/rest" "k8s.io/client-go/rest/fake" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" "k8s.io/kubernetes/pkg/util/term" ) @@ -43,7 +44,7 @@ type fakeRemoteExecutor struct { execErr error } -func (f *fakeRemoteExecutor) Execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue term.TerminalSizeQueue) error { +func (f *fakeRemoteExecutor) Execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error { f.method = method f.url = url return f.execErr diff --git a/pkg/kubelet/BUILD b/pkg/kubelet/BUILD index ef15deb33d..fd5df80d9d 100644 --- a/pkg/kubelet/BUILD +++ b/pkg/kubelet/BUILD @@ -44,6 +44,7 @@ go_library( "//pkg/capabilities:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", "//pkg/client/listers/core/v1:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/cloudprovider:go_default_library", "//pkg/features:go_default_library", "//pkg/fieldpath:go_default_library", @@ -100,7 +101,6 @@ go_library( "//pkg/util/oom:go_default_library", "//pkg/util/procfs:go_default_library", "//pkg/util/removeall:go_default_library", - "//pkg/util/term:go_default_library", "//pkg/version:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", diff --git a/pkg/kubelet/container/BUILD b/pkg/kubelet/container/BUILD index ffac068265..5c587cc7a7 100644 --- a/pkg/kubelet/container/BUILD +++ b/pkg/kubelet/container/BUILD @@ -28,12 +28,12 @@ go_library( deps = [ "//pkg/api:go_default_library", "//pkg/api/v1:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubelet/api/v1alpha1/runtime:go_default_library", "//pkg/kubelet/events:go_default_library", "//pkg/kubelet/util/format:go_default_library", "//pkg/kubelet/util/ioutils:go_default_library", "//pkg/util/hash:go_default_library", - "//pkg/util/term:go_default_library", "//pkg/volume:go_default_library", "//third_party/forked/golang/expansion:go_default_library", "//vendor:github.com/golang/glog", diff --git a/pkg/kubelet/container/resize.go b/pkg/kubelet/container/resize.go index 1491533d87..b880f8fbdd 100644 --- a/pkg/kubelet/container/resize.go +++ b/pkg/kubelet/container/resize.go @@ -18,13 +18,13 @@ package container import ( "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/kubernetes/pkg/util/term" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" ) // handleResizing spawns a goroutine that processes the resize channel, calling resizeFunc for each -// term.Size received from the channel. The resize channel must be closed elsewhere to stop the +// remotecommand.TerminalSize received from the channel. The resize channel must be closed elsewhere to stop the // goroutine. -func HandleResizing(resize <-chan term.Size, resizeFunc func(size term.Size)) { +func HandleResizing(resize <-chan remotecommand.TerminalSize, resizeFunc func(size remotecommand.TerminalSize)) { if resize == nil { return } diff --git a/pkg/kubelet/container/runtime.go b/pkg/kubelet/container/runtime.go index dbacfd519a..c1adf4827e 100644 --- a/pkg/kubelet/container/runtime.go +++ b/pkg/kubelet/container/runtime.go @@ -28,8 +28,8 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/flowcontrol" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" - "k8s.io/kubernetes/pkg/util/term" "k8s.io/kubernetes/pkg/volume" ) @@ -128,7 +128,7 @@ type DirectStreamingRuntime interface { // Runs the command in the container of the specified pod using nsenter. // Attaches the processes stdin, stdout, and stderr. Optionally uses a // tty. - ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error + ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error // Forward the specified port from the specified pod to the stream. PortForward(pod *Pod, port int32, stream io.ReadWriteCloser) error // ContainerAttach encapsulates the attaching to containers for testability @@ -160,7 +160,7 @@ type ImageService interface { } type ContainerAttacher interface { - AttachContainer(id ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) (err error) + AttachContainer(id ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) (err error) } type ContainerCommandRunner interface { diff --git a/pkg/kubelet/container/testing/BUILD b/pkg/kubelet/container/testing/BUILD index 39d10eae9f..257bef254e 100644 --- a/pkg/kubelet/container/testing/BUILD +++ b/pkg/kubelet/container/testing/BUILD @@ -20,8 +20,8 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api/v1:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubelet/container:go_default_library", - "//pkg/util/term:go_default_library", "//pkg/volume:go_default_library", "//vendor:github.com/golang/mock/gomock", "//vendor:github.com/stretchr/testify/mock", diff --git a/pkg/kubelet/container/testing/fake_runtime.go b/pkg/kubelet/container/testing/fake_runtime.go index 21ede43050..ceaaaf076f 100644 --- a/pkg/kubelet/container/testing/fake_runtime.go +++ b/pkg/kubelet/container/testing/fake_runtime.go @@ -27,8 +27,8 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/flowcontrol" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" . "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/util/term" "k8s.io/kubernetes/pkg/volume" ) @@ -311,7 +311,7 @@ func (f *FakeRuntime) GetPodStatus(uid types.UID, name, namespace string) (*PodS return &status, f.Err } -func (f *FakeDirectStreamingRuntime) ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (f *FakeDirectStreamingRuntime) ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { f.Lock() defer f.Unlock() @@ -326,7 +326,7 @@ func (f *FakeDirectStreamingRuntime) ExecInContainer(containerID ContainerID, cm return f.Err } -func (f *FakeDirectStreamingRuntime) AttachContainer(containerID ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (f *FakeDirectStreamingRuntime) AttachContainer(containerID ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { f.Lock() defer f.Unlock() diff --git a/pkg/kubelet/container/testing/runtime_mock.go b/pkg/kubelet/container/testing/runtime_mock.go index a3a0115c99..5f05d8c20a 100644 --- a/pkg/kubelet/container/testing/runtime_mock.go +++ b/pkg/kubelet/container/testing/runtime_mock.go @@ -24,8 +24,8 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/flowcontrol" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" . "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/util/term" "k8s.io/kubernetes/pkg/volume" ) @@ -90,12 +90,12 @@ func (r *Mock) GetPodStatus(uid types.UID, name, namespace string) (*PodStatus, return args.Get(0).(*PodStatus), args.Error(1) } -func (r *Mock) ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (r *Mock) ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { args := r.Called(containerID, cmd, stdin, stdout, stderr, tty) return args.Error(0) } -func (r *Mock) AttachContainer(containerID ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (r *Mock) AttachContainer(containerID ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { args := r.Called(containerID, stdin, stdout, stderr, tty) return args.Error(0) } diff --git a/pkg/kubelet/dockershim/BUILD b/pkg/kubelet/dockershim/BUILD index f9fde0367a..b72ba071ee 100644 --- a/pkg/kubelet/dockershim/BUILD +++ b/pkg/kubelet/dockershim/BUILD @@ -29,6 +29,7 @@ go_library( deps = [ "//pkg/api/v1:go_default_library", "//pkg/apis/componentconfig:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubelet/api:go_default_library", "//pkg/kubelet/api/v1alpha1/runtime:go_default_library", "//pkg/kubelet/cm:go_default_library", @@ -48,7 +49,6 @@ go_library( "//pkg/kubelet/util/cache:go_default_library", "//pkg/kubelet/util/ioutils:go_default_library", "//pkg/util/hash:go_default_library", - "//pkg/util/term:go_default_library", "//vendor:github.com/blang/semver", "//vendor:github.com/docker/engine-api/types", "//vendor:github.com/docker/engine-api/types/container", diff --git a/pkg/kubelet/dockershim/docker_streaming.go b/pkg/kubelet/dockershim/docker_streaming.go index 9f9f3bef2b..42b299fd1a 100644 --- a/pkg/kubelet/dockershim/docker_streaming.go +++ b/pkg/kubelet/dockershim/docker_streaming.go @@ -24,11 +24,11 @@ import ( "time" dockertypes "github.com/docker/engine-api/types" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" "k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/server/streaming" "k8s.io/kubernetes/pkg/kubelet/util/ioutils" - "k8s.io/kubernetes/pkg/util/term" ) type streamingRuntime struct { @@ -38,12 +38,12 @@ type streamingRuntime struct { var _ streaming.Runtime = &streamingRuntime{} -func (r *streamingRuntime) Exec(containerID string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (r *streamingRuntime) Exec(containerID string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { return r.exec(containerID, cmd, in, out, err, tty, resize, 0) } // Internal version of Exec adds a timeout. -func (r *streamingRuntime) exec(containerID string, cmd []string, in io.Reader, out, errw io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (r *streamingRuntime) exec(containerID string, cmd []string, in io.Reader, out, errw io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { container, err := checkContainerStatus(r.client, containerID) if err != nil { return err @@ -51,7 +51,7 @@ func (r *streamingRuntime) exec(containerID string, cmd []string, in io.Reader, return r.execHandler.ExecInContainer(r.client, container, cmd, in, out, errw, tty, resize, timeout) } -func (r *streamingRuntime) Attach(containerID string, in io.Reader, out, errw io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (r *streamingRuntime) Attach(containerID string, in io.Reader, out, errw io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { _, err := checkContainerStatus(r.client, containerID) if err != nil { return err diff --git a/pkg/kubelet/dockertools/BUILD b/pkg/kubelet/dockertools/BUILD index 397edb5305..64226092ee 100644 --- a/pkg/kubelet/dockertools/BUILD +++ b/pkg/kubelet/dockertools/BUILD @@ -28,6 +28,7 @@ go_library( deps = [ "//pkg/api:go_default_library", "//pkg/api/v1:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/credentialprovider:go_default_library", "//pkg/kubelet/cm:go_default_library", "//pkg/kubelet/container:go_default_library", diff --git a/pkg/kubelet/dockertools/docker_manager.go b/pkg/kubelet/dockertools/docker_manager.go index d89e14c12b..dc472999c4 100644 --- a/pkg/kubelet/dockertools/docker_manager.go +++ b/pkg/kubelet/dockertools/docker_manager.go @@ -52,6 +52,7 @@ import ( "k8s.io/client-go/util/flowcontrol" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/kubelet/cm" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" dockersecurity "k8s.io/kubernetes/pkg/kubelet/dockertools/securitycontext" @@ -73,7 +74,6 @@ import ( "k8s.io/kubernetes/pkg/util/selinux" utilstrings "k8s.io/kubernetes/pkg/util/strings" "k8s.io/kubernetes/pkg/util/tail" - "k8s.io/kubernetes/pkg/util/term" utilversion "k8s.io/kubernetes/pkg/util/version" ) @@ -1297,7 +1297,7 @@ func (d *dockerExitError) ExitStatus() int { } // ExecInContainer runs the command inside the container identified by containerID. -func (dm *DockerManager) ExecInContainer(containerID kubecontainer.ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (dm *DockerManager) ExecInContainer(containerID kubecontainer.ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { if dm.execHandler == nil { return errors.New("unable to exec without an exec handler") } @@ -1313,16 +1313,16 @@ func (dm *DockerManager) ExecInContainer(containerID kubecontainer.ContainerID, return dm.execHandler.ExecInContainer(dm.client, container, cmd, stdin, stdout, stderr, tty, resize, timeout) } -func (dm *DockerManager) AttachContainer(containerID kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (dm *DockerManager) AttachContainer(containerID kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { return AttachContainer(dm.client, containerID.ID, stdin, stdout, stderr, tty, resize) } // Temporarily export this function to share with dockershim. // TODO: clean this up. -func AttachContainer(client DockerInterface, containerID string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error { +func AttachContainer(client DockerInterface, containerID string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { // Have to start this before the call to client.AttachToContainer because client.AttachToContainer is a blocking // call :-( Otherwise, resize events don't get processed and the terminal never resizes. - kubecontainer.HandleResizing(resize, func(size term.Size) { + kubecontainer.HandleResizing(resize, func(size remotecommand.TerminalSize) { client.ResizeContainerTTY(containerID, int(size.Height), int(size.Width)) }) diff --git a/pkg/kubelet/dockertools/exec.go b/pkg/kubelet/dockertools/exec.go index 83fad9c6e9..1f72337e57 100644 --- a/pkg/kubelet/dockertools/exec.go +++ b/pkg/kubelet/dockertools/exec.go @@ -25,6 +25,7 @@ import ( dockertypes "github.com/docker/engine-api/types" "github.com/golang/glog" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" utilexec "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/term" @@ -32,14 +33,14 @@ import ( // ExecHandler knows how to execute a command in a running Docker container. type ExecHandler interface { - ExecInContainer(client DockerInterface, container *dockertypes.ContainerJSON, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error + ExecInContainer(client DockerInterface, container *dockertypes.ContainerJSON, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error } // NsenterExecHandler executes commands in Docker containers using nsenter. type NsenterExecHandler struct{} // TODO should we support nsenter in a container, running with elevated privs and --pid=host? -func (*NsenterExecHandler) ExecInContainer(client DockerInterface, container *dockertypes.ContainerJSON, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (*NsenterExecHandler) ExecInContainer(client DockerInterface, container *dockertypes.ContainerJSON, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { nsenter, err := exec.LookPath("nsenter") if err != nil { return fmt.Errorf("exec unavailable - unable to locate nsenter") @@ -64,7 +65,7 @@ func (*NsenterExecHandler) ExecInContainer(client DockerInterface, container *do // make sure to close the stdout stream defer stdout.Close() - kubecontainer.HandleResizing(resize, func(size term.Size) { + kubecontainer.HandleResizing(resize, func(size remotecommand.TerminalSize) { term.SetSize(p.Fd(), size) }) @@ -110,7 +111,7 @@ func (*NsenterExecHandler) ExecInContainer(client DockerInterface, container *do // NativeExecHandler executes commands in Docker containers using Docker's exec API. type NativeExecHandler struct{} -func (*NativeExecHandler) ExecInContainer(client DockerInterface, container *dockertypes.ContainerJSON, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (*NativeExecHandler) ExecInContainer(client DockerInterface, container *dockertypes.ContainerJSON, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { createOpts := dockertypes.ExecConfig{ Cmd: cmd, AttachStdin: stdin != nil, @@ -125,7 +126,7 @@ func (*NativeExecHandler) ExecInContainer(client DockerInterface, container *doc // Have to start this before the call to client.StartExec because client.StartExec is a blocking // call :-( Otherwise, resize events don't get processed and the terminal never resizes. - kubecontainer.HandleResizing(resize, func(size term.Size) { + kubecontainer.HandleResizing(resize, func(size remotecommand.TerminalSize) { client.ResizeExecTTY(execObj.ID, int(size.Height), int(size.Width)) }) diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 6cc135ad51..e0ffa327cf 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -44,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/api/v1" utilpod "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/api/v1/validation" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/fieldpath" "k8s.io/kubernetes/pkg/kubelet/cm" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" @@ -51,11 +52,10 @@ import ( "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/qos" "k8s.io/kubernetes/pkg/kubelet/server/portforward" - "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" + remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" "k8s.io/kubernetes/pkg/kubelet/status" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/util/format" - "k8s.io/kubernetes/pkg/util/term" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util/volumehelper" "k8s.io/kubernetes/third_party/forked/golang/expansion" @@ -1412,7 +1412,7 @@ func (kl *Kubelet) RunInContainer(podFullName string, podUID types.UID, containe // ExecInContainer executes a command in a container, connecting the supplied // stdin/stdout/stderr to the command's IO streams. -func (kl *Kubelet) ExecInContainer(podFullName string, podUID types.UID, containerName string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (kl *Kubelet) ExecInContainer(podFullName string, podUID types.UID, containerName string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { streamingRuntime, ok := kl.containerRuntime.(kubecontainer.DirectStreamingRuntime) if !ok { return fmt.Errorf("streaming methods not supported by runtime") @@ -1430,7 +1430,7 @@ func (kl *Kubelet) ExecInContainer(podFullName string, podUID types.UID, contain // AttachContainer uses the container runtime to attach the given streams to // the given container. -func (kl *Kubelet) AttachContainer(podFullName string, podUID types.UID, containerName string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (kl *Kubelet) AttachContainer(podFullName string, podUID types.UID, containerName string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { streamingRuntime, ok := kl.containerRuntime.(kubecontainer.DirectStreamingRuntime) if !ok { return fmt.Errorf("streaming methods not supported by runtime") @@ -1467,7 +1467,7 @@ func (kl *Kubelet) PortForward(podFullName string, podUID types.UID, port int32, } // GetExec gets the URL the exec will be served from, or nil if the Kubelet will serve it. -func (kl *Kubelet) GetExec(podFullName string, podUID types.UID, containerName string, cmd []string, streamOpts remotecommand.Options) (*url.URL, error) { +func (kl *Kubelet) GetExec(podFullName string, podUID types.UID, containerName string, cmd []string, streamOpts remotecommandserver.Options) (*url.URL, error) { switch streamingRuntime := kl.containerRuntime.(type) { case kubecontainer.DirectStreamingRuntime: // Kubelet will serve the exec directly. @@ -1487,7 +1487,7 @@ func (kl *Kubelet) GetExec(podFullName string, podUID types.UID, containerName s } // GetAttach gets the URL the attach will be served from, or nil if the Kubelet will serve it. -func (kl *Kubelet) GetAttach(podFullName string, podUID types.UID, containerName string, streamOpts remotecommand.Options) (*url.URL, error) { +func (kl *Kubelet) GetAttach(podFullName string, podUID types.UID, containerName string, streamOpts remotecommandserver.Options) (*url.URL, error) { switch streamingRuntime := kl.containerRuntime.(type) { case kubecontainer.DirectStreamingRuntime: // Kubelet will serve the attach directly. diff --git a/pkg/kubelet/rkt/BUILD b/pkg/kubelet/rkt/BUILD index 679bbeb346..576339a5f9 100644 --- a/pkg/kubelet/rkt/BUILD +++ b/pkg/kubelet/rkt/BUILD @@ -24,6 +24,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api/v1:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/credentialprovider:go_default_library", "//pkg/kubelet/container:go_default_library", "//pkg/kubelet/events:go_default_library", diff --git a/pkg/kubelet/rkt/rkt.go b/pkg/kubelet/rkt/rkt.go index 7decec4c5b..526af24251 100644 --- a/pkg/kubelet/rkt/rkt.go +++ b/pkg/kubelet/rkt/rkt.go @@ -49,6 +49,7 @@ import ( "k8s.io/client-go/tools/record" "k8s.io/client-go/util/flowcontrol" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/credentialprovider" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/events" @@ -2068,14 +2069,14 @@ func newRktExitError(e error) error { return e } -func (r *Runtime) AttachContainer(containerID kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (r *Runtime) AttachContainer(containerID kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { return fmt.Errorf("unimplemented") } // Note: In rkt, the container ID is in the form of "UUID:appName", where UUID is // the rkt UUID, and appName is the container name. // TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail. -func (r *Runtime) ExecInContainer(containerID kubecontainer.ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (r *Runtime) ExecInContainer(containerID kubecontainer.ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { glog.V(4).Infof("Rkt execing in container.") id, err := parseContainerID(containerID) @@ -2096,7 +2097,7 @@ func (r *Runtime) ExecInContainer(containerID kubecontainer.ContainerID, cmd []s // make sure to close the stdout stream defer stdout.Close() - kubecontainer.HandleResizing(resize, func(size term.Size) { + kubecontainer.HandleResizing(resize, func(size remotecommand.TerminalSize) { term.SetSize(p.Fd(), size) }) diff --git a/pkg/kubelet/server/BUILD b/pkg/kubelet/server/BUILD index b787b34fe4..66cdde7f34 100644 --- a/pkg/kubelet/server/BUILD +++ b/pkg/kubelet/server/BUILD @@ -20,6 +20,7 @@ go_library( "//pkg/api:go_default_library", "//pkg/api/v1:go_default_library", "//pkg/api/v1/validation:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubelet/cm:go_default_library", "//pkg/kubelet/container:go_default_library", "//pkg/kubelet/server/portforward:go_default_library", @@ -28,7 +29,6 @@ go_library( "//pkg/kubelet/server/streaming:go_default_library", "//pkg/util/configz:go_default_library", "//pkg/util/limitwriter:go_default_library", - "//pkg/util/term:go_default_library", "//pkg/volume:go_default_library", "//vendor:github.com/emicklei/go-restful", "//vendor:github.com/golang/glog", @@ -40,6 +40,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/types", + "//vendor:k8s.io/apimachinery/pkg/util/remotecommand", "//vendor:k8s.io/apimachinery/pkg/util/runtime", "//vendor:k8s.io/apiserver/pkg/authentication/authenticator", "//vendor:k8s.io/apiserver/pkg/authentication/user", @@ -62,13 +63,13 @@ go_test( deps = [ "//pkg/api:go_default_library", "//pkg/api/v1:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubelet/cm:go_default_library", "//pkg/kubelet/container:go_default_library", "//pkg/kubelet/container/testing:go_default_library", "//pkg/kubelet/server/portforward:go_default_library", "//pkg/kubelet/server/remotecommand:go_default_library", "//pkg/kubelet/server/stats:go_default_library", - "//pkg/util/term:go_default_library", "//pkg/volume:go_default_library", "//vendor:github.com/google/cadvisor/info/v1", "//vendor:github.com/google/cadvisor/info/v2", diff --git a/pkg/kubelet/server/remotecommand/BUILD b/pkg/kubelet/server/remotecommand/BUILD index c27eb774ac..f8352e9e05 100644 --- a/pkg/kubelet/server/remotecommand/BUILD +++ b/pkg/kubelet/server/remotecommand/BUILD @@ -11,7 +11,6 @@ go_library( name = "go_default_library", srcs = [ "attach.go", - "constants.go", "doc.go", "exec.go", "httpstream.go", @@ -20,14 +19,15 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/util/exec:go_default_library", - "//pkg/util/term:go_default_library", "//vendor:github.com/golang/glog", "//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/types", "//vendor:k8s.io/apimachinery/pkg/util/httpstream", "//vendor:k8s.io/apimachinery/pkg/util/httpstream/spdy", + "//vendor:k8s.io/apimachinery/pkg/util/remotecommand", "//vendor:k8s.io/apimachinery/pkg/util/runtime", "//vendor:k8s.io/apiserver/pkg/server/httplog", "//vendor:k8s.io/apiserver/pkg/util/wsstream", diff --git a/pkg/kubelet/server/remotecommand/attach.go b/pkg/kubelet/server/remotecommand/attach.go index 5bd95f12d4..2c7736b0a7 100644 --- a/pkg/kubelet/server/remotecommand/attach.go +++ b/pkg/kubelet/server/remotecommand/attach.go @@ -26,14 +26,14 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/kubernetes/pkg/util/term" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" ) // Attacher knows how to attach to a running container in a pod. type Attacher interface { // AttachContainer attaches to the running container in the pod, copying data between in/out/err // and the container's stdin/stdout/stderr. - AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size) error + AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error } // ServeAttach handles requests to attach to a container. After creating/receiving the required diff --git a/pkg/kubelet/server/remotecommand/exec.go b/pkg/kubelet/server/remotecommand/exec.go index 165b0b6149..8c248979c1 100644 --- a/pkg/kubelet/server/remotecommand/exec.go +++ b/pkg/kubelet/server/remotecommand/exec.go @@ -25,21 +25,17 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" utilexec "k8s.io/kubernetes/pkg/util/exec" - "k8s.io/kubernetes/pkg/util/term" -) - -const ( - NonZeroExitCodeReason = metav1.StatusReason("NonZeroExitCode") - ExitCodeCauseType = metav1.CauseType("ExitCode") ) // Executor knows how to execute a command in a container in a pod. type Executor interface { // ExecInContainer executes a command in a container in the pod, copying data // between in/out/err and the container's stdin/stdout/stderr. - ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error + ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error } // ServeExec handles requests to execute a command in a container. After @@ -59,11 +55,11 @@ func ServeExec(w http.ResponseWriter, req *http.Request, executor Executor, podN rc := exitErr.ExitStatus() ctx.writeStatus(&apierrors.StatusError{ErrStatus: metav1.Status{ Status: metav1.StatusFailure, - Reason: NonZeroExitCodeReason, + Reason: remotecommandconsts.NonZeroExitCodeReason, Details: &metav1.StatusDetails{ Causes: []metav1.StatusCause{ { - Type: ExitCodeCauseType, + Type: remotecommandconsts.ExitCodeCauseType, Message: fmt.Sprintf("%d", rc), }, }, diff --git a/pkg/kubelet/server/remotecommand/httpstream.go b/pkg/kubelet/server/remotecommand/httpstream.go index 49f6a08c58..27a9fc4dbf 100644 --- a/pkg/kubelet/server/remotecommand/httpstream.go +++ b/pkg/kubelet/server/remotecommand/httpstream.go @@ -28,10 +28,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/apimachinery/pkg/util/httpstream/spdy" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apiserver/pkg/util/wsstream" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/term" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "github.com/golang/glog" ) @@ -78,7 +79,7 @@ type context struct { stderrStream io.WriteCloser writeStatus func(status *apierrors.StatusError) error resizeStream io.ReadCloser - resizeChan chan term.Size + resizeChan chan remotecommand.TerminalSize tty bool } @@ -114,7 +115,7 @@ func createStreams(req *http.Request, w http.ResponseWriter, opts *Options, supp } if ctx.resizeStream != nil { - ctx.resizeChan = make(chan term.Size) + ctx.resizeChan = make(chan remotecommand.TerminalSize) go handleResizeEvents(ctx.resizeStream, ctx.resizeChan) } @@ -148,16 +149,16 @@ func createHttpStreamStreams(req *http.Request, w http.ResponseWriter, opts *Opt var handler protocolHandler switch protocol { - case StreamProtocolV4Name: + case remotecommandconsts.StreamProtocolV4Name: handler = &v4ProtocolHandler{} - case StreamProtocolV3Name: + case remotecommandconsts.StreamProtocolV3Name: handler = &v3ProtocolHandler{} - case StreamProtocolV2Name: + case remotecommandconsts.StreamProtocolV2Name: handler = &v2ProtocolHandler{} case "": - glog.V(4).Infof("Client did not request protocol negotiaion. Falling back to %q", StreamProtocolV1Name) + glog.V(4).Infof("Client did not request protocol negotiaion. Falling back to %q", remotecommandconsts.StreamProtocolV1Name) fallthrough - case StreamProtocolV1Name: + case remotecommandconsts.StreamProtocolV1Name: handler = &v1ProtocolHandler{} } @@ -409,12 +410,12 @@ WaitForStreams: // supportsTerminalResizing returns false because v1ProtocolHandler doesn't support it. func (*v1ProtocolHandler) supportsTerminalResizing() bool { return false } -func handleResizeEvents(stream io.Reader, channel chan<- term.Size) { +func handleResizeEvents(stream io.Reader, channel chan<- remotecommand.TerminalSize) { defer runtime.HandleCrash() decoder := json.NewDecoder(stream) for { - size := term.Size{} + size := remotecommand.TerminalSize{} if err := decoder.Decode(&size); err != nil { break } diff --git a/pkg/kubelet/server/server.go b/pkg/kubelet/server/server.go index 40924731de..a395431ce8 100644 --- a/pkg/kubelet/server/server.go +++ b/pkg/kubelet/server/server.go @@ -41,6 +41,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authorization/authorizer" @@ -50,15 +51,15 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1/validation" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/kubelet/cm" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/server/portforward" - "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" + remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" "k8s.io/kubernetes/pkg/kubelet/server/stats" "k8s.io/kubernetes/pkg/kubelet/server/streaming" "k8s.io/kubernetes/pkg/util/configz" "k8s.io/kubernetes/pkg/util/limitwriter" - "k8s.io/kubernetes/pkg/util/term" "k8s.io/kubernetes/pkg/volume" ) @@ -170,8 +171,8 @@ type HostInterface interface { GetRunningPods() ([]*v1.Pod, error) GetPodByName(namespace, name string) (*v1.Pod, bool) RunInContainer(name string, uid types.UID, container string, cmd []string) ([]byte, error) - ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error - AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size) error + ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error + AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error GetKubeletContainerLogs(podFullName, containerName string, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) error ServeLogs(w http.ResponseWriter, req *http.Request) PortForward(name string, uid types.UID, port int32, stream io.ReadWriteCloser) error @@ -184,8 +185,8 @@ type HostInterface interface { ImagesFsInfo() (cadvisorapiv2.FsInfo, error) RootFsInfo() (cadvisorapiv2.FsInfo, error) ListVolumesForPod(podUID types.UID) (map[string]volume.Volume, bool) - GetExec(podFullName string, podUID types.UID, containerName string, cmd []string, streamOpts remotecommand.Options) (*url.URL, error) - GetAttach(podFullName string, podUID types.UID, containerName string, streamOpts remotecommand.Options) (*url.URL, error) + GetExec(podFullName string, podUID types.UID, containerName string, cmd []string, streamOpts remotecommandserver.Options) (*url.URL, error) + GetAttach(podFullName string, podUID types.UID, containerName string, streamOpts remotecommandserver.Options) (*url.URL, error) GetPortForward(podName, podNamespace string, podUID types.UID, portForwardOpts portforward.V4Options) (*url.URL, error) } @@ -612,7 +613,7 @@ func getPortForwardRequestParams(req *restful.Request) portForwardRequestParams // getAttach handles requests to attach to a container. func (s *Server) getAttach(request *restful.Request, response *restful.Response) { params := getExecRequestParams(request) - streamOpts, err := remotecommand.NewOptions(request.Request) + streamOpts, err := remotecommandserver.NewOptions(request.Request) if err != nil { utilruntime.HandleError(err) response.WriteError(http.StatusBadRequest, err) @@ -635,7 +636,7 @@ func (s *Server) getAttach(request *restful.Request, response *restful.Response) return } - remotecommand.ServeAttach(response.ResponseWriter, + remotecommandserver.ServeAttach(response.ResponseWriter, request.Request, s.host, podFullName, @@ -643,14 +644,14 @@ func (s *Server) getAttach(request *restful.Request, response *restful.Response) params.containerName, streamOpts, s.host.StreamingConnectionIdleTimeout(), - remotecommand.DefaultStreamCreationTimeout, - remotecommand.SupportedStreamingProtocols) + remotecommandconsts.DefaultStreamCreationTimeout, + remotecommandconsts.SupportedStreamingProtocols) } // getExec handles requests to run a command inside a container. func (s *Server) getExec(request *restful.Request, response *restful.Response) { params := getExecRequestParams(request) - streamOpts, err := remotecommand.NewOptions(request.Request) + streamOpts, err := remotecommandserver.NewOptions(request.Request) if err != nil { utilruntime.HandleError(err) response.WriteError(http.StatusBadRequest, err) @@ -673,7 +674,7 @@ func (s *Server) getExec(request *restful.Request, response *restful.Response) { return } - remotecommand.ServeExec(response.ResponseWriter, + remotecommandserver.ServeExec(response.ResponseWriter, request.Request, s.host, podFullName, @@ -682,8 +683,8 @@ func (s *Server) getExec(request *restful.Request, response *restful.Response) { params.cmd, streamOpts, s.host.StreamingConnectionIdleTimeout(), - remotecommand.DefaultStreamCreationTimeout, - remotecommand.SupportedStreamingProtocols) + remotecommandconsts.DefaultStreamCreationTimeout, + remotecommandconsts.SupportedStreamingProtocols) } // getRun handles requests to run a command inside a container. @@ -757,7 +758,7 @@ func (s *Server) getPortForward(request *restful.Request, response *restful.Resp params.podUID, portForwardOptions, s.host.StreamingConnectionIdleTimeout(), - remotecommand.DefaultStreamCreationTimeout, + remotecommandconsts.DefaultStreamCreationTimeout, portforward.SupportedProtocols) } diff --git a/pkg/kubelet/server/server_test.go b/pkg/kubelet/server/server_test.go index 4a4a30ddd1..4039f8f239 100644 --- a/pkg/kubelet/server/server_test.go +++ b/pkg/kubelet/server/server_test.go @@ -49,13 +49,13 @@ import ( utiltesting "k8s.io/client-go/util/testing" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/kubelet/cm" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainertesting "k8s.io/kubernetes/pkg/kubelet/container/testing" "k8s.io/kubernetes/pkg/kubelet/server/portforward" - "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" + remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" "k8s.io/kubernetes/pkg/kubelet/server/stats" - "k8s.io/kubernetes/pkg/util/term" "k8s.io/kubernetes/pkg/volume" ) @@ -132,11 +132,11 @@ func (fk *fakeKubelet) RunInContainer(podFullName string, uid types.UID, contain return fk.runFunc(podFullName, uid, containerName, cmd) } -func (fk *fakeKubelet) ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (fk *fakeKubelet) ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { return fk.execFunc(name, uid, container, cmd, in, out, err, tty) } -func (fk *fakeKubelet) AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (fk *fakeKubelet) AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { return fk.attachFunc(name, uid, container, in, out, err, tty) } @@ -144,11 +144,11 @@ func (fk *fakeKubelet) PortForward(name string, uid types.UID, port int32, strea return fk.portForwardFunc(name, uid, port, stream) } -func (fk *fakeKubelet) GetExec(podFullName string, podUID types.UID, containerName string, cmd []string, streamOpts remotecommand.Options) (*url.URL, error) { +func (fk *fakeKubelet) GetExec(podFullName string, podUID types.UID, containerName string, cmd []string, streamOpts remotecommandserver.Options) (*url.URL, error) { return fk.redirectURL, nil } -func (fk *fakeKubelet) GetAttach(podFullName string, podUID types.UID, containerName string, streamOpts remotecommand.Options) (*url.URL, error) { +func (fk *fakeKubelet) GetAttach(podFullName string, podUID types.UID, containerName string, streamOpts remotecommandserver.Options) (*url.URL, error) { return fk.redirectURL, nil } diff --git a/pkg/kubelet/server/streaming/BUILD b/pkg/kubelet/server/streaming/BUILD index 405af5c0be..b303c422db 100644 --- a/pkg/kubelet/server/streaming/BUILD +++ b/pkg/kubelet/server/streaming/BUILD @@ -17,14 +17,15 @@ go_library( ], tags = ["automanaged"], deps = [ + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubelet/api/v1alpha1/runtime:go_default_library", "//pkg/kubelet/server/portforward:go_default_library", "//pkg/kubelet/server/remotecommand:go_default_library", - "//pkg/util/term:go_default_library", "//vendor:github.com/emicklei/go-restful", "//vendor:google.golang.org/grpc", "//vendor:google.golang.org/grpc/codes", "//vendor:k8s.io/apimachinery/pkg/types", + "//vendor:k8s.io/apimachinery/pkg/util/remotecommand", "//vendor:k8s.io/client-go/util/clock", ], ) @@ -41,10 +42,9 @@ go_test( "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubelet/api/v1alpha1/runtime:go_default_library", "//pkg/kubelet/server/portforward:go_default_library", - "//pkg/kubelet/server/remotecommand:go_default_library", - "//pkg/util/term:go_default_library", "//vendor:github.com/stretchr/testify/assert", "//vendor:github.com/stretchr/testify/require", + "//vendor:k8s.io/apimachinery/pkg/util/remotecommand", "//vendor:k8s.io/client-go/pkg/api", "//vendor:k8s.io/client-go/rest", "//vendor:k8s.io/client-go/util/clock", diff --git a/pkg/kubelet/server/streaming/server.go b/pkg/kubelet/server/streaming/server.go index bdf14a774e..3fd8fb2077 100644 --- a/pkg/kubelet/server/streaming/server.go +++ b/pkg/kubelet/server/streaming/server.go @@ -31,10 +31,11 @@ import ( restful "github.com/emicklei/go-restful" "k8s.io/apimachinery/pkg/types" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" "k8s.io/kubernetes/pkg/kubelet/server/portforward" - "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" - "k8s.io/kubernetes/pkg/util/term" + remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" ) // The library interface to serve the stream requests. @@ -59,8 +60,8 @@ type Server interface { // The interface to execute the commands and provide the streams. type Runtime interface { - Exec(containerID string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size) error - Attach(containerID string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size) error + Exec(containerID string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error + Attach(containerID string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error PortForward(podSandboxID string, port int32, stream io.ReadWriteCloser) error } @@ -95,8 +96,8 @@ type Config struct { // some fields like Addr must still be provided. var DefaultConfig = Config{ StreamIdleTimeout: 4 * time.Hour, - StreamCreationTimeout: remotecommand.DefaultStreamCreationTimeout, - SupportedRemoteCommandProtocols: remotecommand.SupportedStreamingProtocols, + StreamCreationTimeout: remotecommandconsts.DefaultStreamCreationTimeout, + SupportedRemoteCommandProtocols: remotecommandconsts.SupportedStreamingProtocols, SupportedPortForwardProtocols: portforward.SupportedProtocols, } @@ -236,14 +237,14 @@ func (s *server) serveExec(req *restful.Request, resp *restful.Response) { return } - streamOpts := &remotecommand.Options{ + streamOpts := &remotecommandserver.Options{ Stdin: exec.Stdin, Stdout: true, Stderr: !exec.Tty, TTY: exec.Tty, } - remotecommand.ServeExec( + remotecommandserver.ServeExec( resp.ResponseWriter, req.Request, s.runtime, @@ -270,13 +271,13 @@ func (s *server) serveAttach(req *restful.Request, resp *restful.Response) { return } - streamOpts := &remotecommand.Options{ + streamOpts := &remotecommandserver.Options{ Stdin: attach.Stdin, Stdout: true, Stderr: !attach.Tty, TTY: attach.Tty, } - remotecommand.ServeAttach( + remotecommandserver.ServeAttach( resp.ResponseWriter, req.Request, s.runtime, @@ -326,15 +327,15 @@ type criAdapter struct { Runtime } -var _ remotecommand.Executor = &criAdapter{} -var _ remotecommand.Attacher = &criAdapter{} +var _ remotecommandserver.Executor = &criAdapter{} +var _ remotecommandserver.Attacher = &criAdapter{} var _ portforward.PortForwarder = &criAdapter{} -func (a *criAdapter) ExecInContainer(podName string, podUID types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size, timeout time.Duration) error { +func (a *criAdapter) ExecInContainer(podName string, podUID types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { return a.Exec(container, cmd, in, out, err, tty, resize) } -func (a *criAdapter) AttachContainer(podName string, podUID types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (a *criAdapter) AttachContainer(podName string, podUID types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { return a.Attach(container, in, out, err, tty, resize) } diff --git a/pkg/kubelet/server/streaming/server_test.go b/pkg/kubelet/server/streaming/server_test.go index e8b26090ff..588d32f4b1 100644 --- a/pkg/kubelet/server/streaming/server_test.go +++ b/pkg/kubelet/server/streaming/server_test.go @@ -30,13 +30,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" "k8s.io/client-go/pkg/api" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" kubeletportforward "k8s.io/kubernetes/pkg/kubelet/server/portforward" - kubeletremotecommand "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" - "k8s.io/kubernetes/pkg/util/term" ) const ( @@ -302,12 +301,11 @@ func runRemoteCommandTest(t *testing.T, commandType string) { require.NoError(t, err) opts := remotecommand.StreamOptions{ - SupportedProtocols: kubeletremotecommand.SupportedStreamingProtocols, + SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols, Stdin: stdinR, Stdout: stdoutW, Stderr: stderrW, Tty: false, - TerminalSizeQueue: nil, } require.NoError(t, exec.Stream(opts)) }() @@ -367,13 +365,13 @@ type fakeRuntime struct { t *testing.T } -func (f *fakeRuntime) Exec(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (f *fakeRuntime) Exec(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { assert.Equal(f.t, testContainerID, containerID) doServerStreams(f.t, "exec", stdin, stdout, stderr) return nil } -func (f *fakeRuntime) Attach(containerID string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error { +func (f *fakeRuntime) Attach(containerID string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { assert.Equal(f.t, testContainerID, containerID) doServerStreams(f.t, "attach", stdin, stdout, stderr) return nil diff --git a/pkg/util/term/BUILD b/pkg/util/term/BUILD index e340aeb2fa..182f62f3ba 100644 --- a/pkg/util/term/BUILD +++ b/pkg/util/term/BUILD @@ -19,6 +19,7 @@ go_library( ], tags = ["automanaged"], deps = [ + "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/util/interrupt:go_default_library", "//vendor:github.com/docker/docker/pkg/term", "//vendor:github.com/mitchellh/go-wordwrap", diff --git a/pkg/util/term/resize.go b/pkg/util/term/resize.go index 2a948268d6..e7aa2bb952 100644 --- a/pkg/util/term/resize.go +++ b/pkg/util/term/resize.go @@ -21,17 +21,12 @@ import ( "github.com/docker/docker/pkg/term" "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" ) -// Size represents the width and height of a terminal. -type Size struct { - Width uint16 - Height uint16 -} - // GetSize returns the current size of the user's terminal. If it isn't a terminal, // nil is returned. -func (t TTY) GetSize() *Size { +func (t TTY) GetSize() *remotecommand.TerminalSize { outFd, isTerminal := term.GetFdInfo(t.Out) if !isTerminal { return nil @@ -40,19 +35,19 @@ func (t TTY) GetSize() *Size { } // GetSize returns the current size of the terminal associated with fd. -func GetSize(fd uintptr) *Size { +func GetSize(fd uintptr) *remotecommand.TerminalSize { winsize, err := term.GetWinsize(fd) if err != nil { runtime.HandleError(fmt.Errorf("unable to get terminal size: %v", err)) return nil } - return &Size{Width: winsize.Width, Height: winsize.Height} + return &remotecommand.TerminalSize{Width: winsize.Width, Height: winsize.Height} } // MonitorSize monitors the terminal's size. It returns a TerminalSizeQueue primed with // initialSizes, or nil if there's no TTY present. -func (t *TTY) MonitorSize(initialSizes ...*Size) TerminalSizeQueue { +func (t *TTY) MonitorSize(initialSizes ...*remotecommand.TerminalSize) remotecommand.TerminalSizeQueue { outFd, isTerminal := term.GetFdInfo(t.Out) if !isTerminal { return nil @@ -62,7 +57,7 @@ func (t *TTY) MonitorSize(initialSizes ...*Size) TerminalSizeQueue { t: *t, // make it buffered so we can send the initial terminal sizes without blocking, prior to starting // the streaming below - resizeChan: make(chan Size, len(initialSizes)), + resizeChan: make(chan remotecommand.TerminalSize, len(initialSizes)), stopResizing: make(chan struct{}), } @@ -71,27 +66,20 @@ func (t *TTY) MonitorSize(initialSizes ...*Size) TerminalSizeQueue { return t.sizeQueue } -// TerminalSizeQueue is capable of returning terminal resize events as they occur. -type TerminalSizeQueue interface { - // Next returns the new terminal size after the terminal has been resized. It returns nil when - // monitoring has been stopped. - Next() *Size -} - -// sizeQueue implements TerminalSizeQueue +// sizeQueue implements remotecommand.TerminalSizeQueue type sizeQueue struct { t TTY // resizeChan receives a Size each time the user's terminal is resized. - resizeChan chan Size + resizeChan chan remotecommand.TerminalSize stopResizing chan struct{} } -// make sure sizeQueue implements the TerminalSizeQueue interface -var _ TerminalSizeQueue = &sizeQueue{} +// make sure sizeQueue implements the resize.TerminalSizeQueue interface +var _ remotecommand.TerminalSizeQueue = &sizeQueue{} // monitorSize primes resizeChan with initialSizes and then monitors for resize events. With each // new event, it sends the current terminal size to resizeChan. -func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*Size) { +func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*remotecommand.TerminalSize) { // send the initial sizes for i := range initialSizes { if initialSizes[i] != nil { @@ -99,7 +87,7 @@ func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*Size) { } } - resizeEvents := make(chan Size, 1) + resizeEvents := make(chan remotecommand.TerminalSize, 1) monitorResizeEvents(outFd, resizeEvents, s.stopResizing) @@ -130,7 +118,7 @@ func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*Size) { // Next returns the new terminal size after the terminal has been resized. It returns nil when // monitoring has been stopped. -func (s *sizeQueue) Next() *Size { +func (s *sizeQueue) Next() *remotecommand.TerminalSize { size, ok := <-s.resizeChan if !ok { return nil diff --git a/pkg/util/term/resizeevents.go b/pkg/util/term/resizeevents.go index 375023fbf1..ac2faba044 100644 --- a/pkg/util/term/resizeevents.go +++ b/pkg/util/term/resizeevents.go @@ -24,12 +24,13 @@ import ( "syscall" "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" ) // monitorResizeEvents spawns a goroutine that waits for SIGWINCH signals (these indicate the // terminal has resized). After receiving a SIGWINCH, this gets the terminal size and tries to send // it to the resizeEvents channel. The goroutine stops when the stop channel is closed. -func monitorResizeEvents(fd uintptr, resizeEvents chan<- Size, stop chan struct{}) { +func monitorResizeEvents(fd uintptr, resizeEvents chan<- remotecommand.TerminalSize, stop chan struct{}) { go func() { defer runtime.HandleCrash() diff --git a/pkg/util/term/setsize.go b/pkg/util/term/setsize.go index 944d4e5ab6..32b8526259 100644 --- a/pkg/util/term/setsize.go +++ b/pkg/util/term/setsize.go @@ -20,9 +20,10 @@ package term import ( "github.com/docker/docker/pkg/term" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" ) // SetSize sets the terminal size associated with fd. -func SetSize(fd uintptr, size Size) error { +func SetSize(fd uintptr, size remotecommand.TerminalSize) error { return term.SetWinsize(fd, &term.Winsize{Height: size.Height, Width: size.Width}) } diff --git a/pkg/kubelet/server/remotecommand/constants.go b/staging/src/k8s.io/apimachinery/pkg/util/remotecommand/constants.go similarity index 90% rename from pkg/kubelet/server/remotecommand/constants.go rename to staging/src/k8s.io/apimachinery/pkg/util/remotecommand/constants.go index ebc602b626..acfeb827c9 100644 --- a/pkg/kubelet/server/remotecommand/constants.go +++ b/staging/src/k8s.io/apimachinery/pkg/util/remotecommand/constants.go @@ -16,7 +16,11 @@ limitations under the License. package remotecommand -import "time" +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) const ( DefaultStreamCreationTimeout = 30 * time.Second @@ -41,6 +45,9 @@ const ( // attachment/execution. It is the 4th version of the subprotocol and // adds support for exit codes. StreamProtocolV4Name = "v4.channel.k8s.io" + + NonZeroExitCodeReason = metav1.StatusReason("NonZeroExitCode") + ExitCodeCauseType = metav1.CauseType("ExitCode") ) var SupportedStreamingProtocols = []string{StreamProtocolV4Name, StreamProtocolV3Name, StreamProtocolV2Name, StreamProtocolV1Name} diff --git a/test/e2e/framework/BUILD b/test/e2e/framework/BUILD index 1ca80f3183..aede04fc01 100644 --- a/test/e2e/framework/BUILD +++ b/test/e2e/framework/BUILD @@ -68,7 +68,6 @@ go_library( "//pkg/kubelet/api/v1alpha1/stats:go_default_library", "//pkg/kubelet/events:go_default_library", "//pkg/kubelet/metrics:go_default_library", - "//pkg/kubelet/server/remotecommand:go_default_library", "//pkg/kubelet/server/stats:go_default_library", "//pkg/kubelet/sysctl:go_default_library", "//pkg/kubelet/util/format:go_default_library", @@ -117,6 +116,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/intstr", "//vendor:k8s.io/apimachinery/pkg/util/net", "//vendor:k8s.io/apimachinery/pkg/util/rand", + "//vendor:k8s.io/apimachinery/pkg/util/remotecommand", "//vendor:k8s.io/apimachinery/pkg/util/runtime", "//vendor:k8s.io/apimachinery/pkg/util/sets", "//vendor:k8s.io/apimachinery/pkg/util/uuid", diff --git a/test/e2e/framework/exec_util.go b/test/e2e/framework/exec_util.go index d032ed7246..ad407b8130 100644 --- a/test/e2e/framework/exec_util.go +++ b/test/e2e/framework/exec_util.go @@ -23,11 +23,11 @@ import ( "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + remocommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" - remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" . "github.com/onsi/gomega" ) @@ -140,7 +140,7 @@ func execute(method string, url *url.URL, config *restclient.Config, stdin io.Re return err } return exec.Stream(remotecommand.StreamOptions{ - SupportedProtocols: remotecommandserver.SupportedStreamingProtocols, + SupportedProtocols: remocommandconsts.SupportedStreamingProtocols, Stdin: stdin, Stdout: stdout, Stderr: stderr, diff --git a/vendor/BUILD b/vendor/BUILD index 308c4eb0d7..e2f7d4caca 100644 --- a/vendor/BUILD +++ b/vendor/BUILD @@ -16429,3 +16429,10 @@ go_test( "//vendor:k8s.io/client-go/kubernetes/fake", ], ) + +go_library( + name = "k8s.io/apimachinery/pkg/util/remotecommand", + srcs = ["k8s.io/apimachinery/pkg/util/remotecommand/constants.go"], + tags = ["automanaged"], + deps = ["//vendor:k8s.io/apimachinery/pkg/apis/meta/v1"], +)