diff --git a/docs/configuration.md b/docs/configuration.md
index cb76b231..933474b2 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -283,7 +283,7 @@ For more information about Token based authentication configuration, see the [sp
## middleware
-The middleware option is **optional** and allows middlewares to be injected at named hook points. A requirement of all middlewares is that they implement the same interface as the object they're wrapping. This means a registry middleware must implement the `distribution.Registry` interface, repository middleware must implement `distribution.Respository`, and storage middleware must implement `driver.StorageDriver`.
+The middleware option is **optional** and allows middlewares to be injected at named hook points. A requirement of all middlewares is that they implement the same interface as the object they're wrapping. This means a registry middleware must implement the `distribution.Namespace` interface, repository middleware must implement `distribution.Respository`, and storage middleware must implement `driver.StorageDriver`.
Currently only one middleware, cloudfront, a storage middleware, is included in the registry.
diff --git a/docs/glossary.md b/docs/glossary.md
index 15184567..95c8ec9e 100644
--- a/docs/glossary.md
+++ b/docs/glossary.md
@@ -23,7 +23,7 @@ see the [glossary in the full documentation set](http://docs.docker.com/referenc
Describes a collection layers that make up an image.
Registry
- A registry is a collection of repositories.
+ A registry is a service which serves repositories.
Repository
@@ -33,4 +33,11 @@ see the [glossary in the full documentation set](http://docs.docker.com/referenc
Tag
Tag provides a common name to an image.
-
\ No newline at end of file
+
+ Namespace
+ A namespace is a collection of repositories with a common name prefix. The
+ namespace with an empty common prefix is considered the Global Namespace.
+
+ Scope
+ A common repository name prefix.
+
diff --git a/registry.go b/registry.go
index 52b4f8d3..374d8ca5 100644
--- a/registry.go
+++ b/registry.go
@@ -10,8 +10,31 @@ import (
"golang.org/x/net/context"
)
-// Registry represents a collection of repositories, addressable by name.
-type Registry interface {
+// Scope defines the set of items that match a namespace.
+type Scope interface {
+ // Contains returns true if the name belongs to the namespace.
+ Contains(name string) bool
+}
+
+type fullScope struct{}
+
+func (f fullScope) Contains(string) bool {
+ return true
+}
+
+// GlobalScope represents the full namespace scope which contains
+// all other scopes.
+var GlobalScope = Scope(fullScope{})
+
+// Namespace represents a collection of repositories, addressable by name.
+// Generally, a namespace is backed by a set of one or more services,
+// providing facilities such as registry access, trust, and indexing.
+type Namespace interface {
+ // Scope describes the names that can be used with this Namespace. The
+ // global namespace will have a scope that matches all names. The scope
+ // effectively provides an identity for the namespace.
+ Scope() Scope
+
// Repository should return a reference to the named repository. The
// registry may or may not have the repository but should always return a
// reference.
diff --git a/registry/handlers/app.go b/registry/handlers/app.go
index fac93382..657ed2db 100644
--- a/registry/handlers/app.go
+++ b/registry/handlers/app.go
@@ -40,7 +40,7 @@ type App struct {
router *mux.Router // main application router, configured with dispatchers
driver storagedriver.StorageDriver // driver maintains the app global storage driver instance.
- registry distribution.Registry // registry is the primary registry backend for the app instance.
+ registry distribution.Namespace // registry is the primary registry backend for the app instance.
accessController auth.AccessController // main access controller for application
// events contains notification related configuration.
@@ -541,7 +541,7 @@ func appendAccessRecords(records []auth.Access, method string, repo string) []au
}
// applyRegistryMiddleware wraps a registry instance with the configured middlewares
-func applyRegistryMiddleware(registry distribution.Registry, middlewares []configuration.Middleware) (distribution.Registry, error) {
+func applyRegistryMiddleware(registry distribution.Namespace, middlewares []configuration.Middleware) (distribution.Namespace, error) {
for _, mw := range middlewares {
rmw, err := registrymiddleware.Get(mw.Name, mw.Options, registry)
if err != nil {
diff --git a/registry/middleware/registry/middleware.go b/registry/middleware/registry/middleware.go
index d3e88810..048603b8 100644
--- a/registry/middleware/registry/middleware.go
+++ b/registry/middleware/registry/middleware.go
@@ -8,7 +8,7 @@ import (
// InitFunc is the type of a RegistryMiddleware factory function and is
// used to register the constructor for different RegistryMiddleware backends.
-type InitFunc func(registry distribution.Registry, options map[string]interface{}) (distribution.Registry, error)
+type InitFunc func(registry distribution.Namespace, options map[string]interface{}) (distribution.Namespace, error)
var middlewares map[string]InitFunc
@@ -28,7 +28,7 @@ func Register(name string, initFunc InitFunc) error {
}
// Get constructs a RegistryMiddleware with the given options using the named backend.
-func Get(name string, options map[string]interface{}, registry distribution.Registry) (distribution.Registry, error) {
+func Get(name string, options map[string]interface{}, registry distribution.Namespace) (distribution.Namespace, error) {
if middlewares != nil {
if initFunc, exists := middlewares[name]; exists {
return initFunc(registry, options)
diff --git a/registry/storage/manifeststore_test.go b/registry/storage/manifeststore_test.go
index fe75868b..a70789d3 100644
--- a/registry/storage/manifeststore_test.go
+++ b/registry/storage/manifeststore_test.go
@@ -21,7 +21,7 @@ import (
type manifestStoreTestEnv struct {
ctx context.Context
driver driver.StorageDriver
- registry distribution.Registry
+ registry distribution.Namespace
repository distribution.Repository
name string
tag string
diff --git a/registry/storage/registry.go b/registry/storage/registry.go
index 9ad43acb..1126db45 100644
--- a/registry/storage/registry.go
+++ b/registry/storage/registry.go
@@ -20,7 +20,7 @@ type registry struct {
// NewRegistryWithDriver creates a new registry instance from the provided
// driver. The resulting registry may be shared by multiple goroutines but is
// cheap to allocate.
-func NewRegistryWithDriver(driver storagedriver.StorageDriver, layerInfoCache cache.LayerInfoCache) distribution.Registry {
+func NewRegistryWithDriver(driver storagedriver.StorageDriver, layerInfoCache cache.LayerInfoCache) distribution.Namespace {
bs := &blobStore{
driver: driver,
pm: defaultPathMapper,
@@ -36,6 +36,12 @@ func NewRegistryWithDriver(driver storagedriver.StorageDriver, layerInfoCache ca
}
}
+// Scope returns the namespace scope for a registry. The registry
+// will only serve repositories contained within this scope.
+func (reg *registry) Scope() distribution.Scope {
+ return distribution.GlobalScope
+}
+
// Repository returns an instance of the repository tied to the registry.
// Instances should not be shared between goroutines but are cheap to
// allocate. In general, they should be request scoped.