mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-30 06:09:11 +00:00
Refactor CreateExec, StartExec and InspectExec.
This commit is contained in:
parent
934d7ebb33
commit
de5f407058
@ -71,9 +71,9 @@ type DockerInterface interface {
|
|||||||
Logs(opts docker.LogsOptions) error
|
Logs(opts docker.LogsOptions) error
|
||||||
Version() (*docker.Env, error)
|
Version() (*docker.Env, error)
|
||||||
Info() (*docker.Env, error)
|
Info() (*docker.Env, error)
|
||||||
CreateExec(docker.CreateExecOptions) (*docker.Exec, error)
|
CreateExec(string, dockertypes.ExecConfig) (*dockertypes.ContainerExecCreateResponse, error)
|
||||||
StartExec(string, docker.StartExecOptions) error
|
StartExec(string, dockertypes.ExecStartCheck, StreamOptions) error
|
||||||
InspectExec(id string) (*docker.ExecInspect, error)
|
InspectExec(id string) (*dockertypes.ContainerExecInspect, error)
|
||||||
AttachToContainer(opts docker.AttachToContainerOptions) error
|
AttachToContainer(opts docker.AttachToContainerOptions) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
dockertypes "github.com/docker/engine-api/types"
|
dockertypes "github.com/docker/engine-api/types"
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
)
|
)
|
||||||
@ -100,27 +99,25 @@ func (*NsenterExecHandler) ExecInContainer(client DockerInterface, container *do
|
|||||||
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) error {
|
func (*NativeExecHandler) ExecInContainer(client DockerInterface, container *dockertypes.ContainerJSON, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
|
||||||
createOpts := docker.CreateExecOptions{
|
createOpts := dockertypes.ExecConfig{
|
||||||
Container: container.ID,
|
|
||||||
Cmd: cmd,
|
Cmd: cmd,
|
||||||
AttachStdin: stdin != nil,
|
AttachStdin: stdin != nil,
|
||||||
AttachStdout: stdout != nil,
|
AttachStdout: stdout != nil,
|
||||||
AttachStderr: stderr != nil,
|
AttachStderr: stderr != nil,
|
||||||
Tty: tty,
|
Tty: tty,
|
||||||
}
|
}
|
||||||
execObj, err := client.CreateExec(createOpts)
|
execObj, err := client.CreateExec(container.ID, createOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to exec in container - Exec setup failed - %v", err)
|
return fmt.Errorf("failed to exec in container - Exec setup failed - %v", err)
|
||||||
}
|
}
|
||||||
startOpts := docker.StartExecOptions{
|
startOpts := dockertypes.ExecStartCheck{Detach: false, Tty: tty}
|
||||||
Detach: false,
|
streamOpts := StreamOptions{
|
||||||
InputStream: stdin,
|
InputStream: stdin,
|
||||||
OutputStream: stdout,
|
OutputStream: stdout,
|
||||||
ErrorStream: stderr,
|
ErrorStream: stderr,
|
||||||
Tty: tty,
|
|
||||||
RawTerminal: tty,
|
RawTerminal: tty,
|
||||||
}
|
}
|
||||||
err = client.StartExec(execObj.ID, startOpts)
|
err = client.StartExec(execObj.ID, startOpts, streamOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ type FakeDockerClient struct {
|
|||||||
RemovedImages sets.String
|
RemovedImages sets.String
|
||||||
VersionInfo docker.Env
|
VersionInfo docker.Env
|
||||||
Information docker.Env
|
Information docker.Env
|
||||||
ExecInspect *docker.ExecInspect
|
ExecInspect *dockertypes.ContainerExecInspect
|
||||||
execCmd []string
|
execCmd []string
|
||||||
EnableSleep bool
|
EnableSleep bool
|
||||||
}
|
}
|
||||||
@ -447,15 +447,15 @@ func (f *FakeDockerClient) Info() (*docker.Env, error) {
|
|||||||
return &f.Information, nil
|
return &f.Information, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeDockerClient) CreateExec(opts docker.CreateExecOptions) (*docker.Exec, error) {
|
func (f *FakeDockerClient) CreateExec(id string, opts dockertypes.ExecConfig) (*dockertypes.ContainerExecCreateResponse, error) {
|
||||||
f.Lock()
|
f.Lock()
|
||||||
defer f.Unlock()
|
defer f.Unlock()
|
||||||
f.execCmd = opts.Cmd
|
f.execCmd = opts.Cmd
|
||||||
f.called = append(f.called, "create_exec")
|
f.called = append(f.called, "create_exec")
|
||||||
return &docker.Exec{ID: "12345678"}, nil
|
return &dockertypes.ContainerExecCreateResponse{ID: "12345678"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeDockerClient) StartExec(_ string, _ docker.StartExecOptions) error {
|
func (f *FakeDockerClient) StartExec(startExec string, opts dockertypes.ExecStartCheck, sopts StreamOptions) error {
|
||||||
f.Lock()
|
f.Lock()
|
||||||
defer f.Unlock()
|
defer f.Unlock()
|
||||||
f.called = append(f.called, "start_exec")
|
f.called = append(f.called, "start_exec")
|
||||||
@ -469,7 +469,7 @@ func (f *FakeDockerClient) AttachToContainer(opts docker.AttachToContainerOption
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeDockerClient) InspectExec(id string) (*docker.ExecInspect, error) {
|
func (f *FakeDockerClient) InspectExec(id string) (*dockertypes.ContainerExecInspect, error) {
|
||||||
return f.ExecInspect, f.popError("inspect_exec")
|
return f.ExecInspect, f.popError("inspect_exec")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,25 +166,25 @@ func (in instrumentedDockerInterface) Info() (*docker.Env, error) {
|
|||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (in instrumentedDockerInterface) CreateExec(opts docker.CreateExecOptions) (*docker.Exec, error) {
|
func (in instrumentedDockerInterface) CreateExec(id string, opts dockertypes.ExecConfig) (*dockertypes.ContainerExecCreateResponse, error) {
|
||||||
const operation = "create_exec"
|
const operation = "create_exec"
|
||||||
defer recordOperation(operation, time.Now())
|
defer recordOperation(operation, time.Now())
|
||||||
|
|
||||||
out, err := in.client.CreateExec(opts)
|
out, err := in.client.CreateExec(id, opts)
|
||||||
recordError(operation, err)
|
recordError(operation, err)
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (in instrumentedDockerInterface) StartExec(startExec string, opts docker.StartExecOptions) error {
|
func (in instrumentedDockerInterface) StartExec(startExec string, opts dockertypes.ExecStartCheck, sopts StreamOptions) error {
|
||||||
const operation = "start_exec"
|
const operation = "start_exec"
|
||||||
defer recordOperation(operation, time.Now())
|
defer recordOperation(operation, time.Now())
|
||||||
|
|
||||||
err := in.client.StartExec(startExec, opts)
|
err := in.client.StartExec(startExec, opts, sopts)
|
||||||
recordError(operation, err)
|
recordError(operation, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (in instrumentedDockerInterface) InspectExec(id string) (*docker.ExecInspect, error) {
|
func (in instrumentedDockerInterface) InspectExec(id string) (*dockertypes.ContainerExecInspect, error) {
|
||||||
const operation = "inspect_exec"
|
const operation = "inspect_exec"
|
||||||
defer recordOperation(operation, time.Now())
|
defer recordOperation(operation, time.Now())
|
||||||
|
|
||||||
|
@ -243,28 +243,19 @@ func (d *kubeDockerClient) Info() (*docker.Env, error) {
|
|||||||
return convertEnv(resp)
|
return convertEnv(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) CreateExec(opts docker.CreateExecOptions) (*docker.Exec, error) {
|
// TODO(random-liu): Add unit test for exec and attach functions, just like what go-dockerclient did.
|
||||||
cfg := dockertypes.ExecConfig{}
|
func (d *kubeDockerClient) CreateExec(id string, opts dockertypes.ExecConfig) (*dockertypes.ContainerExecCreateResponse, error) {
|
||||||
if err := convertType(&opts, &cfg); err != nil {
|
opts.Container = id
|
||||||
return nil, err
|
resp, err := d.client.ContainerExecCreate(getDefaultContext(), opts)
|
||||||
}
|
|
||||||
resp, err := d.client.ContainerExecCreate(getDefaultContext(), cfg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
exec := &docker.Exec{}
|
return &resp, nil
|
||||||
if err := convertType(&resp, exec); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return exec, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) StartExec(startExec string, opts docker.StartExecOptions) error {
|
func (d *kubeDockerClient) StartExec(startExec string, opts dockertypes.ExecStartCheck, sopts StreamOptions) error {
|
||||||
if opts.Detach {
|
if opts.Detach {
|
||||||
return d.client.ContainerExecStart(getDefaultContext(), startExec, dockertypes.ExecStartCheck{
|
return d.client.ContainerExecStart(getDefaultContext(), startExec, opts)
|
||||||
Detach: opts.Detach,
|
|
||||||
Tty: opts.Tty,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
resp, err := d.client.ContainerExecAttach(getDefaultContext(), startExec, dockertypes.ExecConfig{
|
resp, err := d.client.ContainerExecAttach(getDefaultContext(), startExec, dockertypes.ExecConfig{
|
||||||
Detach: opts.Detach,
|
Detach: opts.Detach,
|
||||||
@ -274,23 +265,15 @@ func (d *kubeDockerClient) StartExec(startExec string, opts docker.StartExecOpti
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Close()
|
defer resp.Close()
|
||||||
if opts.Success != nil {
|
return d.holdHijackedConnection(sopts.RawTerminal || opts.Tty, sopts.InputStream, sopts.OutputStream, sopts.ErrorStream, resp)
|
||||||
opts.Success <- struct{}{}
|
|
||||||
<-opts.Success
|
|
||||||
}
|
|
||||||
return d.holdHijackedConnection(opts.RawTerminal || opts.Tty, opts.InputStream, opts.OutputStream, opts.ErrorStream, resp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) InspectExec(id string) (*docker.ExecInspect, error) {
|
func (d *kubeDockerClient) InspectExec(id string) (*dockertypes.ContainerExecInspect, error) {
|
||||||
resp, err := d.client.ContainerExecInspect(getDefaultContext(), id)
|
resp, err := d.client.ContainerExecInspect(getDefaultContext(), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
exec := &docker.ExecInspect{}
|
return &resp, nil
|
||||||
if err := convertType(&resp, exec); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return exec, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) AttachToContainer(opts docker.AttachToContainerOptions) error {
|
func (d *kubeDockerClient) AttachToContainer(opts docker.AttachToContainerOptions) error {
|
||||||
@ -367,6 +350,14 @@ func parseDockerTimestamp(s string) (time.Time, error) {
|
|||||||
return time.Parse(time.RFC3339Nano, s)
|
return time.Parse(time.RFC3339Nano, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StreamOptions are the options used to configure the stream redirection
|
||||||
|
type StreamOptions struct {
|
||||||
|
RawTerminal bool
|
||||||
|
InputStream io.Reader
|
||||||
|
OutputStream io.Writer
|
||||||
|
ErrorStream io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
// containerNotFoundError is the error returned by InspectContainer when container not found. We
|
// containerNotFoundError is the error returned by InspectContainer when container not found. We
|
||||||
// add this error type for testability. We don't use the original error returned by engine-api
|
// add this error type for testability. We don't use the original error returned by engine-api
|
||||||
// because dockertypes.containerNotFoundError is private, we can't create and inject it in our test.
|
// because dockertypes.containerNotFoundError is private, we can't create and inject it in our test.
|
||||||
|
@ -1014,27 +1014,25 @@ func (dm *DockerManager) defaultSecurityOpt() ([]string, error) {
|
|||||||
// RunInContainer run the command inside the container identified by containerID
|
// RunInContainer run the command inside the container identified by containerID
|
||||||
func (dm *DockerManager) RunInContainer(containerID kubecontainer.ContainerID, cmd []string) ([]byte, error) {
|
func (dm *DockerManager) RunInContainer(containerID kubecontainer.ContainerID, cmd []string) ([]byte, error) {
|
||||||
glog.V(2).Infof("Using docker native exec to run cmd %+v inside container %s", cmd, containerID)
|
glog.V(2).Infof("Using docker native exec to run cmd %+v inside container %s", cmd, containerID)
|
||||||
createOpts := docker.CreateExecOptions{
|
createOpts := dockertypes.ExecConfig{
|
||||||
Container: containerID.ID,
|
|
||||||
Cmd: cmd,
|
Cmd: cmd,
|
||||||
AttachStdin: false,
|
AttachStdin: false,
|
||||||
AttachStdout: true,
|
AttachStdout: true,
|
||||||
AttachStderr: true,
|
AttachStderr: true,
|
||||||
Tty: false,
|
Tty: false,
|
||||||
}
|
}
|
||||||
execObj, err := dm.client.CreateExec(createOpts)
|
execObj, err := dm.client.CreateExec(containerID.ID, createOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to run in container - Exec setup failed - %v", err)
|
return nil, fmt.Errorf("failed to run in container - Exec setup failed - %v", err)
|
||||||
}
|
}
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
startOpts := docker.StartExecOptions{
|
startOpts := dockertypes.ExecStartCheck{Detach: false, Tty: false}
|
||||||
Detach: false,
|
streamOpts := StreamOptions{
|
||||||
Tty: false,
|
|
||||||
OutputStream: &buf,
|
OutputStream: &buf,
|
||||||
ErrorStream: &buf,
|
ErrorStream: &buf,
|
||||||
RawTerminal: false,
|
RawTerminal: false,
|
||||||
}
|
}
|
||||||
err = dm.client.StartExec(execObj.ID, startOpts)
|
err = dm.client.StartExec(execObj.ID, startOpts, streamOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(2).Infof("StartExec With error: %v", err)
|
glog.V(2).Infof("StartExec With error: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1061,7 +1059,7 @@ func (dm *DockerManager) RunInContainer(containerID kubecontainer.ContainerID, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
type dockerExitError struct {
|
type dockerExitError struct {
|
||||||
Inspect *docker.ExecInspect
|
Inspect *dockertypes.ContainerExecInspect
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dockerExitError) String() string {
|
func (d *dockerExitError) String() string {
|
||||||
|
@ -438,7 +438,7 @@ func TestKillContainerInPod(t *testing.T) {
|
|||||||
|
|
||||||
func TestKillContainerInPodWithPreStop(t *testing.T) {
|
func TestKillContainerInPodWithPreStop(t *testing.T) {
|
||||||
manager, fakeDocker := newTestDockerManager()
|
manager, fakeDocker := newTestDockerManager()
|
||||||
fakeDocker.ExecInspect = &docker.ExecInspect{
|
fakeDocker.ExecInspect = &dockertypes.ContainerExecInspect{
|
||||||
Running: false,
|
Running: false,
|
||||||
ExitCode: 0,
|
ExitCode: 0,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user