diff --git a/internal/provider/docker/container.go b/internal/provider/docker/container.go index f0e11797..b869a867 100644 --- a/internal/provider/docker/container.go +++ b/internal/provider/docker/container.go @@ -36,14 +36,20 @@ func (c *Client) listContainerImage() []model.Image { var list []model.Image for _, ctn := range ctns { - local, err := cli.IsLocalImage(ctn.Image) + imageRaw, err := cli.RawImage(ctn.Image) if err != nil { c.logger.Error().Err(err).Msgf("Cannot inspect image from container %s", ctn.ID) continue - } else if local { - c.logger.Debug().Msgf("Skip locally built image for container %s", ctn.ID) + } + if local := cli.IsLocalImage(imageRaw); local { + c.logger.Debug().Msgf("Skip locally built image from container %s", ctn.ID) continue } + if dangling := cli.IsDanglingImage(imageRaw); dangling { + c.logger.Debug().Msgf("Skip dangling image from container %s", ctn.ID) + continue + } + image, err := provider.ValidateContainerImage(ctn.Image, ctn.Labels, *c.config.WatchByDefault) if err != nil { c.logger.Error().Err(err).Msgf("Cannot get image from container %s", ctn.ID) diff --git a/internal/provider/swarm/service.go b/internal/provider/swarm/service.go index 09f3f35f..6b465b5f 100644 --- a/internal/provider/swarm/service.go +++ b/internal/provider/swarm/service.go @@ -29,11 +29,17 @@ func (c *Client) listServiceImage() []model.Image { var list []model.Image for _, svc := range svcs { - local, _ := cli.IsLocalImage(svc.Spec.TaskTemplate.ContainerSpec.Image) - if local { - c.logger.Debug().Msgf("Skip locally built image for service %s", svc.Spec.Name) - continue + if imageRaw, err := cli.RawImage(svc.Spec.TaskTemplate.ContainerSpec.Image); err == nil { + if local := cli.IsLocalImage(imageRaw); local { + c.logger.Debug().Msgf("Skip locally built image for service %s", svc.Spec.Name) + continue + } + if dangling := cli.IsDanglingImage(imageRaw); dangling { + c.logger.Debug().Msgf("Skip dangling image for service %s", svc.Spec.Name) + continue + } } + image, err := provider.ValidateContainerImage(svc.Spec.TaskTemplate.ContainerSpec.Image, svc.Spec.Labels, *c.config.WatchByDefault) if err != nil { c.logger.Error().Err(err).Msgf("Cannot get image from service %s", svc.Spec.Name) diff --git a/pkg/docker/image.go b/pkg/docker/image.go index 4bd9a464..40351150 100644 --- a/pkg/docker/image.go +++ b/pkg/docker/image.go @@ -1,10 +1,21 @@ package docker -// IsLocalImage checks if the image has been built locally -func (c *Client) IsLocalImage(image string) (bool, error) { - raw, _, err := c.API.ImageInspectWithRaw(c.ctx, image) - if err != nil { - return false, err - } - return len(raw.RepoDigests) == 0, nil +import "github.com/docker/docker/api/types" + +// RawImage returns the image information and its raw representation +func (c *Client) RawImage(image string) (types.ImageInspect, error) { + imageRaw, _, err := c.API.ImageInspectWithRaw(c.ctx, image) + return imageRaw, err +} + +// IsLocalImage checks if the image has been built locally +func (c *Client) IsLocalImage(image types.ImageInspect) bool { + return len(image.RepoDigests) == 0 +} + +// IsDanglingImage returns whether the given image is "dangling" which means +// that there are no repository references to the given image and it has no +// child images +func (c *Client) IsDanglingImage(image types.ImageInspect) bool { + return len(image.RepoTags) == 1 && image.RepoTags[0] == ":" && len(image.RepoDigests) == 1 && image.RepoDigests[0] == "@" }