Replace the in-flight updatedb and read PRUNEPATHS out of any quoting

The machines this targets are the ones with an updatedb already grinding
through every snapshot, and `systemctl start` on an active unit is a
no-op. updatedb reads /etc/updatedb.conf once at startup, so a run that
began before the rewrite keeps burning CPU on the old config until it
finishes. Restart the service instead: it's Type=oneshot and plocate
builds into a temp db, so nothing is lost by replacing the run.

Quotes are optional in updatedb.conf, so parse the existing paths out of
whatever quoting the file uses and write the setting back in one
canonical form. `PRUNEPATHS=/tmp` previously fell through to the append
branch and got a second PRUNEPATHS line, which drops /tmp from the
pruned set. Comparing whole paths rather than substrings also keeps a
config that already prunes something like /var/lib/machines/.snapshots
from being mistaken for one that prunes /.snapshots.

Prefer $OMARCHY_PATH over the packaged copy when locating the config
script, per docs/migrations.md, so the migration test exercises the
checked-out script rather than whatever release is installed. Skip when
neither exists: omarchy-migrate runs under set -e, so a missing script
would take down every migration queued behind it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-07-26 19:00:02 -07:00
co-authored by Claude Opus 5
parent d548c064ee
commit a6a13cf3e6
4 changed files with 54 additions and 15 deletions
+2 -1
View File
@@ -248,7 +248,8 @@ the legacy finalization marker from `~/.local/state/omarchy/` into `done/`.
finalization. It sources: finalization. It sources:
- `install/config/*.sh` — theme links, lockout limits, lockscreen PAM, - `install/config/*.sh` — theme links, lockout limits, lockscreen PAM,
powerprofilesctl shebang fix, docker setup, service enablement, firewall. powerprofilesctl shebang fix, docker setup, Snapper retention, locate
index tuning, service enablement, firewall.
- `install/hardware/all.sh` via `omarchy-setup-hardware` — vendor- and - `install/hardware/all.sh` via `omarchy-setup-hardware` — vendor- and
device-specific kernel modules, udev rules, microcode, wireless regdom, device-specific kernel modules, udev rules, microcode, wireless regdom,
ASUS / Framework / Intel / Apple / Lenovo quirks. ASUS / Framework / Intel / Apple / Lenovo quirks.
+7 -3
View File
@@ -14,9 +14,13 @@ fi
# Snapper snapshots are nested subvolumes reached by plain directory # Snapper snapshots are nested subvolumes reached by plain directory
# traversal, so without this updatedb indexes the system once per snapshot. # traversal, so without this updatedb indexes the system once per snapshot.
if ! grep -E '^PRUNEPATHS[[:space:]]*=' "$UPDATEDB_CONF_PATH" | grep -qF '/.snapshots'; then # The quotes are optional in updatedb.conf, so read the paths back out of
if grep -qE '^PRUNEPATHS[[:space:]]*=[[:space:]]*"' "$UPDATEDB_CONF_PATH"; then # whatever quoting the file uses and write the setting in one canonical form.
sed -i -E 's|^(PRUNEPATHS[[:space:]]*=[[:space:]]*")|\1/.snapshots |' "$UPDATEDB_CONF_PATH" pruned=$(sed -nE 's|^PRUNEPATHS[[:space:]]*=[[:space:]]*"?([^"]*)"?[[:space:]]*$|\1|p' "$UPDATEDB_CONF_PATH" | tail -n 1)
if [[ " $pruned " != *" /.snapshots "* ]]; then
if [[ -n $pruned ]]; then
sed -i -E "s|^PRUNEPATHS[[:space:]]*=.*|PRUNEPATHS = \"/.snapshots $pruned\"|" "$UPDATEDB_CONF_PATH"
else else
printf '%s\n' 'PRUNEPATHS = "/.snapshots"' >>"$UPDATEDB_CONF_PATH" printf '%s\n' 'PRUNEPATHS = "/.snapshots"' >>"$UPDATEDB_CONF_PATH"
fi fi
+8 -8
View File
@@ -1,11 +1,7 @@
echo "Configure locate to skip Btrfs snapshots and index Btrfs subvolumes" echo "Configure locate to skip Btrfs snapshots and index Btrfs subvolumes"
OMARCHY_PATH="${OMARCHY_PATH:-/usr/share/omarchy}" OMARCHY_PATH="${OMARCHY_PATH:-/usr/share/omarchy}"
locate_config_script=/usr/share/omarchy/install/config/locate.sh locate_config_script="$OMARCHY_PATH/install/config/locate.sh"
if [[ ! -f $locate_config_script ]]; then
locate_config_script="$OMARCHY_PATH/install/config/locate.sh"
fi
UPDATEDB_CONF_PATH="${OMARCHY_UPDATEDB_CONF_PATH:-/etc/updatedb.conf}" UPDATEDB_CONF_PATH="${OMARCHY_UPDATEDB_CONF_PATH:-/etc/updatedb.conf}"
as_root() { as_root() {
@@ -17,14 +13,18 @@ as_root() {
} }
[[ -f $UPDATEDB_CONF_PATH ]] || exit 0 [[ -f $UPDATEDB_CONF_PATH ]] || exit 0
[[ -f $locate_config_script ]] || exit 0
if grep -q '^PRUNE_BIND_MOUNTS = "no"' "$UPDATEDB_CONF_PATH" && if grep -q '^PRUNE_BIND_MOUNTS = "no"' "$UPDATEDB_CONF_PATH" &&
grep -E '^PRUNEPATHS' "$UPDATEDB_CONF_PATH" | grep -qF '/.snapshots'; then grep -E '^PRUNEPATHS' "$UPDATEDB_CONF_PATH" | grep -qE '(^|[[:space:]"])/\.snapshots([[:space:]"]|$)'; then
exit 0 exit 0
fi fi
as_root env OMARCHY_UPDATEDB_CONF_PATH="$UPDATEDB_CONF_PATH" bash -euo pipefail "$locate_config_script" as_root env OMARCHY_UPDATEDB_CONF_PATH="$UPDATEDB_CONF_PATH" bash -euo pipefail "$locate_config_script"
# Rebuild the index with the new exclusions; pruning /.snapshots turns # Rebuild the index with the new exclusions; pruning /.snapshots turns
# multi-hour runs on snapshot-heavy systems back into one-minute runs. # multi-hour runs on snapshot-heavy systems back into one-minute runs. Restart
as_root systemctl start --no-block plocate-updatedb.service >/dev/null 2>&1 || true # rather than start: the machines this targets are the ones with an updatedb
# already grinding through every snapshot, and a run that started before the
# rewrite keeps using the config it read at startup.
as_root systemctl restart --no-block plocate-updatedb.service >/dev/null 2>&1 || true
+37 -3
View File
@@ -36,7 +36,7 @@ OMARCHY_UPDATEDB_CONF_PATH="$test_tmp/missing.conf" bash -euo pipefail "$config_
pass "locate config tolerates a missing updatedb.conf" pass "locate config tolerates a missing updatedb.conf"
# A hand-edited updatedb.conf may drop the settings entirely, or write them # A hand-edited updatedb.conf may drop the settings entirely, or write them
# without the spaces around the "=" that the stock Arch file uses. # without the spaces around the "=" or the quotes that the stock Arch file uses.
conf="$test_tmp/sparse-updatedb.conf" conf="$test_tmp/sparse-updatedb.conf"
printf '%s\n' 'PRUNENAMES = ".git .hg .svn"' >"$conf" printf '%s\n' 'PRUNENAMES = ".git .hg .svn"' >"$conf"
@@ -52,10 +52,28 @@ printf '%s\n' 'PRUNE_BIND_MOUNTS="yes"' 'PRUNEPATHS="/tmp /var/tmp"' >"$conf"
OMARCHY_UPDATEDB_CONF_PATH="$conf" bash -euo pipefail "$config_script" >/dev/null OMARCHY_UPDATEDB_CONF_PATH="$conf" bash -euo pipefail "$config_script" >/dev/null
grep -qFx 'PRUNE_BIND_MOUNTS = "no"' "$conf" || fail "locate config rewrites an unspaced PRUNE_BIND_MOUNTS" grep -qFx 'PRUNE_BIND_MOUNTS = "no"' "$conf" || fail "locate config rewrites an unspaced PRUNE_BIND_MOUNTS"
grep -qFx 'PRUNEPATHS="/.snapshots /tmp /var/tmp"' "$conf" || fail "locate config prunes /.snapshots in an unspaced PRUNEPATHS" grep -qFx 'PRUNEPATHS = "/.snapshots /tmp /var/tmp"' "$conf" || fail "locate config prunes /.snapshots in an unspaced PRUNEPATHS"
[[ $(grep -c '^PRUNEPATHS' "$conf") -eq 1 ]] || fail "locate config keeps a single PRUNEPATHS setting" [[ $(grep -c '^PRUNEPATHS' "$conf") -eq 1 ]] || fail "locate config keeps a single PRUNEPATHS setting"
pass "locate config handles updatedb.conf written without spaces around =" pass "locate config handles updatedb.conf written without spaces around ="
conf="$test_tmp/unquoted-updatedb.conf"
printf '%s\n' 'PRUNEPATHS = /tmp' >"$conf"
OMARCHY_UPDATEDB_CONF_PATH="$conf" bash -euo pipefail "$config_script" >/dev/null
grep -qFx 'PRUNEPATHS = "/.snapshots /tmp"' "$conf" || fail "locate config keeps the paths an unquoted PRUNEPATHS already prunes"
[[ $(grep -c '^PRUNEPATHS' "$conf") -eq 1 ]] || fail "locate config replaces an unquoted PRUNEPATHS instead of adding a second one"
pass "locate config handles updatedb.conf written without quotes"
# A path that merely ends in /.snapshots is not the root snapshot directory.
conf="$test_tmp/nested-snapshots-updatedb.conf"
printf '%s\n' 'PRUNEPATHS = "/var/lib/machines/.snapshots"' >"$conf"
OMARCHY_UPDATEDB_CONF_PATH="$conf" bash -euo pipefail "$config_script" >/dev/null
grep -qFx 'PRUNEPATHS = "/.snapshots /var/lib/machines/.snapshots"' "$conf" || fail "locate config prunes /.snapshots alongside a path that ends in it"
pass "locate config tells /.snapshots apart from a path that ends in it"
locate_migration=$(grep -rl 'Configure locate to skip Btrfs snapshots' "$ROOT/migrations" | head -n 1 || true) locate_migration=$(grep -rl 'Configure locate to skip Btrfs snapshots' "$ROOT/migrations" | head -n 1 || true)
[[ -n $locate_migration ]] || fail "locate migration exists" [[ -n $locate_migration ]] || fail "locate migration exists"
@@ -85,7 +103,7 @@ OMARCHY_UPDATEDB_CONF_PATH="$conf" \
grep -qFx 'PRUNE_BIND_MOUNTS = "no"' "$conf" || fail "locate migration rewrites updatedb.conf" grep -qFx 'PRUNE_BIND_MOUNTS = "no"' "$conf" || fail "locate migration rewrites updatedb.conf"
grep -qF 'PRUNEPATHS = "/.snapshots /afs' "$conf" || fail "locate migration prunes /.snapshots" grep -qF 'PRUNEPATHS = "/.snapshots /afs' "$conf" || fail "locate migration prunes /.snapshots"
grep -qFx 'systemctl start --no-block plocate-updatedb.service' "$test_tmp/calls.log" || fail "locate migration rebuilds the locate index without blocking" grep -qFx 'systemctl restart --no-block plocate-updatedb.service' "$test_tmp/calls.log" || fail "locate migration replaces an in-flight run and rebuilds the index without blocking"
pass "locate migration fixes existing installs and rebuilds the index" pass "locate migration fixes existing installs and rebuilds the index"
: >"$test_tmp/calls.log" : >"$test_tmp/calls.log"
@@ -98,3 +116,19 @@ OMARCHY_UPDATEDB_CONF_PATH="$conf" \
[[ ! -s $test_tmp/calls.log ]] || fail "locate migration skips already-configured installs" [[ ! -s $test_tmp/calls.log ]] || fail "locate migration skips already-configured installs"
pass "locate migration is a no-op once updatedb.conf is configured" pass "locate migration is a no-op once updatedb.conf is configured"
# A dev checkout carries migrations from a release whose install scripts the
# checked-out tree may not have yet, and omarchy-migrate runs under set -e.
: >"$test_tmp/calls.log"
conf="$test_tmp/no-config-script-updatedb.conf"
stock_conf "$conf"
TEST_LOG="$test_tmp/calls.log" \
PATH="$fake_bin:$PATH" \
OMARCHY_PATH="$test_tmp/empty" \
OMARCHY_UPDATEDB_CONF_PATH="$conf" \
bash -euo pipefail "$locate_migration" >/dev/null ||
fail "locate migration survives a tree without the locate config script"
[[ ! -s $test_tmp/calls.log ]] || fail "locate migration touches nothing without the locate config script"
pass "locate migration is a no-op when the locate config script is missing"