#!/bin/bash { # Import DietPi-Globals --------------------------------------------------------------- . /boot/dietpi/func/dietpi-globals readonly G_PROGRAM_NAME='dietpi-trixie-upgrade' [[ $G_DISTRO == [78] ]] || { G_DIETPI-NOTIFY 1 'You must run a Debian Bookworm system to run this script!'; exit 1; } (( $G_HW_ARCH < 3 )) && dpkg --compare-versions "$(uname -r)" lt-nl 5.6 && { G_DIETPI-NOTIFY 1 '32-bit systems with Linux older than 5.6 cannot run Debian Trixie, due to missing time64 syscall support. Please upgrade your kernel to run this script!'; exit 1; } G_CHECK_ROOT_USER "$@" G_CHECK_ROOTFS_RW G_INIT # Import DietPi-Globals --------------------------------------------------------------- # Warn about incompatible installed software titles alist=() while read -r id do case $id in 22) alist+=('QuiteRSS');; 65) alist+=('Netdata');; 111) (( $G_HW_ARCH == 3 )) || alist+=('UrBackup');; 116) alist+=('Medusa');; 124) (( $G_HW_ARCH < 3 )) && alist+=('NAA Daemon');; 148) (( $G_HW_ARCH == 1 )) && alist+=('myMPD');; 178) (( $G_HW_ARCH < 3 )) && alist+=('Jellyfin');; 194) (( $G_HW_ARCH < 3 )) && alist+=('PostgreSQL');; 207) (( $G_HW_ARCH < 3 )) && alist+=('Moonlight (CLI)');; 208) (( $G_HW_ARCH < 3 )) && alist+=('Moonlight (GUI)');; *) :;; esac done < <(sed -nE 's/^aSOFTWARE_INSTALL_STATE\[([0-9]+)\]=2$/\1/p' /boot/dietpi/.installed) (( ! ${#alist[@]} )) || G_WHIP_BUTTON_OK_TEXT='Continue' G_WHIP_BUTTON_CANCEL_TEXT='Exit' G_WHIP_YESNO "[WARNING] Incompatible software titles found \nThe following installed software titles are not (yet) compatible with Debian Trixie on your system: ${alist[*]} \nDo you want to continue regardless?\n" || exit 0 # Offer a backup before doing any changes to the system G_PROMPT_BACKUP # Prevent Docker Compose conflict if dpkg-query -s 'docker-compose-plugin' &> /dev/null && dpkg-query -s 'docker-compose' &> /dev/null then G_DIETPI-NOTIFY 2 'Purge obsolete docker-compose package from Debian repo, since docker-compose-plugin from Docker repo is installed already, and both conflict on Trixie' G_AGP docker-compose fi if grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[130\]=2' /boot/dietpi/.installed then G_DIETPI-NOTIFY 2 'Allow Python 3 pip, setuptools, and wheel APT packages autoremoval, which conflict with the Python 3 pip installation of DietPi' # shellcheck disable=SC2046 apt-mark auto $(dpkg --get-selections python3-{pip,setuptools,wheel} 2> /dev/null | mawk '{print $1}') 2> /dev/null fi if [[ -f '/etc/apt/trusted.gpg' ]] then G_DIETPI-NOTIFY 2 'Removing /etc/apt/trusted.gpg, deprecated since Bookworm and obsolete since Trixie' G_EXEC rm /etc/apt/trusted.gpg fi G_DIETPI-NOTIFY 2 'Upgrading APT packages to latest versions provided by Debian Bookworm' /boot/dietpi/dietpi-services stop G_AGUP G_AGDUG G_AGA G_CHECK_KERNEL || { G_WHIP_YESNO '[ INFO ] Reboot required, then rerun this script \nYour system needs to be rebootet to apply a recent kernel upgrade. Please do this first and then rerun this script to proceed with the Trixie upgrade. \nShall we reboot your system now?' && reboot; exit 0; } G_DIETPI-NOTIFY 2 'Updating DietPi to latest version' /boot/dietpi/dietpi-update 1 mapfile -t apackages < <(apt-mark showhold) [[ ${apackages[0]} ]] && G_EXEC_DESC='Unholding all packages' G_EXEC apt-mark unhold "${apackages[@]}" unset -v apackages G_DIETPI-NOTIFY 2 'Migrating package lists to Trixie suite' G_EXEC sed --follow-symlinks -i 's/bookworm/trixie/g' /etc/apt/sources.list # Remove obsolete lists, including those obsoleted with Bookworm G_EXEC rm -f /etc/apt/sources.list.d/dietpi-{mono,mosquitto,wsdd}.list /etc/apt/trusted.gpg.d/dietpi-{mono,mosquitto,wsdd}.gpg for i in /etc/apt/sources.list.d/*.list do [[ $i == '/etc/apt/sources.list.d/*.list' ]] && break G_EXEC sed --follow-symlinks -i 's/bookworm/trixie/g' "$i" G_EXEC sed --follow-symlinks -i '/download\.opensuse\.org/s/Debian_12/Debian_13/' "$i" #G_EXEC sed --follow-symlinks -i '/download\.opensuse\.org/s/Raspbian_12/Raspbian_13/' "$i" done G_DIETPI-NOTIFY 2 'Reverting some package lists to Bookworm which have no Trixie suite (yet)' [[ -f '/etc/apt/sources.list.d/dietpi-influxdb.list' ]] && G_EXEC sed --follow-symlinks -i 's/trixie/bookworm/g' /etc/apt/sources.list.d/dietpi-influxdb.list [[ $G_RASPBIAN == 1 && -f '/etc/apt/sources.list.d/docker.list' ]] && G_EXEC sed --follow-symlinks -i 's/trixie/bookworm/g' /etc/apt/sources.list.d/docker.list [[ -f '/etc/apt/sources.list.d/dietpi-moonlight.list' ]] && G_EXEC sed --follow-symlinks -i 's/trixie/bookworm/g' /etc/apt/sources.list.d/dietpi-moonlight.list if [[ $G_HW_ARCH != 1 ]] then G_DIETPI-NOTIFY 2 'Removing obsolete APT pinnings' [[ -f '/etc/apt/preferences.d/dietpi-openhab' ]] && G_EXEC rm /etc/apt/preferences.d/dietpi-openhab fi if dpkg --compare-versions "$(dpkg-query -Wf '${Version}' syncplay-server 2> /dev/null)" lt-nl '1.7.4+repack1-1' && ! dpkg-query -s 'syncplay-common' &> /dev/null then G_WHIP_MSG '[ INFO ] Syncplay package from non-Debian source detected \nWe recognised that the syncplay-server package is installed without syncplay-common, which means that you did not install it from the Debian repository, but probably from https://github.com/Syncplay/syncplay/releases. \nDebian Trixie provides a newer package version, hence APT would normally try to upgrade to the package from Debian. But due to its different structure with dedicated syncplay-common package, it would run into conflicts, aborting the upgrade. \nTo prevent this, we created /etc/apt/preferences.d/dietpi-syncplay, which prevents Syncplay package installs and upgrades from the Debian repository. \nIf you want to migrate to the package from Debian, you need to remove this file, as well as the syncplay-server package first: \nsudo rm /etc/apt/preferences.d/dietpi-syncplay sudo apt remove syncplay-server sudo apt install syncplay-server \nThe Debian package contains an own systemd unit to start the Syncplay server at boot, but it will most likely stay at v1.7.4, until the next Debian version is released in 2027.' cat << '_EOF_' > /etc/apt/preferences.d/dietpi-syncplay || exit 1 Package: src:syncplay Pin: release o=Debian Pin-Priority: -1 _EOF_ fi if dpkg-query -s 'icecast2' &> /dev/null && [[ ! -f '/etc/default/icecast2' ]] then G_DIETPI-NOTIFY 2 'Create empty /etc/default/icecast2 else package upgrade fails' G_EXEC touch /etc/default/icecast2 fi G_DIETPI-NOTIFY 2 'Applying the actual upgrade to Debian Trixie' /boot/dietpi/dietpi-services stop G_AGUP G_AGUG G_AGDUG /boot/dietpi/func/dietpi-obtain_hw_model . /boot/dietpi/.hw_model G_DIETPI-NOTIFY 0 'Congratulations, you are now on Trixie:' head -4 /etc/os-release echo read -rp 'Next, some migrations are done for all software to run nicely on Trixie. This can include dietpi-software reinstalls. Press ENTER to continue or CTRL+C to abort ...' G_DIETPI-NOTIFY 2 'Running post upgrade migrations' /boot/dietpi/dietpi-services stop # We do not want G_AGP to purge the old kernel package yet! eval "$(declare -f G_AGP | sed 's/autopurge/purge/')" if [[ -f '/etc/apt/trusted.gpg.d/raspbian-archive-keyring.gpg.dpkg-new' ]] then G_DIETPI-NOTIFY 2 'Replace obsolete Raspbian key symlink with real key shipped since Trixie' G_EXEC rm /etc/apt/trusted.gpg.d/raspbian-archive-keyring.gpg G_EXEC mv /etc/apt/trusted.gpg.d/raspbian-archive-keyring.gpg{.dpkg-new,} fi if dpkg-query -s 'p7zip' &> /dev/null || dpkg-query -s 'p7zip-full' &> /dev/null then G_DIETPI-NOTIFY 2 'Migrating from obsolete p7zip to modern 7zip' G_AGI 7zip G_AGP p7zip p7zip-full fi if apt-mark showmanual | grep -q '^libicu72$' then G_DIETPI-NOTIFY 2 'Migrating from libicu72 to libicu76' G_AGI libicu76 G_EXEC apt-mark auto libicu72 fi # Java migration if (( $G_HW_ARCH != 1 )) then if dpkg-query -s 'openjdk-17-jdk-headless' &> /dev/null then G_DIETPI-NOTIFY 2 'Migrating from Java JDK from 17 to 21' # shellcheck disable=SC2046 apt-mark auto $(dpkg --get-selections 'default-jdk*' 'openjdk-*-jdk*' 'openjdk-*-doc' 'openjdk-*-demo' 'openjdk-*-source' 'openjdk-*-testsupport' 2> /dev/null | mawk '{print $1}') 2> /dev/null fi if dpkg-query -s 'openjdk-17-jre-headless' &> /dev/null then G_DIETPI-NOTIFY 2 'Migrating from Java JRE from 17 to 21' # shellcheck disable=SC2046 apt-mark auto $(dpkg --get-selections 'default-jre*' 'openjdk-*-jre*' 'openjdk-*-dbg' ca-certificates-java 2> /dev/null | mawk '{print $1}') 2> /dev/null fi fi if apt-mark showmanual | grep -q '^policykit-1$' then G_DIETPI-NOTIFY 2 'Migrating from policykit-1 to polkitd' G_AGI polkitd G_EXEC apt-mark auto policykit-1 fi if apt-mark showmanual | grep -q '^firmware-misc-nonfree$' then G_DIETPI-NOTIFY 2 'Migrating from bundled firmware packages to new dedicated WiFi firmware packages' G_AGI firmware-{ath9k-htc,carl9170,mediatek} G_EXEC apt-mark auto firmware-misc-nonfree apt-mark showmanual | grep -q '^firmware-linux-free$' && G_EXEC apt-mark auto firmware-linux-free fi if dpkg-query -s 'mime-support' &> /dev/null then G_DIETPI-NOTIFY 2 'Purging obsolete transitional "mime-support" package' # remains installed for unknown reasons even if no dependant G_AGP mime-support fi # Purge PHP 8.2 packages, obsolete after PHP 8.2 install G_AGP '*php8.2*' # Remove obsolete PHP 8.2 configs and Python 3.11 modules, obsolete after Python 3.13 install G_EXEC rm -Rf /etc/php/8.2 /usr/local/lib/python3.11 /usr/local/bin/pip3* # x86_64: Install new Intel/Nvidia GPU firmware package if Intel driver was selected if (( $G_HW_MODEL == 21 )) then gpu_current=$(sed -n '/^[[:blank:]]*CONFIG_GPU_DRIVER=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) case $gpu_current in 'intel') G_AGI firmware-intel-graphics;; 'nvidia') G_AGI firmware-nvidia-graphics;; *) :;; esac fi # PostgreSQL migration if dpkg-query -s 'postgresql' &> /dev/null then G_DIETPI-NOTIFY 2 'Migrating PostgreSQL 15 clusters to v17' mapfile -t clusters < <(pg_lsclusters | mawk '$1 == "15" {print $2}') skipped=0 G_EXEC systemctl start postgresql for cluster in "${clusters[@]}" do [[ -d /var/lib/postgresql/17/$cluster ]] && { G_DIETPI-NOTIFY 2 "PostgreSQL 17 cluster \"$cluster\" exists already, skipping migration"; skipped=1; continue; } G_DIETPI-NOTIFY 2 "Found PostgreSQL 15 cluster \"$cluster\", starting migration ..."; G_EXEC pg_upgradecluster 15 "$cluster" G_EXEC pg_dropcluster 15 "$cluster" done if (( $skipped )) then G_WHIP_MSG '[ INFO ] PostgreSQL 15 to v17 migration incomplete \nFor some PostgreSQL 15 cluster(s), the respective v17 cluster existed already, and the migration has hence been skipped. \nPlease review those left clusters and in case remove or migrate them to v17 manually. PostgreSQL 15 is kept installed for that. Once all needed clusters have been migrated, purge PostgreSQL 15 with the following commands: \nsudo rm /etc/apt/apt.conf.d/02autoremove-postgresql sudo apt autopurge' else G_EXEC rm /etc/apt/apt.conf.d/02autoremove-postgresql fi fi # Reinstalls: # - PHP and all PHP applications which require additional PHP modules: 38 40 89 114 143 210 # - Python and all Python applications which require pip installs: 118 125 130 136 139 141 153 155 180 # - Java for migration to Adoptium Temurin or OpenJDK 21 on ARMv7 respectively # - PaperMC for latest version: 181 extra=() # - Kodi on RPi to migrate from "kodi21" to "kodi" package (( $G_HW_MODEL < 10 )) && extra+=(31) # - LMS on ARM (( $G_HW_ARCH < 10 )) && extra+=(35) # - UnRAR on non-ARMv6 Raspbian systems, for which we host the respective Debian packages on our server (( $G_HW_MODEL != 1 )) && (( $G_RASPBIAN )) && extra+=(170) G_PROMPT_BACKUP_DISABLED=1 /boot/dietpi/dietpi-software reinstall 8 38 40 89 114 118 125 130 136 139 141 143 153 155 180 181 196 210 "${extra[@]}" G_DIETPI-NOTIFY 2 'Purging left config files from packages which were removed before already' mapfile -t packages < <(dpkg -l | mawk '$1=="rc"{print $2}') G_AGP "${packages[@]}" cat << '_EOF_' > /etc/bashrc.d/zz-dietpi-autopurge.bash { (( $UID )) && return 0 G_DIETPI-NOTIFY 2 'Autoremoving leftover packages from Trixie upgrade...' G_EXEC_NOHALT=1 G_EXEC rm /etc/bashrc.d/zz-dietpi-autopurge.bash G_AGA } _EOF_ G_WHIP_YESNO 'All finished!\n\nWe highly recommend to reboot, shall we reboot now?\n\nNB: To have obsolete leftover packages autoremoved, login as root user once after reboot, or run "sudo apt autopurge".' && reboot }