Compare commits
	
		
			2 Commits
		
	
	
		
			e9235a627c
			...
			6e2c1fb45e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6e2c1fb45e | |||
| b14ba9172c | 
@@ -116,6 +116,9 @@
 | 
			
		||||
#    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
from pvcapi.vmbuilder import VMBuilder
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VMBuilderScript(VMBuilder):
 | 
			
		||||
    def setup(self):
 | 
			
		||||
        """
 | 
			
		||||
@@ -183,7 +186,7 @@ class VMBuilderScript(VMBuilder):
 | 
			
		||||
        # Add the network devices
 | 
			
		||||
        network_id = 0
 | 
			
		||||
        for network in self.vm_data["networks"]:
 | 
			
		||||
            vm_id_hex = "{:x}".format(int(vm_id % 16))
 | 
			
		||||
            vm_id_hex = "{:x}".format(int(self.vm_id % 16))
 | 
			
		||||
            net_id_hex = "{:x}".format(int(network_id % 16))
 | 
			
		||||
 | 
			
		||||
            if self.vm_data.get("mac_template") is not None:
 | 
			
		||||
 
 | 
			
		||||
@@ -116,12 +116,18 @@
 | 
			
		||||
#    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
from pvcapid.vmbuilder import VMBuilder
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VMBuilderScript(VMBuilder):
 | 
			
		||||
    def setup(self):
 | 
			
		||||
        """
 | 
			
		||||
        setup(): Perform special setup steps or validation before proceeding
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        # Run any imports first
 | 
			
		||||
        import daemon_lib.common as pvc_common
 | 
			
		||||
 | 
			
		||||
        # Ensure we have debootstrap intalled on the provisioner system
 | 
			
		||||
        retcode, stdout, stderr = pvc_common.run_os_command(f"which debootstrap")
 | 
			
		||||
        if retcode:
 | 
			
		||||
@@ -184,7 +190,7 @@ class VMBuilderScript(VMBuilder):
 | 
			
		||||
        # Add the network devices
 | 
			
		||||
        network_id = 0
 | 
			
		||||
        for network in self.vm_data["networks"]:
 | 
			
		||||
            vm_id_hex = "{:x}".format(int(vm_id % 16))
 | 
			
		||||
            vm_id_hex = "{:x}".format(int(self.vm_id % 16))
 | 
			
		||||
            net_id_hex = "{:x}".format(int(network_id % 16))
 | 
			
		||||
 | 
			
		||||
            if self.vm_data.get("mac_template") is not None:
 | 
			
		||||
@@ -376,6 +382,9 @@ class VMBuilderScript(VMBuilder):
 | 
			
		||||
        arguments for demonstration.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        # Run any imports first
 | 
			
		||||
        from pvcapid.vmbuilder import chroot
 | 
			
		||||
 | 
			
		||||
        # The directory we mounted things on earlier during prepare()
 | 
			
		||||
        temporary_directory = "/tmp/target"
 | 
			
		||||
 | 
			
		||||
@@ -541,7 +550,7 @@ GRUB_DISABLE_LINUX_UUID=false
 | 
			
		||||
            fh.write(data)
 | 
			
		||||
 | 
			
		||||
        # Chroot, do some in-root tasks, then exit the chroot
 | 
			
		||||
        with chroot_target(temporary_directory):
 | 
			
		||||
        with chroot(temporary_directory):
 | 
			
		||||
            # Install and update GRUB
 | 
			
		||||
            os.system(
 | 
			
		||||
                "grub-install --force /dev/rbd/{}/{}_{}".format(
 | 
			
		||||
 
 | 
			
		||||
@@ -137,11 +137,11 @@ def chroot(destination):
 | 
			
		||||
        os.fchdir(fake_root)
 | 
			
		||||
        yield
 | 
			
		||||
    except Exception:
 | 
			
		||||
        pass
 | 
			
		||||
        raise
 | 
			
		||||
    finally:
 | 
			
		||||
        os.fchdir(real_root)
 | 
			
		||||
        os.chroot(".")
 | 
			
		||||
        os.fchdir(fake_root)
 | 
			
		||||
        os.fchdir(real_root)
 | 
			
		||||
        os.close(fake_root)
 | 
			
		||||
        os.close(real_root)
 | 
			
		||||
        del fake_root
 | 
			
		||||
@@ -554,6 +554,46 @@ def create_vm(
 | 
			
		||||
 | 
			
		||||
    print("Chroot environment prepared successfully")
 | 
			
		||||
 | 
			
		||||
    def general_cleanup():
 | 
			
		||||
        print("Running upper cleanup steps")
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            # Unmount bind-mounted devfs on the chroot
 | 
			
		||||
            retcode, stdout, stderr = pvc_common.run_os_command(
 | 
			
		||||
                f"umount {temp_dir}/dev"
 | 
			
		||||
            )
 | 
			
		||||
            # Unmount bind-mounted runfs on the chroot
 | 
			
		||||
            retcode, stdout, stderr = pvc_common.run_os_command(
 | 
			
		||||
                f"umount {temp_dir}/run"
 | 
			
		||||
            )
 | 
			
		||||
            # Unmount bind-mounted sysfs on the chroot
 | 
			
		||||
            retcode, stdout, stderr = pvc_common.run_os_command(
 | 
			
		||||
                f"umount {temp_dir}/sys"
 | 
			
		||||
            )
 | 
			
		||||
            # Unmount bind-mounted tmpfs on the chroot
 | 
			
		||||
            retcode, stdout, stderr = pvc_common.run_os_command(
 | 
			
		||||
                f"umount {temp_dir}/tmp"
 | 
			
		||||
            )
 | 
			
		||||
            # Unmount bind-mounted rootfs on the chroot
 | 
			
		||||
            retcode, stdout, stderr = pvc_common.run_os_command(f"umount {temp_dir}")
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            # We don't care about fails during cleanup, log and continue
 | 
			
		||||
            print(f"Suberror during general cleanup unmounts: {e}")
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            # Remove the temp_dir
 | 
			
		||||
            os.rmdir(temp_dir)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            # We don't care about fails during cleanup, log and continue
 | 
			
		||||
            print(f"Suberror during general cleanup directory removal: {e}")
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            # Remote temporary script (don't fail if not removed)
 | 
			
		||||
            os.remove(script_file)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            # We don't care about fails during cleanup, log and continue
 | 
			
		||||
            print(f"Suberror during general cleanup script removal: {e}")
 | 
			
		||||
 | 
			
		||||
    # Phase 4 - script: setup()
 | 
			
		||||
    #  * Run pre-setup steps
 | 
			
		||||
    self.update_state(
 | 
			
		||||
@@ -568,8 +608,12 @@ def create_vm(
 | 
			
		||||
 | 
			
		||||
    print("Running script setup() step")
 | 
			
		||||
 | 
			
		||||
    with chroot(temp_dir):
 | 
			
		||||
        vm_builder.setup()
 | 
			
		||||
    try:
 | 
			
		||||
        with chroot(temp_dir):
 | 
			
		||||
            vm_builder.setup()
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        general_cleanup()
 | 
			
		||||
        raise ProvisioningError(f"Error in setup(): {e}")
 | 
			
		||||
 | 
			
		||||
    # Phase 5 - script: create()
 | 
			
		||||
    #  * Prepare the libvirt XML defintion for the VM
 | 
			
		||||
@@ -586,9 +630,14 @@ def create_vm(
 | 
			
		||||
    if define_vm:
 | 
			
		||||
        print("Running script create() step")
 | 
			
		||||
 | 
			
		||||
        with chroot(temp_dir):
 | 
			
		||||
            vm_schema = vm_builder.create()
 | 
			
		||||
            print("Generated VM schema:\n{}\n".format(vm_schema))
 | 
			
		||||
        try:
 | 
			
		||||
            with chroot(temp_dir):
 | 
			
		||||
                vm_schema = vm_builder.create()
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            general_cleanup()
 | 
			
		||||
            raise ProvisioningError(f"Error in create(): {e}")
 | 
			
		||||
 | 
			
		||||
        print("Generated VM schema:\n{}\n".format(vm_schema))
 | 
			
		||||
 | 
			
		||||
        print("Defining VM on cluster")
 | 
			
		||||
        node_limit = vm_data["system_details"]["node_limit"]
 | 
			
		||||
@@ -627,8 +676,12 @@ def create_vm(
 | 
			
		||||
 | 
			
		||||
    print("Running script prepare() step")
 | 
			
		||||
 | 
			
		||||
    with chroot(temp_dir):
 | 
			
		||||
        vm_builder.prepare()
 | 
			
		||||
    try:
 | 
			
		||||
        with chroot(temp_dir):
 | 
			
		||||
            vm_builder.prepare()
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        general_cleanup()
 | 
			
		||||
        raise ProvisioningError(f"Error in prepare(): {e}")
 | 
			
		||||
 | 
			
		||||
    # Phase 7 - script: install()
 | 
			
		||||
    #  * Run installation with arguments
 | 
			
		||||
@@ -644,8 +697,12 @@ def create_vm(
 | 
			
		||||
 | 
			
		||||
    print("Running script install() step")
 | 
			
		||||
 | 
			
		||||
    with chroot(temp_dir):
 | 
			
		||||
        vm_builder.install()
 | 
			
		||||
    try:
 | 
			
		||||
        with chroot(temp_dir):
 | 
			
		||||
            vm_builder.install()
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        general_cleanup()
 | 
			
		||||
        raise ProvisioningError(f"Error in install(): {e}")
 | 
			
		||||
 | 
			
		||||
    # Phase 8 - script: cleanup()
 | 
			
		||||
    #  * Run cleanup steps
 | 
			
		||||
@@ -661,8 +718,12 @@ def create_vm(
 | 
			
		||||
 | 
			
		||||
    print("Running script cleanup() step")
 | 
			
		||||
 | 
			
		||||
    with chroot(temp_dir):
 | 
			
		||||
        vm_builder.cleanup()
 | 
			
		||||
    try:
 | 
			
		||||
        with chroot(temp_dir):
 | 
			
		||||
            vm_builder.cleanup()
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        general_cleanup()
 | 
			
		||||
        raise ProvisioningError(f"Error in cleanup(): {e}")
 | 
			
		||||
 | 
			
		||||
    # Phase 9 - general cleanup
 | 
			
		||||
    #  * Clean up the chroot from earlier
 | 
			
		||||
@@ -671,45 +732,12 @@ def create_vm(
 | 
			
		||||
        meta={
 | 
			
		||||
            "current": 9,
 | 
			
		||||
            "total": 10,
 | 
			
		||||
            "status": "Running upper cleanup steps",
 | 
			
		||||
            "status": "Running general cleanup steps",
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
    time.sleep(1)
 | 
			
		||||
 | 
			
		||||
    print("Running upper cleanup steps")
 | 
			
		||||
 | 
			
		||||
    # Remote temporary script (don't fail if not removed)
 | 
			
		||||
    if not os.remove(script_file):
 | 
			
		||||
        print(f"Failed to delete temporary script file '{script_file}'.")
 | 
			
		||||
 | 
			
		||||
    # Unmount bind-mounted devfs on the chroot
 | 
			
		||||
    retcode, stdout, stderr = pvc_common.run_os_command(f"umount {temp_dir}/dev")
 | 
			
		||||
    if retcode:
 | 
			
		||||
        raise ProvisioningError(f"Failed to unmount devfs from chroot: {stderr}")
 | 
			
		||||
 | 
			
		||||
    # Unmount bind-mounted runfs on the chroot
 | 
			
		||||
    retcode, stdout, stderr = pvc_common.run_os_command(f"umount {temp_dir}/run")
 | 
			
		||||
    if retcode:
 | 
			
		||||
        raise ProvisioningError(f"Failed to unmount runfs from chroot: {stderr}")
 | 
			
		||||
 | 
			
		||||
    # Unmount bind-mounted sysfs on the chroot
 | 
			
		||||
    retcode, stdout, stderr = pvc_common.run_os_command(f"umount {temp_dir}/sys")
 | 
			
		||||
    if retcode:
 | 
			
		||||
        raise ProvisioningError(f"Failed to unmount sysfs from chroot: {stderr}")
 | 
			
		||||
 | 
			
		||||
    # Unmount bind-mounted tmpfs on the chroot
 | 
			
		||||
    retcode, stdout, stderr = pvc_common.run_os_command(f"umount {temp_dir}/tmp")
 | 
			
		||||
    if retcode:
 | 
			
		||||
        raise ProvisioningError(f"Failed to unmount tmpfs from chroot: {stderr}")
 | 
			
		||||
 | 
			
		||||
    # Unmount bind-mounted rootfs on the chroot
 | 
			
		||||
    retcode, stdout, stderr = pvc_common.run_os_command(f"umount {temp_dir}")
 | 
			
		||||
    if retcode:
 | 
			
		||||
        raise ProvisioningError(f"Failed to unmount rootfs from chroot: {stderr}")
 | 
			
		||||
 | 
			
		||||
    # Remove the temp_dir
 | 
			
		||||
    if not os.rmdir(temp_dir):
 | 
			
		||||
        print(f"Failed to delete temporary chroot directory '{temp_dir}'.")
 | 
			
		||||
    general_cleanup()
 | 
			
		||||
 | 
			
		||||
    # Phase 10 - startup
 | 
			
		||||
    #  * Start the VM in the PVC cluster
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user