mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
fix(dev-nix): purge stale nixbld users blocking Nix installer
The Nix 2.32.4 installer allocates build users ascending from NIX_FIRST_BUILD_UID. The pkgmgr-centos:stable base image ships nixbld1..nixbld32 with descending UIDs (RHEL `useradd -r` default: nixbld1=997, nixbld2=996, ...) and no nix binary, so the role detects no install, runs the installer, which then aborts on "nixbld2 already exists, but with the UID '996'". Add purge_stale_nixbld.sh, called via ansible.builtin.script before the installer. Three guards must all hold to purge: 1. No nix binary in candidate paths. 2. nixbld2 UID < nixbld1 UID (broken descending layout). 3. /nix/store does not exist (no live store to orphan). Idempotent. Distro-agnostic at the script level: Debian/Ubuntu stay [UNCHANGED] because guard 2 fails (nixbld users absent); Arch never hits this code path. Production hosts with /nix/store present but nixbld users get [FAIL] (rc=1) instead of silent destruction. Fixes the 31/32 test-deploy-server / test-deploy-universal failures observed in run 26634712613. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
1 parent
84ca98e107
commit
45eea2892f
2 files changed
+82
No files matched your search
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
# Purge stale nixbld build users when their layout would block the
|
||||
# multi-user Nix installer (descending UIDs as created by `useradd -r`
|
||||
# on RHEL-family pkgmgr base images) and no live /nix/store exists.
|
||||
#
|
||||
# Idempotent. Safe to re-run.
|
||||
#
|
||||
# Three guards must all hold to purge:
|
||||
# 1. No nix binary in known install paths.
|
||||
# 2. nixbld2 UID < nixbld1 UID (the broken descending layout).
|
||||
# 3. /nix/store does not exist (no live store to orphan).
|
||||
set -euo pipefail
|
||||
|
||||
NIX_BINARY_CANDIDATES=(
|
||||
/nix/var/nix/profiles/default/bin/nix
|
||||
/nix/var/nix/profiles/per-user/root/profile/bin/nix
|
||||
/root/.nix-profile/bin/nix
|
||||
/usr/local/bin/nix
|
||||
/usr/bin/nix
|
||||
)
|
||||
|
||||
found_binary=""
|
||||
for p in "${NIX_BINARY_CANDIDATES[@]}"; do
|
||||
if [[ -x "$p" ]]; then
|
||||
found_binary="$p"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n "$found_binary" ]]; then
|
||||
echo "[UNCHANGED] nix binary present at ${found_binary}, leaving nixbld users intact"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
uid1="$(getent passwd nixbld1 | awk -F: '{print $3}')"
|
||||
uid2="$(getent passwd nixbld2 | awk -F: '{print $3}')"
|
||||
|
||||
if [[ -z "$uid1" || -z "$uid2" ]]; then
|
||||
echo "[UNCHANGED] nixbld1/nixbld2 not both present, nothing to purge"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if (( uid2 >= uid1 )); then
|
||||
echo "[UNCHANGED] nixbld UIDs ascending (nixbld1=${uid1}, nixbld2=${uid2}), no fix needed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -d /nix/store ]]; then
|
||||
echo "[FAIL] /nix/store exists but no nix binary found; refusing to purge build users" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
removed=0
|
||||
for i in $(seq 1 32); do
|
||||
if id "nixbld${i}" >/dev/null 2>&1; then
|
||||
userdel "nixbld${i}"
|
||||
removed=$((removed + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if getent group nixbld >/dev/null; then
|
||||
groupdel nixbld
|
||||
removed=$((removed + 1))
|
||||
fi
|
||||
|
||||
if (( removed > 0 )); then
|
||||
echo "[CHANGED] purged ${removed} stale nixbld entries (descending UID layout: nixbld1=${uid1}, nixbld2=${uid2})"
|
||||
else
|
||||
echo "[UNCHANGED] no nixbld entries found"
|
||||
fi
|
||||
@@ -52,6 +52,18 @@
|
||||
) | default("", true)
|
||||
}}
|
||||
|
||||
- name: Purge stale nixbld users blocking the multi-user installer
|
||||
ansible.builtin.script:
|
||||
cmd: "{{ role_path }}/files/purge_stale_nixbld.sh"
|
||||
register: dev_nix_purge_stale_nixbld_result
|
||||
changed_when: >
|
||||
dev_nix_purge_stale_nixbld_result.stdout is search('\\[CHANGED\\]')
|
||||
failed_when: >
|
||||
dev_nix_purge_stale_nixbld_result.rc != 0 or
|
||||
dev_nix_purge_stale_nixbld_result.stdout is search('\\[FAIL\\]')
|
||||
become: true
|
||||
when: dev_nix_binary_path_before | length == 0
|
||||
|
||||
- name: Read existing nixbld group entry before installer run
|
||||
ansible.builtin.getent:
|
||||
database: group
|
||||
|
||||
Reference in new issue
Block a user