Correctly resolve dependencies when manually deleting image, closes #7

This commit is contained in:
Disassembler 2020-04-26 16:20:23 +02:00
parent 4f33d97386
commit 659992d249
No known key found for this signature in database
GPG Key ID: 524BD33A0EE29499

View File

@ -50,32 +50,25 @@ def delete(image_name):
used_by = [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_by: if used_by:
sys.exit(f'Error: Image {image_name} is used by container{"s" if len(used_by) > 1 else ""} {", ".join(used_by)}') sys.exit(f'Error: Image {image_name} is used by container{"s" if len(used_by) > 1 else ""} {", ".join(used_by)}')
used_images = set() # Gather layers inheriting from the layer to be removed which should be removed as well
for definition in repo_local.get_containers().values(): retained_layers = set(image for image,definition in repo_local.get_images().items() if image_name not in definition['layers'])
used_images.update(definition['layers']) remove_layers(retained_layers)
# Build dependency tree to safely remove the images in order of dependency
depsolver = DepSolver()
for image,definition in repo_local.get_images().items():
if image_name in definition['layers']:
image = Image(image)
depsolver.add(image.name, set(image.layers) - used_images, image)
# Enqueue and run the removal actions
queue = ActionQueue()
for image in reversed(depsolver.solve()):
queue.delete_image(image)
queue.process()
@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_images = set() retained_layers = set()
for definition in repo_local.get_containers().values(): for definition in repo_local.get_containers().values():
used_images.update(definition['layers']) retained_layers.update(definition['layers'])
# Build dependency tree to safely remove the images in order of dependency remove_layers(retained_layers)
def remove_layers(retained_layers):
# Enqueue removal of images for cleanup
depsolver = DepSolver() depsolver = DepSolver()
for image in set(repo_local.get_images()) - used_images: # Build dependency tree to safely remove the images in order of dependency
for image in set(repo_local.get_images()) - retained_layers:
image = Image(image) image = Image(image)
depsolver.add(image.name, set(image.layers) - used_images, image) depsolver.add(image.name, set(image.layers) - retained_layers, 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()):