@@ -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
2829func 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`
4748func 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 ( context . Background (), dockerCli , & opts )
5758 },
5859 Annotations : map [string ]string {
5960 "aliases" : "docker container attach, docker attach" ,
@@ -64,36 +65,36 @@ 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 ( ctx context.Context , dockerCli command. Cli , opts * AttachOptions ) error {
7576 apiClient := dockerCli .Client ()
7677
7778 // request channel to wait for client
78- resultC , errC := apiClient .ContainerWait (ctx , opts .container , "" )
79+ resultC , errC := apiClient .ContainerWait (ctx , opts .Container , "" )
7980
80- c , err := inspectContainerAndCheckState (ctx , apiClient , opts .container )
81+ c , err := inspectContainerAndCheckState (ctx , apiClient , opts .Container )
8182 if err != nil {
8283 return err
8384 }
8485
85- if err := dockerCli .In ().CheckTty (! opts .noStdin , c .Config .Tty ); err != nil {
86+ if err := dockerCli .In ().CheckTty (! opts .NoStdin , c .Config .Tty ); err != nil {
8687 return err
8788 }
8889
8990 detachKeys := dockerCli .ConfigFile ().DetachKeys
90- if opts .detachKeys != "" {
91- detachKeys = opts .detachKeys
91+ if opts .DetachKeys != "" {
92+ detachKeys = opts .DetachKeys
9293 }
9394
9495 options := container.AttachOptions {
9596 Stream : true ,
96- Stdin : ! opts .noStdin && c .Config .OpenStdin ,
97+ Stdin : ! opts .NoStdin && c .Config .OpenStdin ,
9798 Stdout : true ,
9899 Stderr : true ,
99100 DetachKeys : detachKeys ,
@@ -104,13 +105,13 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
104105 in = dockerCli .In ()
105106 }
106107
107- if opts .proxy && ! c .Config .Tty {
108+ if opts .Proxy && ! c .Config .Tty {
108109 sigc := notifyAllSignals ()
109- go ForwardAllSignals (ctx , dockerCli , opts .container , sigc )
110+ go ForwardAllSignals (ctx , dockerCli , opts .Container , sigc )
110111 defer signal .StopCatch (sigc )
111112 }
112113
113- resp , errAttach := apiClient .ContainerAttach (ctx , opts .container , options )
114+ resp , errAttach := apiClient .ContainerAttach (ctx , opts .Container , options )
114115 if errAttach != nil {
115116 return errAttach
116117 }
@@ -124,13 +125,13 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
124125 // the container and not exit.
125126 //
126127 // Recheck the container's state to avoid attach block.
127- _ , err = inspectContainerAndCheckState (ctx , apiClient , opts .container )
128+ _ , err = inspectContainerAndCheckState (ctx , apiClient , opts .Container )
128129 if err != nil {
129130 return err
130131 }
131132
132133 if c .Config .Tty && dockerCli .Out ().IsTerminal () {
133- resizeTTY (ctx , dockerCli , opts .container )
134+ resizeTTY (ctx , dockerCli , opts .Container )
134135 }
135136
136137 streamer := hijackedIOStreamer {
0 commit comments