Add support for blobAccessController middleware

Signed-off-by: Michal Minar <miminar@redhat.com>
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
This commit is contained in:
Alexey Gladkov 2016-05-18 18:54:27 +02:00 committed by Alexey Gladkov
parent 4a915d6efd
commit f97eca5ad6
4 changed files with 57 additions and 18 deletions

View file

@ -124,6 +124,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 {

View file

@ -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)

View file

@ -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
}

View file

@ -20,6 +20,7 @@ type registry struct {
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,