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:
@@ -7,7 +7,7 @@ HOSTNAME="xps9700"
|
|||||||
USERNAME="moze"
|
USERNAME="moze"
|
||||||
USER_FULLNAME="moze"
|
USER_FULLNAME="moze"
|
||||||
USER_UID="1000"
|
USER_UID="1000"
|
||||||
USER_GROUPS="wheel,docker,video,audio,input,plugdev,network,kvm,users"
|
USER_GROUPS="wheel,docker,video,audio,input,plugdev,network,kvm,users,bluetooth"
|
||||||
DEFAULT_SHELL="/bin/bash"
|
DEFAULT_SHELL="/bin/bash"
|
||||||
|
|
||||||
# ---------- Locale ----------
|
# ---------- Locale ----------
|
||||||
|
|||||||
@@ -47,10 +47,8 @@ prefer-no-csd
|
|||||||
|
|
||||||
spawn-at-startup "swaybg" "-i" "/usr/share/backgrounds/void-installer/pxfuel.jpg"
|
spawn-at-startup "swaybg" "-i" "/usr/share/backgrounds/void-installer/pxfuel.jpg"
|
||||||
spawn-at-startup "mako"
|
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"
|
spawn-at-startup "/usr/libexec/polkit-gnome-authentication-agent-1"
|
||||||
spawn-at-startup "noctalia-shell"
|
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 noctalia-shell"
|
||||||
|
|
||||||
cursor {
|
cursor {
|
||||||
xcursor-theme "Bibata-Modern-Ice"
|
xcursor-theme "Bibata-Modern-Ice"
|
||||||
|
|||||||
@@ -110,10 +110,12 @@ gvfs-smb
|
|||||||
file-roller
|
file-roller
|
||||||
gnome-keyring
|
gnome-keyring
|
||||||
seahorse
|
seahorse
|
||||||
network-manager-applet
|
|
||||||
blueman
|
blueman
|
||||||
bluez
|
bluez
|
||||||
|
|
||||||
|
# --- bluetooth audio ---
|
||||||
|
bluez-alsa
|
||||||
|
|
||||||
# --- display manager ---
|
# --- display manager ---
|
||||||
# niri can be launched directly via TTY (`niri-session`) or via a wayland-aware
|
# niri can be launched directly via TTY (`niri-session`) or via a wayland-aware
|
||||||
# greeter. We use greetd + tuigreet — lighter than lightdm under wayland.
|
# greeter. We use greetd + tuigreet — lighter than lightdm under wayland.
|
||||||
@@ -170,9 +172,6 @@ system-config-printer
|
|||||||
sane
|
sane
|
||||||
simple-scan
|
simple-scan
|
||||||
|
|
||||||
# --- bluetooth audio ---
|
|
||||||
bluez-alsa
|
|
||||||
|
|
||||||
# --- backups / snapshots ---
|
# --- backups / snapshots ---
|
||||||
timeshift
|
timeshift
|
||||||
grub-btrfs
|
grub-btrfs
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ brightnessctl
|
|||||||
ImageMagick
|
ImageMagick
|
||||||
python3
|
python3
|
||||||
upower
|
upower
|
||||||
|
power-profiles-daemon
|
||||||
wl-clipboard
|
wl-clipboard
|
||||||
network-manager-applet
|
|
||||||
|
|
||||||
# --- XDG portals ---
|
# --- XDG portals ---
|
||||||
xdg-desktop-portal
|
xdg-desktop-portal
|
||||||
@@ -98,7 +98,7 @@ xdg-desktop-portal-gnome
|
|||||||
xdg-utils
|
xdg-utils
|
||||||
xdg-user-dirs
|
xdg-user-dirs
|
||||||
|
|
||||||
# --- nix (for prebaked packages — spotify, discord, vscode, fastfetch, etc.) ---
|
# --- nix (for prebaked packages — spotify, discord, google-chrome, vscode, fastfetch, etc.) ---
|
||||||
nix
|
nix
|
||||||
|
|
||||||
# --- noctalia-shell (from noctalia third-party XBPS repo) ---
|
# --- noctalia-shell (from noctalia third-party XBPS repo) ---
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# First-login one-shot setup for the user.
|
# First-login one-shot setup for the user.
|
||||||
# Installs: Claude Code, NVM + node LTS, VS Code extensions,
|
# Installs: Claude Code, NVM + node LTS, VS Code extensions,
|
||||||
# and (if NIX_PACKAGES_FILE is present) nix user packages
|
# and (if NIX_PACKAGES_FILE is present) nix user packages
|
||||||
# (google-chrome, spotify, discord, localsend, mission-center).
|
# (google-chrome, spotify, discord, localsend, mission-center, vscode).
|
||||||
# Idempotent: creates ~/.first-login-done marker on success.
|
# Idempotent: creates ~/.first-login-done marker on success.
|
||||||
|
|
||||||
# NOTE: do NOT use `set -u` here — nvm.sh references unbound vars.
|
# NOTE: do NOT use `set -u` here — nvm.sh references unbound vars.
|
||||||
@@ -23,16 +23,17 @@ if ! curl -fsSL --max-time 3 --connect-timeout 3 -o /dev/null https://api.github
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Claude Code (official native installer) ---
|
|
||||||
mkdir -p "$HOME/.local/bin"
|
mkdir -p "$HOME/.local/bin"
|
||||||
export PATH="$HOME/.local/bin:$PATH"
|
export PATH="$HOME/.local/bin:$PATH"
|
||||||
|
|
||||||
|
# --- Claude Code (official native installer) ---
|
||||||
if ! command -v claude >/dev/null 2>&1 && [[ ! -x "$HOME/.local/bin/claude" ]]; then
|
if ! command -v claude >/dev/null 2>&1 && [[ ! -x "$HOME/.local/bin/claude" ]]; then
|
||||||
echo "==> installing Claude Code via official installer"
|
echo "==> installing Claude Code via official installer"
|
||||||
curl -fsSL https://claude.ai/install.sh | bash || {
|
curl -fsSL https://claude.ai/install.sh | bash || {
|
||||||
echo "!! claude install failed"; }
|
echo "!! claude install failed"; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Nix user packages (google-chrome, spotify, discord, etc.) ---
|
# --- Nix user packages (google-chrome, spotify, discord, vscode, etc.) ---
|
||||||
# Present when running from the live ISO (written by build-live-iso.sh).
|
# Present when running from the live ISO (written by build-live-iso.sh).
|
||||||
# In the installed system the packages come from first-boot-nix.sh instead.
|
# In the installed system the packages come from first-boot-nix.sh instead.
|
||||||
# NOTE: nix packages are intentionally skipped in the live session — they
|
# NOTE: nix packages are intentionally skipped in the live session — they
|
||||||
@@ -72,6 +73,7 @@ if [[ -r "$NIX_PACKAGES_FILE" ]] && command -v nix >/dev/null 2>&1; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
export NIXPKGS_ALLOW_UNFREE=1
|
export NIXPKGS_ALLOW_UNFREE=1
|
||||||
|
export NIX_REMOTE=local
|
||||||
|
|
||||||
mapfile -t pkgs < <(grep -vE '^\s*(#|$)' "$NIX_PACKAGES_FILE")
|
mapfile -t pkgs < <(grep -vE '^\s*(#|$)' "$NIX_PACKAGES_FILE")
|
||||||
if [[ ${#pkgs[@]} -gt 0 ]]; then
|
if [[ ${#pkgs[@]} -gt 0 ]]; then
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ main() {
|
|||||||
configure_nvidia_prime
|
configure_nvidia_prime
|
||||||
configure_zram
|
configure_zram
|
||||||
configure_nix
|
configure_nix
|
||||||
install_vscode_real
|
[[ "${DESKTOP:-cinnamon}" != "niri" ]] && install_vscode_real
|
||||||
install_customizations
|
install_customizations
|
||||||
enable_services
|
enable_services
|
||||||
install_grub
|
install_grub
|
||||||
|
|||||||
@@ -206,13 +206,12 @@ mark=/var/lib/first-boot-nix.done
|
|||||||
[[ -f "\$mark" ]] && exit 0
|
[[ -f "\$mark" ]] && exit 0
|
||||||
|
|
||||||
# Wait for nix-daemon to be available.
|
# Wait for nix-daemon to be available.
|
||||||
# The Void xbps nix package puts the socket at /var/nix/daemon-socket/socket.
|
|
||||||
for _ in \$(seq 1 60); do
|
for _ in \$(seq 1 60); do
|
||||||
[[ -S /var/nix/daemon-socket/socket ]] && break
|
[[ -S /nix/var/nix/daemon-socket/socket ]] && break
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ ! -S /var/nix/daemon-socket/socket ]]; then
|
if [[ ! -S /nix/var/nix/daemon-socket/socket ]]; then
|
||||||
echo "nix-daemon not available; aborting first-boot nix install" >&2
|
echo "nix-daemon not available; aborting first-boot nix install" >&2
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
@@ -230,6 +229,12 @@ touch "\$mark"
|
|||||||
EOF
|
EOF
|
||||||
chmod 0755 "$TARGET/usr/local/libexec/first-boot-nix.sh"
|
chmod 0755 "$TARGET/usr/local/libexec/first-boot-nix.sh"
|
||||||
|
|
||||||
|
# Persistent nixpkgs config so the installed user can install unfree packages
|
||||||
|
# without needing to export NIXPKGS_ALLOW_UNFREE=1 every time.
|
||||||
|
install -d -m 0755 "$TARGET/home/$USERNAME/.config/nixpkgs"
|
||||||
|
echo '{ allowUnfree = true; }' > "$TARGET/home/$USERNAME/.config/nixpkgs/config.nix"
|
||||||
|
run_chroot "chown -R $USERNAME:$USERNAME /home/$USERNAME/.config/nixpkgs"
|
||||||
|
|
||||||
# runit one-shot service.
|
# runit one-shot service.
|
||||||
install -d -m 0755 "$TARGET/etc/sv/first-boot-nix"
|
install -d -m 0755 "$TARGET/etc/sv/first-boot-nix"
|
||||||
cat > "$TARGET/etc/sv/first-boot-nix/run" <<'EOF'
|
cat > "$TARGET/etc/sv/first-boot-nix/run" <<'EOF'
|
||||||
@@ -312,10 +317,8 @@ enable_services() {
|
|||||||
local enabled=(
|
local enabled=(
|
||||||
dbus
|
dbus
|
||||||
NetworkManager
|
NetworkManager
|
||||||
lightdm
|
|
||||||
polkitd
|
polkitd
|
||||||
docker
|
docker
|
||||||
bluetoothd
|
|
||||||
acpid
|
acpid
|
||||||
tlp
|
tlp
|
||||||
elogind
|
elogind
|
||||||
@@ -326,6 +329,14 @@ enable_services() {
|
|||||||
cupsd
|
cupsd
|
||||||
cups-browsed
|
cups-browsed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Display manager: greetd for wayland/niri, lightdm for cinnamon.
|
||||||
|
if [[ "${DESKTOP:-cinnamon}" == "niri" ]]; then
|
||||||
|
enabled+=(greetd bluetoothd)
|
||||||
|
else
|
||||||
|
enabled+=(lightdm bluetoothd)
|
||||||
|
fi
|
||||||
|
|
||||||
[[ "${SSHD_ENABLE:-no}" == "yes" ]] && enabled+=(sshd)
|
[[ "${SSHD_ENABLE:-no}" == "yes" ]] && enabled+=(sshd)
|
||||||
|
|
||||||
for svc in "${enabled[@]}"; do
|
for svc in "${enabled[@]}"; do
|
||||||
|
|||||||
@@ -112,6 +112,8 @@ if [[ -n "${NIX_PACKAGES_PREBAKE:-}" ]]; then
|
|||||||
echo " staging /nix into overlay ($(du -sh /nix/store 2>/dev/null | cut -f1))"
|
echo " staging /nix into overlay ($(du -sh /nix/store 2>/dev/null | cut -f1))"
|
||||||
mkdir -p "$INCLUDE_DIR/nix"
|
mkdir -p "$INCLUDE_DIR/nix"
|
||||||
rsync -a /nix/ "$INCLUDE_DIR/nix/" 2>&1 | tail -1
|
rsync -a /nix/ "$INCLUDE_DIR/nix/" 2>&1 | tail -1
|
||||||
|
# Single-user nix: the live user (uid 1000) must own the store to create lock files and new paths.
|
||||||
|
chown -R 1000:1000 "$INCLUDE_DIR/nix"
|
||||||
|
|
||||||
# /etc/skel/.nix-profile → the pre-baked store profile path.
|
# /etc/skel/.nix-profile → the pre-baked store profile path.
|
||||||
# dracut's adduser.sh runs 'useradd -m' which copies skel → /home/live,
|
# dracut's adduser.sh runs 'useradd -m' which copies skel → /home/live,
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ if [[ -n "${NIX_PACKAGES_PREBAKE:-}" ]]; then
|
|||||||
echo " staging /nix into overlay ($(du -sh /nix/store 2>/dev/null | cut -f1))"
|
echo " staging /nix into overlay ($(du -sh /nix/store 2>/dev/null | cut -f1))"
|
||||||
mkdir -p "$INCLUDE_DIR/nix"
|
mkdir -p "$INCLUDE_DIR/nix"
|
||||||
rsync -a /nix/ "$INCLUDE_DIR/nix/" 2>&1 | tail -1
|
rsync -a /nix/ "$INCLUDE_DIR/nix/" 2>&1 | tail -1
|
||||||
|
# Single-user nix: the live user (uid 1000) must own the store to create lock files and new paths.
|
||||||
|
chown -R 1000:1000 "$INCLUDE_DIR/nix"
|
||||||
|
|
||||||
_STORE_PROFILE=$(cat "$_NIX_CACHE/.profile-path" 2>/dev/null \
|
_STORE_PROFILE=$(cat "$_NIX_CACHE/.profile-path" 2>/dev/null \
|
||||||
|| readlink -f /root/.nix-profile 2>/dev/null || echo "")
|
|| readlink -f /root/.nix-profile 2>/dev/null || echo "")
|
||||||
@@ -113,9 +115,10 @@ for ua in ("curl/8.0", "xbps/0.59.2", "Mozilla/5.0 (X11; Linux x86_64)"):
|
|||||||
data = urllib.request.urlopen(req, timeout=15).read()
|
data = urllib.request.urlopen(req, timeout=15).read()
|
||||||
tf = tarfile.open(fileobj=io.BytesIO(data))
|
tf = tarfile.open(fileobj=io.BytesIO(data))
|
||||||
idx = plistlib.loads(tf.extractfile("index.plist").read())
|
idx = plistlib.loads(tf.extractfile("index.plist").read())
|
||||||
for pkgver, meta in idx.items():
|
# index.plist keys are package names; pkgver field holds the versioned name
|
||||||
if isinstance(meta, dict) and meta.get("pkgname") in want:
|
for pkgname, meta in idx.items():
|
||||||
found[meta["pkgname"]] = pkgver
|
if isinstance(meta, dict) and pkgname in want:
|
||||||
|
found[pkgname] = meta.get("pkgver", pkgname)
|
||||||
if len(found) >= len(want):
|
if len(found) >= len(want):
|
||||||
break
|
break
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ LIVE_USER="${USERNAME:-live}"
|
|||||||
LIVE_USER="${USERNAME:-live}"
|
LIVE_USER="${USERNAME:-live}"
|
||||||
|
|
||||||
# Extra groups (dracut only adds audio,video,wheel)
|
# Extra groups (dracut only adds audio,video,wheel)
|
||||||
for g in plugdev input network docker; do
|
for g in plugdev input network docker bluetooth; do
|
||||||
groupadd -f "$g" 2>/dev/null || true
|
groupadd -f "$g" 2>/dev/null || true
|
||||||
usermod -aG "$g" "$LIVE_USER" 2>/dev/null || true
|
usermod -aG "$g" "$LIVE_USER" 2>/dev/null || true
|
||||||
done
|
done
|
||||||
@@ -107,6 +107,7 @@ if [ -x /usr/bin/nix ]; then
|
|||||||
install -d -m 0755 /etc/nix
|
install -d -m 0755 /etc/nix
|
||||||
cat > /etc/nix/nix.conf <<NIXCONF
|
cat > /etc/nix/nix.conf <<NIXCONF
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
|
build-users-group =
|
||||||
sandbox = false
|
sandbox = false
|
||||||
auto-optimise-store = true
|
auto-optimise-store = true
|
||||||
trusted-users = root $LIVE_USER
|
trusted-users = root $LIVE_USER
|
||||||
@@ -288,7 +289,7 @@ EOF
|
|||||||
|
|
||||||
install -d -m 0755 "$INCLUDE_DIR/etc/runit/runsvdir/default"
|
install -d -m 0755 "$INCLUDE_DIR/etc/runit/runsvdir/default"
|
||||||
# Enable services for the live session.
|
# Enable services for the live session.
|
||||||
for svc in dbus NetworkManager lightdm nix-daemon; do
|
for svc in dbus NetworkManager lightdm bluetoothd; do
|
||||||
ln -sf "/etc/sv/$svc" "$INCLUDE_DIR/etc/runit/runsvdir/default/$svc" 2>/dev/null || true
|
ln -sf "/etc/sv/$svc" "$INCLUDE_DIR/etc/runit/runsvdir/default/$svc" 2>/dev/null || true
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -570,6 +571,13 @@ if [[ -d "${HOME:-}/.nix-profile/bin" ]]; then
|
|||||||
*) export PATH="$HOME/.nix-profile/bin:$PATH" ;;
|
*) export PATH="$HOME/.nix-profile/bin:$PATH" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
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
|
||||||
NIXEOF
|
NIXEOF
|
||||||
|
|
||||||
|
|
||||||
@@ -641,6 +649,10 @@ cat > "$INCLUDE_DIR/etc/profile.d/nix-packages-path.sh" <<'EOF'
|
|||||||
export NIX_PACKAGES_FILE=/usr/local/libexec/nix-packages.list
|
export NIX_PACKAGES_FILE=/usr/local/libexec/nix-packages.list
|
||||||
EOF
|
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"
|
||||||
|
|
||||||
# ── 3g) Skel: .bash_profile sources .bashrc only (no first-login autorun) ──
|
# ── 3g) Skel: .bash_profile sources .bashrc only (no first-login autorun) ──
|
||||||
install -d -m 0755 "$INCLUDE_DIR/etc/skel"
|
install -d -m 0755 "$INCLUDE_DIR/etc/skel"
|
||||||
cat > "$INCLUDE_DIR/etc/skel/.bash_profile" <<'EOF'
|
cat > "$INCLUDE_DIR/etc/skel/.bash_profile" <<'EOF'
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ LIVE_USER="${USERNAME:-live}"
|
|||||||
LIVE_USER="${LIVE_USER:-live}"
|
LIVE_USER="${LIVE_USER:-live}"
|
||||||
|
|
||||||
# Extra groups (dracut only adds audio,video,wheel)
|
# 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
|
groupadd -f "$g" 2>/dev/null || true
|
||||||
usermod -aG "$g" "$LIVE_USER" 2>/dev/null || true
|
usermod -aG "$g" "$LIVE_USER" 2>/dev/null || true
|
||||||
done
|
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
|
install -d -m 0700 "$XDG_RUN" 2>/dev/null || true
|
||||||
chown "$LIVE_USER" "$XDG_RUN" 2>/dev/null || true
|
chown "$LIVE_USER" "$XDG_RUN" 2>/dev/null || true
|
||||||
|
|
||||||
|
|
||||||
# Start elogind here, once, before runsvdir brings up greetd.
|
# Start elogind here, once, before runsvdir brings up greetd.
|
||||||
# Runit does NOT supervise it — this avoids cgroup-race restart spam.
|
# Runit does NOT supervise it — this avoids cgroup-race restart spam.
|
||||||
# We wait until dbus is available (dbus service starts first in runsvdir),
|
# We wait until dbus is available (dbus service starts first in runsvdir),
|
||||||
@@ -209,7 +210,7 @@ sleep 3
|
|||||||
EOF
|
EOF
|
||||||
chmod 0755 "$INCLUDE_DIR/etc/sv/elogind/finish"
|
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"
|
ln -sf "/etc/sv/$svc" "$INCLUDE_DIR/etc/runit/runsvdir/default/$svc"
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -237,6 +238,13 @@ if [[ -d "${HOME:-}/.nix-profile/bin" ]]; then
|
|||||||
*) export PATH="$HOME/.nix-profile/bin:$PATH" ;;
|
*) export PATH="$HOME/.nix-profile/bin:$PATH" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
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
|
EOF
|
||||||
chmod 0644 "$INCLUDE_DIR/etc/profile.d/nix-prebaked.sh"
|
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"
|
install -d -m 0755 "$INCLUDE_DIR/etc/nix"
|
||||||
cat > "$INCLUDE_DIR/etc/nix/nix.conf" <<EOF
|
cat > "$INCLUDE_DIR/etc/nix/nix.conf" <<EOF
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
|
build-users-group =
|
||||||
sandbox = false
|
sandbox = false
|
||||||
auto-optimise-store = true
|
auto-optimise-store = true
|
||||||
trusted-users = root ${LIVE_USER}
|
trusted-users = root ${LIVE_USER}
|
||||||
@@ -251,6 +260,10 @@ max-jobs = 2
|
|||||||
http-connections = 10
|
http-connections = 10
|
||||||
EOF
|
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 ───────────────────────────────────
|
# ── 3e) niri config.kdl in /etc/skel ───────────────────────────────────
|
||||||
# dracut's adduser.sh copies skel → /home/live, so the live user gets a
|
# dracut's adduser.sh copies skel → /home/live, so the live user gets a
|
||||||
# ready niri config without any first-boot setup step.
|
# 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 "pipewire-pulse"
|
||||||
spawn-at-startup "wireplumber"
|
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 "swaybg" "-i" "/usr/share/backgrounds/void-installer/pxfuel.jpg" "-m" "fill"
|
||||||
spawn-at-startup "mako"
|
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"
|
spawn-at-startup "/usr/libexec/polkit-gnome-authentication-agent-1"
|
||||||
|
|
||||||
// noctalia-shell (Quickshell-based Wayland shell)
|
// noctalia-shell — wait for org.bluez before launching so the BT module
|
||||||
spawn-at-startup "quickshell" "-c" "noctalia-shell"
|
// 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 {
|
binds {
|
||||||
Mod+T { spawn "alacritty"; }
|
Mod+T { spawn "alacritty"; }
|
||||||
@@ -408,6 +423,28 @@ if [[ -d "$BIBATA_SRC" ]]; then
|
|||||||
echo " cursor: Bibata-Modern-Ice"
|
echo " cursor: Bibata-Modern-Ice"
|
||||||
fi
|
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)
|
# Copy wallpapers and assets into usr/share (rootfs overlay)
|
||||||
install -d -m 0755 "$INCLUDE_DIR/usr/share/backgrounds/void-installer"
|
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
|
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
|
WRAPEOF
|
||||||
chmod 0755 "$INCLUDE_DIR/usr/local/bin/void-install"
|
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}"
|
_SECRETS_SRC="${SECRETS_ENV:-$PROJECT_DIR/secrets.env}"
|
||||||
if [[ -r "$_SECRETS_SRC" ]]; then
|
if [[ -r "$_SECRETS_SRC" ]]; then
|
||||||
install -d -m 0755 "$INCLUDE_DIR/etc"
|
install -d -m 0755 "$INCLUDE_DIR/etc"
|
||||||
|
|||||||
Reference in New Issue
Block a user