同步移动端工程、设备控制改进与发布资料
This commit is contained in:
@@ -11,6 +11,7 @@ from typing import Any, AsyncIterable, Callable
|
||||
from uuid import uuid4
|
||||
|
||||
from app.display.service import DisplayService
|
||||
from app.system.kernel_recovery import KernelRecovery
|
||||
|
||||
from .diagnostics import failure_log_metadata, read_failure_log
|
||||
from .package import MAX_OTA_UPLOAD_BYTES, OtaPackageError, inspect_package
|
||||
@@ -84,8 +85,45 @@ class OtaManager:
|
||||
"last_result": last_result,
|
||||
"failure_log_available": failure_log_available,
|
||||
"failure_log_bytes": failure_log_bytes,
|
||||
"kernel_recovery": self.kernel_recovery_status(),
|
||||
}
|
||||
|
||||
def _production_recovery(self) -> KernelRecovery | None:
|
||||
if os.name == "nt" or self.data_root != Path("/var/lib/matrix-screen-controller"):
|
||||
return None
|
||||
return KernelRecovery(self.data_root)
|
||||
|
||||
def kernel_recovery_status(self) -> dict[str, str]:
|
||||
recovery = self._production_recovery()
|
||||
return recovery.status() if recovery else {"state": "not_needed", "reason": ""}
|
||||
|
||||
def schedule_kernel_recovery_after_ota(self) -> None:
|
||||
recovery = self._production_recovery()
|
||||
if recovery is None:
|
||||
return
|
||||
result = read_last_result(self.data_root)
|
||||
if not result or result.get("status") != "success" or result.get("target_version") != str(self.software_version):
|
||||
return
|
||||
result_id = f"{result.get('target_version')}:{result.get('installed_at')}"
|
||||
if not recovery.prepare_attempt(result_id):
|
||||
return
|
||||
command = [
|
||||
"systemd-run", "--quiet", "--collect", "--unit=matrix-kernel-recovery",
|
||||
"--on-active=5s", "/usr/bin/python3",
|
||||
"/opt/matrix-screen-controller/app/system/kernel_recovery.py", "arm-and-reboot",
|
||||
]
|
||||
try:
|
||||
subprocess.run(command, check=True, capture_output=True, timeout=10)
|
||||
except (OSError, subprocess.CalledProcessError, subprocess.TimeoutExpired) as exc:
|
||||
recovery.write_record("failed", f"could not schedule kernel recovery: {exc}", attempts=0)
|
||||
|
||||
def finalize_kernel_recovery_after_boot(self) -> None:
|
||||
recovery = self._production_recovery()
|
||||
if recovery is None:
|
||||
return
|
||||
thread = threading.Thread(target=recovery.finalize_after_boot, name="kernel-recovery-finalize", daemon=True)
|
||||
thread.start()
|
||||
|
||||
def failure_log(self) -> bytes | None:
|
||||
last_result = read_last_result(self.data_root)
|
||||
return read_failure_log(self.data_root, last_result)
|
||||
|
||||
Reference in New Issue
Block a user