import os import json import subprocess from config import logging, client, BASE_PATH, WITHOUT_CEPH # If you are using WITHOUT_CEPH FLAG in .env # then please make sure that /var/image directory # exists otherwise this script would fail if WITHOUT_CEPH and not os.path.isdir("/var/image"): exit(1) # We want to get images entries that requests images to be created images = client.get_prefix("/v1/image/", value_in_json=True) images_to_be_created = filter(lambda im: im.value["status"] == "TO_BE_CREATED", images) for image in images_to_be_created: try: image_uuid = image.key.split('/')[-1] image_owner = image.value['owner'] image_filename = image.value['filename'] image_store_name = image.value['store_name'] image_full_path = os.path.join(BASE_PATH, image_owner, image_filename) image_stores = client.get_prefix("/v1/image_store/", value_in_json=True) user_image_store = next(filter(lambda s: s.value["name"] == image_store_name, image_stores)) image_store_pool = user_image_store.value['attributes']['pool'] except Exception as e: logging.exception(e) else: # At least our basic data is available qemu_img_info_command = ["qemu-img", "info", image_full_path] qemu_img_convert_command = ["qemu-img", "convert", "-f", "qcow2", "-O", "raw", image_full_path, f"image.raw"] image_import_command = ["rbd", "import", "image.raw", f"{image_store_pool}/{image_uuid}"] snapshot_creation_command = ["rbd", "snap", "create", f"{image_store_pool}/{image_uuid}@protected"] snapshot_protect_command = ["rbd", "snap", "protect", f"{image_store_pool}/{image_uuid}@protected"] if WITHOUT_CEPH: image_import_command = ["mv", "image.raw", os.path.join("/var/image", image_uuid)] snapshot_creation_command = ["true"] snapshot_protect_command = ["true"] # First check whether the image is qcow2 # This would also check whether the file exists or not try: qemu_img_info = subprocess.Popen(qemu_img_info_command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) except Exception as e: # Command itself failed i.e maybe qemu-img not found # Maybe Popen crashes some other ways logging.exception(e) else: # At least we run the qemu-img info command # It may have not executed successfully. If thats # the case, our next command grep would also fail try: # Fetching the lines containing "file format" command = ["grep", "-e", "file format"] output = subprocess.check_output(command, stdin=qemu_img_info.stdout) except Exception as e: logging.exception(e) else: # grep command runs successfully, it implies # the previous command qemu-img would have # run successfully output = output.decode("utf-8").strip() if "qcow2" in output: try: # Convert .qcow2 to .raw subprocess.check_output(qemu_img_convert_command) except Exception as e: logging.exception(e) else: # Image successfully converted try: # Import image either to ceph/filesystem subprocess.check_output(image_import_command) except Exception as e: logging.exception(e) else: # Image imported successfully try: subprocess.check_output(snapshot_creation_command) subprocess.check_output(snapshot_protect_command) except Exception as e: logging.exception(e) else: # Everything is successfully done image.value["status"] = "CREATED" client.put(image.key, json.dumps(image.value)) else: # The user provided image is not in qcow2 format image.value["status"] = "INVALID_FORMAT" client.put(image.key, json.dumps(image.value)) try: os.remove("image.raw") except Exception: pass