docs: add design spec for ansible-arch/machine reconciliation
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# Ansible-arch ↔ machine reconciliation
|
||||
|
||||
Date: 2026-07-28
|
||||
Status: Approved
|
||||
|
||||
## Context
|
||||
|
||||
The `ansible-arch` repo had an in-flight uncommitted diff (hyprland.conf tweaks,
|
||||
new packages across several roles, new dotfiles stow packages) plus untracked
|
||||
files. Separately, `ansible.cfg` sets `become = True` globally, which caused
|
||||
the dotfiles role's `stow` task to run as root — the `hypr`, `zellij`, and
|
||||
`starship.toml` symlinks in `~/.config` ended up owned by `root` instead of
|
||||
the invoking user. A full audit of installed packages (`pacman -Qeq`) against
|
||||
what the roles declare also turned up drift in both directions.
|
||||
|
||||
Resolution order: prefer encoding drift into ansible roles and re-running the
|
||||
playbook over hand-editing the machine directly. Direct machine changes are
|
||||
only for things ansible can't (or already will, as a side effect) fix.
|
||||
|
||||
## Scope
|
||||
|
||||
One reconciliation pass, no new tooling:
|
||||
|
||||
1. Fix the `become` default so privilege escalation is opt-in per task, not
|
||||
global.
|
||||
2. Commit the existing in-flight diff and untracked files as-is — they're
|
||||
already the intended state.
|
||||
3. Fold audited package/service drift into the appropriate roles.
|
||||
|
||||
No repeatable drift-check tool is being added (explicitly out of scope —
|
||||
one-time fix, matches existing YAGNI preference).
|
||||
|
||||
## 1. Privilege escalation fix
|
||||
|
||||
- Remove `become = True` from `ansible.cfg` `[privilege_escalation]` (default
|
||||
becomes `False`).
|
||||
- Add explicit `become: true` to every task that needs root:
|
||||
- all `pacman:` module tasks (every role)
|
||||
- `systemd:` service-enable tasks (hyprland role)
|
||||
- `user:` group-membership task (hyprland role, docker group)
|
||||
- `chsh` / `getent` tasks and the sudoers-setup step (common role)
|
||||
- No change needed for `kewlfft.aur.aur` tasks or the `paru` makepkg shell
|
||||
task — they never had explicit `become` set, so they now correctly inherit
|
||||
`become: false`. (They were arguably broken before: makepkg refuses to run
|
||||
as root. This went unnoticed because the packages were already installed,
|
||||
so the tasks were no-ops.)
|
||||
- No change needed for dotfiles-role stow tasks or any `blockinfile`/`.zshrc`/
|
||||
`.profile` tasks — same reasoning, they now correctly run unprivileged.
|
||||
- Net effect on `~/.config` symlink ownership: no manual `chown`/`rm` step is
|
||||
needed. The dotfiles role's "Remove existing config files before stowing"
|
||||
task unconditionally removes the `hypr`/`zellij`/`starship.toml`/`kanshi`
|
||||
targets before every `stow` run, so simply re-running `site.yml` after this
|
||||
fix deletes the root-owned symlinks and recreates them owned by the
|
||||
invoking user.
|
||||
|
||||
## 2. Formalize the in-flight diff
|
||||
|
||||
Commit as-is:
|
||||
- `dotfiles/hypr/.config/hypr/hyprland.conf` (keyboard layout, mouse/scroll
|
||||
behavior, hyprlock keybind, monitor scaling, dwindle pseudotile changes)
|
||||
- `roles/ai`, `roles/common`, `roles/devops`, `roles/dotfiles`,
|
||||
`roles/hyprland`, `roles/multimedia` package/task additions already in the
|
||||
working tree
|
||||
|
||||
`git add` untracked files that are already part of an existing stow package:
|
||||
- `dotfiles/hypr/.config/hypr/hyprlock.conf`
|
||||
- `dotfiles/hypr/.config/hypr/monitors.sh`
|
||||
- `dotfiles/kanshi/`
|
||||
- `dotfiles/starship/`
|
||||
|
||||
## 3. Package/service audit — role placement
|
||||
|
||||
Cross-referenced `pacman -Qeq` (explicitly installed) against every
|
||||
`roles/*/tasks/*.yml` package list.
|
||||
|
||||
**Add to `ctf` role:**
|
||||
- `gitleaks`
|
||||
- `nuclei-bin` (AUR)
|
||||
- `picocom`
|
||||
- `python-pyserial`
|
||||
|
||||
**Add to `common` role:**
|
||||
- `nano`
|
||||
- `vim`
|
||||
- `sshpass`
|
||||
- `smartmontools`
|
||||
- `cargo-audit`
|
||||
|
||||
**Explicitly out of scope** (base install / firmware / bootloader —
|
||||
provisioning concerns this repo doesn't own):
|
||||
`base`, `linux`, `linux-firmware`, `efibootmgr`, `lvm2`, `sudo`,
|
||||
`btrfs-progs`, `amd-ucode`, `intel-media-driver`, `libva-intel-driver`,
|
||||
`vulkan-intel`, `sof-firmware`, `xorg-server`, `xorg-xinit`,
|
||||
`zram-generator`, `snapper`.
|
||||
|
||||
**Flagged, no role change:** `dunst` — installed but superseded by `swaync`
|
||||
(already declared in the hyprland role). Left as-is; not added to any role,
|
||||
not uninstalled.
|
||||
|
||||
**No action needed** (false positives from the audit):
|
||||
`paru`, `paru-debug` (installed by the common role's own bootstrap task, not
|
||||
a plain pacman list item), `ttf-joypixels` (already declared, just via a
|
||||
single-value `name:` key the audit grep didn't match).
|
||||
|
||||
**Minor cleanup:** remove the duplicate `docker` package entry from the
|
||||
`cs_student` role — `devops` already declares it.
|
||||
|
||||
## Verification
|
||||
|
||||
- `ansible-playbook site.yml --check --diff` runs clean (no unexpected
|
||||
changes) after the `become` fix and role edits.
|
||||
- `ansible-playbook site.yml` run confirms `~/.config/hypr`,
|
||||
`~/.config/zellij`, `~/.config/starship.toml`, `~/.config/kanshi` are
|
||||
owned by the invoking user, not root.
|
||||
- `git status` clean after committing.
|
||||
Reference in New Issue
Block a user