import json import os import subprocess from os.path import join as join_path from ucloud.config import etcd_client, config, image_storage_handler from ucloud.imagescanner import logger def qemu_img_type(path): qemu_img_info_command = ["qemu-img", "info", "--output", "json", path] try: qemu_img_info = subprocess.check_output(qemu_img_info_command) except Exception as e: logger.exception(e) return None else: qemu_img_info = json.loads(qemu_img_info.decode("utf-8")) return qemu_img_info["format"] def check(): """ check whether settings are sane, refuse to start if they aren't """ if config['etcd']['STORAGE_BACKEND'] == 'filesystem' and not isdir(config['etcd']['IMAGE_DIR']): print("You have set STORAGE_BACKEND to filesystem, but " "{} does not exist. Refusing to start".format(config['etcd']['IMAGE_DIR'])) sys.exit(1) try: subprocess.check_output(['which', 'qemu-img']) except Exception: print("qemu-img missing") sys.exit(1) def main(): # We want to get images entries that requests images to be created images = etcd_client.get_prefix(config['etcd']['IMAGE_PREFIX'], value_in_json=True) images_to_be_created = list(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 = join_path(config['etcd']['BASE_DIR'], image_owner, image_filename) image_stores = etcd_client.get_prefix(config['etcd']['IMAGE_STORE_PREFIX'], value_in_json=True) user_image_store = next(filter( lambda s, store_name=image_store_name: s.value["name"] == store_name, image_stores )) image_store_pool = user_image_store.value['attributes']['pool'] except Exception as e: logger.exception(e) else: # At least our basic data is available qemu_img_convert_command = ["qemu-img", "convert", "-f", "qcow2", "-O", "raw", image_full_path, "image.raw"] if qemu_img_type(image_full_path) == "qcow2": try: # Convert .qcow2 to .raw subprocess.check_output(qemu_img_convert_command) except Exception as e: logger.exception(e) else: # Import and Protect r_status = image_storage_handler.import_image(src="image.raw", dest=image_uuid, protect=True) if r_status: # Everything is successfully done image.value["status"] = "CREATED" etcd_client.put(image.key, json.dumps(image.value)) else: # The user provided image is either not found or of invalid format image.value["status"] = "INVALID_IMAGE" etcd_client.put(image.key, json.dumps(image.value)) try: os.remove("image.raw") except Exception: pass if __name__ == "__main__": main()