feat(config): add swarmctl-host to INI, env, CLI; drop hardcoded bind from systemd unit
[swarm] swarmctl-host → DECNET_SWARMCTL_HOST so operators set the bind address once in decnet.ini; `decnet swarmctl` and the systemd unit both resolve it via envvar — no --host/--port pinned on ExecStart.
This commit is contained in:
@@ -74,6 +74,7 @@ _CONFIG_PLACEHOLDER = """\
|
||||
# master-host = 10.0.0.1
|
||||
# syslog-port = 6514
|
||||
# swarmctl-port = 8770
|
||||
# swarmctl-host = 127.0.0.1
|
||||
|
||||
# [logging]
|
||||
# system-log = /var/log/decnet/decnet.system.log
|
||||
|
||||
@@ -16,8 +16,16 @@ from .utils import console, log
|
||||
def register(app: typer.Typer) -> None:
|
||||
@app.command()
|
||||
def swarmctl(
|
||||
port: int = typer.Option(8770, "--port", help="Port for the swarm controller"),
|
||||
host: str = typer.Option("127.0.0.1", "--host", help="Bind address for the swarm controller"),
|
||||
port: int = typer.Option(
|
||||
8770, "--port",
|
||||
envvar="DECNET_SWARMCTL_PORT",
|
||||
help="Port for the swarm controller. Defaults to [swarm] swarmctl-port from /etc/decnet/decnet.ini, else 8770.",
|
||||
),
|
||||
host: str = typer.Option(
|
||||
"127.0.0.1", "--host",
|
||||
envvar="DECNET_SWARMCTL_HOST",
|
||||
help="Bind address for the swarm controller. Defaults to [swarm] swarmctl-host from /etc/decnet/decnet.ini, else 127.0.0.1.",
|
||||
),
|
||||
daemon: bool = typer.Option(False, "--daemon", "-d", help="Detach to background as a daemon process"),
|
||||
no_listener: bool = typer.Option(False, "--no-listener", help="Do not auto-spawn the syslog-TLS listener alongside swarmctl"),
|
||||
tls: bool = typer.Option(False, "--tls", help="Serve over HTTPS with mTLS (required for cross-host worker heartbeats)"),
|
||||
|
||||
@@ -39,6 +39,7 @@ Shape::
|
||||
master-host = 10.0.0.1 # required on agents
|
||||
syslog-port = 6514
|
||||
swarmctl-port = 8770
|
||||
swarmctl-host = 127.0.0.1 # bind address for `decnet swarmctl`
|
||||
|
||||
[logging]
|
||||
system-log = /var/log/decnet/decnet.system.log
|
||||
@@ -120,6 +121,7 @@ _DOMAIN_MAP: dict[str, dict[str, str]] = {
|
||||
"master-host": "DECNET_SWARM_MASTER_HOST",
|
||||
"syslog-port": "DECNET_SWARM_SYSLOG_PORT",
|
||||
"swarmctl-port": "DECNET_SWARMCTL_PORT",
|
||||
"swarmctl-host": "DECNET_SWARMCTL_HOST",
|
||||
},
|
||||
"logging": {
|
||||
"system-log": "DECNET_SYSTEM_LOGS",
|
||||
|
||||
@@ -114,6 +114,11 @@ DECNET_SWARM_MASTER_HOST: str | None = os.environ.get("DECNET_SWARM_MASTER_HOST"
|
||||
DECNET_HOST_UUID: str | None = os.environ.get("DECNET_HOST_UUID")
|
||||
DECNET_MASTER_HOST: str | None = os.environ.get("DECNET_MASTER_HOST")
|
||||
DECNET_SWARMCTL_PORT: int = _port("DECNET_SWARMCTL_PORT", 8770)
|
||||
# Bind address for the master-side swarm controller. Loopback by default —
|
||||
# operators flip to 0.0.0.0 (or a specific NIC) on production masters where
|
||||
# workers heartbeat in over mTLS from other hosts. Seeded by [swarm]
|
||||
# swarmctl-host in /etc/decnet/decnet.ini.
|
||||
DECNET_SWARMCTL_HOST: str = os.environ.get("DECNET_SWARMCTL_HOST", "127.0.0.1")
|
||||
|
||||
# Ingester batching: how many log rows to accumulate per commit, and the
|
||||
# max wait (ms) before flushing a partial batch. Larger batches reduce
|
||||
|
||||
@@ -10,10 +10,12 @@ User={{ user }}
|
||||
Group={{ group }}
|
||||
WorkingDirectory={{ install_dir }}
|
||||
EnvironmentFile=-{{ install_dir }}/.env.local
|
||||
# Default bind is loopback — the controller is a master-local orchestrator
|
||||
# reached by the CLI and the web dashboard, not by workers.
|
||||
# Bind/port resolved from /etc/decnet/decnet.ini ([swarm] swarmctl-host /
|
||||
# swarmctl-port) — falls back to 127.0.0.1:8770 when the keys are absent.
|
||||
# Pass --host/--port on the ExecStart line only if you want to pin them
|
||||
# regardless of what the INI says.
|
||||
Environment=DECNET_SYSTEM_LOGS=/var/log/decnet/decnet.swarmctl.log
|
||||
ExecStart={{ venv_dir }}/bin/decnet swarmctl --host 127.0.0.1 --port 8770
|
||||
ExecStart={{ venv_dir }}/bin/decnet swarmctl
|
||||
StandardOutput=append:/var/log/decnet/decnet.swarmctl.log
|
||||
StandardError=append:/var/log/decnet/decnet.swarmctl.log
|
||||
|
||||
|
||||
@@ -302,3 +302,18 @@ swarmctl-port = 9999
|
||||
load_ini_config(ini)
|
||||
# [master] loaded first, [swarm] lost via setdefault
|
||||
assert os.environ["DECNET_SWARMCTL_PORT"] == "9001"
|
||||
|
||||
|
||||
def test_swarm_section_seeds_swarmctl_host(monkeypatch, tmp_path):
|
||||
"""[swarm] swarmctl-host → DECNET_SWARMCTL_HOST so the systemd unit and
|
||||
`decnet swarmctl` CLI both pick up the operator's bind choice from the
|
||||
INI without anyone passing --host on ExecStart."""
|
||||
_scrub(monkeypatch, "DECNET_MODE", "DECNET_SWARMCTL_HOST", "DECNET_SWARMCTL_PORT")
|
||||
ini = _write_ini(tmp_path, """
|
||||
[swarm]
|
||||
swarmctl-host = 0.0.0.0
|
||||
swarmctl-port = 9000
|
||||
""")
|
||||
load_ini_config(ini)
|
||||
assert os.environ["DECNET_SWARMCTL_HOST"] == "0.0.0.0"
|
||||
assert os.environ["DECNET_SWARMCTL_PORT"] == "9000"
|
||||
|
||||
Reference in New Issue
Block a user