fix (metadb): make sure metadb statistics are initialized on image download, and minor metadb fixes for Docker v2 manifest compatibility (#3545)

fix: make sure metadb statistics are initialized on image download, and minor metadb fixes for Docker v2 manifest compatibility

Looking into potential causes of https://github.com/project-zot/zot/issues/3163

1. One possible reason is the statistics were not properly initialized in the first place because of (unknown and/or unavoidable) errors on image push.
To workaround this add logic to initialize the statistics on the call to download them.

2. Some images have the download statistics while others dont, one cause could be a bug in the logic handling manifest mediatypes in the search extension.
Add compatibility checks for Docker v2 manifest types in metadb convert functions, and more tests for covering the Docker mediatype use case.

Side fixes:
- Ensure PushedBy Statistics entries are properly initialized in SetRepoReference
- Fix and issue in the image upload test functions, they were uploading docker images with oci mediatypes in call headers

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
This commit is contained in:
Andrei Aaron
2025-11-18 20:56:44 +02:00
committed by GitHub
parent 49c15abf06
commit b7ab9dab16
11 changed files with 849 additions and 38 deletions
+1 -1
View File
@@ -193,7 +193,7 @@ func (img Image) AsDockerImage() Image {
}
img.ManifestDescriptor = ispec.Descriptor{
MediaType: docker.MediaTypeImageConfig,
MediaType: docker.MediaTypeManifest,
Digest: img.digestAlgorithm.FromBytes(manifestBlob),
Size: int64(len(manifestBlob)),
Data: manifestBlob,
+36 -3
View File
@@ -118,8 +118,19 @@ func UploadImage(img Image, baseURL, repo, ref string) error {
}
}
// Use the media type from ManifestDescriptor, or fall back to Manifest.MediaType, or default to OCI
mediaType := img.ManifestDescriptor.MediaType
if mediaType == "" {
mediaType = img.Manifest.MediaType
}
if mediaType == "" {
mediaType = ispec.MediaTypeImageManifest
}
resp, err = resty.R().
SetHeader("Content-type", ispec.MediaTypeImageManifest).
SetHeader("Content-type", mediaType).
SetBody(manifestBlob).
Put(baseURL + "/v2/" + repo + "/manifests/" + ref)
@@ -216,9 +227,20 @@ func UploadImageWithBasicAuth(img Image, baseURL, repo, ref, user, password stri
return err
}
// Use the media type from ManifestDescriptor, or fall back to Manifest.MediaType, or default to OCI
mediaType := img.ManifestDescriptor.MediaType
if mediaType == "" {
mediaType = img.Manifest.MediaType
}
if mediaType == "" {
mediaType = ispec.MediaTypeImageManifest
}
_, err = resty.R().
SetBasicAuth(user, password).
SetHeader("Content-type", "application/vnd.oci.image.manifest.v1+json").
SetHeader("Content-type", mediaType).
SetBody(manifestBlob).
Put(baseURL + "/v2/" + repo + "/manifests/" + ref)
@@ -245,8 +267,19 @@ func UploadMultiarchImage(multiImage MultiarchImage, baseURL string, repo, ref s
}
}
// Use the media type from IndexDescriptor, or fall back to Index.MediaType, or default to OCI
mediaType := multiImage.IndexDescriptor.MediaType
if mediaType == "" {
mediaType = multiImage.Index.MediaType
}
if mediaType == "" {
mediaType = ispec.MediaTypeImageIndex
}
resp, err := resty.R().
SetHeader("Content-type", ispec.MediaTypeImageIndex).
SetHeader("Content-type", mediaType).
SetBody(indexBlob).
Put(baseURL + "/v2/" + repo + "/manifests/" + ref)