diff options
author | Alejandro Sirgo Rica <asirgo@soleta.eu> | 2024-03-20 12:42:26 +0100 |
---|---|---|
committer | Alejandro Sirgo Rica <asirgo@soleta.eu> | 2024-03-26 13:32:48 +0100 |
commit | 57787dab5499a38915b5e2f702844553abd2ea2a (patch) | |
tree | 72d10e60579f38bdf94046d81fd3c311f5a90152 | |
parent | 16dcc9b25b305c81efc975df24cf13a04a30bf47 (diff) |
live: improve lzop and partclone error handling
Control non 0 returncode of the lzop and partclone subprocess
in image creation and restoration because this means that either
lzop or partclone has failed.
The implementation must cover cases such as not enough storage
space and log errors into /tmp/command.log and the log file of
the client handling the request.
Check the returncode of lzop and partclone subprocesses and
log the stderr of the process reporting non zero returncode.
-rw-r--r-- | src/live/ogOperations.py | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/src/live/ogOperations.py b/src/live/ogOperations.py index 05c6a10..364f3bd 100644 --- a/src/live/ogOperations.py +++ b/src/live/ogOperations.py @@ -183,20 +183,35 @@ class OgLiveOperations: def _restore_image(self, image_path, devpath): logging.debug(f'Restoring image at {image_path} into {devpath}') logging.debug(f'This process can take some time, please *DO NOT SHUT DOWN OR REBOOT* this client') + cmd_lzop = shlex.split(f'lzop -dc {image_path}') 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') + proc_lzop = subprocess.Popen(cmd_lzop, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc_pc = subprocess.Popen(cmd_pc, + stdin=proc_lzop.stdout, + stderr=subprocess.PIPE) + + pc_stderr = proc_pc.communicate()[1] + lzop_stderr = proc_lzop.stderr.read() + proc_lzop.poll() # update returncode + with open('/tmp/command.log', 'wb', 0) as logfile: - proc_lzop = subprocess.Popen(cmd_lzop, - stdout=subprocess.PIPE) - proc_pc = subprocess.Popen(cmd_pc, - stdin=proc_lzop.stdout, - stderr=logfile) - proc_lzop.stdout.close() - proc_pc.communicate() + logfile.write(lzop_stderr) + logfile.write(pc_stderr) + + if proc_lzop.returncode != 0: + raise OSError(f'lzop subprocess failed: {lzop_stderr.decode("utf-8")}') + + if proc_pc.returncode != 0: + raise OSError(f'partclone subprocess failed: {pc_stderr.decode("utf-8")}') + + logging.info('Image restore successful') def _ogbrowser_clear_logs(self): logfiles = ['/tmp/command.log', '/tmp/session.log'] @@ -450,32 +465,37 @@ class OgLiveOperations: if ogReduceFs(disk, partition) == -1: raise ValueError(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}') - - logfile = open('/tmp/command.log', 'wb', 0) - if os.path.exists(image_path) and backup: shutil.move(image_path, f'{image_path}.ant') - p1 = Popen(cmd1, stdout=PIPE, stderr=logfile) - p2 = Popen(cmd2, stdin=p1.stdout) - p1.stdout.close() - logging.info(f'Creating image at {image_path} from {padev} using {fstype}') logging.info('*DO NOT REBOOT OR POWEROFF* the client during this time') - try: - retdata = p2.communicate() - except OSError as e: - raise OSError(f'Unexpected error when running partclone and lzop commands: {e}') from e - finally: - logfile.close() - p2.terminate() - p1.poll() - - logging.info(f'partclone process exited with code {p1.returncode}') - logging.info(f'lzop process exited with code {p2.returncode}') + cmd_pc = shlex.split(f'partclone.{fstype} -I -C --clone -s {padev} -O -') + cmd_lzop = shlex.split(f'lzop -1 -fo {image_path}') + + proc_pc = subprocess.Popen(cmd_pc, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc_lzop = subprocess.Popen(cmd_lzop, + stdin=proc_pc.stdout, + stderr=subprocess.PIPE) + + lzop_stderr = proc_lzop.communicate()[1] + pc_stderr = proc_pc.stderr.read() + proc_pc.poll() # update returncode + + with open('/tmp/command.log', 'wb', 0) as logfile: + logfile.write(pc_stderr) + logfile.write(lzop_stderr) + + if proc_pc.returncode != 0: + raise OSError(f'partclone subprocess failed: {pc_stderr.decode("utf-8")}') + + if proc_lzop.returncode != 0: + raise OSError(f'lzop subprocess failed: {lzop_stderr.decode("utf-8")}') + + logging.info('Image creation successful') ogExtendFs(disk, partition) |