2014-02-26 07:19:13 +08:00
|
|
|
// +build linux
|
|
|
|
|
2014-06-05 06:47:57 +08:00
|
|
|
package namespaces
|
2014-02-20 11:53:25 +08:00
|
|
|
|
|
|
|
import (
|
2014-08-07 09:44:41 +08:00
|
|
|
"io"
|
2014-08-05 06:05:50 +08:00
|
|
|
"os"
|
2014-08-07 09:44:41 +08:00
|
|
|
"os/exec"
|
2014-08-05 06:05:50 +08:00
|
|
|
"strconv"
|
2014-08-07 09:44:41 +08:00
|
|
|
"syscall"
|
2014-08-05 06:05:50 +08:00
|
|
|
|
2014-07-17 07:52:15 +08:00
|
|
|
"github.com/docker/libcontainer"
|
|
|
|
"github.com/docker/libcontainer/label"
|
2014-08-07 09:44:41 +08:00
|
|
|
"github.com/docker/libcontainer/syncpipe"
|
2014-07-17 07:52:15 +08:00
|
|
|
"github.com/docker/libcontainer/system"
|
2014-02-20 11:53:25 +08:00
|
|
|
)
|
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
func ExecIn(container *libcontainer.Config, state *libcontainer.State, userArgs []string, initPath string,
|
|
|
|
stdin io.Reader, stdout, stderr io.Writer, console string, startCallback func(*exec.Cmd)) (int, error) {
|
2014-07-17 07:52:15 +08:00
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
args := []string{"--nspid", strconv.Itoa(state.InitPid)}
|
2014-07-03 06:11:15 +08:00
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
if console != "" {
|
|
|
|
args = append(args, "--console", console)
|
2014-02-20 11:53:25 +08:00
|
|
|
}
|
2014-07-17 07:52:15 +08:00
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
args = append(args, "nsenter", "--")
|
|
|
|
args = append(args, userArgs...)
|
2014-05-24 09:06:14 +08:00
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
cmd := exec.Command(initPath, args...)
|
|
|
|
|
|
|
|
pipe, err := syncpipe.NewSyncPipe()
|
2014-07-03 06:11:15 +08:00
|
|
|
if err != nil {
|
2014-08-07 09:44:41 +08:00
|
|
|
return -1, err
|
2014-07-03 06:11:15 +08:00
|
|
|
}
|
2014-08-07 09:44:41 +08:00
|
|
|
defer pipe.Close()
|
2014-07-03 06:11:15 +08:00
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
// Note: these are only used in non-tty mode
|
|
|
|
// if there is a tty for the container it will be opened within the namespace and the
|
|
|
|
// fds will be duped to stdin, stdiout, and stderr
|
|
|
|
cmd.Stdin = stdin
|
|
|
|
cmd.Stdout = stdout
|
|
|
|
cmd.Stderr = stderr
|
|
|
|
|
|
|
|
cmd.ExtraFiles = []*os.File{pipe.Child()}
|
|
|
|
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
|
|
return -1, err
|
2014-07-17 07:52:15 +08:00
|
|
|
}
|
2014-08-07 09:44:41 +08:00
|
|
|
pipe.CloseChild()
|
2014-07-17 07:52:15 +08:00
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
if err := pipe.SendToChild(container); err != nil {
|
|
|
|
cmd.Process.Kill()
|
|
|
|
cmd.Wait()
|
|
|
|
return -1, err
|
2014-07-17 07:52:15 +08:00
|
|
|
}
|
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
if startCallback != nil {
|
|
|
|
startCallback(cmd)
|
2014-07-17 07:52:15 +08:00
|
|
|
}
|
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
if err := cmd.Wait(); err != nil {
|
|
|
|
if _, ok := err.(*exec.ExitError); !ok {
|
|
|
|
return -1, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil
|
2014-07-03 06:11:15 +08:00
|
|
|
}
|
|
|
|
|
2014-08-07 09:44:41 +08:00
|
|
|
// Finalize expects that the setns calls have been setup and that is has joined an
|
|
|
|
// existing namespace
|
|
|
|
func FinalizeSetns(container *libcontainer.Config, args []string) error {
|
|
|
|
// clear the current processes env and replace it with the environment defined on the container
|
2014-06-05 08:54:00 +08:00
|
|
|
if err := LoadContainerEnvironment(container); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2014-08-07 09:44:41 +08:00
|
|
|
|
2014-05-01 08:18:07 +08:00
|
|
|
if err := FinalizeNamespace(container); err != nil {
|
2014-05-24 09:06:14 +08:00
|
|
|
return err
|
2014-02-20 11:53:25 +08:00
|
|
|
}
|
2014-06-17 06:28:28 +08:00
|
|
|
|
2014-06-25 08:31:03 +08:00
|
|
|
if container.ProcessLabel != "" {
|
|
|
|
if err := label.SetProcessLabel(container.ProcessLabel); err != nil {
|
2014-06-17 06:28:28 +08:00
|
|
|
return err
|
|
|
|
}
|
2014-03-19 04:49:16 +08:00
|
|
|
}
|
2014-06-17 06:28:28 +08:00
|
|
|
|
2014-06-05 08:54:00 +08:00
|
|
|
if err := system.Execv(args[0], args[0:], container.Env); err != nil {
|
2014-05-24 09:06:14 +08:00
|
|
|
return err
|
2014-02-20 11:53:25 +08:00
|
|
|
}
|
2014-08-07 09:44:41 +08:00
|
|
|
|
2014-02-20 11:53:25 +08:00
|
|
|
panic("unreachable")
|
|
|
|
}
|