Functional options for NewRegistryWithDriver
Clean up calling convention for NewRegistryWithDriver to use functional arguments. This is a first step towards the refactor described in #215. I plan to add additional options in the process of moving configurable items from the App structure to the registry structure. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>master
							parent
							
								
									ed7cc91e6f
								
							
						
					
					
						commit
						dbbcf5fe42
					
				|  | @ -18,7 +18,10 @@ import ( | ||||||
| 
 | 
 | ||||||
| func TestListener(t *testing.T) { | func TestListener(t *testing.T) { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	registry := storage.NewRegistryWithDriver(ctx, inmemory.New(), memory.NewInMemoryBlobDescriptorCacheProvider(), true, true, false) | 	registry, err := storage.NewRegistry(ctx, inmemory.New(), storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), storage.EnableDelete, storage.EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	tl := &testListener{ | 	tl := &testListener{ | ||||||
| 		ops: make(map[string]int), | 		ops: make(map[string]int), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -118,13 +118,18 @@ func NewApp(ctx context.Context, configuration configuration.Configuration) *App | ||||||
| 	app.configureRedis(&configuration) | 	app.configureRedis(&configuration) | ||||||
| 	app.configureLogHook(&configuration) | 	app.configureLogHook(&configuration) | ||||||
| 
 | 
 | ||||||
|  | 	options := []storage.RegistryOption{} | ||||||
|  | 
 | ||||||
|  | 	if app.isCache { | ||||||
|  | 		options = append(options, storage.DisableDigestResumption) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	// configure deletion
 | 	// configure deletion
 | ||||||
| 	var deleteEnabled bool |  | ||||||
| 	if d, ok := configuration.Storage["delete"]; ok { | 	if d, ok := configuration.Storage["delete"]; ok { | ||||||
| 		e, ok := d["enabled"] | 		e, ok := d["enabled"] | ||||||
| 		if ok { | 		if ok { | ||||||
| 			if deleteEnabled, ok = e.(bool); !ok { | 			if deleteEnabled, ok := e.(bool); ok && deleteEnabled { | ||||||
| 				deleteEnabled = false | 				options = append(options, storage.EnableDelete) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -139,10 +144,11 @@ func NewApp(ctx context.Context, configuration configuration.Configuration) *App | ||||||
| 		default: | 		default: | ||||||
| 			panic(fmt.Sprintf("invalid type for redirect config: %#v", redirectConfig)) | 			panic(fmt.Sprintf("invalid type for redirect config: %#v", redirectConfig)) | ||||||
| 		} | 		} | ||||||
| 
 | 	} | ||||||
| 		if redirectDisabled { | 	if redirectDisabled { | ||||||
| 			ctxu.GetLogger(app).Infof("backend redirection disabled") | 		ctxu.GetLogger(app).Infof("backend redirection disabled") | ||||||
| 		} | 	} else { | ||||||
|  | 		options = append(options, storage.EnableRedirect) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// configure storage caches
 | 	// configure storage caches
 | ||||||
|  | @ -158,10 +164,20 @@ func NewApp(ctx context.Context, configuration configuration.Configuration) *App | ||||||
| 			if app.redis == nil { | 			if app.redis == nil { | ||||||
| 				panic("redis configuration required to use for layerinfo cache") | 				panic("redis configuration required to use for layerinfo cache") | ||||||
| 			} | 			} | ||||||
| 			app.registry = storage.NewRegistryWithDriver(app, app.driver, rediscache.NewRedisBlobDescriptorCacheProvider(app.redis), deleteEnabled, !redirectDisabled, app.isCache) | 			cacheProvider := rediscache.NewRedisBlobDescriptorCacheProvider(app.redis) | ||||||
|  | 			localOptions := append(options, storage.BlobDescriptorCacheProvider(cacheProvider)) | ||||||
|  | 			app.registry, err = storage.NewRegistry(app, app.driver, localOptions...) | ||||||
|  | 			if err != nil { | ||||||
|  | 				panic("could not create registry: " + err.Error()) | ||||||
|  | 			} | ||||||
| 			ctxu.GetLogger(app).Infof("using redis blob descriptor cache") | 			ctxu.GetLogger(app).Infof("using redis blob descriptor cache") | ||||||
| 		case "inmemory": | 		case "inmemory": | ||||||
| 			app.registry = storage.NewRegistryWithDriver(app, app.driver, memorycache.NewInMemoryBlobDescriptorCacheProvider(), deleteEnabled, !redirectDisabled, app.isCache) | 			cacheProvider := memorycache.NewInMemoryBlobDescriptorCacheProvider() | ||||||
|  | 			localOptions := append(options, storage.BlobDescriptorCacheProvider(cacheProvider)) | ||||||
|  | 			app.registry, err = storage.NewRegistry(app, app.driver, localOptions...) | ||||||
|  | 			if err != nil { | ||||||
|  | 				panic("could not create registry: " + err.Error()) | ||||||
|  | 			} | ||||||
| 			ctxu.GetLogger(app).Infof("using inmemory blob descriptor cache") | 			ctxu.GetLogger(app).Infof("using inmemory blob descriptor cache") | ||||||
| 		default: | 		default: | ||||||
| 			if v != "" { | 			if v != "" { | ||||||
|  | @ -172,7 +188,10 @@ func NewApp(ctx context.Context, configuration configuration.Configuration) *App | ||||||
| 
 | 
 | ||||||
| 	if app.registry == nil { | 	if app.registry == nil { | ||||||
| 		// configure the registry if no cache section is available.
 | 		// configure the registry if no cache section is available.
 | ||||||
| 		app.registry = storage.NewRegistryWithDriver(app.Context, app.driver, nil, deleteEnabled, !redirectDisabled, app.isCache) | 		app.registry, err = storage.NewRegistry(app.Context, app.driver, options...) | ||||||
|  | 		if err != nil { | ||||||
|  | 			panic("could not create registry: " + err.Error()) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	app.registry, err = applyRegistryMiddleware(app.Context, app.registry, configuration.Middleware["registry"]) | 	app.registry, err = applyRegistryMiddleware(app.Context, app.registry, configuration.Middleware["registry"]) | ||||||
|  |  | ||||||
|  | @ -26,12 +26,16 @@ import ( | ||||||
| func TestAppDispatcher(t *testing.T) { | func TestAppDispatcher(t *testing.T) { | ||||||
| 	driver := inmemory.New() | 	driver := inmemory.New() | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
|  | 	registry, err := storage.NewRegistry(ctx, driver, storage.BlobDescriptorCacheProvider(memorycache.NewInMemoryBlobDescriptorCacheProvider()), storage.EnableDelete, storage.EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	app := &App{ | 	app := &App{ | ||||||
| 		Config:   configuration.Configuration{}, | 		Config:   configuration.Configuration{}, | ||||||
| 		Context:  ctx, | 		Context:  ctx, | ||||||
| 		router:   v2.Router(), | 		router:   v2.Router(), | ||||||
| 		driver:   driver, | 		driver:   driver, | ||||||
| 		registry: storage.NewRegistryWithDriver(ctx, driver, memorycache.NewInMemoryBlobDescriptorCacheProvider(), true, true, false), | 		registry: registry, | ||||||
| 	} | 	} | ||||||
| 	server := httptest.NewServer(app) | 	server := httptest.NewServer(app) | ||||||
| 	router := v2.Router() | 	router := v2.Router() | ||||||
|  |  | ||||||
|  | @ -80,13 +80,19 @@ func (te testEnv) RemoteStats() *map[string]int { | ||||||
| func makeTestEnv(t *testing.T, name string) testEnv { | func makeTestEnv(t *testing.T, name string) testEnv { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	localRegistry := storage.NewRegistryWithDriver(ctx, inmemory.New(), memory.NewInMemoryBlobDescriptorCacheProvider(), false, true, true) | 	localRegistry, err := storage.NewRegistry(ctx, inmemory.New(), storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), storage.EnableRedirect, storage.DisableDigestResumption) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	localRepo, err := localRegistry.Repository(ctx, name) | 	localRepo, err := localRegistry.Repository(ctx, name) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	truthRegistry := storage.NewRegistryWithDriver(ctx, inmemory.New(), memory.NewInMemoryBlobDescriptorCacheProvider(), false, false, false) | 	truthRegistry, err := storage.NewRegistry(ctx, inmemory.New(), storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider())) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	truthRepo, err := truthRegistry.Repository(ctx, name) | 	truthRepo, err := truthRegistry.Repository(ctx, name) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
|  |  | ||||||
|  | @ -73,7 +73,10 @@ func (sm statsManifest) Tags() ([]string, error) { | ||||||
| 
 | 
 | ||||||
| func newManifestStoreTestEnv(t *testing.T, name, tag string) *manifestStoreTestEnv { | func newManifestStoreTestEnv(t *testing.T, name, tag string) *manifestStoreTestEnv { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	truthRegistry := storage.NewRegistryWithDriver(ctx, inmemory.New(), memory.NewInMemoryBlobDescriptorCacheProvider(), false, false, false) | 	truthRegistry, err := storage.NewRegistry(ctx, inmemory.New(), storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider())) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	truthRepo, err := truthRegistry.Repository(ctx, name) | 	truthRepo, err := truthRegistry.Repository(ctx, name) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
|  | @ -92,7 +95,10 @@ func newManifestStoreTestEnv(t *testing.T, name, tag string) *manifestStoreTestE | ||||||
| 		t.Fatalf(err.Error()) | 		t.Fatalf(err.Error()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	localRegistry := storage.NewRegistryWithDriver(ctx, inmemory.New(), memory.NewInMemoryBlobDescriptorCacheProvider(), false, true, true) | 	localRegistry, err := storage.NewRegistry(ctx, inmemory.New(), storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), storage.EnableRedirect, storage.DisableDigestResumption) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	localRepo, err := localRegistry.Repository(ctx, name) | 	localRepo, err := localRegistry.Repository(ctx, name) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
|  |  | ||||||
|  | @ -33,7 +33,10 @@ func TestSimpleBlobUpload(t *testing.T) { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	imageName := "foo/bar" | 	imageName := "foo/bar" | ||||||
| 	driver := inmemory.New() | 	driver := inmemory.New() | ||||||
| 	registry := NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), true, true, false) | 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), EnableDelete, EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	repository, err := registry.Repository(ctx, imageName) | 	repository, err := registry.Repository(ctx, imageName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
|  | @ -193,7 +196,10 @@ func TestSimpleBlobUpload(t *testing.T) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Reuse state to test delete with a delete-disabled registry
 | 	// Reuse state to test delete with a delete-disabled registry
 | ||||||
| 	registry = NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), false, true, false) | 	registry, err = NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	repository, err = registry.Repository(ctx, imageName) | 	repository, err = registry.Repository(ctx, imageName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
|  | @ -212,7 +218,10 @@ func TestSimpleBlobRead(t *testing.T) { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	imageName := "foo/bar" | 	imageName := "foo/bar" | ||||||
| 	driver := inmemory.New() | 	driver := inmemory.New() | ||||||
| 	registry := NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), true, true, false) | 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), EnableDelete, EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	repository, err := registry.Repository(ctx, imageName) | 	repository, err := registry.Repository(ctx, imageName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
|  | @ -316,7 +325,10 @@ func TestLayerUploadZeroLength(t *testing.T) { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	imageName := "foo/bar" | 	imageName := "foo/bar" | ||||||
| 	driver := inmemory.New() | 	driver := inmemory.New() | ||||||
| 	registry := NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), true, true, false) | 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), EnableDelete, EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	repository, err := registry.Repository(ctx, imageName) | 	repository, err := registry.Repository(ctx, imageName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
|  |  | ||||||
|  | @ -22,7 +22,10 @@ func setupFS(t *testing.T) *setupEnv { | ||||||
| 	d := inmemory.New() | 	d := inmemory.New() | ||||||
| 	c := []byte("") | 	c := []byte("") | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	registry := NewRegistryWithDriver(ctx, d, memory.NewInMemoryBlobDescriptorCacheProvider(), false, true, false) | 	registry, err := NewRegistry(ctx, d, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	rootpath, _ := pathFor(repositoriesRootPathSpec{}) | 	rootpath, _ := pathFor(repositoriesRootPathSpec{}) | ||||||
| 
 | 
 | ||||||
| 	repos := []string{ | 	repos := []string{ | ||||||
|  |  | ||||||
|  | @ -29,7 +29,10 @@ type manifestStoreTestEnv struct { | ||||||
| func newManifestStoreTestEnv(t *testing.T, name, tag string) *manifestStoreTestEnv { | func newManifestStoreTestEnv(t *testing.T, name, tag string) *manifestStoreTestEnv { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	driver := inmemory.New() | 	driver := inmemory.New() | ||||||
| 	registry := NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), true, true, false) | 	registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), EnableDelete, EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	repo, err := registry.Repository(ctx, name) | 	repo, err := registry.Repository(ctx, name) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | @ -348,7 +351,10 @@ func TestManifestStorage(t *testing.T) { | ||||||
| 		t.Errorf("Deleted manifest get returned non-nil") | 		t.Errorf("Deleted manifest get returned non-nil") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	r := NewRegistryWithDriver(ctx, env.driver, memory.NewInMemoryBlobDescriptorCacheProvider(), false, true, false) | 	r, err := NewRegistry(ctx, env.driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), EnableRedirect) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("error creating registry: %v", err) | ||||||
|  | 	} | ||||||
| 	repo, err := r.Repository(ctx, env.name) | 	repo, err := r.Repository(ctx, env.name) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error getting repo: %v", err) | 		t.Fatalf("unexpected error getting repo: %v", err) | ||||||
|  |  | ||||||
|  | @ -12,28 +12,65 @@ import ( | ||||||
| // 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                  distribution.BlobServer | 	blobServer                  *blobServer | ||||||
| 	statter                     distribution.BlobStatter // global statter service.
 | 	statter                     *blobStatter // global statter service.
 | ||||||
| 	blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider | 	blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider | ||||||
| 	deleteEnabled               bool | 	deleteEnabled               bool | ||||||
| 	resumableDigestEnabled      bool | 	resumableDigestEnabled      bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewRegistryWithDriver creates a new registry instance from the provided
 | // RegistryOption is the type used for functional options for NewRegistry.
 | ||||||
| // driver. The resulting registry may be shared by multiple goroutines but is
 | type RegistryOption func(*registry) error | ||||||
| // cheap to allocate. If redirect is true, the backend blob server will
 |  | ||||||
| // attempt to use (StorageDriver).URLFor to serve all blobs.
 |  | ||||||
| //
 |  | ||||||
| // TODO(stevvooe): This function signature is getting very out of hand. Move to
 |  | ||||||
| // functional options for instance configuration.
 |  | ||||||
| func NewRegistryWithDriver(ctx context.Context, driver storagedriver.StorageDriver, blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider, deleteEnabled bool, redirect bool, isCache bool) distribution.Namespace { |  | ||||||
| 	// create global statter, with cache.
 |  | ||||||
| 	var statter distribution.BlobDescriptorService = &blobStatter{ |  | ||||||
| 		driver: driver, |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if blobDescriptorCacheProvider != nil { | // EnableRedirect is a functional option for NewRegistry. It causes the backend
 | ||||||
| 		statter = cache.NewCachedBlobStatter(blobDescriptorCacheProvider, statter) | // blob server to attempt using (StorageDriver).URLFor to serve all blobs.
 | ||||||
|  | func EnableRedirect(registry *registry) error { | ||||||
|  | 	registry.blobServer.redirect = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EnableDelete is a functional option for NewRegistry. It enables deletion on
 | ||||||
|  | // the registry.
 | ||||||
|  | func EnableDelete(registry *registry) error { | ||||||
|  | 	registry.deleteEnabled = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DisableDigestResumption is a functional option for NewRegistry. It should be
 | ||||||
|  | // used if the registry is acting as a caching proxy.
 | ||||||
|  | func DisableDigestResumption(registry *registry) error { | ||||||
|  | 	registry.resumableDigestEnabled = false | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BlobDescriptorCacheProvider returns a functional option for
 | ||||||
|  | // NewRegistry. It creates a cached blob statter for use by the
 | ||||||
|  | // registry.
 | ||||||
|  | func BlobDescriptorCacheProvider(blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider) RegistryOption { | ||||||
|  | 	// TODO(aaronl): The duplication of statter across several objects is
 | ||||||
|  | 	// ugly, and prevents us from using interface types in the registry
 | ||||||
|  | 	// struct. Ideally, blobStore and blobServer should be lazily
 | ||||||
|  | 	// initialized, and use the current value of
 | ||||||
|  | 	// blobDescriptorCacheProvider.
 | ||||||
|  | 	return func(registry *registry) error { | ||||||
|  | 		if blobDescriptorCacheProvider != nil { | ||||||
|  | 			statter := cache.NewCachedBlobStatter(blobDescriptorCacheProvider, registry.statter) | ||||||
|  | 			registry.blobStore.statter = statter | ||||||
|  | 			registry.blobServer.statter = statter | ||||||
|  | 			registry.blobDescriptorCacheProvider = blobDescriptorCacheProvider | ||||||
|  | 		} | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewRegistry creates a new registry instance from the provided driver. The
 | ||||||
|  | // resulting registry may be shared by multiple goroutines but is cheap to
 | ||||||
|  | // allocate. If the Redirect option is specified, the backend blob server will
 | ||||||
|  | // attempt to use (StorageDriver).URLFor to serve all blobs.
 | ||||||
|  | func NewRegistry(ctx context.Context, driver storagedriver.StorageDriver, options ...RegistryOption) (distribution.Namespace, error) { | ||||||
|  | 	// create global statter
 | ||||||
|  | 	statter := &blobStatter{ | ||||||
|  | 		driver: driver, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bs := &blobStore{ | 	bs := &blobStore{ | ||||||
|  | @ -41,18 +78,24 @@ func NewRegistryWithDriver(ctx context.Context, driver storagedriver.StorageDriv | ||||||
| 		statter: statter, | 		statter: statter, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return ®istry{ | 	registry := ®istry{ | ||||||
| 		blobStore: bs, | 		blobStore: bs, | ||||||
| 		blobServer: &blobServer{ | 		blobServer: &blobServer{ | ||||||
| 			driver:   driver, | 			driver:  driver, | ||||||
| 			statter:  statter, | 			statter: statter, | ||||||
| 			pathFn:   bs.path, | 			pathFn:  bs.path, | ||||||
| 			redirect: redirect, |  | ||||||
| 		}, | 		}, | ||||||
| 		blobDescriptorCacheProvider: blobDescriptorCacheProvider, | 		statter:                statter, | ||||||
| 		deleteEnabled:               deleteEnabled, | 		resumableDigestEnabled: true, | ||||||
| 		resumableDigestEnabled:      !isCache, |  | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, option := range options { | ||||||
|  | 		if err := option(registry); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return registry, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Scope returns the namespace scope for a registry. The registry
 | // Scope returns the namespace scope for a registry. The registry
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue