forked from TrueCloudLab/distribution
Merge pull request #1665 from andrewhsu/middleware-redirect
add middleware storage driver for redirect
This commit is contained in:
commit
a7dda2ce93
3 changed files with 123 additions and 3 deletions
|
@ -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.
|
||||
|
||||
|
|
50
registry/storage/driver/middleware/redirect/middleware.go
Normal file
50
registry/storage/driver/middleware/redirect/middleware.go
Normal file
|
@ -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 a new issue