106 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
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
 |