New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manifest/tag deletion use cases need to be thought through #1859

Open
Vanuan opened this Issue Jul 21, 2016 · 11 comments

Comments

Projects
None yet
5 participants
@Vanuan

Vanuan commented Jul 21, 2016

Deletion use cases clearly need some thought.

Here they are:

  1. Delete a tag without deleting a manifest (who needs that?)
  2. Delete a manifest without deleting a tag (impossible, should throw error)
  3. Delete a manifest (and all related tags)
    • by specifying tag
    • by specifying a digest
    • warn if there are more than one related tag to be deleted (with override option)

Different interfaces:

  1. http (partially exists)
  2. docker cli (docker push :registry/name:tag or docker push --delete registry/name:tag)
  3. docker registry cli (garbage-collect option)

There are the following issues related:
#462
#1515
#1566
#1600
#1801
#1811
#1813
#1844

@RichardScothern

This comment has been minimized.

Contributor

RichardScothern commented Jul 28, 2016

hi @Vanuan : thanks for digging into this. I totally agree that deletion could do with some refining.

  1. Delete a tag without deleting a manifest.
    This should be supported - a tag pushed in error should be removable. There is an outstanding debate about making tags a first class citizen in the registry with their own API (see #173) which would be required for this kind of feature.
  2. Delete a manifest without deleting a tag. Deleting a manifest does currently delete a tag - I'm not sure what error case you are referring to here.
  3. Delete a manifest
    3.1. By tag: see point 1.
    3.2. By digest is currently supported and I agree that the resultant tag cleanup could be communicated in the response (with a force option to override)

Some of those linked issues refer to another issue:
4. garbage collecting unreferenced data. Currently garbage collection remove data that was explicitly deleted, but not data that is no longer tracked. We could have an extension to the garbage collect subcommand to enable this.

Another dependency for a lot of this work is improving the way metadata is stored. Currently we have no locking/transactions or even a consistent view of the storage with all drivers. We are working on improving this with changes like this in mind.

@Vanuan

This comment has been minimized.

Vanuan commented Jul 29, 2016

Delete a manifest without deleting a tag. Deleting a manifest does currently delete a tag - I'm not sure what error case you are referring to here.

I'm saying that if you delete a manifest, all referencing tags would be deleted. Sometimes it's unexpected. I.e. if there's a command "delete only manifest" it should throw an error if there are tags.

So the clean up would be like this:

  1. delete only tag
  2. delete only manifest (error if there are tags still exist)

vs.

  1. delete a manifest
  2. all tags are automatically removed without a warning
@RichardScothern

This comment has been minimized.

Contributor

RichardScothern commented Jul 30, 2016

OK. I think that's covered with point 3.2 above?

@Vanuan

This comment has been minimized.

Vanuan commented Jul 30, 2016

Yeap

@gbougeard

This comment has been minimized.

gbougeard commented Mar 30, 2017

I'm trying to clean my private registry.
Basically I delete tags by there digest calling the route DELETE /v2/<name>/manifests/<reference> .
Even after doing that the tags are still listed when I retrieve the whole tags list for an image (using https://github.com/mayflower/docker-ls for example). But they are not pullable.
Is there some cache anywhere?
Do I have to run the GC to remove them from the list of tags?

Bonus question : what are the best practices to clean a registry and free some storage?

@Vanuan

This comment has been minimized.

Vanuan commented Mar 31, 2017

Do I have to run the GC to remove them from the list of tags?

Yes. You should stop docker registry, run GC command, and then start it again.

what are the best practices to clean a registry and free some storage?

None. Best practice is to have unlimited amount of space. And buy more when you run out of space.

@Vanuan

This comment has been minimized.

Vanuan commented Mar 31, 2017

The best I came up with is this:

docker exec -ti docker_registry_1 registry garbage-collect /etc/docker/registry/config.yml

docker exec -ti docker_registry_1 /bin/bash
> export IMAGE_NAME=...
> export REGISTRY=/var/lib/registry/docker/registry/v2/repositories
> export LATEST=`cat $REGISTRY/$IMAGE_NAME/_manifests/tags/latest/current/link | sed -r 's/sha256\://'`
find $REGISTRY/$IMAGE_NAME/_manifests/revisions/sha256/ -not -name $LATEST -print0 | sudo xargs -0 rm -r
/bin/registry garbage-collect  /etc/docker/registry/config.yml

But it's not reliable. You should ensure to take registry down. Otherwise you'll loose your data

@scottcarey

This comment has been minimized.

scottcarey commented Sep 15, 2017

Important use cases:

I have a registry full of cruft cause by an automated build system that overwrites latest many times a day.

So there are a LOT (90% storage) of manifests with no tags.

I need to identify all the manifests without tags. At best I would have to do that today by:

running GC and parsing the output for marked manifests, then subtracting the manifests that match any known tags, then deleting them. This brings up a few apis that would be helpful:

  • list all manifests (seriously, if you don't know the hash ahead of time, and it does not have a tag, how do you locate it? I have to inspect the stdout of gc! Yuck!)
  • list all manifests without a tag
  • list all manifests with a tag (or alternatively, list tags 'verbose' along with what manifests they point to)
  • a single command to delete all manifests that have no tag

Or simply the end-game: give gc a flag that lets it clean up content that has no tag pointing to it. IOW, use tags as the 'root' of the mark phase, instead of manifests.

@scottcarey

This comment has been minimized.

scottcarey commented Sep 15, 2017

w.r.t. docker cli, how would one reference manifests without tags?

docker push --delete registry/name:tag would be nice, but today one can just overwrite a tag and orphan a manifest with no way to reference it. The hash would work, if there was a way to query it, docker images ls --remote registry/name ?

@jonjohnsonjr

This comment has been minimized.

Contributor

jonjohnsonjr commented Sep 15, 2017

#2199 would make this easy to implement client-side.

@Vanuan

This comment has been minimized.

Vanuan commented Sep 15, 2017

When I researched the issue I've came to conclusion that you must push both latest and some build number tag. Afterwards you can grep by build number and remove all manifests except the latest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment