aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-13 13:43:21 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-13 13:43:21 +0100
commit3b2beec0ca95ce863a6cd4f7bf7be24247f96acd (patch)
treea30d5abf4b4c5e62b595422a237e6ba63f577f49
parent3840003c26c4d3183cb842787e9f381f7265ef0c (diff)
downloaddotfiles-3b2beec0ca95ce863a6cd4f7bf7be24247f96acd.tar.gz
dotfiles-3b2beec0ca95ce863a6cd4f7bf7be24247f96acd.tar.bz2
dotfiles-3b2beec0ca95ce863a6cd4f7bf7be24247f96acd.zip
refactor(etc): narrow etc-status to tracked-file drift
The old etc-status scanned all of /etc (pacman -Qkk for modified backup configs, then 'find /etc | xargs pacman -Qo' for unowned files), producing a discovery report of things we might want to track. That was useful when seeding the repo but is slow and misaligned with dotfiles-status, which only reports drift on files chezmoi already manages. Rewrite etc-status to mirror that model: iterate etc/, render .tmpl sources, and cmp against the live /etc file. Report 'modified' or 'missing' per tracked path. Runs in under a second and matches the semantics of 'just status'. Drop the now-unused etc/.ignore and update README.
-rw-r--r--README.md2
-rw-r--r--etc/.ignore57
-rw-r--r--justfile48
3 files changed, 18 insertions, 89 deletions
diff --git a/README.md b/README.md
index 1e2ce98..c390db3 100644
--- a/README.md
+++ b/README.md
@@ -118,7 +118,7 @@ Four sources of drift are tracked independently and combined by `just status`:
- **Dotfiles** (`just dotfiles-status`): live `$HOME` files differ from the repo. Resolve with `just apply` (repo → home), `just re-add PATH` (home → repo), `just diff PATH`, or `just merge PATH`.
- **Packages** (`just pkg-status`): installed but undeclared, or declared but missing. Resolve by adding to a `meta/` group (`just add GROUP PKG`) or uninstalling.
-- **/etc** (`just etc-status` / `just etc-diff`): modified package configs or user-created files in `/etc` that aren't in the repo. Resolve with `just etc-re-add PATH` (track), `just etc-restore PATH` (revert to package default), or `just etc-untrack PATH`.
+- **/etc** (`just etc-status` / `just etc-diff`): repo-tracked files in `etc/` that differ from or are missing on the live `/etc`. Resolve with `just etc-apply` (repo → live), `just etc-re-add PATH` (live → repo), or `just etc-untrack PATH`.
- **Units** (`just unit-status`): enabled units not in any `systemd-units/{system,user}/*.txt`, or declared units that aren't enabled (checked for both scopes).
## Git hooks
diff --git a/etc/.ignore b/etc/.ignore
deleted file mode 100644
index 31f9ec0..0000000
--- a/etc/.ignore
+++ /dev/null
@@ -1,57 +0,0 @@
-# Paths excluded from `just etc-drift` output.
-# Shell-glob patterns (case $path in $pat) work here: *, ?, [].
-
-# Per-host state / auto-generated
-/etc/machine-id
-/etc/adjtime
-/etc/.updated
-/etc/.pwd.lock
-/etc/mtab
-/etc/ld.so.cache
-/etc/hostname
-/etc/xml/catalog
-
-# Per-host identity / secrets
-/etc/ssh/ssh_host_*
-/etc/passwd
-/etc/passwd-
-/etc/group
-/etc/group-
-/etc/shadow
-/etc/shadow-
-/etc/gshadow
-/etc/gshadow-
-/etc/shells
-
-# pacman leftovers from removed packages
-*.pacsave
-*.pacsave.*
-*.pacnew
-*.pacorig
-
-# Regenerated by tools (not worth versioning)
-/etc/resolv.conf
-/etc/ssl/certs/*
-/etc/ca-certificates/extracted/*
-/etc/pacman.d/gnupg/*
-/etc/pacman.d/mirrorlist
-
-# Host-specific (UUIDs, partition layout)
-/etc/fstab
-
-# Managed by useradd (podman uses them)
-/etc/subuid
-/etc/subgid
-/etc/subuid-
-/etc/subgid-
-
-# sbctl signed-boot state (keys live here; never commit)
-/etc/secureboot/*
-
-# WireGuard peer configs — .netdev has PrivateKey=, .network has public IPs (PII).
-# Keep local only. To version: template secrets via `pass` at chezmoi apply time.
-/etc/systemd/network/99-hodor.*
-/etc/systemd/network/99-mandibles.*
-
-# Contains hardcoded username (autologin); host-specific
-/etc/systemd/system/getty@tty1.service.d/override.conf
diff --git a/justfile b/justfile
index 32d831e..0a74263 100644
--- a/justfile
+++ b/justfile
@@ -566,42 +566,28 @@ unit-forget group +units:
# /etc domain
# ═══════════════════════════════════════════════════════════════════
-# Show /etc drift: package configs modified from defaults, plus user-created files
+# Show /etc drift: repo-tracked files that differ from or are missing on the host
etc-status:
#!/usr/bin/env bash
set -eo pipefail
tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
-
- find etc -type f ! -name .ignore 2>/dev/null \
- | sed 's|^etc/|/etc/|; s|\.tmpl$||' | sort -u > "$tmp/managed"
-
- patterns=()
- if [ -f etc/.ignore ]; then
- while IFS= read -r line; do
- [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
- patterns+=("$line")
- done < etc/.ignore
- fi
-
- keep() {
- local path=$1
- grep -qxF "$path" "$tmp/managed" && return 1
- for pat in ${patterns[@]+"${patterns[@]}"}; do
- [[ "$path" == $pat ]] && return 1
- done
- return 0
- }
-
echo "=== /etc drift ==="
- echo "--- modified package configs ---"
- { pacman -Qkk 2>/dev/null | grep -oP '^backup file:\s+[^:]+:\s+\K/etc/\S+' || true; } | sort -u \
- | while IFS= read -r p; do keep "$p" && echo " modified: $p"; :; done
-
- echo "--- user-created (no owning package) ---"
- { find /etc -xdev -type f -print0 2>/dev/null \
- | xargs -0 pacman -Qo 2>&1 >/dev/null \
- | sed -n 's/^error: No package owns //p' || true; } | sort -u \
- | while IFS= read -r p; do keep "$p" && echo " unowned: $p"; :; done
+ while IFS= read -r repo; do
+ live=/etc/${repo#etc/}; live=${live%.tmpl}
+ if [ "${repo%.tmpl}" != "$repo" ]; then
+ src=$tmp/rendered
+ chezmoi execute-template <"$repo" >"$src"
+ else
+ src=$repo
+ fi
+ if [ -r "$live" ]; then
+ cmp -s "$src" "$live" || echo " modified: $live"
+ elif doas test -f "$live" 2>/dev/null; then
+ doas cat "$live" | cmp -s "$src" - || echo " modified: $live"
+ else
+ echo " missing: $live"
+ fi
+ done < <(find etc -type f ! -name .ignore | sort)
# Diff repo-managed etc/<path> against live /etc/<path> (all managed files if no args)
etc-diff *paths: