fix(init): gate userdel/groupdel on --purge to avoid nuking the operator

Every plain `decnet deinit` ran userdel + groupdel unconditionally. In
dev the operator may pass `--user $USER --group $USER` to avoid file
ownership churn against a source checkout — at which point deinit
would cheerfully delete their own login account.

Move user/group removal behind --purge, matching the existing
behaviour for /var/lib/decnet + /var/log/decnet. Help text updated:
--purge now clearly advertises that it also wipes the service
user/group, with an explicit warning to only run it when `decnet init`
created the account in the first place.

Test updated: plain --deinit must NOT invoke userdel/groupdel;
--deinit --purge must.
This commit is contained in:
2026-04-24 00:38:51 -04:00
parent 38832d87d5
commit edc8297af3
2 changed files with 36 additions and 16 deletions

View File

@@ -387,11 +387,13 @@ def test_deinit_removes_units_polkit_tmpfiles_and_preserves_data(
assert (prefix / "var/lib/decnet").exists()
assert (prefix / "var/log/decnet/events.jsonl").read_text() == "{}\n"
# systemctl disable + daemon-reload + userdel + groupdel were invoked.
# systemctl disable + daemon-reload invoked.
assert ["systemctl", "disable", "--now", "decnet.target"] in subprocess_calls
assert ["systemctl", "daemon-reload"] in subprocess_calls
assert ["userdel", "decnet"] in subprocess_calls
assert ["groupdel", "decnet"] in subprocess_calls
# User / group are PRESERVED without --purge — an operator who
# passed --user $USER during dev must not lose their login account.
assert ["userdel", "decnet"] not in subprocess_calls
assert ["groupdel", "decnet"] not in subprocess_calls
def test_deinit_purge_wipes_data_dirs(
@@ -406,6 +408,9 @@ def test_deinit_purge_wipes_data_dirs(
assert result.exit_code == 0, result.output
assert not (prefix / "var/lib/decnet").exists()
assert not (prefix / "var/log/decnet").exists()
# --purge also removes the service user/group.
assert ["userdel", "decnet"] in subprocess_calls
assert ["groupdel", "decnet"] in subprocess_calls
def test_deinit_is_idempotent_on_clean_host(