@@ -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
2827func 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`
4746func 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 {
0 commit comments