From f5a1182a3de5e687e56d8c4323ed18b0b44d8a0e Mon Sep 17 00:00:00 2001 From: The_miro Date: Fri, 26 Jun 2026 10:57:32 +0200 Subject: [PATCH] feat(plymouth): add custom-logo variant, sync answerfile + docs - plymouth.sh: accepts PLYMOUTH_LOGO_SRC env var; PNG used as-is, SVG converted via rsvg-convert (librsvg only installed when needed) - apps/plymouth-custom.sh: thin wrapper that validates the caller-supplied path and delegates to plymouth.sh with PLYMOUTH_LOGO_SRC exported - install-modules.sh: adds 'Plymouth (custom)' checklist entry; prompts for image path via inputbox before the confirmation dialog; exports PLYMOUTH_LOGO_SRC into the module run - generate-answerfile.sh: adds 'plymouth' (on by default) to the components checklist to match tui-install.sh - docs: installation.md and modules.md updated with Plymouth component, answerfile schema, mkinitcpio note, and custom-logo module entry Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01SyBNiWy3wpawrWb9ryVk7p --- docs/md/installation.md | 7 +- docs/md/modules.md | 13 ++++ setup/generate-answerfile.sh | 11 ++-- setup/install-modules.sh | 39 ++++++++++- .../optional-Modules/apps/plymouth-custom.sh | 22 +++++++ setup/modules/optional-Modules/plymouth.sh | 64 +++++++++++-------- 6 files changed, 119 insertions(+), 37 deletions(-) create mode 100644 setup/modules/optional-Modules/apps/plymouth-custom.sh diff --git a/docs/md/installation.md b/docs/md/installation.md index 944366e..7967dad 100644 --- a/docs/md/installation.md +++ b/docs/md/installation.md @@ -35,6 +35,7 @@ The TUI walks you through: - `core` — 100+ base system packages - `svc` — core services (NetworkManager, cronie, fail2ban, greetd) - `shell` — zsh, Neovim, Yazi, Micro, Starship + - `plymouth` — boot splash screen (skull logo + magenta spinner, **on by default**) 3. **Desktop Environment** — HyprLua, Niri, Hyprland, Sway, KDE Plasma, GNOME, COSMIC, XFCE, LXQt, or none 4. **Applications** — checklist of ~50 optional apps (see [Modules](modules.md)) 5. **Colorway** — optional; enter hex values to customise the CyberQueer palette @@ -79,7 +80,7 @@ This dry-runs every installer dialog and saves your choices. **No software is in "fido2_root": false, "fido2_user": false, "run_tui": true, - "components": ["pkg", "core", "svc", "shell"], + "components": ["pkg", "core", "svc", "shell", "plymouth"], "desktop_environment": "hyprlua", "apps": ["firefox-browser", "vscodium", "docker"], "colors": { @@ -102,7 +103,7 @@ This dry-runs every installer dialog and saves your choices. **No software is in | `fido2_root` | bool | Enroll FIDO2 key for LUKS unlock | | `fido2_user` | bool | Enroll FIDO2 key for PAM login | | `run_tui` | bool | Run dotfiles setup automatically after base install | -| `components` | array | Dotfiles components to install | +| `components` | array | Dotfiles components to install (`"pkg"`, `"core"`, `"svc"`, `"shell"`, `"plymouth"`) | | `desktop_environment` | string | DE name or `"none"` | | `apps` | array | Optional app IDs (see [Modules](modules.md)) | | `colors` | object | Optional colour overrides (omit to keep defaults) | @@ -180,6 +181,8 @@ The backup key can be collected by Ansible — see [FreeIPA & Ansible](freeipa-a | LUKS + password | `base udev autodetect microcode modconf kms consolefont block encrypt lvm2 btrfs filesystems keyboard keymap fsck` | | LUKS + FIDO2 | `base udev systemd autodetect microcode modconf kms consolefont block sd-encrypt lvm2 btrfs filesystems keyboard keymap fsck` | +When Plymouth is enabled the installer automatically injects the appropriate hook (`plymouth` after `udev`, or `sd-plymouth` after `systemd`) and adds `quiet splash` to `GRUB_CMDLINE_LINUX_DEFAULT`. + --- ## Custom Live ISO diff --git a/docs/md/modules.md b/docs/md/modules.md index c257662..639d7db 100644 --- a/docs/md/modules.md +++ b/docs/md/modules.md @@ -47,6 +47,17 @@ Also deploys `greetd-tuigreet` config from the dotfiles. - **Yazi** file manager - Deploys `.bashrc`, `.zshrc`, `starship.toml`, Micro config, Neovim config +### `plymouth` — Boot Splash *(on by default)* + +Installs the **M-Archy Plymouth theme**: the skull logo (`resources/bg-skull.svg`) centred on a dark background with a 12-dot magenta spinner animation below it. + +- Converts the bundled SVG to PNG via `rsvg-convert` (Plymouth's image loader is PNG-only) +- Injects the `plymouth` or `sd-plymouth` mkinitcpio hook automatically (detects `udev` vs `systemd` hook set) +- Adds `quiet splash` to `GRUB_CMDLINE_LINUX_DEFAULT` and regenerates GRUB config +- Rebuilds the initramfs so the theme is baked in + +To install with a **custom image** on an existing system, use `install-modules.sh` and select *Plymouth (custom)* — you will be prompted for a PNG or SVG path. + --- ## Desktop Environments @@ -198,6 +209,8 @@ bash ~/Dotfiles/setup/install-modules.sh | ID | Packages | Description | |----|---------|-------------| +| `plymouth` | plymouth · librsvg | Boot splash (bundled skull logo + spinner) — same as the core component | +| `plymouth-custom` | plymouth · librsvg or imagemagick | Boot splash with a user-supplied image; prompts for a PNG or SVG path | | `tlp` | tlp · tlp-rdw | Laptop battery optimisation | | `zfs` | zfs-dkms | ZFS kernel module | | `wprs` | wprs-git (AUR) | Wayland proxy for remote sessions | diff --git a/setup/generate-answerfile.sh b/setup/generate-answerfile.sh index ba4a0d8..9b70f1d 100644 --- a/setup/generate-answerfile.sh +++ b/setup/generate-answerfile.sh @@ -191,11 +191,12 @@ if [[ "$AF_RUN_TUI" == "true" ]]; then # ── Components ──────────────────────────────────────────────────────────── AF_COMPONENTS=$(dialog --backtitle "$BACKTITLE" \ --title " Select Components " \ - --checklist "Space toggles · Enter confirms · Esc quits" 15 68 4 \ - "pkg" "Package managers yay · nvm · rust" on \ - "core" "Core packages 100+ base system packages" on \ - "svc" "Core services NetworkManager · cronie · fail2ban" on \ - "shell" "Shell setup zsh · nvim · yazi · micro · starship" on \ + --checklist "Space toggles · Enter confirms · Esc quits" 16 68 5 \ + "pkg" "Package managers yay · nvm · rust" on \ + "core" "Core packages 100+ base system packages" on \ + "svc" "Core services NetworkManager · cronie · fail2ban" on \ + "shell" "Shell setup zsh · nvim · yazi · micro · starship" on \ + "plymouth" "Plymouth boot splash — skull logo + spinner" on \ 3>&1 1>&2 2>&3) || AF_COMPONENTS="" # ── DE ──────────────────────────────────────────────────────────────────── diff --git a/setup/install-modules.sh b/setup/install-modules.sh index 53b7e57..090dac8 100755 --- a/setup/install-modules.sh +++ b/setup/install-modules.sh @@ -111,7 +111,8 @@ count_steps() { [[ "$sel" == *"ffmpeg"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"localtunnel"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"butter"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$sel" == *"plymouth"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$sel" == *"plymouth"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$sel" == *"plymouth-custom"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"tlp"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"steam"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"vesktop"* ]] && TOTAL=$(( TOTAL + 1 )) @@ -209,6 +210,7 @@ SELECTED=$(dialog --backtitle "$BACKTITLE" \ "localtunnel" "LocalTunnel expose localhost via tunnel" off \ "butter" "butter btrfs snapshot backup (AUR)" off \ "plymouth" "Plymouth boot splash — skull logo + spinner" off \ + "plymouth-custom" "Plymouth (custom) boot splash — supply your own image" off \ "tlp" "TLP laptop power management" off \ \ "steam" "Steam gaming platform" off \ @@ -253,6 +255,26 @@ SELECTED=$(dialog --backtitle "$BACKTITLE" \ [[ -z "$SELECTED" ]] && { clear; echo "Nothing selected."; exit 0; } +# ── Plymouth custom logo ─────────────────────────────────────────────────────── +# Ask for image path now (before the confirmation dialog) so it can appear in +# the summary. The path is exported and picked up by plymouth-custom.sh. +PLYMOUTH_LOGO_SRC="" +if [[ "$SELECTED" == *"plymouth-custom"* ]]; then + PLYMOUTH_LOGO_SRC=$(dialog --backtitle "$BACKTITLE" \ + --title " Plymouth — Custom Logo " \ + --inputbox "\n Path to the image to display during boot.\n\n PNG → used as-is (must already be the right size)\n SVG → converted to PNG automatically via rsvg-convert\n\n Leave blank to use a transparent placeholder.\n" \ + 13 66 "" \ + 3>&1 1>&2 2>&3) || PLYMOUTH_LOGO_SRC="" + + if [[ -n "$PLYMOUTH_LOGO_SRC" && ! -f "$PLYMOUTH_LOGO_SRC" ]]; then + dialog --backtitle "$BACKTITLE" \ + --title " Warning " \ + --msgbox "\n File not found:\n $PLYMOUTH_LOGO_SRC\n\n A transparent placeholder will be used instead.\n" \ + 9 62 + PLYMOUTH_LOGO_SRC="" + fi +fi + SUMMARY="" [[ "$SELECTED" == *"kde-plasma"* ]] && SUMMARY+=" ✦ KDE Plasma\n" [[ "$SELECTED" == *"gnome"* ]] && SUMMARY+=" ✦ GNOME\n" @@ -281,7 +303,14 @@ SUMMARY="" [[ "$SELECTED" == *"ffmpeg"* ]] && SUMMARY+=" ✦ FFmpeg extras\n" [[ "$SELECTED" == *"localtunnel"* ]] && SUMMARY+=" ✦ LocalTunnel\n" [[ "$SELECTED" == *"butter"* ]] && SUMMARY+=" ✦ butter (btrfs backup)\n" -[[ "$SELECTED" == *"plymouth"* ]] && SUMMARY+=" ✦ Plymouth boot splash\n" +[[ "$SELECTED" == *"plymouth"* ]] && SUMMARY+=" ✦ Plymouth boot splash\n" +if [[ "$SELECTED" == *"plymouth-custom"* ]]; then + if [[ -n "$PLYMOUTH_LOGO_SRC" ]]; then + SUMMARY+=" ✦ Plymouth (custom logo: $PLYMOUTH_LOGO_SRC)\n" + else + SUMMARY+=" ✦ Plymouth (custom logo: placeholder — no file given)\n" + fi +fi [[ "$SELECTED" == *"tlp"* ]] && SUMMARY+=" ✦ TLP\n" [[ "$SELECTED" == *"steam"* ]] && SUMMARY+=" ✦ Steam\n" [[ "$SELECTED" == *"vesktop"* ]] && SUMMARY+=" ✦ Vesktop\n" @@ -355,7 +384,11 @@ DE_DIR="$MODULES/Desktop-Environments" [[ "$SELECTED" == *"ffmpeg"* ]] && run_module "FFmpeg extras" "$APPS/ffmpeg.sh" [[ "$SELECTED" == *"localtunnel"* ]] && run_module "LocalTunnel" "$APPS/localtunnel.sh" [[ "$SELECTED" == *"butter"* ]] && run_module "butter" "$APPS/butter.sh" -[[ "$SELECTED" == *"plymouth"* ]] && run_module "Plymouth" "$MODULES/optional-Modules/plymouth.sh" +[[ "$SELECTED" == *"plymouth"* ]] && run_module "Plymouth" "$MODULES/optional-Modules/plymouth.sh" +if [[ "$SELECTED" == *"plymouth-custom"* ]]; then + export PLYMOUTH_LOGO_SRC + run_module "Plymouth (custom)" "$APPS/plymouth-custom.sh" +fi [[ "$SELECTED" == *"tlp"* ]] && run_module "TLP" "$APPS/tlp.sh" [[ "$SELECTED" == *"steam"* ]] && run_module "Steam" "$APPS/steam.sh" [[ "$SELECTED" == *"vesktop"* ]] && run_module "Vesktop" "$APPS/vesktop.sh" diff --git a/setup/modules/optional-Modules/apps/plymouth-custom.sh b/setup/modules/optional-Modules/apps/plymouth-custom.sh new file mode 100644 index 0000000..e84957d --- /dev/null +++ b/setup/modules/optional-Modules/apps/plymouth-custom.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# plymouth-custom.sh — Plymouth boot splash with user-supplied logo +# +# Called by install-modules.sh with PLYMOUTH_LOGO_SRC already exported. +# Validates the path then delegates all installation work to plymouth.sh. +# Supports PNG (used as-is) and SVG (converted via rsvg-convert). + +set -euo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh" + +if [[ -z "${PLYMOUTH_LOGO_SRC:-}" ]]; then + err "PLYMOUTH_LOGO_SRC is not set — cannot install custom Plymouth theme." + exit 1 +fi +if [[ ! -f "$PLYMOUTH_LOGO_SRC" ]]; then + err "Logo file not found: $PLYMOUTH_LOGO_SRC" + exit 1 +fi + +log "Custom Plymouth logo: $PLYMOUTH_LOGO_SRC" +export PLYMOUTH_LOGO_SRC +exec bash "$(dirname "${BASH_SOURCE[0]}")/../plymouth.sh" diff --git a/setup/modules/optional-Modules/plymouth.sh b/setup/modules/optional-Modules/plymouth.sh index 3d64638..09229c6 100644 --- a/setup/modules/optional-Modules/plymouth.sh +++ b/setup/modules/optional-Modules/plymouth.sh @@ -9,14 +9,17 @@ # even commented "png file loader". bg-skull.svg must be converted to PNG with # rsvg-convert (higher fidelity than ImageMagick for SVG) before deployment. # -# Logo resolution order (no user intervention required): -# 1. $DOTFILES_DIR/resources/bg-skull.svg — repo copy, always present -# 2. /root/installer/resources/bg-skull.svg — archiso embedded copy +# Logo resolution order: +# 1. $PLYMOUTH_LOGO_SRC env var — caller-supplied custom image (PNG or SVG) +# 2. $DOTFILES_DIR/resources/bg-skull.svg — repo copy, always present +# 3. /root/installer/resources/bg-skull.svg — archiso embedded copy +# +# PNG inputs are used directly; SVG inputs are converted via rsvg-convert. # # Steps: # 1. Install plymouth (extra repo) -# 2. Install librsvg (rsvg-convert) + imagemagick if absent -# 3. Convert bg-skull.svg → logo.png (300 px wide) +# 2. Install librsvg (rsvg-convert) if logo is SVG; imagemagick for dot +# 3. Produce logo.png (300 px wide) from the resolved source # 4. Generate a 10×10 magenta dot.png for the spinner # 5. Write the m-archy theme (.plymouth descriptor + .script animation) # 6. Register with plymouth-set-default-theme @@ -31,44 +34,51 @@ THEME_DIR="/usr/share/plymouth/themes/m-archy" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOTFILES_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)" -# Resolve logo SVG — repo copy first, ISO embedded copy as fallback -LOGO_SVG="" -for _candidate in \ - "$DOTFILES_DIR/resources/bg-skull.svg" \ - "/root/installer/resources/bg-skull.svg" -do - if [[ -f "$_candidate" ]]; then - LOGO_SVG="$_candidate" - break - fi -done +# Resolve logo source — env var takes priority, then bundled SVG +LOGO_SRC="${PLYMOUTH_LOGO_SRC:-}" +if [[ -z "$LOGO_SRC" ]]; then + for _candidate in \ + "$DOTFILES_DIR/resources/bg-skull.svg" \ + "/root/installer/resources/bg-skull.svg" + do + if [[ -f "$_candidate" ]]; then + LOGO_SRC="$_candidate" + break + fi + done +fi # ── Install Plymouth ────────────────────────────────────────────────────────── log "Installing Plymouth..." sudo pacman -S --noconfirm --needed plymouth # ── Ensure conversion tools ─────────────────────────────────────────────────── -# Plymouth only loads PNG (libpng); rsvg-convert gives the best SVG→PNG output. -if ! command -v rsvg-convert &>/dev/null; then - log "Installing librsvg (rsvg-convert) for SVG→PNG conversion..." - sudo pacman -S --noconfirm --needed librsvg -fi +# imagemagick is always needed for the spinner dot. +# librsvg (rsvg-convert) is only needed when the logo source is an SVG. if ! command -v convert &>/dev/null; then log "Installing imagemagick (dot generation)..." sudo pacman -S --noconfirm --needed imagemagick fi -# ── Convert logo SVG → PNG ──────────────────────────────────────────────────── +# ── Produce logo.png ────────────────────────────────────────────────────────── TMP_LOGO="$(mktemp /tmp/plymouth-logo.XXXXXX.png)" TMP_DOT="/tmp/plymouth-dot.png" trap 'rm -f "$TMP_LOGO" "$TMP_DOT"' EXIT -if [[ -n "$LOGO_SVG" ]]; then - log "Converting $LOGO_SVG → PNG (300 px wide)..." - rsvg-convert -w 300 "$LOGO_SVG" -o "$TMP_LOGO" -else - warn "bg-skull.svg not found in repo resources or ISO — using transparent placeholder." +if [[ -z "$LOGO_SRC" ]]; then + warn "No logo source found — using transparent placeholder." convert -size 300x300 xc:transparent "$TMP_LOGO" +elif [[ "${LOGO_SRC,,}" == *.png ]]; then + log "Using PNG directly: $LOGO_SRC" + cp "$LOGO_SRC" "$TMP_LOGO" +else + # SVG (or unknown) — convert via rsvg-convert for best fidelity + if ! command -v rsvg-convert &>/dev/null; then + log "Installing librsvg (rsvg-convert) for SVG→PNG conversion..." + sudo pacman -S --noconfirm --needed librsvg + fi + log "Converting $LOGO_SRC → PNG (300 px wide)..." + rsvg-convert -w 300 "$LOGO_SRC" -o "$TMP_LOGO" fi # ── Generate spinner dot ──────────────────────────────────────────────────────