fix: non-distributable layers may not exist (#1404)

Currently, when pushing an image, validation is performed to check that
a layer/blob in the manifest already exists. For non-distributable
layers, that check needs to be skipped.

Fixes issue #1394

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
This commit is contained in:
Ramkumar Chinchani 2023-05-01 12:49:41 -07:00 committed by GitHub
parent 42df4c505a
commit 86ecbd3926
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 3 deletions

View File

@ -152,10 +152,16 @@ func validateOCIManifest(imgStore ImageStore, repo, reference string, manifest *
}
// validate the layers
for _, l := range manifest.Layers {
_, err := imgStore.GetBlobContent(repo, l.Digest)
for _, layer := range manifest.Layers {
if IsNonDistributable(layer.MediaType) {
log.Warn().Str("digest", layer.Digest.String()).Str("mediaType", layer.MediaType).Msg("not validating layer exists")
continue
}
_, err := imgStore.GetBlobContent(repo, layer.Digest)
if err != nil {
return l.Digest, zerr.ErrBlobNotFound
return layer.Digest, zerr.ErrBlobNotFound
}
}
@ -717,6 +723,12 @@ func IsSupportedMediaType(mediaType string) bool {
mediaType == oras.MediaTypeArtifactManifest
}
func IsNonDistributable(mediaType string) bool {
return mediaType == ispec.MediaTypeImageLayerNonDistributable ||
mediaType == ispec.MediaTypeImageLayerNonDistributableGzip ||
mediaType == ispec.MediaTypeImageLayerNonDistributableZstd
}
// CheckIsImageSignature checks if the given image (repo:tag) represents a signature. The function
// returns:
//

View File

@ -104,6 +104,35 @@ func TestValidateManifest(t *testing.T) {
_, err = imgStore.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, body)
So(err, ShouldNotBeNil)
})
Convey("manifest with non-distributable layers", func() {
content := []byte("this blob doesn't exist")
digest := godigest.FromBytes(content)
So(digest, ShouldNotBeNil)
manifest := ispec.Manifest{
Config: ispec.Descriptor{
MediaType: ispec.MediaTypeImageConfig,
Digest: cdigest,
Size: int64(len(cblob)),
},
Layers: []ispec.Descriptor{
{
MediaType: ispec.MediaTypeImageLayerNonDistributable,
Digest: digest,
Size: int64(len(content)),
},
},
}
manifest.SchemaVersion = 2
body, err := json.Marshal(manifest)
So(err, ShouldBeNil)
_, err = imgStore.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, body)
So(err, ShouldBeNil)
})
})
}