Skip provisioning process steps if script is "empty"

This commit is contained in:
Joshua Boniface 2020-01-05 16:35:55 -05:00
parent d1331401d8
commit 8b05dfea7b
1 changed files with 80 additions and 68 deletions

View File

@ -892,6 +892,13 @@ def create_vm(self, vm_name, vm_profile, define_vm=True, start_vm=True):
db_cur.execute(query, args) db_cur.execute(query, args)
vm_data['script'] = db_cur.fetchone()['script'] vm_data['script'] = db_cur.fetchone()['script']
if vm_data['script']['name'] == 'empty':
# We do not have a script; skip it
is_script_install = False
else:
is_script_install = True
close_database(db_conn, db_cur) close_database(db_conn, db_cur)
print("VM configuration data:\n{}".format(json.dumps(vm_data, sort_keys=True, indent=2))) print("VM configuration data:\n{}".format(json.dumps(vm_data, sort_keys=True, indent=2)))
@ -982,26 +989,27 @@ def create_vm(self, vm_name, vm_profile, define_vm=True, start_vm=True):
self.update_state(state='RUNNING', meta={'current': 3, 'total': 10, 'status': 'Preparing provisioning script'}) self.update_state(state='RUNNING', meta={'current': 3, 'total': 10, 'status': 'Preparing provisioning script'})
time.sleep(1) time.sleep(1)
# Write the script out to a temporary file if is_script_install:
retcode, stdout, stderr = run_os_command("mktemp") # Write the script out to a temporary file
if retcode: retcode, stdout, stderr = run_os_command("mktemp")
raise ProvisioningError("Failed to create a temporary file: {}".format(stderr)) if retcode:
script_file = stdout.strip() raise ProvisioningError("Failed to create a temporary file: {}".format(stderr))
with open(script_file, 'w') as fh: script_file = stdout.strip()
fh.write(vm_data['script']) with open(script_file, 'w') as fh:
fh.write('\n') fh.write(vm_data['script'])
fh.write('\n')
# Import the script file # Import the script file
loader = importlib.machinery.SourceFileLoader('installer_script', script_file) loader = importlib.machinery.SourceFileLoader('installer_script', script_file)
spec = importlib.util.spec_from_loader(loader.name, loader) spec = importlib.util.spec_from_loader(loader.name, loader)
installer_script = importlib.util.module_from_spec(spec) installer_script = importlib.util.module_from_spec(spec)
loader.exec_module(installer_script) loader.exec_module(installer_script)
# Verify that the install() function is valid # Verify that the install() function is valid
if not "install" in dir(installer_script): if not "install" in dir(installer_script):
raise ProvisioningError("Specified script does not contain an install() function") raise ProvisioningError("Specified script does not contain an install() function")
print("Provisioning script imported successfully") print("Provisioning script imported successfully")
# Phase 4 - disk creation # Phase 4 - disk creation
# * Create each Ceph storage volume for the disks # * Create each Ceph storage volume for the disks
@ -1052,53 +1060,55 @@ def create_vm(self, vm_name, vm_profile, define_vm=True, start_vm=True):
print("Created {} filesystem on {}:\n{}".format(volume['filesystem'], rbd_volume, stdout)) print("Created {} filesystem on {}:\n{}".format(volume['filesystem'], rbd_volume, stdout))
# Create temporary directory if is_script_install:
retcode, stdout, stderr = run_os_command("mktemp -d") # Create temporary directory
if retcode: retcode, stdout, stderr = run_os_command("mktemp -d")
raise ProvisioningError("Failed to create a temporary directory: {}".format(stderr))
temp_dir = stdout.strip()
for volume in vm_data['volumes']:
if not volume['mountpoint']:
continue
mapped_rbd_volume = "/dev/rbd/{}/{}_{}".format(volume['pool'], vm_name, volume['disk_id'])
mount_path = "{}{}".format(temp_dir, volume['mountpoint'])
# Ensure the mount path exists (within the filesystems)
retcode, stdout, stderr = run_os_command("mkdir -p {}".format(mount_path))
if retcode: if retcode:
raise ProvisioningError('Failed to create mountpoint "{}": {}'.format(mount_path, stderr)) raise ProvisioningError("Failed to create a temporary directory: {}".format(stderr))
temp_dir = stdout.strip()
# Mount filesystems to temporary directory for volume in vm_data['volumes']:
retcode, stdout, stderr = run_os_command("mount {} {}".format(mapped_rbd_volume, mount_path)) if not volume['mountpoint']:
if retcode: continue
raise ProvisioningError('Failed to mount "{}" on "{}": {}'.format(mapped_rbd_volume, mount_path, stderr))
print("Successfully mounted {} on {}".format(mapped_rbd_volume, mount_path)) mapped_rbd_volume = "/dev/rbd/{}/{}_{}".format(volume['pool'], vm_name, volume['disk_id'])
mount_path = "{}{}".format(temp_dir, volume['mountpoint'])
# Ensure the mount path exists (within the filesystems)
retcode, stdout, stderr = run_os_command("mkdir -p {}".format(mount_path))
if retcode:
raise ProvisioningError('Failed to create mountpoint "{}": {}'.format(mount_path, stderr))
# Mount filesystems to temporary directory
retcode, stdout, stderr = run_os_command("mount {} {}".format(mapped_rbd_volume, mount_path))
if retcode:
raise ProvisioningError('Failed to mount "{}" on "{}": {}'.format(mapped_rbd_volume, mount_path, stderr))
print("Successfully mounted {} on {}".format(mapped_rbd_volume, mount_path))
# Phase 6 - provisioning script execution # Phase 6 - provisioning script execution
# * Execute the provisioning script main function ("install") passing any custom arguments # * Execute the provisioning script main function ("install") passing any custom arguments
self.update_state(state='RUNNING', meta={'current': 6, 'total': 10, 'status': 'Executing provisioning script'}) self.update_state(state='RUNNING', meta={'current': 6, 'total': 10, 'status': 'Executing provisioning script'})
time.sleep(1) time.sleep(1)
print("Running installer script") if is_script_install:
print("Running installer script")
# Parse the script arguments # Parse the script arguments
script_arguments = dict() script_arguments = dict()
for argument in vm_data['script_arguments']: for argument in vm_data['script_arguments']:
argument_name, argument_data = argument.split('=') argument_name, argument_data = argument.split('=')
script_arguments[argument_name] = argument_data script_arguments[argument_name] = argument_data
# Run the script # Run the script
installer_script.install( installer_script.install(
vm_name=vm_name, vm_name=vm_name,
vm_id=vm_id, vm_id=vm_id,
temporary_directory=temp_dir, temporary_directory=temp_dir,
disks=vm_data['volumes'], disks=vm_data['volumes'],
networks=vm_data['networks'], networks=vm_data['networks'],
**script_arguments **script_arguments
) )
# Phase 7 - install cleanup # Phase 7 - install cleanup
# * Unmount any mounted volumes # * Unmount any mounted volumes
@ -1107,14 +1117,15 @@ def create_vm(self, vm_name, vm_profile, define_vm=True, start_vm=True):
time.sleep(1) time.sleep(1)
for volume in list(reversed(vm_data['volumes'])): for volume in list(reversed(vm_data['volumes'])):
# Unmount the volume if is_script_install:
if volume['mountpoint']: # Unmount the volume
print("Cleaning up mount {}{}".format(temp_dir, volume['mountpoint'])) if volume['mountpoint']:
print("Cleaning up mount {}{}".format(temp_dir, volume['mountpoint']))
mount_path = "{}{}".format(temp_dir, volume['mountpoint']) mount_path = "{}{}".format(temp_dir, volume['mountpoint'])
retcode, stdout, stderr = run_os_command("umount {}".format(mount_path)) retcode, stdout, stderr = run_os_command("umount {}".format(mount_path))
if retcode: if retcode:
raise ProvisioningError('Failed to unmount "{}": {}'.format(mount_path, stderr)) raise ProvisioningError('Failed to unmount "{}": {}'.format(mount_path, stderr))
# Unmap the RBD device # Unmap the RBD device
if volume['filesystem']: if volume['filesystem']:
@ -1127,15 +1138,16 @@ def create_vm(self, vm_name, vm_profile, define_vm=True, start_vm=True):
print("Cleaning up temporary directories and files") print("Cleaning up temporary directories and files")
# Remove temporary mount directory (don't fail if not removed) if is_script_install:
retcode, stdout, stderr = run_os_command("rmdir {}".format(temp_dir)) # Remove temporary mount directory (don't fail if not removed)
if retcode: retcode, stdout, stderr = run_os_command("rmdir {}".format(temp_dir))
print('Failed to delete temporary directory "{}": {}'.format(temp_dir, stderr)) if retcode:
print('Failed to delete temporary directory "{}": {}'.format(temp_dir, stderr))
# Remote temporary script (don't fail if not removed) # Remote temporary script (don't fail if not removed)
retcode, stdout, stderr = run_os_command("rm -f {}".format(script_file)) retcode, stdout, stderr = run_os_command("rm -f {}".format(script_file))
if retcode: if retcode:
print('Failed to delete temporary script file "{}": {}'.format(script_file, stderr)) print('Failed to delete temporary script file "{}": {}'.format(script_file, stderr))
# Phase 8 - configuration creation # Phase 8 - configuration creation
# * Create the libvirt XML configuration # * Create the libvirt XML configuration