diff --git a/containerd/main.go b/containerd/main.go index 6f238bb..8a78328 100644 --- a/containerd/main.go +++ b/containerd/main.go @@ -48,13 +48,18 @@ var daemonFlags = []cli.Flag{ cli.StringFlag{ Name: "runtime,r", Value: "runc", - Usage: "name of the OCI compliant runtime to use when executing containers", + Usage: "name or path of the OCI compliant runtime to use when executing containers", }, cli.StringSliceFlag{ Name: "runtime-args", Value: &cli.StringSlice{}, Usage: "specify additional runtime args", }, + cli.StringFlag{ + Name: "shim", + Value: "containerd-shim", + Usage: "Name or path of shim", + }, cli.StringFlag{ Name: "pprof-address", Usage: "http address to listen for pprof events", @@ -86,6 +91,7 @@ func main() { 10, context.String("runtime"), context.StringSlice("runtime-args"), + context.String("shim"), context.Duration("start-timeout"), ); err != nil { logrus.Fatal(err) @@ -96,7 +102,7 @@ func main() { } } -func daemon(address, stateDir string, concurrency int, runtimeName string, runtimeArgs []string, timeout time.Duration) error { +func daemon(address, stateDir string, concurrency int, runtimeName string, runtimeArgs []string, shimName string, timeout time.Duration) error { // setup a standard reaper so that we don't leave any zombies if we are still alive // this is just good practice because we are spawning new processes s := make(chan os.Signal, 2048) @@ -104,7 +110,7 @@ func daemon(address, stateDir string, concurrency int, runtimeName string, runti if err := osutils.SetSubreaper(1); err != nil { logrus.WithField("error", err).Error("containerd: set subpreaper") } - sv, err := supervisor.New(stateDir, runtimeName, runtimeArgs, timeout) + sv, err := supervisor.New(stateDir, runtimeName, shimName, runtimeArgs, timeout) if err != nil { return err } diff --git a/runtime/container.go b/runtime/container.go index 0d38ee9..2a96289 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -89,6 +89,7 @@ type ContainerOpts struct { Bundle string Runtime string RuntimeArgs []string + Shim string Labels []string NoPivotRoot bool Timeout time.Duration @@ -104,6 +105,7 @@ func New(opts ContainerOpts) (Container, error) { processes: make(map[string]*process), runtime: opts.Runtime, runtimeArgs: opts.RuntimeArgs, + shim: opts.Shim, noPivotRoot: opts.NoPivotRoot, timeout: opts.Timeout, } @@ -144,6 +146,7 @@ func Load(root, id string) (Container, error) { labels: s.Labels, runtime: s.Runtime, runtimeArgs: s.RuntimeArgs, + shim: s.Shim, noPivotRoot: s.NoPivotRoot, processes: make(map[string]*process), } @@ -190,6 +193,7 @@ type container struct { bundle string runtime string runtimeArgs []string + shim string processes map[string]*process labels []string oomFds []int diff --git a/runtime/container_linux.go b/runtime/container_linux.go index 25fd9a4..e720e6e 100644 --- a/runtime/container_linux.go +++ b/runtime/container_linux.go @@ -17,8 +17,6 @@ import ( ocs "github.com/opencontainers/specs/specs-go" ) -var shimBinary = os.Args[0] + "-shim" - func getRootIDs(s *specs.Spec) (int, int, error) { if s == nil { return 0, 0, nil @@ -145,7 +143,7 @@ func (c *container) Start(checkpoint string, s Stdio) (Process, error) { if err := os.Mkdir(processRoot, 0755); err != nil { return nil, err } - cmd := exec.Command(shimBinary, + cmd := exec.Command(c.shim, c.id, c.bundle, c.runtime, ) cmd.Dir = processRoot @@ -185,7 +183,7 @@ func (c *container) Exec(pid string, pspec specs.ProcessSpec, s Stdio) (pp Proce c.RemoveProcess(pid) } }() - cmd := exec.Command(shimBinary, + cmd := exec.Command(c.shim, c.id, c.bundle, c.runtime, ) cmd.Dir = processRoot @@ -219,7 +217,7 @@ func (c *container) startCmd(pid string, cmd *exec.Cmd, p *process) error { if err := cmd.Start(); err != nil { if exErr, ok := err.(*exec.Error); ok { if exErr.Err == exec.ErrNotFound || exErr.Err == os.ErrNotExist { - return fmt.Errorf("%s not installed on system", shimBinary) + return fmt.Errorf("%s not installed on system", c.shim) } } return err diff --git a/runtime/runtime.go b/runtime/runtime.go index e6d2060..77a0865 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -61,6 +61,7 @@ type state struct { Stderr string `json:"stderr"` Runtime string `json:"runtime"` RuntimeArgs []string `json:"runtimeArgs"` + Shim string `json:"shim"` NoPivotRoot bool `json:"noPivotRoot"` } diff --git a/supervisor/create.go b/supervisor/create.go index 7561fa7..e51fe8d 100644 --- a/supervisor/create.go +++ b/supervisor/create.go @@ -27,6 +27,7 @@ func (s *Supervisor) start(t *StartTask) error { Bundle: t.BundlePath, Runtime: s.runtime, RuntimeArgs: s.runtimeArgs, + Shim: s.shim, Labels: t.Labels, NoPivotRoot: t.NoPivotRoot, Timeout: s.timeout, diff --git a/supervisor/supervisor.go b/supervisor/supervisor.go index c642a18..94b6138 100644 --- a/supervisor/supervisor.go +++ b/supervisor/supervisor.go @@ -18,7 +18,7 @@ const ( ) // New returns an initialized Process supervisor. -func New(stateDir string, runtimeName string, runtimeArgs []string, timeout time.Duration) (*Supervisor, error) { +func New(stateDir string, runtimeName, shimName string, runtimeArgs []string, timeout time.Duration) (*Supervisor, error) { startTasks := make(chan *startTask, 10) if err := os.MkdirAll(stateDir, 0755); err != nil { return nil, err @@ -41,6 +41,7 @@ func New(stateDir string, runtimeName string, runtimeArgs []string, timeout time monitor: monitor, runtime: runtimeName, runtimeArgs: runtimeArgs, + shim: shimName, timeout: timeout, } if err := setupEventLog(s); err != nil { @@ -109,6 +110,7 @@ type Supervisor struct { // name of the OCI compatible runtime used to execute containers runtime string runtimeArgs []string + shim string containers map[string]*containerInfo startTasks chan *startTask // we need a lock around the subscribers map only because additions and deletions from