Dotfiles/setup/tools/migrate-to-lightdm.sh

215 lines
9.6 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# migrate-to-lightdm.sh — switch an existing install to Plymouth + LightDM
# =============================================================================
# Migrates a machine that currently boots ly / greetd / GDM / SDDM / LXDM (or any
# other display manager) to this repo's boot experience:
#
# Plymouth skull splash → LightDM + lightdm-gtk-greeter (cyberqueer theme)
#
# What it does:
# 1. Detects the currently-configured display manager(s).
# 2. Disables every known greeter EXCEPT lightdm — for the NEXT boot only. It
# does NOT stop your running session, so you stay logged in until you
# reboot yourself.
# 3. Runs the lightdm module (installs LightDM + lightdm-gtk-greeter, deploys
# the cyberqueer greeter config + skull background, enables lightdm.service).
# 4. Purges obsolete Plymouth artifacts left by earlier versions of this repo
# (e.g. the spinner's dot.png) so an upgraded install ends up byte-clean.
# 5. Runs the plymouth module (skull splash, initramfs + GRUB cmdline) unless
# --no-plymouth is given.
#
# 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.
#
# Double duty: on a machine that is ALREADY on Plymouth + LightDM (an install
# migrated by an earlier version of this repo) re-running simply refreshes the
# greeter config and re-installs the current Plymouth theme — the clean upgrade
# path from the old full-screen-skull + spinner splash to the centred-skull +
# boot-log-tail one.
#
# Safe to re-run (idempotent). Reboot to complete the switch.
#
# Usage:
# migrate-to-lightdm.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-lightdm.sh — switch this machine to Plymouth + LightDM (cyberqueer)
Disables the current display manager (ly / greetd / GDM / SDDM / LXDM / …) for
the next boot, installs and themes LightDM, and sets up the Plymouth splash. Your
running session is left untouched; reboot to complete the switch.
Usage:
migrate-to-lightdm.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. lightdm is the TARGET,
# so it never appears here. ly is a template unit (ly@tty1) but some setups use
# the plain ly.service alias, so both are listed.
OTHER_DMS=(
"ly@tty1.service" "ly.service"
"greetd.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.
lightdm_state="$(systemctl is-enabled lightdm.service 2>/dev/null || true)"
[[ -z "$lightdm_state" || "$lightdm_state" == "not-found" ]] && lightdm_state="not-installed"
echo
echo " Current display-manager.service : ${primary_dm:-<none>}"
if (( ${#enabled_dms[@]} )); then
echo " Enabled greeter units : ${enabled_dms[*]}"
else
echo " Enabled greeter units : <none detected>"
fi
echo " lightdm.service : $lightdm_state"
echo " Plymouth migration : $( ((DO_PLYMOUTH)) && echo 'yes' || echo 'skipped (--no-plymouth)')"
echo
if (( ${#enabled_dms[@]} == 0 )) && [[ "$lightdm_state" == "enabled" ]]; then
log "LightDM already appears to be the active greeter — re-running to refresh config/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 + LightDM 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;
# lightdm.service (enabled below) 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 LightDM (delegated to the module) ─────────────
# lightdm.sh installs LightDM + the GTK greeter, deploys the cyberqueer greeter
# config + skull background, disables greetd/ly@tty1/getty@tty1, and enables
# lightdm.service. Running it here keeps a single source of truth.
log "Setting up LightDM via the lightdm module..."
run bash "$APPS/lightdm.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 LightDM cyberqueer greeter."
fi