// startContainer starts the container. Returns the exit status or -1 and an // error. // // Signals sent to the current process will be forwarded to container. func startContainer(container *libcontainer.Config, term namespaces.Terminal, dataPath string, args []string) (int, error) { var ( cmd *exec.Cmd sigc = make(chan os.Signal, 10) ) signal.Notify(sigc) createCommand := func(container *libcontainer.Config, console, rootfs, dataPath, init string, pipe *os.File, args []string) *exec.Cmd { cmd = namespaces.DefaultCreateCommand(container, console, rootfs, dataPath, init, pipe, args) if logPath != "" { cmd.Env = append(cmd.Env, fmt.Sprintf("log=%s", logPath)) } return cmd } startCallback := func() { go func() { for sig := range sigc { cmd.Process.Signal(sig) } }() } return namespaces.Exec(container, term, "", dataPath, args, createCommand, startCallback) }
// start a long-running container so we have time to inspect execin processes func startLongRunningContainer(config *libcontainer.Config) (*exec.Cmd, string, chan error) { containerErr := make(chan error, 1) containerCmd := &exec.Cmd{} var statePath string createCmd := func(container *libcontainer.Config, console, dataPath, init string, pipe *os.File, args []string) *exec.Cmd { containerCmd = namespaces.DefaultCreateCommand(container, console, dataPath, init, pipe, args) statePath = dataPath return containerCmd } var containerStart sync.WaitGroup containerStart.Add(1) go func() { buffers := newStdBuffers() _, err := namespaces.Exec(config, buffers.Stdin, buffers.Stdout, buffers.Stderr, "", config.RootFs, []string{"sleep", "10"}, createCmd, containerStart.Done) containerErr <- err }() containerStart.Wait() return containerCmd, statePath, containerErr }
// startContainer starts the container. Returns the exit status or -1 and an // error. // // Signals sent to the current process will be forwarded to container. func startContainer(container *libcontainer.Config, dataPath string, args []string) (int, error) { var ( cmd *exec.Cmd sigc = make(chan os.Signal, 10) ) signal.Notify(sigc) createCommand := func(container *libcontainer.Config, console, rootfs, dataPath, init string, pipe *os.File, args []string) *exec.Cmd { cmd = namespaces.DefaultCreateCommand(container, console, rootfs, dataPath, init, pipe, args) if logPath != "" { cmd.Env = append(cmd.Env, fmt.Sprintf("log=%s", logPath)) } return cmd } var ( master *os.File console string err error stdin = os.Stdin stdout = os.Stdout stderr = os.Stderr ) if container.Tty { stdin = nil stdout = nil stderr = nil master, console, err = consolepkg.CreateMasterAndConsole() if err != nil { return -1, err } go io.Copy(master, os.Stdin) go io.Copy(os.Stdout, master) state, err := term.SetRawTerminal(os.Stdin.Fd()) if err != nil { return -1, err } defer term.RestoreTerminal(os.Stdin.Fd(), state) } startCallback := func() { go func() { resizeTty(master) for sig := range sigc { switch sig { case syscall.SIGWINCH: resizeTty(master) default: cmd.Process.Signal(sig) } } }() } return namespaces.Exec(container, stdin, stdout, stderr, console, "", dataPath, args, createCommand, startCallback) }