| ... | ... |
@@ -22,20 +22,10 @@ import ( |
| 22 | 22 |
func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io.Writer, |
| 23 | 23 |
master *os.File, logFile string, args []string) (int, error) {
|
| 24 | 24 |
var ( |
| 25 |
- console string |
|
| 26 |
- err error |
|
| 27 |
- inPipe io.WriteCloser |
|
| 28 |
- outPipe, errPipe io.ReadCloser |
|
| 25 |
+ console string |
|
| 26 |
+ err error |
|
| 29 | 27 |
) |
| 30 | 28 |
|
| 31 |
- if container.Tty {
|
|
| 32 |
- log.Printf("setting up master and console")
|
|
| 33 |
- master, console, err = CreateMasterAndConsole() |
|
| 34 |
- if err != nil {
|
|
| 35 |
- return -1, err |
|
| 36 |
- } |
|
| 37 |
- } |
|
| 38 |
- |
|
| 39 | 29 |
// create a pipe so that we can syncronize with the namespaced process and |
| 40 | 30 |
// pass the veth name to the child |
| 41 | 31 |
r, w, err := os.Pipe() |
| ... | ... |
@@ -44,16 +34,30 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 44 | 44 |
} |
| 45 | 45 |
system.UsetCloseOnExec(r.Fd()) |
| 46 | 46 |
|
| 47 |
- command := CreateCommand(container, console, logFile, r.Fd(), args) |
|
| 48 |
- if !container.Tty {
|
|
| 49 |
- log.Printf("opening std pipes")
|
|
| 50 |
- if inPipe, err = command.StdinPipe(); err != nil {
|
|
| 47 |
+ if container.Tty {
|
|
| 48 |
+ log.Printf("setting up master and console")
|
|
| 49 |
+ master, console, err = CreateMasterAndConsole() |
|
| 50 |
+ if err != nil {
|
|
| 51 | 51 |
return -1, err |
| 52 | 52 |
} |
| 53 |
- if outPipe, err = command.StdoutPipe(); err != nil {
|
|
| 53 |
+ } |
|
| 54 |
+ |
|
| 55 |
+ command := CreateCommand(container, console, logFile, r.Fd(), args) |
|
| 56 |
+ |
|
| 57 |
+ if container.Tty {
|
|
| 58 |
+ log.Printf("starting copy for tty")
|
|
| 59 |
+ go io.Copy(stdout, master) |
|
| 60 |
+ go io.Copy(master, stdin) |
|
| 61 |
+ |
|
| 62 |
+ state, err := SetupWindow(master, os.Stdin) |
|
| 63 |
+ if err != nil {
|
|
| 64 |
+ command.Process.Kill() |
|
| 54 | 65 |
return -1, err |
| 55 | 66 |
} |
| 56 |
- if errPipe, err = command.StderrPipe(); err != nil {
|
|
| 67 |
+ defer term.RestoreTerminal(os.Stdin.Fd(), state) |
|
| 68 |
+ } else {
|
|
| 69 |
+ if err := startStdCopy(command, stdin, stdout, stderr); err != nil {
|
|
| 70 |
+ command.Process.Kill() |
|
| 57 | 71 |
return -1, err |
| 58 | 72 |
} |
| 59 | 73 |
} |
| ... | ... |
@@ -62,7 +66,7 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 62 | 62 |
if err := command.Start(); err != nil {
|
| 63 | 63 |
return -1, err |
| 64 | 64 |
} |
| 65 |
- log.Printf("writting state file")
|
|
| 65 |
+ log.Printf("writing state file")
|
|
| 66 | 66 |
if err := writePidFile(command); err != nil {
|
| 67 | 67 |
command.Process.Kill() |
| 68 | 68 |
return -1, err |
| ... | ... |
@@ -71,12 +75,9 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 71 | 71 |
|
| 72 | 72 |
// Do this before syncing with child so that no children |
| 73 | 73 |
// can escape the cgroup |
| 74 |
- if container.Cgroups != nil {
|
|
| 75 |
- log.Printf("setting up cgroups")
|
|
| 76 |
- if err := container.Cgroups.Apply(command.Process.Pid); err != nil {
|
|
| 77 |
- command.Process.Kill() |
|
| 78 |
- return -1, err |
|
| 79 |
- } |
|
| 74 |
+ if err := SetupCgroups(container, command.Process.Pid); err != nil {
|
|
| 75 |
+ command.Process.Kill() |
|
| 76 |
+ return -1, err |
|
| 80 | 77 |
} |
| 81 | 78 |
if err := InitializeNetworking(container, command.Process.Pid, w); err != nil {
|
| 82 | 79 |
command.Process.Kill() |
| ... | ... |
@@ -88,27 +89,6 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 88 | 88 |
w.Close() |
| 89 | 89 |
r.Close() |
| 90 | 90 |
|
| 91 |
- if container.Tty {
|
|
| 92 |
- log.Printf("starting copy for tty")
|
|
| 93 |
- go io.Copy(stdout, master) |
|
| 94 |
- go io.Copy(master, stdin) |
|
| 95 |
- |
|
| 96 |
- state, err := SetupWindow(master, os.Stdin) |
|
| 97 |
- if err != nil {
|
|
| 98 |
- command.Process.Kill() |
|
| 99 |
- return -1, err |
|
| 100 |
- } |
|
| 101 |
- defer term.RestoreTerminal(os.Stdin.Fd(), state) |
|
| 102 |
- } else {
|
|
| 103 |
- log.Printf("starting copy for std pipes")
|
|
| 104 |
- go func() {
|
|
| 105 |
- defer inPipe.Close() |
|
| 106 |
- io.Copy(inPipe, stdin) |
|
| 107 |
- }() |
|
| 108 |
- go io.Copy(stdout, outPipe) |
|
| 109 |
- go io.Copy(stderr, errPipe) |
|
| 110 |
- } |
|
| 111 |
- |
|
| 112 | 91 |
log.Printf("waiting on process")
|
| 113 | 92 |
if err := command.Wait(); err != nil {
|
| 114 | 93 |
if _, ok := err.(*exec.ExitError); !ok {
|
| ... | ... |
@@ -119,6 +99,16 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 119 | 119 |
return command.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil |
| 120 | 120 |
} |
| 121 | 121 |
|
| 122 |
+func SetupCgroups(container *libcontainer.Container, nspid int) error {
|
|
| 123 |
+ if container.Cgroups != nil {
|
|
| 124 |
+ log.Printf("setting up cgroups")
|
|
| 125 |
+ if err := container.Cgroups.Apply(nspid); err != nil {
|
|
| 126 |
+ return err |
|
| 127 |
+ } |
|
| 128 |
+ } |
|
| 129 |
+ return nil |
|
| 130 |
+} |
|
| 131 |
+ |
|
| 122 | 132 |
func InitializeNetworking(container *libcontainer.Container, nspid int, pipe io.Writer) error {
|
| 123 | 133 |
if container.Network != nil {
|
| 124 | 134 |
log.Printf("creating host network configuration type %s", container.Network.Type)
|
| ... | ... |
@@ -207,3 +197,29 @@ func CreateCommand(container *libcontainer.Container, console, logFile string, p |
| 207 | 207 |
command.Env = container.Env |
| 208 | 208 |
return command |
| 209 | 209 |
} |
| 210 |
+ |
|
| 211 |
+func startStdCopy(command *exec.Cmd, stdin io.Reader, stdout, stderr io.Writer) error {
|
|
| 212 |
+ log.Printf("opening std pipes")
|
|
| 213 |
+ inPipe, err := command.StdinPipe() |
|
| 214 |
+ if err != nil {
|
|
| 215 |
+ return err |
|
| 216 |
+ } |
|
| 217 |
+ outPipe, err := command.StdoutPipe() |
|
| 218 |
+ if err != nil {
|
|
| 219 |
+ return err |
|
| 220 |
+ } |
|
| 221 |
+ errPipe, err := command.StderrPipe() |
|
| 222 |
+ if err != nil {
|
|
| 223 |
+ return err |
|
| 224 |
+ } |
|
| 225 |
+ |
|
| 226 |
+ log.Printf("starting copy for std pipes")
|
|
| 227 |
+ go func() {
|
|
| 228 |
+ defer inPipe.Close() |
|
| 229 |
+ io.Copy(inPipe, stdin) |
|
| 230 |
+ }() |
|
| 231 |
+ go io.Copy(stdout, outPipe) |
|
| 232 |
+ go io.Copy(stderr, errPipe) |
|
| 233 |
+ |
|
| 234 |
+ return nil |
|
| 235 |
+} |