@@ -51,8 +51,21 @@ func NewAttachCommand(dockerCLI command.Cli) *cobra.Command {
5151 Short : "Attach local standard input, output, and error streams to a running container" ,
5252 Args : cli .ExactArgs (1 ),
5353 RunE : func (cmd * cobra.Command , args []string ) error {
54+ attachStdIn := true
55+ if opts .NoStdin {
56+ // TODO(thaJeztah): this is the tricky one: can we use container.AttachOptions for this one without it being ambiguous?
57+ attachStdIn = false
58+ }
59+
5460 containerID := args [0 ]
55- return RunAttach (cmd .Context (), dockerCLI , containerID , & opts )
61+ disableSignalProxy := ! opts .Proxy
62+ return RunAttach (cmd .Context (), dockerCLI , containerID , disableSignalProxy , container.AttachOptions {
63+ Stream : true ,
64+ Stdin : attachStdIn ,
65+ Stdout : true ,
66+ Stderr : true ,
67+ DetachKeys : opts .DetachKeys ,
68+ })
5669 },
5770 Annotations : map [string ]string {
5871 "aliases" : "docker container attach, docker attach" ,
@@ -64,61 +77,54 @@ func NewAttachCommand(dockerCLI command.Cli) *cobra.Command {
6477
6578 flags := cmd .Flags ()
6679 flags .BoolVar (& opts .NoStdin , "no-stdin" , false , "Do not attach STDIN" )
80+ // Is this feature still used?
81+ // It was added in https://github.com/moby/moby/commit/4918769b1ac2d38f23087b766140e6a7f8979310 to allow forwarding signals to containers
82+ // Changed in https://github.com/moby/moby/commit/333bc23f21e8423d3085632db99a6d1df227c5f1
83+ // And changed to be enabled by default in https://github.com/moby/moby/commit/e0b59ab52b87b8fc15dd5534c3231fdd74843f9f (unless a TTY is attached)
84+ // related: https://github.com/moby/moby/commit/e0b59ab52b87b8fc15dd5534c3231fdd74843f9f#commitcomment-25897874
85+ // related: https://github.com/moby/moby/issues/9098
86+ // related: https://github.com/docker/cli/pull/1841
6787 flags .BoolVar (& opts .Proxy , "sig-proxy" , true , "Proxy all received signals to the process" )
6888 flags .StringVar (& opts .DetachKeys , "detach-keys" , "" , "Override the key sequence for detaching a container" )
6989 return cmd
7090}
7191
72- // RunAttach executes an `attach` command
73- func RunAttach (ctx context.Context , dockerCLI command.Cli , containerID string , opts * AttachOptions ) error {
92+ // RunAttach attaches to the given container.
93+ func RunAttach (ctx context.Context , dockerCLI command.Cli , containerID string , disableSignalProxy bool , opts container. AttachOptions ) error {
7494 apiClient := dockerCLI .Client ()
7595
76- attachStdIn := true
77- if opts .NoStdin {
78- // TODO(thaJeztah): this is the tricky one: can we use container.AttachOptions for this one without it being ambiguous?
79- attachStdIn = false
80- }
81-
8296 c , err := inspectContainerAndCheckState (ctx , apiClient , containerID )
8397 if err != nil {
8498 return err
8599 }
86100
87- if attachStdIn {
88- if err := dockerCLI .In ().CheckTty (attachStdIn , c .Config .Tty ); err != nil {
101+ if opts . Stdin {
102+ if err := dockerCLI .In ().CheckTty (opts . Stdin , c .Config .Tty ); err != nil {
89103 return err
90104 }
91105 if ! c .Config .OpenStdin {
92106 // TODO(thaJeztah): should this produce an error?
93- attachStdIn = false
107+ opts . Stdin = false
94108 }
95109 }
96110
97- detachKeys := opts .DetachKeys
98111 if opts .DetachKeys == "" {
99- detachKeys = dockerCLI .ConfigFile ().DetachKeys
100- }
101-
102- options := container.AttachOptions {
103- Stream : true ,
104- Stdin : attachStdIn ,
105- Stdout : true ,
106- Stderr : true ,
107- DetachKeys : detachKeys ,
112+ opts .DetachKeys = dockerCLI .ConfigFile ().DetachKeys
108113 }
109114
110115 var in io.ReadCloser
111- if options .Stdin {
116+ if opts .Stdin {
112117 in = dockerCLI .In ()
113118 }
114119
115- if opts .Proxy && ! c .Config .Tty {
120+ // TODO(thaJeztah): should this still depend on Config.Tty? It's unconditionally enabled on `docker exec` since https://github.com/docker/cli/pull/1841/files
121+ if ! disableSignalProxy && ! c .Config .Tty {
116122 sigc := notifyAllSignals ()
117123 go ForwardAllSignals (ctx , apiClient , containerID , sigc )
118124 defer signal .StopCatch (sigc )
119125 }
120126
121- resp , errAttach := apiClient .ContainerAttach (ctx , containerID , options )
127+ resp , errAttach := apiClient .ContainerAttach (ctx , containerID , opts )
122128 if errAttach != nil {
123129 return errAttach
124130 }
@@ -148,7 +154,7 @@ func RunAttach(ctx context.Context, dockerCLI command.Cli, containerID string, o
148154 errorStream : dockerCLI .Err (),
149155 resp : resp ,
150156 tty : c .Config .Tty ,
151- detachKeys : options .DetachKeys ,
157+ detachKeys : opts .DetachKeys ,
152158 }
153159
154160 if err := streamer .stream (ctx ); err != nil {
0 commit comments