forked from TrueCloudLab/distribution
commit
ef1c72b978
3 changed files with 206 additions and 14 deletions
141
docs/spec/api.md
141
docs/spec/api.md
|
@ -175,7 +175,6 @@ identify a set of modifications.
|
||||||
<li>Added error code for unsupported operations.</li>
|
<li>Added error code for unsupported operations.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
@ -727,7 +726,8 @@ delete may be issued with the following request format:
|
||||||
|
|
||||||
DELETE /v2/<name>/blobs/<digest>
|
DELETE /v2/<name>/blobs/<digest>
|
||||||
|
|
||||||
If the blob exists and has been successfully deleted, the following response will be issued:
|
If the blob exists and has been successfully deleted, the following response
|
||||||
|
will be issued:
|
||||||
|
|
||||||
202 Accepted
|
202 Accepted
|
||||||
Content-Length: None
|
Content-Length: None
|
||||||
|
@ -735,6 +735,8 @@ If the blob exists and has been successfully deleted, the following response wil
|
||||||
If the blob had already been deleted or did not exist, a `404 Not Found`
|
If the blob had already been deleted or did not exist, a `404 Not Found`
|
||||||
response will be issued instead.
|
response will be issued instead.
|
||||||
|
|
||||||
|
If a layer is deleted which is referenced by a manifest in the registry,
|
||||||
|
then the complete images will not be resolvable.
|
||||||
|
|
||||||
#### Pushing an Image Manifest
|
#### Pushing an Image Manifest
|
||||||
|
|
||||||
|
@ -1016,13 +1018,13 @@ A list of methods and URIs are covered in the table below:
|
||||||
| PUT | `/v2/<name>/manifests/<reference>` | Manifest | Put the manifest identified by `name` and `reference` where `reference` can be a tag or digest. |
|
| PUT | `/v2/<name>/manifests/<reference>` | Manifest | Put the manifest identified by `name` and `reference` where `reference` can be a tag or digest. |
|
||||||
| DELETE | `/v2/<name>/manifests/<reference>` | Manifest | Delete the manifest identified by `name` and `reference`. Note that a manifest can _only_ be deleted by `digest`. |
|
| DELETE | `/v2/<name>/manifests/<reference>` | Manifest | Delete the manifest identified by `name` and `reference`. Note that a manifest can _only_ be deleted by `digest`. |
|
||||||
| GET | `/v2/<name>/blobs/<digest>` | Blob | Retrieve the blob from the registry identified by `digest`. A `HEAD` request can also be issued to this endpoint to obtain resource information without receiving all data. |
|
| GET | `/v2/<name>/blobs/<digest>` | Blob | Retrieve the blob from the registry identified by `digest`. A `HEAD` request can also be issued to this endpoint to obtain resource information without receiving all data. |
|
||||||
|
| DELETE | `/v2/<name>/blobs/<digest>` | Blob | Delete the blob identified by `name` and `digest` |
|
||||||
| POST | `/v2/<name>/blobs/uploads/` | Initiate Blob Upload | Initiate a resumable blob upload. If successful, an upload location will be provided to complete the upload. Optionally, if the `digest` parameter is present, the request body will be used to complete the upload in a single request. |
|
| POST | `/v2/<name>/blobs/uploads/` | Initiate Blob Upload | Initiate a resumable blob upload. If successful, an upload location will be provided to complete the upload. Optionally, if the `digest` parameter is present, the request body will be used to complete the upload in a single request. |
|
||||||
| GET | `/v2/<name>/blobs/uploads/<uuid>` | Blob Upload | Retrieve status of upload identified by `uuid`. The primary purpose of this endpoint is to resolve the current status of a resumable upload. |
|
| GET | `/v2/<name>/blobs/uploads/<uuid>` | Blob Upload | Retrieve status of upload identified by `uuid`. The primary purpose of this endpoint is to resolve the current status of a resumable upload. |
|
||||||
| PATCH | `/v2/<name>/blobs/uploads/<uuid>` | Blob Upload | Upload a chunk of data for the specified upload. |
|
| PATCH | `/v2/<name>/blobs/uploads/<uuid>` | Blob Upload | Upload a chunk of data for the specified upload. |
|
||||||
| PUT | `/v2/<name>/blobs/uploads/<uuid>` | Blob Upload | Complete the upload specified by `uuid`, optionally appending the body as the final chunk. |
|
| PUT | `/v2/<name>/blobs/uploads/<uuid>` | Blob Upload | Complete the upload specified by `uuid`, optionally appending the body as the final chunk. |
|
||||||
| DELETE | `/v2/<name>/blobs/uploads/<uuid>` | Blob Upload | Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished uploads will eventually timeout. |
|
| DELETE | `/v2/<name>/blobs/uploads/<uuid>` | Blob Upload | Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished uploads will eventually timeout. |
|
||||||
| GET | `/v2/_catalog` | Catalog | Retrieve a sorted, json list of repositories available in the registry. |
|
| GET | `/v2/_catalog` | Catalog | Retrieve a sorted, json list of repositories available in the registry. |
|
||||||
| DELETE | `/v2/<name>/blobs/<digest>` | Blob delete | Delete the blob identified by `name` and `digest`|
|
|
||||||
|
|
||||||
|
|
||||||
The detail for each endpoint is covered in the following sections.
|
The detail for each endpoint is covered in the following sections.
|
||||||
|
@ -1374,7 +1376,7 @@ The error codes that may be included in the response body are enumerated below:
|
||||||
|
|
||||||
### Manifest
|
### Manifest
|
||||||
|
|
||||||
Create, update and retrieve manifests.
|
Create, update, delete and retrieve manifests.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1732,7 +1734,6 @@ The error codes that may be included in the response body are enumerated below:
|
||||||
|
|
||||||
#### DELETE Manifest
|
#### DELETE Manifest
|
||||||
|
|
||||||
|
|
||||||
Delete the manifest identified by `name` and `reference`. Note that a manifest can _only_ be deleted by `digest`.
|
Delete the manifest identified by `name` and `reference`. Note that a manifest can _only_ be deleted by `digest`.
|
||||||
|
|
||||||
|
|
||||||
|
@ -1874,7 +1875,7 @@ The error codes that may be included in the response body are enumerated below:
|
||||||
|
|
||||||
### Blob
|
### Blob
|
||||||
|
|
||||||
Fetch the blob identified by `name` and `digest`. Used to fetch layers by digest.
|
Operations on blobs identified by `name` and `digest`. Used to fetch or delete layers by digest.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2207,6 +2208,134 @@ The range specification cannot be satisfied for the requested content. This can
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### DELETE Blob
|
||||||
|
|
||||||
|
Delete the blob identified by `name` and `digest`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
DELETE /v2/<name>/blobs/<digest>
|
||||||
|
Host: <registry host>
|
||||||
|
Authorization: <scheme> <token>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The following parameters should be specified on the request:
|
||||||
|
|
||||||
|
|Name|Kind|Description|
|
||||||
|
|----|----|-----------|
|
||||||
|
|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.|
|
||||||
|
|`Authorization`|header|An RFC7235 compliant authorization header.|
|
||||||
|
|`name`|path|Name of the target repository.|
|
||||||
|
|`digest`|path|Digest of desired blob.|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###### On Success: Accepted
|
||||||
|
|
||||||
|
```
|
||||||
|
202 Accepted
|
||||||
|
Content-Length: 0
|
||||||
|
Docker-Content-Digest: <digest>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The following headers will be returned with the response:
|
||||||
|
|
||||||
|
|Name|Description|
|
||||||
|
|----|-----------|
|
||||||
|
|`Content-Length`|Zero|
|
||||||
|
|`Docker-Content-Digest`|Digest of the targeted content for the request.|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###### On Failure: Invalid Name or Digest
|
||||||
|
|
||||||
|
```
|
||||||
|
400 Bad Request
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The error codes that may be included in the response body are enumerated below:
|
||||||
|
|
||||||
|
|Code|Message|Description|
|
||||||
|
|----|-------|-----------|
|
||||||
|
| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. |
|
||||||
|
| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###### On Failure: Not Found
|
||||||
|
|
||||||
|
```
|
||||||
|
404 Not Found
|
||||||
|
Content-Type: application/json; charset=utf-8
|
||||||
|
|
||||||
|
{
|
||||||
|
"errors:" [
|
||||||
|
{
|
||||||
|
"code": <error code>,
|
||||||
|
"message": "<error message>",
|
||||||
|
"detail": ...
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The blob, identified by `name` and `digest`, is unknown to the registry.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The error codes that may be included in the response body are enumerated below:
|
||||||
|
|
||||||
|
|Code|Message|Description|
|
||||||
|
|----|-------|-----------|
|
||||||
|
| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. |
|
||||||
|
| `BLOB_UNKNOWN` | blob unknown to registry | This error may be returned when a blob is unknown to the registry in a specified repository. This can be returned with a standard get or if a manifest references an unknown layer during upload. |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###### On Failure: Method Not Allowed
|
||||||
|
|
||||||
|
```
|
||||||
|
405 Method Not Allowed
|
||||||
|
Content-Type: application/json; charset=utf-8
|
||||||
|
|
||||||
|
{
|
||||||
|
"errors:" [
|
||||||
|
{
|
||||||
|
"code": <error code>,
|
||||||
|
"message": "<error message>",
|
||||||
|
"detail": ...
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Delete is not enabled on the registry
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The error codes that may be included in the response body are enumerated below:
|
||||||
|
|
||||||
|
|Code|Message|Description|
|
||||||
|
|----|-------|-----------|
|
||||||
|
| `UNSUPPORTED` | The operation is unsupported. | The operation was unsupported due to a missing implementation or invalid set of parameters. |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Initiate Blob Upload
|
### Initiate Blob Upload
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,7 @@ API. When this header is omitted, clients may fallback to an older API version.
|
||||||
|
|
||||||
This API design is driven heavily by [content addressability](http://en.wikipedia.org/wiki/Content-addressable_storage).
|
This API design is driven heavily by [content addressability](http://en.wikipedia.org/wiki/Content-addressable_storage).
|
||||||
The core of this design is the concept of a content addressable identifier. It
|
The core of this design is the concept of a content addressable identifier. It
|
||||||
uniquely identifies content by taking a collision-resistent hash of the bytes.
|
uniquely identifies content by taking a collision-resistant hash of the bytes.
|
||||||
Such an identifier can be independently calculated and verified by selection
|
Such an identifier can be independently calculated and verified by selection
|
||||||
of a common _algorithm_. If such an identifier can be communicated in a secure
|
of a common _algorithm_. If such an identifier can be communicated in a secure
|
||||||
manner, one can retrieve the content from an insecure source, calculate it
|
manner, one can retrieve the content from an insecure source, calculate it
|
||||||
|
@ -791,7 +791,7 @@ Images are stored in collections, known as a _repository_, which is keyed by a
|
||||||
contain several repositories. The list of available repositories is made
|
contain several repositories. The list of available repositories is made
|
||||||
available through the _catalog_.
|
available through the _catalog_.
|
||||||
|
|
||||||
The catalog for a given registry can be retrived with the following request:
|
The catalog for a given registry can be retrieved with the following request:
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /v2/_catalog
|
GET /v2/_catalog
|
||||||
|
@ -875,7 +875,7 @@ To get the next result set, a client would issue the request as follows, using
|
||||||
the URL encoded in the described `Link` header:
|
the URL encoded in the described `Link` header:
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /v2/_catalog?n=<n from the request>&last=<last repostory value from previous response>
|
GET /v2/_catalog?n=<n from the request>&last=<last repository value from previous response>
|
||||||
```
|
```
|
||||||
|
|
||||||
The above process should then be repeated until the `Link` header is no longer
|
The above process should then be repeated until the `Link` header is no longer
|
||||||
|
|
|
@ -519,7 +519,7 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
Name: RouteNameManifest,
|
Name: RouteNameManifest,
|
||||||
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/manifests/{reference:" + TagNameRegexp.String() + "|" + digest.DigestRegexp.String() + "}",
|
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/manifests/{reference:" + TagNameRegexp.String() + "|" + digest.DigestRegexp.String() + "}",
|
||||||
Entity: "Manifest",
|
Entity: "Manifest",
|
||||||
Description: "Create, update and retrieve manifests.",
|
Description: "Create, update, delete and retrieve manifests.",
|
||||||
Methods: []MethodDescriptor{
|
Methods: []MethodDescriptor{
|
||||||
{
|
{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
|
@ -536,7 +536,7 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
},
|
},
|
||||||
Successes: []ResponseDescriptor{
|
Successes: []ResponseDescriptor{
|
||||||
{
|
{
|
||||||
Description: "The manifest idenfied by `name` and `reference`. The contents can be used to identify and resolve resources required to run the specified image.",
|
Description: "The manifest identified by `name` and `reference`. The contents can be used to identify and resolve resources required to run the specified image.",
|
||||||
StatusCode: http.StatusOK,
|
StatusCode: http.StatusOK,
|
||||||
Headers: []ParameterDescriptor{
|
Headers: []ParameterDescriptor{
|
||||||
digestHeader,
|
digestHeader,
|
||||||
|
@ -768,9 +768,8 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
Name: RouteNameBlob,
|
Name: RouteNameBlob,
|
||||||
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/{digest:" + digest.DigestRegexp.String() + "}",
|
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/{digest:" + digest.DigestRegexp.String() + "}",
|
||||||
Entity: "Blob",
|
Entity: "Blob",
|
||||||
Description: "Fetch the blob identified by `name` and `digest`. Used to fetch layers by digest.",
|
Description: "Operations on blobs identified by `name` and `digest`. Used to fetch or delete layers by digest.",
|
||||||
Methods: []MethodDescriptor{
|
Methods: []MethodDescriptor{
|
||||||
|
|
||||||
{
|
{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
Description: "Retrieve the blob from the registry identified by `digest`. A `HEAD` request can also be issued to this endpoint to obtain resource information without receiving all data.",
|
Description: "Retrieve the blob from the registry identified by `digest`. A `HEAD` request can also be issued to this endpoint to obtain resource information without receiving all data.",
|
||||||
|
@ -919,6 +918,70 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: "DELETE",
|
||||||
|
Description: "Delete the blob identified by `name` and `digest`",
|
||||||
|
Requests: []RequestDescriptor{
|
||||||
|
{
|
||||||
|
Headers: []ParameterDescriptor{
|
||||||
|
hostHeader,
|
||||||
|
authHeader,
|
||||||
|
},
|
||||||
|
PathParameters: []ParameterDescriptor{
|
||||||
|
nameParameterDescriptor,
|
||||||
|
digestPathParameter,
|
||||||
|
},
|
||||||
|
Successes: []ResponseDescriptor{
|
||||||
|
{
|
||||||
|
StatusCode: http.StatusAccepted,
|
||||||
|
Headers: []ParameterDescriptor{
|
||||||
|
{
|
||||||
|
Name: "Content-Length",
|
||||||
|
Type: "integer",
|
||||||
|
Description: "0",
|
||||||
|
Format: "0",
|
||||||
|
},
|
||||||
|
digestHeader,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Failures: []ResponseDescriptor{
|
||||||
|
{
|
||||||
|
Name: "Invalid Name or Digest",
|
||||||
|
StatusCode: http.StatusBadRequest,
|
||||||
|
ErrorCodes: []errcode.ErrorCode{
|
||||||
|
ErrorCodeDigestInvalid,
|
||||||
|
ErrorCodeNameInvalid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Description: "The blob, identified by `name` and `digest`, is unknown to the registry.",
|
||||||
|
StatusCode: http.StatusNotFound,
|
||||||
|
Body: BodyDescriptor{
|
||||||
|
ContentType: "application/json; charset=utf-8",
|
||||||
|
Format: errorsBody,
|
||||||
|
},
|
||||||
|
ErrorCodes: []errcode.ErrorCode{
|
||||||
|
ErrorCodeNameUnknown,
|
||||||
|
ErrorCodeBlobUnknown,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Description: "Delete is not enabled on the registry",
|
||||||
|
StatusCode: http.StatusMethodNotAllowed,
|
||||||
|
Body: BodyDescriptor{
|
||||||
|
ContentType: "application/json; charset=utf-8",
|
||||||
|
Format: errorsBody,
|
||||||
|
},
|
||||||
|
ErrorCodes: []errcode.ErrorCode{
|
||||||
|
ErrorCodeUnsupported,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// TODO(stevvooe): We may want to add a PUT request here to
|
// TODO(stevvooe): We may want to add a PUT request here to
|
||||||
// kickoff an upload of a blob, integrated with the blob upload
|
// kickoff an upload of a blob, integrated with the blob upload
|
||||||
// API.
|
// API.
|
||||||
|
@ -928,7 +991,7 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
{
|
{
|
||||||
Name: RouteNameBlobUpload,
|
Name: RouteNameBlobUpload,
|
||||||
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/uploads/",
|
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/uploads/",
|
||||||
Entity: "Intiate Blob Upload",
|
Entity: "Initiate Blob Upload",
|
||||||
Description: "Initiate a blob upload. This endpoint can be used to create resumable uploads or monolithic uploads.",
|
Description: "Initiate a blob upload. This endpoint can be used to create resumable uploads or monolithic uploads.",
|
||||||
Methods: []MethodDescriptor{
|
Methods: []MethodDescriptor{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue