Merge pull request #751 from stevvooe/update-routes

Update routes to reflect specification changes
This commit is contained in:
Olivier Gambier 2014-11-18 23:45:55 -08:00
commit ce91eabaab
6 changed files with 70 additions and 63 deletions

6
app.go
View file

@ -29,10 +29,10 @@ func NewApp(configuration configuration.Configuration) *App {
// Register the handler dispatchers. // Register the handler dispatchers.
app.register(routeNameImageManifest, imageManifestDispatcher) app.register(routeNameImageManifest, imageManifestDispatcher)
app.register(routeNameLayer, layerDispatcher) app.register(routeNameBlob, layerDispatcher)
app.register(routeNameTags, tagsDispatcher) app.register(routeNameTags, tagsDispatcher)
app.register(routeNameLayerUpload, layerUploadDispatcher) app.register(routeNameBlobUpload, layerUploadDispatcher)
app.register(routeNameLayerUploadResume, layerUploadDispatcher) app.register(routeNameBlobUploadResume, layerUploadDispatcher)
return app return app
} }

View file

@ -84,24 +84,22 @@ func TestAppDispatcher(t *testing.T) {
}, },
}, },
{ {
endpoint: routeNameLayer, endpoint: routeNameBlob,
vars: []string{ vars: []string{
"name", "foo/bar", "name", "foo/bar",
"tarsum", "tarsum.v1+bogus:abcdef0123456789", "digest", "tarsum.v1+bogus:abcdef0123456789",
}, },
}, },
{ {
endpoint: routeNameLayerUpload, endpoint: routeNameBlobUpload,
vars: []string{ vars: []string{
"name", "foo/bar", "name", "foo/bar",
"tarsum", "tarsum.v1+bogus:abcdef0123456789",
}, },
}, },
{ {
endpoint: routeNameLayerUploadResume, endpoint: routeNameBlobUploadResume,
vars: []string{ vars: []string{
"name", "foo/bar", "name", "foo/bar",
"tarsum", "tarsum.v1+bogus:abcdef0123456789",
"uuid", "theuuid", "uuid", "theuuid",
}, },
}, },

View file

@ -17,6 +17,7 @@ func layerDispatcher(ctx *Context, r *http.Request) http.Handler {
return handlers.MethodHandler{ return handlers.MethodHandler{
"GET": http.HandlerFunc(layerHandler.GetLayer), "GET": http.HandlerFunc(layerHandler.GetLayer),
"HEAD": http.HandlerFunc(layerHandler.GetLayer),
} }
} }

View file

@ -24,6 +24,7 @@ func layerUploadDispatcher(ctx *Context, r *http.Request) http.Handler {
return handlers.MethodHandler{ return handlers.MethodHandler{
"POST": http.HandlerFunc(layerUploadHandler.StartLayerUpload), "POST": http.HandlerFunc(layerUploadHandler.StartLayerUpload),
"GET": http.HandlerFunc(layerUploadHandler.GetUploadStatus), "GET": http.HandlerFunc(layerUploadHandler.GetUploadStatus),
"HEAD": http.HandlerFunc(layerUploadHandler.GetUploadStatus),
"PUT": http.HandlerFunc(layerUploadHandler.PutLayerChunk), "PUT": http.HandlerFunc(layerUploadHandler.PutLayerChunk),
"DELETE": http.HandlerFunc(layerUploadHandler.CancelLayerUpload), "DELETE": http.HandlerFunc(layerUploadHandler.CancelLayerUpload),
} }

View file

@ -8,17 +8,17 @@ import (
const ( const (
routeNameImageManifest = "image-manifest" routeNameImageManifest = "image-manifest"
routeNameTags = "tags" routeNameTags = "tags"
routeNameLayer = "layer" routeNameBlob = "blob"
routeNameLayerUpload = "layer-upload" routeNameBlobUpload = "blob-upload"
routeNameLayerUploadResume = "layer-upload-resume" routeNameBlobUploadResume = "blob-upload-resume"
) )
var allEndpoints = []string{ var allEndpoints = []string{
routeNameImageManifest, routeNameImageManifest,
routeNameTags, routeNameTags,
routeNameLayer, routeNameBlob,
routeNameLayerUpload, routeNameBlobUpload,
routeNameLayerUploadResume, routeNameBlobUploadResume,
} }
// v2APIRouter builds a gorilla router with named routes for the various API // v2APIRouter builds a gorilla router with named routes for the various API
@ -27,11 +27,11 @@ func v2APIRouter() *mux.Router {
router := mux.NewRouter(). router := mux.NewRouter().
StrictSlash(true) StrictSlash(true)
// GET /v2/<name>/image/<tag> Image Manifest Fetch the image manifest identified by name and tag. // GET /v2/<name>/manifest/<tag> Image Manifest Fetch the image manifest identified by name and tag.
// PUT /v2/<name>/image/<tag> Image Manifest Upload the image manifest identified by name and tag. // PUT /v2/<name>/manifest/<tag> Image Manifest Upload the image manifest identified by name and tag.
// DELETE /v2/<name>/image/<tag> Image Manifest Delete the image identified by name and tag. // DELETE /v2/<name>/manifest/<tag> Image Manifest Delete the image identified by name and tag.
router. router.
Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/image/{tag:" + common.TagNameRegexp.String() + "}"). Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/manifest/{tag:" + common.TagNameRegexp.String() + "}").
Name(routeNameImageManifest) Name(routeNameImageManifest)
// GET /v2/<name>/tags/list Tags Fetch the tags under the repository identified by name. // GET /v2/<name>/tags/list Tags Fetch the tags under the repository identified by name.
@ -39,22 +39,22 @@ func v2APIRouter() *mux.Router {
Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/tags/list"). Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/tags/list").
Name(routeNameTags) Name(routeNameTags)
// GET /v2/<name>/layer/<tarsum> Layer Fetch the layer identified by tarsum. // GET /v2/<name>/blob/<digest> Layer Fetch the blob identified by digest.
router. router.
Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/layer/{tarsum:" + common.TarsumRegexp.String() + "}"). Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blob/{digest:[a-zA-Z0-9-_+.]+:[a-zA-Z0-9-_+.=]+}").
Name(routeNameLayer) Name(routeNameBlob)
// POST /v2/<name>/layer/<tarsum>/upload/ Layer Upload Initiate an upload of the layer identified by tarsum. Requires length and a checksum parameter. // POST /v2/<name>/blob/upload/ Layer Upload Initiate an upload of the layer identified by tarsum.
router. router.
Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/layer/{tarsum:" + common.TarsumRegexp.String() + "}/upload/"). Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blob/upload/").
Name(routeNameLayerUpload) Name(routeNameBlobUpload)
// GET /v2/<name>/layer/<tarsum>/upload/<uuid> Layer Upload Get the status of the upload identified by tarsum and uuid. // GET /v2/<name>/blob/upload/<uuid> Layer Upload Get the status of the upload identified by tarsum and uuid.
// PUT /v2/<name>/layer/<tarsum>/upload/<uuid> Layer Upload Upload all or a chunk of the upload identified by tarsum and uuid. // PUT /v2/<name>/blob/upload/<uuid> Layer Upload Upload all or a chunk of the upload identified by tarsum and uuid.
// DELETE /v2/<name>/layer/<tarsum>/upload/<uuid> Layer Upload Cancel the upload identified by layer and uuid // DELETE /v2/<name>/blob/upload/<uuid> Layer Upload Cancel the upload identified by layer and uuid
router. router.
Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/layer/{tarsum:" + common.TarsumRegexp.String() + "}/upload/{uuid}"). Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blob/upload/{uuid}").
Name(routeNameLayerUploadResume) Name(routeNameBlobUploadResume)
return router return router
} }

View file

@ -48,7 +48,7 @@ func TestRouter(t *testing.T) {
for _, testcase := range []routeTestCase{ for _, testcase := range []routeTestCase{
{ {
RouteName: routeNameImageManifest, RouteName: routeNameImageManifest,
RequestURI: "/v2/foo/bar/image/tag", RequestURI: "/v2/foo/bar/manifest/tag",
Vars: map[string]string{ Vars: map[string]string{
"name": "foo/bar", "name": "foo/bar",
"tag": "tag", "tag": "tag",
@ -62,68 +62,75 @@ func TestRouter(t *testing.T) {
}, },
}, },
{ {
RouteName: routeNameLayer, RouteName: routeNameBlob,
RequestURI: "/v2/foo/bar/layer/tarsum.dev+foo:abcdef0919234", RequestURI: "/v2/foo/bar/blob/tarsum.dev+foo:abcdef0919234",
Vars: map[string]string{ Vars: map[string]string{
"name": "foo/bar", "name": "foo/bar",
"tarsum": "tarsum.dev+foo:abcdef0919234", "digest": "tarsum.dev+foo:abcdef0919234",
}, },
}, },
{ {
RouteName: routeNameLayerUpload, RouteName: routeNameBlob,
RequestURI: "/v2/foo/bar/layer/tarsum.dev+foo:abcdef0919234/upload/", RequestURI: "/v2/foo/bar/blob/sha256:abcdef0919234",
Vars: map[string]string{ Vars: map[string]string{
"name": "foo/bar", "name": "foo/bar",
"tarsum": "tarsum.dev+foo:abcdef0919234", "digest": "sha256:abcdef0919234",
}, },
}, },
{ {
RouteName: routeNameLayerUploadResume, RouteName: routeNameBlobUpload,
RequestURI: "/v2/foo/bar/layer/tarsum.dev+foo:abcdef0919234/upload/uuid", RequestURI: "/v2/foo/bar/blob/upload/",
Vars: map[string]string{
"name": "foo/bar",
},
},
{
RouteName: routeNameBlobUploadResume,
RequestURI: "/v2/foo/bar/blob/upload/uuid",
Vars: map[string]string{ Vars: map[string]string{
"name": "foo/bar", "name": "foo/bar",
"tarsum": "tarsum.dev+foo:abcdef0919234",
"uuid": "uuid", "uuid": "uuid",
}, },
}, },
{ {
RouteName: routeNameLayerUploadResume, RouteName: routeNameBlobUploadResume,
RequestURI: "/v2/foo/bar/layer/tarsum.dev+foo:abcdef0919234/upload/D95306FA-FAD3-4E36-8D41-CF1C93EF8286", RequestURI: "/v2/foo/bar/blob/upload/D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
Vars: map[string]string{ Vars: map[string]string{
"name": "foo/bar", "name": "foo/bar",
"tarsum": "tarsum.dev+foo:abcdef0919234",
"uuid": "D95306FA-FAD3-4E36-8D41-CF1C93EF8286", "uuid": "D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
}, },
}, },
{
RouteName: routeNameBlobUploadResume,
RequestURI: "/v2/foo/bar/blob/upload/RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==",
Vars: map[string]string{
"name": "foo/bar",
"uuid": "RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==",
},
},
{ {
// Check ambiguity: ensure we can distinguish between tags for // Check ambiguity: ensure we can distinguish between tags for
// "foo/bar/image/image" and image for "foo/bar/image" with tag // "foo/bar/image/image" and image for "foo/bar/image" with tag
// "tags" // "tags"
RouteName: routeNameImageManifest, RouteName: routeNameImageManifest,
RequestURI: "/v2/foo/bar/image/image/tags", RequestURI: "/v2/foo/bar/manifest/manifest/tags",
Vars: map[string]string{ Vars: map[string]string{
"name": "foo/bar/image", "name": "foo/bar/manifest",
"tag": "tags", "tag": "tags",
}, },
}, },
{ {
// This case presents an ambiguity between foo/bar with tag="tags" // This case presents an ambiguity between foo/bar with tag="tags"
// and list tags for "foo/bar/image" // and list tags for "foo/bar/manifest"
RouteName: routeNameTags, RouteName: routeNameTags,
RequestURI: "/v2/foo/bar/image/tags/list", RequestURI: "/v2/foo/bar/manifest/tags/list",
Vars: map[string]string{ Vars: map[string]string{
"name": "foo/bar/image", "name": "foo/bar/manifest",
}, },
}, },
{ {
RouteName: routeNameLayerUploadResume, RouteName: routeNameBlobUploadResume,
RequestURI: "/v2/foo/../../layer/tarsum.dev+foo:abcdef0919234/upload/D95306FA-FAD3-4E36-8D41-CF1C93EF8286", RequestURI: "/v2/foo/../../layer/upload/D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
Vars: map[string]string{
"name": "foo/bar",
"tarsum": "tarsum.dev+foo:abcdef0919234",
"uuid": "D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
},
StatusCode: http.StatusNotFound, StatusCode: http.StatusNotFound,
}, },
} { } {