feat(plugins): add plugin manager service installation and restart logic

This commit is contained in:
Rightup committed 2026-09-04 21:30:29 +01:00
1 parent 65836c2e2f
commit 9ce23a77d5
2 files changed
+100

No files matched your search

+47
View File
@@ -915,6 +915,52 @@ def _disable_legacy_services() -> None:
subprocess.run([_SYSTEMCTL_BIN, "daemon-reload"], check=False) # nosec B603
def _ensure_plugin_manager_service() -> None:
"""Install and enable the plugin-manager service unit when present."""
service_unit = "/etc/systemd/system/openhop-plugin-manager.service"
candidates = [
"/root/openhop-repeater/openhop-plugin-manager.service",
"/opt/openhop_repeater/openhop-plugin-manager.service",
"/opt/openhop_repeater/openhop-repeater/openhop-plugin-manager.service",
"/root/scripts/openhop-plugin-manager.service",
"/opt/openhop_repeater/openhop-repeater/openhop-plugin-manager.service",
]
source = next((path for path in candidates if os.path.isfile(path)), None)
if source and not os.path.isfile(service_unit):
_state.append_line(f"[pyMC updater] Installing plugin-manager service from {source}")
try:
os.makedirs(os.path.dirname(service_unit), exist_ok=True)
shutil.copy2(source, service_unit)
except OSError as exc:
logger.warning(f"[Update] Could not install plugin-manager unit: {exc}")
return
if not os.path.isfile(service_unit):
return
_state.append_line("[pyMC updater] Ensuring openhop-plugin-manager service is enabled")
for cmd in (
[_SYSTEMCTL_BIN, "daemon-reload"],
[_SYSTEMCTL_BIN, "enable", "openhop-plugin-manager"],
):
subprocess.run(cmd, check=False, capture_output=True, text=True) # nosec B603
restart = subprocess.run(
[_SYSTEMCTL_BIN, "restart", "openhop-plugin-manager"],
check=False,
capture_output=True,
text=True,
) # nosec B603
if restart.returncode != 0:
subprocess.run(
[_SYSTEMCTL_BIN, "start", "openhop-plugin-manager"],
check=False,
capture_output=True,
text=True,
) # nosec B603
def _do_install() -> None:
channel = _state.channel
@@ -1023,6 +1069,7 @@ def _do_install() -> None:
if success:
_cleanup_stale_dist_info()
_ensure_plugin_manager_service()
_state.append_line("[pyMC updater] Restarting service in 3 seconds…")
time.sleep(3)
restart_ok = False
+53
View File
@@ -440,6 +440,53 @@ def test_do_install_wrapper_success_then_restart_failure(isolated_state, monkeyp
assert "restart failed" in (st.error_message or "")
def test_do_install_restarts_plugin_manager_service_when_present(isolated_state, monkeypatch):
st = isolated_state
st.channel = "main"
st.latest_version = "4.0.0"
monkeypatch.setattr(ue.os, "geteuid", lambda: 1000)
monkeypatch.setattr(ue, "is_buildroot", lambda: False)
monkeypatch.setattr(ue, "_cleanup_stale_dist_info", lambda *args, **kwargs: None)
monkeypatch.setattr(ue.time, "sleep", lambda _s: None)
monkeypatch.setattr(
ue.os.path,
"isfile",
lambda p: (
p
in {
"/usr/local/bin/pymc-do-upgrade",
"/etc/systemd/system/openhop-plugin-manager.service",
}
),
)
monkeypatch.setattr("repeater.service_utils.restart_service", lambda: (True, "ok"))
calls = []
def fake_run(cmd, **kwargs):
calls.append(cmd)
return SimpleNamespace(returncode=0, stdout="", stderr="")
class _Proc:
def __init__(self, cmd):
self.cmd = cmd
self.stdout = ["ok\n"]
self.returncode = 0
def wait(self):
return None
monkeypatch.setattr(ue.subprocess, "Popen", lambda cmd, **kwargs: _Proc(cmd))
monkeypatch.setattr(ue.subprocess, "run", fake_run)
ue._do_install()
assert any(cmd[:3] == ["/bin/systemctl", "enable", "openhop-plugin-manager"] for cmd in calls)
assert any(cmd[:3] == ["/bin/systemctl", "restart", "openhop-plugin-manager"] for cmd in calls)
assert st.state == "complete"
def test_do_install_wrapper_success_container_path(isolated_state, monkeypatch):
st = isolated_state
st.channel = "main"
@@ -523,6 +570,12 @@ def _capturing_popen(monkeypatch, calls):
monkeypatch.setattr(ue.subprocess, "Popen", lambda cmd, **kwargs: _Proc(cmd, kwargs.get("env")))
def fake_run(cmd, **kwargs):
calls.append({"cmd": cmd, "env": kwargs.get("env", {}), "run": True})
return SimpleNamespace(returncode=0, stdout="", stderr="")
monkeypatch.setattr(ue.subprocess, "run", fake_run)
def test_do_install_root_does_not_force_a_predicted_version(isolated_state, monkeypatch):
st = isolated_state