Merge pull request #1665 from andrewhsu/middleware-redirect
add middleware storage driver for redirectmaster
						commit
						a7dda2ce93
					
				|  | @ -165,6 +165,10 @@ information about each option that appears later in this page. | |||
|             privatekey: /path/to/pem | ||||
|             keypairid: cloudfrontkeypairid | ||||
|             duration: 3000s | ||||
|       storage: | ||||
|         - name: redirect | ||||
|           options: | ||||
|             baseurl: https://example.com/ | ||||
|     reporting: | ||||
|       bugsnag: | ||||
|         apikey: bugsnagapikey | ||||
|  | @ -676,8 +680,7 @@ object they're wrapping. This means a registry middleware must implement the | |||
| `distribution.Repository`, and storage middleware must implement | ||||
| `driver.StorageDriver`. | ||||
| 
 | ||||
| Currently only one middleware, `cloudfront`, a storage middleware, is supported | ||||
| in the registry implementation. | ||||
| An example configuration of the `cloudfront`  middleware, a storage middleware: | ||||
| 
 | ||||
|     middleware: | ||||
|       registry: | ||||
|  | @ -758,6 +761,15 @@ interpretation of the options. | |||
|   </tr> | ||||
| </table> | ||||
| 
 | ||||
| ### redirect | ||||
| 
 | ||||
| In place of the `cloudfront` storage middleware, the `redirect` | ||||
| storage middleware can be used to specify a custom URL to a location | ||||
| of a proxy for the layer stored by the S3 storage driver. | ||||
| 
 | ||||
| | Parameter | Required | Description | | ||||
| | --- | --- | --- | | ||||
| | baseurl   | yes      | `SCHEME://HOST` at which layers are served. Can also contain port. For example, `https://example.com:5443`. | | ||||
| 
 | ||||
| ## reporting | ||||
| 
 | ||||
|  | @ -1794,7 +1806,7 @@ This example illustrates how to configure storage middleware in a registry. | |||
| Middleware allows the registry to serve layers via a content delivery network | ||||
| (CDN). This is useful for reducing requests to the storage layer. | ||||
| 
 | ||||
| Currently, the registry supports [Amazon | ||||
| The registry supports [Amazon | ||||
| Cloudfront](http://aws.amazon.com/cloudfront/). You can only use Cloudfront in | ||||
| conjunction with the S3 storage driver. | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,50 @@ | |||
| package middleware | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
| 
 | ||||
| 	"github.com/docker/distribution/context" | ||||
| 	storagedriver "github.com/docker/distribution/registry/storage/driver" | ||||
| 	storagemiddleware "github.com/docker/distribution/registry/storage/driver/middleware" | ||||
| ) | ||||
| 
 | ||||
| type redirectStorageMiddleware struct { | ||||
| 	storagedriver.StorageDriver | ||||
| 	scheme string | ||||
| 	host   string | ||||
| } | ||||
| 
 | ||||
| var _ storagedriver.StorageDriver = &redirectStorageMiddleware{} | ||||
| 
 | ||||
| func newRedirectStorageMiddleware(sd storagedriver.StorageDriver, options map[string]interface{}) (storagedriver.StorageDriver, error) { | ||||
| 	o, ok := options["baseurl"] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("no baseurl provided") | ||||
| 	} | ||||
| 	b, ok := o.(string) | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("baseurl must be a string") | ||||
| 	} | ||||
| 	u, err := url.Parse(b) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("unable to parse redirect baseurl: %s", b) | ||||
| 	} | ||||
| 	if u.Scheme == "" { | ||||
| 		return nil, fmt.Errorf("no scheme specified for redirect baseurl") | ||||
| 	} | ||||
| 	if u.Host == "" { | ||||
| 		return nil, fmt.Errorf("no host specified for redirect baseurl") | ||||
| 	} | ||||
| 
 | ||||
| 	return &redirectStorageMiddleware{StorageDriver: sd, scheme: u.Scheme, host: u.Host}, nil | ||||
| } | ||||
| 
 | ||||
| func (r *redirectStorageMiddleware) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) { | ||||
| 	u := &url.URL{Scheme: r.scheme, Host: r.host, Path: path} | ||||
| 	return u.String(), nil | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	storagemiddleware.Register("redirect", storagemiddleware.InitFunc(newRedirectStorageMiddleware)) | ||||
| } | ||||
|  | @ -0,0 +1,58 @@ | |||
| package middleware | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	check "gopkg.in/check.v1" | ||||
| ) | ||||
| 
 | ||||
| func Test(t *testing.T) { check.TestingT(t) } | ||||
| 
 | ||||
| type MiddlewareSuite struct{} | ||||
| 
 | ||||
| var _ = check.Suite(&MiddlewareSuite{}) | ||||
| 
 | ||||
| func (s *MiddlewareSuite) TestNoConfig(c *check.C) { | ||||
| 	options := make(map[string]interface{}) | ||||
| 	_, err := newRedirectStorageMiddleware(nil, options) | ||||
| 	c.Assert(err, check.ErrorMatches, "no baseurl provided") | ||||
| } | ||||
| 
 | ||||
| func (s *MiddlewareSuite) TestMissingScheme(c *check.C) { | ||||
| 	options := make(map[string]interface{}) | ||||
| 	options["baseurl"] = "example.com" | ||||
| 	_, err := newRedirectStorageMiddleware(nil, options) | ||||
| 	c.Assert(err, check.ErrorMatches, "no scheme specified for redirect baseurl") | ||||
| } | ||||
| 
 | ||||
| func (s *MiddlewareSuite) TestHttpsPort(c *check.C) { | ||||
| 	options := make(map[string]interface{}) | ||||
| 	options["baseurl"] = "https://example.com:5443" | ||||
| 	middleware, err := newRedirectStorageMiddleware(nil, options) | ||||
| 	c.Assert(err, check.Equals, nil) | ||||
| 
 | ||||
| 	m, ok := middleware.(*redirectStorageMiddleware) | ||||
| 	c.Assert(ok, check.Equals, true) | ||||
| 	c.Assert(m.scheme, check.Equals, "https") | ||||
| 	c.Assert(m.host, check.Equals, "example.com:5443") | ||||
| 
 | ||||
| 	url, err := middleware.URLFor(nil, "/rick/data", nil) | ||||
| 	c.Assert(err, check.Equals, nil) | ||||
| 	c.Assert(url, check.Equals, "https://example.com:5443/rick/data") | ||||
| } | ||||
| 
 | ||||
| func (s *MiddlewareSuite) TestHTTP(c *check.C) { | ||||
| 	options := make(map[string]interface{}) | ||||
| 	options["baseurl"] = "http://example.com" | ||||
| 	middleware, err := newRedirectStorageMiddleware(nil, options) | ||||
| 	c.Assert(err, check.Equals, nil) | ||||
| 
 | ||||
| 	m, ok := middleware.(*redirectStorageMiddleware) | ||||
| 	c.Assert(ok, check.Equals, true) | ||||
| 	c.Assert(m.scheme, check.Equals, "http") | ||||
| 	c.Assert(m.host, check.Equals, "example.com") | ||||
| 
 | ||||
| 	url, err := middleware.URLFor(nil, "morty/data", nil) | ||||
| 	c.Assert(err, check.Equals, nil) | ||||
| 	c.Assert(url, check.Equals, "http://example.com/morty/data") | ||||
| } | ||||
		Loading…
	
		Reference in New Issue