From 4a6cbf9bcb78d38c48ef963f585f0fadf733e101 Mon Sep 17 00:00:00 2001 From: Yuanhong Peng Date: Fri, 7 Jul 2017 15:33:45 +0800 Subject: [PATCH] Return an empty stats if "container not found" If we get "container not found" error from containerd, it's possibly because that this container has already been stopped. It will be ok to ignore this error and just return an empty stats. Signed-off-by: Yuanhong Peng --- daemon/daemon_unix.go | 3 +++ daemon/daemon_windows.go | 3 +++ daemon/errors.go | 12 ++++++++++++ daemon/stats/collector.go | 30 ++++++++++++++++++------------ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index a7ba9c37b2..ff9eadf75b 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -1165,6 +1165,9 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) { } stats, err := daemon.containerd.Stats(c.ID) if err != nil { + if strings.Contains(err.Error(), "container not found") { + return nil, errNotFound{c.ID} + } return nil, err } s := &types.StatsJSON{} diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index bb9c85b80e..798ba39971 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -525,6 +525,9 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) { // Obtain the stats from HCS via libcontainerd stats, err := daemon.containerd.Stats(c.ID) if err != nil { + if strings.Contains(err.Error(), "container not found") { + return nil, errNotFound{c.ID} + } return nil, err } diff --git a/daemon/errors.go b/daemon/errors.go index 96c30df2ea..5050f87e4c 100644 --- a/daemon/errors.go +++ b/daemon/errors.go @@ -39,3 +39,15 @@ func errExecPaused(id string) error { err := fmt.Errorf("Container %s is paused, unpause the container before exec", id) return errors.NewRequestConflictError(err) } + +type errNotFound struct { + containerID string +} + +func (e errNotFound) Error() string { + return fmt.Sprintf("Container %s is not found", e.containerID) +} + +func (e errNotFound) ContainerNotFound() bool { + return true +} diff --git a/daemon/stats/collector.go b/daemon/stats/collector.go index 71bcff446e..0520efa238 100644 --- a/daemon/stats/collector.go +++ b/daemon/stats/collector.go @@ -88,24 +88,25 @@ func (s *Collector) Run() { for _, pair := range pairs { stats, err := s.supervisor.GetContainerStats(pair.container) - if err != nil { - if _, ok := err.(notRunningErr); !ok { - logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err) - continue - } - // publish empty stats containing only name and ID if not running + switch err.(type) { + case nil: + // FIXME: move to containerd on Linux (not Windows) + stats.CPUStats.SystemUsage = systemUsage + stats.CPUStats.OnlineCPUs = onlineCPUs + + pair.publisher.Publish(*stats) + + case notRunningErr, notFoundErr: + // publish empty stats containing only name and ID if not running or not found pair.publisher.Publish(types.StatsJSON{ Name: pair.container.Name, ID: pair.container.ID, }) - continue - } - // FIXME: move to containerd on Linux (not Windows) - stats.CPUStats.SystemUsage = systemUsage - stats.CPUStats.OnlineCPUs = onlineCPUs - pair.publisher.Publish(*stats) + default: + logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err) + } } } } @@ -114,3 +115,8 @@ type notRunningErr interface { error ContainerIsRunning() bool } + +type notFoundErr interface { + error + ContainerNotFound() bool +}