github.com/npaton/distribution@v2.3.1-rc.0+incompatible/registry/proxy/proxymanifeststore.go (about)

     1  package proxy
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/docker/distribution"
     7  	"github.com/docker/distribution/context"
     8  	"github.com/docker/distribution/digest"
     9  	"github.com/docker/distribution/reference"
    10  	"github.com/docker/distribution/registry/proxy/scheduler"
    11  )
    12  
    13  // todo(richardscothern): from cache control header or config
    14  const repositoryTTL = time.Duration(24 * 7 * time.Hour)
    15  
    16  type proxyManifestStore struct {
    17  	ctx             context.Context
    18  	localManifests  distribution.ManifestService
    19  	remoteManifests distribution.ManifestService
    20  	repositoryName  reference.Named
    21  	scheduler       *scheduler.TTLExpirationScheduler
    22  	authChallenger  authChallenger
    23  }
    24  
    25  var _ distribution.ManifestService = &proxyManifestStore{}
    26  
    27  func (pms proxyManifestStore) Exists(ctx context.Context, dgst digest.Digest) (bool, error) {
    28  	exists, err := pms.localManifests.Exists(ctx, dgst)
    29  	if err != nil {
    30  		return false, err
    31  	}
    32  	if exists {
    33  		return true, nil
    34  	}
    35  	if err := pms.authChallenger.tryEstablishChallenges(ctx); err != nil {
    36  		return false, err
    37  	}
    38  	return pms.remoteManifests.Exists(ctx, dgst)
    39  }
    40  
    41  func (pms proxyManifestStore) Get(ctx context.Context, dgst digest.Digest, options ...distribution.ManifestServiceOption) (distribution.Manifest, error) {
    42  	// At this point `dgst` was either specified explicitly, or returned by the
    43  	// tagstore with the most recent association.
    44  	var fromRemote bool
    45  	manifest, err := pms.localManifests.Get(ctx, dgst, options...)
    46  	if err != nil {
    47  		if err := pms.authChallenger.tryEstablishChallenges(ctx); err != nil {
    48  			return nil, err
    49  		}
    50  
    51  		manifest, err = pms.remoteManifests.Get(ctx, dgst, options...)
    52  		if err != nil {
    53  			return nil, err
    54  		}
    55  		fromRemote = true
    56  	}
    57  
    58  	_, payload, err := manifest.Payload()
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	proxyMetrics.ManifestPush(uint64(len(payload)))
    64  	if fromRemote {
    65  		proxyMetrics.ManifestPull(uint64(len(payload)))
    66  
    67  		_, err = pms.localManifests.Put(ctx, manifest)
    68  		if err != nil {
    69  			return nil, err
    70  		}
    71  
    72  		// Schedule the manifest blob for removal
    73  		repoBlob, err := reference.WithDigest(pms.repositoryName, dgst)
    74  		if err != nil {
    75  			context.GetLogger(ctx).Errorf("Error creating reference: %s", err)
    76  			return nil, err
    77  		}
    78  
    79  		pms.scheduler.AddManifest(repoBlob, repositoryTTL)
    80  		// Ensure the manifest blob is cleaned up
    81  		//pms.scheduler.AddBlob(blobRef, repositoryTTL)
    82  
    83  	}
    84  
    85  	return manifest, err
    86  }
    87  
    88  func (pms proxyManifestStore) Put(ctx context.Context, manifest distribution.Manifest, options ...distribution.ManifestServiceOption) (digest.Digest, error) {
    89  	var d digest.Digest
    90  	return d, distribution.ErrUnsupported
    91  }
    92  
    93  func (pms proxyManifestStore) Delete(ctx context.Context, dgst digest.Digest) error {
    94  	return distribution.ErrUnsupported
    95  }
    96  
    97  /*func (pms proxyManifestStore) Enumerate(ctx context.Context, manifests []distribution.Manifest, last distribution.Manifest) (n int, err error) {
    98  	return 0, distribution.ErrUnsupported
    99  }
   100  */