From 9d30093505dca0d16469c56855bb5606e85db847 Mon Sep 17 00:00:00 2001 From: HuKeping Date: Fri, 22 Apr 2016 15:49:55 -0400 Subject: [PATCH 1/3] Interface: introduce status to runtime container Signed-off-by: Hu Keping --- runtime/container.go | 3 +++ runtime/container_linux.go | 5 +++++ runtime/container_windows.go | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/runtime/container.go b/runtime/container.go index 2a962890b..6a3db7d33 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -52,6 +52,9 @@ type Container interface { OOM() (OOM, error) // UpdateResource updates the containers resources to new values UpdateResources(*Resource) error + + // Status return the current status of the container. + Status() (State, error) } type OOM interface { diff --git a/runtime/container_linux.go b/runtime/container_linux.go index 5bc5abea4..f573473bb 100644 --- a/runtime/container_linux.go +++ b/runtime/container_linux.go @@ -284,6 +284,11 @@ func (c *container) Stats() (*Stat, error) { }, nil } +// Status implements the runtime Container interface. +func (c *container) Status() (State, error) { + return "running", nil +} + func (c *container) OOM() (OOM, error) { container, err := c.getLibctContainer() if err != nil { diff --git a/runtime/container_windows.go b/runtime/container_windows.go index 47b6b492a..6a354003c 100644 --- a/runtime/container_windows.go +++ b/runtime/container_windows.go @@ -61,6 +61,11 @@ func (c *container) Stats() (*Stat, error) { return nil, errors.New("Stats not yet implemented on Windows") } +// Status implements the runtime Container interface. +func (c *container) Status() (State, error) { + return "", errors.New("Status not yet implemented on Windows") +} + func (c *container) OOM() (OOM, error) { return nil, errors.New("OOM not yet implemented on Windows") } From 40d42a1aac9bac6c0a7a135bcf9c2699a5df9703 Mon Sep 17 00:00:00 2001 From: HuKeping Date: Fri, 22 Apr 2016 17:29:30 -0400 Subject: [PATCH 2/3] Rework function getContainers - Use canonical way to check if a map contains a key. - Use "ci" to keep consistence since it is for "containerInfo". Signed-off-by: Hu Keping --- supervisor/get_containers.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/supervisor/get_containers.go b/supervisor/get_containers.go index 3e24783a8..23f49c789 100644 --- a/supervisor/get_containers.go +++ b/supervisor/get_containers.go @@ -9,16 +9,20 @@ type GetContainersTask struct { } func (s *Supervisor) getContainers(t *GetContainersTask) error { + if t.ID != "" { - ci := s.containers[t.ID] - if ci == nil { + ci, ok := s.containers[t.ID] + if !ok { return ErrContainerNotFound } t.Containers = append(t.Containers, ci.container) + return nil } - for _, i := range s.containers { - t.Containers = append(t.Containers, i.container) + + for _, ci := range s.containers { + t.Containers = append(t.Containers, ci.container) } + return nil } From ca7c5040685a441b011bbb1d3513b241d34be012 Mon Sep 17 00:00:00 2001 From: HuKeping Date: Fri, 22 Apr 2016 17:42:08 -0400 Subject: [PATCH 3/3] Bugfix: ctr container list can not get the proper status of container Prior to this patch, when list containers by "ctr containers" or "ctr containers xxx", it will not get the proper status of conatinser(s). That was caused by the wrong implementation of State() for structure process, it only send a signal "0" to ping the "init" process and do nothing. Since the OCI/runc has implemented an interface Status(), we can use that. And I think this is more compatible with the design for containerd: - containerd -> runtime -> fun() Signed-off-by: Hu Keping --- api/grpc/server/server.go | 6 +++++- runtime/container_linux.go | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/api/grpc/server/server.go b/api/grpc/server/server.go index 1b8736ecc..bc696e7b4 100644 --- a/api/grpc/server/server.go +++ b/api/grpc/server/server.go @@ -146,7 +146,11 @@ func createAPIContainer(c runtime.Container, getPids bool) (*types.Container, er procs = append(procs, appendToProcs) } var pids []int - state := c.State() + state, err := c.Status() + if err != nil { + return nil, grpc.Errorf(codes.Internal, "get status for container: "+err.Error()) + } + if getPids && (state == runtime.Running || state == runtime.Paused) { if pids, err = c.Pids(); err != nil { return nil, grpc.Errorf(codes.Internal, "get all pids for container: "+err.Error()) diff --git a/runtime/container_linux.go b/runtime/container_linux.go index f573473bb..2c6bc7fb1 100644 --- a/runtime/container_linux.go +++ b/runtime/container_linux.go @@ -286,7 +286,22 @@ func (c *container) Stats() (*Stat, error) { // Status implements the runtime Container interface. func (c *container) Status() (State, error) { - return "running", nil + args := c.runtimeArgs + args = append(args, "state", c.id) + + out, err := exec.Command(c.runtime, args...).CombinedOutput() + if err != nil { + return "", fmt.Errorf(string(out)) + } + + // We only require the runtime json output to have a top level Status field. + var s struct { + Status State `json:"status"` + } + if err := json.Unmarshal(out, &s); err != nil { + return "", err + } + return s.Status, nil } func (c *container) OOM() (OOM, error) {