Skip to content

Commit 667665c

Browse files
committed
make runAttach public and allow passing context
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
1 parent 9cb175f commit 667665c

2 files changed

Lines changed: 35 additions & 25 deletions

File tree

cli/command/container/attach.go

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

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

25-
container string
26+
Container string
2627
}
2728

2829
func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, args string) (*types.ContainerJSON, error) {
@@ -45,15 +46,15 @@ func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, ar
4546

4647
// NewAttachCommand creates a new cobra.Command for `docker attach`
4748
func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
48-
var opts attachOptions
49+
var opts AttachOptions
4950

5051
cmd := &cobra.Command{
5152
Use: "attach [OPTIONS] CONTAINER",
5253
Short: "Attach local standard input, output, and error streams to a running container",
5354
Args: cli.ExactArgs(1),
5455
RunE: func(cmd *cobra.Command, args []string) error {
55-
opts.container = args[0]
56-
return runAttach(dockerCli, &opts)
56+
opts.Container = args[0]
57+
return RunAttach(dockerCli, &opts)
5758
},
5859
Annotations: map[string]string{
5960
"aliases": "docker container attach, docker attach",
@@ -64,36 +65,41 @@ func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
6465
}
6566

6667
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")
68+
flags.BoolVar(&opts.NoStdin, "no-stdin", false, "Do not attach STDIN")
69+
flags.BoolVar(&opts.Proxy, "sig-proxy", true, "Proxy all received signals to the process")
70+
flags.StringVar(&opts.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
7071
return cmd
7172
}
7273

73-
func runAttach(dockerCli command.Cli, opts *attachOptions) error {
74-
ctx := context.Background()
74+
// RunAttach executes an `attach` command
75+
func RunAttach(dockerCli command.Cli, opts *AttachOptions) error {
76+
return RunAttachWithContext(context.Background(), dockerCli, opts)
77+
}
78+
79+
// RunAttachWithContext executes an `attach` command
80+
func RunAttachWithContext(ctx context.Context, dockerCli command.Cli, opts *AttachOptions) error {
7581
apiClient := dockerCli.Client()
7682

7783
// request channel to wait for client
78-
resultC, errC := apiClient.ContainerWait(ctx, opts.container, "")
84+
resultC, errC := apiClient.ContainerWait(ctx, opts.Container, "")
7985

80-
c, err := inspectContainerAndCheckState(ctx, apiClient, opts.container)
86+
c, err := inspectContainerAndCheckState(ctx, apiClient, opts.Container)
8187
if err != nil {
8288
return err
8389
}
8490

85-
if err := dockerCli.In().CheckTty(!opts.noStdin, c.Config.Tty); err != nil {
91+
if err := dockerCli.In().CheckTty(!opts.NoStdin, c.Config.Tty); err != nil {
8692
return err
8793
}
8894

8995
detachKeys := dockerCli.ConfigFile().DetachKeys
90-
if opts.detachKeys != "" {
91-
detachKeys = opts.detachKeys
96+
if opts.DetachKeys != "" {
97+
detachKeys = opts.DetachKeys
9298
}
9399

94100
options := container.AttachOptions{
95101
Stream: true,
96-
Stdin: !opts.noStdin && c.Config.OpenStdin,
102+
Stdin: !opts.NoStdin && c.Config.OpenStdin,
97103
Stdout: true,
98104
Stderr: true,
99105
DetachKeys: detachKeys,
@@ -104,13 +110,13 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
104110
in = dockerCli.In()
105111
}
106112

107-
if opts.proxy && !c.Config.Tty {
113+
if opts.Proxy && !c.Config.Tty {
108114
sigc := notifyAllSignals()
109-
go ForwardAllSignals(ctx, dockerCli, opts.container, sigc)
115+
go ForwardAllSignals(ctx, dockerCli, opts.Container, sigc)
110116
defer signal.StopCatch(sigc)
111117
}
112118

113-
resp, errAttach := apiClient.ContainerAttach(ctx, opts.container, options)
119+
resp, errAttach := apiClient.ContainerAttach(ctx, opts.Container, options)
114120
if errAttach != nil {
115121
return errAttach
116122
}
@@ -124,13 +130,13 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
124130
// the container and not exit.
125131
//
126132
// Recheck the container's state to avoid attach block.
127-
_, err = inspectContainerAndCheckState(ctx, apiClient, opts.container)
133+
_, err = inspectContainerAndCheckState(ctx, apiClient, opts.Container)
128134
if err != nil {
129135
return err
130136
}
131137

132138
if c.Config.Tty && dockerCli.Out().IsTerminal() {
133-
resizeTTY(ctx, dockerCli, opts.container)
139+
resizeTTY(ctx, dockerCli, opts.Container)
134140
}
135141

136142
streamer := hijackedIOStreamer{

cli/command/container/exec.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,16 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
9797

9898
// RunExec executes an `exec` command
9999
func RunExec(dockerCli command.Cli, options ExecOptions) error {
100+
return RunExecWithContext(context.Background(), dockerCli, options)
101+
}
102+
103+
// RunExecWithContext executes an `exec` command
104+
func RunExecWithContext(ctx context.Context, dockerCli command.Cli, options ExecOptions) error {
100105
execConfig, err := parseExec(options, dockerCli.ConfigFile())
101106
if err != nil {
102107
return err
103108
}
104109

105-
ctx := context.Background()
106110
client := dockerCli.Client()
107111

108112
// We need to check the tty _before_ we do the ContainerExecCreate, because

0 commit comments

Comments
 (0)