453 lines
24 KiB
Python
453 lines
24 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Este script convierte la imagen de OpengGnsys especificada como primer parámetro en una imagen virtual con la extensión especificada como segundo parámetro ("vdi", "vmdk", etc).
|
|
La imagen virtual se exporta a la ruta "/opt/opengnsys/ogrepository/images_virtual/export/", desde donde puede ser descargada para importarla en VirtualBox, VMware, etc.
|
|
|
|
Paquetes APT requeridos: "qemu" (se puede instalar con "sudo apt install qemu-utils").
|
|
"partclone" (se puede instalar con "sudo apt install partclone").
|
|
"lzop" (se puede instalar con "sudo apt install lzop").
|
|
|
|
Parámetros
|
|
------------
|
|
sys.argv[1] - Nombre completo de la imagen a convertir (sin ruta).
|
|
- Ejemplo1: Ubuntu.img
|
|
- Ejemplo2: Windows.img
|
|
|
|
sys.argv[2] - Extensión del disco virtual destino (sin punto).
|
|
- Ejemplo1: vdi
|
|
- Ejemplo2: vmdk
|
|
|
|
Sintaxis
|
|
----------
|
|
./comvertIMGtoVM.py image_name virtual_extension
|
|
|
|
Ejemplos
|
|
---------
|
|
./comvertIMGtoVM.py Ubuntu.img vdi
|
|
./comvertIMGtoVM.py Windows.img vmdk
|
|
"""
|
|
|
|
# --------------------------------------------------------------------------------------------
|
|
# IMPORTS
|
|
# --------------------------------------------------------------------------------------------
|
|
|
|
import sys
|
|
import os
|
|
import pwd
|
|
import grp
|
|
import subprocess
|
|
from systemd import journal
|
|
|
|
|
|
# --------------------------------------------------------------------------------------------
|
|
# VARIABLES
|
|
# --------------------------------------------------------------------------------------------
|
|
|
|
script_name = os.path.basename(__file__)
|
|
repo_path = '/opt/opengnsys/ogrepository/images/' # No borrar la barra final
|
|
vm_export_path = '/opt/opengnsys/ogrepository/images_virtual/export/' # No borrar la barra final
|
|
partclone_logfile = '/opt/opengnsys/ogrepository/log/partclone.log'
|
|
|
|
raw_img = '/opt/opengnsys/ogrepository/images_virtual/export/disk.raw'
|
|
mount_point = "/mnt/recovery"
|
|
|
|
|
|
# --------------------------------------------------------------------------------------------
|
|
# FUNCTIONS
|
|
# --------------------------------------------------------------------------------------------
|
|
|
|
|
|
def show_help():
|
|
""" Imprime la ayuda, cuando se ejecuta el script con el parámetro "help".
|
|
"""
|
|
help_text = f"""
|
|
Sintaxis: {script_name} image_name virtual_extension
|
|
Ejemplo1: {script_name} Ubuntu.img vdi
|
|
Ejemplo2: {script_name} Windows.img vmdk
|
|
"""
|
|
print(help_text)
|
|
|
|
|
|
def check_params():
|
|
""" Comprueba que se haya enviado la cantidad correcta de parámetros, y en el formato correcto.
|
|
Si no es así, muestra un mensaje de error, y sale del script.
|
|
LLama a la función "show_help" cuando se ejecuta el script con el parámetro "help".
|
|
"""
|
|
# Si se ejecuta el script con el parámetro "help", se muestra la ayuda, y se sale del script:
|
|
if len(sys.argv) == 2 and sys.argv[1] == "help":
|
|
show_help()
|
|
sys.exit(0)
|
|
# Si se ejecuta el script con más o menos de 2 parámetroa, se muestra un error y la ayuda, y se sale del script:
|
|
elif len(sys.argv) != 3:
|
|
print(f"{script_name} Error: Formato incorrecto: Se debe especificar 2 parámetros")
|
|
show_help()
|
|
sys.exit(1)
|
|
|
|
|
|
def create_export_folder():
|
|
""" Crea el directorio '/opt/opengnsys/ogrepository/images_virtual/export/', y le asigna propietarios y permisos.
|
|
Evidentemente, esta función solo es llamada cuando no existe el directorio.
|
|
"""
|
|
# Obtenemos el UID del usuario "opengnsys" y el GID del grupo "opengnsys":
|
|
uid = pwd.getpwnam('opengnsys').pw_uid
|
|
gid = grp.getgrnam('opengnsys').gr_gid
|
|
# Creamos el directorio '/opt/opengnsys/ogrepository/images_virtual/export/':
|
|
os.mkdir(vm_export_path)
|
|
# Asignamos el usuario y el grupo propietarios del directorio:
|
|
os.chown(vm_export_path, uid, gid)
|
|
# Asignamos permisos "755" al directorio :
|
|
os.chmod(vm_export_path, 0o755)
|
|
|
|
|
|
def create_raw_disk(raw_size):
|
|
""" Crea un disco "RAW", sobre el que luego se creará una tabla de particiones, mediante "qemu-img create".
|
|
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
|
|
"""
|
|
try:
|
|
journal.send("convertIMGtoVM.py: Running command 'qemu-img create'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
result = subprocess.run(['qemu-img', 'create', '-f', 'raw', raw_img, raw_size], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
|
|
if result.returncode == 0:
|
|
return True
|
|
else:
|
|
return False
|
|
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: 'qemu-img create' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'qemu-img create' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
|
|
|
|
def create_partition_table(partition_size):
|
|
""" Crea una tabla de particiones en el disco "RAW", mediante "fdisk".
|
|
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
|
|
"""
|
|
try:
|
|
journal.send("convertIMGtoVM.py: Running command 'fdisk'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Construimos el parámetro "input", que debe codificarse en bytes (con "encode"):
|
|
input_data = f"o\nn\np\n1\n\n+{partition_size}\nw".encode()
|
|
|
|
result = subprocess.run(['fdisk', raw_img], input=input_data, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
|
|
if result.returncode == 0:
|
|
return True
|
|
else:
|
|
return False
|
|
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: 'fdisk' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'fdisk' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
|
|
|
|
def associate_loop_device():
|
|
""" Asocia el disco "RAW" a un dispositivo loopback, mediante "losetup".
|
|
Si se ejecuta correctamente retorna "True", el dispositivo loopback y la partición de destino, y si da error retorna "False", "None" y "None".
|
|
"""
|
|
try:
|
|
journal.send("convertIMGtoVM.py: Running command 'losetup'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
result = subprocess.run(['losetup', '-P', '--find', '--show', raw_img], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF8')
|
|
|
|
# Si el resultado de la ejecución es correcto, obtenemos el dispositivo loopback y la partición de destino, y los retornamos:
|
|
if result.returncode == 0:
|
|
# Obtenemos la partición de destino, y la imprimimos en el log, junto con el dispositivo loopback:
|
|
loop_device = result.stdout.strip()
|
|
dest_partition = f"{loop_device}p1"
|
|
journal.send(f"convertIMGtoVM.py: Loopback device obtained: {loop_device}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
journal.send(f"convertIMGtoVM.py: Destination partition obtained: {dest_partition}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return True, loop_device, dest_partition
|
|
else:
|
|
return False, None, None
|
|
|
|
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False", "None" y "None" (entrará aquí si el return code no es "0"):
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: 'losetup' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False, None, None
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'losetup' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False, None, None
|
|
|
|
|
|
def decompress_image(image_name_full):
|
|
""" Descomprime la imagen "IMG" origen, con "lzop".
|
|
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
|
|
"""
|
|
try:
|
|
journal.send("convertIMGtoVM.py: Running command 'lzop'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
result = subprocess.run(['lzop', '-d', f"{repo_path}{image_name_full}", '-o', f"{vm_export_path}{image_name_full}"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
|
|
if result.returncode == 0:
|
|
return True
|
|
else:
|
|
return False
|
|
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: 'lzop' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'lzop' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
|
|
|
|
def restore_image(image_name_full, dest_partition):
|
|
""" Restaura la imagen descomprimida en la partición de destino (que hemos obtenido con "losetup").
|
|
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
|
|
"""
|
|
try:
|
|
journal.send("convertIMGtoVM.py: Running command 'partclone.restore'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
result = subprocess.run(['partclone.restore', '-s', f"{vm_export_path}{image_name_full}", '-o', dest_partition, '-L', partclone_logfile], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
|
|
if result.returncode == 0:
|
|
return True
|
|
else:
|
|
return False
|
|
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: 'partclone.restore' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'partclone.restore' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
|
|
|
|
def mount_partition(dest_partition):
|
|
""" Crea un directorio de montaje, y monta allí la partición de destino (que hemos obtenido con "losetup").
|
|
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
|
|
NOTA: Los comandos "mkdir" y "mount" deben ejecutarse con "sudo", o darán error.
|
|
"""
|
|
try:
|
|
# Creamos el directorio de montaje:
|
|
subprocess.run(['sudo', 'mkdir', '-p', mount_point], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'mkdir' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
|
|
try:
|
|
# Montamos la partición en el directorio de montaje:
|
|
journal.send("convertIMGtoVM.py: Running command 'mount'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
result = subprocess.run(['sudo', 'mount', dest_partition, mount_point], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
|
|
if result.returncode == 0:
|
|
return True
|
|
else:
|
|
return False
|
|
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: 'mount' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'mount' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
|
|
|
|
def install_grub(loop_device):
|
|
""" Instala GRUB en el dispositivo loopback.
|
|
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
|
|
NOTA: Los comandos deben ejecutarse con "sudo", o darán error.
|
|
"""
|
|
try:
|
|
journal.send("convertIMGtoVM.py: Installing GRUB...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Ejecutamos los comandos necesarios para instalar GRUB:
|
|
subprocess.run(['sudo', 'mount', '--bind', '/dev', f"{mount_point}/dev"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
subprocess.run(['sudo', 'mount', '--bind', '/proc', f"{mount_point}/proc"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
subprocess.run(['sudo', 'mount', '--bind', '/sys', f"{mount_point}/sys"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
subprocess.run(['sudo', 'chroot', mount_point, 'grub-install', '--target=i386-pc', loop_device], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
subprocess.run(['sudo', 'chroot', mount_point, 'grub-mkconfig', '-o', '/boot/grub/grub.cfg'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
# Como no ha habido errores, retornamos "True":
|
|
return True
|
|
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: GRUB install error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: GRUB install exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
|
|
|
|
def umount_partitions(loop_device):
|
|
""" Desmonta todas las particiones montadas previamente, con "umount" y "losetup".
|
|
No retorna "True" o "False", porque este paso no afecta a la conversión de la imagen.
|
|
NOTA: Los comandos deben ejecutarse con "sudo", o darán error.
|
|
"""
|
|
try:
|
|
journal.send("convertIMGtoVM.py: Umounting partitions...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Desmontamos las particiones, con "umount" y "losetup":
|
|
subprocess.run(['sudo', 'umount', f"{mount_point}/dev"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
subprocess.run(['sudo', 'umount', f"{mount_point}/proc"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
subprocess.run(['sudo', 'umount', f"{mount_point}/sys"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
subprocess.run(['sudo', 'umount', '-l', mount_point], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
subprocess.run(['sudo', 'losetup', '-d', loop_device], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
# Como no ha habido errores, imprimimos un mensaje en el log:
|
|
journal.send("convertIMGtoVM.py: Umount partitions OK", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
# Si se produce un error o una excepción lo imprimimos en el log:
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: 'umount' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'umount' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
|
|
def convert_image(image_name, vm_extension):
|
|
""" Convierte el disco "RAW" en un disco virtual, con la extensión especificada como parámetro.
|
|
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
|
|
"""
|
|
try:
|
|
journal.send("convertIMGtoVM.py: Running command 'qemu-img convert'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
result = subprocess.run(['qemu-img', 'convert', '-f', 'raw', '-O', vm_extension, raw_img, f"{vm_export_path}{image_name}.{vm_extension}"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
|
|
if result.returncode == 0:
|
|
return True
|
|
else:
|
|
return False
|
|
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
|
|
except subprocess.CalledProcessError as error:
|
|
journal.send(f"convertIMGtoVM.py: 'qemu-img convert' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
except Exception as error:
|
|
journal.send(f"convertIMGtoVM.py: 'qemu-img convert' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
return False
|
|
|
|
|
|
def erase_image_file(file2del):
|
|
""" Borra el archivo correspondiente a la ruta "file2del".
|
|
No retorna "True" o "False", porque este paso no afecta a la conversión de la imagen.
|
|
"""
|
|
journal.send(f"convertIMGtoVM.py: Erasing file {file2del}...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
# Si existe el archivo "file2del", lo borramos:
|
|
if os.path.exists(file2del):
|
|
os.remove(file2del)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------------------------------
|
|
# MAIN
|
|
# --------------------------------------------------------------------------------------------
|
|
|
|
|
|
def main():
|
|
"""
|
|
"""
|
|
# Evaluamos si se ha enviado la cantidad correcta de parámetros, y en el formato correcto:
|
|
check_params()
|
|
|
|
# Almacenamos el nombre completo de la imagen y la extensión del disco virtual de destino (desde los parámetros), y extraemos el nombre sin extensión:
|
|
image_name_full = sys.argv[1]
|
|
image_name = image_name_full.split('.')[0]
|
|
vm_extension = sys.argv[2].lower()
|
|
|
|
# Obtenemos el tamaño de la imagen, y calculamos el tamaño a asignar al disco "RAW" y a la partición:
|
|
image_size = os.path.getsize(f"{repo_path}{image_name_full}")
|
|
raw_size = image_size * 6.5 # El disco "RAW" debe ser "6,5" veces más grande que la imagen
|
|
partition_size = (90 * raw_size) / 100 # La partición debe tener el 90% del tamaño del disco "RAW"
|
|
|
|
# Si no existe el directorio '/opt/opengnsys/ogrepository/images_virtual/export/', lo creamos:
|
|
if not os.path.exists(vm_export_path):
|
|
journal.send("convertIMGtoVM.py: Creating export folder...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
create_export_folder()
|
|
|
|
# Creamos el disco "RAW" (con "qemu-img create"):
|
|
create_raw = create_raw_disk(f"{raw_size / 1024 / 1024 / 1024}G")
|
|
if create_raw == False:
|
|
journal.send("convertIMGtoVM.py: RAW disk creation failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
|
|
sys.exit(2)
|
|
else:
|
|
journal.send("convertIMGtoVM.py: RAW disk creation OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Creamos una tabla de particiones en el disco "RAW" (con "fdisk"):
|
|
create_table = create_partition_table(f"{int(partition_size / 1024 / 1024 / 1024)}G")
|
|
if create_table == False:
|
|
journal.send("convertIMGtoVM.py: Partition table creation failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
|
|
sys.exit(3)
|
|
else:
|
|
journal.send("convertIMGtoVM.py: Partition table creation OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Asociamos el disco "RAW" a un dispositivo loopback, y almacenamos este y la partición de destino
|
|
assoc_loop_result, loop_device, dest_partition = associate_loop_device()
|
|
if assoc_loop_result == False:
|
|
journal.send("convertIMGtoVM.py: Loop device association failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
|
|
sys.exit(4)
|
|
else:
|
|
journal.send("convertIMGtoVM.py: Loop device association OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Descomprimimos la imagen original (con "lzop"):
|
|
image_decompressed = decompress_image(image_name_full)
|
|
if image_decompressed == False:
|
|
journal.send("convertIMGtoVM.py: Image decompression failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
|
|
erase_image_file(f"{vm_export_path}{image_name_full}") # Como ha fallado, borramos la imagen descomprimida
|
|
sys.exit(5)
|
|
else:
|
|
journal.send("convertIMGtoVM.py: Image decompression OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Restauramos la imagen descomprimida en la partición de destino (con "partclone.restore"):
|
|
image_restored = restore_image(image_name_full, dest_partition)
|
|
if image_restored == False:
|
|
journal.send("convertIMGtoVM.py: Image restoration failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
|
|
erase_image_file(f"{vm_export_path}{image_name_full}") # Como ha fallado, borramos la imagen descomprimida
|
|
sys.exit(6)
|
|
else:
|
|
journal.send("convertIMGtoVM.py: Image restoration OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
erase_image_file(f"{vm_export_path}{image_name_full}") # Si ha ido OK también borramos la imagen descomprimida, porque ya no la necesitamos.
|
|
|
|
# Montamos la partición de destino (con "mount"):
|
|
partition_mounted = mount_partition(dest_partition)
|
|
if partition_mounted == False:
|
|
journal.send("convertIMGtoVM.py: Partition mount failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
|
|
sys.exit(7)
|
|
else:
|
|
journal.send("convertIMGtoVM.py: Partition mount OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Instalamos GRUB en el dispositivo loopback (con "mount" y "chroot"):
|
|
grub_installed = install_grub(loop_device)
|
|
if grub_installed == False:
|
|
journal.send("convertIMGtoVM.py: GRUB install failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
umount_partitions(loop_device) # Como ha fallado, desmontamos todas las particiones
|
|
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
|
|
sys.exit(8)
|
|
else:
|
|
journal.send("convertIMGtoVM.py: GRUB install OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
# Desmontamos las particiones montadas previamente (con "umount" y "losetup"):
|
|
umount_partitions(loop_device)
|
|
|
|
# Convertimos el disco "RAW" en un disco virtual (con "qemu-img convert"):
|
|
image_conversion = convert_image(image_name, vm_extension)
|
|
if image_conversion == False:
|
|
journal.send("convertIMGtoVM.py: Image conversion failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
|
|
erase_image_file(f"{vm_export_path}{image_name}.{vm_extension}") # Como ha fallado, borramos la imagen virtual (por si ha creado algo)
|
|
sys.exit(9)
|
|
else:
|
|
erase_image_file(raw_img) # Si ha funcionado OK, también borramos el disco "RAW"
|
|
journal.send("convertIMGtoVM.py: Image conversion OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------------------------------
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|
|
# --------------------------------------------------------------------------------------------
|