Merge pull request #41543 from dshulyak/decouple_remotecommand

Automatic merge from submit-queue (batch tested with PRs 44406, 41543, 44071, 44374, 44299)

Decouple remotecommand

Refactored unversioned/remotecommand to decouple it from undesirable dependencies:

- term package now is not required, and functionality required to resize terminal size can be plugged in directly in kubectl
- in order to remove dependency on kubelet package - constants from kubelet/server/remotecommand were moved to separate util package (pkg/util/remotecommand)
- remotecommand_test.go moved to pkg/client/tests module
This commit is contained in:
Kubernetes Submit Queue
2017-04-13 19:52:05 -07:00
committed by GitHub
45 changed files with 222 additions and 184 deletions

View File

@@ -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",

View File

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

View File

@@ -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",
],
)

View File

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

View File

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

View File

@@ -66,7 +66,6 @@ func (p *streamProtocolV3) handleResizes() {
if p.resizeStream == nil || p.TerminalSizeQueue == nil {
return
}
go func() {
defer runtime.HandleCrash()

View File

@@ -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"
)