- Add nvidia/nvidia-dkms/nvidia-libs-32bit/nvidia-vaapi-driver to niri live and installed profiles; wireless-regdb and sof-firmware to all profiles (fixes regulatory.db and SOF firmware dmesg errors) - iso/postsetup-nvidia.sh: new mklive -x hook that re-runs dracut inside the rootfs chroot after the overlay is applied; ensures the squashfs initramfs includes nvidia.ko and omits nouveau.ko at build time — no driver install needed at runtime (fixes /run tmpfs overflow that was killing wireplumber by corrupting D-Bus sockets) - Both ISO inner build scripts gain -x postsetup-nvidia.sh and the nonfree repo flag so nvidia packages resolve correctly - niri config: wireplumber started via supervisor loop (waits for PipeWire socket, auto-restarts on crash) replacing the one-shot exec — survives any D-Bus or pipewire disruption - build-niri-live-iso.sh: NVIDIA modprobe blacklist-nouveau.conf, btusb-quirks.conf, modules-load.d/nvidia.conf, dracut/10-nvidia.conf, Xorg intel/nvidia configs, prime-run helper, elogind run script loop guard, timezone Europe/Zurich overlay, updated BOOT_CMDLINE - build-live-iso.sh: same NVIDIA + timezone + sound udev rule overlays; live-setup.sh timezone and audio group fix - installer/lib/grub.sh: GRUB_CMDLINE_LINUX_DEFAULT gains nvidia-drm.modeset=1 rd.driver.blacklist=nouveau btusb.enable_autosuspend=0 - installer/lib/postinstall.sh: configure_nvidia_prime() adds blacklist-nouveau.conf, btusb-quirks.conf, dracut omit_drivers nouveau, modules-load.d with all four nvidia modules
233 lines
10 KiB
Bash
Executable File
233 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
# Runs INSIDE the docker container (as root). Invoked by iso/build-niri-live-iso.sh.
|
|
# Niri/Wayland variant: nix prebake (shared cache with Cinnamon), adds noctalia repo.
|
|
# Expects the project bind-mounted at /work and the cache at /cache.
|
|
#
|
|
# Required env (set by build-niri-live-iso.sh):
|
|
# ARCH, REPO_URL, KEYMAP, LOCALE, ISO_PKGS, ISO_TITLE, OUT_ISO_REL,
|
|
# INCLUDE_DIR_REL, NIX_PACKAGES_PREBAKE (optional)
|
|
|
|
set -Eeuo pipefail
|
|
|
|
: "${ARCH:?}"; : "${REPO_URL:?}"; : "${KEYMAP:?}"; : "${LOCALE:?}"
|
|
: "${ISO_PKGS:?}"; : "${ISO_TITLE:?}"; : "${OUT_ISO_REL:?}"
|
|
: "${INCLUDE_DIR_REL:?}"
|
|
|
|
CACHE_DIR=/cache
|
|
PROJECT_DIR=/work
|
|
MKLIVE_DIR="$CACHE_DIR/void-mklive-niri" # separate clone — avoids race with Cinnamon parallel build
|
|
INCLUDE_DIR="$PROJECT_DIR/$INCLUDE_DIR_REL"
|
|
OUT_ISO="$PROJECT_DIR/$OUT_ISO_REL"
|
|
|
|
# Third-party Void repo that ships noctalia-shell + noctalia-qs.
|
|
NOCTALIA_REPO="${NOCTALIA_REPO:-https://universalrepo.r1xelelo.workers.dev/void}"
|
|
|
|
export PATH="$CACHE_DIR/xbps-static/usr/bin:$PATH"
|
|
|
|
[[ -d "$MKLIVE_DIR" ]] || { echo "ERROR: $MKLIVE_DIR missing"; exit 1; }
|
|
[[ -d "$INCLUDE_DIR" ]] || { echo "ERROR: $INCLUDE_DIR missing"; exit 1; }
|
|
command -v xbps-install.static >/dev/null \
|
|
|| { echo "ERROR: xbps-install.static not on PATH"; exit 1; }
|
|
|
|
mkdir -p "$(dirname "$OUT_ISO")"
|
|
|
|
cd "$MKLIVE_DIR"
|
|
|
|
# ── Pre-bake nix packages ────────────────────────────────────────────────
|
|
# Shared with the Cinnamon build — same cache dir, same store.
|
|
if [[ -n "${NIX_PACKAGES_PREBAKE:-}" ]]; then
|
|
echo ">>> pre-baking nix packages"
|
|
read -r -a _NIX_PKGS <<< "$NIX_PACKAGES_PREBAKE"
|
|
|
|
_NIX_CACHE="$CACHE_DIR/nix-prebake"
|
|
_CACHE_KEY="$_NIX_CACHE/.done.$(printf '%s\n' "${_NIX_PKGS[@]}" | sort | md5sum | cut -c1-8)"
|
|
|
|
mkdir -p "$_NIX_CACHE"
|
|
|
|
if [[ -f "$_CACHE_KEY" ]] && [[ -d "$_NIX_CACHE/store" ]] && [[ -f "$_NIX_CACHE/.profile-path" ]]; then
|
|
echo " restoring cached nix store ($(du -sh "$_NIX_CACHE/store" 2>/dev/null | cut -f1))"
|
|
mkdir -p /nix
|
|
rsync -a "$_NIX_CACHE/" /nix/ 2>&1 | tail -1
|
|
else
|
|
echo " installing nix (single-user, no-daemon)..."
|
|
rm -rf /nix ~/.nix-profile ~/.nix-defexpr ~/.nix-channels
|
|
mkdir -m 0755 -p /nix
|
|
export NIX_CONFIG="build-users-group = "
|
|
curl -fsSL https://nixos.org/nix/install | \
|
|
NIX_INSTALLER_TRUST_INSTALLER=1 sh -s -- --no-daemon --no-channel-add
|
|
# shellcheck disable=SC1091
|
|
. /root/.nix-profile/etc/profile.d/nix.sh 2>/dev/null || true
|
|
export PATH="/root/.nix-profile/bin:/nix/var/nix/profiles/default/bin:$PATH"
|
|
|
|
export NIXPKGS_ALLOW_UNFREE=1
|
|
echo " nix profile install: ${_NIX_PKGS[*]}"
|
|
nix profile add --extra-experimental-features "nix-command flakes" \
|
|
--impure "${_NIX_PKGS[@]}" 2>&1
|
|
|
|
readlink -f /root/.nix-profile > "$_NIX_CACHE/.profile-path"
|
|
rsync -a /nix/ "$_NIX_CACHE/" 2>&1 | tail -1
|
|
touch "$_CACHE_KEY"
|
|
echo " cached nix store: $(du -sh "$_NIX_CACHE/store" 2>/dev/null | cut -f1)"
|
|
fi
|
|
|
|
echo " staging /nix into overlay ($(du -sh /nix/store 2>/dev/null | cut -f1))"
|
|
mkdir -p "$INCLUDE_DIR/nix"
|
|
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 \
|
|
|| readlink -f /root/.nix-profile 2>/dev/null || echo "")
|
|
if [[ -n "$_STORE_PROFILE" && -d "$_STORE_PROFILE" ]]; then
|
|
mkdir -p "$INCLUDE_DIR/etc/skel"
|
|
ln -sf "$_STORE_PROFILE" "$INCLUDE_DIR/etc/skel/.nix-profile"
|
|
echo " skel/.nix-profile → $_STORE_PROFILE"
|
|
fi
|
|
fi
|
|
# ── end nix prebake ──────────────────────────────────────────────────────
|
|
|
|
# ── Noctalia: build a locally SIGNED XBPS repo ───────────────────────────
|
|
# noctalia-qs has a broken .sig2 on the CDN (RSA signature not valid).
|
|
# noctalia-shell's CDN key import also fails intermittently (EAGAIN).
|
|
# Solution: download both .xbps archives directly (no sig check), create a
|
|
# LOCAL SIGNED repo with a fresh keypair, register our public key in
|
|
# mklive/keys/ so copy_void_keys pre-trusts it in the rootfs.
|
|
# Our local signed repo gets HIGHEST priority (-r last = prepended first),
|
|
# so xbps resolves and verifies both packages against our trusted key.
|
|
echo ">>> building local signed noctalia XBPS repo (CDN .sig2 workaround)"
|
|
_NOC_LOCAL="/tmp/noctalia-local"
|
|
_NOC_HOME="/tmp/noc-sign-home"
|
|
_ARCH="${ARCH:-x86_64}"
|
|
mkdir -p "$_NOC_LOCAL" "$_NOC_HOME"
|
|
export HOME="$_NOC_HOME"
|
|
|
|
# Discover exact package versions from CDN repodata (try multiple User-Agents).
|
|
# Falls back to versions confirmed by previous build errors.
|
|
_NOC_VERS=$(python3 - <<'PYEOF' 2>/dev/null
|
|
import urllib.request, plistlib, tarfile, io, sys, os
|
|
repo = os.environ.get("NOCTALIA_REPO", "https://universalrepo.r1xelelo.workers.dev/void")
|
|
arch = os.environ.get("ARCH", "x86_64")
|
|
want = {"noctalia-qs", "noctalia-shell"}
|
|
found = {}
|
|
for ua in ("curl/8.0", "xbps/0.59.2", "Mozilla/5.0 (X11; Linux x86_64)"):
|
|
try:
|
|
req = urllib.request.Request(f"{repo}/{arch}-repodata", headers={"User-Agent": ua})
|
|
data = urllib.request.urlopen(req, timeout=15).read()
|
|
tf = tarfile.open(fileobj=io.BytesIO(data))
|
|
idx = plistlib.loads(tf.extractfile("index.plist").read())
|
|
# index.plist keys are package names; pkgver field holds the versioned name
|
|
for pkgname, meta in idx.items():
|
|
if isinstance(meta, dict) and pkgname in want:
|
|
found[pkgname] = meta.get("pkgver", pkgname)
|
|
if len(found) >= len(want):
|
|
break
|
|
except Exception:
|
|
pass
|
|
# Fallback to versions confirmed by last build errors
|
|
defaults = {"noctalia-qs": "noctalia-qs-0.0.12_0", "noctalia-shell": "noctalia-shell-4.7.6_1"}
|
|
for pkg, ver in defaults.items():
|
|
if pkg not in found:
|
|
found[pkg] = ver
|
|
for ver in found.values():
|
|
print(ver)
|
|
PYEOF
|
|
)
|
|
|
|
# Download both .xbps archives directly (curl never checks .sig2)
|
|
for _ver in $_NOC_VERS; do
|
|
_fname="${_ver}.${_ARCH}.xbps"
|
|
# Clear any cached bad sig2 from a previous failed build
|
|
rm -f "$CACHE_DIR/xbps-niri-pkgs/${_ver}"* 2>/dev/null || true
|
|
if [[ ! -f "$_NOC_LOCAL/$_fname" ]]; then
|
|
echo " downloading $_fname ..."
|
|
curl -fsSL "$NOCTALIA_REPO/$_fname" -o "$_NOC_LOCAL/$_fname" \
|
|
|| { echo " WARNING: failed to download $_fname"; rm -f "$_NOC_LOCAL/$_fname"; }
|
|
else
|
|
echo " cached: $_fname"
|
|
fi
|
|
done
|
|
|
|
# Build index
|
|
xbps-rindex.static -a "$_NOC_LOCAL"/*.xbps
|
|
|
|
# Generate RSA keypair. xbps-rindex requires --privkey passed explicitly.
|
|
mkdir -p "$_NOC_HOME/.xbps-sign"
|
|
openssl genrsa -out "$_NOC_HOME/.xbps-sign/privkey.pem" 4096 2>/dev/null
|
|
[[ -s "$_NOC_HOME/.xbps-sign/privkey.pem" ]] \
|
|
|| { echo "ERROR: openssl genrsa failed"; exit 1; }
|
|
|
|
_NOC_PRIVKEY="$_NOC_HOME/.xbps-sign/privkey.pem"
|
|
|
|
# Sign repodata then each package (separate calls — xbps-rindex restriction).
|
|
xbps-rindex.static --sign --privkey "$_NOC_PRIVKEY" \
|
|
--signedby "noctalia-local" "$_NOC_LOCAL"
|
|
for _pkg in "$_NOC_LOCAL"/*.xbps; do
|
|
xbps-rindex.static --sign-pkg --privkey "$_NOC_PRIVKEY" \
|
|
--signedby "noctalia-local" "$_pkg"
|
|
done
|
|
|
|
# Register public key in mklive/keys/ so copy_void_keys installs it in the rootfs.
|
|
# xbps fingerprint = MD5 of DER-encoded public key, formatted as aa:bb:cc:...
|
|
openssl rsa -in "$_NOC_PRIVKEY" \
|
|
-pubout -outform DER -out "$_NOC_HOME/pubkey.der" 2>/dev/null
|
|
_FINGERPRINT=$(md5sum "$_NOC_HOME/pubkey.der" \
|
|
| cut -d' ' -f1 | sed 's/../&:/g; s/:$//')
|
|
# The plist <data> field = base64 of the PEM public key (headers included)
|
|
_PUBKEY_B64=$(openssl rsa -in "$_NOC_PRIVKEY" \
|
|
-pubout 2>/dev/null | base64 -w 0)
|
|
cat > "$MKLIVE_DIR/keys/$_FINGERPRINT.plist" <<KEOF
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>public-key</key>
|
|
<data>$_PUBKEY_B64</data>
|
|
<key>public-key-size</key>
|
|
<integer>4096</integer>
|
|
<key>signature-by</key>
|
|
<string>noctalia-local</string>
|
|
</dict>
|
|
</plist>
|
|
KEOF
|
|
echo " local signed noctalia repo ready — key: $_FINGERPRINT"
|
|
unset HOME
|
|
# ── end noctalia local repo ───────────────────────────────────────────────
|
|
|
|
_cleanup_mklive_builds() {
|
|
local d sub
|
|
for d in "$MKLIVE_DIR"/mklive-build.*/; do
|
|
[[ -d "$d" ]] || continue
|
|
for sub in tmp-rootfs/sys tmp-rootfs/proc tmp-rootfs/dev tmp-rootfs/run \
|
|
image/rootfs/sys image/rootfs/proc image/rootfs/dev image/rootfs/run; do
|
|
[[ -d "$d$sub" ]] && umount -R --lazy "$d$sub" 2>/dev/null || true
|
|
done
|
|
rm -rf "$d" 2>/dev/null || true
|
|
done
|
|
}
|
|
trap _cleanup_mklive_builds EXIT
|
|
|
|
# mklive prepends -r args: LAST -r = HIGHEST priority.
|
|
# Our local signed repo is last so xbps resolves noctalia-* from it.
|
|
./mklive.sh \
|
|
-a "$ARCH" \
|
|
-r "$REPO_URL" \
|
|
-r "${REPO_URL%/current}/current/nonfree" \
|
|
-r "$NOCTALIA_REPO" \
|
|
-r "$_NOC_LOCAL" \
|
|
-c "$CACHE_DIR/xbps-niri-pkgs" \
|
|
-H "$CACHE_DIR/xbps-host-pkgs" \
|
|
-k "$KEYMAP" \
|
|
-l "$LOCALE" \
|
|
-T "$ISO_TITLE" \
|
|
-p "$ISO_PKGS" \
|
|
-I "$INCLUDE_DIR" \
|
|
-x "$PROJECT_DIR/iso/postsetup-nvidia.sh" \
|
|
-C "${BOOT_CMDLINE:-}" \
|
|
-o "$OUT_ISO"
|
|
|
|
# Fix ownership so the host user can clean up without sudo.
|
|
# u+rwX: sets read+write on all, execute only on directories (capital X).
|
|
chmod -R u+rwX "$INCLUDE_DIR" 2>/dev/null || true
|
|
chown -R "${HOST_UID:-1000}:${HOST_GID:-1000}" "$INCLUDE_DIR" 2>/dev/null || true
|
|
chown -R "${HOST_UID:-1000}:${HOST_GID:-1000}" "$OUT_ISO" "${OUT_ISO}".* 2>/dev/null || true
|