From 5efb249a86288106f8878144d7aee15d759b1bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Tue, 18 Aug 2020 20:55:35 +0200 Subject: [PATCH] Skip updating containers where no local image info can be retrieved (#612) * Revert "Image of running container no longer needed locally (#571)" This reverts commit 6da66fb3129da691923bea59731733e3f06d30ac. * Update client.go * fix: skip updating when no image info can be retrieved This will allow watchtower to continue even though the image info for a container cannot be retrieved. If this happens one warning will be emitted and the container will be skipped, unless NoRestart or OnlyMonitor is supplied --- internal/actions/update.go | 19 +++++++++++-------- pkg/container/client.go | 8 ++++++-- pkg/container/container.go | 5 +++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/internal/actions/update.go b/internal/actions/update.go index 89aa24543..31a0fa23a 100644 --- a/internal/actions/update.go +++ b/internal/actions/update.go @@ -1,6 +1,7 @@ package actions import ( + "errors" "github.com/containrrr/watchtower/internal/util" "github.com/containrrr/watchtower/pkg/container" "github.com/containrrr/watchtower/pkg/lifecycle" @@ -25,11 +26,13 @@ func Update(client container.Client, params types.UpdateParams) error { return err } - for i, container := range containers { - stale, err := client.IsContainerStale(container) + for i, targetContainer := range containers { + stale, err := client.IsContainerStale(targetContainer) + if stale && !params.NoRestart && !params.MonitorOnly && !targetContainer.HasImageInfo() { + err = errors.New("no available image info") + } if err != nil { - log.Infof("Unable to update container %s. Proceeding to next.", containers[i].Name()) - log.Debug(err) + log.Infof("Unable to update container %q: %v. Proceeding to next.", containers[i].Name(), err) stale = false } containers[i].Stale = stale @@ -89,12 +92,12 @@ func stopStaleContainer(container container.Container, client container.Client, func restartContainersInSortedOrder(containers []container.Container, client container.Client, params types.UpdateParams) { imageIDs := make(map[string]bool) - for _, container := range containers { - if !container.Stale { + for _, staleContainer := range containers { + if !staleContainer.Stale { continue } - restartStaleContainer(container, client, params) - imageIDs[container.ImageID()] = true + restartStaleContainer(staleContainer, client, params) + imageIDs[staleContainer.ImageID()] = true } if params.Cleanup { for imageID := range imageIDs { diff --git a/pkg/container/client.go b/pkg/container/client.go index 5c6e5d6c7..eb0bb5f9d 100644 --- a/pkg/container/client.go +++ b/pkg/container/client.go @@ -119,8 +119,12 @@ func (client dockerClient) GetContainer(containerID string) (Container, error) { return Container{}, err } - container := Container{containerInfo: &containerInfo} - return container, nil + imageInfo, _, err := client.api.ImageInspectWithRaw(bg, containerInfo.Image) + if err != nil { + log.Warnf("Failed to retrieve container image info: %v", err) + } + + return Container{containerInfo: &containerInfo, imageInfo: &imageInfo}, nil } func (client dockerClient) StopContainer(c Container, timeout time.Duration) error { diff --git a/pkg/container/container.go b/pkg/container/container.go index bc2f600bc..50d3bb41f 100644 --- a/pkg/container/container.go +++ b/pkg/container/container.go @@ -221,3 +221,8 @@ func (c Container) hostConfig() *dockercontainer.HostConfig { return hostConfig } + +// HasImageInfo returns whether image information could be retrieved for the container +func (c Container) HasImageInfo() bool { + return c.imageInfo != nil +}