github.com/lusis/distribution@v2.0.1+incompatible/registry/storage/registry.go (about) 1 package storage 2 3 import ( 4 "github.com/docker/distribution" 5 "github.com/docker/distribution/registry/api/v2" 6 "github.com/docker/distribution/registry/storage/cache" 7 storagedriver "github.com/docker/distribution/registry/storage/driver" 8 "golang.org/x/net/context" 9 ) 10 11 // registry is the top-level implementation of Registry for use in the storage 12 // package. All instances should descend from this object. 13 type registry struct { 14 driver storagedriver.StorageDriver 15 pm *pathMapper 16 blobStore *blobStore 17 layerInfoCache cache.LayerInfoCache 18 } 19 20 // NewRegistryWithDriver creates a new registry instance from the provided 21 // driver. The resulting registry may be shared by multiple goroutines but is 22 // cheap to allocate. 23 func NewRegistryWithDriver(driver storagedriver.StorageDriver, layerInfoCache cache.LayerInfoCache) distribution.Namespace { 24 bs := &blobStore{ 25 driver: driver, 26 pm: defaultPathMapper, 27 } 28 29 return ®istry{ 30 driver: driver, 31 blobStore: bs, 32 33 // TODO(sday): This should be configurable. 34 pm: defaultPathMapper, 35 layerInfoCache: layerInfoCache, 36 } 37 } 38 39 // Scope returns the namespace scope for a registry. The registry 40 // will only serve repositories contained within this scope. 41 func (reg *registry) Scope() distribution.Scope { 42 return distribution.GlobalScope 43 } 44 45 // Repository returns an instance of the repository tied to the registry. 46 // Instances should not be shared between goroutines but are cheap to 47 // allocate. In general, they should be request scoped. 48 func (reg *registry) Repository(ctx context.Context, name string) (distribution.Repository, error) { 49 if err := v2.ValidateRespositoryName(name); err != nil { 50 return nil, distribution.ErrRepositoryNameInvalid{ 51 Name: name, 52 Reason: err, 53 } 54 } 55 56 return &repository{ 57 ctx: ctx, 58 registry: reg, 59 name: name, 60 }, nil 61 } 62 63 // repository provides name-scoped access to various services. 64 type repository struct { 65 *registry 66 ctx context.Context 67 name string 68 } 69 70 // Name returns the name of the repository. 71 func (repo *repository) Name() string { 72 return repo.name 73 } 74 75 // Manifests returns an instance of ManifestService. Instantiation is cheap and 76 // may be context sensitive in the future. The instance should be used similar 77 // to a request local. 78 func (repo *repository) Manifests() distribution.ManifestService { 79 return &manifestStore{ 80 repository: repo, 81 revisionStore: &revisionStore{ 82 repository: repo, 83 }, 84 tagStore: &tagStore{ 85 repository: repo, 86 }, 87 } 88 } 89 90 // Layers returns an instance of the LayerService. Instantiation is cheap and 91 // may be context sensitive in the future. The instance should be used similar 92 // to a request local. 93 func (repo *repository) Layers() distribution.LayerService { 94 ls := &layerStore{ 95 repository: repo, 96 } 97 98 if repo.registry.layerInfoCache != nil { 99 // TODO(stevvooe): This is not the best place to setup a cache. We would 100 // really like to decouple the cache from the backend but also have the 101 // manifeset service use the layer service cache. For now, we can simply 102 // integrate the cache directly. The main issue is that we have layer 103 // access and layer data coupled in a single object. Work is already under 104 // way to decouple this. 105 106 return &cachedLayerService{ 107 LayerService: ls, 108 repository: repo, 109 ctx: repo.ctx, 110 driver: repo.driver, 111 blobStore: repo.blobStore, 112 cache: repo.registry.layerInfoCache, 113 } 114 } 115 116 return ls 117 } 118 119 func (repo *repository) Signatures() distribution.SignatureService { 120 return &signatureStore{ 121 repository: repo, 122 } 123 }