Docker-DCO-1.1-Signed-off-by: Vishnu Kannan <vishnuk@google.com> (github: vishh)
Vishnu Kannan authored on 2014/08/27 07:05:37... | ... |
@@ -103,7 +103,6 @@ func (daemon *Daemon) ContainerAttach(job *engine.Job) engine.Status { |
103 | 103 |
} |
104 | 104 |
|
105 | 105 |
<-daemon.Attach(container, cStdin, cStdinCloser, cStdout, cStderr) |
106 |
- |
|
107 | 106 |
// If we are in stdinonce mode, wait for the process to end |
108 | 107 |
// otherwise, simply return |
109 | 108 |
if container.Config.StdinOnce && !container.Config.Tty { |
... | ... |
@@ -128,7 +127,7 @@ func (daemon *Daemon) Attach(container *Container, stdin io.ReadCloser, stdinClo |
128 | 128 |
|
129 | 129 |
if stdin != nil && container.Config.OpenStdin { |
130 | 130 |
nJobs++ |
131 |
- if cStdin, err := container.StdinPipe(); err != nil { |
|
131 |
+ if cStdin, err := container.StdConfig.StdinPipe(); err != nil { |
|
132 | 132 |
errors <- err |
133 | 133 |
} else { |
134 | 134 |
go func() { |
... | ... |
@@ -164,7 +163,7 @@ func (daemon *Daemon) Attach(container *Container, stdin io.ReadCloser, stdinClo |
164 | 164 |
} |
165 | 165 |
if stdout != nil { |
166 | 166 |
nJobs++ |
167 |
- if p, err := container.StdoutPipe(); err != nil { |
|
167 |
+ if p, err := container.StdConfig.StdoutPipe(); err != nil { |
|
168 | 168 |
errors <- err |
169 | 169 |
} else { |
170 | 170 |
cStdout = p |
... | ... |
@@ -193,7 +192,7 @@ func (daemon *Daemon) Attach(container *Container, stdin io.ReadCloser, stdinClo |
193 | 193 |
if stdinCloser != nil { |
194 | 194 |
defer stdinCloser.Close() |
195 | 195 |
} |
196 |
- if cStdout, err := container.StdoutPipe(); err != nil { |
|
196 |
+ if cStdout, err := container.StdConfig.StdoutPipe(); err != nil { |
|
197 | 197 |
log.Errorf("attach: stdout pipe: %s", err) |
198 | 198 |
} else { |
199 | 199 |
io.Copy(&utils.NopWriter{}, cStdout) |
... | ... |
@@ -202,7 +201,7 @@ func (daemon *Daemon) Attach(container *Container, stdin io.ReadCloser, stdinClo |
202 | 202 |
} |
203 | 203 |
if stderr != nil { |
204 | 204 |
nJobs++ |
205 |
- if p, err := container.StderrPipe(); err != nil { |
|
205 |
+ if p, err := container.StdConfig.StderrPipe(); err != nil { |
|
206 | 206 |
errors <- err |
207 | 207 |
} else { |
208 | 208 |
cStderr = p |
... | ... |
@@ -232,7 +231,7 @@ func (daemon *Daemon) Attach(container *Container, stdin io.ReadCloser, stdinClo |
232 | 232 |
defer stdinCloser.Close() |
233 | 233 |
} |
234 | 234 |
|
235 |
- if cStderr, err := container.StderrPipe(); err != nil { |
|
235 |
+ if cStderr, err := container.StdConfig.StderrPipe(); err != nil { |
|
236 | 236 |
log.Errorf("attach: stdout pipe: %s", err) |
237 | 237 |
} else { |
238 | 238 |
io.Copy(&utils.NopWriter{}, cStderr) |
... | ... |
@@ -41,6 +41,13 @@ var ( |
41 | 41 |
ErrContainerStartTimeout = errors.New("The container failed to start due to timed out.") |
42 | 42 |
) |
43 | 43 |
|
44 |
+type StdConfig struct { |
|
45 |
+ stdout *broadcastwriter.BroadcastWriter |
|
46 |
+ stderr *broadcastwriter.BroadcastWriter |
|
47 |
+ stdin io.ReadCloser |
|
48 |
+ stdinPipe io.WriteCloser |
|
49 |
+} |
|
50 |
+ |
|
44 | 51 |
type Container struct { |
45 | 52 |
*State |
46 | 53 |
root string // Path to the "home" of the container, including metadata. |
... | ... |
@@ -66,10 +73,7 @@ type Container struct { |
66 | 66 |
ExecDriver string |
67 | 67 |
|
68 | 68 |
command *execdriver.Command |
69 |
- stdout *broadcastwriter.BroadcastWriter |
|
70 |
- stderr *broadcastwriter.BroadcastWriter |
|
71 |
- stdin io.ReadCloser |
|
72 |
- stdinPipe io.WriteCloser |
|
69 |
+ StdConfig StdConfig |
|
73 | 70 |
|
74 | 71 |
daemon *Daemon |
75 | 72 |
MountLabel, ProcessLabel string |
... | ... |
@@ -247,26 +251,31 @@ func populateCommand(c *Container, env []string) error { |
247 | 247 |
CpuShares: c.Config.CpuShares, |
248 | 248 |
Cpuset: c.Config.Cpuset, |
249 | 249 |
} |
250 |
+ |
|
251 |
+ processConfig := execdriver.ProcessConfig{ |
|
252 |
+ Privileged: c.hostConfig.Privileged, |
|
253 |
+ Entrypoint: c.Path, |
|
254 |
+ Arguments: c.Args, |
|
255 |
+ Tty: c.Config.Tty, |
|
256 |
+ User: c.Config.User, |
|
257 |
+ } |
|
258 |
+ processConfig.SysProcAttr = &syscall.SysProcAttr{Setsid: true} |
|
259 |
+ processConfig.Env = env |
|
250 | 260 |
c.command = &execdriver.Command{ |
251 | 261 |
ID: c.ID, |
252 |
- Privileged: c.hostConfig.Privileged, |
|
253 | 262 |
Rootfs: c.RootfsPath(), |
254 | 263 |
InitPath: "/.dockerinit", |
255 |
- Entrypoint: c.Path, |
|
256 |
- Arguments: c.Args, |
|
257 | 264 |
WorkingDir: c.Config.WorkingDir, |
258 | 265 |
Network: en, |
259 |
- Tty: c.Config.Tty, |
|
260 |
- User: c.Config.User, |
|
261 | 266 |
Config: context, |
262 | 267 |
Resources: resources, |
263 | 268 |
AllowedDevices: allowedDevices, |
264 | 269 |
AutoCreatedDevices: autoCreatedDevices, |
265 | 270 |
CapAdd: c.hostConfig.CapAdd, |
266 | 271 |
CapDrop: c.hostConfig.CapDrop, |
272 |
+ ProcessConfig: processConfig, |
|
267 | 273 |
} |
268 |
- c.command.SysProcAttr = &syscall.SysProcAttr{Setsid: true} |
|
269 |
- c.command.Env = env |
|
274 |
+ |
|
270 | 275 |
return nil |
271 | 276 |
} |
272 | 277 |
|
... | ... |
@@ -329,7 +338,7 @@ func (container *Container) Run() error { |
329 | 329 |
} |
330 | 330 |
|
331 | 331 |
func (container *Container) Output() (output []byte, err error) { |
332 |
- pipe, err := container.StdoutPipe() |
|
332 |
+ pipe, err := container.StdConfig.StdoutPipe() |
|
333 | 333 |
if err != nil { |
334 | 334 |
return nil, err |
335 | 335 |
} |
... | ... |
@@ -342,7 +351,7 @@ func (container *Container) Output() (output []byte, err error) { |
342 | 342 |
return output, err |
343 | 343 |
} |
344 | 344 |
|
345 |
-// Container.StdinPipe returns a WriteCloser which can be used to feed data |
|
345 |
+// StdConfig.StdinPipe returns a WriteCloser which can be used to feed data |
|
346 | 346 |
// to the standard input of the container's active process. |
347 | 347 |
// Container.StdoutPipe and Container.StderrPipe each return a ReadCloser |
348 | 348 |
// which can be used to retrieve the standard output (and error) generated |
... | ... |
@@ -350,31 +359,31 @@ func (container *Container) Output() (output []byte, err error) { |
350 | 350 |
// copied and delivered to all StdoutPipe and StderrPipe consumers, using |
351 | 351 |
// a kind of "broadcaster". |
352 | 352 |
|
353 |
-func (container *Container) StdinPipe() (io.WriteCloser, error) { |
|
354 |
- return container.stdinPipe, nil |
|
353 |
+func (stdConfig *StdConfig) StdinPipe() (io.WriteCloser, error) { |
|
354 |
+ return stdConfig.stdinPipe, nil |
|
355 | 355 |
} |
356 | 356 |
|
357 |
-func (container *Container) StdoutPipe() (io.ReadCloser, error) { |
|
357 |
+func (stdConfig *StdConfig) StdoutPipe() (io.ReadCloser, error) { |
|
358 | 358 |
reader, writer := io.Pipe() |
359 |
- container.stdout.AddWriter(writer, "") |
|
359 |
+ stdConfig.stdout.AddWriter(writer, "") |
|
360 | 360 |
return utils.NewBufReader(reader), nil |
361 | 361 |
} |
362 | 362 |
|
363 |
-func (container *Container) StderrPipe() (io.ReadCloser, error) { |
|
363 |
+func (stdConfig *StdConfig) StderrPipe() (io.ReadCloser, error) { |
|
364 | 364 |
reader, writer := io.Pipe() |
365 |
- container.stderr.AddWriter(writer, "") |
|
365 |
+ stdConfig.stderr.AddWriter(writer, "") |
|
366 | 366 |
return utils.NewBufReader(reader), nil |
367 | 367 |
} |
368 | 368 |
|
369 | 369 |
func (container *Container) StdoutLogPipe() io.ReadCloser { |
370 | 370 |
reader, writer := io.Pipe() |
371 |
- container.stdout.AddWriter(writer, "stdout") |
|
371 |
+ container.StdConfig.stdout.AddWriter(writer, "stdout") |
|
372 | 372 |
return utils.NewBufReader(reader) |
373 | 373 |
} |
374 | 374 |
|
375 | 375 |
func (container *Container) StderrLogPipe() io.ReadCloser { |
376 | 376 |
reader, writer := io.Pipe() |
377 |
- container.stderr.AddWriter(writer, "stderr") |
|
377 |
+ container.StdConfig.stderr.AddWriter(writer, "stderr") |
|
378 | 378 |
return utils.NewBufReader(reader) |
379 | 379 |
} |
380 | 380 |
|
... | ... |
@@ -631,7 +640,7 @@ func (container *Container) Restart(seconds int) error { |
631 | 631 |
} |
632 | 632 |
|
633 | 633 |
func (container *Container) Resize(h, w int) error { |
634 |
- return container.command.Terminal.Resize(h, w) |
|
634 |
+ return container.command.ProcessConfig.Terminal.Resize(h, w) |
|
635 | 635 |
} |
636 | 636 |
|
637 | 637 |
func (container *Container) ExportRw() (archive.Archive, error) { |
... | ... |
@@ -815,7 +824,7 @@ func (container *Container) Exposes(p nat.Port) bool { |
815 | 815 |
} |
816 | 816 |
|
817 | 817 |
func (container *Container) GetPtyMaster() (*os.File, error) { |
818 |
- ttyConsole, ok := container.command.Terminal.(execdriver.TtyTerminal) |
|
818 |
+ ttyConsole, ok := container.command.ProcessConfig.Terminal.(execdriver.TtyTerminal) |
|
819 | 819 |
if !ok { |
820 | 820 |
return nil, ErrNoTTY |
821 | 821 |
} |
... | ... |
@@ -1083,11 +1092,11 @@ func (container *Container) startLoggingToDisk() error { |
1083 | 1083 |
return err |
1084 | 1084 |
} |
1085 | 1085 |
|
1086 |
- if err := container.daemon.LogToDisk(container.stdout, pth, "stdout"); err != nil { |
|
1086 |
+ if err := container.daemon.LogToDisk(container.StdConfig.stdout, pth, "stdout"); err != nil { |
|
1087 | 1087 |
return err |
1088 | 1088 |
} |
1089 | 1089 |
|
1090 |
- if err := container.daemon.LogToDisk(container.stderr, pth, "stderr"); err != nil { |
|
1090 |
+ if err := container.daemon.LogToDisk(container.StdConfig.stderr, pth, "stderr"); err != nil { |
|
1091 | 1091 |
return err |
1092 | 1092 |
} |
1093 | 1093 |
|
... | ... |
@@ -195,13 +195,13 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool) err |
195 | 195 |
container.daemon = daemon |
196 | 196 |
|
197 | 197 |
// Attach to stdout and stderr |
198 |
- container.stderr = broadcastwriter.New() |
|
199 |
- container.stdout = broadcastwriter.New() |
|
198 |
+ container.StdConfig.stderr = broadcastwriter.New() |
|
199 |
+ container.StdConfig.stdout = broadcastwriter.New() |
|
200 | 200 |
// Attach to stdin |
201 | 201 |
if container.Config.OpenStdin { |
202 |
- container.stdin, container.stdinPipe = io.Pipe() |
|
202 |
+ container.StdConfig.stdin, container.StdConfig.stdinPipe = io.Pipe() |
|
203 | 203 |
} else { |
204 |
- container.stdinPipe = utils.NopWriteCloser(ioutil.Discard) // Silently drop stdin |
|
204 |
+ container.StdConfig.stdinPipe = utils.NopWriteCloser(ioutil.Discard) // Silently drop stdin |
|
205 | 205 |
} |
206 | 206 |
// done |
207 | 207 |
daemon.containers.Add(container.ID, container) |
... | ... |
@@ -229,7 +229,7 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool) err |
229 | 229 |
ID: container.ID, |
230 | 230 |
} |
231 | 231 |
var err error |
232 |
- cmd.Process, err = os.FindProcess(existingPid) |
|
232 |
+ cmd.ProcessConfig.Process, err = os.FindProcess(existingPid) |
|
233 | 233 |
if err != nil { |
234 | 234 |
log.Debugf("cannot find existing process for %d", existingPid) |
235 | 235 |
} |
... | ... |
@@ -20,7 +20,7 @@ var ( |
20 | 20 |
ErrDriverNotFound = errors.New("The requested docker init has not been found") |
21 | 21 |
) |
22 | 22 |
|
23 |
-type StartCallback func(*Command) |
|
23 |
+type StartCallback func(*ProcessConfig) |
|
24 | 24 |
|
25 | 25 |
// Driver specific information based on |
26 | 26 |
// processes registered with the driver |
... | ... |
@@ -80,20 +80,27 @@ type Mount struct { |
80 | 80 |
Private bool `json:"private"` |
81 | 81 |
} |
82 | 82 |
|
83 |
-// Process wrapps an os/exec.Cmd to add more metadata |
|
84 |
-type Command struct { |
|
83 |
+// Describes a process that will be run inside a container. |
|
84 |
+type ProcessConfig struct { |
|
85 | 85 |
exec.Cmd `json:"-"` |
86 | 86 |
|
87 |
+ Privileged bool `json:"privileged"` |
|
88 |
+ User string `json:"user"` |
|
89 |
+ Tty bool `json:"tty"` |
|
90 |
+ Entrypoint string `json:"entrypoint"` |
|
91 |
+ Arguments []string `json:"arguments"` |
|
92 |
+ Terminal Terminal `json:"-"` // standard or tty terminal |
|
93 |
+ ContainerPid int `json:"container_pid"` // the pid for the process inside a container |
|
94 |
+ Console string `json:"-"` // dev/console path |
|
95 |
+} |
|
96 |
+ |
|
97 |
+// Process wrapps an os/exec.Cmd to add more metadata |
|
98 |
+type Command struct { |
|
87 | 99 |
ID string `json:"id"` |
88 |
- Privileged bool `json:"privileged"` |
|
89 |
- User string `json:"user"` |
|
90 | 100 |
Rootfs string `json:"rootfs"` // root fs of the container |
91 | 101 |
InitPath string `json:"initpath"` // dockerinit |
92 |
- Entrypoint string `json:"entrypoint"` |
|
93 |
- Arguments []string `json:"arguments"` |
|
94 | 102 |
WorkingDir string `json:"working_dir"` |
95 | 103 |
ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver |
96 |
- Tty bool `json:"tty"` |
|
97 | 104 |
Network *Network `json:"network"` |
98 | 105 |
Config map[string][]string `json:"config"` // generic values that specific drivers can consume |
99 | 106 |
Resources *Resources `json:"resources"` |
... | ... |
@@ -103,13 +110,11 @@ type Command struct { |
103 | 103 |
CapAdd []string `json:"cap_add"` |
104 | 104 |
CapDrop []string `json:"cap_drop"` |
105 | 105 |
|
106 |
- Terminal Terminal `json:"-"` // standard or tty terminal |
|
107 |
- Console string `json:"-"` // dev/console path |
|
108 |
- ContainerPid int `json:"container_pid"` // the pid for the process inside a container |
|
106 |
+ ProcessConfig ProcessConfig `json:"process_config"` // Describes the init process of the container. |
|
109 | 107 |
} |
110 | 108 |
|
111 | 109 |
// Return the pid of the process |
112 | 110 |
// If the process is nil -1 will be returned |
113 |
-func (c *Command) Pid() int { |
|
114 |
- return c.ContainerPid |
|
111 |
+func (processConfig *ProcessConfig) Pid() int { |
|
112 |
+ return processConfig.ContainerPid |
|
115 | 113 |
} |
... | ... |
@@ -59,12 +59,12 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
59 | 59 |
err error |
60 | 60 |
) |
61 | 61 |
|
62 |
- if c.Tty { |
|
63 |
- term, err = NewTtyConsole(c, pipes) |
|
62 |
+ if c.ProcessConfig.Tty { |
|
63 |
+ term, err = NewTtyConsole(&c.ProcessConfig, pipes) |
|
64 | 64 |
} else { |
65 |
- term, err = execdriver.NewStdConsole(c, pipes) |
|
65 |
+ term, err = execdriver.NewStdConsole(&c.ProcessConfig, pipes) |
|
66 | 66 |
} |
67 |
- c.Terminal = term |
|
67 |
+ c.ProcessConfig.Terminal = term |
|
68 | 68 |
|
69 | 69 |
c.Mounts = append(c.Mounts, execdriver.Mount{ |
70 | 70 |
Source: d.initPath, |
... | ... |
@@ -98,11 +98,11 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
98 | 98 |
"-mtu", strconv.Itoa(c.Network.Mtu), |
99 | 99 |
) |
100 | 100 |
|
101 |
- if c.User != "" { |
|
102 |
- params = append(params, "-u", c.User) |
|
101 |
+ if c.ProcessConfig.User != "" { |
|
102 |
+ params = append(params, "-u", c.ProcessConfig.User) |
|
103 | 103 |
} |
104 | 104 |
|
105 |
- if c.Privileged { |
|
105 |
+ if c.ProcessConfig.Privileged { |
|
106 | 106 |
if d.apparmor { |
107 | 107 |
params[0] = path.Join(d.root, "lxc-start-unconfined") |
108 | 108 |
|
... | ... |
@@ -122,8 +122,8 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
122 | 122 |
params = append(params, fmt.Sprintf("-cap-drop=%s", strings.Join(c.CapDrop, ":"))) |
123 | 123 |
} |
124 | 124 |
|
125 |
- params = append(params, "--", c.Entrypoint) |
|
126 |
- params = append(params, c.Arguments...) |
|
125 |
+ params = append(params, "--", c.ProcessConfig.Entrypoint) |
|
126 |
+ params = append(params, c.ProcessConfig.Arguments...) |
|
127 | 127 |
|
128 | 128 |
if d.sharedRoot { |
129 | 129 |
// lxc-start really needs / to be non-shared, or all kinds of stuff break |
... | ... |
@@ -149,14 +149,14 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
149 | 149 |
if err != nil { |
150 | 150 |
aname = name |
151 | 151 |
} |
152 |
- c.Path = aname |
|
153 |
- c.Args = append([]string{name}, arg...) |
|
152 |
+ c.ProcessConfig.Path = aname |
|
153 |
+ c.ProcessConfig.Args = append([]string{name}, arg...) |
|
154 | 154 |
|
155 | 155 |
if err := nodes.CreateDeviceNodes(c.Rootfs, c.AutoCreatedDevices); err != nil { |
156 | 156 |
return -1, err |
157 | 157 |
} |
158 | 158 |
|
159 |
- if err := c.Start(); err != nil { |
|
159 |
+ if err := c.ProcessConfig.Start(); err != nil { |
|
160 | 160 |
return -1, err |
161 | 161 |
} |
162 | 162 |
|
... | ... |
@@ -166,7 +166,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
166 | 166 |
) |
167 | 167 |
|
168 | 168 |
go func() { |
169 |
- if err := c.Wait(); err != nil { |
|
169 |
+ if err := c.ProcessConfig.Wait(); err != nil { |
|
170 | 170 |
if _, ok := err.(*exec.ExitError); !ok { // Do not propagate the error if it's simply a status code != 0 |
171 | 171 |
waitErr = err |
172 | 172 |
} |
... | ... |
@@ -177,17 +177,17 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
177 | 177 |
// Poll lxc for RUNNING status |
178 | 178 |
pid, err := d.waitForStart(c, waitLock) |
179 | 179 |
if err != nil { |
180 |
- if c.Process != nil { |
|
181 |
- c.Process.Kill() |
|
182 |
- c.Wait() |
|
180 |
+ if c.ProcessConfig.Process != nil { |
|
181 |
+ c.ProcessConfig.Process.Kill() |
|
182 |
+ c.ProcessConfig.Wait() |
|
183 | 183 |
} |
184 | 184 |
return -1, err |
185 | 185 |
} |
186 | 186 |
|
187 |
- c.ContainerPid = pid |
|
187 |
+ c.ProcessConfig.ContainerPid = pid |
|
188 | 188 |
|
189 | 189 |
if startCallback != nil { |
190 |
- startCallback(c) |
|
190 |
+ startCallback(&c.ProcessConfig) |
|
191 | 191 |
} |
192 | 192 |
|
193 | 193 |
<-waitLock |
... | ... |
@@ -198,10 +198,10 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
198 | 198 |
/// Return the exit code of the process |
199 | 199 |
// if the process has not exited -1 will be returned |
200 | 200 |
func getExitCode(c *execdriver.Command) int { |
201 |
- if c.ProcessState == nil { |
|
201 |
+ if c.ProcessConfig.ProcessState == nil { |
|
202 | 202 |
return -1 |
203 | 203 |
} |
204 |
- return c.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() |
|
204 |
+ return c.ProcessConfig.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() |
|
205 | 205 |
} |
206 | 206 |
|
207 | 207 |
func (d *driver) Kill(c *execdriver.Command, sig int) error { |
... | ... |
@@ -442,7 +442,7 @@ func (d *driver) generateLXCConfig(c *execdriver.Command) (string, error) { |
442 | 442 |
} |
443 | 443 |
|
444 | 444 |
func (d *driver) generateEnvConfig(c *execdriver.Command) error { |
445 |
- data, err := json.Marshal(c.Env) |
|
445 |
+ data, err := json.Marshal(c.ProcessConfig.Env) |
|
446 | 446 |
if err != nil { |
447 | 447 |
return err |
448 | 448 |
} |
... | ... |
@@ -462,7 +462,7 @@ type TtyConsole struct { |
462 | 462 |
SlavePty *os.File |
463 | 463 |
} |
464 | 464 |
|
465 |
-func NewTtyConsole(command *execdriver.Command, pipes *execdriver.Pipes) (*TtyConsole, error) { |
|
465 |
+func NewTtyConsole(processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes) (*TtyConsole, error) { |
|
466 | 466 |
// lxc is special in that we cannot create the master outside of the container without |
467 | 467 |
// opening the slave because we have nothing to provide to the cmd. We have to open both then do |
468 | 468 |
// the crazy setup on command right now instead of passing the console path to lxc and telling it |
... | ... |
@@ -478,12 +478,12 @@ func NewTtyConsole(command *execdriver.Command, pipes *execdriver.Pipes) (*TtyCo |
478 | 478 |
SlavePty: ptySlave, |
479 | 479 |
} |
480 | 480 |
|
481 |
- if err := tty.AttachPipes(&command.Cmd, pipes); err != nil { |
|
481 |
+ if err := tty.AttachPipes(&processConfig.Cmd, pipes); err != nil { |
|
482 | 482 |
tty.Close() |
483 | 483 |
return nil, err |
484 | 484 |
} |
485 | 485 |
|
486 |
- command.Console = tty.SlavePty.Name() |
|
486 |
+ processConfig.Console = tty.SlavePty.Name() |
|
487 | 487 |
|
488 | 488 |
return tty, nil |
489 | 489 |
} |
... | ... |
@@ -42,7 +42,7 @@ lxc.se_context = {{ .ProcessLabel}} |
42 | 42 |
# no controlling tty at all |
43 | 43 |
lxc.tty = 1 |
44 | 44 |
|
45 |
-{{if .Privileged}} |
|
45 |
+{{if .ProcessConfig.Privileged}} |
|
46 | 46 |
lxc.cgroup.devices.allow = a |
47 | 47 |
{{else}} |
48 | 48 |
# no implicit access to devices |
... | ... |
@@ -66,7 +66,7 @@ lxc.pivotdir = lxc_putold |
66 | 66 |
lxc.mount.entry = proc {{escapeFstabSpaces $ROOTFS}}/proc proc nosuid,nodev,noexec 0 0 |
67 | 67 |
lxc.mount.entry = sysfs {{escapeFstabSpaces $ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0 |
68 | 68 |
|
69 |
-{{if .Tty}} |
|
69 |
+{{if .ProcessConfig.Tty}} |
|
70 | 70 |
lxc.mount.entry = {{.Console}} {{escapeFstabSpaces $ROOTFS}}/dev/console none bind,rw 0 0 |
71 | 71 |
{{end}} |
72 | 72 |
|
... | ... |
@@ -81,7 +81,7 @@ lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabS |
81 | 81 |
{{end}} |
82 | 82 |
{{end}} |
83 | 83 |
|
84 |
-{{if .Privileged}} |
|
84 |
+{{if .ProcessConfig.Privileged}} |
|
85 | 85 |
{{if .AppArmor}} |
86 | 86 |
lxc.aa_profile = unconfined |
87 | 87 |
{{else}} |
... | ... |
@@ -77,9 +77,11 @@ func TestCustomLxcConfig(t *testing.T) { |
77 | 77 |
if err != nil { |
78 | 78 |
t.Fatal(err) |
79 | 79 |
} |
80 |
- command := &execdriver.Command{ |
|
81 |
- ID: "1", |
|
80 |
+ processConfig := execdriver.ProcessConfig{ |
|
82 | 81 |
Privileged: false, |
82 |
+ } |
|
83 |
+ command := &execdriver.Command{ |
|
84 |
+ ID: "1", |
|
83 | 85 |
Config: map[string][]string{ |
84 | 86 |
"lxc": { |
85 | 87 |
"lxc.utsname = docker", |
... | ... |
@@ -90,6 +92,7 @@ func TestCustomLxcConfig(t *testing.T) { |
90 | 90 |
Mtu: 1500, |
91 | 91 |
Interface: nil, |
92 | 92 |
}, |
93 |
+ ProcessConfig: processConfig, |
|
93 | 94 |
} |
94 | 95 |
|
95 | 96 |
p, err := driver.generateLXCConfig(command) |
... | ... |
@@ -23,11 +23,11 @@ import ( |
23 | 23 |
func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, error) { |
24 | 24 |
container := template.New() |
25 | 25 |
|
26 |
- container.Hostname = getEnv("HOSTNAME", c.Env) |
|
27 |
- container.Tty = c.Tty |
|
28 |
- container.User = c.User |
|
26 |
+ container.Hostname = getEnv("HOSTNAME", c.ProcessConfig.Env) |
|
27 |
+ container.Tty = c.ProcessConfig.Tty |
|
28 |
+ container.User = c.ProcessConfig.User |
|
29 | 29 |
container.WorkingDir = c.WorkingDir |
30 |
- container.Env = c.Env |
|
30 |
+ container.Env = c.ProcessConfig.Env |
|
31 | 31 |
container.Cgroups.Name = c.ID |
32 | 32 |
container.Cgroups.AllowedDevices = c.AllowedDevices |
33 | 33 |
container.MountConfig.DeviceNodes = c.AutoCreatedDevices |
... | ... |
@@ -40,7 +40,7 @@ func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, e |
40 | 40 |
return nil, err |
41 | 41 |
} |
42 | 42 |
|
43 |
- if c.Privileged { |
|
43 |
+ if c.ProcessConfig.Privileged { |
|
44 | 44 |
if err := d.setPrivileged(container); err != nil { |
45 | 45 |
return nil, err |
46 | 46 |
} |
... | ... |
@@ -68,26 +68,26 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
68 | 68 |
|
69 | 69 |
var term execdriver.Terminal |
70 | 70 |
|
71 |
- if c.Tty { |
|
72 |
- term, err = NewTtyConsole(c, pipes) |
|
71 |
+ if c.ProcessConfig.Tty { |
|
72 |
+ term, err = NewTtyConsole(&c.ProcessConfig, pipes) |
|
73 | 73 |
} else { |
74 |
- term, err = execdriver.NewStdConsole(c, pipes) |
|
74 |
+ term, err = execdriver.NewStdConsole(&c.ProcessConfig, pipes) |
|
75 | 75 |
} |
76 | 76 |
if err != nil { |
77 | 77 |
return -1, err |
78 | 78 |
} |
79 |
- c.Terminal = term |
|
79 |
+ c.ProcessConfig.Terminal = term |
|
80 | 80 |
|
81 | 81 |
d.Lock() |
82 | 82 |
d.activeContainers[c.ID] = &activeContainer{ |
83 | 83 |
container: container, |
84 |
- cmd: &c.Cmd, |
|
84 |
+ cmd: &c.ProcessConfig.Cmd, |
|
85 | 85 |
} |
86 | 86 |
d.Unlock() |
87 | 87 |
|
88 | 88 |
var ( |
89 | 89 |
dataPath = filepath.Join(d.root, c.ID) |
90 |
- args = append([]string{c.Entrypoint}, c.Arguments...) |
|
90 |
+ args = append([]string{c.ProcessConfig.Entrypoint}, c.ProcessConfig.Arguments...) |
|
91 | 91 |
) |
92 | 92 |
|
93 | 93 |
if err := d.createContainerRoot(c.ID); err != nil { |
... | ... |
@@ -99,9 +99,9 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
99 | 99 |
return -1, err |
100 | 100 |
} |
101 | 101 |
|
102 |
- return namespaces.Exec(container, c.Stdin, c.Stdout, c.Stderr, c.Console, c.Rootfs, dataPath, args, func(container *libcontainer.Config, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd { |
|
103 |
- c.Path = d.initPath |
|
104 |
- c.Args = append([]string{ |
|
102 |
+ return namespaces.Exec(container, c.ProcessConfig.Stdin, c.ProcessConfig.Stdout, c.ProcessConfig.Stderr, c.ProcessConfig.Console, c.Rootfs, dataPath, args, func(container *libcontainer.Config, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd { |
|
103 |
+ c.ProcessConfig.Path = d.initPath |
|
104 |
+ c.ProcessConfig.Args = append([]string{ |
|
105 | 105 |
DriverName, |
106 | 106 |
"-console", console, |
107 | 107 |
"-pipe", "3", |
... | ... |
@@ -110,25 +110,25 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba |
110 | 110 |
}, args...) |
111 | 111 |
|
112 | 112 |
// set this to nil so that when we set the clone flags anything else is reset |
113 |
- c.SysProcAttr = &syscall.SysProcAttr{ |
|
113 |
+ c.ProcessConfig.SysProcAttr = &syscall.SysProcAttr{ |
|
114 | 114 |
Cloneflags: uintptr(namespaces.GetNamespaceFlags(container.Namespaces)), |
115 | 115 |
} |
116 |
- c.ExtraFiles = []*os.File{child} |
|
116 |
+ c.ProcessConfig.ExtraFiles = []*os.File{child} |
|
117 | 117 |
|
118 |
- c.Env = container.Env |
|
119 |
- c.Dir = c.Rootfs |
|
118 |
+ c.ProcessConfig.Env = container.Env |
|
119 |
+ c.ProcessConfig.Dir = c.Rootfs |
|
120 | 120 |
|
121 |
- return &c.Cmd |
|
121 |
+ return &c.ProcessConfig.Cmd |
|
122 | 122 |
}, func() { |
123 | 123 |
if startCallback != nil { |
124 |
- c.ContainerPid = c.Process.Pid |
|
125 |
- startCallback(c) |
|
124 |
+ c.ProcessConfig.ContainerPid = c.ProcessConfig.Process.Pid |
|
125 |
+ startCallback(&c.ProcessConfig) |
|
126 | 126 |
} |
127 | 127 |
}) |
128 | 128 |
} |
129 | 129 |
|
130 | 130 |
func (d *driver) Kill(p *execdriver.Command, sig int) error { |
131 |
- return syscall.Kill(p.Process.Pid, syscall.Signal(sig)) |
|
131 |
+ return syscall.Kill(p.ProcessConfig.Process.Pid, syscall.Signal(sig)) |
|
132 | 132 |
} |
133 | 133 |
|
134 | 134 |
func (d *driver) Pause(c *execdriver.Command) error { |
... | ... |
@@ -176,14 +176,14 @@ func (d *driver) Terminate(p *execdriver.Command) error { |
176 | 176 |
state = &libcontainer.State{InitStartTime: string(data)} |
177 | 177 |
} |
178 | 178 |
|
179 |
- currentStartTime, err := system.GetProcessStartTime(p.Process.Pid) |
|
179 |
+ currentStartTime, err := system.GetProcessStartTime(p.ProcessConfig.Process.Pid) |
|
180 | 180 |
if err != nil { |
181 | 181 |
return err |
182 | 182 |
} |
183 | 183 |
|
184 | 184 |
if state.InitStartTime == currentStartTime { |
185 |
- err = syscall.Kill(p.Process.Pid, 9) |
|
186 |
- syscall.Wait4(p.Process.Pid, nil, 0, nil) |
|
185 |
+ err = syscall.Kill(p.ProcessConfig.Process.Pid, 9) |
|
186 |
+ syscall.Wait4(p.ProcessConfig.Process.Pid, nil, 0, nil) |
|
187 | 187 |
} |
188 | 188 |
d.removeContainerRoot(p.ID) |
189 | 189 |
|
... | ... |
@@ -252,7 +252,7 @@ type TtyConsole struct { |
252 | 252 |
MasterPty *os.File |
253 | 253 |
} |
254 | 254 |
|
255 |
-func NewTtyConsole(command *execdriver.Command, pipes *execdriver.Pipes) (*TtyConsole, error) { |
|
255 |
+func NewTtyConsole(processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes) (*TtyConsole, error) { |
|
256 | 256 |
ptyMaster, console, err := consolepkg.CreateMasterAndConsole() |
257 | 257 |
if err != nil { |
258 | 258 |
return nil, err |
... | ... |
@@ -262,12 +262,12 @@ func NewTtyConsole(command *execdriver.Command, pipes *execdriver.Pipes) (*TtyCo |
262 | 262 |
MasterPty: ptyMaster, |
263 | 263 |
} |
264 | 264 |
|
265 |
- if err := tty.AttachPipes(&command.Cmd, pipes); err != nil { |
|
265 |
+ if err := tty.AttachPipes(&processConfig.Cmd, pipes); err != nil { |
|
266 | 266 |
tty.Close() |
267 | 267 |
return nil, err |
268 | 268 |
} |
269 | 269 |
|
270 |
- command.Console = console |
|
270 |
+ processConfig.Console = console |
|
271 | 271 |
|
272 | 272 |
return tty, nil |
273 | 273 |
} |
... | ... |
@@ -8,10 +8,10 @@ import ( |
8 | 8 |
type StdConsole struct { |
9 | 9 |
} |
10 | 10 |
|
11 |
-func NewStdConsole(command *Command, pipes *Pipes) (*StdConsole, error) { |
|
11 |
+func NewStdConsole(processConfig *ProcessConfig, pipes *Pipes) (*StdConsole, error) { |
|
12 | 12 |
std := &StdConsole{} |
13 | 13 |
|
14 |
- if err := std.AttachPipes(&command.Cmd, pipes); err != nil { |
|
14 |
+ if err := std.AttachPipes(&processConfig.Cmd, pipes); err != nil { |
|
15 | 15 |
return nil, err |
16 | 16 |
} |
17 | 17 |
return std, nil |
... | ... |
@@ -128,7 +128,7 @@ func (m *containerMonitor) Start() error { |
128 | 128 |
return err |
129 | 129 |
} |
130 | 130 |
|
131 |
- pipes := execdriver.NewPipes(m.container.stdin, m.container.stdout, m.container.stderr, m.container.Config.OpenStdin) |
|
131 |
+ pipes := execdriver.NewPipes(m.container.StdConfig.stdin, m.container.StdConfig.stdout, m.container.StdConfig.stderr, m.container.Config.OpenStdin) |
|
132 | 132 |
|
133 | 133 |
m.container.LogEvent("start") |
134 | 134 |
|
... | ... |
@@ -233,17 +233,17 @@ func (m *containerMonitor) shouldRestart(exitStatus int) bool { |
233 | 233 |
|
234 | 234 |
// callback ensures that the container's state is properly updated after we |
235 | 235 |
// received ack from the execution drivers |
236 |
-func (m *containerMonitor) callback(command *execdriver.Command) { |
|
237 |
- if command.Tty { |
|
236 |
+func (m *containerMonitor) callback(processConfig *execdriver.ProcessConfig) { |
|
237 |
+ if processConfig.Tty { |
|
238 | 238 |
// The callback is called after the process Start() |
239 | 239 |
// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlace |
240 | 240 |
// which we close here. |
241 |
- if c, ok := command.Stdout.(io.Closer); ok { |
|
241 |
+ if c, ok := processConfig.Stdout.(io.Closer); ok { |
|
242 | 242 |
c.Close() |
243 | 243 |
} |
244 | 244 |
} |
245 | 245 |
|
246 |
- m.container.State.setRunning(command.Pid()) |
|
246 |
+ m.container.State.setRunning(processConfig.Pid()) |
|
247 | 247 |
|
248 | 248 |
// signal that the process has started |
249 | 249 |
// close channel only if not closed |
... | ... |
@@ -269,33 +269,33 @@ func (m *containerMonitor) resetContainer(lock bool) { |
269 | 269 |
} |
270 | 270 |
|
271 | 271 |
if container.Config.OpenStdin { |
272 |
- if err := container.stdin.Close(); err != nil { |
|
272 |
+ if err := container.StdConfig.stdin.Close(); err != nil { |
|
273 | 273 |
log.Errorf("%s: Error close stdin: %s", container.ID, err) |
274 | 274 |
} |
275 | 275 |
} |
276 | 276 |
|
277 |
- if err := container.stdout.Clean(); err != nil { |
|
277 |
+ if err := container.StdConfig.stdout.Clean(); err != nil { |
|
278 | 278 |
log.Errorf("%s: Error close stdout: %s", container.ID, err) |
279 | 279 |
} |
280 | 280 |
|
281 |
- if err := container.stderr.Clean(); err != nil { |
|
281 |
+ if err := container.StdConfig.stderr.Clean(); err != nil { |
|
282 | 282 |
log.Errorf("%s: Error close stderr: %s", container.ID, err) |
283 | 283 |
} |
284 | 284 |
|
285 |
- if container.command != nil && container.command.Terminal != nil { |
|
286 |
- if err := container.command.Terminal.Close(); err != nil { |
|
285 |
+ if container.command != nil && container.command.ProcessConfig.Terminal != nil { |
|
286 |
+ if err := container.command.ProcessConfig.Terminal.Close(); err != nil { |
|
287 | 287 |
log.Errorf("%s: Error closing terminal: %s", container.ID, err) |
288 | 288 |
} |
289 | 289 |
} |
290 | 290 |
|
291 | 291 |
// Re-create a brand new stdin pipe once the container exited |
292 | 292 |
if container.Config.OpenStdin { |
293 |
- container.stdin, container.stdinPipe = io.Pipe() |
|
293 |
+ container.StdConfig.stdin, container.StdConfig.stdinPipe = io.Pipe() |
|
294 | 294 |
} |
295 | 295 |
|
296 |
- c := container.command.Cmd |
|
296 |
+ c := container.command.ProcessConfig.Cmd |
|
297 | 297 |
|
298 |
- container.command.Cmd = exec.Cmd{ |
|
298 |
+ container.command.ProcessConfig.Cmd = exec.Cmd{ |
|
299 | 299 |
Stdin: c.Stdin, |
300 | 300 |
Stdout: c.Stdout, |
301 | 301 |
Stderr: c.Stderr, |
... | ... |
@@ -467,7 +467,7 @@ func TestAttachDisconnect(t *testing.T) { |
467 | 467 |
} |
468 | 468 |
|
469 | 469 |
// Try to avoid the timeout in destroy. Best effort, don't check error |
470 |
- cStdin, _ := container.StdinPipe() |
|
470 |
+ cStdin, _ := container.StdConfig.StdinPipe() |
|
471 | 471 |
cStdin.Close() |
472 | 472 |
container.State.WaitStop(-1 * time.Second) |
473 | 473 |
} |
... | ... |
@@ -25,11 +25,11 @@ func TestRestartStdin(t *testing.T) { |
25 | 25 |
} |
26 | 26 |
defer daemon.Destroy(container) |
27 | 27 |
|
28 |
- stdin, err := container.StdinPipe() |
|
28 |
+ stdin, err := container.StdConfig.StdinPipe() |
|
29 | 29 |
if err != nil { |
30 | 30 |
t.Fatal(err) |
31 | 31 |
} |
32 |
- stdout, err := container.StdoutPipe() |
|
32 |
+ stdout, err := container.StdConfig.StdoutPipe() |
|
33 | 33 |
if err != nil { |
34 | 34 |
t.Fatal(err) |
35 | 35 |
} |
... | ... |
@@ -55,11 +55,11 @@ func TestRestartStdin(t *testing.T) { |
55 | 55 |
} |
56 | 56 |
|
57 | 57 |
// Restart and try again |
58 |
- stdin, err = container.StdinPipe() |
|
58 |
+ stdin, err = container.StdConfig.StdinPipe() |
|
59 | 59 |
if err != nil { |
60 | 60 |
t.Fatal(err) |
61 | 61 |
} |
62 |
- stdout, err = container.StdoutPipe() |
|
62 |
+ stdout, err = container.StdConfig.StdoutPipe() |
|
63 | 63 |
if err != nil { |
64 | 64 |
t.Fatal(err) |
65 | 65 |
} |
... | ... |
@@ -101,11 +101,11 @@ func TestStdin(t *testing.T) { |
101 | 101 |
} |
102 | 102 |
defer daemon.Destroy(container) |
103 | 103 |
|
104 |
- stdin, err := container.StdinPipe() |
|
104 |
+ stdin, err := container.StdConfig.StdinPipe() |
|
105 | 105 |
if err != nil { |
106 | 106 |
t.Fatal(err) |
107 | 107 |
} |
108 |
- stdout, err := container.StdoutPipe() |
|
108 |
+ stdout, err := container.StdConfig.StdoutPipe() |
|
109 | 109 |
if err != nil { |
110 | 110 |
t.Fatal(err) |
111 | 111 |
} |
... | ... |
@@ -146,11 +146,11 @@ func TestTty(t *testing.T) { |
146 | 146 |
} |
147 | 147 |
defer daemon.Destroy(container) |
148 | 148 |
|
149 |
- stdin, err := container.StdinPipe() |
|
149 |
+ stdin, err := container.StdConfig.StdinPipe() |
|
150 | 150 |
if err != nil { |
151 | 151 |
t.Fatal(err) |
152 | 152 |
} |
153 |
- stdout, err := container.StdoutPipe() |
|
153 |
+ stdout, err := container.StdConfig.StdoutPipe() |
|
154 | 154 |
if err != nil { |
155 | 155 |
t.Fatal(err) |
156 | 156 |
} |
... | ... |
@@ -611,7 +611,7 @@ func TestRestore(t *testing.T) { |
611 | 611 |
} |
612 | 612 |
|
613 | 613 |
// Simulate a crash/manual quit of dockerd: process dies, states stays 'Running' |
614 |
- cStdin, _ := container2.StdinPipe() |
|
614 |
+ cStdin, _ := container2.StdConfig.StdinPipe() |
|
615 | 615 |
cStdin.Close() |
616 | 616 |
if _, err := container2.State.WaitStop(2 * time.Second); err != nil { |
617 | 617 |
t.Fatal(err) |
... | ... |
@@ -84,11 +84,11 @@ func containerFileExists(eng *engine.Engine, id, dir string, t log.Fataler) bool |
84 | 84 |
|
85 | 85 |
func containerAttach(eng *engine.Engine, id string, t log.Fataler) (io.WriteCloser, io.ReadCloser) { |
86 | 86 |
c := getContainer(eng, id, t) |
87 |
- i, err := c.StdinPipe() |
|
87 |
+ i, err := c.StdConfig.StdinPipe() |
|
88 | 88 |
if err != nil { |
89 | 89 |
t.Fatal(err) |
90 | 90 |
} |
91 |
- o, err := c.StdoutPipe() |
|
91 |
+ o, err := c.StdConfig.StdoutPipe() |
|
92 | 92 |
if err != nil { |
93 | 93 |
t.Fatal(err) |
94 | 94 |
} |
... | ... |
@@ -289,7 +289,7 @@ func runContainer(eng *engine.Engine, r *daemon.Daemon, args []string, t *testin |
289 | 289 |
return "", err |
290 | 290 |
} |
291 | 291 |
defer r.Destroy(container) |
292 |
- stdout, err := container.StdoutPipe() |
|
292 |
+ stdout, err := container.StdConfig.StdoutPipe() |
|
293 | 293 |
if err != nil { |
294 | 294 |
return "", err |
295 | 295 |
} |