Merge pull request #740 from stevvooe/disable-storage-redirects
Allow disabling of storage driver redirectsmaster
						commit
						39658be063
					
				| 
						 | 
					@ -112,7 +112,8 @@ func NewApp(ctx context.Context, configuration configuration.Configuration) *App
 | 
				
			||||||
	app.configureRedis(&configuration)
 | 
						app.configureRedis(&configuration)
 | 
				
			||||||
	app.configureLogHook(&configuration)
 | 
						app.configureLogHook(&configuration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	deleteEnabled := false
 | 
						// 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 {
 | 
				
			||||||
| 
						 | 
					@ -122,6 +123,22 @@ func NewApp(ctx context.Context, configuration configuration.Configuration) *App
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// configure redirects
 | 
				
			||||||
 | 
						var redirectDisabled bool
 | 
				
			||||||
 | 
						if redirectConfig, ok := configuration.Storage["redirect"]; ok {
 | 
				
			||||||
 | 
							v := redirectConfig["disable"]
 | 
				
			||||||
 | 
							switch v := v.(type) {
 | 
				
			||||||
 | 
							case bool:
 | 
				
			||||||
 | 
								redirectDisabled = v
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								panic(fmt.Sprintf("invalid type for redirect config: %#v", redirectConfig))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if redirectDisabled {
 | 
				
			||||||
 | 
								ctxu.GetLogger(app).Infof("backend redirection disabled")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// configure storage caches
 | 
						// configure storage caches
 | 
				
			||||||
	if cc, ok := configuration.Storage["cache"]; ok {
 | 
						if cc, ok := configuration.Storage["cache"]; ok {
 | 
				
			||||||
		v, ok := cc["blobdescriptor"]
 | 
							v, ok := cc["blobdescriptor"]
 | 
				
			||||||
| 
						 | 
					@ -135,10 +152,10 @@ 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)
 | 
								app.registry = storage.NewRegistryWithDriver(app, app.driver, rediscache.NewRedisBlobDescriptorCacheProvider(app.redis), deleteEnabled, !redirectDisabled)
 | 
				
			||||||
			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)
 | 
								app.registry = storage.NewRegistryWithDriver(app, app.driver, memorycache.NewInMemoryBlobDescriptorCacheProvider(), deleteEnabled, !redirectDisabled)
 | 
				
			||||||
			ctxu.GetLogger(app).Infof("using inmemory blob descriptor cache")
 | 
								ctxu.GetLogger(app).Infof("using inmemory blob descriptor cache")
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			if v != "" {
 | 
								if v != "" {
 | 
				
			||||||
| 
						 | 
					@ -149,7 +166,7 @@ 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)
 | 
							app.registry = storage.NewRegistryWithDriver(app.Context, app.driver, nil, deleteEnabled, !redirectDisabled)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	app.registry, err = applyRegistryMiddleware(app.registry, configuration.Middleware["registry"])
 | 
						app.registry, err = applyRegistryMiddleware(app.registry, configuration.Middleware["registry"])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,7 @@ func TestAppDispatcher(t *testing.T) {
 | 
				
			||||||
		Context:  ctx,
 | 
							Context:  ctx,
 | 
				
			||||||
		router:   v2.Router(),
 | 
							router:   v2.Router(),
 | 
				
			||||||
		driver:   driver,
 | 
							driver:   driver,
 | 
				
			||||||
		registry: storage.NewRegistryWithDriver(ctx, driver, memorycache.NewInMemoryBlobDescriptorCacheProvider(), true),
 | 
							registry: storage.NewRegistryWithDriver(ctx, driver, memorycache.NewInMemoryBlobDescriptorCacheProvider(), true, true),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	server := httptest.NewServer(app)
 | 
						server := httptest.NewServer(app)
 | 
				
			||||||
	router := v2.Router()
 | 
						router := v2.Router()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ 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)
 | 
						registry := NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), true, true)
 | 
				
			||||||
	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 +193,7 @@ 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)
 | 
						registry = NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), false, true)
 | 
				
			||||||
	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 +212,7 @@ 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)
 | 
						registry := NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), true, true)
 | 
				
			||||||
	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 +316,7 @@ 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)
 | 
						registry := NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), true, true)
 | 
				
			||||||
	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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,9 +17,10 @@ const blobCacheControlMaxAge = 365 * 24 * time.Hour
 | 
				
			||||||
// blobServer simply serves blobs from a driver instance using a path function
 | 
					// blobServer simply serves blobs from a driver instance using a path function
 | 
				
			||||||
// to identify paths and a descriptor service to fill in metadata.
 | 
					// to identify paths and a descriptor service to fill in metadata.
 | 
				
			||||||
type blobServer struct {
 | 
					type blobServer struct {
 | 
				
			||||||
	driver  driver.StorageDriver
 | 
						driver   driver.StorageDriver
 | 
				
			||||||
	statter distribution.BlobStatter
 | 
						statter  distribution.BlobStatter
 | 
				
			||||||
	pathFn  func(dgst digest.Digest) (string, error)
 | 
						pathFn   func(dgst digest.Digest) (string, error)
 | 
				
			||||||
 | 
						redirect bool // allows disabling URLFor redirects
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (bs *blobServer) ServeBlob(ctx context.Context, w http.ResponseWriter, r *http.Request, dgst digest.Digest) error {
 | 
					func (bs *blobServer) ServeBlob(ctx context.Context, w http.ResponseWriter, r *http.Request, dgst digest.Digest) error {
 | 
				
			||||||
| 
						 | 
					@ -37,8 +38,13 @@ func (bs *blobServer) ServeBlob(ctx context.Context, w http.ResponseWriter, r *h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch err {
 | 
						switch err {
 | 
				
			||||||
	case nil:
 | 
						case nil:
 | 
				
			||||||
		// Redirect to storage URL.
 | 
							if bs.redirect {
 | 
				
			||||||
		http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
 | 
								// Redirect to storage URL.
 | 
				
			||||||
 | 
								http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fallthrough
 | 
				
			||||||
	case driver.ErrUnsupportedMethod:
 | 
						case driver.ErrUnsupportedMethod:
 | 
				
			||||||
		// Fallback to serving the content directly.
 | 
							// Fallback to serving the content directly.
 | 
				
			||||||
		br, err := newFileReader(ctx, bs.driver, path, desc.Size)
 | 
							br, err := newFileReader(ctx, bs.driver, path, desc.Size)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ 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)
 | 
						registry := NewRegistryWithDriver(ctx, d, memory.NewInMemoryBlobDescriptorCacheProvider(), false, true)
 | 
				
			||||||
	rootpath, _ := defaultPathMapper.path(repositoriesRootPathSpec{})
 | 
						rootpath, _ := defaultPathMapper.path(repositoriesRootPathSpec{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repos := []string{
 | 
						repos := []string{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,8 @@ 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)
 | 
						registry := NewRegistryWithDriver(ctx, driver, memory.NewInMemoryBlobDescriptorCacheProvider(), true, true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo, err := registry.Repository(ctx, name)
 | 
						repo, err := registry.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)
 | 
				
			||||||
| 
						 | 
					@ -347,7 +348,7 @@ 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)
 | 
						r := NewRegistryWithDriver(ctx, env.driver, memory.NewInMemoryBlobDescriptorCacheProvider(), false, true)
 | 
				
			||||||
	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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,9 +20,12 @@ type registry struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewRegistryWithDriver creates a new registry instance from the provided
 | 
					// NewRegistryWithDriver creates a new registry instance from the provided
 | 
				
			||||||
// driver. The resulting registry may be shared by multiple goroutines but is
 | 
					// driver. The resulting registry may be shared by multiple goroutines but is
 | 
				
			||||||
// cheap to allocate.
 | 
					// cheap to allocate. If redirect is true, the backend blob server will
 | 
				
			||||||
func NewRegistryWithDriver(ctx context.Context, driver storagedriver.StorageDriver, blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider, deleteEnabled bool) distribution.Namespace {
 | 
					// attempt to use (StorageDriver).URLFor to serve all blobs.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// TODO(stevvooe): This function signature is getting 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) distribution.Namespace {
 | 
				
			||||||
	// create global statter, with cache.
 | 
						// create global statter, with cache.
 | 
				
			||||||
	var statter distribution.BlobDescriptorService = &blobStatter{
 | 
						var statter distribution.BlobDescriptorService = &blobStatter{
 | 
				
			||||||
		driver: driver,
 | 
							driver: driver,
 | 
				
			||||||
| 
						 | 
					@ -42,9 +45,10 @@ func NewRegistryWithDriver(ctx context.Context, driver storagedriver.StorageDriv
 | 
				
			||||||
	return ®istry{
 | 
						return ®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,
 | 
							blobDescriptorCacheProvider: blobDescriptorCacheProvider,
 | 
				
			||||||
		deleteEnabled:               deleteEnabled,
 | 
							deleteEnabled:               deleteEnabled,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue