#!/bin/bash # ============================================================================= # migrate-to-greetd.sh — switch an existing install to Plymouth + greetd/ReGreet # ============================================================================= # Migrates a machine that currently boots lightdm / ly / GDM / SDDM / LXDM (or a # bare greetd+tuigreet) to this repo's current default boot experience: # # Plymouth skull splash → greetd + ReGreet + cage (Wayland-native, # cyberqueer-themed graphical greeter) # # This is the Wayland counterpart to migrate-to-lightdm.sh. ReGreet runs on # wlroots (inside a cage kiosk), so it drives every output natively (no blank # monitor) and hands input straight to the Wayland session with no Xorg→Wayland # VT handover race — the reason The-Core moved off the LightDM (Xorg) greeter. # # What it does: # 1. Detects the currently-configured display manager(s). # 2. Disables every known greeter EXCEPT greetd — for the NEXT boot only. It # does NOT stop your running session, so you stay logged in until you # reboot yourself. # 3. Runs the greetd-regreet module (installs greetd + greetd-regreet + cage, # deploys the greetd/ReGreet config, the cyberqueer regreet.css skin, the # skull fallback background + wallpaper-sync units, sets up PAM/FIDO, # disables lightdm/ly@tty1/getty@tty1, and enables greetd.service). # 4. Runs the plymouth module (skull splash, initramfs + GRUB cmdline) unless # --no-plymouth is given. # # greetd.service is the TARGET, so it is never disabled here: a machine already # on a bare greetd+tuigreet is simply reconfigured to run ReGreet instead. # # It reuses the real module scripts under optional-Modules/apps/ so there is no # duplicated install logic — this tool only handles detection, teardown of the # OLD display manager, and orchestration. # # Safe to re-run (idempotent). Reboot to complete the switch. # # Usage: # migrate-to-greetd.sh [--yes] [--no-plymouth] [--dry-run] [--help] # -y, --yes Skip the confirmation prompt (required for non-TTY runs) # --no-plymouth Migrate the display manager only; leave Plymouth alone # -n, --dry-run Print what would happen; change nothing # -h, --help Show this help and exit # ============================================================================= set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SETUP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" APPS="$SETUP_DIR/modules/optional-Modules/apps" # Shared helpers: log / skip / warn / err, and best-effort disable_service. source "$SETUP_DIR/modules/lib/logging.sh" # ── Argument parsing ────────────────────────────────────────────────────────── ASSUME_YES=0 DO_PLYMOUTH=1 DRY_RUN=0 usage() { cat <<'EOF' migrate-to-greetd.sh — switch this machine to Plymouth + greetd/ReGreet (cyberqueer) Disables the current display manager (lightdm / ly / GDM / SDDM / LXDM / …) for the next boot, installs and themes the greetd + ReGreet (Wayland) greeter, and sets up the Plymouth splash. Your running session is left untouched; reboot to complete the switch. Usage: migrate-to-greetd.sh [--yes] [--no-plymouth] [--dry-run] [--help] -y, --yes Skip the confirmation prompt (required for non-TTY runs) --no-plymouth Migrate the display manager only; leave Plymouth alone -n, --dry-run Print what would happen; change nothing -h, --help Show this help and exit EOF } while [[ $# -gt 0 ]]; do case "$1" in -y|--yes) ASSUME_YES=1 ;; --no-plymouth) DO_PLYMOUTH=0 ;; -n|--dry-run) DRY_RUN=1 ;; -h|--help) usage; exit 0 ;; *) err "Unknown argument: $1"; echo "Try --help." >&2; exit 2 ;; esac shift done # In dry-run, describe an action instead of doing it. In real mode, run it. run() { if (( DRY_RUN )); then printf '[dry-run] would run: %s\n' "$*" else "$@" fi } # ── Known display managers ──────────────────────────────────────────────────── # Every greeter/DM unit this tool knows how to turn off. greetd is the TARGET, # so it never appears here (a bare greetd+tuigreet install is reconfigured, not # disabled). ly is a template unit (ly@tty1) but some setups use the plain # ly.service alias, so both are listed. OTHER_DMS=( "lightdm.service" "ly@tty1.service" "ly.service" "gdm.service" "gdm3.service" "sddm.service" "lxdm.service" "xdm.service" "slim.service" "lemurs.service" "emptty.service" ) # ── 1. Detect what is configured now ────────────────────────────────────────── log "Detecting the current display manager configuration..." # The canonical "which DM boots" pointer is the display-manager.service symlink. # Use plain readlink to get the intended target name even if the link is broken; # a self-referential/absent target means no real DM is configured there. primary_dm="" if dm_link="$(readlink /etc/systemd/system/display-manager.service 2>/dev/null)"; then dm_link="$(basename "$dm_link")" [[ "$dm_link" != "display-manager.service" ]] && primary_dm="$dm_link" fi # Also probe every known unit directly — ly-based installs often have no # display-manager.service symlink, they just enable ly@tty1 on tty1. enabled_dms=() for unit in "${OTHER_DMS[@]}"; do state="$(systemctl is-enabled "$unit" 2>/dev/null || true)" [[ "$state" == "enabled" || "$state" == "alias" || "$state" == "enabled-runtime" ]] \ && enabled_dms+=("$unit") done # `is-enabled` on an absent unit both prints "not-found" and exits non-zero; # capture with `|| true` (never `|| echo`, which would concatenate two lines) # and normalise the "not installed" cases to one label. greetd_state="$(systemctl is-enabled greetd.service 2>/dev/null || true)" [[ -z "$greetd_state" || "$greetd_state" == "not-found" ]] && greetd_state="not-installed" echo echo " Current display-manager.service : ${primary_dm:-}" if (( ${#enabled_dms[@]} )); then echo " Enabled greeter units : ${enabled_dms[*]}" else echo " Enabled greeter units : " fi echo " greetd.service : $greetd_state" echo " Plymouth migration : $( ((DO_PLYMOUTH)) && echo 'yes' || echo 'skipped (--no-plymouth)')" echo if (( ${#enabled_dms[@]} == 0 )) && [[ "$greetd_state" == "enabled" ]]; then log "greetd already appears to be the active greeter — re-running to install/refresh ReGreet + theme." fi # ── 2. Confirm ──────────────────────────────────────────────────────────────── # This changes what greets you at the NEXT boot. Require an explicit yes unless # --yes was given; on a non-interactive stdin, --yes is mandatory. if (( ! ASSUME_YES )); then if [[ ! -t 0 ]]; then err "Non-interactive shell and --yes not given — refusing to change the display manager." exit 1 fi read -r -p "Switch this machine to Plymouth + greetd/ReGreet as described above? [y/N] " reply case "$reply" in y|Y|yes|YES) ;; *) warn "Aborted — nothing changed."; exit 0 ;; esac fi # ── 3. Disable the OLD display managers (next boot only) ────────────────────── # We intentionally do NOT `systemctl stop` the running greeter: that would kill # your current graphical session. Disabling only removes it from the next boot; # greetd.service (enabled below by the module) takes over then. if (( ${#enabled_dms[@]} )); then log "Disabling old display manager(s) for the next boot: ${enabled_dms[*]}" for unit in "${enabled_dms[@]}"; do run disable_service "$unit" done else skip "No competing display managers enabled — nothing to disable." fi # ── 4. Install + theme + enable greetd/ReGreet (delegated to the module) ────── # greetd-regreet.sh installs greetd + greetd-regreet + cage, deploys the greetd # config + ReGreet config + cyberqueer regreet.css skin + skull background, # wires up PAM/FIDO and the wallpaper-sync units, disables lightdm/ly@tty1/ # getty@tty1, and enables greetd.service. Running it here keeps a single source # of truth. log "Setting up greetd + ReGreet via the greetd-regreet module..." run bash "$APPS/greetd-regreet.sh" # ── 5. Plymouth splash (delegated to the module) ────────────────────────────── if (( DO_PLYMOUTH )); then # Upgrade cleanup: the current theme is a centred skull + boot-log tail. The # previous version scaled the skull full-screen and drew a spinning-dot # throbber from dot.png. That file is now dead weight — strip it (and any # other stale theme assets) BEFORE re-running the module, so it is neither # rendered nor baked into the initramfs that plymouth.sh rebuilds. THEME_DIR="/usr/share/plymouth/themes/m-archy" for stale in "$THEME_DIR/dot.png"; do if [[ -e "$stale" ]]; then log "Removing obsolete Plymouth asset: $stale" run sudo rm -f "$stale" fi done log "Setting up the Plymouth splash via the plymouth module..." run bash "$APPS/plymouth.sh" else skip "Skipping Plymouth setup (--no-plymouth)." fi # ── Done ────────────────────────────────────────────────────────────────────── echo if (( DRY_RUN )); then log "Dry run complete — no changes were made." else log "Migration complete. Your current session is untouched." log "Reboot to boot into the Plymouth splash and the greetd/ReGreet cyberqueer greeter." fi