diff --git a/scripts/utils/auto_update_verify.py b/scripts/utils/auto_update_verify.py index 17079835..245166eb 100644 --- a/scripts/utils/auto_update_verify.py +++ b/scripts/utils/auto_update_verify.py @@ -23,8 +23,9 @@ success. """ import json import os -import subprocess +import subprocess # nosec B404 - list-form argv only, no shell # nosemgrep import sys +from collections import namedtuple import tempfile import time import traceback @@ -46,6 +47,10 @@ PIP_TIMEOUT_SECONDS = 600 #: candidates src/common/permission_utils.install_requirements_file tries. BASH_CANDIDATES = ('/usr/bin/bash', '/bin/bash') +#: What a command that could not run at all reports: its callers only read +#: these three fields, the same ones a completed subprocess has. +_Failed = namedtuple('_Failed', 'returncode stdout stderr') + def pending_path(project_root): return Path(project_root) / 'data' / PENDING_NAME @@ -104,7 +109,7 @@ class Verifier: return self.run(args, cwd=str(self.project_root), capture_output=True, text=True, timeout=timeout) except (subprocess.SubprocessError, OSError) as e: - return subprocess.CompletedProcess(args, 1, stdout='', stderr=str(e)) + return _Failed(returncode=1, stdout='', stderr=str(e)) # -- services --------------------------------------------------------- diff --git a/src/auto_update_setup.py b/src/auto_update_setup.py index 0ecf30f7..d4033791 100644 --- a/src/auto_update_setup.py +++ b/src/auto_update_setup.py @@ -23,7 +23,7 @@ import json import logging import os import re -import subprocess +import subprocess # nosec B404 - list-form argv only, no shell # nosemgrep import tempfile import time from pathlib import Path diff --git a/web_interface/auto_update.py b/web_interface/auto_update.py index 995dbdd9..ce76d2e9 100644 --- a/web_interface/auto_update.py +++ b/web_interface/auto_update.py @@ -32,7 +32,7 @@ import json import logging import os import shutil -import subprocess +import subprocess # nosec B404 - list-form argv only, no shell # nosemgrep import tempfile import threading import time @@ -574,7 +574,7 @@ class AutoUpdater: state['rolled_back_head'] = new else: outcome = 'rollback_failed' - message = (f'The LEDMatrix update to {_short(new)} failed ({reason or "unknown reason"}) and ' + message = (f'The LEDMatrix update to {_short(new)} failed ({reason or "unknown reason"}) and ' # nosec B608 - user-facing message, not SQL # nosemgrep f'could not be rolled back: {detail or "unknown error"}. The device may need ' f'attention: run "git reset --hard {old}" in the LEDMatrix folder, then restart ' 'the display and web services.')