@@ -50,9 +50,22 @@ func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
5050 Short : "Attach local standard input, output, and error streams to a running container" ,
5151 Args : cli .ExactArgs (1 ),
5252 RunE : func (cmd * cobra.Command , args []string ) error {
53+ attachStdIn := true
54+ if opts .noStdin {
55+ // TODO(thaJeztah): this is the tricky one: can we use container.AttachOptions for this one without it being ambiguous?
56+ attachStdIn = false
57+ }
58+
5359 containerID := args [0 ]
60+ disableSignalProxy := ! opts .proxy
5461 ctx := context .Background ()
55- return runAttach (ctx , dockerCli , containerID , & opts )
62+ return RunAttach (ctx , 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,60 +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- 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 {
7394 apiClient := dockerCli .Client ()
7495
75- attachStdIn := true
76- if opts .noStdin {
77- // TODO(thaJeztah): this is the tricky one: can we use container.AttachOptions for this one without it being ambiguous?
78- attachStdIn = false
79- }
80-
8196 c , err := inspectContainerAndCheckState (ctx , apiClient , containerID )
8297 if err != nil {
8398 return err
8499 }
85100
86- if attachStdIn {
87- 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 {
88103 return err
89104 }
90105 if ! c .Config .OpenStdin {
91106 // TODO(thaJeztah): should this produce an error?
92- attachStdIn = false
107+ opts . Stdin = false
93108 }
94109 }
95110
96- detachKeys := opts .detachKeys
97- if opts .detachKeys == "" {
98- detachKeys = dockerCli .ConfigFile ().DetachKeys
99- }
100-
101- options := container.AttachOptions {
102- Stream : true ,
103- Stdin : attachStdIn ,
104- Stdout : true ,
105- Stderr : true ,
106- DetachKeys : detachKeys ,
111+ if opts .DetachKeys == "" {
112+ opts .DetachKeys = dockerCli .ConfigFile ().DetachKeys
107113 }
108114
109115 var in io.ReadCloser
110- if options .Stdin {
116+ if opts .Stdin {
111117 in = dockerCli .In ()
112118 }
113119
114- 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 {
115122 sigc := notifyAllSignals ()
116123 go ForwardAllSignals (ctx , dockerCli , containerID , sigc )
117124 defer signal .StopCatch (sigc )
118125 }
119126
120- resp , errAttach := apiClient .ContainerAttach (ctx , containerID , options )
127+ resp , errAttach := apiClient .ContainerAttach (ctx , containerID , opts )
121128 if errAttach != nil {
122129 return errAttach
123130 }
@@ -147,7 +154,7 @@ func runAttach(ctx context.Context, dockerCli command.Cli, containerID string, o
147154 errorStream : dockerCli .Err (),
148155 resp : resp ,
149156 tty : c .Config .Tty ,
150- detachKeys : options .DetachKeys ,
157+ detachKeys : opts .DetachKeys ,
151158 }
152159
153160 if err := streamer .stream (ctx ); err != nil {
0 commit comments