From ad26ef1afc43dd3923d1903dbe62ff88d8dd28c2 Mon Sep 17 00:00:00 2001 From: Doug Davis Date: Thu, 4 Feb 2016 17:58:46 -0800 Subject: [PATCH] Create some util funcs that are common between start and exec and it'll really help my start/create PR when I need to rebase :-) Signed-off-by: Doug Davis --- exec.go | 31 +++++----------------------- start.go | 54 +++++++------------------------------------------ utils.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 73 deletions(-) diff --git a/exec.go b/exec.go index fdfc08e3..5f7c9e7d 100644 --- a/exec.go +++ b/exec.go @@ -9,7 +9,6 @@ import ( "path" "strconv" "strings" - "syscall" "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" @@ -71,39 +70,19 @@ func execProcess(context *cli.Context) (int, error) { if err != nil { return -1, err } + var ( detach = context.Bool("detach") rootfs = container.Config().Rootfs ) - rootuid, err := container.Config().HostUID() - if err != nil { - return -1, err - } + p, err := getProcess(context, path.Dir(rootfs)) if err != nil { return -1, err } - process := newProcess(*p) - tty, err := setupIO(process, rootuid, context.String("console"), p.Terminal, detach) - if err != nil { - return -1, err - } - if err := container.Start(process); err != nil { - return -1, err - } - if pidFile := context.String("pid-file"); pidFile != "" { - if err := createPidFile(pidFile, process); err != nil { - process.Signal(syscall.SIGKILL) - process.Wait() - return -1, err - } - } - if detach { - return 0, nil - } - handler := newSignalHandler(tty) - defer handler.Close() - return handler.forward(process) + + return runProcess(container, p, nil, context.String("console"), context.String("pid-file"), detach) + } func getProcess(context *cli.Context, bundle string) (*specs.Process, error) { diff --git a/start.go b/start.go index 3a31ff8b..6d8238e1 100644 --- a/start.go +++ b/start.go @@ -3,10 +3,8 @@ package main import ( - "fmt" "os" "runtime" - "syscall" "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" @@ -88,61 +86,23 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec) (int, error) { if id == "" { return -1, errEmptyID } - config, err := createLibcontainerConfig(id, spec) - if err != nil { - return -1, err - } - if _, err := os.Stat(config.Rootfs); err != nil { - if os.IsNotExist(err) { - return -1, fmt.Errorf("rootfs (%q) does not exist", config.Rootfs) - } - return -1, err - } - rootuid, err := config.HostUID() - if err != nil { - return -1, err - } - factory, err := loadFactory(context) - if err != nil { - return -1, err - } - container, err := factory.Create(id, config) + container, err := createContainer(context, id, spec) if err != nil { return -1, err } + // ensure that the container is always removed if we were the process // that created it. detach := context.Bool("detach") if !detach { defer destroy(container) } - process := newProcess(spec.Process) + // Support on-demand socket activation by passing file descriptors into the container init process. + listenFDs := []*os.File{} if os.Getenv("LISTEN_FDS") != "" { - listenFds := activation.Files(false) - if len(listenFds) > 0 { - process.Env = append(process.Env, fmt.Sprintf("LISTEN_FDS=%d", len(listenFds)), "LISTEN_PID=1") - process.ExtraFiles = append(process.ExtraFiles, listenFds...) - } + listenFDs = activation.Files(false) } - tty, err := setupIO(process, rootuid, context.String("console"), spec.Process.Terminal, detach) - if err != nil { - return -1, err - } - if err := container.Start(process); err != nil { - return -1, err - } - if pidFile := context.String("pid-file"); pidFile != "" { - if err := createPidFile(pidFile, process); err != nil { - process.Signal(syscall.SIGKILL) - process.Wait() - return -1, err - } - } - if detach { - return 0, nil - } - handler := newSignalHandler(tty) - defer handler.Close() - return handler.forward(process) + + return runProcess(container, &spec.Process, listenFDs, context.String("console"), context.String("pid-file"), detach) } diff --git a/utils.go b/utils.go index 936abb67..159f0d5a 100644 --- a/utils.go +++ b/utils.go @@ -265,3 +265,64 @@ func createPidFile(path string, process *libcontainer.Process) error { _, err = fmt.Fprintf(f, "%d", pid) return err } + +func createContainer(context *cli.Context, id string, spec *specs.LinuxSpec) (libcontainer.Container, error) { + config, err := createLibcontainerConfig(id, spec) + if err != nil { + return nil, err + } + + if _, err := os.Stat(config.Rootfs); err != nil { + if os.IsNotExist(err) { + return nil, fmt.Errorf("rootfs (%q) does not exist", config.Rootfs) + } + return nil, err + } + + factory, err := loadFactory(context) + if err != nil { + return nil, err + } + return factory.Create(id, config) +} + +// runProcess will create a new process in the specified container +// by executing the process specified in the 'config'. +func runProcess(container libcontainer.Container, config *specs.Process, listenFDs []*os.File, console string, pidFile string, detach bool) (int, error) { + process := newProcess(*config) + + // Add extra file descriptors if needed + if len(listenFDs) > 0 { + process.Env = append(process.Env, fmt.Sprintf("LISTEN_FDS=%d", len(listenFDs)), "LISTEN_PID=1") + process.ExtraFiles = append(process.ExtraFiles, listenFDs...) + } + + rootuid, err := container.Config().HostUID() + if err != nil { + return -1, err + } + + tty, err := setupIO(process, rootuid, console, config.Terminal, detach) + if err != nil { + return -1, err + } + + if err := container.Start(process); err != nil { + return -1, err + } + + if pidFile != "" { + if err := createPidFile(pidFile, process); err != nil { + process.Signal(syscall.SIGKILL) + process.Wait() + return -1, err + } + } + if detach { + return 0, nil + } + handler := newSignalHandler(tty) + defer handler.Close() + + return handler.forward(process) +}