github.com/mheon/docker@v0.11.2-0.20150922122814-44f47903a831/daemon/execdriver/native/exec.go (about) 1 // +build linux 2 3 package native 4 5 import ( 6 "fmt" 7 "os" 8 "os/exec" 9 "syscall" 10 11 "github.com/docker/docker/daemon/execdriver" 12 "github.com/opencontainers/runc/libcontainer" 13 // Blank import 'nsenter' so that init in that package will call c 14 // function 'nsexec()' to do 'setns' before Go runtime take over, 15 // it's used for join to exist ns like 'docker exec' command. 16 _ "github.com/opencontainers/runc/libcontainer/nsenter" 17 "github.com/opencontainers/runc/libcontainer/utils" 18 ) 19 20 // Exec implements the exec driver Driver interface, 21 // it calls libcontainer APIs to execute a container. 22 func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) { 23 active := d.activeContainers[c.ID] 24 if active == nil { 25 return -1, fmt.Errorf("No active container exists with ID %s", c.ID) 26 } 27 28 p := &libcontainer.Process{ 29 Args: append([]string{processConfig.Entrypoint}, processConfig.Arguments...), 30 Env: c.ProcessConfig.Env, 31 Cwd: c.WorkingDir, 32 User: processConfig.User, 33 } 34 35 if processConfig.Privileged { 36 p.Capabilities = execdriver.GetAllCapabilities() 37 } 38 39 config := active.Config() 40 if err := setupPipes(&config, processConfig, p, pipes); err != nil { 41 return -1, err 42 } 43 44 if err := active.Start(p); err != nil { 45 return -1, err 46 } 47 48 if hooks.Start != nil { 49 pid, err := p.Pid() 50 if err != nil { 51 p.Signal(os.Kill) 52 p.Wait() 53 return -1, err 54 } 55 hooks.Start(&c.ProcessConfig, pid) 56 } 57 58 ps, err := p.Wait() 59 if err != nil { 60 exitErr, ok := err.(*exec.ExitError) 61 if !ok { 62 return -1, err 63 } 64 ps = exitErr.ProcessState 65 } 66 return utils.ExitStatus(ps.Sys().(syscall.WaitStatus)), nil 67 }