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.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..2c6bc7fb1 100644 --- a/runtime/container_linux.go +++ b/runtime/container_linux.go @@ -284,6 +284,26 @@ func (c *container) Stats() (*Stat, error) { }, nil } +// Status implements the runtime Container interface. +func (c *container) Status() (State, error) { + 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) { 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") } 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 }