Run apply/rollback in background via systemd-run and add CLI modes
This commit is contained in:
57
pikit-api.py
57
pikit-api.py
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import json, os, subprocess, socket, shutil, pathlib, datetime, tarfile
|
import json, os, subprocess, socket, shutil, pathlib, datetime, tarfile, sys, argparse
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
import re
|
import re
|
||||||
import urllib.request
|
import urllib.request
|
||||||
@@ -741,6 +741,28 @@ def rollback_update_stub():
|
|||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
|
def start_background_task(mode: str):
|
||||||
|
"""
|
||||||
|
Kick off a background update/rollback via systemd-run so nginx/API restarts
|
||||||
|
do not break the caller connection.
|
||||||
|
mode: "apply" or "rollback"
|
||||||
|
"""
|
||||||
|
assert mode in ("apply", "rollback"), "invalid mode"
|
||||||
|
unit = f"pikit-update-{mode}"
|
||||||
|
flag = f"--{mode}-update"
|
||||||
|
cmd = [
|
||||||
|
"systemd-run",
|
||||||
|
"--unit",
|
||||||
|
unit,
|
||||||
|
"--quiet",
|
||||||
|
"/usr/bin/env",
|
||||||
|
"python3",
|
||||||
|
str(API_PATH),
|
||||||
|
flag,
|
||||||
|
]
|
||||||
|
subprocess.run(cmd, check=False)
|
||||||
|
|
||||||
|
|
||||||
def acquire_lock():
|
def acquire_lock():
|
||||||
try:
|
try:
|
||||||
ensure_dir(UPDATE_LOCK.parent)
|
ensure_dir(UPDATE_LOCK.parent)
|
||||||
@@ -899,11 +921,20 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
state = check_for_update()
|
state = check_for_update()
|
||||||
return self._send(200, state)
|
return self._send(200, state)
|
||||||
if self.path.startswith("/api/update/apply"):
|
if self.path.startswith("/api/update/apply"):
|
||||||
state = apply_update_stub()
|
# Start background apply to avoid breaking caller during service restart
|
||||||
return self._send(200, state)
|
start_background_task("apply")
|
||||||
|
state = load_update_state()
|
||||||
|
state["status"] = "in_progress"
|
||||||
|
state["message"] = "Starting background apply"
|
||||||
|
save_update_state(state)
|
||||||
|
return self._send(202, state)
|
||||||
if self.path.startswith("/api/update/rollback"):
|
if self.path.startswith("/api/update/rollback"):
|
||||||
state = rollback_update_stub()
|
start_background_task("rollback")
|
||||||
return self._send(200, state)
|
state = load_update_state()
|
||||||
|
state["status"] = "in_progress"
|
||||||
|
state["message"] = "Starting rollback"
|
||||||
|
save_update_state(state)
|
||||||
|
return self._send(202, state)
|
||||||
if self.path.startswith("/api/update/auto"):
|
if self.path.startswith("/api/update/auto"):
|
||||||
state = load_update_state()
|
state = load_update_state()
|
||||||
state["auto_check"] = bool(payload.get("enable"))
|
state["auto_check"] = bool(payload.get("enable"))
|
||||||
@@ -1043,4 +1074,20 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="Pi-Kit API / updater")
|
||||||
|
parser.add_argument("--apply-update", action="store_true", help="Apply latest release (non-HTTP mode)")
|
||||||
|
parser.add_argument("--check-update", action="store_true", help="Check for latest release (non-HTTP mode)")
|
||||||
|
parser.add_argument("--rollback-update", action="store_true", help="Rollback to last backup (non-HTTP mode)")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.apply_update:
|
||||||
|
apply_update_stub()
|
||||||
|
sys.exit(0)
|
||||||
|
if args.check_update:
|
||||||
|
check_for_update()
|
||||||
|
sys.exit(0)
|
||||||
|
if args.rollback_update:
|
||||||
|
rollback_update_stub()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user