Pluralize route API paths
During the specification period, it was suggested that pluralized object names are more idiomatic in APIs than singular. This changeset simply adopts that preference for the API going forward. The client has been updated to remain compatible.master
							parent
							
								
									500d11564b
								
							
						
					
					
						commit
						2a16a2ff6a
					
				|  | @ -222,7 +222,7 @@ func (r *clientImpl) ListImageTags(name string) ([]string, error) { | |||
| } | ||||
| 
 | ||||
| func (r *clientImpl) BlobLength(name string, dgst digest.Digest) (int, error) { | ||||
| 	response, err := http.Head(fmt.Sprintf("%s/v2/%s/blob/%s", r.Endpoint, name, dgst)) | ||||
| 	response, err := http.Head(fmt.Sprintf("%s/v2/%s/blobs/%s", r.Endpoint, name, dgst)) | ||||
| 	if err != nil { | ||||
| 		return -1, err | ||||
| 	} | ||||
|  | @ -255,7 +255,7 @@ func (r *clientImpl) BlobLength(name string, dgst digest.Digest) (int, error) { | |||
| 
 | ||||
| func (r *clientImpl) GetBlob(name string, dgst digest.Digest, byteOffset int) (io.ReadCloser, int, error) { | ||||
| 	getRequest, err := http.NewRequest("GET", | ||||
| 		fmt.Sprintf("%s/v2/%s/blob/%s", r.Endpoint, name, dgst), nil) | ||||
| 		fmt.Sprintf("%s/v2/%s/blobs/%s", r.Endpoint, name, dgst), nil) | ||||
| 	if err != nil { | ||||
| 		return nil, 0, err | ||||
| 	} | ||||
|  | @ -294,7 +294,7 @@ func (r *clientImpl) GetBlob(name string, dgst digest.Digest, byteOffset int) (i | |||
| 
 | ||||
| func (r *clientImpl) InitiateBlobUpload(name string) (string, error) { | ||||
| 	postRequest, err := http.NewRequest("POST", | ||||
| 		fmt.Sprintf("%s/v2/%s/blob/upload/", r.Endpoint, name), nil) | ||||
| 		fmt.Sprintf("%s/v2/%s/blobs/uploads/", r.Endpoint, name), nil) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | @ -519,7 +519,7 @@ func (r *clientImpl) CancelBlobUpload(location string) error { | |||
| // imageManifestURL is a helper method for returning the full url to an image
 | ||||
| // manifest
 | ||||
| func (r *clientImpl) imageManifestURL(name, tag string) string { | ||||
| 	return fmt.Sprintf("%s/v2/%s/manifest/%s", r.Endpoint, name, tag) | ||||
| 	return fmt.Sprintf("%s/v2/%s/manifests/%s", r.Endpoint, name, tag) | ||||
| } | ||||
| 
 | ||||
| // parseRangeHeader parses out the offset and length from a returned Range
 | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ func TestPush(t *testing.T) { | |||
| 		// because we can't know which blob will get which location.
 | ||||
| 		// It's sort of okay because we're using unique digests, but this needs
 | ||||
| 		// to change at some point.
 | ||||
| 		uploadLocations[i] = fmt.Sprintf("/v2/%s/blob/test-uuid", name) | ||||
| 		uploadLocations[i] = fmt.Sprintf("/v2/%s/blobs/test-uuid", name) | ||||
| 		blobs[i] = storage.FSLayer{BlobSum: blob.digest} | ||||
| 		history[i] = storage.ManifestHistory{V1Compatibility: blob.digest.String()} | ||||
| 	} | ||||
|  | @ -66,7 +66,7 @@ func TestPush(t *testing.T) { | |||
| 		blobRequestResponseMappings[2*i] = testutil.RequestResponseMapping{ | ||||
| 			Request: testutil.Request{ | ||||
| 				Method: "POST", | ||||
| 				Route:  "/v2/" + name + "/blob/upload/", | ||||
| 				Route:  "/v2/" + name + "/blobs/uploads/", | ||||
| 			}, | ||||
| 			Response: testutil.Response{ | ||||
| 				StatusCode: http.StatusAccepted, | ||||
|  | @ -94,7 +94,7 @@ func TestPush(t *testing.T) { | |||
| 	handler := testutil.NewHandler(append(blobRequestResponseMappings, testutil.RequestResponseMapping{ | ||||
| 		Request: testutil.Request{ | ||||
| 			Method: "PUT", | ||||
| 			Route:  "/v2/" + name + "/manifest/" + tag, | ||||
| 			Route:  "/v2/" + name + "/manifests/" + tag, | ||||
| 			Body:   manifest.Raw, | ||||
| 		}, | ||||
| 		Response: testutil.Response{ | ||||
|  | @ -185,7 +185,7 @@ func TestPull(t *testing.T) { | |||
| 		blobRequestResponseMappings[i] = testutil.RequestResponseMapping{ | ||||
| 			Request: testutil.Request{ | ||||
| 				Method: "GET", | ||||
| 				Route:  "/v2/" + name + "/blob/" + blob.digest.String(), | ||||
| 				Route:  "/v2/" + name + "/blobs/" + blob.digest.String(), | ||||
| 			}, | ||||
| 			Response: testutil.Response{ | ||||
| 				StatusCode: http.StatusOK, | ||||
|  | @ -197,7 +197,7 @@ func TestPull(t *testing.T) { | |||
| 	handler := testutil.NewHandler(append(blobRequestResponseMappings, testutil.RequestResponseMapping{ | ||||
| 		Request: testutil.Request{ | ||||
| 			Method: "GET", | ||||
| 			Route:  "/v2/" + name + "/manifest/" + tag, | ||||
| 			Route:  "/v2/" + name + "/manifests/" + tag, | ||||
| 		}, | ||||
| 		Response: testutil.Response{ | ||||
| 			StatusCode: http.StatusOK, | ||||
|  | @ -292,7 +292,7 @@ func TestPullResume(t *testing.T) { | |||
| 		layerRequestResponseMappings[2*i] = testutil.RequestResponseMapping{ | ||||
| 			Request: testutil.Request{ | ||||
| 				Method: "GET", | ||||
| 				Route:  "/v2/" + name + "/blob/" + blob.digest.String(), | ||||
| 				Route:  "/v2/" + name + "/blobs/" + blob.digest.String(), | ||||
| 			}, | ||||
| 			Response: testutil.Response{ | ||||
| 				StatusCode: http.StatusOK, | ||||
|  | @ -305,7 +305,7 @@ func TestPullResume(t *testing.T) { | |||
| 		layerRequestResponseMappings[2*i+1] = testutil.RequestResponseMapping{ | ||||
| 			Request: testutil.Request{ | ||||
| 				Method: "GET", | ||||
| 				Route:  "/v2/" + name + "/blob/" + blob.digest.String(), | ||||
| 				Route:  "/v2/" + name + "/blobs/" + blob.digest.String(), | ||||
| 			}, | ||||
| 			Response: testutil.Response{ | ||||
| 				StatusCode: http.StatusOK, | ||||
|  | @ -318,7 +318,7 @@ func TestPullResume(t *testing.T) { | |||
| 		layerRequestResponseMappings = append(layerRequestResponseMappings, testutil.RequestResponseMapping{ | ||||
| 			Request: testutil.Request{ | ||||
| 				Method: "GET", | ||||
| 				Route:  "/v2/" + name + "/manifest/" + tag, | ||||
| 				Route:  "/v2/" + name + "/manifests/" + tag, | ||||
| 			}, | ||||
| 			Response: testutil.Response{ | ||||
| 				StatusCode: http.StatusOK, | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ func v2APIRouter() *mux.Router { | |||
| 	// PUT      /v2/<name>/manifest/<tag>	Image Manifest	Upload the image manifest identified by name and tag.
 | ||||
| 	// DELETE   /v2/<name>/manifest/<tag>	Image Manifest	Delete the image identified by name and tag.
 | ||||
| 	router. | ||||
| 		Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/manifest/{tag:" + common.TagNameRegexp.String() + "}"). | ||||
| 		Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/manifests/{tag:" + common.TagNameRegexp.String() + "}"). | ||||
| 		Name(routeNameImageManifest) | ||||
| 
 | ||||
| 	// GET	/v2/<name>/tags/list	Tags	Fetch the tags under the repository identified by name.
 | ||||
|  | @ -41,19 +41,19 @@ func v2APIRouter() *mux.Router { | |||
| 
 | ||||
| 	// GET	/v2/<name>/blob/<digest>	Layer	Fetch the blob identified by digest.
 | ||||
| 	router. | ||||
| 		Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blob/{digest:[a-zA-Z0-9-_+.]+:[a-zA-Z0-9-_+.=]+}"). | ||||
| 		Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blobs/{digest:[a-zA-Z0-9-_+.]+:[a-zA-Z0-9-_+.=]+}"). | ||||
| 		Name(routeNameBlob) | ||||
| 
 | ||||
| 	// POST	/v2/<name>/blob/upload/	Layer Upload	Initiate an upload of the layer identified by tarsum.
 | ||||
| 	router. | ||||
| 		Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blob/upload/"). | ||||
| 		Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blobs/uploads/"). | ||||
| 		Name(routeNameBlobUpload) | ||||
| 
 | ||||
| 	// GET	/v2/<name>/blob/upload/<uuid>	Layer Upload	Get the status 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>/blob/upload/<uuid>	Layer Upload	Cancel the upload identified by layer and uuid
 | ||||
| 	router. | ||||
| 		Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blob/upload/{uuid}"). | ||||
| 		Path("/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blobs/uploads/{uuid}"). | ||||
| 		Name(routeNameBlobUploadResume) | ||||
| 
 | ||||
| 	return router | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ func TestRouter(t *testing.T) { | |||
| 	for _, testcase := range []routeTestCase{ | ||||
| 		{ | ||||
| 			RouteName:  routeNameImageManifest, | ||||
| 			RequestURI: "/v2/foo/bar/manifest/tag", | ||||
| 			RequestURI: "/v2/foo/bar/manifests/tag", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name": "foo/bar", | ||||
| 				"tag":  "tag", | ||||
|  | @ -63,7 +63,7 @@ func TestRouter(t *testing.T) { | |||
| 		}, | ||||
| 		{ | ||||
| 			RouteName:  routeNameBlob, | ||||
| 			RequestURI: "/v2/foo/bar/blob/tarsum.dev+foo:abcdef0919234", | ||||
| 			RequestURI: "/v2/foo/bar/blobs/tarsum.dev+foo:abcdef0919234", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name":   "foo/bar", | ||||
| 				"digest": "tarsum.dev+foo:abcdef0919234", | ||||
|  | @ -71,7 +71,7 @@ func TestRouter(t *testing.T) { | |||
| 		}, | ||||
| 		{ | ||||
| 			RouteName:  routeNameBlob, | ||||
| 			RequestURI: "/v2/foo/bar/blob/sha256:abcdef0919234", | ||||
| 			RequestURI: "/v2/foo/bar/blobs/sha256:abcdef0919234", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name":   "foo/bar", | ||||
| 				"digest": "sha256:abcdef0919234", | ||||
|  | @ -79,14 +79,14 @@ func TestRouter(t *testing.T) { | |||
| 		}, | ||||
| 		{ | ||||
| 			RouteName:  routeNameBlobUpload, | ||||
| 			RequestURI: "/v2/foo/bar/blob/upload/", | ||||
| 			RequestURI: "/v2/foo/bar/blobs/uploads/", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name": "foo/bar", | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			RouteName:  routeNameBlobUploadResume, | ||||
| 			RequestURI: "/v2/foo/bar/blob/upload/uuid", | ||||
| 			RequestURI: "/v2/foo/bar/blobs/uploads/uuid", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name": "foo/bar", | ||||
| 				"uuid": "uuid", | ||||
|  | @ -94,7 +94,7 @@ func TestRouter(t *testing.T) { | |||
| 		}, | ||||
| 		{ | ||||
| 			RouteName:  routeNameBlobUploadResume, | ||||
| 			RequestURI: "/v2/foo/bar/blob/upload/D95306FA-FAD3-4E36-8D41-CF1C93EF8286", | ||||
| 			RequestURI: "/v2/foo/bar/blobs/uploads/D95306FA-FAD3-4E36-8D41-CF1C93EF8286", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name": "foo/bar", | ||||
| 				"uuid": "D95306FA-FAD3-4E36-8D41-CF1C93EF8286", | ||||
|  | @ -102,7 +102,7 @@ func TestRouter(t *testing.T) { | |||
| 		}, | ||||
| 		{ | ||||
| 			RouteName:  routeNameBlobUploadResume, | ||||
| 			RequestURI: "/v2/foo/bar/blob/upload/RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==", | ||||
| 			RequestURI: "/v2/foo/bar/blobs/uploads/RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name": "foo/bar", | ||||
| 				"uuid": "RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==", | ||||
|  | @ -113,9 +113,9 @@ func TestRouter(t *testing.T) { | |||
| 			// "foo/bar/image/image" and image for "foo/bar/image" with tag
 | ||||
| 			// "tags"
 | ||||
| 			RouteName:  routeNameImageManifest, | ||||
| 			RequestURI: "/v2/foo/bar/manifest/manifest/tags", | ||||
| 			RequestURI: "/v2/foo/bar/manifests/manifests/tags", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name": "foo/bar/manifest", | ||||
| 				"name": "foo/bar/manifests", | ||||
| 				"tag":  "tags", | ||||
| 			}, | ||||
| 		}, | ||||
|  | @ -123,14 +123,14 @@ func TestRouter(t *testing.T) { | |||
| 			// This case presents an ambiguity between foo/bar with tag="tags"
 | ||||
| 			// and list tags for "foo/bar/manifest"
 | ||||
| 			RouteName:  routeNameTags, | ||||
| 			RequestURI: "/v2/foo/bar/manifest/tags/list", | ||||
| 			RequestURI: "/v2/foo/bar/manifests/tags/list", | ||||
| 			Vars: map[string]string{ | ||||
| 				"name": "foo/bar/manifest", | ||||
| 				"name": "foo/bar/manifests", | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			RouteName:  routeNameBlobUploadResume, | ||||
| 			RequestURI: "/v2/foo/../../layer/upload/D95306FA-FAD3-4E36-8D41-CF1C93EF8286", | ||||
| 			RequestURI: "/v2/foo/../../blob/uploads/D95306FA-FAD3-4E36-8D41-CF1C93EF8286", | ||||
| 			StatusCode: http.StatusNotFound, | ||||
| 		}, | ||||
| 	} { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue