From a7eb25c7a4634418325256a8b368591e5b86ebeb Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Tue, 21 Apr 2026 01:24:35 +0100 Subject: feat(etc-restore): reset live /etc/ to pristine without repo round-trip Sibling to etc-reset but operates directly on /etc (via doas tee) and never touches the repo. Use when a live file has drifted from pristine but you don't want to track it: just etc-restore /etc/systemd/resolved.conf Previously this required a 2-step dance (etc-add + etc-untrack). --- .github/copilot-instructions.md | 2 +- justfile | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index a72ec26..a91bc99 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -21,7 +21,7 @@ The repo root is a chezmoi source directory. Files targeting `$HOME` use chezmoi - `bootstrap.sh` at the repo root is a POSIX shell script that takes a fresh minimal Arch install (only `base`) to a fully deployed state. It installs prerequisites, enables `%wheel` sudoers, bootstraps `paru-bin` from the AUR, clones the repo, runs `just init`, and optionally invokes `create-efi`. Designed to be curlable: `curl -fsSL .../bootstrap.sh | sh`. - `.chezmoiignore` excludes non-home files (`etc/`, `meta/`, `systemd-units/`, `firefox/`, docs) from deployment to `$HOME`. - `.githooks/` contains git hooks (notably `post-commit` which runs `chezmoi apply`). Activated by `just init`. -- `justfile` provides recipes: `init` (first-time setup), `sync` (apply + fix), `apply`, `readd`, `fix`, `status`, `pkg-drift`, `dotfile-drift`, `undeclared`, `diff`, `merge`, `groups`, `install`, `install-all`, `add`, `remove`, `services`, `services-enable`, `services-drift`, `etc`, `etc-diff`, `etc-upstream-diff`, `etc-add`, `etc-readd`, `etc-rm`, `etc-reset`, `etc-untrack`. Run `just` or `just --list` to see them. +- `justfile` provides recipes: `init` (first-time setup), `sync` (apply + fix), `apply`, `readd`, `fix`, `status`, `pkg-drift`, `dotfile-drift`, `undeclared`, `diff`, `merge`, `groups`, `install`, `install-all`, `add`, `remove`, `services`, `services-enable`, `services-drift`, `etc`, `etc-diff`, `etc-upstream-diff`, `etc-add`, `etc-readd`, `etc-rm`, `etc-reset`, `etc-untrack`, `etc-restore`. Run `just` or `just --list` to see them. ## Window manager diff --git a/justfile b/justfile index bbf2eec..f8205ff 100644 --- a/justfile +++ b/justfile @@ -448,6 +448,41 @@ etc-untrack +paths: just etc-reset {{ paths }} just etc-rm {{ paths }} +# Restore live /etc/ to pristine pacman contents (bypasses the repo) +etc-restore +paths: + #!/usr/bin/env bash + set -eo pipefail + for raw in {{ paths }}; do + case "$raw" in + *..*|*/./*|./*|../*) echo "error: unsafe path: $raw" >&2; exit 1 ;; + esac + p=${raw#/}; p=${p#etc/} + live=/etc/$p + [ -e "$live" ] || { echo "error: $live does not exist" >&2; exit 1; } + pkg=$(pacman -Qoq "$live" 2>/dev/null) \ + || { echo "error: $live has no owning package; nothing to restore to" >&2; exit 1; } + ver=$(pacman -Q "$pkg" | awk '{print $2}') + arch=$(pacman -Qi "$pkg" | awk -F': *' '/^Architecture/{print $2; exit}') + cache="" + for ext in zst xz; do + c="/var/cache/pacman/pkg/${pkg}-${ver}-${arch}.pkg.tar.${ext}" + [ -f "$c" ] && { cache="$c"; break; } + done + if [ -z "$cache" ]; then + echo " fetching $pkg from mirror..." >&2 + doas pacman -Sw --noconfirm "$pkg" >/dev/null || true + for ext in zst xz; do + c="/var/cache/pacman/pkg/${pkg}-${ver}-${arch}.pkg.tar.${ext}" + [ -f "$c" ] && { cache="$c"; break; } + done + fi + [ -n "$cache" ] || { echo "error: no cache for ${pkg}-${ver}; mirror may have moved past installed version" >&2; exit 1; } + bsdtar -tf "$cache" "${live#/}" >/dev/null 2>&1 \ + || { echo "error: $live not present in $pkg archive" >&2; exit 1; } + bsdtar -xOf "$cache" "${live#/}" | doas tee "$live" >/dev/null + echo "restored (from $pkg): $live" + done + # ═══════════════════════════════════════════════════════════════════ # Package management # ═══════════════════════════════════════════════════════════════════ -- cgit v1.2.3-70-g09d2