Instead of downloading at first login, everything is ready at boot:
- iso/build-live-iso.sh:
* apply-live-settings.sh XDG autostart applies theme/wallpaper/terminal
via gsettings at first Cinnamon login (reliable vs dconf binary format)
* /etc/environment: XDG_DATA_DIRS includes nix profile so Cinnamon menu
shows pre-baked nix apps immediately
* /etc/profile.d/nix-prebaked.sh: PATH setup for terminal sessions
* first-login.sh kept at /usr/local/libexec but NOT autostarted (manual
use for Claude/NVM installs)
* NIX_PACKAGES_PREBAKE passed to Docker build
- iso/_inner-build-live.sh:
* Pre-bake nix packages inside Docker before mklive.sh; copy /nix store
into squashfs overlay; set /etc/skel/.nix-profile → store profile path
* Cached at /cache/nix-prebake (keyed by package list md5)
- iso/Dockerfile: add rsync (needed by nix prebake)
- packages.live-desktop.list: add vscode + chromium (XBPS, no download)
129 lines
5.2 KiB
Bash
Executable File
129 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Runs INSIDE the docker container (as root). Invoked by iso/build-live-iso.sh.
|
|
# Expects the project bind-mounted at /work and the cache at /cache.
|
|
#
|
|
# Required env (set by build-live-iso.sh):
|
|
# ARCH, REPO_URL, KEYMAP, LOCALE, ISO_PKGS, ISO_TITLE, OUT_ISO_REL,
|
|
# INCLUDE_DIR_REL
|
|
|
|
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"
|
|
INCLUDE_DIR="$PROJECT_DIR/$INCLUDE_DIR_REL"
|
|
OUT_ISO="$PROJECT_DIR/$OUT_ISO_REL"
|
|
|
|
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")"
|
|
|
|
# Compile dconf system-db inside the include dir so it ships compiled.
|
|
# Debian's dconf-cli provides 'dconf compile <output_db> <keyfile_dir>'.
|
|
if command -v dconf >/dev/null 2>&1 && [[ -d "$INCLUDE_DIR/etc/dconf/db/local.d" ]]; then
|
|
dconf compile "$INCLUDE_DIR/etc/dconf/db/local" \
|
|
"$INCLUDE_DIR/etc/dconf/db/local.d" 2>/dev/null \
|
|
&& echo "dconf: compiled system-db/local" \
|
|
|| echo "dconf: compile failed (non-fatal)"
|
|
fi
|
|
|
|
cd "$MKLIVE_DIR"
|
|
|
|
# ── Pre-bake nix packages ────────────────────────────────────────────────
|
|
# Install the nix user packages inside the Docker container and bake the
|
|
# resulting /nix store directly into the squashfs overlay. The live session
|
|
# then boots with all apps already present — no network downloads needed.
|
|
#
|
|
# The store is cached at /cache/nix-prebake; only rebuilt when the package
|
|
# list changes (checked via an md5 key file).
|
|
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
|
|
curl -fsSL https://nixos.org/nix/install | sh -s -- --no-daemon --no-channel-add
|
|
# shellcheck disable=SC1091
|
|
. /root/.nix-profile/etc/profile.d/nix.sh
|
|
|
|
export NIXPKGS_ALLOW_UNFREE=1
|
|
echo " nix profile install: ${_NIX_PKGS[*]}"
|
|
nix profile install --impure "${_NIX_PKGS[@]}" 2>&1
|
|
|
|
# Save the profile store path so we can restore from cache next time
|
|
readlink -f /root/.nix-profile > "$_NIX_CACHE/.profile-path"
|
|
|
|
# Cache the full /nix store
|
|
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
|
|
|
|
# Stage the nix store into the squashfs overlay
|
|
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
|
|
|
|
# /etc/skel/.nix-profile → the pre-baked store profile path.
|
|
# dracut's adduser.sh runs 'useradd -m' which copies skel → /home/live,
|
|
# so the live user gets a ready nix profile from the squashfs store.
|
|
_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"
|
|
else
|
|
echo " WARNING: could not determine nix store profile path"
|
|
fi
|
|
fi
|
|
# ── end nix prebake ──────────────────────────────────────────────────────
|
|
|
|
_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.sh \
|
|
-a "$ARCH" \
|
|
-r "$REPO_URL" \
|
|
-r "${REPO_URL%/current}/current/nonfree" \
|
|
-c "$CACHE_DIR/xbps-live-pkgs" \
|
|
-H "$CACHE_DIR/xbps-host-pkgs" \
|
|
-k "$KEYMAP" \
|
|
-l "$LOCALE" \
|
|
-T "$ISO_TITLE" \
|
|
-p "$ISO_PKGS" \
|
|
-I "$INCLUDE_DIR" \
|
|
-C "${BOOT_CMDLINE:-}" \
|
|
-o "$OUT_ISO"
|
|
|
|
chown "$(stat -c '%u:%g' "$PROJECT_DIR")" "$OUT_ISO" "${OUT_ISO}".* 2>/dev/null || true
|