2021-06-08 23:11:18 +03:00
|
|
|
package sync
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2022-12-22 20:19:42 +02:00
|
|
|
"net/url"
|
2021-10-28 12:10:01 +03:00
|
|
|
"os"
|
2022-01-10 18:06:12 +02:00
|
|
|
"sync"
|
|
|
|
"time"
|
2021-06-08 23:11:18 +03:00
|
|
|
|
|
|
|
"github.com/containers/common/pkg/retry"
|
|
|
|
"github.com/containers/image/v5/copy"
|
2022-03-07 10:45:10 +02:00
|
|
|
"github.com/containers/image/v5/signature"
|
|
|
|
"github.com/containers/image/v5/types"
|
2022-12-09 21:38:00 +02:00
|
|
|
"github.com/opencontainers/go-digest"
|
|
|
|
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
2022-10-20 19:39:20 +03:00
|
|
|
|
2022-12-22 20:19:42 +02:00
|
|
|
"zotregistry.io/zot/pkg/common"
|
2023-02-16 08:20:28 +02:00
|
|
|
syncconf "zotregistry.io/zot/pkg/extensions/config/sync"
|
2021-12-04 03:50:58 +00:00
|
|
|
"zotregistry.io/zot/pkg/log"
|
|
|
|
"zotregistry.io/zot/pkg/storage"
|
2021-06-08 23:11:18 +03:00
|
|
|
)
|
|
|
|
|
2022-11-15 08:21:49 +02:00
|
|
|
const (
|
|
|
|
OrasArtifact = "orasArtifact"
|
|
|
|
OCIReference = "ociReference"
|
|
|
|
)
|
|
|
|
|
2022-03-07 10:45:10 +02:00
|
|
|
type syncContextUtils struct {
|
|
|
|
policyCtx *signature.PolicyContext
|
|
|
|
localCtx *types.SystemContext
|
|
|
|
upstreamCtx *types.SystemContext
|
|
|
|
upstreamAddr string
|
|
|
|
copyOptions copy.Options
|
|
|
|
}
|
|
|
|
|
2022-10-05 13:21:14 +03:00
|
|
|
//nolint:gochecknoglobals
|
2022-01-10 18:06:12 +02:00
|
|
|
var demandedImgs demandedImages
|
|
|
|
|
|
|
|
type demandedImages struct {
|
|
|
|
syncedMap sync.Map
|
|
|
|
}
|
|
|
|
|
|
|
|
func (di *demandedImages) loadOrStoreChan(key string, value chan error) (chan error, bool) {
|
|
|
|
val, found := di.syncedMap.LoadOrStore(key, value)
|
|
|
|
errChannel, _ := val.(chan error)
|
|
|
|
|
|
|
|
return errChannel, found
|
|
|
|
}
|
|
|
|
|
2022-03-21 17:37:23 +00:00
|
|
|
func (di *demandedImages) loadOrStoreStr(key, value string) (string, bool) {
|
2022-01-10 18:06:12 +02:00
|
|
|
val, found := di.syncedMap.LoadOrStore(key, value)
|
|
|
|
str, _ := val.(string)
|
|
|
|
|
|
|
|
return str, found
|
|
|
|
}
|
|
|
|
|
|
|
|
func (di *demandedImages) delete(key string) {
|
|
|
|
di.syncedMap.Delete(key)
|
|
|
|
}
|
|
|
|
|
2023-02-16 08:20:28 +02:00
|
|
|
func OneImage(ctx context.Context, cfg syncconf.Config, storeController storage.StoreController,
|
2022-11-15 08:21:49 +02:00
|
|
|
repo, reference string, artifactType string, log log.Logger,
|
2022-03-21 17:37:23 +00:00
|
|
|
) error {
|
2022-01-10 18:06:12 +02:00
|
|
|
// guard against multiple parallel requests
|
2022-10-27 19:39:59 +03:00
|
|
|
demandedImage := fmt.Sprintf("%s:%s", repo, reference)
|
2022-01-10 18:06:12 +02:00
|
|
|
// loadOrStore image-based channel
|
|
|
|
imageChannel, found := demandedImgs.loadOrStoreChan(demandedImage, make(chan error))
|
|
|
|
// if value found wait on channel receive or close
|
|
|
|
if found {
|
|
|
|
log.Info().Msgf("image %s already demanded by another client, waiting on imageChannel", demandedImage)
|
|
|
|
|
|
|
|
err, ok := <-imageChannel
|
|
|
|
// if channel closed exit
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer demandedImgs.delete(demandedImage)
|
|
|
|
defer close(imageChannel)
|
|
|
|
|
2022-11-15 08:21:49 +02:00
|
|
|
go syncOneImage(ctx, imageChannel, cfg, storeController, repo, reference, artifactType, log)
|
2021-06-08 23:11:18 +03:00
|
|
|
|
2022-01-10 18:06:12 +02:00
|
|
|
err, ok := <-imageChannel
|
|
|
|
if !ok {
|
2021-12-07 20:26:26 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-10 18:06:12 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-02-16 08:20:28 +02:00
|
|
|
func syncOneImage(ctx context.Context, imageChannel chan error,
|
|
|
|
cfg syncconf.Config, storeController storage.StoreController,
|
2022-11-15 08:21:49 +02:00
|
|
|
localRepo, reference string, artifactType string, log log.Logger,
|
2022-03-21 17:37:23 +00:00
|
|
|
) {
|
2023-02-16 08:20:28 +02:00
|
|
|
var credentialsFile syncconf.CredentialsFile
|
2022-01-10 18:06:12 +02:00
|
|
|
|
2021-06-08 23:11:18 +03:00
|
|
|
if cfg.CredentialsFile != "" {
|
2021-10-28 12:10:01 +03:00
|
|
|
var err error
|
|
|
|
|
2021-06-08 23:11:18 +03:00
|
|
|
credentialsFile, err = getFileCredentials(cfg.CredentialsFile)
|
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2022-04-21 11:09:08 +03:00
|
|
|
Err(err).Msgf("couldn't get registry credentials from %s", cfg.CredentialsFile)
|
2021-12-13 19:23:31 +00:00
|
|
|
|
2022-01-10 18:06:12 +02:00
|
|
|
imageChannel <- err
|
|
|
|
|
|
|
|
return
|
2021-06-08 23:11:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-28 12:10:01 +03:00
|
|
|
localCtx, policyCtx, err := getLocalContexts(log)
|
|
|
|
if err != nil {
|
2022-01-10 18:06:12 +02:00
|
|
|
imageChannel <- err
|
|
|
|
|
|
|
|
return
|
2021-10-28 12:10:01 +03:00
|
|
|
}
|
|
|
|
|
2021-12-07 20:26:26 +02:00
|
|
|
for _, registryCfg := range cfg.Registries {
|
|
|
|
regCfg := registryCfg
|
2021-06-08 23:11:18 +03:00
|
|
|
if !regCfg.OnDemand {
|
2021-12-29 17:14:56 +02:00
|
|
|
log.Info().Msgf("skipping syncing on demand from %v, onDemand flag is false", regCfg.URLs)
|
2021-12-13 19:23:31 +00:00
|
|
|
|
2021-06-08 23:11:18 +03:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2022-10-22 10:26:14 +03:00
|
|
|
upstreamRepo := localRepo
|
2022-03-10 17:39:11 +02:00
|
|
|
|
2021-10-25 15:05:03 +03:00
|
|
|
// if content config is not specified, then don't filter, just sync demanded image
|
|
|
|
if len(regCfg.Content) != 0 {
|
2022-03-10 17:39:11 +02:00
|
|
|
contentID, err := findRepoMatchingContentID(localRepo, regCfg.Content)
|
|
|
|
if err != nil {
|
2021-12-29 17:14:56 +02:00
|
|
|
log.Info().Msgf("skipping syncing on demand %s from %v registry because it's filtered out by content config",
|
2022-03-10 17:39:11 +02:00
|
|
|
localRepo, regCfg.URLs)
|
2021-12-13 19:23:31 +00:00
|
|
|
|
2021-10-25 15:05:03 +03:00
|
|
|
continue
|
|
|
|
}
|
2022-03-10 17:39:11 +02:00
|
|
|
|
2022-10-22 10:26:14 +03:00
|
|
|
upstreamRepo = getRepoSource(localRepo, regCfg.Content[contentID])
|
2021-10-25 15:05:03 +03:00
|
|
|
}
|
|
|
|
|
2022-01-10 18:06:12 +02:00
|
|
|
retryOptions := &retry.RetryOptions{}
|
|
|
|
|
|
|
|
if regCfg.MaxRetries != nil {
|
|
|
|
retryOptions.MaxRetry = *regCfg.MaxRetries
|
|
|
|
if regCfg.RetryDelay != nil {
|
|
|
|
retryOptions.Delay = *regCfg.RetryDelay
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Info().Msgf("syncing on demand with %v", regCfg.URLs)
|
|
|
|
|
|
|
|
for _, regCfgURL := range regCfg.URLs {
|
|
|
|
upstreamURL := regCfgURL
|
2021-06-08 23:11:18 +03:00
|
|
|
|
2021-12-29 17:14:56 +02:00
|
|
|
upstreamAddr := StripRegistryTransport(upstreamURL)
|
2021-06-08 23:11:18 +03:00
|
|
|
|
2022-12-22 20:19:42 +02:00
|
|
|
var TLSverify bool
|
|
|
|
|
|
|
|
if regCfg.TLSVerify != nil && *regCfg.TLSVerify {
|
|
|
|
TLSverify = true
|
|
|
|
}
|
|
|
|
|
|
|
|
registryURL, err := url.Parse(upstreamURL)
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
|
|
|
Err(err).Str("url", upstreamURL).Msg("couldn't parse url")
|
|
|
|
imageChannel <- err
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
httpClient, err := common.CreateHTTPClient(TLSverify, registryURL.Host, regCfg.CertDir)
|
2021-12-29 17:14:56 +02:00
|
|
|
if err != nil {
|
2022-01-10 18:06:12 +02:00
|
|
|
imageChannel <- err
|
2021-06-08 23:11:18 +03:00
|
|
|
|
2022-01-10 18:06:12 +02:00
|
|
|
return
|
2021-12-29 17:14:56 +02:00
|
|
|
}
|
2021-12-13 19:23:31 +00:00
|
|
|
|
2022-12-22 20:19:42 +02:00
|
|
|
sig := newSignaturesCopier(httpClient, credentialsFile[upstreamAddr], *registryURL, storeController, log)
|
2022-10-22 10:26:14 +03:00
|
|
|
|
2022-03-07 10:45:10 +02:00
|
|
|
upstreamCtx := getUpstreamContext(®Cfg, credentialsFile[upstreamAddr])
|
|
|
|
options := getCopyOptions(upstreamCtx, localCtx)
|
|
|
|
|
2022-11-15 08:21:49 +02:00
|
|
|
/* demanded object is a signature or artifact
|
|
|
|
at tis point we already have images synced, but not their signatures. */
|
|
|
|
if isCosignTag(reference) || artifactType != "" {
|
|
|
|
err = syncSignaturesArtifacts(sig, localRepo, upstreamRepo, reference, artifactType)
|
2022-03-07 10:45:10 +02:00
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
imageChannel <- nil
|
2022-01-10 18:06:12 +02:00
|
|
|
|
|
|
|
return
|
2021-12-29 17:14:56 +02:00
|
|
|
}
|
2021-06-08 23:11:18 +03:00
|
|
|
|
2022-03-07 10:45:10 +02:00
|
|
|
syncContextUtils := syncContextUtils{
|
|
|
|
policyCtx: policyCtx,
|
|
|
|
localCtx: localCtx,
|
|
|
|
upstreamCtx: upstreamCtx,
|
|
|
|
upstreamAddr: upstreamAddr,
|
|
|
|
copyOptions: options,
|
2022-01-10 18:06:12 +02:00
|
|
|
}
|
2022-11-22 20:29:57 +02:00
|
|
|
//nolint:contextcheck
|
2022-10-27 19:39:59 +03:00
|
|
|
skipped, copyErr := syncRun(regCfg, localRepo, upstreamRepo, reference, syncContextUtils, sig, log)
|
2022-03-07 10:45:10 +02:00
|
|
|
if skipped {
|
|
|
|
continue
|
|
|
|
}
|
2021-10-28 12:10:01 +03:00
|
|
|
|
2022-03-07 10:45:10 +02:00
|
|
|
// key used to check if we already have a go routine syncing this image
|
2022-10-27 19:39:59 +03:00
|
|
|
demandedImageRef := fmt.Sprintf("%s/%s:%s", upstreamAddr, upstreamRepo, reference)
|
2022-01-10 18:06:12 +02:00
|
|
|
|
|
|
|
if copyErr != nil {
|
2022-03-07 10:45:10 +02:00
|
|
|
// don't retry in background if maxretry is 0
|
|
|
|
if retryOptions.MaxRetry == 0 {
|
|
|
|
continue
|
|
|
|
}
|
2022-01-10 18:06:12 +02:00
|
|
|
|
|
|
|
_, found := demandedImgs.loadOrStoreStr(demandedImageRef, "")
|
2022-03-07 10:45:10 +02:00
|
|
|
if found {
|
|
|
|
log.Info().Msgf("image %s already demanded in background", demandedImageRef)
|
2022-01-10 18:06:12 +02:00
|
|
|
/* we already have a go routine spawned for this image
|
|
|
|
or retryOptions is not configured */
|
|
|
|
continue
|
2021-12-29 17:14:56 +02:00
|
|
|
}
|
2021-12-07 20:26:26 +02:00
|
|
|
|
2022-01-10 18:06:12 +02:00
|
|
|
// spawn goroutine to later pull the image
|
|
|
|
go func() {
|
|
|
|
// remove image after syncing
|
|
|
|
defer func() {
|
|
|
|
demandedImgs.delete(demandedImageRef)
|
|
|
|
log.Info().Msgf("sync routine: %s exited", demandedImageRef)
|
|
|
|
}()
|
|
|
|
|
|
|
|
log.Info().Msgf("sync routine: starting routine to copy image %s, cause err: %v",
|
|
|
|
demandedImageRef, copyErr)
|
|
|
|
time.Sleep(retryOptions.Delay)
|
|
|
|
|
2022-11-08 00:38:16 -08:00
|
|
|
if err = retry.RetryIfNecessary(ctx, func() error {
|
2022-10-27 19:39:59 +03:00
|
|
|
_, err := syncRun(regCfg, localRepo, upstreamRepo, reference, syncContextUtils, sig, log)
|
2022-01-10 18:06:12 +02:00
|
|
|
|
|
|
|
return err
|
|
|
|
}, retryOptions); err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2022-04-21 11:09:08 +03:00
|
|
|
Err(err).Msgf("sync routine: error while copying image %s", demandedImageRef)
|
2022-01-10 18:06:12 +02:00
|
|
|
}
|
|
|
|
}()
|
2022-10-27 19:39:59 +03:00
|
|
|
} else {
|
|
|
|
imageChannel <- nil
|
|
|
|
|
|
|
|
return
|
2021-12-07 20:26:26 +02:00
|
|
|
}
|
2021-06-08 23:11:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-07 10:45:10 +02:00
|
|
|
imageChannel <- nil
|
2022-01-10 18:06:12 +02:00
|
|
|
}
|
|
|
|
|
2023-02-16 08:20:28 +02:00
|
|
|
func syncRun(regCfg syncconf.RegistryConfig,
|
2022-10-27 19:39:59 +03:00
|
|
|
localRepo, upstreamRepo, reference string, utils syncContextUtils, sig *signaturesCopier,
|
2022-03-21 17:37:23 +00:00
|
|
|
log log.Logger,
|
|
|
|
) (bool, error) {
|
2022-12-09 21:38:00 +02:00
|
|
|
upstreamImageDigest, refIsDigest := parseReference(reference)
|
2022-10-27 19:39:59 +03:00
|
|
|
|
|
|
|
upstreamImageRef, err := getImageRef(utils.upstreamAddr, upstreamRepo, reference)
|
2022-03-07 10:45:10 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2022-04-21 11:09:08 +03:00
|
|
|
Err(err).Msgf("error creating docker reference for repository %s/%s:%s",
|
2022-10-27 19:39:59 +03:00
|
|
|
utils.upstreamAddr, upstreamRepo, reference)
|
2022-03-07 10:45:10 +02:00
|
|
|
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2022-12-09 21:38:00 +02:00
|
|
|
manifestBuf, mediaType, err := getImageRefManifest(context.Background(), utils.upstreamCtx, upstreamImageRef, log)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2022-10-27 19:39:59 +03:00
|
|
|
if !refIsDigest {
|
2022-12-09 21:38:00 +02:00
|
|
|
upstreamImageDigest = digest.FromBytes(manifestBuf)
|
|
|
|
}
|
2022-03-07 10:45:10 +02:00
|
|
|
|
2022-12-09 21:38:00 +02:00
|
|
|
if !isSupportedMediaType(mediaType) {
|
|
|
|
if mediaType == ispec.MediaTypeArtifactManifest {
|
|
|
|
err = sig.syncOCIArtifact(localRepo, upstreamRepo, reference, manifestBuf)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
2022-10-27 19:39:59 +03:00
|
|
|
}
|
2022-12-09 21:38:00 +02:00
|
|
|
|
|
|
|
return false, nil
|
2022-03-07 10:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// get upstream signatures
|
2022-10-22 10:26:14 +03:00
|
|
|
cosignManifest, err := sig.getCosignManifest(upstreamRepo, upstreamImageDigest.String())
|
2022-03-07 10:45:10 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2022-04-21 11:09:08 +03:00
|
|
|
Err(err).Msgf("couldn't get upstream image %s cosign manifest", upstreamImageRef.DockerReference())
|
2022-03-07 10:45:10 +02:00
|
|
|
}
|
|
|
|
|
2023-02-13 20:43:52 +02:00
|
|
|
index, err := sig.getOCIRefs(upstreamRepo, upstreamImageDigest.String())
|
2022-03-07 10:45:10 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2023-02-13 20:43:52 +02:00
|
|
|
Err(err).Msgf("couldn't get upstream image %s OCI references", upstreamImageRef.DockerReference())
|
2022-03-07 10:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// check if upstream image is signed
|
2023-02-13 20:43:52 +02:00
|
|
|
if cosignManifest == nil && len(getNotationManifestsFromOCIRefs(index)) == 0 {
|
2022-03-07 10:45:10 +02:00
|
|
|
// upstream image not signed
|
|
|
|
if regCfg.OnlySigned != nil && *regCfg.OnlySigned {
|
|
|
|
// skip unsigned images
|
|
|
|
log.Info().Msgf("skipping image without signature %s", upstreamImageRef.DockerReference())
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-22 10:26:14 +03:00
|
|
|
imageStore := sig.storeController.GetImageStore(localRepo)
|
|
|
|
|
|
|
|
localCachePath, err := getLocalCachePath(imageStore, localRepo)
|
2022-04-05 18:18:31 +03:00
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msgf("couldn't get localCachePath for %s", localRepo)
|
|
|
|
}
|
|
|
|
|
2022-10-27 19:39:59 +03:00
|
|
|
localImageRef, err := getLocalImageRef(localCachePath, localRepo, reference)
|
2022-03-07 10:45:10 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2022-04-21 11:09:08 +03:00
|
|
|
Err(err).Msgf("couldn't obtain a valid image reference for reference %s/%s:%s",
|
2022-10-27 19:39:59 +03:00
|
|
|
localCachePath, localRepo, reference)
|
2022-03-07 10:45:10 +02:00
|
|
|
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer os.RemoveAll(localCachePath)
|
|
|
|
|
|
|
|
log.Info().Msgf("copying image %s to %s", upstreamImageRef.DockerReference(), localCachePath)
|
|
|
|
|
|
|
|
_, err = copy.Image(context.Background(), utils.policyCtx, localImageRef, upstreamImageRef, &utils.copyOptions)
|
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2022-04-21 11:09:08 +03:00
|
|
|
Err(err).Msgf("error encountered while syncing on demand %s to %s",
|
2022-03-07 10:45:10 +02:00
|
|
|
upstreamImageRef.DockerReference(), localCachePath)
|
|
|
|
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2022-10-27 19:39:59 +03:00
|
|
|
err = pushSyncedLocalImage(localRepo, reference, localCachePath, imageStore, log)
|
2022-01-10 18:06:12 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2022-04-21 11:09:08 +03:00
|
|
|
Err(err).Msgf("error while pushing synced cached image %s",
|
2022-10-27 19:39:59 +03:00
|
|
|
fmt.Sprintf("%s/%s:%s", localCachePath, localRepo, reference))
|
2022-01-10 18:06:12 +02:00
|
|
|
|
2022-03-07 10:45:10 +02:00
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2022-11-15 08:21:49 +02:00
|
|
|
err = sig.syncOCIRefs(localRepo, upstreamRepo, upstreamImageDigest.String(), index)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2022-10-22 10:26:14 +03:00
|
|
|
err = sig.syncCosignSignature(localRepo, upstreamRepo, upstreamImageDigest.String(), cosignManifest)
|
2022-03-07 10:45:10 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2022-10-27 19:39:59 +03:00
|
|
|
Err(err).Msgf("couldn't copy image cosign signature %s/%s:%s", utils.upstreamAddr, upstreamRepo, reference)
|
2022-03-07 10:45:10 +02:00
|
|
|
|
|
|
|
return false, err
|
2022-01-10 18:06:12 +02:00
|
|
|
}
|
|
|
|
|
2023-02-13 20:43:52 +02:00
|
|
|
refs, err := sig.getORASRefs(upstreamRepo, upstreamImageDigest.String())
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
|
|
|
Err(err).Msgf("couldn't get upstream image %s ORAS references", upstreamImageRef.DockerReference())
|
|
|
|
}
|
|
|
|
|
|
|
|
err = sig.syncORASRefs(localRepo, upstreamRepo, upstreamImageDigest.String(), refs)
|
2022-03-07 10:45:10 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
log.Error().Str("errorType", common.TypeOf(err)).
|
2023-02-13 20:43:52 +02:00
|
|
|
Err(err).Msgf("couldn't copy image ORAS references %s/%s:%s", utils.upstreamAddr, upstreamRepo, reference)
|
2022-01-10 18:06:12 +02:00
|
|
|
|
2022-03-07 10:45:10 +02:00
|
|
|
return false, err
|
2022-01-10 18:06:12 +02:00
|
|
|
}
|
|
|
|
|
2022-10-27 19:39:59 +03:00
|
|
|
log.Info().Msgf("successfully synced %s/%s:%s", utils.upstreamAddr, upstreamRepo, reference)
|
2022-01-10 18:06:12 +02:00
|
|
|
|
2022-03-07 10:45:10 +02:00
|
|
|
return false, nil
|
2021-06-08 23:11:18 +03:00
|
|
|
}
|
2022-11-15 08:21:49 +02:00
|
|
|
|
|
|
|
func syncSignaturesArtifacts(sig *signaturesCopier, localRepo, upstreamRepo, reference, artifactType string) error {
|
|
|
|
upstreamURL := sig.upstreamURL.String()
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case isCosignTag(reference):
|
|
|
|
// is cosign signature
|
|
|
|
cosignManifest, err := sig.getCosignManifest(upstreamRepo, reference)
|
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
sig.log.Error().Str("errorType", common.TypeOf(err)).
|
2022-11-15 08:21:49 +02:00
|
|
|
Err(err).Msgf("couldn't get upstream image %s:%s:%s cosign manifest", upstreamURL, upstreamRepo, reference)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = sig.syncCosignSignature(localRepo, upstreamRepo, reference, cosignManifest)
|
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
sig.log.Error().Str("errorType", common.TypeOf(err)).
|
2022-11-15 08:21:49 +02:00
|
|
|
Err(err).Msgf("couldn't copy upstream image cosign signature %s/%s:%s", upstreamURL, upstreamRepo, reference)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
case artifactType == OrasArtifact:
|
2023-02-13 20:43:52 +02:00
|
|
|
// is oras artifact
|
|
|
|
refs, err := sig.getORASRefs(upstreamRepo, reference)
|
2022-11-15 08:21:49 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
sig.log.Error().Str("errorType", common.TypeOf(err)).
|
2023-02-13 20:43:52 +02:00
|
|
|
Err(err).Msgf("couldn't get upstream image %s/%s:%s ORAS references", upstreamURL, upstreamRepo, reference)
|
2022-11-15 08:21:49 +02:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-02-13 20:43:52 +02:00
|
|
|
err = sig.syncORASRefs(localRepo, upstreamRepo, reference, refs)
|
2022-11-15 08:21:49 +02:00
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
sig.log.Error().Str("errorType", common.TypeOf(err)).
|
2023-02-13 20:43:52 +02:00
|
|
|
Err(err).Msgf("couldn't copy image ORAS references %s/%s:%s", upstreamURL, upstreamRepo, reference)
|
2022-11-15 08:21:49 +02:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
case artifactType == OCIReference:
|
2023-02-13 20:43:52 +02:00
|
|
|
// this contains notary signatures
|
2022-11-15 08:21:49 +02:00
|
|
|
index, err := sig.getOCIRefs(upstreamRepo, reference)
|
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
sig.log.Error().Str("errorType", common.TypeOf(err)).
|
2023-02-13 20:43:52 +02:00
|
|
|
Err(err).Msgf("couldn't get OCI references %s/%s:%s", upstreamURL, upstreamRepo, reference)
|
2022-11-15 08:21:49 +02:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = sig.syncOCIRefs(localRepo, upstreamRepo, reference, index)
|
|
|
|
if err != nil {
|
2022-12-22 20:19:42 +02:00
|
|
|
sig.log.Error().Str("errorType", common.TypeOf(err)).
|
2023-02-13 20:43:52 +02:00
|
|
|
Err(err).Msgf("couldn't copy OCI references %s/%s:%s", upstreamURL, upstreamRepo, reference)
|
2022-11-15 08:21:49 +02:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|