Skip to content

Commit 5488bfe

Browse files
committed
image_pull: repull when image ID (config digest) changed
Signed-off-by: Antonio Murdaca <[email protected]>
1 parent 8a39d94 commit 5488bfe

File tree

2 files changed

+49
-14
lines changed

2 files changed

+49
-14
lines changed

pkg/storage/image.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/containers/image/types"
1818
"github.com/containers/storage"
1919
distreference "github.com/docker/distribution/reference"
20+
digest "github.com/opencontainers/go-digest"
2021
)
2122

2223
// ImageResult wraps a subset of information about an image: its ID, its names,
@@ -25,6 +26,10 @@ type ImageResult struct {
2526
ID string
2627
Names []string
2728
Size *uint64
29+
// TODO(runcom): this is an hack for https://github.com/kubernetes-incubator/cri-o/pull/1136
30+
// drop this when we have proper image IDs (as in, image IDs should be just
31+
// the config blog digest which is stable across same images).
32+
ConfigDigest digest.Digest
2833
}
2934

3035
type indexInfo struct {
@@ -47,6 +52,9 @@ type ImageServer interface {
4752
ListImages(systemContext *types.SystemContext, filter string) ([]ImageResult, error)
4853
// ImageStatus returns status of an image which matches the filter.
4954
ImageStatus(systemContext *types.SystemContext, filter string) (*ImageResult, error)
55+
// PrepareImage returns an Image where the config digest can be grabbed
56+
// for further analysis. Call Close() on the resulting image.
57+
PrepareImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.Image, error)
5058
// PullImage imports an image from the specified location.
5159
PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error)
5260
// RemoveImage deletes the specified image.
@@ -146,14 +154,16 @@ func (svc *imageService) ImageStatus(systemContext *types.SystemContext, nameOrI
146154
if err != nil {
147155
return nil, err
148156
}
157+
defer img.Close()
149158
size := imageSize(img)
150-
img.Close()
151159

152-
return &ImageResult{
153-
ID: image.ID,
154-
Names: image.Names,
155-
Size: size,
156-
}, nil
160+
res := &ImageResult{
161+
ID: image.ID,
162+
Names: image.Names,
163+
Size: size,
164+
ConfigDigest: img.ConfigInfo().Digest,
165+
}
166+
return res, nil
157167
}
158168

159169
func imageSize(img types.Image) *uint64 {
@@ -165,7 +175,7 @@ func imageSize(img types.Image) *uint64 {
165175
}
166176

167177
func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool, error) {
168-
srcRef, err := svc.prepareImage(imageName, options)
178+
srcRef, err := svc.prepareReference(imageName, options)
169179
if err != nil {
170180
return false, err
171181
}
@@ -182,9 +192,9 @@ func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool,
182192
return true, nil
183193
}
184194

185-
// prepareImage creates an image reference from an image string and set options
195+
// prepareReference creates an image reference from an image string and set options
186196
// for the source context
187-
func (svc *imageService) prepareImage(imageName string, options *copy.Options) (types.ImageReference, error) {
197+
func (svc *imageService) prepareReference(imageName string, options *copy.Options) (types.ImageReference, error) {
188198
if imageName == "" {
189199
return nil, storage.ErrNotAnImage
190200
}
@@ -212,6 +222,18 @@ func (svc *imageService) prepareImage(imageName string, options *copy.Options) (
212222
return srcRef, nil
213223
}
214224

225+
func (svc *imageService) PrepareImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.Image, error) {
226+
if options == nil {
227+
options = &copy.Options{}
228+
}
229+
230+
srcRef, err := svc.prepareReference(imageName, options)
231+
if err != nil {
232+
return nil, err
233+
}
234+
return srcRef.NewImage(systemContext)
235+
}
236+
215237
func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error) {
216238
policy, err := signature.DefaultPolicy(systemContext)
217239
if err != nil {
@@ -225,7 +247,7 @@ func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName
225247
options = &copy.Options{}
226248
}
227249

228-
srcRef, err := svc.prepareImage(imageName, options)
250+
srcRef, err := svc.prepareReference(imageName, options)
229251
if err != nil {
230252
return nil, err
231253
}

server/image_pull.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/containers/image/copy"
88
"github.com/containers/image/types"
9+
"github.com/kubernetes-incubator/cri-o/pkg/storage"
910
"github.com/sirupsen/logrus"
1011
"golang.org/x/net/context"
1112
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
6768
}
6869

6970
// let's be smart, docker doesn't repull if image already exists.
70-
_, err = s.StorageImageServer().ImageStatus(s.ImageContext(), img)
71+
var storedImage *storage.ImageResult
72+
storedImage, err = s.StorageImageServer().ImageStatus(s.ImageContext(), img)
7173
if err == nil {
72-
logrus.Debugf("image %s already in store, skipping pull", img)
73-
pulled = img
74-
break
74+
tmpImg, err := s.StorageImageServer().PrepareImage(s.ImageContext(), img, options)
75+
if err == nil {
76+
tmpImgConfigDigest := tmpImg.ConfigInfo().Digest
77+
if tmpImgConfigDigest.String() == "" {
78+
// this means we are playing with a schema1 image, in which
79+
// case, we're going to repull the image in any case
80+
logrus.Debugf("image config digest is empty, re-pulling image")
81+
} else if tmpImgConfigDigest.String() == storedImage.ConfigDigest.String() {
82+
logrus.Debugf("image %s already in store, skipping pull", img)
83+
pulled = img
84+
break
85+
}
86+
}
87+
logrus.Debugf("image in store has different ID, re-pulling %s", img)
7588
}
7689

7790
_, err = s.StorageImageServer().PullImage(s.ImageContext(), img, options)

0 commit comments

Comments
 (0)