Conversation
docs/spec/api.md.tmpl
Outdated
| for an image repository can be retrieved with the following request: | ||
|
|
||
| GET /v2/<name>/tags/list | ||
| GET /v2/<name>/tags/_list |
There was a problem hiding this comment.
This doesn't match was was added above. Please make sure to regenerate from the template.
There was a problem hiding this comment.
I did not realize that one was generated from another so both were updated manually, What is the process to generate .md from .md.tpl?
docs/spec/api.md.tmpl
Outdated
| issued: | ||
|
|
||
| 202 Accepted | ||
| Content-Length: None |
There was a problem hiding this comment.
Do we really do None for Content-Length? How about 0?
docs/spec/api.md.tmpl
Outdated
| If the tag had already been deleted or did not exist, a `404 Not Found` | ||
| response will be issued instead. | ||
|
|
||
| > **Note** Manifests can never be deleted using this call. If you delete all |
There was a problem hiding this comment.
While writing for the API user helps, please target the implementer of the specification.
There was a problem hiding this comment.
Do you mean no need for that note?
There was a problem hiding this comment.
Well, just explain that the endpoint should not delete the manifest, but the reference from tag to the manifest, so something like that. This doesn't even need to be a note.
registry/handlers/tags_list.go
Outdated
| @@ -0,0 +1,62 @@ | |||
| package handlers | |||
There was a problem hiding this comment.
Let's not make a separate file for this.
There was a problem hiding this comment.
Are you sure? These are two different Dispatchers, but I am fine either way.
There was a problem hiding this comment.
That is okay to have two separate dispatchers in the same file. Its nice to have everything related to tags in the same file.
I'd also have a not about what is going on here (redirect) + some historical context.
registry/handlers/tags.go
Outdated
| } | ||
|
|
||
| // GetTags returns a json list of tags for a specific image name. | ||
| func (th *tagsHandler) GetTags(w http.ResponseWriter, r *http.Request) { |
|
@sergeyfd Could you open a road map issue with the steps in the description to tie this all together? |
|
I am 👎 to migrating docker to |
|
So what is the process of generating .md from that template? And what is a road map issue? Is it just a regular issue with the [ROADMAP] in the name or is it something special? Sorry for the novice questions. |
docs/spec/api.md
Outdated
|
|
||
| #### DELETE Tags | ||
|
|
||
| Delete the that identified by `name` and `tag`. |
|
@sergeyfd Just make an issue describing the steps with some checkboxes. Next to each step, include the related PRs. As far as generating the api.md goes, just use @dmcgowan Clients should be able to handle a simple redirect. Does that not work? As far as API versioning goes, this should be fully compatible. Old clients will redirect and new clients can try one then the other. This is better than version negotiation; it is active discovery. |
|
Does it look better now? |
| func (th *tagsHandler) GetTagsCompat(w http.ResponseWriter, r *http.Request) { | ||
| ctxu.GetLogger(th).Debug("GetTags") | ||
|
|
||
| if th.Tag == "list" { |
There was a problem hiding this comment.
Provide a little comment about why.
| Tags []string `json:"tags"` | ||
| } | ||
|
|
||
| func (th *tagsHandler) GetTagsCompat(w http.ResponseWriter, r *http.Request) { |
There was a problem hiding this comment.
Make sure to document the handler.
|
@sergeyfd This is looking better! I think there needs to be a little work in the client. I am not quite sure how we want to handle fallback, quite yet but making the client handle it will help explore possibilities. |
|
@stevvooe I added a couple of comments to document new handler. I am not sure what changes are needed on the client side. With this change client will start using BuildTagsListURL, which returns new |
This needs to handle both cases. If |
|
Makes sense. Please take a look at the latest commit. |
registry/client/repository.go
Outdated
| var compatUrl bool | ||
|
|
||
| // This is needed to be compatible with old registries that use "list" instead of "_list" | ||
| _, compatUrl = ctx.Value("tags.url.compat").(bool) |
There was a problem hiding this comment.
Not sure I'm on board with this use of context. Just make a helper that takes the URL.
| }) | ||
| if i < 2 { | ||
| headers.Set("Link", "<"+s.URL+"/v2/"+repo.Name()+"/tags/list?n=1&last="+tagsList[i]+`>; rel="next"`) | ||
| headers.Set("Link", "<"+s.URL+"/v2/"+repo.Name()+"/tags/"+ref+"?n=1&last="+tagsList[i]+`>; rel="next"`) |
There was a problem hiding this comment.
Let's try and setup tests that have the following:
- Older client hits
tags/listand is redirected. - Newer client hits
tags/_listagainst old registry and falls back. - Newer client hits
tags/_listagainst new registry.
There was a problem hiding this comment.
This is split between different test cases. 1) is covered in handlers/api_test.go and 2) and 3) are covered in client/repository_test.go
| @@ -1000,8 +1000,12 @@ to last response or be fully omitted, depending on the server implementation. | |||
| It may be necessary to list all of the tags under a given repository. The tags | |||
There was a problem hiding this comment.
I missed this earlier: make sure to create a change entry at the top of the specification.
|
@sergeyfd Thanks for sticking with this one! It is a tricky change and we'll keep filling in everything to ensure that it will be a smooth transition. |
registry/client/repository.go
Outdated
| } | ||
| defer resp.Body.Close() | ||
|
|
||
| if resp.StatusCode == http.StatusNotFound && !compatURL { |
There was a problem hiding this comment.
I think this needs to cover a broader range of possible status codes. Possibly any 4xx except 401. We haven't defined what the behavior must be for undefined routes which in some cases could leave proxies to set the rules.
registry/client/repository.go
Outdated
| var compatURL bool | ||
|
|
||
| // This is needed to be compatible with old registries that use "list" instead of "_list" | ||
| _, compatURL = ctx.Value(compatTagsURLKey{}).(bool) |
There was a problem hiding this comment.
Instead of using context, you can just define a func (t *tags) all(ctx context.Context, fallback bool) ([]string, error) method which All calls and will call itself recursively. Passing arguments through context should be avoided whenever possible.
There was a problem hiding this comment.
@dmcgowan I suggested he has an unexported helper that takes the url.
There was a problem hiding this comment.
The way @dmcgowan suggested seems as less intrusive change to the original code so I changed my code that way. I am not sure how to go with "helper that takes url" idea for this case.
|
Design sounds good, marking as code review |
docs/spec/api.md
Outdated
| | GET | `/v2/` | Base | Check that the endpoint implements Docker Registry API V2. | | ||
| | 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`. | | ||
| | GET | `/v2/<name>/tags/<reference>` | Tags | Redirect to tags list. | |
There was a problem hiding this comment.
I think <reference> is a typo, shouldn't it be list?
There was a problem hiding this comment.
It is not. The route is used for DELETE operations and GET is just a special case where only 'list' reference supported for backward compatibility.
There was a problem hiding this comment.
For DELETE sure, this is GET. Your change description specifically mentions redirecting /tags/list to /tags/_list:
It introduces new TagAPI which allows deleting tags for a given image and also supports legacy Tags List URL /v2//tags/list by redirecting it to the new one /v2//tags/_list.
So I am a bit confused by this line.
There was a problem hiding this comment.
Sorry, just reread your comment. If only list is supported as <reference> why bother to call it reference?
There was a problem hiding this comment.
That part of template is generated from /registry/api/v2/descriptors.go Over there it's just one route for GET and DELETE with uses <reference> to get correct tag. It works same way for DELETE and GET and if we were developing from scratches we would not implement GET at all. But we have to be backward compatible, hence the only <reference> supported in GET is list and that's just a special case. I see no reason to define a special route and handler for it.
There was a problem hiding this comment.
I see, it wasn't clear that was coming from the auto-generation.
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
Signed-off-by: Serge Dubrouski <sergeyfd@gmail.com>
|
still not merged. Will it be at some point ? |
|
Waiting for it too :(
…On Mon, 1 Oct 2018 at 19:59, Prune Sebastien THOMAS < ***@***.***> wrote:
still not merged. Will it be at some point ?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2169 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACTpQaKSkbt_VSLB95wKc5a5NhTBzNGaks5uglf4gaJpZM4LqNtM>
.
|
|
Any update on this request? |
|
Any update on this? It is fairly critical for us because we have a registry cleanup script which purges old images. But if tag "old" points to the same image (manifest) as tag "new" then the new tag is removed as well as the old one. This will leave customers who reference the image by the new tag without an image to pull!!! |
|
Any update on this ? |
|
A little more than a month and then this issue will be three years old! 🎉 |
|
With the distribution spec now living elsewhere, this should likely now be opened as a proposal in https://github.com/opencontainers/distribution-spec |
|
For those looking for a workaround: you can push a new temporary manifest to the tag and then delete it again, which will ensure you don't delete anything else. I've implemented the following in my cleanup script:
This will leave some extra detritus in the registry, but it should get cleaned up by garbage collection. Note that this process never removes any manifests that were originally in the registry, so to actually get space savings you need to use the garbage collector with I've only just implemented this and haven't yet used it on a production registry, so caveat emptor. |
|
Additions to the specification are no longer being considered here. The specification has moved to https://github.com/opencontainers/distribution-spec |
|
For anyone waiting for this, the tag delete API has been added to the OCI Distribution spec in v1.0.0. I've created a PR to implement it here: #3427 |
This is a PR to cover first two first steps of the plan discussed at #1956 It introduces new TagAPI which allows deleting tags for a given image and also supports legacy Tags List URL
/v2/<name>/tags/listby redirecting it to the new one/v2/<name>/tags/_list.@stevvooe please take a look when you have a chance. It seems rather big but most of the changes are caused by renaming some functions to better reflect their new purpose.
Signed-off-by: Serge Dubrouski sergeyfd@gmail.com