mirror of
https://github.com/projectatomic/atomic.git
synced 2026-02-07 06:44:52 +01:00
Add an optional --storage flag to the following commands: - images delete - info - mount - verify - version If specified, the command will only look at the specified storage (ostree/docker) for the image to perform the action. If not specified, the command will look through both ostree/docker for the image (as it was before). However, if the storage is not specified and the image exists in both ostree and docker, the command will error and prompt the user to specify. Image inspection also no longer forces the user to delete/rename one or the other. This is meant to address the duplicate naming issue (where a user can have an image in both ostree and docker with the same name). Signed-off-by: Yu Qi Zhang <jerzhang@redhat.com> Closes: #720 Approved by: giuseppe
111 lines
4.2 KiB
Python
111 lines
4.2 KiB
Python
from . import Atomic
|
|
from . import util
|
|
from docker.errors import NotFound
|
|
from docker.errors import APIError
|
|
import sys
|
|
|
|
class Delete(Atomic):
|
|
def __init__(self):
|
|
super(Delete, self).__init__()
|
|
|
|
def delete_image(self):
|
|
"""
|
|
Mark given image(s) for deletion from registry
|
|
:return: 0 if all images marked for deletion, otherwise 2 on any failure
|
|
"""
|
|
|
|
if not self.args.assumeyes:
|
|
confirm = util.input("Do you wish to delete {}? (y/N) ".format(self.args.delete_targets))
|
|
confirm = confirm.strip().lower()
|
|
if not confirm in ['y', 'yes']:
|
|
util.write_err("User aborted delete operation for {}".format(self.args.delete_targets))
|
|
sys.exit(2)
|
|
|
|
if self.args.remote:
|
|
results = self._delete_remote(self.args.delete_targets)
|
|
else:
|
|
results = self._delete_local(self.args.delete_targets, self.args.force)
|
|
return results
|
|
|
|
def prune_images(self):
|
|
"""
|
|
Remove dangling images from registry
|
|
:return: 0 if all images deleted or no dangling images found
|
|
"""
|
|
self.syscontainers.prune_ostree_images()
|
|
|
|
results = self.d.images(filters={"dangling":True}, quiet=True)
|
|
if len(results) == 0:
|
|
return 0
|
|
|
|
for img in results:
|
|
self.d.remove_image(img, force=True)
|
|
util.write_out("Removed dangling Image {}".format(img))
|
|
return 0
|
|
|
|
def _delete_remote(self, targets):
|
|
results = 0
|
|
for target in targets:
|
|
# _convert_to_skopeo requires registry v1 support while delete requires v2 support
|
|
# args, img = self.syscontainers._convert_to_skopeo(target)
|
|
|
|
args = []
|
|
if "http:" in target:
|
|
args.append("--insecure")
|
|
|
|
for i in ["oci:", "http:", "https:"]:
|
|
img = target.replace(i, "docker:")
|
|
|
|
if not img.startswith("docker:"):
|
|
img = "docker://" + img
|
|
|
|
try:
|
|
util.skopeo_delete(img, args)
|
|
util.write_out("Image {} marked for deletion".format(img))
|
|
except ValueError as e:
|
|
util.write_err("Failed to mark Image {} for deletion: {}".format(img, e))
|
|
results = 2
|
|
return results
|
|
|
|
def _delete_local(self, targets, force=False):
|
|
results = 0
|
|
for target in targets:
|
|
if not self.args.storage:
|
|
if self.is_duplicate_image(target):
|
|
util.write_err("Failed to delete Image {}: has duplicate naming; please specify "
|
|
"--storage to delete from a specific storage.".format(target))
|
|
results = 2
|
|
else:
|
|
if self.syscontainers.has_image(target):
|
|
self.syscontainers.delete_image(target)
|
|
else:
|
|
try:
|
|
self.d.remove_image(target, force=force)
|
|
except NotFound as e:
|
|
util.write_err("Failed to delete Image {}: {}".format(target, e))
|
|
results = 2
|
|
except APIError as e:
|
|
util.write_err("Failed operation for delete Image {}: {}".format(target, e))
|
|
results = 2
|
|
|
|
elif self.args.storage.lower() == "ostree":
|
|
if not self.syscontainers.has_image(target):
|
|
util.write_err("Failed to delete Image {}: does not exist in ostree.".format(target))
|
|
self.syscontainers.delete_image(target)
|
|
|
|
elif self.args.storage.lower() == "docker":
|
|
try:
|
|
self.d.remove_image(target, force=force)
|
|
except NotFound as e:
|
|
util.write_err("Failed to delete Image {}: {}".format(target, e))
|
|
results = 2
|
|
except APIError as e:
|
|
util.write_err("Failed operation for delete Image {}: {}".format(target, e))
|
|
results = 2
|
|
|
|
else:
|
|
util.write_err("{} is not a valid storage".format(self.args.storage))
|
|
results = 2
|
|
|
|
return results
|