1
0
mirror of https://github.com/gryf/boxpy.git synced 2025-12-19 13:37:58 +01:00

Introducing custom exceptions tree.

This commit is contained in:
2021-04-08 21:44:54 +02:00
parent 4029284815
commit 69ff7206e5

56
box.py
View File

@@ -34,6 +34,26 @@ power_state:
''')
class BoxError(Exception):
pass
class BoxNotFound(BoxError):
pass
class BoxVBoxFailure(BoxError):
pass
class BoxConvertionError(BoxError):
pass
class BoxSysCommandError(BoxError):
pass
class VMCreate:
"""
Create vbox VM of Ubuntu server from cloud image with the following steps:
@@ -64,8 +84,8 @@ class VMCreate:
if not self.ssh_key_path.endswith('.pub'):
self.ssh_key_path += '.pub'
if not os.path.exists(self.ssh_key_path):
raise AttributeError(f'Cannot find default ssh public key: '
f'{self.ssh_key_path}')
raise BoxNotFound(f'Cannot find default ssh public key: '
f'{self.ssh_key_path}')
self._img = f"ubuntu-{self.ubuntu_version}-server-cloudimg-amd64.img"
self._temp_path = None
@@ -89,7 +109,7 @@ class VMCreate:
def _power_on_and_wait_for_ci_finish(self):
if subprocess.call(['vboxmanage', 'startvm', self._vm_uuid, '--type',
'headless']) != 0:
raise AttributeError(f'Failed to start: {self.vm_name}.')
raise BoxVBoxFailure(f'Failed to start: {self.vm_name}.')
# give VBox some time to actually change the state of the VM before
# query
@@ -112,13 +132,13 @@ class VMCreate:
'--device', '0',
'--type', 'dvddrive',
'--medium', 'none']) != 0:
raise AttributeError(f'Failed to detach cloud image from '
raise BoxVBoxFailure(f'Failed to detach cloud image from '
f'{self.vm_name} VM.')
# and start it again
if subprocess.call(['vboxmanage', 'startvm', self._vm_uuid, '--type',
'headless']) != 0:
raise AttributeError(f'Failed to start: {self.vm_name}.')
raise BoxVBoxFailure(f'Failed to start: {self.vm_name}.')
print('You can access your VM by issuing:')
print(f'ssh -p 2222 -i {self.ssh_key_path[:-4]} ubuntu@localhost')
@@ -154,7 +174,7 @@ class VMCreate:
for cmd in commands:
if subprocess.call(cmd) != 0:
cmd = ' '.join(cmd)
raise AttributeError(f'command: {cmd} has failed')
raise BoxVBoxFailure(f'command: {cmd} has failed')
def _create_and_setup_vm(self):
out = subprocess.check_output(['vboxmanage', 'createvm', '--name',
@@ -166,7 +186,7 @@ class VMCreate:
self._vm_uuid = line.split('UUID:')[1].strip()
if not self._vm_uuid:
raise OSError(f'Cannot create VM "{self.vm_name}".')
raise BoxVBoxFailure(f'Cannot create VM "{self.vm_name}".')
if subprocess.call(['vboxmanage', 'modifyvm', self._vm_uuid,
'--memory', str(self.memory),
@@ -176,7 +196,7 @@ class VMCreate:
'--audio', 'none',
'--nic1', 'nat',
'--natpf1', 'guestssh,tcp,,2222,,22']) != 0:
raise OSError(f'Cannot modify VM "{self._vm_uuid}".')
raise BoxVBoxFailure(f'Cannot modify VM "{self._vm_uuid}".')
out = subprocess.check_output(['vboxmanage', 'showvminfo',
self._vm_uuid],
encoding=sys.getdefaultencoding())
@@ -186,7 +206,7 @@ class VMCreate:
path = os.path.dirname(line.split('Config file:')[1].strip())
if not path:
raise AttributeError(f'There is something wrong doing VM '
raise BoxVBoxFailure(f'There is something wrong doing VM '
f'"{self.vm_name}" creation and registration')
self._vm_base_path = path
@@ -212,7 +232,8 @@ class VMCreate:
os.path.join(self._tmp, self.CLOUD_IMAGE),
os.path.join(self._tmp, 'user-data'),
os.path.join(self._tmp, 'meta-data')]) != 0:
raise AttributeError('Cannot create ISO image for config drive')
raise BoxSysCommandError('Cannot create ISO image for config '
'drive')
def _prepare_temp(self):
self._tmp = tempfile.mkdtemp()
@@ -234,7 +255,7 @@ class VMCreate:
break
if not expected_sum:
raise AttributeError('Cannot find provided cloud image')
raise BoxError('Cannot find provided cloud image')
if os.path.exists(os.path.join(self.CACHE_DIR, self._img)):
cmd = 'sha256sum ' + os.path.join(self.CACHE_DIR, self._img)
@@ -248,7 +269,8 @@ class VMCreate:
raw_path = os.path.join(self._tmp, self._img + ".raw")
if subprocess.call(['qemu-img', 'convert', '-O', 'raw',
img_path, raw_path]) != 0:
raise AttributeError(f'Cannot convert image {self._img} to RAW.')
raise BoxConvertionError(f'Cannot convert image {self._img} to '
'RAW.')
def _convert_and_resize(self):
self._convert_to_raw()
@@ -256,8 +278,8 @@ class VMCreate:
vdi_path = os.path.join(self._tmp, self._disk_img)
if subprocess.call(["vboxmanage", "convertfromraw", raw_path,
vdi_path]) != 0:
raise AttributeError(f'Cannot convert image {self._disk_img} '
'to VDI.')
raise BoxVBoxFailure(f'Cannot convert image {self._disk_img} '
f'to VDI.')
os.unlink(raw_path)
def _download_image(self):
@@ -275,8 +297,8 @@ class VMCreate:
if not self._checksum():
# TODO: make some retry mechanism?
raise AttributeError('Checksum for downloaded image differ from'
' expected')
raise BoxSysCommandError('Checksum for downloaded image differ '
'from expected.')
else:
print(f'Downloaded image {self._img}')
@@ -295,7 +317,7 @@ class VMDestroy:
'poweroff'], stderr=subprocess.DEVNULL)
if subprocess.call(['vboxmanage', 'unregistervm', self.vm_name_or_uuid,
'--delete']) != 0:
raise AttributeError(f'Removing VM {self.vm_name_or_uuid} failed')
raise BoxVBoxFailure(f'Removing VM {self.vm_name_or_uuid} failed')
def main():