""" `decnet init` — one-shot master-host bootstrap. Idempotent: running it twice is a no-op on already-configured items. Takes a freshly ``pip install``'d DECNET and turns it into a ready-to- run master host: creates the ``decnet`` system user/group, installs the systemd units + polkit rule + tmpfiles.d entry, seeds the directory layout, drops a placeholder config, and starts the ``decnet.target`` grouping unit. Requires root. Uses ``subprocess.run`` (never ``shell=True``) for every privileged call so the full argv surface is auditable. """ from __future__ import annotations import grp import hashlib import os import pwd import shutil import subprocess # nosec B404 import sys from pathlib import Path from typing import Callable, List import typer import decnet as _decnet_pkg from .gating import _require_master_mode from .utils import console, log _CONFIG_PLACEHOLDER = """\ # /etc/decnet/config.ini — DECNET master-host config. # Placeholder; reserved for future structured settings. # Today, most knobs live in /opt/decnet/.env.local as env vars. [decnet] """ def _deploy_root() -> Path: """Resolve the on-disk ``deploy/`` directory of the installed package. Editable install (``pip install -e .``): sibling of the ``decnet`` package at repo root. Wheel installs aren't supported yet — the error message tells the operator to use an editable install. """ root = Path(_decnet_pkg.__file__).resolve().parent.parent / "deploy" if not (root / "decnet.target").is_file(): raise RuntimeError( f"cannot locate deploy/ directory (looked at {root}); " "are you on a wheel install that didn't bundle deploy/? " "use `pip install -e .` from a git checkout" ) return root def _sha256(path: Path) -> str: h = hashlib.sha256() h.update(path.read_bytes()) return h.hexdigest() def _run(argv: List[str], *, dry_run: bool) -> None: if dry_run: console.print(f" [dim]would run:[/] {' '.join(argv)}") return log.info("init: exec %s", argv) subprocess.run(argv, check=True) # nosec B603 def _step(label: str, action: Callable[[], str]) -> bool: """Run ``action``, print a checklist line. The callable returns the human-readable outcome verb: ``"ok"`` → ``[ OK ]