diff --git a/execution/container.go b/execution/container.go index cf2677d..68b17de 100644 --- a/execution/container.go +++ b/execution/container.go @@ -11,12 +11,12 @@ func NewContainer(stateRoot, id, bundle string) (*Container, error) { id: id, bundle: bundle, stateDir: stateDir, - status: "created", + status: Created, processes: make(map[string]Process), }, nil } -func LoadContainer(dir StateDir, id, bundle, status string, initPid int64) *Container { +func LoadContainer(dir StateDir, id, bundle string, status Status, initPid int64) *Container { return &Container{ id: id, stateDir: dir, @@ -32,7 +32,7 @@ type Container struct { bundle string stateDir StateDir initPid int64 - status string + status Status processes map[string]Process } @@ -41,7 +41,7 @@ func (c *Container) ID() string { return c.id } -func (c *Container) Status() string { +func (c *Container) Status() Status { return c.status } diff --git a/execution/error.go b/execution/error.go new file mode 100644 index 0000000..5d06fc5 --- /dev/null +++ b/execution/error.go @@ -0,0 +1,7 @@ +package execution + +import "fmt" + +var ( + ErrProcessNotFound = fmt.Errorf("process not found") +) diff --git a/execution/executors/oci/oci.go b/execution/executors/oci/oci.go index c389034..98c78e7 100644 --- a/execution/executors/oci/oci.go +++ b/execution/executors/oci/oci.go @@ -113,7 +113,7 @@ func (r *OCIRuntime) load(runcC *runc.Container) (*execution.Container, error) { execution.StateDir(filepath.Join(r.root, runcC.ID)), runcC.ID, runcC.Bundle, - runcC.Status, + execution.Status(runcC.Status), int64(runcC.Pid), ) diff --git a/execution/executors/oci/process.go b/execution/executors/oci/process.go index 3ae61a7..53a4a53 100644 --- a/execution/executors/oci/process.go +++ b/execution/executors/oci/process.go @@ -1,6 +1,7 @@ package oci import ( + "fmt" "os" "syscall" @@ -8,21 +9,27 @@ import ( ) func newProcess(c *execution.Container, id string, pid int) (execution.Process, error) { - proc, err := os.FindProcess(pid) - if err != nil { - return nil, err + status := execution.Running + if err := syscall.Kill(pid, 0); err != nil { + if err == syscall.ESRCH { + status = execution.Stopped + } else { + return nil, err + } } return &process{ - c: c, - id: id, - proc: proc, + c: c, + id: id, + pid: pid, + status: status, }, nil } type process struct { - c *execution.Container - id string - proc *os.Process + c *execution.Container + id string + pid int + status execution.Status } func (p *process) Container() *execution.Container { @@ -34,18 +41,35 @@ func (p *process) ID() string { } func (p *process) Pid() int64 { - return int64(p.proc.Pid) + return int64(p.pid) } func (p *process) Wait() (uint32, error) { - state, err := p.proc.Wait() - if err != nil { - return 0, nil + if p.status == execution.Running { + var wstatus syscall.WaitStatus + _, err := syscall.Wait4(p.pid, &wstatus, 0, nil) + if err != nil { + return 255, nil + } + // TODO: implement kill-all if we are the init pid + p.status = execution.Stopped + return uint32(wstatus.ExitStatus()), nil } - // TODO: implement kill-all if we are the init pid - return uint32(state.Sys().(syscall.WaitStatus).ExitStatus()), nil + + return 255, execution.ErrProcessNotFound } func (p *process) Signal(s os.Signal) error { - return p.proc.Signal(s) + if p.status == execution.Running { + 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 } diff --git a/execution/log.go b/execution/log.go deleted file mode 100644 index 21f55e9..0000000 --- a/execution/log.go +++ /dev/null @@ -1,19 +0,0 @@ -package execution - -import ( - "context" - - "github.com/docker/containerd/log" - "github.com/sirupsen/logrus" -) - -var ctx context.Context - -func GetLogger(module string) *logrus.Entry { - if ctx == nil { - ctx = log.WithModule(context.Background(), "execution") - } - - subCtx := log.WithModule(ctx, module) - return log.GetLogger(subCtx) -} diff --git a/execution/process.go b/execution/process.go index 2f0b1f8..9f365a6 100644 --- a/execution/process.go +++ b/execution/process.go @@ -9,4 +9,5 @@ type Process interface { //Spec() *specs.Process Wait() (uint32, error) Signal(os.Signal) error + Status() Status } diff --git a/execution/service.go b/execution/service.go index c9a6e19..f812183 100644 --- a/execution/service.go +++ b/execution/service.go @@ -13,8 +13,7 @@ import ( ) var ( - emptyResponse = &google_protobuf.Empty{} - ErrProcessNotFound = fmt.Errorf("Process not found") + emptyResponse = &google_protobuf.Empty{} ) func New(executor Executor) (*Service, error) { @@ -24,8 +23,7 @@ func New(executor Executor) (*Service, error) { } type Service struct { - executor Executor - supervisor *Supervisor + executor Executor } func (s *Service) Create(ctx context.Context, r *api.CreateContainerRequest) (*api.CreateContainerResponse, error) { diff --git a/execution/status.go b/execution/status.go index ad8cf68..a6be45a 100644 --- a/execution/status.go +++ b/execution/status.go @@ -3,6 +3,7 @@ package execution type Status string const ( + Created Status = "created" Paused Status = "paused" Running Status = "running" Stopped Status = "stopped"