// 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 } handler := newSignalHandler(tty) defer handler.Close() if err := container.Start(process); err != nil { if tty != nil { tty.Close() } return -1, err } if pidFile != "" { if err := createPidFile(pidFile, process); err != nil { process.Signal(syscall.SIGKILL) process.Wait() if tty != nil { tty.Close() } return -1, err } } if detach { return 0, nil } return handler.forward(process) }
// runCmdInDir runs the given command inside a container under dir func runCmdInDir(im *schema.ImageManifest, cmd, dir string, jail bool, mounts []*configs.Mount) error { exePath, err := osext.Executable() if err != nil { return fmt.Errorf("error getting path to the current executable: %v", err) } factory, err := libcontainer.New(dir, libcontainer.InitArgs(exePath, "init")) if err != nil { return fmt.Errorf("error creating a container factory: %v", err) } // The containter ID doesn't really matter here... using a UUID containerID := uuid.NewV4().String() var container libcontainer.Container if jail { config := &configs.Config{} if err := json.Unmarshal([]byte(LibcontainerDefaultConfig), config); err != nil { return fmt.Errorf("error unmarshalling default config: %v", err) } config.Rootfs = dir config.Readonlyfs = false container, err = factory.Create(containerID, config) if err != nil { return fmt.Errorf("error creating a container: %v", err) } } else { container, err = factory.Create(containerID, &configs.Config{ Rootfs: dir, Mounts: mounts, Cgroups: &configs.Cgroup{ Name: containerID, Parent: "system", AllowAllDevices: false, AllowedDevices: configs.DefaultAllowedDevices, }, }) if err != nil { return fmt.Errorf("error creating a container: %v", err) } } process := &libcontainer.Process{ Args: strings.Fields(cmd), User: "******", Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, } if im.App != nil { process.Env = util.ACIEnvironmentToList(im.App.Environment) } process.Env = []string{"PATH=/usr/bin:/sbin/:/bin"} if err := container.Start(process); err != nil { return fmt.Errorf("error starting the process inside the container: %v", err) } _, err = process.Wait() if err != nil { return fmt.Errorf("error running the process: %v", err) } if err := container.Destroy(); err != nil { return fmt.Errorf("error destroying the container: %v", err) } return nil }