summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/cli/lifecycle.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/cli/lifecycle.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/cli/lifecycle.py135
1 files changed, 135 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/cli/lifecycle.py b/packages/meshbay-node/src/meshbay_node/cli/lifecycle.py
new file mode 100644
index 0000000..6341561
--- /dev/null
+++ b/packages/meshbay-node/src/meshbay_node/cli/lifecycle.py
@@ -0,0 +1,135 @@
+"""Starting, stopping and reloading the node: systemd here, the Startup
+launcher or the service task on Windows."""
+
+import sys
+
+from meshbay_node.cli.api import _daemon_api, _systemctl_user
+from meshbay_node.config import DEFAULT_CONFIG_PATH, load_config
+
+
+def reload(args) -> None:
+ if sys.platform == "win32":
+ # No systemd, no SIGHUP: the daemon exposes a hot reload on its
+ # own loopback API (the same one ops.reload_config drives).
+ cfg = load_config(args.config or DEFAULT_CONFIG_PATH)
+ _daemon_api(cfg, "/api/reload", method="POST")
+ print("sent reload to the running node")
+ return
+ _systemctl_user(
+ "reload", "meshbay-node",
+ not_running_hint="Node is not running as a systemd unit — start it "
+ "with: systemctl --user start meshbay-node",
+ success="sent reload to meshbay-node",
+ watch="watch the result: journalctl --user -u meshbay-node -f")
+ return
+
+
+def restart_daemon(args) -> None:
+ if sys.platform == "win32":
+ from meshbay_node.platform import (
+ autostart_end,
+ autostart_run,
+ service_end,
+ service_run,
+ service_status,
+ )
+ if service_status()["installed"]:
+ service_end()
+ service_run()
+ print("restarted the node (service task)")
+ return
+ autostart_end() # kill whatever is running now
+ try:
+ autostart_run()
+ except RuntimeError as e:
+ print(f"Could not restart: {e}. Stop the daemon (Ctrl+C) and "
+ "relaunch it from where meshbay-node is on PATH.")
+ sys.exit(1)
+ print("restarted the node")
+ return
+ _systemctl_user(
+ "restart", "meshbay-node",
+ not_running_hint="meshbay-node is not installed as a systemd unit — "
+ "see packaging/systemd/",
+ success="meshbay-node restarted via systemd",
+ watch="check status: systemctl --user status meshbay-node\n"
+ "watch logs: journalctl --user -u meshbay-node -f")
+ return
+
+
+def autostart(args) -> None:
+ from meshbay_node import platform as _plat
+ if sys.platform != "win32":
+ print("autostart is Windows-only — elsewhere use "
+ "'systemctl --user enable --now meshbay-node'.")
+ sys.exit(1)
+ sub = args.subcommand or "status"
+ if sub == "install":
+ _plat.autostart_install()
+ print("Installed the Startup launcher — meshbay-node starts at "
+ "each sign-in (no window, no admin).")
+ print("Start it now with: meshbay-node autostart start")
+ elif sub == "remove":
+ _plat.autostart_remove()
+ print("Removed the Startup launcher.")
+ elif sub == "start":
+ try:
+ _plat.autostart_run()
+ except RuntimeError as e:
+ print(f"Could not start: {e}")
+ sys.exit(1)
+ print("started")
+ elif sub == "stop":
+ _plat.autostart_end()
+ print("stopped")
+ elif sub == "status":
+ st = _plat.autostart_status()
+ if st["installed"]:
+ print("autostart installed — runs meshbay-node at sign-in")
+ else:
+ print("autostart not installed — meshbay-node autostart install")
+ else:
+ print("autostart: install | remove | start | stop | status")
+ sys.exit(1)
+ return
+
+
+def service(args) -> None:
+ from meshbay_node import platform as _plat
+ if sys.platform != "win32":
+ print("service mode is Windows-only — elsewhere use "
+ "'systemctl --user enable --now meshbay-node'.")
+ sys.exit(1)
+ sub = args.subcommand or "status"
+ if sub == "install":
+ try:
+ _plat.service_install()
+ except RuntimeError as e:
+ print(f"Could not install: {e}")
+ if "denied" in str(e).lower():
+ print("Run this from an elevated (Administrator) prompt.")
+ sys.exit(1)
+ print(f"Registered the {_plat.TASK_NAME!r} scheduled task — it starts "
+ "meshbay-node at boot, as this user, whether or not you have "
+ "signed in yet (no password stored).")
+ print("Start it now with: meshbay-node service start")
+ elif sub == "remove":
+ _plat.service_remove()
+ print(f"Removed the {_plat.TASK_NAME!r} scheduled task.")
+ elif sub == "start":
+ _plat.service_run()
+ print("started")
+ elif sub == "stop":
+ _plat.service_end()
+ print("stopped")
+ elif sub == "status":
+ st = _plat.service_status()
+ if st["installed"]:
+ print(f"service installed — {st['state'] or 'unknown state'}")
+ else:
+ print("service not installed — meshbay-node service install "
+ "(needs an elevated prompt)")
+ else:
+ print("service: install | remove | start | stop | status")
+ sys.exit(1)
+ return