Compare commits
6
Commits
edf6294315
...
v1.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff70668f38 | ||
|
|
fbe431555e | ||
|
|
bd4c4f8716 | ||
|
|
201cdb5bf9 | ||
|
|
7ba4adb376 | ||
|
|
a4fc880c38 |
@@ -1219,7 +1219,7 @@ def _generate_qr_base64(data: str) -> str | None:
|
|||||||
# ── Update helpers (file-based, no systemctl) ────────────────────
|
# ── Update helpers (file-based, no systemctl) ────────────────────
|
||||||
|
|
||||||
def _read_update_status() -> str:
|
def _read_update_status() -> str:
|
||||||
"""Read the status file. Returns RUNNING, SUCCESS, FAILED, or IDLE."""
|
"""Read the status file. Returns RUNNING, SUCCESS, REBOOT_REQUIRED, FAILED, or IDLE."""
|
||||||
try:
|
try:
|
||||||
with open(UPDATE_STATUS, "r") as f:
|
with open(UPDATE_STATUS, "r") as f:
|
||||||
return f.read().strip()
|
return f.read().strip()
|
||||||
@@ -4755,17 +4755,21 @@ def _recover_stale_status(status_file: str, log_file: str, unit_name: str) -> bo
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
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:
|
try:
|
||||||
with open(status_file, "w") as f:
|
with open(status_file, "w") as f:
|
||||||
f.write(new_status)
|
f.write(new_status)
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
msg = (
|
if new_status == "REBOOT_REQUIRED":
|
||||||
"\n[Update completed successfully while the server was restarting.]\n"
|
msg = "\n[Update staged successfully while the server was restarting. Reboot required.]\n"
|
||||||
if new_status == "SUCCESS"
|
elif new_status == "SUCCESS":
|
||||||
else "\n[Update encountered an error. See log above for details.]\n"
|
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:
|
try:
|
||||||
with open(log_file, "a") as f:
|
with open(log_file, "a") as f:
|
||||||
f.write(msg)
|
f.write(msg)
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
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.find(start)
|
||||||
|
if start_idx == -1:
|
||||||
|
raise AssertionError(f"Expected section start not found: {start!r}")
|
||||||
|
end_idx = source.find(end, start_idx)
|
||||||
|
if end_idx == -1:
|
||||||
|
raise AssertionError(f"Expected section end not found: {end!r}")
|
||||||
|
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()
|
||||||
@@ -146,33 +146,16 @@ let
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
if [ "$RC" -eq 0 ]; then
|
if [ "$RC" -eq 0 ]; then
|
||||||
echo "── Step 2/3: nixos-rebuild ──────────────────────────"
|
echo "── Step 2/3: nixos-rebuild boot (stage next reboot) ──"
|
||||||
SWITCH_OUT=$(nixos-rebuild switch --flake /etc/nixos --print-build-logs \
|
BOOT_OUT=$(nixos-rebuild boot --flake /etc/nixos --print-build-logs \
|
||||||
--option connect-timeout 10 \
|
--option connect-timeout 10 \
|
||||||
--option stalled-download-timeout 90 \
|
--option stalled-download-timeout 90 \
|
||||||
--option download-attempts 7 \
|
--option download-attempts 7 \
|
||||||
--option fallback true 2>&1)
|
--option fallback true 2>&1)
|
||||||
SWITCH_RC=$?
|
BOOT_RC=$?
|
||||||
echo "$SWITCH_OUT"
|
echo "$BOOT_OUT"
|
||||||
if [ "$SWITCH_RC" -eq 0 ]; then
|
if [ "$BOOT_RC" -ne 0 ]; then
|
||||||
echo "[OK] switch succeeded"
|
echo "[ERROR] nixos-rebuild boot failed"
|
||||||
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"
|
|
||||||
RC=1
|
RC=1
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
@@ -188,9 +171,10 @@ let
|
|||||||
|
|
||||||
if [ "$RC" -eq 0 ]; then
|
if [ "$RC" -eq 0 ]; then
|
||||||
echo "══════════════════════════════════════════════════"
|
echo "══════════════════════════════════════════════════"
|
||||||
echo " ✓ Update completed successfully"
|
echo " ✓ Update staged successfully"
|
||||||
|
echo " Reboot required to activate the new system"
|
||||||
echo "══════════════════════════════════════════════════"
|
echo "══════════════════════════════════════════════════"
|
||||||
echo "SUCCESS" > "$STATUS"
|
echo "REBOOT_REQUIRED" > "$STATUS"
|
||||||
else
|
else
|
||||||
echo "══════════════════════════════════════════════════"
|
echo "══════════════════════════════════════════════════"
|
||||||
echo " ✗ Update failed — see errors above"
|
echo " ✗ Update failed — see errors above"
|
||||||
|
|||||||
Reference in New Issue
Block a user