Update spec to include tag history endpoint#606
Update spec to include tag history endpoint#606jcarter3 wants to merge 1 commit intoopencontainers:mainfrom
Conversation
ba1f62d to
dd534be
Compare
|
|
||
| Specifies the maximum number of results to return. | ||
| The registry MAY return fewer results than requested if fewer historical entries exist. | ||
| When `n` is zero, this endpoint MUST return an empty array. |
There was a problem hiding this comment.
| When `n` is zero, this endpoint MUST return an empty array. | |
| When `n` is zero, this endpoint MUST return an empty array, useful for determining if history is available (200) or not (404) for the tag query. |
| When `n` is zero, this endpoint MUST return an empty array. | ||
| When `n` is not specified, the registry MAY apply a default limit. | ||
|
|
||
| - **`before`** *string (RFC 3339 timestamp)*, OPTIONAL |
There was a problem hiding this comment.
maybe from or ot (older than)
| - **`before`** *string (RFC 3339 timestamp)*, OPTIONAL | |
| - **`ot`** *string (RFC 3339 timestamp)*, OPTIONAL |
|
|
||
| - **`before`** *string (RFC 3339 timestamp)*, OPTIONAL | ||
|
|
||
| When provided, only entries whose `org.opencontainers.tag.created` value is strictly less than (i.e. older than) `before` will be returned. |
There was a problem hiding this comment.
| When provided, only entries whose `org.opencontainers.tag.created` value is strictly less than (i.e. older than) `before` will be returned. | |
| When provided, only entries whose `org.opencontainers.tag.created` value is strictly less than (i.e. older than) the `ot` timestamp will be returned. |
| When `n` is zero, this endpoint MUST return an empty array. | ||
| When `n` is not specified, the registry MAY apply a default limit. | ||
|
|
||
| - **`before`** *string (RFC 3339 timestamp)*, OPTIONAL |
There was a problem hiding this comment.
is there a chance to have two results with the exact same time stamp..
|
|
||
| When provided, only entries whose `org.opencontainers.tag.created` value is strictly less than (i.e. older than) `before` will be returned. | ||
| This is used for time-based pagination: pass the `org.opencontainers.tag.created` value of the last entry returned in the previous response to retrieve the next page. | ||
|
|
There was a problem hiding this comment.
another idea would be to include a "newer-than" option, or a "between" timestamp1/timestamp2 allowing a client to query new tags or a time range..
Signed-off-by: Jeff Carter <jeff.carter@docker.com>
sudo-bmitch
left a comment
There was a problem hiding this comment.
Here's some early feedback. I still need to spend some time implementing this before considering approving, and we need a conformance test.
| Tag history MAY be retrieved with a standard `GET` as follows. | ||
|
|
||
| ```HTTP | ||
| GET /v2/<name>/_oci/tag-history/<tag> |
There was a problem hiding this comment.
I think <component>=tag, <module>=history, and use parameters for passing the tag, better follows the extensions syntax documented at https://github.com/opencontainers/distribution-spec/tree/main/extensions#repository-level-extensions
| GET /v2/<name>/_oci/tag-history/<tag> | |
| GET /v2/<name>/_oci/tag/history/?tag=<tag> |
(Note that I personally wish we weren't so prescriptive and only specified the extension is _<extension> with everything after that being implementation defined, but I suspect I lost that battle when we added extensions to the spec.)
There was a problem hiding this comment.
How hard is it to push back and change this? That design makes every downstream extension significantly worse. If there aren't any defined extensions yet, it should be possible?
There was a problem hiding this comment.
Looking back at the PR where we introduced them, I'd want to pull in other maintainers like @stevvooe to weigh in: #111 (comment)
|
|
||
| A successful request MUST return a `200 OK` response code. | ||
| If the repository does not exist, the registry MUST return a `404 Not Found` response code. | ||
| If the tag has no history, the registry MUST return a `404 Not Found` response code. |
There was a problem hiding this comment.
| If the tag has no history, the registry MUST return a `404 Not Found` response code. | |
| If the tag has no history or the registry does not implement this extension, the registry MUST return a `404 Not Found` response code. |
| If the repository does not exist, the registry MUST return a `404 Not Found` response code. | ||
| If the tag has no history, the registry MUST return a `404 Not Found` response code. | ||
| Tag history SHOULD remain queryable after the tag is deleted. | ||
| Deleted manifests MUST NOT be removed from tag history. |
There was a problem hiding this comment.
MUST feels a bit strong here, and may break some retention and redaction requirements of some registries.
| Deleted manifests MUST NOT be removed from tag history. | |
| Deleted manifests SHOULD NOT be removed from tag history. |
| If the tag has no history, the registry MUST return a `404 Not Found` response code. | ||
| Tag history SHOULD remain queryable after the tag is deleted. | ||
| Deleted manifests MUST NOT be removed from tag history. | ||
| History entries for deleted manifests MUST continue to include the descriptor fields recorded when the tag was assigned to the manifest. |
There was a problem hiding this comment.
Is this rephrasing the previous line? If so, I'd consolidate the two, with a "SHOULD".
| ] | ||
| ``` | ||
|
|
||
| Results MUST be sorted in descending order by the history entry timestamp, which is either the `org.opencontainers.tag.created` annotation value or the `org.opencontainers.tag.deleted` annotation value (i.e. the most recent entry appears first). |
There was a problem hiding this comment.
In image spec, we use the prefix org.opencontainers.image. For distribution, perhaps we should standardize on org.opencontainers.distribution to avoid conflicts with other specs?
|
|
||
| Results MUST be sorted in descending order by the history entry timestamp, which is either the `org.opencontainers.tag.created` annotation value or the `org.opencontainers.tag.deleted` annotation value (i.e. the most recent entry appears first). | ||
|
|
||
| Each descriptor object in the response MUST be either a manifest descriptor or a delete marker. |
There was a problem hiding this comment.
| Each descriptor object in the response MUST be either a manifest descriptor or a delete marker. | |
| Each descriptor object in the response MUST be either a create or delete entry. |
|
|
||
| Each descriptor object in the response MUST be either a manifest descriptor or a delete marker. | ||
|
|
||
| Manifest descriptors MUST include the following properties: |
There was a problem hiding this comment.
| Manifest descriptors MUST include the following properties: | |
| Tag create entries, which includes replacing an existing tag, MUST include the following properties: |
|
|
||
| The RFC 3339 timestamp at which the tag was assigned to this manifest. Used as the sort key and as the cursor for time-based pagination. | ||
|
|
||
| Delete markers MUST be represented by the OCI empty descriptor and MUST include the following properties: |
There was a problem hiding this comment.
| Delete markers MUST be represented by the OCI empty descriptor and MUST include the following properties: | |
| Tag delete entries MUST include the following properties: |
| - **`mediaType`** *string*, REQUIRED | ||
|
|
||
| MUST be `application/vnd.oci.empty.v1+json`. | ||
|
|
||
| - **`digest`** *string*, REQUIRED | ||
|
|
||
| MUST be `sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a`. | ||
|
|
||
| - **`size`** *integer*, REQUIRED | ||
|
|
||
| MUST be `2`. | ||
|
|
||
| - **`data`** *string*, REQUIRED | ||
|
|
||
| MUST be `e30=`. | ||
|
|
||
| - **`annotations`** *map of strings*, REQUIRED | ||
|
|
||
| Annotations associated with the historical tag entry. MUST include: | ||
|
|
||
| - **`org.opencontainers.tag.deleted`** *string*, REQUIRED | ||
|
|
||
| The RFC 3339 timestamp at which the tag was deleted. Used as the sort key and as the cursor for time-based pagination. |
There was a problem hiding this comment.
I'd rephrase to use the descriptor of the deleted entry. And now with so much overlap, I think we can probably merge the two create/delete sections and then document the two possible annotations.
| - **`mediaType`** *string*, REQUIRED | |
| MUST be `application/vnd.oci.empty.v1+json`. | |
| - **`digest`** *string*, REQUIRED | |
| MUST be `sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a`. | |
| - **`size`** *integer*, REQUIRED | |
| MUST be `2`. | |
| - **`data`** *string*, REQUIRED | |
| MUST be `e30=`. | |
| - **`annotations`** *map of strings*, REQUIRED | |
| Annotations associated with the historical tag entry. MUST include: | |
| - **`org.opencontainers.tag.deleted`** *string*, REQUIRED | |
| The RFC 3339 timestamp at which the tag was deleted. Used as the sort key and as the cursor for time-based pagination. | |
| - **`mediaType`** *string*, REQUIRED | |
| The media type of the manifest this tag previously pointed to at that point in time. | |
| - **`size`** *integer*, REQUIRED | |
| The size in bytes of the manifest. | |
| - **`digest`** *string*, REQUIRED | |
| The digest of the manifest, in the form `<algorithm>:<encoded>`. | |
| - **`annotations`** *map of strings*, REQUIRED | |
| Annotations associated with the historical tag entry. MUST include: | |
| - **`org.opencontainers.distribution.tag.deleted`** *string*, REQUIRED | |
| The RFC 3339 timestamp at which the tag was deleted. Used as the sort key and as the cursor for time-based pagination. |
Updates distribution spec to include new endpoint for retrieving the history of a given tag. The response is a json list of descriptors,including the created timestamp and sorted in descending order (newest first).
The list can be paged.