feat(sync): use regclient for sync extension (#2903)

* feat(sync): use regclient for sync extension

replaced containers/image package with regclient/regclient package

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

* fix(sync): fixed converting innner docker list mediatype

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

* feat(sync): added option to preserve digest

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

* fix(sync): added coverage and various fixes

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

* fix(metadb): fixed converting manifest list not setting platform and annotations

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

* fix(sync): remove read lock on storage, not used concurrently

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

* feat(sync): added cache for repo tags

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

* fix(sync): fixed Makefile
removed opengpg tag

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

* fix(sync): add test for on demand referrer

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>

---------

Signed-off-by: Eusebiu Petu <petu.eusebiu@gmail.com>
This commit is contained in:
peusebiu
2025-04-16 02:58:15 +03:00
committed by GitHub
parent 2592d4c784
commit 0e2aa81439
58 changed files with 2279 additions and 3741 deletions
+4
View File
@@ -512,6 +512,10 @@ func (c *Config) IsSyncEnabled() bool {
return c.Extensions != nil && c.Extensions.Sync != nil && *c.Extensions.Sync.Enable
}
func (c *Config) IsCompatEnabled() bool {
return len(c.HTTP.Compat) > 0
}
func IsOpenIDSupported(provider string) bool {
for _, supportedProvider := range openIDSupportedProviders {
if supportedProvider == provider {
+1 -1
View File
@@ -523,5 +523,5 @@ func (c *Controller) StartBackgroundTasks() {
type SyncOnDemand interface {
SyncImage(ctx context.Context, repo, reference string) error
SyncReference(ctx context.Context, repo string, subjectDigestStr string, referenceType string) error
SyncReferrers(ctx context.Context, repo string, subjectDigestStr string, referenceTypes []string) error
}
+13 -14
View File
@@ -41,7 +41,6 @@ import (
"zotregistry.dev/zot/pkg/debug/pprof"
debug "zotregistry.dev/zot/pkg/debug/swagger"
ext "zotregistry.dev/zot/pkg/extensions"
syncConstants "zotregistry.dev/zot/pkg/extensions/sync/constants"
"zotregistry.dev/zot/pkg/log"
"zotregistry.dev/zot/pkg/meta"
mTypes "zotregistry.dev/zot/pkg/meta/types"
@@ -457,6 +456,9 @@ func (rh *RouteHandler) CheckManifest(response http.ResponseWriter, request *htt
} else if errors.Is(err, zerr.ErrManifestNotFound) {
e := apiErr.NewError(apiErr.MANIFEST_UNKNOWN).AddDetail(details)
zcommon.WriteJSON(response, http.StatusNotFound, apiErr.NewErrorList(e))
} else if errors.Is(err, zerr.ErrSyncParseRemoteRepo) {
e := apiErr.NewError(apiErr.DENIED).AddDetail(details)
zcommon.WriteJSON(response, http.StatusForbidden, apiErr.NewErrorList(e))
} else {
rh.c.Log.Error().Err(err).Msg("unexpected error")
@@ -532,6 +534,9 @@ func (rh *RouteHandler) GetManifest(response http.ResponseWriter, request *http.
details["reference"] = reference
e := apiErr.NewError(apiErr.MANIFEST_UNKNOWN).AddDetail(details)
zcommon.WriteJSON(response, http.StatusNotFound, apiErr.NewErrorList(e))
} else if errors.Is(err, zerr.ErrSyncParseRemoteRepo) {
e := apiErr.NewError(apiErr.DENIED).AddDetail(details)
zcommon.WriteJSON(response, http.StatusForbidden, apiErr.NewErrorList(e))
} else {
rh.c.Log.Error().Err(err).Msg("unexpected error")
response.WriteHeader(http.StatusInternalServerError)
@@ -563,23 +568,17 @@ func getReferrers(ctx context.Context, routeHandler *RouteHandler,
imgStore storageTypes.ImageStore, name string, digest godigest.Digest,
artifactTypes []string,
) (ispec.Index, error) {
refs, err := imgStore.GetReferrers(name, digest, artifactTypes)
if err != nil || len(refs.Manifests) == 0 {
if isSyncOnDemandEnabled(*routeHandler.c) {
routeHandler.c.Log.Info().Str("repository", name).Str("reference", digest.String()).
Msg("referrers not found, trying to get reference by syncing on demand")
if isSyncOnDemandEnabled(*routeHandler.c) {
routeHandler.c.Log.Info().Str("repository", name).Str("reference", digest.String()).
Msg("trying to get updated referrers by syncing on demand")
if errSync := routeHandler.c.SyncOnDemand.SyncReference(ctx, name, digest.String(),
syncConstants.OCI); errSync != nil {
routeHandler.c.Log.Err(errSync).Str("repository", name).Str("reference", digest.String()).
Msg("failed to sync OCI reference for image")
}
refs, err = imgStore.GetReferrers(name, digest, artifactTypes)
if errSync := routeHandler.c.SyncOnDemand.SyncReferrers(ctx, name, digest.String(), artifactTypes); errSync != nil {
routeHandler.c.Log.Err(errSync).Str("repository", name).Str("reference", digest.String()).
Msg("failed to sync image referrers")
}
}
return refs, err
return imgStore.GetReferrers(name, digest, artifactTypes)
}
// GetReferrers godoc