summaryrefslogtreecommitdiffstats
path: root/src/live
diff options
context:
space:
mode:
authorAlejandro Sirgo Rica <asirgo@soleta.eu>2024-04-02 12:51:34 +0200
committerAlejandro Sirgo Rica <asirgo@soleta.eu>2024-04-03 13:31:10 +0200
commitdfde363aa63ad3e7967da49f4ab599399b89e7f8 (patch)
tree051f1f1d1e3c8e07ae12af2bfb35174be18f1201 /src/live
parentc5ccc3c7e201beccf8eb3d329e478bb33b34d43e (diff)
src: log backtrace in unhandled error cases
Log an error message in known error cases and log a backtrace otherwise. Define a new error type OgError to be used in all the 'raise' blocks to define the error message to log. The exception propagates until it reaches send_internal_server_error() where the exception type is checked. If the type is OgError we log the exception message. Logs the backtrace for other types. The initial error implementation printed a backtrace everytime an error ocurred. The next iteration changed it to only print a backtrace in a very particular case but ended up omiting too much information such as syntax errors or unknown error context. The actual implementation only logs the cases we already cover in the codebase and logs a bracktrace in the others, enabling a better debugging experience.
Diffstat (limited to 'src/live')
-rw-r--r--src/live/ogOperations.py49
-rw-r--r--src/live/parttypes.py9
2 files changed, 30 insertions, 28 deletions
diff --git a/src/live/ogOperations.py b/src/live/ogOperations.py
index cfe05f6..0c08459 100644
--- a/src/live/ogOperations.py
+++ b/src/live/ogOperations.py
@@ -35,6 +35,7 @@ from src.utils.uefi import *
from src.utils.boot import *
from src.utils.sw_inventory import get_package_set
from src.utils.hw_inventory import get_hardware_inventory, legacy_list_hardware_inventory
+from src.log import OgError
OG_SHELL = '/bin/bash'
@@ -52,7 +53,7 @@ class OgLiveOperations:
proc = subprocess.call(["pkill", "-9", "browser"])
proc = subprocess.Popen(["browser", "-qws", url])
except Exception as e:
- raise RuntimeError('Cannot restart browser') from e
+ raise OgError('Cannot restart browser') from e
def _refresh_payload_disk(self, cxt, part_setup, num_disk):
part_setup['disk'] = str(num_disk)
@@ -119,7 +120,7 @@ class OgLiveOperations:
def _write_md5_file(self, path):
if not os.path.exists(path):
- raise ValueError(f'Invalid image path {path} when computing md5 checksum')
+ raise OgError(f'Invalid image path {path} when computing md5 checksum')
filename = path + ".full.sum"
dig = self._compute_md5(path)
try:
@@ -144,12 +145,12 @@ class OgLiveOperations:
r = shutil.copy(src, dst)
tip_write_csum(image_name)
except Exception as e:
- raise RuntimeError(f'Error copying image {image_name} to cache. Reported: {e}') from e
+ raise OgError(f'Error copying image {image_name} to cache. Reported: {e}') from e
def _restore_image_unicast(self, repo, name, devpath, cache=False):
if ogChangeRepo(repo, smb_user=self._smb_user, smb_pass=self._smb_pass) != 0:
self._restartBrowser(self._url)
- raise ValueError(f'Cannot change repository to {repo}')
+ raise OgError(f'Cannot change repository to {repo}')
logging.debug(f'restore_image_unicast: name => {name}')
if cache:
image_path = f'/opt/opengnsys/cache/opt/opengnsys/images/{name}.img'
@@ -162,7 +163,7 @@ class OgLiveOperations:
def _restore_image_tiptorrent(self, repo, name, devpath):
if not os.path.exists(OG_CACHE_PATH):
- raise RuntimeError('No cache partition is mounted')
+ raise OgError('No cache partition is mounted')
image_path = f'/opt/opengnsys/cache/opt/opengnsys/images/{name}.img'
try:
@@ -172,11 +173,11 @@ class OgLiveOperations:
except:
self._restartBrowser(self._url)
if (not os.path.exists(image_path)):
- raise RuntimeError(f'Image file {image_path} does not exist')
+ raise OgError(f'Image file {image_path} does not exist')
if (not tip_check_csum(repo, name)):
- raise RuntimeError(f'checksum file {name}.full.sum is missing in repository {repo}')
+ raise OgError(f'checksum file {name}.full.sum is missing in repository {repo}')
- raise RuntimeError(f'Unexpected error when restoring image file {image_path}')
+ raise OgError(f'Unexpected error when restoring image file {image_path}')
self._restore_image(image_path, devpath)
@@ -188,7 +189,7 @@ class OgLiveOperations:
cmd_pc = shlex.split(f'partclone.restore -d0 -C -I -o {devpath}')
if not os.path.exists(image_path):
- raise RuntimeError(f'Image not found at {image_path} during image restore')
+ raise OgError(f'Image not found at {image_path} during image restore')
with open('/tmp/command.log', 'wb', 0) as logfile:
proc_lzop = subprocess.Popen(cmd_lzop,
@@ -245,7 +246,7 @@ class OgLiveOperations:
executable=OG_SHELL)
(output, error) = ogRest.proc.communicate()
except Exception as e:
- raise RuntimeError(f'Error when running "shell run" subprocess: {e}') from e
+ raise OgError(f'Error when running "shell run" subprocess: {e}') from e
if ogRest.proc.returncode != 0:
logging.warn('Non zero exit code when running: %s', ' '.join(cmds))
@@ -269,9 +270,9 @@ class OgLiveOperations:
partdev = get_partition_device(int(disk), int(partition))
mountpoint = partdev.replace('dev', 'mnt')
if not mount_mkdir(partdev, mountpoint):
- raise RuntimeError(f'Error mounting {partdev} at {mountpoint}')
+ raise OgError(f'Error mounting {partdev} at {mountpoint}')
if not os.path.ismount(mountpoint):
- raise RuntimeError(f'Invalid mountpoint {mountpoint} for software inventory')
+ raise OgError(f'Invalid mountpoint {mountpoint} for software inventory')
self._restartBrowser(self._url_log)
pkgset = get_package_set(mountpoint)
@@ -294,7 +295,7 @@ class OgLiveOperations:
try:
inventory = get_hardware_inventory()
except Exception as e:
- raise RuntimeError(f'Error while running hardware inventory. {e}') from e
+ raise OgError(f'Error while running hardware inventory. {e}') from e
finally:
self._restartBrowser(self._url)
@@ -321,7 +322,7 @@ class OgLiveOperations:
elif table_type == 'GPT':
cxt.create_disklabel('gpt')
else:
- raise ValueError(f'Unsupported partition scheme {table_type}, only MSDOS and GPT are supported')
+ raise OgError(f'Unsupported partition scheme {table_type}, only MSDOS and GPT are supported')
logging.info(f'Setting up partition layout to {table_type}')
@@ -415,7 +416,7 @@ class OgLiveOperations:
if ogChangeRepo(repo, smb_user=self._smb_user, smb_pass=self._smb_pass) != 0:
self._restartBrowser(self._url)
- raise RuntimeError(f'Cannot change image repository to {repo}')
+ raise OgError(f'Cannot change image repository to {repo}')
if ogRest.terminated:
return
@@ -431,25 +432,25 @@ class OgLiveOperations:
if pa is None:
self._restartBrowser(self._url)
- raise RuntimeError(f'Target partition /dev/{diskname} not found')
+ raise OgError(f'Target partition /dev/{diskname} not found')
padev = cxt.partition_to_string(pa, fdisk.FDISK_FIELD_DEVICE)
fstype = cxt.partition_to_string(pa, fdisk.FDISK_FIELD_FSTYPE)
if not fstype:
- raise RuntimeError(f'No filesystem detected in {padev}. Aborting image creation')
+ raise OgError(f'No filesystem detected in {padev}. Aborting image creation')
if change_access(user=self._smb_user, pwd=self._smb_pass) == -1:
- raise RuntimeError('remount of /opt/opengnsys/images has failed')
+ raise OgError('remount of /opt/opengnsys/images has failed')
if os.access(f'/opt/opengnsys/images', os.R_OK | os.W_OK) == False:
- raise RuntimeError('Cannot access /opt/opengnsys/images in read and write mode, check permissions')
+ raise OgError('Cannot access /opt/opengnsys/images in read and write mode, check permissions')
if os.access(f'{image_path}', os.R_OK) == True:
logging.info(f'image file {image_path} already exists, updating.')
copy_windows_efi_bootloader(disk, partition)
if ogReduceFs(disk, partition) == -1:
- raise ValueError(f'Failed to shrink {fstype} filesystem in {padev}')
+ raise OgError(f'Failed to shrink {fstype} filesystem in {padev}')
cmd1 = shlex.split(f'partclone.{fstype} -I -C --clone -s {padev} -O -')
cmd2 = shlex.split(f'lzop -1 -fo {image_path}')
@@ -469,7 +470,7 @@ class OgLiveOperations:
try:
retdata = p2.communicate()
except OSError as e:
- raise OSError(f'Unexpected error when running partclone and lzop commands: {e}') from e
+ raise OgError(f'Unexpected error when running partclone and lzop commands: {e}') from e
finally:
logfile.close()
p2.terminate()
@@ -481,7 +482,7 @@ class OgLiveOperations:
ogExtendFs(disk, partition)
if os.access(f'{image_path}', os.R_OK) == False:
- raise RuntimeError(f'Cannot access partclone image file {image_path}')
+ raise OgError(f'Cannot access partclone image file {image_path}')
image_info = ogGetImageInfo(image_path)
except Exception as e:
@@ -492,7 +493,7 @@ class OgLiveOperations:
shutil.move(f'{image_path}.ant', image_path)
self._restartBrowser(self._url)
- raise RuntimeError(f'Failed to create image for {fstype} filesystem in device {padev}: {e}') from e
+ raise OgError(f'Failed to create image for {fstype} filesystem in device {padev}: {e}') from e
try:
st = os.stat(image_path)
@@ -510,7 +511,7 @@ class OgLiveOperations:
image_info.mtime = mtime
if self._write_md5_file(f'/opt/opengnsys/images/{name}.img') == -1:
- raise ValueError(f'Cannot write {name}.full.sum file')
+ raise OgError(f'Cannot write {name}.full.sum file')
self._restartBrowser(self._url)
diff --git a/src/live/parttypes.py b/src/live/parttypes.py
index b4c1793..d8db8f6 100644
--- a/src/live/parttypes.py
+++ b/src/live/parttypes.py
@@ -7,6 +7,7 @@
# (at your option) any later version.
import fdisk
+from src.log import OgError
GPT_PARTTYPES = {
'LINUX-SWAP': '0657FD6D-A4AB-43C4-84E5-0933C84B4F4F',
@@ -43,15 +44,15 @@ def get_gpt_parttype(cxt, ptype_str):
def get_parttype(cxt, ptype_str):
if not cxt:
- raise RuntimeError('No libfdisk context')
+ raise OgError('No libfdisk context')
if not cxt.label or cxt.label.name not in ['dos', 'gpt']:
- raise RuntimeError('Unknown libfdisk label')
+ raise OgError('Unknown libfdisk label')
if type(ptype_str) != str:
- raise RuntimeError('Invalid partition type')
+ raise OgError('Invalid partition type')
if cxt.label.name == 'dos':
return get_dos_parttype(cxt, ptype_str)
elif cxt.label.name == 'gpt':
return get_gpt_parttype(cxt, ptype_str)
else:
- raise RuntimeError(f'Invalid partition label \'{cxt.label.name}\'')
+ raise OgError(f'Invalid partition label \'{cxt.label.name}\'')