From 3f2d9d19bfab51ff07f940408a197882034120b3 Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Wed, 18 Jan 2017 14:38:32 -0800 Subject: [PATCH] execution: remove oci executor Signed-off-by: Kenfe-Mickael Laventure --- cmd/containerd/main.go | 8 +- execution/executors/oci/console.go | 54 ------- execution/executors/oci/io.go | 53 ------ execution/executors/oci/oci.go | 251 ----------------------------- execution/executors/oci/process.go | 102 ------------ 5 files changed, 1 insertion(+), 467 deletions(-) delete mode 100644 execution/executors/oci/console.go delete mode 100644 execution/executors/oci/io.go delete mode 100644 execution/executors/oci/oci.go delete mode 100644 execution/executors/oci/process.go diff --git a/cmd/containerd/main.go b/cmd/containerd/main.go index 605e0f3..775b364 100644 --- a/cmd/containerd/main.go +++ b/cmd/containerd/main.go @@ -20,7 +20,6 @@ import ( api "github.com/docker/containerd/api/execution" "github.com/docker/containerd/events" "github.com/docker/containerd/execution" - "github.com/docker/containerd/execution/executors/oci" "github.com/docker/containerd/execution/executors/shim" "github.com/docker/containerd/log" metrics "github.com/docker/go-metrics" @@ -57,7 +56,7 @@ high performance container runtime cli.StringFlag{ Name: "runtime", Usage: "runtime for execution", - Value: "runc", + Value: "shim", }, cli.StringFlag{ Name: "socket, s", @@ -119,11 +118,6 @@ high performance container runtime runtime = context.GlobalString("runtime") ) switch runtime { - case "runc": - executor, err = oci.New(context.GlobalString("root")) - if err != nil { - return err - } case "shim": root := filepath.Join(context.GlobalString("root"), "shim") err = os.Mkdir(root, 0700) diff --git a/execution/executors/oci/console.go b/execution/executors/oci/console.go deleted file mode 100644 index 8d34c53..0000000 --- a/execution/executors/oci/console.go +++ /dev/null @@ -1,54 +0,0 @@ -package oci - -import ( - "fmt" - "os" - "syscall" - "unsafe" -) - -// newConsole returns an initialized console that can be used within a container by copying bytes -// from the master side to the slave that is attached as the tty for the container's init process. -func newConsole(uid, gid int) (*os.File, string, error) { - master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0) - if err != nil { - return nil, "", err - } - console, err := ptsname(master) - if err != nil { - return nil, "", err - } - if err := unlockpt(master); err != nil { - return nil, "", err - } - if err := os.Chmod(console, 0600); err != nil { - return nil, "", err - } - if err := os.Chown(console, uid, gid); err != nil { - return nil, "", err - } - return master, console, nil -} - -func ioctl(fd uintptr, flag, data uintptr) error { - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, flag, data); err != 0 { - return err - } - return nil -} - -// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// unlockpt should be called before opening the slave side of a pty. -func unlockpt(f *os.File) error { - var u int32 - return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) -} - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - var n int32 - if err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil { - return "", err - } - return fmt.Sprintf("/dev/pts/%d", n), nil -} diff --git a/execution/executors/oci/io.go b/execution/executors/oci/io.go deleted file mode 100644 index 03b70de..0000000 --- a/execution/executors/oci/io.go +++ /dev/null @@ -1,53 +0,0 @@ -package oci - -import ( - "io" - "os" - - "github.com/crosbymichael/go-runc" -) - -type OIO struct { - master *os.File // master holds a fd to the created pty if any - console string // console holds the path to the slave linked to master - rio runc.IO // rio holds the open fifos for stdios -} - -func newOIO(stdin, stdout, stderr string, console bool) (o OIO, err error) { - defer func() { - if err != nil { - o.cleanup() - } - }() - - if o.rio.Stdin, err = os.OpenFile(stdin, os.O_RDONLY, 0); err != nil { - return - } - if o.rio.Stdout, err = os.OpenFile(stdout, os.O_WRONLY, 0); err != nil { - return - } - if o.rio.Stderr, err = os.OpenFile(stderr, os.O_WRONLY, 0); err != nil { - return - } - - if console { - o.master, o.console, err = newConsole(0, 0) - if err != nil { - return - } - go io.Copy(o.master, o.rio.Stdin) - go func() { - io.Copy(o.rio.Stdout, o.master) - o.master.Close() - }() - } - - return -} - -func (o OIO) cleanup() { - if o.master != nil { - o.master.Close() - } - o.rio.Close() -} diff --git a/execution/executors/oci/oci.go b/execution/executors/oci/oci.go deleted file mode 100644 index 620df49..0000000 --- a/execution/executors/oci/oci.go +++ /dev/null @@ -1,251 +0,0 @@ -package oci - -import ( - "context" - "errors" - "fmt" - "os" - "path/filepath" - "syscall" - - "github.com/crosbymichael/go-runc" - "github.com/docker/containerd/execution" - "github.com/docker/containerd/sys" -) - -const ( - initProcessID = "init" -) - -const ( - PidFilename = "pid" - StartTimeFilename = "starttime" -) - -var ( - ErrRootEmpty = errors.New("oci: runtime root cannot be an empty string") -) - -func New(root string) (*OCIRuntime, error) { - err := sys.SetSubreaper(1) - if err != nil { - return nil, err - } - go func() { - syscall.Wait4(-1, nil, 0, nil) - }() - return &OCIRuntime{ - root: root, - runc: &runc.Runc{ - Root: filepath.Join(root, "runc"), - }, - ios: make(map[string]OIO), - }, nil -} - -type OCIRuntime struct { - root string - runc *runc.Runc - ios map[string]OIO // ios tracks created process io for cleanup purpose on delete -} - -func (r *OCIRuntime) Create(ctx context.Context, id string, o execution.CreateOpts) (container *execution.Container, err error) { - if o.Bundle == "" { - return nil, errors.New("bundle path cannot be an empty string") - } - oio, err := newOIO(o.Stdin, o.Stdout, o.Stderr, o.Console) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - oio.cleanup() - } - }() - - if container, err = execution.NewContainer(r.root, id, o.Bundle); err != nil { - return nil, err - } - defer func(c *execution.Container) { - if err != nil { - c.StateDir().Delete() - } - }(container) - - initStateDir, err := container.StateDir().NewProcess(initProcessID) - if err != nil { - return nil, err - } - pidFile := filepath.Join(initStateDir, PidFilename) - err = r.runc.Create(ctx, id, o.Bundle, &runc.CreateOpts{ - PidFile: pidFile, - Console: oio.console, - IO: oio.rio, - }) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - r.runc.Kill(ctx, id, int(syscall.SIGKILL)) - r.runc.Delete(ctx, id) - } - }() - - process, err := newProcess(initProcessID, initStateDir, execution.Created) - if err != nil { - return nil, err - } - - container.AddProcess(process, true) - - r.ios[id] = oio - - return container, nil -} - -func (r *OCIRuntime) Start(ctx context.Context, c *execution.Container) error { - return r.runc.Start(ctx, c.ID()) -} - -func (r *OCIRuntime) Status(ctx context.Context, c *execution.Container) (execution.Status, error) { - state, err := r.runc.State(ctx, c.ID()) - if err != nil { - return "", err - } - return execution.Status(state.Status), nil -} - -func (r *OCIRuntime) load(runcC *runc.Container) (*execution.Container, error) { - container := execution.LoadContainer( - execution.StateDir(filepath.Join(r.root, runcC.ID)), - runcC.ID, - runcC.Bundle, - execution.Status(runcC.Status), - ) - - dirs, err := container.StateDir().Processes() - if err != nil { - return nil, err - } - for _, d := range dirs { - process, err := newProcess(filepath.Base(d), d, execution.Running) - if err != nil { - return nil, err - } - container.AddProcess(process, process.Pid() == int64(runcC.Pid)) - } - - return container, nil -} - -func (r *OCIRuntime) List(ctx context.Context) ([]*execution.Container, error) { - runcCs, err := r.runc.List(ctx) - if err != nil { - return nil, err - } - - var containers []*execution.Container - for _, c := range runcCs { - select { - case <-ctx.Done(): - return nil, ctx.Err() - default: - container, err := r.load(c) - if err != nil { - return nil, err - } - containers = append(containers, container) - } - } - - return containers, nil -} - -func (r *OCIRuntime) Load(ctx context.Context, id string) (*execution.Container, error) { - runcC, err := r.runc.State(ctx, id) - if err != nil { - return nil, err - } - - return r.load(runcC) -} - -func (r *OCIRuntime) Delete(ctx context.Context, c *execution.Container) error { - id := c.ID() - if err := r.runc.Delete(ctx, id); err != nil { - return err - } - c.StateDir().Delete() - r.ios[id].cleanup() - delete(r.ios, id) - return nil -} - -func (r *OCIRuntime) Pause(ctx context.Context, c *execution.Container) error { - return r.runc.Pause(ctx, c.ID()) -} - -func (r *OCIRuntime) Resume(ctx context.Context, c *execution.Container) error { - return r.runc.Resume(ctx, c.ID()) -} - -func (r *OCIRuntime) StartProcess(ctx context.Context, c *execution.Container, o execution.StartProcessOpts) (p execution.Process, err error) { - oio, err := newOIO(o.Stdin, o.Stdout, o.Stderr, o.Console) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - oio.cleanup() - } - }() - - procStateDir, err := c.StateDir().NewProcess(o.ID) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - c.StateDir().DeleteProcess(o.ID) - } - }() - - pidFile := filepath.Join(procStateDir, PidFilename) - if err := r.runc.Exec(ctx, c.ID(), o.Spec, &runc.ExecOpts{ - PidFile: pidFile, - Detach: false, - Console: oio.console, - Cwd: o.Spec.Cwd, - IO: oio.rio, - }); err != nil { - return nil, err - } - - process, err := newProcess(o.ID, procStateDir, execution.Running) - if err != nil { - return nil, err - } - - c.AddProcess(process, false) - - r.ios[fmt.Sprintf("%s-%s", c.ID(), process.ID())] = oio - - return process, nil -} - -func (r *OCIRuntime) SignalProcess(ctx context.Context, c *execution.Container, id string, sig os.Signal) error { - process := c.GetProcess(id) - if process == nil { - return fmt.Errorf("Make a Process Not Found error") - } - return syscall.Kill(int(process.Pid()), sig.(syscall.Signal)) -} - -func (r *OCIRuntime) DeleteProcess(ctx context.Context, c *execution.Container, id string) error { - ioID := fmt.Sprintf("%s-%s", c.ID(), id) - r.ios[ioID].cleanup() - delete(r.ios, ioID) - c.RemoveProcess(id) - return c.StateDir().DeleteProcess(id) -} diff --git a/execution/executors/oci/process.go b/execution/executors/oci/process.go deleted file mode 100644 index 6e6095d..0000000 --- a/execution/executors/oci/process.go +++ /dev/null @@ -1,102 +0,0 @@ -package oci - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "syscall" - - "github.com/crosbymichael/go-runc" - "github.com/docker/containerd/execution" - starttime "github.com/opencontainers/runc/libcontainer/system" -) - -func newProcess(id, stateDir string, status execution.Status) (execution.Process, error) { - pid, err := runc.ReadPidFile(filepath.Join(stateDir, PidFilename)) - if err != nil { - return nil, err - } - if err := syscall.Kill(pid, 0); err != nil { - if err == syscall.ESRCH { - status = execution.Stopped - } else { - return nil, err - } - } - if status != execution.Stopped { - stime, err := starttime.GetProcessStartTime(pid) - switch { - case os.IsNotExist(err): - status = execution.Stopped - case err != nil: - return nil, err - default: - b, err := ioutil.ReadFile(filepath.Join(stateDir, StartTimeFilename)) - switch { - case os.IsNotExist(err): - err = ioutil.WriteFile(filepath.Join(stateDir, StartTimeFilename), []byte(stime), 0600) - if err != nil { - return nil, err - } - case err != nil: - return nil, err - case string(b) != stime: - status = execution.Stopped - } - } - } - return &process{ - id: id, - pid: pid, - status: status, - exitCode: execution.UnknownStatusCode, - }, nil -} - -type process struct { - id string - pid int - status execution.Status - exitCode uint32 -} - -func (p *process) ID() string { - return p.id -} - -func (p *process) Pid() int64 { - return int64(p.pid) -} - -func (p *process) Wait() (uint32, error) { - if p.status != execution.Stopped { - var wstatus syscall.WaitStatus - _, err := syscall.Wait4(p.pid, &wstatus, 0, nil) - if err != nil { - // This process doesn't belong to us - p.exitCode = execution.UnknownStatusCode - return p.exitCode, nil - } - // TODO: implement kill-all if we are the init pid? - p.status = execution.Stopped - p.exitCode = uint32(wstatus.ExitStatus()) - } - return p.exitCode, nil - -} - -func (p *process) Signal(s os.Signal) error { - if p.status != execution.Stopped { - sig, ok := s.(syscall.Signal) - if !ok { - return fmt.Errorf("invalid signal %v", s) - } - return syscall.Kill(p.pid, sig) - } - return execution.ErrProcessNotFound -} - -func (p *process) Status() execution.Status { - return p.status -}