Skip to content
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

Deleting tags without deleting the image #2317

Open
richardellisjr opened this issue Jun 23, 2017 · 10 comments · Fixed by #3427
Open

Deleting tags without deleting the image #2317

richardellisjr opened this issue Jun 23, 2017 · 10 comments · Fixed by #3427

Comments

@richardellisjr
Copy link

Hello, in my company we have a private registry (v2) and we use tags to determine the latest version of running applications. Thus it's possible for an image to have several tags. Is it possible through the API to untag an image without deleting the underlying image. I've searched the API and so far all I found is:

DELETE /v2//manifests/

Which deletes the image and all tags associated with it, while in many cases I just want to remove one tag.

If an API endpoint isn't available can it be added.

thanks

@Oleksii-Terekhov
Copy link

when delete via
/v2/{0}/manifests/{1}
{0} - image name
{1} - digest for tagged image

@vidarl
Copy link
Contributor

vidarl commented Sep 27, 2017

@Oleksii-Terekhov : Could you or someone else elaborate on that please?
I wonder what digest you mean exactly...

let's say you push two tags for the same image:

docker tag localregistry:5000/vltest/zoombie:1.0 localregistry:5000/vltest/zoombie:latest
docker push localregistry:5000/vltest/zoombie:latest
docker push localregistry:5000/vltest/zoombie:1.0

If you next try to get the digest for those two tags, you will get the exact same value in the Docker-Content-Digest HTTP header:

GET http://localregistry:5000/v2/vltest/zoombie/manifests/latest with header Accept: application/vnd.docker.distribution.manifest.v2+json

GET http://localregistry:5000/v2/vltest/zoombie/manifests/1.0 with header Accept: application/vnd.docker.distribution.manifest.v2+json

So, how do you get a digest which points only to the tag, not the image ?

@Oleksii-Terekhov
Copy link

Oleksii-Terekhov commented Sep 28, 2017

in short - digest - string like "sha256:3f6952b193ece0b3b3f63e3d888f5a572fa095723a11535e08c42ecc50733435"

we use python, look on get_tag_digest():
`
class Registry:
def init(self, host, username, password):
self.hostname = host
self.username = username
self.password = password

def send(self, path, method="GET"):
    result = requests.request(
        method, "{0}{1}".format(self.hostname, path),
        headers={"Accept": "application/vnd.docker.distribution.manifest.v2+json"},
        auth=(self.username, self.password))
    if 200 <= result.status_code <= 299:
        return result
    else:
        raise ValueError('Request error #%s -> %s at url %s' % (result.status_code, result.text,  path))

def list_images(self):
    result = self.send('/v2/_catalog')
    return json.loads(result.text)['repositories']

def list_tags(self, image_name):
    result = self.send("/v2/{0}/tags/list".format(image_name))
    return json.loads(result.text)['tags']

def get_tag_digest(self, image_name, tag_name):
    image_headers = self.send("/v2/{0}/manifests/{1}".format(
        image_name, tag_name), method="HEAD")
    return image_headers.headers['Docker-Content-Digest']

def delete_image_by_digest(self, image_name, tag_digest):
    self.send("/v2/{0}/manifests/{1}".format(image_name, tag_digest), method="DELETE")

`

@vidarl
Copy link
Contributor

vidarl commented Sep 28, 2017

It looks to me like you are doing the exact same thing as me. And I can assure you, that does not only delete the tag. It deletes the image and all it's associated tags

@Oleksii-Terekhov
Copy link

yes... but tag disk cost - zero... if you plan kill all old/unused/unwanted images - you MUST:

  • collect digest for all GOOD images
  • loop over all images and tags, delete image by digest if digest not in set of good images
  • profit!!

@vidarl
Copy link
Contributor

vidarl commented Oct 2, 2017

Not correct I am afraid. I think you miss the point that it removes the image and all it's associated tags.
So, if you want to delete old/unused/unwanted images - you MUST:

  • Pull all the GOOD images and tags you want to keep
  • Delete the tags you no longer need
  • Loop over catalogue and check if any of the GOOD tags also was deleted. If so :
    • push those images back to the registry with the tags you wanted to keep

So my conclusion is that this issue report is indeed valid

@bartelsb
Copy link

bartelsb commented Nov 9, 2017

#1811 is pretty related and describes the root of this issue. My company is running into this as well.

I believe that two tags will only have the same digest if they have the same content. If, for whatever reason, you push the same image content twice but with a different tag each time (as @vidarl mentioned in comment 3), they will have the same digest. The API does not support deleting just one of those tags. It will delete both.

@Davidrjx
Copy link

besides the issue, i have a similar one for registry 2.6.2 with storage delete enabled, namely when to delete an image with curl -X DELETE --cacert .. https://***/v2/test-debian/manifests/digest , actions can not be executed successfully with {"errors":[{"code":"MANIFEST_UNKNOWN","message":"manifest unknown"}]}

@sudo-bmitch
Copy link
Contributor

Currently the only API call for deleting is to delete the entire image manifest, which results in all tags also being deleted. There been discussion on improving the tag APIs in OCI distribution-spec. Until something like that makes it into the spec and then implemented in registries, I'm hacking around this in regclient by pushing a temporary unique manifest to the tag and then delete that unique manifest.

@kohtala
Copy link

kohtala commented Dec 8, 2022

This is not implemented in 2.8.1, but implementation is merged in main. #3427

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants