Skip to content

Commit ad861cd

Browse files
authored
Merge pull request #4637 from ndeloof/RunExecWithContextb
make runAttach public and allow passing context
2 parents 1598586 + a2ec50a commit ad861cd

3 files changed

Lines changed: 33 additions & 35 deletions

File tree

cli/command/container/attach.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ import (
1717
"github.com/spf13/cobra"
1818
)
1919

20-
type attachOptions struct {
21-
noStdin bool
22-
proxy bool
23-
detachKeys string
24-
25-
container string
20+
// AttachOptions group options for `attach` command
21+
type AttachOptions struct {
22+
NoStdin bool
23+
Proxy bool
24+
DetachKeys string
2625
}
2726

2827
func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, args string) (*types.ContainerJSON, error) {
@@ -45,15 +44,16 @@ func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, ar
4544

4645
// NewAttachCommand creates a new cobra.Command for `docker attach`
4746
func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
48-
var opts attachOptions
47+
var opts AttachOptions
48+
var container string
4949

5050
cmd := &cobra.Command{
5151
Use: "attach [OPTIONS] CONTAINER",
5252
Short: "Attach local standard input, output, and error streams to a running container",
5353
Args: cli.ExactArgs(1),
5454
RunE: func(cmd *cobra.Command, args []string) error {
55-
opts.container = args[0]
56-
return runAttach(dockerCli, &opts)
55+
container = args[0]
56+
return RunAttach(context.Background(), dockerCli, container, &opts)
5757
},
5858
Annotations: map[string]string{
5959
"aliases": "docker container attach, docker attach",
@@ -64,36 +64,36 @@ func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
6464
}
6565

6666
flags := cmd.Flags()
67-
flags.BoolVar(&opts.noStdin, "no-stdin", false, "Do not attach STDIN")
68-
flags.BoolVar(&opts.proxy, "sig-proxy", true, "Proxy all received signals to the process")
69-
flags.StringVar(&opts.detachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
67+
flags.BoolVar(&opts.NoStdin, "no-stdin", false, "Do not attach STDIN")
68+
flags.BoolVar(&opts.Proxy, "sig-proxy", true, "Proxy all received signals to the process")
69+
flags.StringVar(&opts.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
7070
return cmd
7171
}
7272

73-
func runAttach(dockerCli command.Cli, opts *attachOptions) error {
74-
ctx := context.Background()
73+
// RunAttach executes an `attach` command
74+
func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts *AttachOptions) error {
7575
apiClient := dockerCli.Client()
7676

7777
// request channel to wait for client
78-
resultC, errC := apiClient.ContainerWait(ctx, opts.container, "")
78+
resultC, errC := apiClient.ContainerWait(ctx, target, "")
7979

80-
c, err := inspectContainerAndCheckState(ctx, apiClient, opts.container)
80+
c, err := inspectContainerAndCheckState(ctx, apiClient, target)
8181
if err != nil {
8282
return err
8383
}
8484

85-
if err := dockerCli.In().CheckTty(!opts.noStdin, c.Config.Tty); err != nil {
85+
if err := dockerCli.In().CheckTty(!opts.NoStdin, c.Config.Tty); err != nil {
8686
return err
8787
}
8888

8989
detachKeys := dockerCli.ConfigFile().DetachKeys
90-
if opts.detachKeys != "" {
91-
detachKeys = opts.detachKeys
90+
if opts.DetachKeys != "" {
91+
detachKeys = opts.DetachKeys
9292
}
9393

9494
options := container.AttachOptions{
9595
Stream: true,
96-
Stdin: !opts.noStdin && c.Config.OpenStdin,
96+
Stdin: !opts.NoStdin && c.Config.OpenStdin,
9797
Stdout: true,
9898
Stderr: true,
9999
DetachKeys: detachKeys,
@@ -104,13 +104,13 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
104104
in = dockerCli.In()
105105
}
106106

107-
if opts.proxy && !c.Config.Tty {
107+
if opts.Proxy && !c.Config.Tty {
108108
sigc := notifyAllSignals()
109-
go ForwardAllSignals(ctx, dockerCli, opts.container, sigc)
109+
go ForwardAllSignals(ctx, dockerCli, target, sigc)
110110
defer signal.StopCatch(sigc)
111111
}
112112

113-
resp, errAttach := apiClient.ContainerAttach(ctx, opts.container, options)
113+
resp, errAttach := apiClient.ContainerAttach(ctx, target, options)
114114
if errAttach != nil {
115115
return errAttach
116116
}
@@ -124,13 +124,13 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
124124
// the container and not exit.
125125
//
126126
// Recheck the container's state to avoid attach block.
127-
_, err = inspectContainerAndCheckState(ctx, apiClient, opts.container)
127+
_, err = inspectContainerAndCheckState(ctx, apiClient, target)
128128
if err != nil {
129129
return err
130130
}
131131

132132
if c.Config.Tty && dockerCli.Out().IsTerminal() {
133-
resizeTTY(ctx, dockerCli, opts.container)
133+
resizeTTY(ctx, dockerCli, target)
134134
}
135135

136136
streamer := hijackedIOStreamer{

cli/command/container/exec.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ type ExecOptions struct {
2828
Privileged bool
2929
Env opts.ListOpts
3030
Workdir string
31-
Container string
3231
Command []string
3332
EnvFile opts.ListOpts
3433
}
@@ -44,15 +43,16 @@ func NewExecOptions() ExecOptions {
4443
// NewExecCommand creates a new cobra.Command for `docker exec`
4544
func NewExecCommand(dockerCli command.Cli) *cobra.Command {
4645
options := NewExecOptions()
46+
var container string
4747

4848
cmd := &cobra.Command{
4949
Use: "exec [OPTIONS] CONTAINER COMMAND [ARG...]",
5050
Short: "Execute a command in a running container",
5151
Args: cli.RequiresMinArgs(2),
5252
RunE: func(cmd *cobra.Command, args []string) error {
53-
options.Container = args[0]
53+
container = args[0]
5454
options.Command = args[1:]
55-
return RunExec(dockerCli, options)
55+
return RunExec(context.Background(), dockerCli, container, options)
5656
},
5757
ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(container types.Container) bool {
5858
return container.State != "paused"
@@ -96,20 +96,19 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
9696
}
9797

9898
// RunExec executes an `exec` command
99-
func RunExec(dockerCli command.Cli, options ExecOptions) error {
99+
func RunExec(ctx context.Context, dockerCli command.Cli, container string, options ExecOptions) error {
100100
execConfig, err := parseExec(options, dockerCli.ConfigFile())
101101
if err != nil {
102102
return err
103103
}
104104

105-
ctx := context.Background()
106105
client := dockerCli.Client()
107106

108107
// We need to check the tty _before_ we do the ContainerExecCreate, because
109108
// otherwise if we error out we will leak execIDs on the server (and
110109
// there's no easy way to clean those up). But also in order to make "not
111110
// exist" errors take precedence we do a dummy inspect first.
112-
if _, err := client.ContainerInspect(ctx, options.Container); err != nil {
111+
if _, err := client.ContainerInspect(ctx, container); err != nil {
113112
return err
114113
}
115114
if !execConfig.Detach {
@@ -120,7 +119,7 @@ func RunExec(dockerCli command.Cli, options ExecOptions) error {
120119

121120
fillConsoleSize(execConfig, dockerCli)
122121

123-
response, err := client.ContainerExecCreate(ctx, options.Container, *execConfig)
122+
response, err := client.ContainerExecCreate(ctx, container, *execConfig)
124123
if err != nil {
125124
return err
126125
}

cli/command/container/exec_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,7 @@ func TestRunExec(t *testing.T) {
169169
{
170170
doc: "successful detach",
171171
options: withDefaultOpts(ExecOptions{
172-
Container: "thecontainer",
173-
Detach: true,
172+
Detach: true,
174173
}),
175174
client: fakeClient{execCreateFunc: execCreateWithID},
176175
},
@@ -195,7 +194,7 @@ func TestRunExec(t *testing.T) {
195194
t.Run(testcase.doc, func(t *testing.T) {
196195
cli := test.NewFakeCli(&testcase.client)
197196

198-
err := RunExec(cli, testcase.options)
197+
err := RunExec(context.Background(), cli, "thecontainer", testcase.options)
199198
if testcase.expectedError != "" {
200199
assert.ErrorContains(t, err, testcase.expectedError)
201200
} else {

0 commit comments

Comments
 (0)