2023-03-28 12:20:09 -05:00
|
|
|
package meta
|
2023-01-09 15:37:44 -05:00
|
|
|
|
|
|
|
import (
|
2023-11-01 11:16:18 -05:00
|
|
|
"context"
|
|
|
|
|
2023-01-09 15:37:44 -05:00
|
|
|
godigest "github.com/opencontainers/go-digest"
|
2023-10-30 15:06:04 -05:00
|
|
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
2023-01-09 15:37:44 -05:00
|
|
|
|
2023-10-12 20:45:20 -05:00
|
|
|
zcommon "zotregistry.io/zot/pkg/common"
|
2023-01-09 15:37:44 -05:00
|
|
|
"zotregistry.io/zot/pkg/log"
|
2023-07-18 12:27:26 -05:00
|
|
|
mTypes "zotregistry.io/zot/pkg/meta/types"
|
2023-01-09 15:37:44 -05:00
|
|
|
"zotregistry.io/zot/pkg/storage"
|
|
|
|
)
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
// OnUpdateManifest is called when a new manifest is added. It updates metadb according to the type
|
2023-01-09 15:37:44 -05:00
|
|
|
// of image pushed(normal images, signatues, etc.). In care of any errors, it makes sure to keep
|
2023-07-18 12:27:26 -05:00
|
|
|
// consistency between metadb and the image store.
|
2023-11-01 11:16:18 -05:00
|
|
|
func OnUpdateManifest(ctx context.Context, repo, reference, mediaType string, digest godigest.Digest, body []byte,
|
2023-07-18 12:27:26 -05:00
|
|
|
storeController storage.StoreController, metaDB mTypes.MetaDB, log log.Logger,
|
2023-01-09 15:37:44 -05:00
|
|
|
) error {
|
2023-10-12 20:45:20 -05:00
|
|
|
if zcommon.IsReferrersTag(reference) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-03-10 13:37:29 -05:00
|
|
|
imgStore := storeController.GetImageStore(repo)
|
2023-01-09 15:37:44 -05:00
|
|
|
|
2023-11-01 11:16:18 -05:00
|
|
|
err := SetImageMetaFromInput(ctx, repo, reference, mediaType, digest, body,
|
2023-10-30 15:06:04 -05:00
|
|
|
imgStore, metaDB, log)
|
2023-01-09 15:37:44 -05:00
|
|
|
if err != nil {
|
2023-07-31 14:16:09 -05:00
|
|
|
log.Info().Str("tag", reference).Str("repository", repo).Msg("uploading image meta was unsuccessful for tag in repo")
|
2023-01-09 15:37:44 -05:00
|
|
|
|
2023-03-10 13:37:29 -05:00
|
|
|
if err := imgStore.DeleteImageManifest(repo, reference, false); err != nil {
|
2023-04-27 21:44:22 -05:00
|
|
|
log.Error().Err(err).Str("reference", reference).Str("repository", repo).
|
2023-12-08 03:05:02 -05:00
|
|
|
Msg("failed to remove image manifest in repo")
|
2023-01-09 15:37:44 -05:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
// OnDeleteManifest is called when a manifest is deleted. It updates metadb according to the type
|
2023-01-09 15:37:44 -05:00
|
|
|
// of image pushed(normal images, signatues, etc.). In care of any errors, it makes sure to keep
|
2023-07-18 12:27:26 -05:00
|
|
|
// consistency between metadb and the image store.
|
2023-03-10 13:37:29 -05:00
|
|
|
func OnDeleteManifest(repo, reference, mediaType string, digest godigest.Digest, manifestBlob []byte,
|
2023-07-18 12:27:26 -05:00
|
|
|
storeController storage.StoreController, metaDB mTypes.MetaDB, log log.Logger,
|
2023-01-09 15:37:44 -05:00
|
|
|
) error {
|
2023-10-12 20:45:20 -05:00
|
|
|
if zcommon.IsReferrersTag(reference) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-03-10 13:37:29 -05:00
|
|
|
imgStore := storeController.GetImageStore(repo)
|
2023-01-09 15:37:44 -05:00
|
|
|
|
2023-03-10 13:37:29 -05:00
|
|
|
isSignature, signatureType, signedManifestDigest, err := storage.CheckIsImageSignature(repo, manifestBlob,
|
2023-05-15 04:02:23 -05:00
|
|
|
reference)
|
2023-01-09 15:37:44 -05:00
|
|
|
if err != nil {
|
2023-12-08 03:05:02 -05:00
|
|
|
log.Error().Err(err).Msg("failed to check if image is a signature or not")
|
2023-01-09 15:37:44 -05:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
manageRepoMetaSuccessfully := true
|
|
|
|
|
|
|
|
if isSignature {
|
2023-07-18 12:27:26 -05:00
|
|
|
err = metaDB.DeleteSignature(repo, signedManifestDigest, mTypes.SignatureMetadata{
|
2023-01-09 15:37:44 -05:00
|
|
|
SignatureDigest: digest.String(),
|
|
|
|
SignatureType: signatureType,
|
|
|
|
})
|
|
|
|
if err != nil {
|
2023-12-08 03:05:02 -05:00
|
|
|
log.Error().Err(err).Str("component", "metadb").
|
|
|
|
Msg("failed to check if image is a signature or not")
|
2023-01-09 15:37:44 -05:00
|
|
|
manageRepoMetaSuccessfully = false
|
|
|
|
}
|
|
|
|
} else {
|
2023-09-22 13:51:20 -05:00
|
|
|
err = metaDB.RemoveRepoReference(repo, reference, digest)
|
2023-01-09 15:37:44 -05:00
|
|
|
if err != nil {
|
2023-12-08 03:05:02 -05:00
|
|
|
log.Info().Str("component", "metadb").Msg("restoring image store")
|
2023-01-09 15:37:44 -05:00
|
|
|
|
|
|
|
// restore image store
|
2023-05-12 11:32:01 -05:00
|
|
|
_, _, err := imgStore.PutImageManifest(repo, reference, mediaType, manifestBlob)
|
2023-01-09 15:37:44 -05:00
|
|
|
if err != nil {
|
2023-12-08 03:05:02 -05:00
|
|
|
log.Error().Err(err).Str("component", "metadb").
|
|
|
|
Msg("failed to restore manifest to image store, database is not consistent")
|
2023-01-09 15:37:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
manageRepoMetaSuccessfully = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !manageRepoMetaSuccessfully {
|
2023-12-08 03:05:02 -05:00
|
|
|
log.Info().Str("tag", reference).Str("repository", repo).Str("component", "metadb").
|
|
|
|
Msg("failed to delete image meta was unsuccessful for tag in repo")
|
2023-01-09 15:37:44 -05:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// OnDeleteManifest is called when a manifest is downloaded. It increments the download couter on that manifest.
|
2023-10-30 15:06:04 -05:00
|
|
|
func OnGetManifest(name, reference, mediaType string, body []byte,
|
2023-07-18 12:27:26 -05:00
|
|
|
storeController storage.StoreController, metaDB mTypes.MetaDB, log log.Logger,
|
2023-01-09 15:37:44 -05:00
|
|
|
) error {
|
|
|
|
// check if image is a signature
|
2023-05-15 04:02:23 -05:00
|
|
|
isSignature, _, _, err := storage.CheckIsImageSignature(name, body, reference)
|
2023-01-09 15:37:44 -05:00
|
|
|
if err != nil {
|
2023-12-08 03:05:02 -05:00
|
|
|
log.Error().Err(err).Msg("failed to check if manifest is a signature or not")
|
2023-01-09 15:37:44 -05:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-10-30 15:06:04 -05:00
|
|
|
if isSignature || zcommon.IsReferrersTag(reference) {
|
|
|
|
return nil
|
|
|
|
}
|
2023-01-09 15:37:44 -05:00
|
|
|
|
2023-10-30 15:06:04 -05:00
|
|
|
if !(mediaType == v1.MediaTypeImageManifest || mediaType == v1.MediaTypeImageIndex) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-11-01 11:16:18 -05:00
|
|
|
err = metaDB.UpdateStatsOnDownload(name, reference)
|
2023-10-30 15:06:04 -05:00
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Str("repository", name).Str("reference", reference).
|
2023-12-08 03:05:02 -05:00
|
|
|
Msg("failed to update stats on download image")
|
2023-10-30 15:06:04 -05:00
|
|
|
|
|
|
|
return err
|
2023-01-09 15:37:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|