97 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
package proxy
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/distribution/distribution/v3"
 | 
						|
	dcontext "github.com/distribution/distribution/v3/context"
 | 
						|
	"github.com/distribution/distribution/v3/reference"
 | 
						|
	"github.com/distribution/distribution/v3/registry/proxy/scheduler"
 | 
						|
	"github.com/opencontainers/go-digest"
 | 
						|
)
 | 
						|
 | 
						|
// todo(richardscothern): from cache control header or config
 | 
						|
const repositoryTTL = 24 * 7 * time.Hour
 | 
						|
 | 
						|
type proxyManifestStore struct {
 | 
						|
	ctx             context.Context
 | 
						|
	localManifests  distribution.ManifestService
 | 
						|
	remoteManifests distribution.ManifestService
 | 
						|
	repositoryName  reference.Named
 | 
						|
	scheduler       *scheduler.TTLExpirationScheduler
 | 
						|
	authChallenger  authChallenger
 | 
						|
}
 | 
						|
 | 
						|
var _ distribution.ManifestService = &proxyManifestStore{}
 | 
						|
 | 
						|
func (pms proxyManifestStore) Exists(ctx context.Context, dgst digest.Digest) (bool, error) {
 | 
						|
	exists, err := pms.localManifests.Exists(ctx, dgst)
 | 
						|
	if err != nil {
 | 
						|
		return false, err
 | 
						|
	}
 | 
						|
	if exists {
 | 
						|
		return true, nil
 | 
						|
	}
 | 
						|
	if err := pms.authChallenger.tryEstablishChallenges(ctx); err != nil {
 | 
						|
		return false, err
 | 
						|
	}
 | 
						|
	return pms.remoteManifests.Exists(ctx, dgst)
 | 
						|
}
 | 
						|
 | 
						|
func (pms proxyManifestStore) Get(ctx context.Context, dgst digest.Digest, options ...distribution.ManifestServiceOption) (distribution.Manifest, error) {
 | 
						|
	// At this point `dgst` was either specified explicitly, or returned by the
 | 
						|
	// tagstore with the most recent association.
 | 
						|
	var fromRemote bool
 | 
						|
	manifest, err := pms.localManifests.Get(ctx, dgst, options...)
 | 
						|
	if err != nil {
 | 
						|
		if err := pms.authChallenger.tryEstablishChallenges(ctx); err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
 | 
						|
		manifest, err = pms.remoteManifests.Get(ctx, dgst, options...)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		fromRemote = true
 | 
						|
	}
 | 
						|
 | 
						|
	_, payload, err := manifest.Payload()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	proxyMetrics.ManifestPush(uint64(len(payload)))
 | 
						|
	if fromRemote {
 | 
						|
		proxyMetrics.ManifestPull(uint64(len(payload)))
 | 
						|
 | 
						|
		_, err = pms.localManifests.Put(ctx, manifest)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
 | 
						|
		// Schedule the manifest blob for removal
 | 
						|
		repoBlob, err := reference.WithDigest(pms.repositoryName, dgst)
 | 
						|
		if err != nil {
 | 
						|
			dcontext.GetLogger(ctx).Errorf("Error creating reference: %s", err)
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
 | 
						|
		pms.scheduler.AddManifest(repoBlob, repositoryTTL)
 | 
						|
		// Ensure the manifest blob is cleaned up
 | 
						|
		// pms.scheduler.AddBlob(blobRef, repositoryTTL)
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	return manifest, err
 | 
						|
}
 | 
						|
 | 
						|
func (pms proxyManifestStore) Put(ctx context.Context, manifest distribution.Manifest, options ...distribution.ManifestServiceOption) (digest.Digest, error) {
 | 
						|
	var d digest.Digest
 | 
						|
	return d, distribution.ErrUnsupported
 | 
						|
}
 | 
						|
 | 
						|
func (pms proxyManifestStore) Delete(ctx context.Context, dgst digest.Digest) error {
 | 
						|
	return distribution.ErrUnsupported
 | 
						|
}
 |