image_pull: repull when image ID (config digest) changed
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
190650ecca
commit
8611c2dfef
2 changed files with 46 additions and 12 deletions
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/containers/image/types"
|
||||
"github.com/containers/storage"
|
||||
distreference "github.com/docker/distribution/reference"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// ImageResult wraps a subset of information about an image: its ID, its names,
|
||||
|
@ -27,6 +28,10 @@ type ImageResult struct {
|
|||
Digests []string
|
||||
Size *uint64
|
||||
ImageRef string
|
||||
// TODO(runcom): this is an hack for https://github.com/kubernetes-incubator/cri-o/pull/1136
|
||||
// drop this when we have proper image IDs (as in, image IDs should be just
|
||||
// the config blog digest which is stable across same images).
|
||||
ConfigDigest digest.Digest
|
||||
}
|
||||
|
||||
type indexInfo struct {
|
||||
|
@ -49,6 +54,9 @@ type ImageServer interface {
|
|||
ListImages(systemContext *types.SystemContext, filter string) ([]ImageResult, error)
|
||||
// ImageStatus returns status of an image which matches the filter.
|
||||
ImageStatus(systemContext *types.SystemContext, filter string) (*ImageResult, error)
|
||||
// PrepareImage returns an Image where the config digest can be grabbed
|
||||
// for further analysis. Call Close() on the resulting image.
|
||||
PrepareImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.Image, error)
|
||||
// PullImage imports an image from the specified location.
|
||||
PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error)
|
||||
// UntagImage removes a name from the specified image, and if it was
|
||||
|
@ -155,9 +163,10 @@ func (svc *imageService) ImageStatus(systemContext *types.SystemContext, nameOrI
|
|||
img.Close()
|
||||
|
||||
result := ImageResult{
|
||||
ID: image.ID,
|
||||
Names: image.Names,
|
||||
Size: size,
|
||||
ID: image.ID,
|
||||
Names: image.Names,
|
||||
Size: size,
|
||||
ConfigDigest: img.ConfigInfo().Digest,
|
||||
}
|
||||
if len(image.Names) > 0 {
|
||||
result.ImageRef = image.Names[0]
|
||||
|
@ -180,7 +189,7 @@ func imageSize(img types.Image) *uint64 {
|
|||
}
|
||||
|
||||
func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool, error) {
|
||||
srcRef, err := svc.prepareImage(imageName, options)
|
||||
srcRef, err := svc.prepareReference(imageName, options)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -197,9 +206,9 @@ func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool,
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// prepareImage creates an image reference from an image string and set options
|
||||
// prepareReference creates an image reference from an image string and set options
|
||||
// for the source context
|
||||
func (svc *imageService) prepareImage(imageName string, options *copy.Options) (types.ImageReference, error) {
|
||||
func (svc *imageService) prepareReference(imageName string, options *copy.Options) (types.ImageReference, error) {
|
||||
if imageName == "" {
|
||||
return nil, storage.ErrNotAnImage
|
||||
}
|
||||
|
@ -227,6 +236,18 @@ func (svc *imageService) prepareImage(imageName string, options *copy.Options) (
|
|||
return srcRef, nil
|
||||
}
|
||||
|
||||
func (svc *imageService) PrepareImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.Image, error) {
|
||||
if options == nil {
|
||||
options = ©.Options{}
|
||||
}
|
||||
|
||||
srcRef, err := svc.prepareReference(imageName, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return srcRef.NewImage(systemContext)
|
||||
}
|
||||
|
||||
func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error) {
|
||||
policy, err := signature.DefaultPolicy(systemContext)
|
||||
if err != nil {
|
||||
|
@ -240,7 +261,7 @@ func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName
|
|||
options = ©.Options{}
|
||||
}
|
||||
|
||||
srcRef, err := svc.prepareImage(imageName, options)
|
||||
srcRef, err := svc.prepareReference(imageName, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -286,7 +307,7 @@ func (svc *imageService) UntagImage(systemContext *types.SystemContext, nameOrID
|
|||
}
|
||||
|
||||
if nameOrID != img.ID {
|
||||
namedRef, err := svc.prepareImage(nameOrID, ©.Options{})
|
||||
namedRef, err := svc.prepareReference(nameOrID, ©.Options{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/containers/image/copy"
|
||||
"github.com/containers/image/types"
|
||||
"github.com/kubernetes-incubator/cri-o/pkg/storage"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
|
@ -67,11 +68,23 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (*pb.P
|
|||
}
|
||||
|
||||
// let's be smart, docker doesn't repull if image already exists.
|
||||
_, err = s.StorageImageServer().ImageStatus(s.ImageContext(), img)
|
||||
var storedImage *storage.ImageResult
|
||||
storedImage, err = s.StorageImageServer().ImageStatus(s.ImageContext(), img)
|
||||
if err == nil {
|
||||
logrus.Debugf("image %s already in store, skipping pull", img)
|
||||
pulled = img
|
||||
break
|
||||
tmpImg, err := s.StorageImageServer().PrepareImage(s.ImageContext(), img, options)
|
||||
if err == nil {
|
||||
tmpImgConfigDigest := tmpImg.ConfigInfo().Digest
|
||||
if tmpImgConfigDigest.String() == "" {
|
||||
// this means we are playing with a schema1 image, in which
|
||||
// case, we're going to repull the image in any case
|
||||
logrus.Debugf("image config digest is empty, re-pulling image")
|
||||
} else if tmpImgConfigDigest.String() == storedImage.ConfigDigest.String() {
|
||||
logrus.Debugf("image %s already in store, skipping pull", img)
|
||||
pulled = img
|
||||
break
|
||||
}
|
||||
}
|
||||
logrus.Debugf("image in store has different ID, re-pulling %s", img)
|
||||
}
|
||||
|
||||
_, err = s.StorageImageServer().PullImage(s.ImageContext(), img, options)
|
||||
|
|
Loading…
Reference in a new issue