diff --git a/usr/bin/spoc-image b/usr/bin/spoc-image index 16cadf0..39e5f1c 100644 --- a/usr/bin/spoc-image +++ b/usr/bin/spoc-image @@ -6,9 +6,10 @@ import argparse from spoc import repo_local from spoc import repo_online from spoc import repo_publish +from spoc.exceptions import ImageNotFoundError from spoc.image import Image from spoc.imagebuilder import ImageBuilder -from spoc.cli import ActionQueue, ActionItem, readable_size +from spoc.cli import ActionQueue, readable_size ACTION_LIST = 1 ACTION_DOWNLOAD = 2 @@ -36,17 +37,24 @@ def listing(repo_type): print(image) def download(image_name): - actionqueue = ActionQueue() + queue = ActionQueue() local_images = repo_local.get_images() for layer in repo_online.get_image(image_name)['layers']: if layer not in local_images: - image = Image(layer, False) - actionqueue.append(ActionItem(f'Downloading {image_name}', image.download)) - actionqueue.append(ActionItem(f'Unpacking {image_name}', image.unpack_downloaded)) - actionqueue.process() + queue.download_image(Image(layer, False)) + queue.process() def delete(image_name): - Image(image_name, False).delete() + # TODO: Check if any container or image doesn't depend + # TODO: Some kind of autoremove routine for images unused in containers + try: + image = Image(image_name) + except ImageNotFoundError: + return + queue = ActionQueue() + for layer in reversed(image.layers): + queue.delete_image(Image(layer, False)) + queue.process() def build(filename, force, do_publish): # Check if a build is needed and attempt to build the image from image file @@ -68,8 +76,8 @@ def publish(image_name, force): # Check if publishing is needed and attempt to publish the image if force or image_name not in repo_publish.get_images(): image = Image(image_name) - image.unpublish() print(f'Publishing image {image_name}') + image.unpublish() image.publish() print(f'Image {image_name} compressed from {readable_size(image.size)} to {readable_size(image.dlsize)} and published successfully') else: diff --git a/usr/lib/python3.8/spoc/cli.py b/usr/lib/python3.8/spoc/cli.py index 1f36680..0cbd9b0 100644 --- a/usr/lib/python3.8/spoc/cli.py +++ b/usr/lib/python3.8/spoc/cli.py @@ -10,8 +10,12 @@ class ActionQueue: def __init__(self): self.queue = [] - def append(self, actionitem): - self.queue.append(actionitem) + def download_image(self, image): + self.queue.append(ActionItem(f'Downloading image {image.name}', image.download)) + self.queue.append(ActionItem(f'Unpacking image {image.name}', image.unpack_downloaded)) + + def delete_image(self, image): + self.queue.append(ActionItem(f'Deleting image {image.name}', image.delete, False)) def process(self): index = 0 @@ -22,23 +26,30 @@ class ActionQueue: item.run() class ActionItem: - def __init__(self, text, action): + def __init__(self, text, action, has_progress=True): self.text = text self.action = action - self.units_total = 0 + self.has_progress = has_progress + self.units_total = 1 self.units_done = 0 def run(self): - with ThreadPoolExecutor() as executor: - future = executor.submit(self.action, self) - while not future.done(): - time.sleep(0.2) - self.print_status() - # Get the result of the future and let it raise exception, if there was any - data = future.result() - self.print_status('\n') + if self.has_progress: + with ThreadPoolExecutor() as executor: + future = executor.submit(self.action, self) + while not future.done(): + time.sleep(0.2) + self.print_progress() + # Get the result of the future and let it raise exception, if there was any + data = future.result() + self.print_progress('\n') + else: + self.print_progress() + self.action() + self.units_done = 1 + self.print_progress('\n') - def print_status(self, end='\r'): + def print_progress(self, end='\r'): print(f'\x1b[K{self.text} ({self.units_done}/{self.units_total}) [{self.units_done/self.units_total*100:.2f} %]', end=end) def readable_size(bytes):