Fix dependency solving during image removal

This commit is contained in:
Disassembler 2020-03-14 20:55:11 +01:00
parent c1e60a4adf
commit fc42131bb6
No known key found for this signature in database
GPG Key ID: 524BD33A0EE29499

View File

@ -47,15 +47,18 @@ def download(image_name):
def delete(image_name): def delete(image_name):
# Remove the image including all images that have it as one of its parents # Remove the image including all images that have it as one of its parents
# Check if image is in use # Check if image is in use
used = [c for c,d in repo_local.get_containers().items() if image_name in d['layers']] used_by = [c for c,d in repo_local.get_containers().items() if image_name in d['layers']]
if used: if used_by:
sys.exit(f'Error: Image {image_name} is used by container{"s" if len(used) > 1 else ""} {", ".join(used)}') sys.exit(f'Error: Image {image_name} is used by container{"s" if len(used_by) > 1 else ""} {", ".join(used_by)}')
used_images = set()
for definition in repo_local.get_containers().values():
used_images.update(definition['layers'])
# Build dependency tree to safely remove the images in order of dependency # Build dependency tree to safely remove the images in order of dependency
depsolver = DepSolver() depsolver = DepSolver()
for image,definition in repo_local.get_images().items(): for image,definition in repo_local.get_images().items():
if image_name in definition['layers']: if image_name in definition['layers']:
image = Image(image) image = Image(image)
depsolver.add(image.name, image.layers, image) depsolver.add(image.name, set(image.layers) - used_images, image)
# Enqueue and run the removal actions # Enqueue and run the removal actions
queue = ActionQueue() queue = ActionQueue()
for image in reversed(depsolver.solve()): for image in reversed(depsolver.solve()):
@ -65,14 +68,14 @@ def delete(image_name):
@locked(LOCK_FILE, print_lock) @locked(LOCK_FILE, print_lock)
def clean(): def clean():
# Remove images which aren't used in any locally defined containers # Remove images which aren't used in any locally defined containers
used = set() used_images = set()
for definition in repo_local.get_containers().values(): for definition in repo_local.get_containers().values():
used.update(definition['layers']) used_images.update(definition['layers'])
# Build dependency tree to safely remove the images in order of dependency # Build dependency tree to safely remove the images in order of dependency
depsolver = DepSolver() depsolver = DepSolver()
for image in set(repo_local.get_images()) - used: for image in set(repo_local.get_images()) - used_images:
image = Image(image) image = Image(image)
depsolver.add(image.name, image.layers, image) depsolver.add(image.name, set(image.layers) - used_images, image)
# Enqueue and run the removal actions # Enqueue and run the removal actions
queue = ActionQueue() queue = ActionQueue()
for image in reversed(depsolver.solve()): for image in reversed(depsolver.solve()):