github.com/dougm/docker@v1.5.0/daemon/execdriver/native/exec.go (about) 1 // +build linux 2 3 package native 4 5 import ( 6 "fmt" 7 "log" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "runtime" 12 13 "github.com/docker/docker/daemon/execdriver" 14 "github.com/docker/docker/pkg/reexec" 15 "github.com/docker/libcontainer" 16 "github.com/docker/libcontainer/namespaces" 17 ) 18 19 const execCommandName = "nsenter-exec" 20 21 func init() { 22 reexec.Register(execCommandName, nsenterExec) 23 } 24 25 func nsenterExec() { 26 runtime.LockOSThread() 27 28 // User args are passed after '--' in the command line. 29 userArgs := findUserArgs() 30 31 config, err := loadConfigFromFd() 32 if err != nil { 33 log.Fatalf("docker-exec: unable to receive config from sync pipe: %s", err) 34 } 35 36 if err := namespaces.FinalizeSetns(config, userArgs); err != nil { 37 log.Fatalf("docker-exec: failed to exec: %s", err) 38 } 39 } 40 41 // TODO(vishh): Add support for running in priviledged mode and running as a different user. 42 func (d *driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) { 43 active := d.activeContainers[c.ID] 44 if active == nil { 45 return -1, fmt.Errorf("No active container exists with ID %s", c.ID) 46 } 47 state, err := libcontainer.GetState(filepath.Join(d.root, c.ID)) 48 if err != nil { 49 return -1, fmt.Errorf("State unavailable for container with ID %s. The container may have been cleaned up already. Error: %s", c.ID, err) 50 } 51 52 var term execdriver.Terminal 53 54 if processConfig.Tty { 55 term, err = NewTtyConsole(processConfig, pipes) 56 } else { 57 term, err = execdriver.NewStdConsole(processConfig, pipes) 58 } 59 60 processConfig.Terminal = term 61 62 args := append([]string{processConfig.Entrypoint}, processConfig.Arguments...) 63 64 return namespaces.ExecIn(active.container, state, args, os.Args[0], "exec", processConfig.Stdin, processConfig.Stdout, processConfig.Stderr, processConfig.Console, 65 func(cmd *exec.Cmd) { 66 if startCallback != nil { 67 startCallback(&c.ProcessConfig, cmd.Process.Pid) 68 } 69 }) 70 }