summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlejandro Sirgo Rica <asirgo@soleta.eu>2024-03-20 12:42:26 +0100
committerAlejandro Sirgo Rica <asirgo@soleta.eu>2024-03-26 13:32:48 +0100
commit57787dab5499a38915b5e2f702844553abd2ea2a (patch)
tree72d10e60579f38bdf94046d81fd3c311f5a90152
parent16dcc9b25b305c81efc975df24cf13a04a30bf47 (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.py74
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)