daemon/list: Refactor refreshImage
Add context comments and make it a bit more readable.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 68991ae240
)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
fcb68e55fa
commit
6c4121a943
1 changed files with 61 additions and 12 deletions
|
@ -578,21 +578,70 @@ func includeContainerInList(container *container.Snapshot, filter *listContext)
|
|||
return includeContainer
|
||||
}
|
||||
|
||||
// refreshImage checks if the Image ref still points to the correct ID, and updates the ref to the actual ID when it doesn't
|
||||
// refreshImage checks if the Image ref still points to the correct ID, and
|
||||
// updates the ref to the actual ID when it doesn't.
|
||||
// This happens when the image with a reference that was used to create
|
||||
// container was deleted or updated and now resolves to a different ID.
|
||||
//
|
||||
// For example:
|
||||
// $ docker run -d busybox:latest
|
||||
// $ docker ps -a
|
||||
// CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
// b0318bca5aef busybox "sh" 4 seconds ago Exited (0) 3 seconds ago ecstatic_beaver
|
||||
//
|
||||
// After some time, busybox image got updated on the Docker Hub:
|
||||
// $ docker pull busybox:latest
|
||||
//
|
||||
// So now busybox:latest points to a different digest, but that doesn't impact
|
||||
// the ecstatic_beaver container which was still created under an older
|
||||
// version. In this case, it should still point to the original image ID it was
|
||||
// created from.
|
||||
//
|
||||
// $ docker ps -a
|
||||
// CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
// b0318bca5aef 3fbc63216742 "sh" 3 years ago Exited (0) 3 years ago ecstatic_beaver
|
||||
func (daemon *Daemon) refreshImage(ctx context.Context, s *container.Snapshot, filter *listContext) (*types.Container, error) {
|
||||
c := s.Container
|
||||
tmpImage := s.Image // keep the original ref if still valid (hasn't changed)
|
||||
if tmpImage != s.ImageID {
|
||||
img, err := daemon.imageService.GetImage(ctx, tmpImage, imagetypes.GetImageOpts{})
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil || img.ImageID() != s.ImageID {
|
||||
// ref changed, we need to use original ID
|
||||
tmpImage = s.ImageID
|
||||
}
|
||||
|
||||
// s.Image is the image reference passed by the user to create an image
|
||||
// can be a:
|
||||
// - name (like nginx, ubuntu:latest, docker.io/library/busybox:latest),
|
||||
// - truncated ID (abcdef),
|
||||
// - full digest (sha256:abcdef...)
|
||||
//
|
||||
// s.ImageID is the ID of the image that s.Image resolved to at the time
|
||||
// of the container creation. It's always a full digest.
|
||||
|
||||
// If these match, there's nothing to refresh.
|
||||
if s.Image == s.ImageID {
|
||||
return &c, nil
|
||||
}
|
||||
c.Image = tmpImage
|
||||
|
||||
// Check if the image reference still resolves to the same digest.
|
||||
img, err := daemon.imageService.GetImage(ctx, s.Image, imagetypes.GetImageOpts{})
|
||||
|
||||
// If the image is no longer found or can't be resolved for some other
|
||||
// reason. Update the Image to the specific ID of the original image it
|
||||
// resolved to when the container was created.
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
logrus.ErrorKey: err,
|
||||
"containerID": c.ID,
|
||||
"image": s.Image,
|
||||
"imageID": s.ImageID,
|
||||
}).Warn("failed to resolve container image")
|
||||
}
|
||||
c.Image = s.ImageID
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
// Also update the image to the specific image ID, if the Image now
|
||||
// resolves to a different ID.
|
||||
if img.ImageID() != s.ImageID {
|
||||
c.Image = s.ImageID
|
||||
}
|
||||
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue