Stage Hub full updates for next reboot

This commit is contained in:
copilot-swe-agent[bot]
2026-07-13 17:39:14 +00:00
committed by GitHub
parent a4fc880c38
commit 7ba4adb376
3 changed files with 60 additions and 32 deletions
+11 -7
View File
@@ -1219,7 +1219,7 @@ def _generate_qr_base64(data: str) -> str | None:
# ── Update helpers (file-based, no systemctl) ────────────────────
def _read_update_status() -> str:
"""Read the status file. Returns RUNNING, SUCCESS, FAILED, or IDLE."""
"""Read the status file. Returns RUNNING, REBOOT_REQUIRED, SUCCESS, FAILED, or IDLE."""
try:
with open(UPDATE_STATUS, "r") as f:
return f.read().strip()
@@ -4755,17 +4755,21 @@ def _recover_stale_status(status_file: str, log_file: str, unit_name: str) -> bo
except Exception:
pass
new_status = "SUCCESS" if unit_result == "success" else "FAILED"
if unit_result == "success":
new_status = "REBOOT_REQUIRED" if unit_name == UPDATE_UNIT else "SUCCESS"
else:
new_status = "FAILED"
try:
with open(status_file, "w") as f:
f.write(new_status)
except OSError:
pass
msg = (
"\n[Update completed successfully while the server was restarting.]\n"
if new_status == "SUCCESS"
else "\n[Update encountered an error. See log above for details.]\n"
)
if new_status == "REBOOT_REQUIRED":
msg = "\n[Update staged successfully while the server was restarting. Reboot required.]\n"
elif new_status == "SUCCESS":
msg = "\n[Update completed successfully while the server was restarting.]\n"
else:
msg = "\n[Update encountered an error. See log above for details.]\n"
try:
with open(log_file, "a") as f:
f.write(msg)
+40
View File
@@ -0,0 +1,40 @@
import unittest
from pathlib import Path
HUB_NIX = Path(__file__).resolve().parents[2] / "modules" / "core" / "sovran-hub.nix"
def _section(source: str, start: str, end: str) -> str:
start_idx = source.index(start)
end_idx = source.index(end, start_idx)
return source[start_idx:end_idx]
class HubUpdateBootStagingTests(unittest.TestCase):
def setUp(self):
self.source = HUB_NIX.read_text()
self.update_section = _section(
self.source,
'update-script = pkgs.writeShellScript "sovran-hub-update.sh" \'\'',
"# ── Rebuild wrapper script",
)
self.rebuild_section = _section(
self.source,
'rebuild-script = pkgs.writeShellScript "sovran-hub-rebuild.sh" \'\'',
"# ── Brave launcher wrapper",
)
def test_full_update_uses_boot_not_switch(self):
self.assertIn("nixos-rebuild boot --flake /etc/nixos", self.update_section)
self.assertNotIn("nixos-rebuild switch --flake /etc/nixos", self.update_section)
def test_full_update_marks_reboot_required(self):
self.assertIn('echo "REBOOT_REQUIRED" > "$STATUS"', self.update_section)
def test_rebuild_path_keeps_switch_semantics(self):
self.assertIn("nixos-rebuild switch --flake /etc/nixos", self.rebuild_section)
if __name__ == "__main__":
unittest.main()
+9 -25
View File
@@ -146,33 +146,16 @@ let
echo ""
if [ "$RC" -eq 0 ]; then
echo " Step 2/3: nixos-rebuild "
SWITCH_OUT=$(nixos-rebuild switch --flake /etc/nixos --print-build-logs \
echo " Step 2/3: nixos-rebuild boot (stage next reboot) "
BOOT_OUT=$(nixos-rebuild boot --flake /etc/nixos --print-build-logs \
--option connect-timeout 10 \
--option stalled-download-timeout 90 \
--option download-attempts 7 \
--option fallback true 2>&1)
SWITCH_RC=$?
echo "$SWITCH_OUT"
if [ "$SWITCH_RC" -eq 0 ]; then
echo "[OK] switch succeeded"
elif echo "$SWITCH_OUT" | grep -q "switchInhibitors\|Pre-switch checks failed"; then
echo ""
echo " Build succeeded a reboot is required to apply this update"
echo " (Critical system components changed; running nixos-rebuild boot instead)"
if nixos-rebuild boot --flake /etc/nixos --print-build-logs \
--option connect-timeout 10 \
--option stalled-download-timeout 90 \
--option download-attempts 7 \
--option fallback true 2>&1; then
echo "REBOOT_REQUIRED" > "$STATUS"
exit 0
else
echo "[ERROR] nixos-rebuild boot also failed"
RC=1
fi
else
echo "[ERROR] nixos-rebuild switch failed"
BOOT_RC=$?
echo "$BOOT_OUT"
if [ "$BOOT_RC" -ne 0 ]; then
echo "[ERROR] nixos-rebuild boot failed"
RC=1
fi
echo ""
@@ -188,9 +171,10 @@ let
if [ "$RC" -eq 0 ]; then
echo ""
echo " Update completed successfully"
echo " Update staged successfully"
echo " Reboot required to activate the new system"
echo ""
echo "SUCCESS" > "$STATUS"
echo "REBOOT_REQUIRED" > "$STATUS"
else
echo ""
echo " Update failed see errors above"