Merge pull request #1734 from legionus/blob-access-controller
Add support for blobAccessController middleware
This commit is contained in:
commit
32e9779faf
4 changed files with 57 additions and 18 deletions
5
blobs.go
5
blobs.go
|
@ -127,6 +127,11 @@ type BlobDescriptorService interface {
|
||||||
Clear(ctx context.Context, dgst digest.Digest) error
|
Clear(ctx context.Context, dgst digest.Digest) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BlobDescriptorServiceFactory creates middleware for BlobDescriptorService.
|
||||||
|
type BlobDescriptorServiceFactory interface {
|
||||||
|
BlobAccessController(svc BlobDescriptorService) BlobDescriptorService
|
||||||
|
}
|
||||||
|
|
||||||
// ReadSeekCloser is the primary reader type for blob data, combining
|
// ReadSeekCloser is the primary reader type for blob data, combining
|
||||||
// io.ReadSeeker with io.Closer.
|
// io.ReadSeeker with io.Closer.
|
||||||
type ReadSeekCloser interface {
|
type ReadSeekCloser interface {
|
||||||
|
|
|
@ -177,7 +177,7 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App {
|
||||||
app.httpHost = *u
|
app.httpHost = *u
|
||||||
}
|
}
|
||||||
|
|
||||||
options := []storage.RegistryOption{}
|
options := registrymiddleware.GetRegistryOptions()
|
||||||
|
|
||||||
if app.isCache {
|
if app.isCache {
|
||||||
options = append(options, storage.DisableDigestResumption)
|
options = append(options, storage.DisableDigestResumption)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/context"
|
"github.com/docker/distribution/context"
|
||||||
|
"github.com/docker/distribution/registry/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitFunc is the type of a RegistryMiddleware factory function and is
|
// InitFunc is the type of a RegistryMiddleware factory function and is
|
||||||
|
@ -12,6 +13,7 @@ import (
|
||||||
type InitFunc func(ctx context.Context, registry distribution.Namespace, options map[string]interface{}) (distribution.Namespace, error)
|
type InitFunc func(ctx context.Context, registry distribution.Namespace, options map[string]interface{}) (distribution.Namespace, error)
|
||||||
|
|
||||||
var middlewares map[string]InitFunc
|
var middlewares map[string]InitFunc
|
||||||
|
var registryoptions []storage.RegistryOption
|
||||||
|
|
||||||
// Register is used to register an InitFunc for
|
// Register is used to register an InitFunc for
|
||||||
// a RegistryMiddleware backend with the given name.
|
// a RegistryMiddleware backend with the given name.
|
||||||
|
@ -38,3 +40,15 @@ func Get(ctx context.Context, name string, options map[string]interface{}, regis
|
||||||
|
|
||||||
return nil, fmt.Errorf("no registry middleware registered with name: %s", name)
|
return nil, fmt.Errorf("no registry middleware registered with name: %s", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterOptions adds more options to RegistryOption list. Options get applied before
|
||||||
|
// any other configuration-based options.
|
||||||
|
func RegisterOptions(options ...storage.RegistryOption) error {
|
||||||
|
registryoptions = append(registryoptions, options...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRegistryOptions returns list of RegistryOption.
|
||||||
|
func GetRegistryOptions() []storage.RegistryOption {
|
||||||
|
return registryoptions
|
||||||
|
}
|
||||||
|
|
|
@ -12,14 +12,15 @@ import (
|
||||||
// registry is the top-level implementation of Registry for use in the storage
|
// registry is the top-level implementation of Registry for use in the storage
|
||||||
// package. All instances should descend from this object.
|
// package. All instances should descend from this object.
|
||||||
type registry struct {
|
type registry struct {
|
||||||
blobStore *blobStore
|
blobStore *blobStore
|
||||||
blobServer *blobServer
|
blobServer *blobServer
|
||||||
statter *blobStatter // global statter service.
|
statter *blobStatter // global statter service.
|
||||||
blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider
|
blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider
|
||||||
deleteEnabled bool
|
deleteEnabled bool
|
||||||
resumableDigestEnabled bool
|
resumableDigestEnabled bool
|
||||||
schema1SignaturesEnabled bool
|
schema1SignaturesEnabled bool
|
||||||
schema1SigningKey libtrust.PrivateKey
|
schema1SigningKey libtrust.PrivateKey
|
||||||
|
blobDescriptorServiceFactory distribution.BlobDescriptorServiceFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegistryOption is the type used for functional options for NewRegistry.
|
// RegistryOption is the type used for functional options for NewRegistry.
|
||||||
|
@ -64,6 +65,15 @@ func Schema1SigningKey(key libtrust.PrivateKey) RegistryOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BlobDescriptorServiceFactory returns a functional option for NewRegistry. It sets the
|
||||||
|
// factory to create BlobDescriptorServiceFactory middleware.
|
||||||
|
func BlobDescriptorServiceFactory(factory distribution.BlobDescriptorServiceFactory) RegistryOption {
|
||||||
|
return func(registry *registry) error {
|
||||||
|
registry.blobDescriptorServiceFactory = factory
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BlobDescriptorCacheProvider returns a functional option for
|
// BlobDescriptorCacheProvider returns a functional option for
|
||||||
// NewRegistry. It creates a cached blob statter for use by the
|
// NewRegistry. It creates a cached blob statter for use by the
|
||||||
// registry.
|
// registry.
|
||||||
|
@ -190,16 +200,22 @@ func (repo *repository) Manifests(ctx context.Context, options ...distribution.M
|
||||||
|
|
||||||
manifestDirectoryPathSpec := manifestRevisionsPathSpec{name: repo.name.Name()}
|
manifestDirectoryPathSpec := manifestRevisionsPathSpec{name: repo.name.Name()}
|
||||||
|
|
||||||
|
var statter distribution.BlobDescriptorService = &linkedBlobStatter{
|
||||||
|
blobStore: repo.blobStore,
|
||||||
|
repository: repo,
|
||||||
|
linkPathFns: manifestLinkPathFns,
|
||||||
|
}
|
||||||
|
|
||||||
|
if repo.registry.blobDescriptorServiceFactory != nil {
|
||||||
|
statter = repo.registry.blobDescriptorServiceFactory.BlobAccessController(statter)
|
||||||
|
}
|
||||||
|
|
||||||
blobStore := &linkedBlobStore{
|
blobStore := &linkedBlobStore{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
blobStore: repo.blobStore,
|
blobStore: repo.blobStore,
|
||||||
repository: repo,
|
repository: repo,
|
||||||
deleteEnabled: repo.registry.deleteEnabled,
|
deleteEnabled: repo.registry.deleteEnabled,
|
||||||
blobAccessController: &linkedBlobStatter{
|
blobAccessController: statter,
|
||||||
blobStore: repo.blobStore,
|
|
||||||
repository: repo,
|
|
||||||
linkPathFns: manifestLinkPathFns,
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO(stevvooe): linkPath limits this blob store to only
|
// TODO(stevvooe): linkPath limits this blob store to only
|
||||||
// manifests. This instance cannot be used for blob checks.
|
// manifests. This instance cannot be used for blob checks.
|
||||||
|
@ -258,6 +274,10 @@ func (repo *repository) Blobs(ctx context.Context) distribution.BlobStore {
|
||||||
statter = cache.NewCachedBlobStatter(repo.descriptorCache, statter)
|
statter = cache.NewCachedBlobStatter(repo.descriptorCache, statter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if repo.registry.blobDescriptorServiceFactory != nil {
|
||||||
|
statter = repo.registry.blobDescriptorServiceFactory.BlobAccessController(statter)
|
||||||
|
}
|
||||||
|
|
||||||
return &linkedBlobStore{
|
return &linkedBlobStore{
|
||||||
registry: repo.registry,
|
registry: repo.registry,
|
||||||
blobStore: repo.blobStore,
|
blobStore: repo.blobStore,
|
||||||
|
|
Loading…
Reference in a new issue