@@ -163,18 +163,22 @@ func (r *RepoStore) Exists(ctx context.Context, descriptor v1.Descriptor) (bool,
163163// Push pushes a blob to the in memory repository. If the blob already exists, it returns an error.
164164// Tag is optional and can be empty.
165165func (r * RepoStore ) Push (ctx context.Context , desc v1.Descriptor , tag string , content []byte ) error {
166- exists , err := r .Exists (ctx , desc )
166+ manifestExists , err := r .Exists (ctx , desc )
167167 if err != nil {
168168 return err
169169 }
170- if exists {
171- return nil // No error is returned on push if image is already present
170+
171+ // Verify content by computing the digest. Real registries are expected to do this.
172+ contentDigest := digest .FromBytes (content )
173+ if contentDigest != desc .Digest {
174+ return fmt .Errorf ("content digest %s does not match descriptor digest %s" , contentDigest .String (), desc .Digest .String ())
172175 }
176+
173177 isManifest := false
174178 switch desc .MediaType {
175179 case v1 .MediaTypeImageManifest , images .MediaTypeDockerSchema2Manifest :
176180 isManifest = true
177- if r .opts .ManifestPushIgnoresLayers {
181+ if r .opts .ManifestPushIgnoresLayers || manifestExists {
178182 break // No layer verification necessary
179183 }
180184 manifest := v1.Manifest {}
@@ -185,12 +189,12 @@ func (r *RepoStore) Push(ctx context.Context, desc v1.Descriptor, tag string, co
185189 return err
186190 }
187191 if ! exists {
188- return fmt .Errorf ("Layer %s not found" , layer .Digest .String ())
192+ return fmt .Errorf ("layer %s not found" , layer .Digest .String ())
189193 }
190194 }
191195 case v1 .MediaTypeImageIndex , images .MediaTypeDockerSchema2ManifestList :
192196 isManifest = true
193- if r .opts .ManifestPushIgnoresLayers {
197+ if r .opts .ManifestPushIgnoresLayers || manifestExists {
194198 break // No manifest verification necessary
195199 }
196200 manifestList := v1.Index {}
@@ -201,12 +205,14 @@ func (r *RepoStore) Push(ctx context.Context, desc v1.Descriptor, tag string, co
201205 return err
202206 }
203207 if ! exists {
204- return fmt .Errorf ("Sub manifest %s not found" , subManifestDesc .Digest .String ())
208+ return fmt .Errorf ("sub manifest %s not found" , subManifestDesc .Digest .String ())
205209 }
206210 }
207211 }
208212 r .inmemoryRepo .blobs [desc .Digest .String ()] = content
209213
214+ // We need to always store the manifest digest to tag mapping as the latest pushed manifest
215+ // may have a different digest than the previous one.
210216 if isManifest && tag != "" {
211217 r .inmemoryRepo .tags [tag ] = desc .Digest
212218 }
0 commit comments