summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/cli/lifecycle.py
blob: 63415618bdfe484606f25325242cc23da26f6c02 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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