feat(config): promote /etc/decnet/decnet.ini to real config with domain sections
The config file `decnet init` dropped at /etc/decnet/config.ini was a stub with a single [decnet] header saying 'reserved for future structured settings.' Admins who wanted to tune DECNET_API_HOST, DECNET_DB_URL, DECNET_BATCH_SIZE, etc. had to hunt env.py for the exact variable name and drop it in .env.local. Changes: - decnet/config_ini.py — adds a _DOMAIN_MAP translation table covering [api], [web], [database], [bus], [swarm], [logging], [ingester], [tracing]. Loads regardless of mode; unknown keys inside a known section log a WARNING (operator typos shouldn't be silent). Explicit key map (not auto kebab-to-snake) so [web] admin-user lands in DECNET_ADMIN_USER without silently renaming the env-var contract consumers import from decnet.env. - decnet/cli/init.py — renames the placeholder target config.ini → decnet.ini (unifies with the name already used by load_ini_config and the enroll bundle's _render_decnet_ini). Placeholder body now shows every domain section as a commented example so admins learn the shape by reading. Deinit removes both decnet.ini and the legacy config.ini so upgrading hosts leave no orphan file. Precedence is unchanged: real env > INI > built-in default in env.py. os.environ.setdefault means systemd EnvironmentFile= and one-off DECNET_FOO=bar decnet ... invocations always win. Secrets explicitly NOT moved to the INI: - DECNET_JWT_SECRET - DECNET_ADMIN_PASSWORD - DECNET_DB_PASSWORD They stay in .env.local / EnvironmentFile= — never in a group-readable INI, never in a diff, never on the dashboard. Dev/profiling flags (DECNET_DEVELOPER, DECNET_EMBED_*, DECNET_PROFILE_*) also stay env-only per maintainer direction — dev knobs shouldn't be one 'I'll flip this for tonight' away. Tests: +5 in test_config_ini.py (domain sections load regardless of mode, env beats INI for domain keys, unknown key warns, absent section is no-op, role section beats domain section via setdefault precedence). +1 in test_init.py (placeholder writes decnet.ini with every section header present as commented guidance). 31 tests pass across the two files (was 26).
This commit is contained in:
@@ -166,6 +166,32 @@ def test_unit_files_are_installed_then_idempotent(
|
||||
assert "unit files up to date" in r2.output
|
||||
|
||||
|
||||
def test_init_writes_decnet_ini_not_config_ini(
|
||||
monkeypatch: Any, tmp_path: Path, subprocess_calls: List[List[str]],
|
||||
no_missing_tools: None, missing_user_and_group: None,
|
||||
) -> None:
|
||||
"""Placeholder target is /etc/decnet/decnet.ini (new name) — matches
|
||||
what decnet.config_ini.load_ini_config() actually reads. Guards
|
||||
against regressing to the old `config.ini` name."""
|
||||
_seed_deploy(monkeypatch, tmp_path)
|
||||
prefix = tmp_path / "root"
|
||||
r = runner.invoke(app, ["init", "--no-start", "--prefix", str(prefix)])
|
||||
assert r.exit_code == 0, r.output
|
||||
|
||||
ini = prefix / "etc/decnet/decnet.ini"
|
||||
legacy = prefix / "etc/decnet/config.ini"
|
||||
assert ini.is_file(), "decnet.ini should be written"
|
||||
assert not legacy.exists(), "legacy config.ini must not be written"
|
||||
|
||||
body = ini.read_text()
|
||||
# Admin-facing sections are documented as commented examples so
|
||||
# the placeholder teaches the file shape.
|
||||
for header in ("[decnet]", "[api]", "[web]", "[database]",
|
||||
"[bus]", "[swarm]", "[logging]", "[ingester]",
|
||||
"[tracing]", "[agent]"):
|
||||
assert header in body, f"placeholder missing {header} example"
|
||||
|
||||
|
||||
def test_install_dir_renders_into_service_units(
|
||||
monkeypatch: Any, tmp_path: Path, subprocess_calls: List[List[str]],
|
||||
no_missing_tools: None, missing_user_and_group: None,
|
||||
@@ -328,6 +354,8 @@ def _seed_installed_state(prefix: Path) -> None:
|
||||
(tmpfiles / "decnet.conf").write_text("d /run/decnet\n")
|
||||
etc_decnet = prefix / "etc/decnet"
|
||||
etc_decnet.mkdir(parents=True)
|
||||
(etc_decnet / "decnet.ini").write_text("[decnet]\n")
|
||||
# Also seed the legacy config.ini so we cover the legacy-cleanup path.
|
||||
(etc_decnet / "config.ini").write_text("[decnet]\n")
|
||||
(prefix / "opt/decnet").mkdir(parents=True)
|
||||
(prefix / "run/decnet").mkdir(parents=True)
|
||||
|
||||
Reference in New Issue
Block a user