@@ -15,14 +15,6 @@ import (
15
15
"github.com/docker/docker/pkg/term"
16
16
)
17
17
18
- type containerAttachConfig struct {
19
- detachKeys []byte
20
- stdin io.ReadCloser
21
- stdout , stderr io.Writer
22
- showHistory bool
23
- stream bool
24
- }
25
-
26
18
// ContainerAttach attaches to logs according to the config passed in. See ContainerAttachConfig.
27
19
func (daemon * Daemon ) ContainerAttach (prefixOrName string , c * backend.ContainerAttachConfig ) error {
28
20
keys := []byte {}
@@ -43,6 +35,16 @@ func (daemon *Daemon) ContainerAttach(prefixOrName string, c *backend.ContainerA
43
35
return errors .NewRequestConflictError (err )
44
36
}
45
37
38
+ cfg := stream.AttachConfig {
39
+ UseStdin : c .UseStdin && container .Config .OpenStdin ,
40
+ UseStdout : c .UseStdout ,
41
+ UseStderr : c .UseStderr ,
42
+ TTY : container .Config .Tty ,
43
+ CloseStdin : container .Config .StdinOnce ,
44
+ DetachKeys : keys ,
45
+ }
46
+ container .StreamConfig .AttachStreams (& cfg )
47
+
46
48
inStream , outStream , errStream , err := c .GetStreams ()
47
49
if err != nil {
48
50
return err
@@ -54,48 +56,51 @@ func (daemon *Daemon) ContainerAttach(prefixOrName string, c *backend.ContainerA
54
56
outStream = stdcopy .NewStdWriter (outStream , stdcopy .Stdout )
55
57
}
56
58
57
- var cfg containerAttachConfig
58
-
59
- if c .UseStdin {
60
- cfg .stdin = inStream
59
+ if cfg .UseStdin {
60
+ cfg .Stdin = inStream
61
61
}
62
- if c .UseStdout {
63
- cfg .stdout = outStream
62
+ if cfg .UseStdout {
63
+ cfg .Stdout = outStream
64
64
}
65
- if c .UseStderr {
66
- cfg .stderr = errStream
65
+ if cfg .UseStderr {
66
+ cfg .Stderr = errStream
67
67
}
68
68
69
- cfg .showHistory = c .Logs
70
- cfg .stream = c .Stream
71
- cfg .detachKeys = keys
72
-
73
- if err := daemon .containerAttach (container , & cfg ); err != nil {
69
+ if err := daemon .containerAttach (container , & cfg , c .Logs , c .Stream ); err != nil {
74
70
fmt .Fprintf (outStream , "Error attaching: %s\n " , err )
75
71
}
76
72
return nil
77
73
}
78
74
79
75
// ContainerAttachRaw attaches the provided streams to the container's stdio
80
- func (daemon * Daemon ) ContainerAttachRaw (prefixOrName string , stdin io.ReadCloser , stdout , stderr io.Writer , stream bool ) error {
76
+ func (daemon * Daemon ) ContainerAttachRaw (prefixOrName string , stdin io.ReadCloser , stdout , stderr io.Writer , doStream bool ) error {
81
77
container , err := daemon .GetContainer (prefixOrName )
82
78
if err != nil {
83
79
return err
84
80
}
85
- cfg := & containerAttachConfig {
86
- stdin : stdin ,
87
- stdout : stdout ,
88
- stderr : stderr ,
89
- stream : stream ,
81
+ cfg := stream.AttachConfig {
82
+ UseStdin : stdin != nil && container .Config .OpenStdin ,
83
+ UseStdout : stdout != nil ,
84
+ UseStderr : stderr != nil ,
85
+ TTY : container .Config .Tty ,
86
+ CloseStdin : container .Config .StdinOnce ,
87
+ }
88
+ container .StreamConfig .AttachStreams (& cfg )
89
+ if cfg .UseStdin {
90
+ cfg .Stdin = stdin
90
91
}
91
- return daemon .containerAttach (container , cfg )
92
+ if cfg .UseStdout {
93
+ cfg .Stdout = stdout
94
+ }
95
+ if cfg .UseStderr {
96
+ cfg .Stderr = stderr
97
+ }
98
+
99
+ return daemon .containerAttach (container , & cfg , false , doStream )
92
100
}
93
101
94
- func (daemon * Daemon ) containerAttach (c * container.Container , cfg * containerAttachConfig ) error {
95
- stdin := cfg .stdin
96
- stdout := cfg .stdout
97
- stderr := cfg .stderr
98
- if cfg .showHistory {
102
+ func (daemon * Daemon ) containerAttach (c * container.Container , cfg * stream.AttachConfig , logs , doStream bool ) error {
103
+ if logs {
99
104
logDriver , err := daemon .getLogger (c )
100
105
if err != nil {
101
106
return err
@@ -113,11 +118,11 @@ func (daemon *Daemon) containerAttach(c *container.Container, cfg *containerAtta
113
118
if ! ok {
114
119
break LogLoop
115
120
}
116
- if msg .Source == "stdout" && stdout != nil {
117
- stdout .Write (msg .Line )
121
+ if msg .Source == "stdout" && cfg . Stdout != nil {
122
+ cfg . Stdout .Write (msg .Line )
118
123
}
119
- if msg .Source == "stderr" && stderr != nil {
120
- stderr .Write (msg .Line )
124
+ if msg .Source == "stderr" && cfg . Stderr != nil {
125
+ cfg . Stderr .Write (msg .Line )
121
126
}
122
127
case err := <- logs .Err :
123
128
logrus .Errorf ("Error streaming logs: %v" , err )
@@ -128,19 +133,18 @@ func (daemon *Daemon) containerAttach(c *container.Container, cfg *containerAtta
128
133
129
134
daemon .LogContainerEvent (c , "attach" )
130
135
131
- if ! cfg . stream {
136
+ if ! doStream {
132
137
return nil
133
138
}
134
139
135
- var stdinPipe io.ReadCloser
136
- if stdin != nil {
140
+ if cfg .Stdin != nil {
137
141
r , w := io .Pipe ()
138
- go func () {
142
+ go func (stdin io. ReadCloser ) {
139
143
defer w .Close ()
140
144
defer logrus .Debug ("Closing buffered stdin pipe" )
141
145
io .Copy (w , stdin )
142
- }()
143
- stdinPipe = r
146
+ }(cfg . Stdin )
147
+ cfg . Stdin = r
144
148
}
145
149
146
150
waitChan := make (chan struct {})
@@ -154,14 +158,8 @@ func (daemon *Daemon) containerAttach(c *container.Container, cfg *containerAtta
154
158
}()
155
159
}
156
160
157
- aCfg := & stream.AttachConfig {
158
- Stdin : stdinPipe ,
159
- Stdout : stdout ,
160
- Stderr : stderr ,
161
- DetachKeys : cfg .detachKeys ,
162
- }
163
-
164
- err := <- c .Attach (aCfg )
161
+ ctx := c .InitAttachContext ()
162
+ err := <- c .StreamConfig .CopyStreams (ctx , cfg )
165
163
if err != nil {
166
164
if _ , ok := err .(stream.DetachError ); ok {
167
165
daemon .LogContainerEvent (c , "detach" )
0 commit comments