forked from TrueCloudLab/distribution
Merge pull request #751 from stevvooe/update-routes
Update routes to reflect specification changes
This commit is contained in:
commit
ce91eabaab
6 changed files with 70 additions and 63 deletions
6
app.go
6
app.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
10
app_test.go
10
app_test.go
|
@ -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",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
1
layer.go
1
layer.go
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
42
routes.go
42
routes.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
|
Loading…
Reference in a new issue