diff --git a/registry/handlers/app.go b/registry/handlers/app.go index 022701e06..95c677f00 100644 --- a/registry/handlers/app.go +++ b/registry/handlers/app.go @@ -316,7 +316,7 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App { } } - app.registry, err = applyRegistryMiddleware(app, app.registry, config.Middleware["registry"]) + app.registry, err = applyRegistryMiddleware(app, app.registry, app.driver, config.Middleware["registry"]) if err != nil { panic(err) } @@ -969,9 +969,9 @@ func appendCatalogAccessRecord(accessRecords []auth.Access, r *http.Request) []a } // applyRegistryMiddleware wraps a registry instance with the configured middlewares -func applyRegistryMiddleware(ctx context.Context, registry distribution.Namespace, middlewares []configuration.Middleware) (distribution.Namespace, error) { +func applyRegistryMiddleware(ctx context.Context, registry distribution.Namespace, driver storagedriver.StorageDriver, middlewares []configuration.Middleware) (distribution.Namespace, error) { for _, mw := range middlewares { - rmw, err := registrymiddleware.Get(ctx, mw.Name, mw.Options, registry) + rmw, err := registrymiddleware.Get(ctx, mw.Name, mw.Options, registry, driver) if err != nil { return nil, fmt.Errorf("unable to configure registry middleware (%s): %s", mw.Name, err) } diff --git a/registry/middleware/registry/middleware.go b/registry/middleware/registry/middleware.go index a19d7e53d..16552a319 100644 --- a/registry/middleware/registry/middleware.go +++ b/registry/middleware/registry/middleware.go @@ -6,11 +6,12 @@ import ( "github.com/distribution/distribution/v3" "github.com/distribution/distribution/v3/registry/storage" + storagedriver "github.com/distribution/distribution/v3/registry/storage/driver" ) // InitFunc is the type of a RegistryMiddleware factory function and is // used to register the constructor for different RegistryMiddleware backends. -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, driver storagedriver.StorageDriver, options map[string]interface{}) (distribution.Namespace, error) var ( middlewares map[string]InitFunc @@ -33,10 +34,10 @@ func Register(name string, initFunc InitFunc) error { } // Get constructs a RegistryMiddleware with the given options using the named backend. -func Get(ctx context.Context, name string, options map[string]interface{}, registry distribution.Namespace) (distribution.Namespace, error) { +func Get(ctx context.Context, name string, options map[string]interface{}, registry distribution.Namespace, driver storagedriver.StorageDriver) (distribution.Namespace, error) { if middlewares != nil { if initFunc, exists := middlewares[name]; exists { - return initFunc(ctx, registry, options) + return initFunc(ctx, registry, driver, options) } } diff --git a/registry/registry.go b/registry/registry.go index 8a9c05a4d..d4a91d0bd 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -85,6 +85,16 @@ const defaultLogFormatter = "text" // this channel gets notified when process receives signal. It is global to ease unit testing var quit = make(chan os.Signal, 1) +// HandlerFunc defines an http middleware +type HandlerFunc func(config *configuration.Configuration, handler http.Handler) http.Handler + +var handlerMiddlewares []HandlerFunc + +// RegisterHandler is used to register http middlewares to the registry service +func RegisterHandler(handlerFunc HandlerFunc) { + handlerMiddlewares = append(handlerMiddlewares, handlerFunc) +} + // ServeCmd is a cobra command for running the registry. var ServeCmd = &cobra.Command{ Use: "serve ", @@ -148,6 +158,10 @@ func NewRegistry(ctx context.Context, config *configuration.Configuration) (*Reg handler = gorhandlers.CombinedLoggingHandler(os.Stdout, handler) } + for _, applyHandlerMiddleware := range handlerMiddlewares { + handler = applyHandlerMiddleware(config, handler) + } + server := &http.Server{ Handler: handler, }