Refactor exec method
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
parent
609c298810
commit
c71bc03279
1 changed files with 77 additions and 61 deletions
|
@ -22,20 +22,10 @@ import (
|
|||
func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io.Writer,
|
||||
master *os.File, logFile string, args []string) (int, error) {
|
||||
var (
|
||||
console string
|
||||
err error
|
||||
inPipe io.WriteCloser
|
||||
outPipe, errPipe io.ReadCloser
|
||||
console string
|
||||
err error
|
||||
)
|
||||
|
||||
if container.Tty {
|
||||
log.Printf("setting up master and console")
|
||||
master, console, err = CreateMasterAndConsole()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
// create a pipe so that we can syncronize with the namespaced process and
|
||||
// pass the veth name to the child
|
||||
r, w, err := os.Pipe()
|
||||
|
@ -44,49 +34,15 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io.
|
|||
}
|
||||
system.UsetCloseOnExec(r.Fd())
|
||||
|
||||
if container.Tty {
|
||||
log.Printf("setting up master and console")
|
||||
master, console, err = CreateMasterAndConsole()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
command := CreateCommand(container, console, logFile, r.Fd(), args)
|
||||
if !container.Tty {
|
||||
log.Printf("opening std pipes")
|
||||
if inPipe, err = command.StdinPipe(); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
if outPipe, err = command.StdoutPipe(); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
if errPipe, err = command.StderrPipe(); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("staring init")
|
||||
if err := command.Start(); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
log.Printf("writting state file")
|
||||
if err := writePidFile(command); err != nil {
|
||||
command.Process.Kill()
|
||||
return -1, err
|
||||
}
|
||||
defer deletePidFile()
|
||||
|
||||
// Do this before syncing with child so that no children
|
||||
// can escape the cgroup
|
||||
if container.Cgroups != nil {
|
||||
log.Printf("setting up cgroups")
|
||||
if err := container.Cgroups.Apply(command.Process.Pid); err != nil {
|
||||
command.Process.Kill()
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
if err := InitializeNetworking(container, command.Process.Pid, w); err != nil {
|
||||
command.Process.Kill()
|
||||
return -1, err
|
||||
}
|
||||
|
||||
// Sync with child
|
||||
log.Printf("closing sync pipes")
|
||||
w.Close()
|
||||
r.Close()
|
||||
|
||||
if container.Tty {
|
||||
log.Printf("starting copy for tty")
|
||||
|
@ -100,15 +56,39 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io.
|
|||
}
|
||||
defer term.RestoreTerminal(os.Stdin.Fd(), state)
|
||||
} else {
|
||||
log.Printf("starting copy for std pipes")
|
||||
go func() {
|
||||
defer inPipe.Close()
|
||||
io.Copy(inPipe, stdin)
|
||||
}()
|
||||
go io.Copy(stdout, outPipe)
|
||||
go io.Copy(stderr, errPipe)
|
||||
if err := startStdCopy(command, stdin, stdout, stderr); err != nil {
|
||||
command.Process.Kill()
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("staring init")
|
||||
if err := command.Start(); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
log.Printf("writing state file")
|
||||
if err := writePidFile(command); err != nil {
|
||||
command.Process.Kill()
|
||||
return -1, err
|
||||
}
|
||||
defer deletePidFile()
|
||||
|
||||
// Do this before syncing with child so that no children
|
||||
// can escape the cgroup
|
||||
if err := SetupCgroups(container, command.Process.Pid); err != nil {
|
||||
command.Process.Kill()
|
||||
return -1, err
|
||||
}
|
||||
if err := InitializeNetworking(container, command.Process.Pid, w); err != nil {
|
||||
command.Process.Kill()
|
||||
return -1, err
|
||||
}
|
||||
|
||||
// Sync with child
|
||||
log.Printf("closing sync pipes")
|
||||
w.Close()
|
||||
r.Close()
|
||||
|
||||
log.Printf("waiting on process")
|
||||
if err := command.Wait(); err != nil {
|
||||
if _, ok := err.(*exec.ExitError); !ok {
|
||||
|
@ -119,6 +99,16 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io.
|
|||
return command.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil
|
||||
}
|
||||
|
||||
func SetupCgroups(container *libcontainer.Container, nspid int) error {
|
||||
if container.Cgroups != nil {
|
||||
log.Printf("setting up cgroups")
|
||||
if err := container.Cgroups.Apply(nspid); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func InitializeNetworking(container *libcontainer.Container, nspid int, pipe io.Writer) error {
|
||||
if container.Network != nil {
|
||||
log.Printf("creating host network configuration type %s", container.Network.Type)
|
||||
|
@ -207,3 +197,29 @@ func CreateCommand(container *libcontainer.Container, console, logFile string, p
|
|||
command.Env = container.Env
|
||||
return command
|
||||
}
|
||||
|
||||
func startStdCopy(command *exec.Cmd, stdin io.Reader, stdout, stderr io.Writer) error {
|
||||
log.Printf("opening std pipes")
|
||||
inPipe, err := command.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outPipe, err := command.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
errPipe, err := command.StderrPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("starting copy for std pipes")
|
||||
go func() {
|
||||
defer inPipe.Close()
|
||||
io.Copy(inPipe, stdin)
|
||||
}()
|
||||
go io.Copy(stdout, outPipe)
|
||||
go io.Copy(stderr, errPipe)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue