Update script version to 4.9 and enhance error handling

This commit is contained in:
LINUXexpert.org
2026-01-26 12:51:55 -07:00
committed by GitHub
parent 53569075a2
commit 6f354a5da7
+71 -49
View File
@@ -20,7 +20,7 @@ set -euo pipefail
# =========================
# Version
# =========================
SCRIPT_VERSION="4.8"
SCRIPT_VERSION="4.9"
# =========================
# Globals / Defaults
@@ -58,6 +58,16 @@ SYSTEM_KEYRING="/usr/share/keyrings/linuxmint-repo.gpg"
# Error handling
ON_ERROR_BACKUP_HINT=""
on_err() {
local rc=$?
local line="${BASH_LINENO[0]:-unknown}"
echo "ERROR: FAILED at line ${line} (exit ${rc})."
echo "ERROR: Command: ${BASH_COMMAND}"
[[ -n "${ON_ERROR_BACKUP_HINT:-}" ]] && echo "${ON_ERROR_BACKUP_HINT}"
exit "$rc"
}
trap on_err ERR
# =========================
# Pretty output
# =========================
@@ -100,7 +110,7 @@ Usage (command-first):
sudo bash $0 convert --i-accept-the-risk [options]
sudo bash $0 rollback /root/ubuntu-to-mint-backup-YYYYMMDD-HHMMSS
Usage (options-first ALSO supported in v${SCRIPT_VERSION}):
Usage (options-first ALSO supported):
sudo bash $0 [options] doctor
sudo bash $0 [options] plan
sudo bash $0 [options] convert --i-accept-the-risk
@@ -264,7 +274,7 @@ timeshift_snapshot_best_effort() {
}
# =========================
# Mint repo key bootstrap (no keyservers)
# Keyrings
# =========================
gpg_key_file_has_keyid() {
local f="$1"
@@ -272,6 +282,16 @@ gpg_key_file_has_keyid() {
gpg --batch --with-colons --show-keys "$f" 2>/dev/null | awk -F: '$1=="pub"||$1=="sub"{print toupper($5)}' | grep -qx "$(echo "$keyid" | tr '[:lower:]' '[:upper:]')"
}
ubuntu_archive_keyring_path() {
# Needed for plan mode temp APT root signature verification.
DEBIAN_FRONTEND=noninteractive apt-get install -y ubuntu-keyring >/dev/null 2>&1 || true
if [[ -r /usr/share/keyrings/ubuntu-archive-keyring.gpg ]]; then
echo "/usr/share/keyrings/ubuntu-archive-keyring.gpg"
return 0
fi
die "Ubuntu archive keyring not found at /usr/share/keyrings/ubuntu-archive-keyring.gpg (install ubuntu-keyring?)"
}
mint_keyring_build_from_linuxmint_keyring_deb() {
local out_keyring="$1"
[[ -n "$out_keyring" ]] || die "mint_keyring_build_from_linuxmint_keyring_deb: missing output path"
@@ -346,7 +366,7 @@ mint_keyring_build_from_linuxmint_keyring_deb() {
info "Using key candidate: $chosen"
if [[ "$chosen" == *.asc || "$chosen" == *.key ]]; then
grep -q "BEGIN PGP PUBLIC KEY BLOCK" "$chosen" 2>/dev/null || { rm -rf "$tmpdir"; die "Selected key candidate is not armored PGP: $chosen"; }
gpg --batch --dearmor -o "$tmp_out" "$chosen" || { rm -rf "$tmpdir"; die "gpg dearmor failed for key candidate"; }
gpg --batch --dearmor -o "$tmp_out" "$chosen"
else
cp -a "$chosen" "$tmp_out"
fi
@@ -408,7 +428,9 @@ detect_ubuntu_mirrors() {
write_mint_sources_system() {
local list="/etc/apt/sources.list.d/official-package-repositories.list"
local keyring="$SYSTEM_KEYRING"
local mint_keyring="$SYSTEM_KEYRING"
local ubuntu_keyring
ubuntu_keyring="$(ubuntu_archive_keyring_path)"
detect_ubuntu_mirrors
@@ -418,13 +440,13 @@ write_mint_sources_system() {
# Generated by ubuntu-to-mint-convert-v3.sh on $(date -Is)
#
# Linux Mint repository:
deb [signed-by=${keyring}] ${MINT_MIRROR%/} ${TARGET_MINT} main upstream import backport
deb [signed-by=${mint_keyring}] ${MINT_MIRROR%/} ${TARGET_MINT} main upstream import backport
# Ubuntu base repositories:
deb ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE} main restricted universe multiverse
deb ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE}-updates main restricted universe multiverse
deb ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE}-backports main restricted universe multiverse
deb ${UBUNTU_SECURITY_MIRROR%/} ${UBUNTU_BASE}-security main restricted universe multiverse
deb [signed-by=${ubuntu_keyring}] ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE} main restricted universe multiverse
deb [signed-by=${ubuntu_keyring}] ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE}-updates main restricted universe multiverse
deb [signed-by=${ubuntu_keyring}] ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE}-backports main restricted universe multiverse
deb [signed-by=${ubuntu_keyring}] ${UBUNTU_SECURITY_MIRROR%/} ${UBUNTU_BASE}-security main restricted universe multiverse
EOF
if [[ -f /etc/apt/sources.list ]]; then
@@ -490,7 +512,6 @@ session_name_for_edition() {
}
ensure_lightdm_on_boot() {
# Make LightDM the default display manager and ensure graphical boot.
if [[ ! -d /run/systemd/system ]]; then
warn "systemd not detected; cannot enable LightDM on boot in this environment."
return 0
@@ -498,33 +519,23 @@ ensure_lightdm_on_boot() {
info "Ensuring LightDM starts on boot (graphical.target + default display manager)..."
# Unmask LightDM in case something previously masked it
systemctl unmask lightdm >/dev/null 2>&1 || true
# Ensure the default DM marker is LightDM
echo "/usr/sbin/lightdm" > /etc/X11/default-display-manager || true
# Debian/Ubuntu DM selection often uses update-alternatives
if have_cmd update-alternatives; then
update-alternatives --set x-display-manager /usr/sbin/lightdm >/dev/null 2>&1 || true
fi
# Ensure graphical boot target
systemctl set-default graphical.target >/dev/null 2>&1 || true
systemctl enable graphical.target >/dev/null 2>&1 || true
# Enable LightDM for boot
systemctl enable lightdm >/dev/null 2>&1 || true
# Prevent GDM from stealing the greeter
if systemctl list-unit-files | awk '{print $1}' | grep -qx 'gdm3.service'; then
systemctl disable --now gdm3 >/dev/null 2>&1 || true
systemctl mask gdm3 >/dev/null 2>&1 || true
fi
# Restart the active DM if we can
systemctl restart lightdm >/dev/null 2>&1 || true
ok "LightDM configured to start on boot."
}
@@ -533,21 +544,11 @@ ensure_lightdm_defaults() {
sess="$(session_name_for_edition)"
info "Configuring LightDM defaults for edition=${EDITION} (session=${sess})"
DEBIAN_FRONTEND=noninteractive apt-get install -y lightdm slick-greeter
# Keep Ubuntu's gdm3 installed (if present) but ensure it can't win.
if systemctl is-enabled gdm3 >/dev/null 2>&1; then
warn "Disabling gdm3 (keeping installed)."
systemctl disable --now gdm3 || true
systemctl mask gdm3 || true
if [[ -f /etc/gdm3/custom.conf ]]; then
sed -i 's/^[#[:space:]]*WaylandEnable=.*/WaylandEnable=false/' /etc/gdm3/custom.conf || true
grep -q '^WaylandEnable=' /etc/gdm3/custom.conf || echo 'WaylandEnable=false' >> /etc/gdm3/custom.conf
fi
fi
mkdir -p /etc/lightdm/lightdm.conf.d
# Comment out any existing user-session settings (keep files)
shopt -s nullglob
for f in /etc/lightdm/lightdm.conf.d/*.conf; do
[[ "$(basename "$f")" == "99-ubuntu2mint.conf" ]] && continue
@@ -596,9 +597,7 @@ EOF
chmod 644 "$dmrc" || true
done
# This is the baked-in boot behavior you asked for:
ensure_lightdm_on_boot
ok "LightDM defaults applied; default session set to ${sess}."
}
@@ -621,8 +620,7 @@ apply_mintupdate_icon_diversion() {
# Post-install sanity checks
# =========================
post_install_sanity() {
local out_file="$1"
[[ -n "$out_file" ]] || out_file="/tmp/post-convert-validation.txt"
local out_file="${1:-/tmp/post-convert-validation.txt}"
{
echo "Post-conversion validation ($(date -Is))"
@@ -650,7 +648,7 @@ post_install_sanity() {
}
# =========================
# Plan mode (temp APT root)
# Plan mode helpers
# =========================
apt_tmp_run() {
local tmpapt="$1"; shift
@@ -665,6 +663,24 @@ apt_tmp_run() {
apt-get "${extra[@]}" "$@"
}
plan_fix_tmpapt_perms() {
local tmpapt="$1"
# Allow _apt sandbox to traverse and write partial lists
chmod 755 "$tmpapt" || true
chmod 755 "$tmpapt"/{etc,usr,var} 2>/dev/null || true
chmod 755 "$tmpapt"/var/{lib,cache} 2>/dev/null || true
chmod 755 "$tmpapt"/var/lib/apt 2>/dev/null || true
chmod 755 "$tmpapt"/var/cache/apt 2>/dev/null || true
if id _apt >/dev/null 2>&1; then
chown -R _apt:root "$tmpapt/var/lib/apt/lists/partial" 2>/dev/null || true
chown -R _apt:root "$tmpapt/var/cache/apt/archives/partial" 2>/dev/null || true
chmod 755 "$tmpapt/var/lib/apt/lists/partial" 2>/dev/null || true
chmod 755 "$tmpapt/var/cache/apt/archives/partial" 2>/dev/null || true
fi
}
plan_mode() {
need_root
ensure_no_apt_locks
@@ -674,19 +690,29 @@ plan_mode() {
local tmpapt
tmpapt="$(mktemp -d)"
mkdir -p "${tmpapt}/etc/apt/sources.list.d" "${tmpapt}/etc/apt/preferences.d" "${tmpapt}/var/lib/apt/lists/partial" "${tmpapt}/var/cache/apt/archives/partial" "${tmpapt}/usr/share/keyrings"
mkdir -p "${tmpapt}/etc/apt/sources.list.d" \
"${tmpapt}/etc/apt/preferences.d" \
"${tmpapt}/var/lib/apt/lists/partial" \
"${tmpapt}/var/cache/apt/archives/partial" \
"${tmpapt}/usr/share/keyrings"
plan_fix_tmpapt_perms "$tmpapt"
local tmp_keyring="${tmpapt}/usr/share/keyrings/linuxmint-repo.gpg"
mint_keyring_build_from_linuxmint_keyring_deb "$tmp_keyring"
local ubuntu_keyring
ubuntu_keyring="$(ubuntu_archive_keyring_path)"
detect_ubuntu_mirrors
cat > "${tmpapt}/etc/apt/sources.list" <<EOF
deb [signed-by=${tmp_keyring}] ${MINT_MIRROR%/} ${TARGET_MINT} main upstream import backport
deb ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE} main restricted universe multiverse
deb ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE}-updates main restricted universe multiverse
deb ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE}-backports main restricted universe multiverse
deb ${UBUNTU_SECURITY_MIRROR%/} ${UBUNTU_BASE}-security main restricted universe multiverse
deb [signed-by=${ubuntu_keyring}] ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE} main restricted universe multiverse
deb [signed-by=${ubuntu_keyring}] ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE}-updates main restricted universe multiverse
deb [signed-by=${ubuntu_keyring}] ${UBUNTU_ARCHIVE_MIRROR%/} ${UBUNTU_BASE}-backports main restricted universe multiverse
deb [signed-by=${ubuntu_keyring}] ${UBUNTU_SECURITY_MIRROR%/} ${UBUNTU_BASE}-security main restricted universe multiverse
EOF
cat > "${tmpapt}/etc/apt/preferences.d/50-linuxmint-conversion.pref" <<'EOF'
@@ -723,14 +749,14 @@ EOF
local rc=${PIPESTATUS[0]}
set -e
rm -rf "$tmpapt"
if [[ $rc -ne 0 ]]; then
warn "Plan simulation failed (exit $rc). Review: $plan_out"
rm -rf "$tmpapt"
exit $rc
fi
ok "Plan completed successfully. Review: $plan_out"
rm -rf "$tmpapt"
}
# =========================
@@ -829,10 +855,6 @@ convert() {
info "Reinstalling x11-common (fixes Xsession has_option issues)..."
DEBIAN_FRONTEND=noninteractive apt-get $(apt_opts_common) install --reinstall x11-common || true
info "Ensuring GNOME RandR runtime libs present (best-effort)..."
DEBIAN_FRONTEND=noninteractive apt-get $(apt_opts_common) install \
libgnome-rr-4-2t64 libgnome-desktop-4-2t64 libgnome-bg-4-2t64 || true
ensure_lightdm_defaults
mkdir -p "$backup_dir"