Fix nix single-user mode for live ISO and installer

- Store ownership: chown -R 1000:1000 at Docker build time (not runtime)
  so the live user can create lock files without flooding the tmpfs overlay
- nix.conf: add build-users-group= to force single-user mode and avoid
  daemon connection attempts (xbps nix-daemon v2.30.2 incompatible with
  pre-baked nix v2.34.6)
- profile.d: export NIX_REMOTE=local and NIXPKGS_ALLOW_UNFREE=1; wrap nix()
  to append --impure so flake installs work without extra flags
- Skel: add ~/.config/nixpkgs/config.nix with allowUnfree=true
- postinstall.sh: fix daemon socket path (/nix/var/nix/...), write
  ~/.config/nixpkgs/config.nix for installed user
- first-login.sh: add NIX_REMOTE=local alongside NIXPKGS_ALLOW_UNFREE=1
- Remove nix-daemon from live ISO services (wrong version for pre-baked client)
- Misc: bluetooth group, package list reorg, skip vscode install for niri profile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
moze
2026-04-25 12:56:13 +00:00
parent 6d65f28844
commit 49d94bd2ac
11 changed files with 109 additions and 31 deletions

View File

@@ -119,7 +119,7 @@ LIVE_USER="${USERNAME:-live}"
LIVE_USER="${LIVE_USER:-live}"
# Extra groups (dracut only adds audio,video,wheel)
for g in plugdev input network video audio _seatd; do
for g in plugdev input network video audio _seatd bluetooth; do
groupadd -f "$g" 2>/dev/null || true
usermod -aG "$g" "$LIVE_USER" 2>/dev/null || true
done
@@ -145,6 +145,7 @@ XDG_RUN="/run/user/$(id -u "$LIVE_USER" 2>/dev/null || echo 1000)"
install -d -m 0700 "$XDG_RUN" 2>/dev/null || true
chown "$LIVE_USER" "$XDG_RUN" 2>/dev/null || true
# Start elogind here, once, before runsvdir brings up greetd.
# Runit does NOT supervise it — this avoids cgroup-race restart spam.
# We wait until dbus is available (dbus service starts first in runsvdir),
@@ -209,7 +210,7 @@ sleep 3
EOF
chmod 0755 "$INCLUDE_DIR/etc/sv/elogind/finish"
for svc in dbus elogind NetworkManager sshd; do
for svc in dbus elogind NetworkManager bluetoothd sshd; do
ln -sf "/etc/sv/$svc" "$INCLUDE_DIR/etc/runit/runsvdir/default/$svc"
done
@@ -237,6 +238,13 @@ if [[ -d "${HOME:-}/.nix-profile/bin" ]]; then
*) export PATH="$HOME/.nix-profile/bin:$PATH" ;;
esac
fi
export NIXPKGS_ALLOW_UNFREE=1
# Pre-baked nix is single-user (no daemon) — bypass daemon connection attempt
export NIX_REMOTE=local
# Flake commands ignore NIXPKGS_ALLOW_UNFREE unless --impure is passed.
# Wrap nix so interactive installs work without extra flags.
nix() { command nix "$@" --impure; }
export -f nix
EOF
chmod 0644 "$INCLUDE_DIR/etc/profile.d/nix-prebaked.sh"
@@ -244,6 +252,7 @@ chmod 0644 "$INCLUDE_DIR/etc/profile.d/nix-prebaked.sh"
install -d -m 0755 "$INCLUDE_DIR/etc/nix"
cat > "$INCLUDE_DIR/etc/nix/nix.conf" <<EOF
experimental-features = nix-command flakes
build-users-group =
sandbox = false
auto-optimise-store = true
trusted-users = root ${LIVE_USER}
@@ -251,6 +260,10 @@ max-jobs = 2
http-connections = 10
EOF
# nixpkgs config: allow unfree packages for all users
install -d -m 0755 "$INCLUDE_DIR/etc/skel/.config/nixpkgs"
echo '{ allowUnfree = true; }' > "$INCLUDE_DIR/etc/skel/.config/nixpkgs/config.nix"
# ── 3e) niri config.kdl in /etc/skel ───────────────────────────────────
# dracut's adduser.sh copies skel → /home/live, so the live user gets a
# ready niri config without any first-boot setup step.
@@ -314,15 +327,17 @@ spawn-at-startup "pipewire"
spawn-at-startup "pipewire-pulse"
spawn-at-startup "wireplumber"
// Background, notifications, network, bluetooth, auth
// Background, notifications and auth
spawn-at-startup "swaybg" "-i" "/usr/share/backgrounds/void-installer/pxfuel.jpg" "-m" "fill"
spawn-at-startup "mako"
spawn-at-startup "nm-applet" "--indicator"
spawn-at-startup "blueman-applet"
spawn-at-startup "/usr/libexec/polkit-gnome-authentication-agent-1"
// noctalia-shell (Quickshell-based Wayland shell)
spawn-at-startup "quickshell" "-c" "noctalia-shell"
// noctalia-shell — wait for org.bluez before launching so the BT module
// initialises correctly (bluetoothd may not be on D-Bus yet at this point).
spawn-at-startup "sh" "-c" "i=0; while [ \$i -lt 30 ] && ! dbus-send --system --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.bluez >/dev/null 2>&1; do sleep 1; i=\$((i+1)); done; exec quickshell -c noctalia-shell"
// First-login setup: installs Claude Code (and NVM) once, then closes
spawn-at-startup "sh" "-c" "[ -f ~/.first-login-done ] || alacritty -T 'Void Setup' -e /usr/local/libexec/first-login.sh"
binds {
Mod+T { spawn "alacritty"; }
@@ -408,6 +423,28 @@ if [[ -d "$BIBATA_SRC" ]]; then
echo " cursor: Bibata-Modern-Ice"
fi
# first-login.sh — deployed by _deploy_first_login() to the installed system.
[[ -r "$PROJECT_DIR/installer/first-login.sh" ]] && \
install -m 0755 "$PROJECT_DIR/installer/first-login.sh" "$OVERLAY/first-login.sh"
# Claude Code config + auth tokens from host (deployed to the installed system).
CLAUDE_SRC="${CLAUDE_SRC:-$HOME/.claude}"
[[ -d "$CLAUDE_SRC" ]] && { cp -a "$CLAUDE_SRC" "$OVERLAY/claude"; echo " claude: ~/.claude bundled"; }
[[ -r "${HOME}/.claude.json" ]] && install -m 0600 "${HOME}/.claude.json" "$OVERLAY/claude.json"
# VS Code user config + extension list from host.
VSCODE_SRC="${VSCODE_USER_SRC:-$HOME/.config/Code/User}"
install -d -m 0755 "$OVERLAY/vscode-user"
if [[ -d "$VSCODE_SRC" ]]; then
for f in settings.json keybindings.json; do
[[ -r "$VSCODE_SRC/$f" ]] && install -m 0644 "$VSCODE_SRC/$f" "$OVERLAY/vscode-user/$f"
done
[[ -d "$VSCODE_SRC/snippets" ]] && cp -a "$VSCODE_SRC/snippets" "$OVERLAY/vscode-user/snippets"
command -v code >/dev/null 2>&1 && \
code --list-extensions > "$OVERLAY/vscode-extensions.txt" 2>/dev/null || true
echo " vscode-user: staged from $VSCODE_SRC"
fi
# Copy wallpapers and assets into usr/share (rootfs overlay)
install -d -m 0755 "$INCLUDE_DIR/usr/share/backgrounds/void-installer"
cp -a "$OVERLAY/wallpapers"/. "$INCLUDE_DIR/usr/share/backgrounds/void-installer/" 2>/dev/null || true
@@ -488,6 +525,20 @@ exec /usr/local/lib/void-installer/install.sh "$@"
WRAPEOF
chmod 0755 "$INCLUDE_DIR/usr/local/bin/void-install"
# first-login.sh at /usr/local/libexec: available in the live session and
# deployed by _deploy_first_login() to the installed system via the overlay.
install -d -m 0755 "$INCLUDE_DIR/usr/local/libexec"
install -m 0755 "$PROJECT_DIR/installer/first-login.sh" \
"$INCLUDE_DIR/usr/local/libexec/first-login.sh"
# nix-packages.list: tells first-login.sh which nix packages to install.
# In the live session these are already prebaked; in the installed system the
# first-boot-nix runit service handles them, so this is informational only.
{
printf '# Nix user packages\n'
printf '%s\n' "${NIX_USER_PACKAGES[@]}"
} > "$INCLUDE_DIR/usr/local/libexec/nix-packages.list"
_SECRETS_SRC="${SECRETS_ENV:-$PROJECT_DIR/secrets.env}"
if [[ -r "$_SECRETS_SRC" ]]; then
install -d -m 0755 "$INCLUDE_DIR/etc"