ucloud-image-scanner/main.py

107 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