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:
commit
4653a9b280
@ -14,6 +14,7 @@ go_test(
|
|||||||
"fake_client_test.go",
|
"fake_client_test.go",
|
||||||
"listwatch_test.go",
|
"listwatch_test.go",
|
||||||
"portfoward_test.go",
|
"portfoward_test.go",
|
||||||
|
"remotecommand_test.go",
|
||||||
],
|
],
|
||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
@ -26,10 +27,15 @@ go_test(
|
|||||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||||
"//pkg/client/unversioned/remotecommand:go_default_library",
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/kubelet/server/portforward: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/apis/meta/v1",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/fields",
|
"//vendor:k8s.io/apimachinery/pkg/fields",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
"//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/apimachinery/pkg/watch",
|
||||||
"//vendor:k8s.io/client-go/pkg/api/install",
|
"//vendor:k8s.io/client-go/pkg/api/install",
|
||||||
"//vendor:k8s.io/client-go/rest",
|
"//vendor:k8s.io/client-go/rest",
|
||||||
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package remotecommand
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -34,11 +34,12 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/httpstream"
|
"k8s.io/apimachinery/pkg/util/httpstream"
|
||||||
|
remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"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/kubelet/server/remotecommand"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeExecutor struct {
|
type fakeExecutor struct {
|
||||||
@ -55,11 +56,11 @@ type fakeExecutor struct {
|
|||||||
exec bool
|
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)
|
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)
|
return ex.run(name, uid, container, nil, in, out, err, tty)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,8 +152,8 @@ func TestStream(t *testing.T) {
|
|||||||
TestName: "error",
|
TestName: "error",
|
||||||
Error: "bail",
|
Error: "bail",
|
||||||
Stdout: "a",
|
Stdout: "a",
|
||||||
ClientProtocols: []string{remotecommand.StreamProtocolV2Name},
|
ClientProtocols: []string{remotecommandconsts.StreamProtocolV2Name},
|
||||||
ServerProtocols: []string{remotecommand.StreamProtocolV2Name},
|
ServerProtocols: []string{remotecommandconsts.StreamProtocolV2Name},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
TestName: "in/out/err",
|
TestName: "in/out/err",
|
||||||
@ -160,8 +161,8 @@ func TestStream(t *testing.T) {
|
|||||||
Stdout: "b",
|
Stdout: "b",
|
||||||
Stderr: "c",
|
Stderr: "c",
|
||||||
MessageCount: 100,
|
MessageCount: 100,
|
||||||
ClientProtocols: []string{remotecommand.StreamProtocolV2Name},
|
ClientProtocols: []string{remotecommandconsts.StreamProtocolV2Name},
|
||||||
ServerProtocols: []string{remotecommand.StreamProtocolV2Name},
|
ServerProtocols: []string{remotecommandconsts.StreamProtocolV2Name},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
TestName: "in/out/tty",
|
TestName: "in/out/tty",
|
||||||
@ -169,8 +170,8 @@ func TestStream(t *testing.T) {
|
|||||||
Stdout: "b",
|
Stdout: "b",
|
||||||
Tty: true,
|
Tty: true,
|
||||||
MessageCount: 100,
|
MessageCount: 100,
|
||||||
ClientProtocols: []string{remotecommand.StreamProtocolV2Name},
|
ClientProtocols: []string{remotecommandconsts.StreamProtocolV2Name},
|
||||||
ServerProtocols: []string{remotecommand.StreamProtocolV2Name},
|
ServerProtocols: []string{remotecommandconsts.StreamProtocolV2Name},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 1.0 kubectl, 1.0 kubelet
|
// 1.0 kubectl, 1.0 kubelet
|
||||||
@ -188,7 +189,7 @@ func TestStream(t *testing.T) {
|
|||||||
Stderr: "c",
|
Stderr: "c",
|
||||||
MessageCount: 1,
|
MessageCount: 1,
|
||||||
ClientProtocols: []string{},
|
ClientProtocols: []string{},
|
||||||
ServerProtocols: []string{remotecommand.StreamProtocolV2Name, remotecommand.StreamProtocolV1Name},
|
ServerProtocols: []string{remotecommandconsts.StreamProtocolV2Name, remotecommandconsts.StreamProtocolV1Name},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 1.1+ kubectl, 1.0 kubelet
|
// 1.1+ kubectl, 1.0 kubelet
|
||||||
@ -196,7 +197,7 @@ func TestStream(t *testing.T) {
|
|||||||
Stdout: "b",
|
Stdout: "b",
|
||||||
Stderr: "c",
|
Stderr: "c",
|
||||||
MessageCount: 1,
|
MessageCount: 1,
|
||||||
ClientProtocols: []string{remotecommand.StreamProtocolV2Name, remotecommand.StreamProtocolV1Name},
|
ClientProtocols: []string{remotecommandconsts.StreamProtocolV2Name, remotecommandconsts.StreamProtocolV1Name},
|
||||||
ServerProtocols: []string{},
|
ServerProtocols: []string{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -254,12 +255,12 @@ func TestStream(t *testing.T) {
|
|||||||
conf := &restclient.Config{
|
conf := &restclient.Config{
|
||||||
Host: server.URL,
|
Host: server.URL,
|
||||||
}
|
}
|
||||||
e, err := NewExecutor(conf, "POST", req.URL())
|
e, err := remoteclient.NewExecutor(conf, "POST", req.URL())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%s: unexpected error: %v", name, err)
|
t.Errorf("%s: unexpected error: %v", name, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = e.Stream(StreamOptions{
|
err = e.Stream(remoteclient.StreamOptions{
|
||||||
SupportedProtocols: testCase.ClientProtocols,
|
SupportedProtocols: testCase.ClientProtocols,
|
||||||
Stdin: streamIn,
|
Stdin: streamIn,
|
||||||
Stdout: streamOut,
|
Stdout: streamOut,
|
||||||
@ -351,7 +352,7 @@ func TestDial(t *testing.T) {
|
|||||||
called = true
|
called = true
|
||||||
return rt
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
@ -14,6 +14,7 @@ go_library(
|
|||||||
"doc.go",
|
"doc.go",
|
||||||
"errorstream.go",
|
"errorstream.go",
|
||||||
"remotecommand.go",
|
"remotecommand.go",
|
||||||
|
"resize.go",
|
||||||
"v1.go",
|
"v1.go",
|
||||||
"v2.go",
|
"v2.go",
|
||||||
"v3.go",
|
"v3.go",
|
||||||
@ -22,13 +23,12 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/kubelet/server/remotecommand:go_default_library",
|
|
||||||
"//pkg/util/exec:go_default_library",
|
"//pkg/util/exec:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//vendor:github.com/golang/glog",
|
"//vendor:github.com/golang/glog",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/httpstream",
|
"//vendor:k8s.io/apimachinery/pkg/util/httpstream",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
"//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/apimachinery/pkg/util/runtime",
|
||||||
"//vendor:k8s.io/client-go/rest",
|
"//vendor:k8s.io/client-go/rest",
|
||||||
"//vendor:k8s.io/client-go/transport",
|
"//vendor:k8s.io/client-go/transport",
|
||||||
@ -38,7 +38,6 @@ go_library(
|
|||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
"remotecommand_test.go",
|
|
||||||
"v2_test.go",
|
"v2_test.go",
|
||||||
"v4_test.go",
|
"v4_test.go",
|
||||||
],
|
],
|
||||||
@ -46,15 +45,8 @@ go_test(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//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/httpstream",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||||
"//vendor:k8s.io/client-go/rest",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,10 +26,9 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/httpstream"
|
"k8s.io/apimachinery/pkg/util/httpstream"
|
||||||
"k8s.io/apimachinery/pkg/util/httpstream/spdy"
|
"k8s.io/apimachinery/pkg/util/httpstream/spdy"
|
||||||
|
"k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/transport"
|
"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
|
// StreamOptions holds information pertaining to the current streaming session: supported stream
|
||||||
@ -41,7 +40,7 @@ type StreamOptions struct {
|
|||||||
Stdout io.Writer
|
Stdout io.Writer
|
||||||
Stderr io.Writer
|
Stderr io.Writer
|
||||||
Tty bool
|
Tty bool
|
||||||
TerminalSizeQueue term.TerminalSizeQueue
|
TerminalSizeQueue TerminalSizeQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executor is an interface for transporting shell-style streams.
|
// Executor is an interface for transporting shell-style streams.
|
||||||
|
33
pkg/client/unversioned/remotecommand/resize.go
Normal file
33
pkg/client/unversioned/remotecommand/resize.go
Normal 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
|
||||||
|
}
|
@ -66,7 +66,6 @@ func (p *streamProtocolV3) handleResizes() {
|
|||||||
if p.resizeStream == nil || p.TerminalSizeQueue == nil {
|
if p.resizeStream == nil || p.TerminalSizeQueue == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer runtime.HandleCrash()
|
defer runtime.HandleCrash()
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
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"
|
"k8s.io/kubernetes/pkg/util/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -93,7 +93,6 @@ go_library(
|
|||||||
"//pkg/kubectl/cmd/util/editor:go_default_library",
|
"//pkg/kubectl/cmd/util/editor:go_default_library",
|
||||||
"//pkg/kubectl/metricsutil:go_default_library",
|
"//pkg/kubectl/metricsutil:go_default_library",
|
||||||
"//pkg/kubectl/resource:go_default_library",
|
"//pkg/kubectl/resource:go_default_library",
|
||||||
"//pkg/kubelet/server/remotecommand:go_default_library",
|
|
||||||
"//pkg/kubelet/types:go_default_library",
|
"//pkg/kubelet/types:go_default_library",
|
||||||
"//pkg/printers:go_default_library",
|
"//pkg/printers:go_default_library",
|
||||||
"//pkg/printers/internalversion:go_default_library",
|
"//pkg/printers/internalversion:go_default_library",
|
||||||
@ -128,6 +127,7 @@ go_library(
|
|||||||
"//vendor:k8s.io/apimachinery/pkg/util/json",
|
"//vendor:k8s.io/apimachinery/pkg/util/json",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/jsonmergepatch",
|
"//vendor:k8s.io/apimachinery/pkg/util/jsonmergepatch",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/mergepatch",
|
"//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/sets",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/strategicpatch",
|
"//vendor:k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/validation",
|
"//vendor:k8s.io/apimachinery/pkg/util/validation",
|
||||||
@ -203,6 +203,7 @@ go_test(
|
|||||||
"//pkg/apis/extensions:go_default_library",
|
"//pkg/apis/extensions:go_default_library",
|
||||||
"//pkg/apis/policy:go_default_library",
|
"//pkg/apis/policy:go_default_library",
|
||||||
"//pkg/apis/rbac:go_default_library",
|
"//pkg/apis/rbac:go_default_library",
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/kubectl:go_default_library",
|
"//pkg/kubectl:go_default_library",
|
||||||
"//pkg/kubectl/cmd/testing:go_default_library",
|
"//pkg/kubectl/cmd/testing:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
|
remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
@ -34,9 +35,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"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/i18n"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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
|
// RemoteAttach defines the interface accepted by the Attach command - provided for test stubbing
|
||||||
type RemoteAttach interface {
|
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
|
// DefaultRemoteAttach is the standard implementation of attaching
|
||||||
type DefaultRemoteAttach struct{}
|
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)
|
exec, err := remotecommand.NewExecutor(config, method, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return exec.Stream(remotecommand.StreamOptions{
|
return exec.Stream(remotecommand.StreamOptions{
|
||||||
SupportedProtocols: remotecommandserver.SupportedStreamingProtocols,
|
SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols,
|
||||||
Stdin: stdin,
|
Stdin: stdin,
|
||||||
Stdout: stdout,
|
Stdout: stdout,
|
||||||
Stderr: stderr,
|
Stderr: stderr,
|
||||||
@ -242,7 +241,7 @@ func (p *AttachOptions) Run() error {
|
|||||||
// save p.Err so we can print the command prompt message below
|
// save p.Err so we can print the command prompt message below
|
||||||
stderr := p.Err
|
stderr := p.Err
|
||||||
|
|
||||||
var sizeQueue term.TerminalSizeQueue
|
var sizeQueue remotecommand.TerminalSizeQueue
|
||||||
if t.Raw {
|
if t.Raw {
|
||||||
if size := t.GetSize(); size != nil {
|
if size := t.GetSize(); size != nil {
|
||||||
// fake resizing +1 and then back to normal so that attach-detach-reattach will result in the
|
// fake resizing +1 and then back to normal so that attach-detach-reattach will result in the
|
||||||
|
@ -34,9 +34,9 @@ import (
|
|||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/rest/fake"
|
"k8s.io/client-go/rest/fake"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeRemoteAttach struct {
|
type fakeRemoteAttach struct {
|
||||||
@ -45,7 +45,7 @@ type fakeRemoteAttach struct {
|
|||||||
err error
|
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.method = method
|
||||||
f.url = url
|
f.url = url
|
||||||
return f.err
|
return f.err
|
||||||
|
@ -25,13 +25,13 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
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/i18n"
|
||||||
"k8s.io/kubernetes/pkg/util/interrupt"
|
"k8s.io/kubernetes/pkg/util/interrupt"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
"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
|
// RemoteExecutor defines the interface accepted by the Exec command - provided for test stubbing
|
||||||
type RemoteExecutor interface {
|
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
|
// DefaultRemoteExecutor is the standard implementation of remote command execution
|
||||||
type DefaultRemoteExecutor struct{}
|
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)
|
exec, err := remotecommand.NewExecutor(config, method, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return exec.Stream(remotecommand.StreamOptions{
|
return exec.Stream(remotecommand.StreamOptions{
|
||||||
SupportedProtocols: remotecommandserver.SupportedStreamingProtocols,
|
SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols,
|
||||||
Stdin: stdin,
|
Stdin: stdin,
|
||||||
Stdout: stdout,
|
Stdout: stdout,
|
||||||
Stderr: stderr,
|
Stderr: stderr,
|
||||||
@ -284,7 +284,7 @@ func (p *ExecOptions) Run() error {
|
|||||||
// ensure we can recover the terminal while attached
|
// ensure we can recover the terminal while attached
|
||||||
t := p.setupTTY()
|
t := p.setupTTY()
|
||||||
|
|
||||||
var sizeQueue term.TerminalSizeQueue
|
var sizeQueue remotecommand.TerminalSizeQueue
|
||||||
if t.Raw {
|
if t.Raw {
|
||||||
// this call spawns a goroutine to monitor/update the terminal size
|
// this call spawns a goroutine to monitor/update the terminal size
|
||||||
sizeQueue = t.MonitorSize(t.GetSize())
|
sizeQueue = t.MonitorSize(t.GetSize())
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/rest/fake"
|
"k8s.io/client-go/rest/fake"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
"k8s.io/kubernetes/pkg/util/term"
|
||||||
)
|
)
|
||||||
@ -43,7 +44,7 @@ type fakeRemoteExecutor struct {
|
|||||||
execErr error
|
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.method = method
|
||||||
f.url = url
|
f.url = url
|
||||||
return f.execErr
|
return f.execErr
|
||||||
|
@ -43,6 +43,7 @@ go_library(
|
|||||||
"//pkg/capabilities:go_default_library",
|
"//pkg/capabilities:go_default_library",
|
||||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||||
"//pkg/client/listers/core/v1:go_default_library",
|
"//pkg/client/listers/core/v1:go_default_library",
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/cloudprovider:go_default_library",
|
"//pkg/cloudprovider:go_default_library",
|
||||||
"//pkg/features:go_default_library",
|
"//pkg/features:go_default_library",
|
||||||
"//pkg/fieldpath:go_default_library",
|
"//pkg/fieldpath:go_default_library",
|
||||||
@ -99,7 +100,6 @@ go_library(
|
|||||||
"//pkg/util/oom:go_default_library",
|
"//pkg/util/oom:go_default_library",
|
||||||
"//pkg/util/procfs:go_default_library",
|
"//pkg/util/procfs:go_default_library",
|
||||||
"//pkg/util/removeall:go_default_library",
|
"//pkg/util/removeall:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//pkg/version:go_default_library",
|
"//pkg/version:go_default_library",
|
||||||
"//pkg/volume:go_default_library",
|
"//pkg/volume:go_default_library",
|
||||||
"//pkg/volume/util:go_default_library",
|
"//pkg/volume/util:go_default_library",
|
||||||
|
@ -28,12 +28,12 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/v1: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/api/v1alpha1/runtime:go_default_library",
|
||||||
"//pkg/kubelet/events:go_default_library",
|
"//pkg/kubelet/events:go_default_library",
|
||||||
"//pkg/kubelet/util/format:go_default_library",
|
"//pkg/kubelet/util/format:go_default_library",
|
||||||
"//pkg/kubelet/util/ioutils:go_default_library",
|
"//pkg/kubelet/util/ioutils:go_default_library",
|
||||||
"//pkg/util/hash:go_default_library",
|
"//pkg/util/hash:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//pkg/volume:go_default_library",
|
"//pkg/volume:go_default_library",
|
||||||
"//third_party/forked/golang/expansion:go_default_library",
|
"//third_party/forked/golang/expansion:go_default_library",
|
||||||
"//vendor:github.com/golang/glog",
|
"//vendor:github.com/golang/glog",
|
||||||
|
@ -18,13 +18,13 @@ package container
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"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
|
// 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.
|
// 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 {
|
if resize == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ type DirectStreamingRuntime interface {
|
|||||||
// Runs the command in the container of the specified pod using nsenter.
|
// Runs the command in the container of the specified pod using nsenter.
|
||||||
// Attaches the processes stdin, stdout, and stderr. Optionally uses a
|
// Attaches the processes stdin, stdout, and stderr. Optionally uses a
|
||||||
// tty.
|
// 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.
|
// Forward the specified port from the specified pod to the stream.
|
||||||
PortForward(pod *Pod, port int32, stream io.ReadWriteCloser) error
|
PortForward(pod *Pod, port int32, stream io.ReadWriteCloser) error
|
||||||
// ContainerAttach encapsulates the attaching to containers for testability
|
// ContainerAttach encapsulates the attaching to containers for testability
|
||||||
@ -160,7 +160,7 @@ type ImageService interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ContainerAttacher 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 {
|
type ContainerCommandRunner interface {
|
||||||
|
@ -20,8 +20,8 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/kubelet/container:go_default_library",
|
"//pkg/kubelet/container:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//pkg/volume:go_default_library",
|
"//pkg/volume:go_default_library",
|
||||||
"//vendor:github.com/golang/mock/gomock",
|
"//vendor:github.com/golang/mock/gomock",
|
||||||
"//vendor:github.com/stretchr/testify/mock",
|
"//vendor:github.com/stretchr/testify/mock",
|
||||||
|
@ -27,8 +27,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
. "k8s.io/kubernetes/pkg/kubelet/container"
|
. "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -311,7 +311,7 @@ func (f *FakeRuntime) GetPodStatus(uid types.UID, name, namespace string) (*PodS
|
|||||||
return &status, f.Err
|
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()
|
f.Lock()
|
||||||
defer f.Unlock()
|
defer f.Unlock()
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ func (f *FakeDirectStreamingRuntime) ExecInContainer(containerID ContainerID, cm
|
|||||||
return f.Err
|
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()
|
f.Lock()
|
||||||
defer f.Unlock()
|
defer f.Unlock()
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
. "k8s.io/kubernetes/pkg/kubelet/container"
|
. "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"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)
|
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)
|
args := r.Called(containerID, cmd, stdin, stdout, stderr, tty)
|
||||||
return args.Error(0)
|
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)
|
args := r.Called(containerID, stdin, stdout, stderr, tty)
|
||||||
return args.Error(0)
|
return args.Error(0)
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/apis/componentconfig: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:go_default_library",
|
||||||
"//pkg/kubelet/api/v1alpha1/runtime:go_default_library",
|
"//pkg/kubelet/api/v1alpha1/runtime:go_default_library",
|
||||||
"//pkg/kubelet/cm: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/cache:go_default_library",
|
||||||
"//pkg/kubelet/util/ioutils:go_default_library",
|
"//pkg/kubelet/util/ioutils:go_default_library",
|
||||||
"//pkg/util/hash:go_default_library",
|
"//pkg/util/hash:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//vendor:github.com/blang/semver",
|
"//vendor:github.com/blang/semver",
|
||||||
"//vendor:github.com/docker/engine-api/types",
|
"//vendor:github.com/docker/engine-api/types",
|
||||||
"//vendor:github.com/docker/engine-api/types/container",
|
"//vendor:github.com/docker/engine-api/types/container",
|
||||||
|
@ -24,11 +24,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
dockertypes "github.com/docker/engine-api/types"
|
dockertypes "github.com/docker/engine-api/types"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/dockertools"
|
"k8s.io/kubernetes/pkg/kubelet/dockertools"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/server/streaming"
|
"k8s.io/kubernetes/pkg/kubelet/server/streaming"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/util/ioutils"
|
"k8s.io/kubernetes/pkg/kubelet/util/ioutils"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type streamingRuntime struct {
|
type streamingRuntime struct {
|
||||||
@ -38,12 +38,12 @@ type streamingRuntime struct {
|
|||||||
|
|
||||||
var _ streaming.Runtime = &streamingRuntime{}
|
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)
|
return r.exec(containerID, cmd, in, out, err, tty, resize, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal version of Exec adds a timeout.
|
// 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)
|
container, err := checkContainerStatus(r.client, containerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)
|
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)
|
_, err := checkContainerStatus(r.client, containerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -28,6 +28,7 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/credentialprovider:go_default_library",
|
"//pkg/credentialprovider:go_default_library",
|
||||||
"//pkg/kubelet/cm:go_default_library",
|
"//pkg/kubelet/cm:go_default_library",
|
||||||
"//pkg/kubelet/container:go_default_library",
|
"//pkg/kubelet/container:go_default_library",
|
||||||
|
@ -52,6 +52,7 @@ import (
|
|||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm"
|
"k8s.io/kubernetes/pkg/kubelet/cm"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
dockersecurity "k8s.io/kubernetes/pkg/kubelet/dockertools/securitycontext"
|
dockersecurity "k8s.io/kubernetes/pkg/kubelet/dockertools/securitycontext"
|
||||||
@ -73,7 +74,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/util/selinux"
|
"k8s.io/kubernetes/pkg/util/selinux"
|
||||||
utilstrings "k8s.io/kubernetes/pkg/util/strings"
|
utilstrings "k8s.io/kubernetes/pkg/util/strings"
|
||||||
"k8s.io/kubernetes/pkg/util/tail"
|
"k8s.io/kubernetes/pkg/util/tail"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
utilversion "k8s.io/kubernetes/pkg/util/version"
|
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.
|
// 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 {
|
if dm.execHandler == nil {
|
||||||
return errors.New("unable to exec without an exec handler")
|
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)
|
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)
|
return AttachContainer(dm.client, containerID.ID, stdin, stdout, stderr, tty, resize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporarily export this function to share with dockershim.
|
// Temporarily export this function to share with dockershim.
|
||||||
// TODO: clean this up.
|
// 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
|
// 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.
|
// 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))
|
client.ResizeContainerTTY(containerID, int(size.Height), int(size.Width))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
dockertypes "github.com/docker/engine-api/types"
|
dockertypes "github.com/docker/engine-api/types"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
utilexec "k8s.io/kubernetes/pkg/util/exec"
|
utilexec "k8s.io/kubernetes/pkg/util/exec"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
"k8s.io/kubernetes/pkg/util/term"
|
||||||
@ -32,14 +33,14 @@ import (
|
|||||||
|
|
||||||
// ExecHandler knows how to execute a command in a running Docker container.
|
// ExecHandler knows how to execute a command in a running Docker container.
|
||||||
type ExecHandler interface {
|
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.
|
// NsenterExecHandler executes commands in Docker containers using nsenter.
|
||||||
type NsenterExecHandler struct{}
|
type NsenterExecHandler struct{}
|
||||||
|
|
||||||
// TODO should we support nsenter in a container, running with elevated privs and --pid=host?
|
// 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")
|
nsenter, err := exec.LookPath("nsenter")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("exec unavailable - unable to locate nsenter")
|
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
|
// make sure to close the stdout stream
|
||||||
defer stdout.Close()
|
defer stdout.Close()
|
||||||
|
|
||||||
kubecontainer.HandleResizing(resize, func(size term.Size) {
|
kubecontainer.HandleResizing(resize, func(size remotecommand.TerminalSize) {
|
||||||
term.SetSize(p.Fd(), size)
|
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.
|
// NativeExecHandler executes commands in Docker containers using Docker's exec API.
|
||||||
type NativeExecHandler struct{}
|
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{
|
createOpts := dockertypes.ExecConfig{
|
||||||
Cmd: cmd,
|
Cmd: cmd,
|
||||||
AttachStdin: stdin != nil,
|
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
|
// 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.
|
// 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))
|
client.ResizeExecTTY(execObj.ID, int(size.Height), int(size.Width))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/api/v1/validation"
|
"k8s.io/kubernetes/pkg/api/v1/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
"k8s.io/kubernetes/pkg/fieldpath"
|
"k8s.io/kubernetes/pkg/fieldpath"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm"
|
"k8s.io/kubernetes/pkg/kubelet/cm"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
@ -50,11 +51,10 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubelet/images"
|
"k8s.io/kubernetes/pkg/kubelet/images"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/server/portforward"
|
"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"
|
"k8s.io/kubernetes/pkg/kubelet/status"
|
||||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||||
"k8s.io/kubernetes/third_party/forked/golang/expansion"
|
"k8s.io/kubernetes/third_party/forked/golang/expansion"
|
||||||
@ -1399,7 +1399,7 @@ func (kl *Kubelet) RunInContainer(podFullName string, podUID types.UID, containe
|
|||||||
|
|
||||||
// ExecInContainer executes a command in a container, connecting the supplied
|
// ExecInContainer executes a command in a container, connecting the supplied
|
||||||
// stdin/stdout/stderr to the command's IO streams.
|
// 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)
|
streamingRuntime, ok := kl.containerRuntime.(kubecontainer.DirectStreamingRuntime)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("streaming methods not supported by runtime")
|
return fmt.Errorf("streaming methods not supported by runtime")
|
||||||
@ -1417,7 +1417,7 @@ func (kl *Kubelet) ExecInContainer(podFullName string, podUID types.UID, contain
|
|||||||
|
|
||||||
// AttachContainer uses the container runtime to attach the given streams to
|
// AttachContainer uses the container runtime to attach the given streams to
|
||||||
// the given container.
|
// 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)
|
streamingRuntime, ok := kl.containerRuntime.(kubecontainer.DirectStreamingRuntime)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("streaming methods not supported by runtime")
|
return fmt.Errorf("streaming methods not supported by runtime")
|
||||||
@ -1454,7 +1454,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.
|
// 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) {
|
switch streamingRuntime := kl.containerRuntime.(type) {
|
||||||
case kubecontainer.DirectStreamingRuntime:
|
case kubecontainer.DirectStreamingRuntime:
|
||||||
// Kubelet will serve the exec directly.
|
// Kubelet will serve the exec directly.
|
||||||
@ -1474,7 +1474,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.
|
// 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) {
|
switch streamingRuntime := kl.containerRuntime.(type) {
|
||||||
case kubecontainer.DirectStreamingRuntime:
|
case kubecontainer.DirectStreamingRuntime:
|
||||||
// Kubelet will serve the attach directly.
|
// Kubelet will serve the attach directly.
|
||||||
|
@ -24,6 +24,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/credentialprovider:go_default_library",
|
"//pkg/credentialprovider:go_default_library",
|
||||||
"//pkg/kubelet/container:go_default_library",
|
"//pkg/kubelet/container:go_default_library",
|
||||||
"//pkg/kubelet/events:go_default_library",
|
"//pkg/kubelet/events:go_default_library",
|
||||||
|
@ -49,6 +49,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
"k8s.io/kubernetes/pkg/credentialprovider"
|
"k8s.io/kubernetes/pkg/credentialprovider"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/events"
|
"k8s.io/kubernetes/pkg/kubelet/events"
|
||||||
@ -2068,14 +2069,14 @@ func newRktExitError(e error) error {
|
|||||||
return e
|
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")
|
return fmt.Errorf("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: In rkt, the container ID is in the form of "UUID:appName", where UUID is
|
// 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.
|
// 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.
|
// 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.")
|
glog.V(4).Infof("Rkt execing in container.")
|
||||||
|
|
||||||
id, err := parseContainerID(containerID)
|
id, err := parseContainerID(containerID)
|
||||||
@ -2096,7 +2097,7 @@ func (r *Runtime) ExecInContainer(containerID kubecontainer.ContainerID, cmd []s
|
|||||||
// make sure to close the stdout stream
|
// make sure to close the stdout stream
|
||||||
defer stdout.Close()
|
defer stdout.Close()
|
||||||
|
|
||||||
kubecontainer.HandleResizing(resize, func(size term.Size) {
|
kubecontainer.HandleResizing(resize, func(size remotecommand.TerminalSize) {
|
||||||
term.SetSize(p.Fd(), size)
|
term.SetSize(p.Fd(), size)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ go_library(
|
|||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/api/v1/validation: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/cm:go_default_library",
|
||||||
"//pkg/kubelet/container:go_default_library",
|
"//pkg/kubelet/container:go_default_library",
|
||||||
"//pkg/kubelet/server/portforward:go_default_library",
|
"//pkg/kubelet/server/portforward:go_default_library",
|
||||||
@ -28,7 +29,6 @@ go_library(
|
|||||||
"//pkg/kubelet/server/streaming:go_default_library",
|
"//pkg/kubelet/server/streaming:go_default_library",
|
||||||
"//pkg/util/configz:go_default_library",
|
"//pkg/util/configz:go_default_library",
|
||||||
"//pkg/util/limitwriter:go_default_library",
|
"//pkg/util/limitwriter:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//pkg/volume:go_default_library",
|
"//pkg/volume:go_default_library",
|
||||||
"//vendor:github.com/emicklei/go-restful",
|
"//vendor:github.com/emicklei/go-restful",
|
||||||
"//vendor:github.com/golang/glog",
|
"//vendor:github.com/golang/glog",
|
||||||
@ -40,6 +40,7 @@ go_library(
|
|||||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/util/remotecommand",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
|
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
|
||||||
"//vendor:k8s.io/apiserver/pkg/authentication/authenticator",
|
"//vendor:k8s.io/apiserver/pkg/authentication/authenticator",
|
||||||
"//vendor:k8s.io/apiserver/pkg/authentication/user",
|
"//vendor:k8s.io/apiserver/pkg/authentication/user",
|
||||||
@ -62,13 +63,13 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/kubelet/cm:go_default_library",
|
"//pkg/kubelet/cm:go_default_library",
|
||||||
"//pkg/kubelet/container:go_default_library",
|
"//pkg/kubelet/container:go_default_library",
|
||||||
"//pkg/kubelet/container/testing:go_default_library",
|
"//pkg/kubelet/container/testing:go_default_library",
|
||||||
"//pkg/kubelet/server/portforward:go_default_library",
|
"//pkg/kubelet/server/portforward:go_default_library",
|
||||||
"//pkg/kubelet/server/remotecommand:go_default_library",
|
"//pkg/kubelet/server/remotecommand:go_default_library",
|
||||||
"//pkg/kubelet/server/stats:go_default_library",
|
"//pkg/kubelet/server/stats:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//pkg/volume:go_default_library",
|
"//pkg/volume:go_default_library",
|
||||||
"//vendor:github.com/google/cadvisor/info/v1",
|
"//vendor:github.com/google/cadvisor/info/v1",
|
||||||
"//vendor:github.com/google/cadvisor/info/v2",
|
"//vendor:github.com/google/cadvisor/info/v2",
|
||||||
|
@ -11,7 +11,6 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
"attach.go",
|
"attach.go",
|
||||||
"constants.go",
|
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"exec.go",
|
"exec.go",
|
||||||
"httpstream.go",
|
"httpstream.go",
|
||||||
@ -20,14 +19,15 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/util/exec:go_default_library",
|
"//pkg/util/exec:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//vendor:github.com/golang/glog",
|
"//vendor:github.com/golang/glog",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/httpstream",
|
"//vendor:k8s.io/apimachinery/pkg/util/httpstream",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
"//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/apimachinery/pkg/util/runtime",
|
||||||
"//vendor:k8s.io/apiserver/pkg/server/httplog",
|
"//vendor:k8s.io/apiserver/pkg/server/httplog",
|
||||||
"//vendor:k8s.io/apiserver/pkg/util/wsstream",
|
"//vendor:k8s.io/apiserver/pkg/util/wsstream",
|
||||||
|
@ -26,14 +26,14 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"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.
|
// Attacher knows how to attach to a running container in a pod.
|
||||||
type Attacher interface {
|
type Attacher interface {
|
||||||
// AttachContainer attaches to the running container in the pod, copying data between in/out/err
|
// AttachContainer attaches to the running container in the pod, copying data between in/out/err
|
||||||
// and the container's stdin/stdout/stderr.
|
// 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
|
// ServeAttach handles requests to attach to a container. After creating/receiving the required
|
||||||
|
@ -25,21 +25,17 @@ import (
|
|||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
utilexec "k8s.io/kubernetes/pkg/util/exec"
|
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.
|
// Executor knows how to execute a command in a container in a pod.
|
||||||
type Executor interface {
|
type Executor interface {
|
||||||
// ExecInContainer executes a command in a container in the pod, copying data
|
// ExecInContainer executes a command in a container in the pod, copying data
|
||||||
// between in/out/err and the container's stdin/stdout/stderr.
|
// 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
|
// 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()
|
rc := exitErr.ExitStatus()
|
||||||
ctx.writeStatus(&apierrors.StatusError{ErrStatus: metav1.Status{
|
ctx.writeStatus(&apierrors.StatusError{ErrStatus: metav1.Status{
|
||||||
Status: metav1.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Reason: NonZeroExitCodeReason,
|
Reason: remotecommandconsts.NonZeroExitCodeReason,
|
||||||
Details: &metav1.StatusDetails{
|
Details: &metav1.StatusDetails{
|
||||||
Causes: []metav1.StatusCause{
|
Causes: []metav1.StatusCause{
|
||||||
{
|
{
|
||||||
Type: ExitCodeCauseType,
|
Type: remotecommandconsts.ExitCodeCauseType,
|
||||||
Message: fmt.Sprintf("%d", rc),
|
Message: fmt.Sprintf("%d", rc),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -28,10 +28,11 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/httpstream"
|
"k8s.io/apimachinery/pkg/util/httpstream"
|
||||||
"k8s.io/apimachinery/pkg/util/httpstream/spdy"
|
"k8s.io/apimachinery/pkg/util/httpstream/spdy"
|
||||||
|
remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apiserver/pkg/util/wsstream"
|
"k8s.io/apiserver/pkg/util/wsstream"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
@ -78,7 +79,7 @@ type context struct {
|
|||||||
stderrStream io.WriteCloser
|
stderrStream io.WriteCloser
|
||||||
writeStatus func(status *apierrors.StatusError) error
|
writeStatus func(status *apierrors.StatusError) error
|
||||||
resizeStream io.ReadCloser
|
resizeStream io.ReadCloser
|
||||||
resizeChan chan term.Size
|
resizeChan chan remotecommand.TerminalSize
|
||||||
tty bool
|
tty bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ func createStreams(req *http.Request, w http.ResponseWriter, opts *Options, supp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.resizeStream != nil {
|
if ctx.resizeStream != nil {
|
||||||
ctx.resizeChan = make(chan term.Size)
|
ctx.resizeChan = make(chan remotecommand.TerminalSize)
|
||||||
go handleResizeEvents(ctx.resizeStream, ctx.resizeChan)
|
go handleResizeEvents(ctx.resizeStream, ctx.resizeChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,16 +149,16 @@ func createHttpStreamStreams(req *http.Request, w http.ResponseWriter, opts *Opt
|
|||||||
|
|
||||||
var handler protocolHandler
|
var handler protocolHandler
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case StreamProtocolV4Name:
|
case remotecommandconsts.StreamProtocolV4Name:
|
||||||
handler = &v4ProtocolHandler{}
|
handler = &v4ProtocolHandler{}
|
||||||
case StreamProtocolV3Name:
|
case remotecommandconsts.StreamProtocolV3Name:
|
||||||
handler = &v3ProtocolHandler{}
|
handler = &v3ProtocolHandler{}
|
||||||
case StreamProtocolV2Name:
|
case remotecommandconsts.StreamProtocolV2Name:
|
||||||
handler = &v2ProtocolHandler{}
|
handler = &v2ProtocolHandler{}
|
||||||
case "":
|
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
|
fallthrough
|
||||||
case StreamProtocolV1Name:
|
case remotecommandconsts.StreamProtocolV1Name:
|
||||||
handler = &v1ProtocolHandler{}
|
handler = &v1ProtocolHandler{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,12 +410,12 @@ WaitForStreams:
|
|||||||
// supportsTerminalResizing returns false because v1ProtocolHandler doesn't support it.
|
// supportsTerminalResizing returns false because v1ProtocolHandler doesn't support it.
|
||||||
func (*v1ProtocolHandler) supportsTerminalResizing() bool { return false }
|
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()
|
defer runtime.HandleCrash()
|
||||||
|
|
||||||
decoder := json.NewDecoder(stream)
|
decoder := json.NewDecoder(stream)
|
||||||
for {
|
for {
|
||||||
size := term.Size{}
|
size := remotecommand.TerminalSize{}
|
||||||
if err := decoder.Decode(&size); err != nil {
|
if err := decoder.Decode(&size); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
@ -50,15 +51,15 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/api/v1/validation"
|
"k8s.io/kubernetes/pkg/api/v1/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm"
|
"k8s.io/kubernetes/pkg/kubelet/cm"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/server/portforward"
|
"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/stats"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/server/streaming"
|
"k8s.io/kubernetes/pkg/kubelet/server/streaming"
|
||||||
"k8s.io/kubernetes/pkg/util/configz"
|
"k8s.io/kubernetes/pkg/util/configz"
|
||||||
"k8s.io/kubernetes/pkg/util/limitwriter"
|
"k8s.io/kubernetes/pkg/util/limitwriter"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -170,8 +171,8 @@ type HostInterface interface {
|
|||||||
GetRunningPods() ([]*v1.Pod, error)
|
GetRunningPods() ([]*v1.Pod, error)
|
||||||
GetPodByName(namespace, name string) (*v1.Pod, bool)
|
GetPodByName(namespace, name string) (*v1.Pod, bool)
|
||||||
RunInContainer(name string, uid types.UID, container string, cmd []string) ([]byte, error)
|
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
|
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 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
|
||||||
GetKubeletContainerLogs(podFullName, containerName string, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) error
|
GetKubeletContainerLogs(podFullName, containerName string, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) error
|
||||||
ServeLogs(w http.ResponseWriter, req *http.Request)
|
ServeLogs(w http.ResponseWriter, req *http.Request)
|
||||||
PortForward(name string, uid types.UID, port int32, stream io.ReadWriteCloser) error
|
PortForward(name string, uid types.UID, port int32, stream io.ReadWriteCloser) error
|
||||||
@ -184,8 +185,8 @@ type HostInterface interface {
|
|||||||
ImagesFsInfo() (cadvisorapiv2.FsInfo, error)
|
ImagesFsInfo() (cadvisorapiv2.FsInfo, error)
|
||||||
RootFsInfo() (cadvisorapiv2.FsInfo, error)
|
RootFsInfo() (cadvisorapiv2.FsInfo, error)
|
||||||
ListVolumesForPod(podUID types.UID) (map[string]volume.Volume, bool)
|
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)
|
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 remotecommand.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)
|
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.
|
// getAttach handles requests to attach to a container.
|
||||||
func (s *Server) getAttach(request *restful.Request, response *restful.Response) {
|
func (s *Server) getAttach(request *restful.Request, response *restful.Response) {
|
||||||
params := getExecRequestParams(request)
|
params := getExecRequestParams(request)
|
||||||
streamOpts, err := remotecommand.NewOptions(request.Request)
|
streamOpts, err := remotecommandserver.NewOptions(request.Request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
response.WriteError(http.StatusBadRequest, err)
|
response.WriteError(http.StatusBadRequest, err)
|
||||||
@ -635,7 +636,7 @@ func (s *Server) getAttach(request *restful.Request, response *restful.Response)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
remotecommand.ServeAttach(response.ResponseWriter,
|
remotecommandserver.ServeAttach(response.ResponseWriter,
|
||||||
request.Request,
|
request.Request,
|
||||||
s.host,
|
s.host,
|
||||||
podFullName,
|
podFullName,
|
||||||
@ -643,14 +644,14 @@ func (s *Server) getAttach(request *restful.Request, response *restful.Response)
|
|||||||
params.containerName,
|
params.containerName,
|
||||||
streamOpts,
|
streamOpts,
|
||||||
s.host.StreamingConnectionIdleTimeout(),
|
s.host.StreamingConnectionIdleTimeout(),
|
||||||
remotecommand.DefaultStreamCreationTimeout,
|
remotecommandconsts.DefaultStreamCreationTimeout,
|
||||||
remotecommand.SupportedStreamingProtocols)
|
remotecommandconsts.SupportedStreamingProtocols)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getExec handles requests to run a command inside a container.
|
// getExec handles requests to run a command inside a container.
|
||||||
func (s *Server) getExec(request *restful.Request, response *restful.Response) {
|
func (s *Server) getExec(request *restful.Request, response *restful.Response) {
|
||||||
params := getExecRequestParams(request)
|
params := getExecRequestParams(request)
|
||||||
streamOpts, err := remotecommand.NewOptions(request.Request)
|
streamOpts, err := remotecommandserver.NewOptions(request.Request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
response.WriteError(http.StatusBadRequest, err)
|
response.WriteError(http.StatusBadRequest, err)
|
||||||
@ -673,7 +674,7 @@ func (s *Server) getExec(request *restful.Request, response *restful.Response) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
remotecommand.ServeExec(response.ResponseWriter,
|
remotecommandserver.ServeExec(response.ResponseWriter,
|
||||||
request.Request,
|
request.Request,
|
||||||
s.host,
|
s.host,
|
||||||
podFullName,
|
podFullName,
|
||||||
@ -682,8 +683,8 @@ func (s *Server) getExec(request *restful.Request, response *restful.Response) {
|
|||||||
params.cmd,
|
params.cmd,
|
||||||
streamOpts,
|
streamOpts,
|
||||||
s.host.StreamingConnectionIdleTimeout(),
|
s.host.StreamingConnectionIdleTimeout(),
|
||||||
remotecommand.DefaultStreamCreationTimeout,
|
remotecommandconsts.DefaultStreamCreationTimeout,
|
||||||
remotecommand.SupportedStreamingProtocols)
|
remotecommandconsts.SupportedStreamingProtocols)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRun handles requests to run a command inside a container.
|
// 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,
|
params.podUID,
|
||||||
portForwardOptions,
|
portForwardOptions,
|
||||||
s.host.StreamingConnectionIdleTimeout(),
|
s.host.StreamingConnectionIdleTimeout(),
|
||||||
remotecommand.DefaultStreamCreationTimeout,
|
remotecommandconsts.DefaultStreamCreationTimeout,
|
||||||
portforward.SupportedProtocols)
|
portforward.SupportedProtocols)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,13 +49,13 @@ import (
|
|||||||
utiltesting "k8s.io/client-go/util/testing"
|
utiltesting "k8s.io/client-go/util/testing"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm"
|
"k8s.io/kubernetes/pkg/kubelet/cm"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
kubecontainertesting "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
kubecontainertesting "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/server/portforward"
|
"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/stats"
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"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)
|
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)
|
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)
|
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)
|
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
|
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
|
return fk.redirectURL, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,14 +17,15 @@ go_library(
|
|||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/kubelet/api/v1alpha1/runtime:go_default_library",
|
"//pkg/kubelet/api/v1alpha1/runtime:go_default_library",
|
||||||
"//pkg/kubelet/server/portforward:go_default_library",
|
"//pkg/kubelet/server/portforward:go_default_library",
|
||||||
"//pkg/kubelet/server/remotecommand:go_default_library",
|
"//pkg/kubelet/server/remotecommand:go_default_library",
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//vendor:github.com/emicklei/go-restful",
|
"//vendor:github.com/emicklei/go-restful",
|
||||||
"//vendor:google.golang.org/grpc",
|
"//vendor:google.golang.org/grpc",
|
||||||
"//vendor:google.golang.org/grpc/codes",
|
"//vendor:google.golang.org/grpc/codes",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/util/remotecommand",
|
||||||
"//vendor:k8s.io/client-go/util/clock",
|
"//vendor:k8s.io/client-go/util/clock",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -41,10 +42,9 @@ go_test(
|
|||||||
"//pkg/client/unversioned/remotecommand:go_default_library",
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/kubelet/api/v1alpha1/runtime:go_default_library",
|
"//pkg/kubelet/api/v1alpha1/runtime:go_default_library",
|
||||||
"//pkg/kubelet/server/portforward: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/assert",
|
||||||
"//vendor:github.com/stretchr/testify/require",
|
"//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/pkg/api",
|
||||||
"//vendor:k8s.io/client-go/rest",
|
"//vendor:k8s.io/client-go/rest",
|
||||||
"//vendor:k8s.io/client-go/util/clock",
|
"//vendor:k8s.io/client-go/util/clock",
|
||||||
|
@ -31,10 +31,11 @@ import (
|
|||||||
restful "github.com/emicklei/go-restful"
|
restful "github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"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"
|
runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/server/portforward"
|
"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/util/term"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The library interface to serve the stream requests.
|
// 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.
|
// The interface to execute the commands and provide the streams.
|
||||||
type Runtime interface {
|
type Runtime interface {
|
||||||
Exec(containerID string, cmd []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 term.Size) 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
|
PortForward(podSandboxID string, port int32, stream io.ReadWriteCloser) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,8 +96,8 @@ type Config struct {
|
|||||||
// some fields like Addr must still be provided.
|
// some fields like Addr must still be provided.
|
||||||
var DefaultConfig = Config{
|
var DefaultConfig = Config{
|
||||||
StreamIdleTimeout: 4 * time.Hour,
|
StreamIdleTimeout: 4 * time.Hour,
|
||||||
StreamCreationTimeout: remotecommand.DefaultStreamCreationTimeout,
|
StreamCreationTimeout: remotecommandconsts.DefaultStreamCreationTimeout,
|
||||||
SupportedRemoteCommandProtocols: remotecommand.SupportedStreamingProtocols,
|
SupportedRemoteCommandProtocols: remotecommandconsts.SupportedStreamingProtocols,
|
||||||
SupportedPortForwardProtocols: portforward.SupportedProtocols,
|
SupportedPortForwardProtocols: portforward.SupportedProtocols,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,14 +237,14 @@ func (s *server) serveExec(req *restful.Request, resp *restful.Response) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
streamOpts := &remotecommand.Options{
|
streamOpts := &remotecommandserver.Options{
|
||||||
Stdin: exec.Stdin,
|
Stdin: exec.Stdin,
|
||||||
Stdout: true,
|
Stdout: true,
|
||||||
Stderr: !exec.Tty,
|
Stderr: !exec.Tty,
|
||||||
TTY: exec.Tty,
|
TTY: exec.Tty,
|
||||||
}
|
}
|
||||||
|
|
||||||
remotecommand.ServeExec(
|
remotecommandserver.ServeExec(
|
||||||
resp.ResponseWriter,
|
resp.ResponseWriter,
|
||||||
req.Request,
|
req.Request,
|
||||||
s.runtime,
|
s.runtime,
|
||||||
@ -270,13 +271,13 @@ func (s *server) serveAttach(req *restful.Request, resp *restful.Response) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
streamOpts := &remotecommand.Options{
|
streamOpts := &remotecommandserver.Options{
|
||||||
Stdin: attach.Stdin,
|
Stdin: attach.Stdin,
|
||||||
Stdout: true,
|
Stdout: true,
|
||||||
Stderr: !attach.Tty,
|
Stderr: !attach.Tty,
|
||||||
TTY: attach.Tty,
|
TTY: attach.Tty,
|
||||||
}
|
}
|
||||||
remotecommand.ServeAttach(
|
remotecommandserver.ServeAttach(
|
||||||
resp.ResponseWriter,
|
resp.ResponseWriter,
|
||||||
req.Request,
|
req.Request,
|
||||||
s.runtime,
|
s.runtime,
|
||||||
@ -326,15 +327,15 @@ type criAdapter struct {
|
|||||||
Runtime
|
Runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ remotecommand.Executor = &criAdapter{}
|
var _ remotecommandserver.Executor = &criAdapter{}
|
||||||
var _ remotecommand.Attacher = &criAdapter{}
|
var _ remotecommandserver.Attacher = &criAdapter{}
|
||||||
var _ portforward.PortForwarder = &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)
|
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)
|
return a.Attach(container, in, out, err, tty, resize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,13 +30,12 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
"k8s.io/client-go/pkg/api"
|
"k8s.io/client-go/pkg/api"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
||||||
kubeletportforward "k8s.io/kubernetes/pkg/kubelet/server/portforward"
|
kubeletportforward "k8s.io/kubernetes/pkg/kubelet/server/portforward"
|
||||||
kubeletremotecommand "k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
|
|
||||||
"k8s.io/kubernetes/pkg/util/term"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -302,12 +301,11 @@ func runRemoteCommandTest(t *testing.T, commandType string) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
opts := remotecommand.StreamOptions{
|
opts := remotecommand.StreamOptions{
|
||||||
SupportedProtocols: kubeletremotecommand.SupportedStreamingProtocols,
|
SupportedProtocols: remotecommandconsts.SupportedStreamingProtocols,
|
||||||
Stdin: stdinR,
|
Stdin: stdinR,
|
||||||
Stdout: stdoutW,
|
Stdout: stdoutW,
|
||||||
Stderr: stderrW,
|
Stderr: stderrW,
|
||||||
Tty: false,
|
Tty: false,
|
||||||
TerminalSizeQueue: nil,
|
|
||||||
}
|
}
|
||||||
require.NoError(t, exec.Stream(opts))
|
require.NoError(t, exec.Stream(opts))
|
||||||
}()
|
}()
|
||||||
@ -367,13 +365,13 @@ type fakeRuntime struct {
|
|||||||
t *testing.T
|
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)
|
assert.Equal(f.t, testContainerID, containerID)
|
||||||
doServerStreams(f.t, "exec", stdin, stdout, stderr)
|
doServerStreams(f.t, "exec", stdin, stdout, stderr)
|
||||||
return nil
|
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)
|
assert.Equal(f.t, testContainerID, containerID)
|
||||||
doServerStreams(f.t, "attach", stdin, stdout, stderr)
|
doServerStreams(f.t, "attach", stdin, stdout, stderr)
|
||||||
return nil
|
return nil
|
||||||
|
@ -19,6 +19,7 @@ go_library(
|
|||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//pkg/client/unversioned/remotecommand:go_default_library",
|
||||||
"//pkg/util/interrupt:go_default_library",
|
"//pkg/util/interrupt:go_default_library",
|
||||||
"//vendor:github.com/docker/docker/pkg/term",
|
"//vendor:github.com/docker/docker/pkg/term",
|
||||||
"//vendor:github.com/mitchellh/go-wordwrap",
|
"//vendor:github.com/mitchellh/go-wordwrap",
|
||||||
|
@ -21,17 +21,12 @@ import (
|
|||||||
|
|
||||||
"github.com/docker/docker/pkg/term"
|
"github.com/docker/docker/pkg/term"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"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,
|
// GetSize returns the current size of the user's terminal. If it isn't a terminal,
|
||||||
// nil is returned.
|
// nil is returned.
|
||||||
func (t TTY) GetSize() *Size {
|
func (t TTY) GetSize() *remotecommand.TerminalSize {
|
||||||
outFd, isTerminal := term.GetFdInfo(t.Out)
|
outFd, isTerminal := term.GetFdInfo(t.Out)
|
||||||
if !isTerminal {
|
if !isTerminal {
|
||||||
return nil
|
return nil
|
||||||
@ -40,19 +35,19 @@ func (t TTY) GetSize() *Size {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSize returns the current size of the terminal associated with fd.
|
// 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)
|
winsize, err := term.GetWinsize(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HandleError(fmt.Errorf("unable to get terminal size: %v", err))
|
runtime.HandleError(fmt.Errorf("unable to get terminal size: %v", err))
|
||||||
return nil
|
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
|
// MonitorSize monitors the terminal's size. It returns a TerminalSizeQueue primed with
|
||||||
// initialSizes, or nil if there's no TTY present.
|
// 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)
|
outFd, isTerminal := term.GetFdInfo(t.Out)
|
||||||
if !isTerminal {
|
if !isTerminal {
|
||||||
return nil
|
return nil
|
||||||
@ -62,7 +57,7 @@ func (t *TTY) MonitorSize(initialSizes ...*Size) TerminalSizeQueue {
|
|||||||
t: *t,
|
t: *t,
|
||||||
// make it buffered so we can send the initial terminal sizes without blocking, prior to starting
|
// make it buffered so we can send the initial terminal sizes without blocking, prior to starting
|
||||||
// the streaming below
|
// the streaming below
|
||||||
resizeChan: make(chan Size, len(initialSizes)),
|
resizeChan: make(chan remotecommand.TerminalSize, len(initialSizes)),
|
||||||
stopResizing: make(chan struct{}),
|
stopResizing: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,27 +66,20 @@ func (t *TTY) MonitorSize(initialSizes ...*Size) TerminalSizeQueue {
|
|||||||
return t.sizeQueue
|
return t.sizeQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
// TerminalSizeQueue is capable of returning terminal resize events as they occur.
|
// sizeQueue implements remotecommand.TerminalSizeQueue
|
||||||
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
|
|
||||||
type sizeQueue struct {
|
type sizeQueue struct {
|
||||||
t TTY
|
t TTY
|
||||||
// resizeChan receives a Size each time the user's terminal is resized.
|
// resizeChan receives a Size each time the user's terminal is resized.
|
||||||
resizeChan chan Size
|
resizeChan chan remotecommand.TerminalSize
|
||||||
stopResizing chan struct{}
|
stopResizing chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure sizeQueue implements the TerminalSizeQueue interface
|
// make sure sizeQueue implements the resize.TerminalSizeQueue interface
|
||||||
var _ TerminalSizeQueue = &sizeQueue{}
|
var _ remotecommand.TerminalSizeQueue = &sizeQueue{}
|
||||||
|
|
||||||
// monitorSize primes resizeChan with initialSizes and then monitors for resize events. With each
|
// monitorSize primes resizeChan with initialSizes and then monitors for resize events. With each
|
||||||
// new event, it sends the current terminal size to resizeChan.
|
// 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
|
// send the initial sizes
|
||||||
for i := range initialSizes {
|
for i := range initialSizes {
|
||||||
if initialSizes[i] != nil {
|
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)
|
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
|
// Next returns the new terminal size after the terminal has been resized. It returns nil when
|
||||||
// monitoring has been stopped.
|
// monitoring has been stopped.
|
||||||
func (s *sizeQueue) Next() *Size {
|
func (s *sizeQueue) Next() *remotecommand.TerminalSize {
|
||||||
size, ok := <-s.resizeChan
|
size, ok := <-s.resizeChan
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
|
@ -24,12 +24,13 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"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
|
// 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
|
// 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.
|
// 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() {
|
go func() {
|
||||||
defer runtime.HandleCrash()
|
defer runtime.HandleCrash()
|
||||||
|
|
||||||
|
@ -20,9 +20,10 @@ package term
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/docker/pkg/term"
|
"github.com/docker/docker/pkg/term"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetSize sets the terminal size associated with fd.
|
// 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})
|
return term.SetWinsize(fd, &term.Winsize{Height: size.Height, Width: size.Width})
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,11 @@ limitations under the License.
|
|||||||
|
|
||||||
package remotecommand
|
package remotecommand
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultStreamCreationTimeout = 30 * time.Second
|
DefaultStreamCreationTimeout = 30 * time.Second
|
||||||
@ -41,6 +45,9 @@ const (
|
|||||||
// attachment/execution. It is the 4th version of the subprotocol and
|
// attachment/execution. It is the 4th version of the subprotocol and
|
||||||
// adds support for exit codes.
|
// adds support for exit codes.
|
||||||
StreamProtocolV4Name = "v4.channel.k8s.io"
|
StreamProtocolV4Name = "v4.channel.k8s.io"
|
||||||
|
|
||||||
|
NonZeroExitCodeReason = metav1.StatusReason("NonZeroExitCode")
|
||||||
|
ExitCodeCauseType = metav1.CauseType("ExitCode")
|
||||||
)
|
)
|
||||||
|
|
||||||
var SupportedStreamingProtocols = []string{StreamProtocolV4Name, StreamProtocolV3Name, StreamProtocolV2Name, StreamProtocolV1Name}
|
var SupportedStreamingProtocols = []string{StreamProtocolV4Name, StreamProtocolV3Name, StreamProtocolV2Name, StreamProtocolV1Name}
|
@ -69,7 +69,6 @@ go_library(
|
|||||||
"//pkg/kubelet/api/v1alpha1/stats:go_default_library",
|
"//pkg/kubelet/api/v1alpha1/stats:go_default_library",
|
||||||
"//pkg/kubelet/events:go_default_library",
|
"//pkg/kubelet/events:go_default_library",
|
||||||
"//pkg/kubelet/metrics: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/server/stats:go_default_library",
|
||||||
"//pkg/kubelet/sysctl:go_default_library",
|
"//pkg/kubelet/sysctl:go_default_library",
|
||||||
"//pkg/kubelet/util/format:go_default_library",
|
"//pkg/kubelet/util/format:go_default_library",
|
||||||
@ -118,6 +117,7 @@ go_library(
|
|||||||
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
|
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/net",
|
"//vendor:k8s.io/apimachinery/pkg/util/net",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/rand",
|
"//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/runtime",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/uuid",
|
"//vendor:k8s.io/apimachinery/pkg/util/uuid",
|
||||||
|
@ -23,11 +23,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
remocommandconsts "k8s.io/apimachinery/pkg/util/remotecommand"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
|
|
||||||
|
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
@ -140,7 +140,7 @@ func execute(method string, url *url.URL, config *restclient.Config, stdin io.Re
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return exec.Stream(remotecommand.StreamOptions{
|
return exec.Stream(remotecommand.StreamOptions{
|
||||||
SupportedProtocols: remotecommandserver.SupportedStreamingProtocols,
|
SupportedProtocols: remocommandconsts.SupportedStreamingProtocols,
|
||||||
Stdin: stdin,
|
Stdin: stdin,
|
||||||
Stdout: stdout,
|
Stdout: stdout,
|
||||||
Stderr: stderr,
|
Stderr: stderr,
|
||||||
|
7
vendor/BUILD
vendored
7
vendor/BUILD
vendored
@ -16775,3 +16775,10 @@ go_library(
|
|||||||
"//vendor:k8s.io/client-go/pkg/api",
|
"//vendor:k8s.io/client-go/pkg/api",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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"],
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user