diff --git a/.github/workflows/dietpi-software.bash b/.github/workflows/dietpi-software.bash index 6904697820..e9e83921ad 100644 --- a/.github/workflows/dietpi-software.bash +++ b/.github/workflows/dietpi-software.bash @@ -334,7 +334,7 @@ do 61) Process_Software 60;; 125) Process_Software 194;; 86|134|185) Process_Software 162;; - 141) Process_Software 17 130 134 162;; + 141) Process_Software 17 134 162;; 166) Process_Software 70;; 180) (( $arch == 10 || $arch == 3 )) || Process_Software 170;; 188) Process_Software 17;; diff --git a/.update/patches b/.update/patches index a277db0330..1c137e96f9 100755 --- a/.update/patches +++ b/.update/patches @@ -2228,7 +2228,7 @@ Patch_10_1() then G_DIETPI-NOTIFY 2 'Fixing Chromium kiosk mode' # shellcheck disable=SC2016 - G_EXEC sed --follow-symlink -i 's|"\$STARTX" chromium|"$STARTX" /usr/bin/chromium|' /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh + G_EXEC sed --follow-symlinks -i 's|"\$STARTX" chromium|"$STARTX" /usr/bin/chromium|' /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh fi # Orange Pi 3B @@ -2258,6 +2258,42 @@ _EOF_' # Software updates, migrations and patches if [[ -f '/boot/dietpi/.installed' ]] then + # Python software migration to venv + # - Python 3 + if grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[130\]=2' /boot/dietpi/.installed && [[ -f '/etc/pip.conf' ]] + then + G_DIETPI-NOTIFY 2 'Removing obsolete pip directives now that we move all Python software into venvs' + G_EXEC sed --follow-symlinks -i '/^[[:blank:]]*break-system-packages[[:blank:]]*=/d' /etc/pip.conf + G_EXEC sed --follow-symlinks -i '/^[[:blank:]]*root-user-action[[:blank:]]*=/d' /etc/pip.conf + fi + # - Synapse + if grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[125\]=2' /boot/dietpi/.installed + then + G_DIETPI-NOTIFY 2 'Removing system-level Synpase Python module and scheduling reinstall to install it into a venv' + command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y --break-system-packages --root-user-action=ignore matrix-synapse + G_EXEC eval 'echo 125 >> /var/tmp/dietpi/dietpi-update_reinstalls' + fi + # - motionEye + if grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[136\]=2' /boot/dietpi/.installed + then + G_DIETPI-NOTIFY 2 'Removing system-level motionEye Python module and scheduling reinstall to install it into a venv' + command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y --break-system-packages --root-user-action=ignore motioneye + G_EXEC eval 'echo 136 >> /var/tmp/dietpi/dietpi-update_reinstalls' + fi + # - OctoPrint + if grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[153\]=2' /boot/dietpi/.installed + then + G_DIETPI-NOTIFY 2 'Moving user-level OctoPrint Python modules into venv and scheduling reinstall' + if [[ -d '/mnt/dietpi_userdata/octoprint/.local' && ! -d '/mnt/dietpi_userdata/octoprint/venv' ]] + then + G_AGI python3-venv + G_EXEC mv /mnt/dietpi_userdata/octoprint/{.local,venv} + G_EXEC python3 -m venv /mnt/dietpi_userdata/octoprint/venv + G_EXEC find /mnt/dietpi_userdata/octoprint/venv/bin -type f -exec sed --follow-symlinks -i '1s|^#!/.*/bin/python3|#!/mnt/dietpi_userdata/octoprint/venv/bin/python3|' {} + + fi + G_EXEC eval 'echo 153 >> /var/tmp/dietpi/dietpi-update_reinstalls' + fi + # Pi-hole v6 migration # - /etc/pihole/pihole.toml indicates that Pi-hole has been upgraded to v6 already. # - The /var/www/pihole symlink indicates that an instance installed via dietpi-software has not been migrated yet. diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c00bbd1901..07a3d94ba7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -7,6 +7,7 @@ New images: Enhancements: - NanoPi R5C | Resolved an issue where the Ethernet network interface names could have swapped on reboots. They are now assigned with eth0 as LAN port and eth1 as WAN port. Many thanks to @firebox for reporting this issue: https://dietpi.com/forum/t/24845/24 - DietPi-Tools | DietPi-Banner: New option to output the Linux kernel version +- DietPi-Software | Python 3: All Python software options make now use of venvs, instead of being installed to the system site "/usr/local/lib/python3.*/dist-packages". Recent pip has increasing issues managing modules there on distros which have own Python module packages. Modern setups almost require isolated environments like venv. Synapse, motionEye, and OctoPrint are reinstalled on DietPi update to perform the migration directly, preserving user data and plugins. The "break-system-packages" flag in /etc/pip.conf is consequently removed. If you need to manage packages via pip at the system site, add the "--break-system-packages" CLI flag to each call. - DietPi-Software | Navidrome: Support for RISC-V has been unlocked, as official builds have been added with the v0.60.0 release on GitHub. - DietPi-Software | MinIO: The console client "mc" is now installed along with the server, to make up with the lost administration functionalities of the community server web UI. A shell alias is generated to invoke it as "minio-user" user, using a pre-generated config file /mnt/dietpi_userdata/minio-data/.mc/config.json. It adds the local MinIO server instance as "local" alias. Additionally, the default credentials have been changed to username (access key) "dietpi" and the default software password as secret key. Since MinIO requires the password to be at least 8 characters long, the default software password is concatenated until 8 characters are reached. E.g. if "test" was used, it will be "testtest" for MinIO. However, don't try it and use a secure default software password of 12 characters or more on production systems ;). Change it afterwards for the MinIO server in /etc/default/minio, and for the console client "mc" accordingly in /mnt/dietpi_userdata/minio-data/.mc/config.json. - DietPi-Software | TigerVNC/RealVNC/XRDP: Those remote desktop servers do not actually require a desktop anymore, but just the X server. This allows lighter setups when using them to show an individual GUI application like Chromium only, instead of a full desktop. Many thanks to @fow0ryl for doing this suggestion: https://github.com/MichaIng/DietPi/issues/7947 diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 6e4f32e882..1920bab3d9 100755 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -1575,7 +1575,7 @@ Available commands: aSOFTWARE_DESC[$software_id]='track airplanes using SDRs and feed the data to ADS-B aggregators' aSOFTWARE_CATX[$software_id]=19 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/distributed_projects/#adsb-feeder' - aSOFTWARE_DEPS[$software_id]='17 130 134 162' # Git, Python, Docker & Docker Compose + aSOFTWARE_DEPS[$software_id]='17 134 162' # Git, Docker & Docker Compose #------------------ software_id=184 aSOFTWARE_NAME[$software_id]='Tor Relay' @@ -1689,7 +1689,7 @@ Available commands: #------------------ software_id=130 aSOFTWARE_NAME[$software_id]='Python 3' - aSOFTWARE_DESC[$software_id]='Runtime system, pip package installer and development headers' + aSOFTWARE_DESC[$software_id]='Runtime system, venv, and development headers' aSOFTWARE_CATX[$software_id]=24 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/programming/#python-3' #------------------ @@ -2589,26 +2589,18 @@ sudo sysctl -p /etc/sysctl.d/dietpi-$1.conf" # pyenv Add APT dependencies needed to compile Python for pyenv # Add APT dependencies needed to compile and in case run the named module # Environment variables: - # PYTHON_VERSION Python version in case e.g. pyenv is used + # PYTHON_VERSION Python version (required) Python_Deps() { - local install=0 user rust=0 piwheels=0 - - if [[ $PYTHON_VERSION ]] - then - until [[ $PYTHON_VERSION =~ ^3\.[0-9]+$ ]]; do PYTHON_VERSION=${PYTHON_VERSION%\.*}; done - else - case $G_DISTRO in - 7) PYTHON_VERSION='3.11';; - *) PYTHON_VERSION='3.13';; - esac - fi - PYTHON_VERSION=${PYTHON_VERSION/.} # so we can check in bash arithmetic + local install=0 user rust=0 piwheels=0 python_version=$PYTHON_VERSION + [[ $python_version =~ ^3(\.[0-9]+)+$ ]] || { G_DIETPI-NOTIFY 1 'PYTHON_VERSION is not or falsely set, this should never happen, please report to https://github.com/MichaIng/DietPi/issues. Aborting ...'; exit 1; } + until [[ $python_version =~ ^3\.[0-9]+$ ]]; do python_version=${python_version%\.*}; done + python_version=${python_version/.} # so we can check in bash arithmetic # Can piwheels be used? The Python version needs to match the Debian version, else dynamically linked shared libraries may not match! if (( $G_HW_ARCH < 3 )) then - if (( ( $G_DISTRO == 7 && $PYTHON_VERSION == 311 ) || ( $G_DISTRO > 7 && $PYTHON_VERSION == 313 ) )) + if (( ( $G_DISTRO == 7 && $python_version == 311 ) || ( $G_DISTRO > 7 && $python_version == 313 ) )) then piwheels=1 fi @@ -2622,23 +2614,25 @@ sudo sysctl -p /etc/sysctl.d/dietpi-$1.conf" '--user'|'-u') shift; user=$1;; '--rust'|'-r') rust=1;; '--no-piwheels'|'-P') piwheels=0;; - 'av') (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && $PYTHON_VERSION != 313 ) )) && aDEPS+=('libavdevice-dev');; + 'av') (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && $python_version != 313 ) )) && aDEPS+=('libavdevice-dev');; 'bcrypt') (( $G_HW_ARCH == 11 || ( $G_HW_ARCH == 1 && ! $piwheels ) )) && rust=1;; 'brotli'|'sabctools'|'ujson') (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ! $piwheels ) )) && aDEPS+=('g++');; - 'cffi') (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && $PYTHON_VERSION != 311 ) )) && aDEPS+=('gcc' 'libffi-dev');; + 'cffi') (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && $python_version != 311 ) )) && aDEPS+=('gcc' 'libffi-dev');; 'cryptography') if (( $G_HW_ARCH == 11 || ( $G_HW_ARCH == 1 && ! $piwheels ) )) then aDEPS+=('pkg-config' 'libssl-dev') rust=1 + # Temporary workaround for maturin bug on riscv64: https://github.com/PyO3/maturin/pull/3009 + (( $G_HW_ARCH == 11 )) && export PIP_NO_BINARY='maturin' fi set -- "$@" cffi ;; - 'greenlet113') (( $PYTHON_VERSION > 311 || $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ! $piwheels ) )) && aDEPS+=('g++');; + 'greenlet113') (( $python_version > 311 || $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ! $piwheels ) )) && aDEPS+=('g++');; 'libsass') (( $G_HW_ARCH == 10 || $piwheels )) || aDEPS+=('g++');; - 'lxml') (( $G_HW_ARCH == 1 && ( ! $piwheels || $PYTHON_VERSION == 313 ) )) && aDEPS+=('libxslt1-dev');; - 'matrix-synapse') (( $PYTHON_VERSION > 311 || $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ! $piwheels ) )) && rust=1;; - 'netifaces') (( $piwheels || ( $G_HW_ARCH == 10 && $PYTHON_VERSION <= 39 ) )) || aDEPS+=('gcc');; + 'lxml') (( $G_HW_ARCH == 1 && ( ! $piwheels || $python_version == 313 ) )) && aDEPS+=('libxslt1-dev');; + 'matrix-synapse') (( $python_version > 311 || $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ! $piwheels ) )) && rust=1;; + 'netifaces') (( $piwheels )) || aDEPS+=('gcc');; 'numpy') if (( $G_HW_ARCH == 11 || ( $G_HW_ARCH == 1 && ! $piwheels ) )) then @@ -2653,8 +2647,8 @@ sudo sysctl -p /etc/sysctl.d/dietpi-$1.conf" fi ;; 'pillow') - (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ( ! $piwheels || $PYTHON_VERSION == 39 ) ) )) && aDEPS+=('gcc' 'libjpeg62-turbo-dev') - if (( $piwheels && $PYTHON_VERSION != 39 )) + (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ( ! $piwheels || $python_version != 311 ) ) )) && aDEPS+=('gcc' 'libjpeg62-turbo-dev') + if (( $piwheels && $python_version == 311 )) then aDEPS+=('libopenjp2-7' 'libtiff6' 'libxcb1') fi @@ -2664,7 +2658,7 @@ sudo sysctl -p /etc/sysctl.d/dietpi-$1.conf" set -- "$@" cryptography ;; 'psutil') (( $G_HW_ARCH < 3 || $G_HW_ARCH == 11 )) && aDEPS+=('gcc');; - 'psycopg2') (( $piwheels && $PYTHON_VERSION != 39 )) || aDEPS+=('gcc' 'libpq-dev');; + 'psycopg2') (( $piwheels )) || aDEPS+=('gcc' 'libpq-dev');; 'pycares') (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ! $piwheels ) )) && aDEPS+=('cmake');; 'pycurl') (( $G_HW_ARCH == 11 || ( $G_HW_ARCH < 3 && ! $piwheels ) )) && aDEPS+=('gcc' 'libcurl4-openssl-dev' 'libssl-dev');; 'pydantic') @@ -2677,7 +2671,7 @@ sudo sysctl -p /etc/sysctl.d/dietpi-$1.conf" # libffi-dev for the optional _ctypes module, needed at least for Home Assistant => include it in all pyenv builds to avoid surprises aDEPS+=('gcc' 'libc6-dev' 'make' 'libssl-dev' 'zlib1g-dev' 'libbz2-dev' 'libreadline-dev' 'libsqlite3-dev' 'liblzma-dev' 'libffi-dev') # Python < 3.12: https://dietpi.com/forum/t/24975/2 - (( $PYTHON_VERSION < 312 )) && aDEPS+=('patch') + (( $python_version < 312 )) && aDEPS+=('patch') ;; 'pymicro-vad') aDEPS+=('g++');; 'pynacl') @@ -2689,7 +2683,6 @@ sudo sysctl -p /etc/sysctl.d/dietpi-$1.conf" esac shift done - unset -v PYTHON_VERSION # Install Rust if needed if (( $rust )) @@ -2714,6 +2707,16 @@ sudo sysctl -p /etc/sysctl.d/dietpi-$1.conf" aDEPS=() } + # Remove venv at $1 if Python version changed + Remove_old_venv() + { + [[ -f $1'/bin/python3' ]] || return 0 + local venv_version=$("$1/bin/python3" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2> /dev/null) + [[ $venv_version == "$PYTHON_VERSION" ]] && return 0 + G_DIETPI-NOTIFY 2 "Recreating venv due to Python version change: $venv_version -> $PYTHON_VERSION" + G_EXEC rm -R "$1" + } + To_Install() { (( ${aSOFTWARE_INSTALL_STATE[$1]} == 1 )) || return 1 @@ -3149,23 +3152,18 @@ _EOF_" if To_Install 130 # Python 3 then - # Allow pip to install modules on system level, and mute the warning when doing so as root (which is needed, of course) - >> /etc/pip.conf - G_CONFIG_INJECT '\[global\]' '[global]' /etc/pip.conf - G_CONFIG_INJECT 'break-system-packages[[:blank:]]*=' 'break-system-packages=true' /etc/pip.conf '\[global\]' - G_CONFIG_INJECT 'root-user-action[[:blank:]]*=' 'root-user-action=ignore' /etc/pip.conf '\[global\]' + G_AGI python3-{dev,venv} # Disable cache: It is rarely ever needed to install the very same module and version twice, hence this usually only causes unnecessary disk writes and usage. + >> /etc/pip.conf + G_CONFIG_INJECT '\[global\]' '[global]' /etc/pip.conf G_CONFIG_INJECT 'no-cache-dir[[:blank:]]*=' 'no-cache-dir=true' /etc/pip.conf '\[global\]' # ARMv6/7: Add piwheels (( $G_HW_ARCH < 3 )) && G_CONFIG_INJECT 'extra-index-url[[:blank:]]*=' 'extra-index-url=https://www.piwheels.org/simple/' /etc/pip.conf '\[global\]' - # Perform pip3 install (which includes setuptools and wheel modules) - aDEPS=('python3-dev') - Download_Install 'https://bootstrap.pypa.io/get-pip.py' - G_EXEC_OUTPUT=1 G_EXEC python3 get-pip.py - G_EXEC rm get-pip.py + # Obtain Python version as global variable for use in venv creation and Python_Deps + PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') fi if To_Install 150 # Mono: https://www.mono-project.com/download/stable/#download-lin-debian @@ -4089,7 +4087,9 @@ sudo sysctl -p /etc/sysctl.d/98-dietpi-redis.conf' Python_Deps -i bcrypt cryptography pillow psycopg2 pynacl matrix-synapse # Install - G_EXEC_OUTPUT=1 G_EXEC pip3 install -U matrix-synapse psycopg2 + Remove_old_venv /opt/synapse + G_EXEC python3 -m venv --upgrade-deps /opt/synapse + G_EXEC_OUTPUT=1 G_EXEC /opt/synapse/bin/pip3 install -U matrix-synapse psycopg2 # User Create_User -d /mnt/dietpi_userdata/synapse synapse @@ -4106,7 +4106,7 @@ Type=notify SyslogIdentifier=Synapse User=synapse WorkingDirectory=/mnt/dietpi_userdata/synapse -ExecStart=/usr/bin/python3 -m synapse.app.homeserver -c homeserver.yaml -c homeserver.yaml.d +ExecStart=/opt/synapse/bin/python3 -m synapse.app.homeserver -c homeserver.yaml -c homeserver.yaml.d ExecReload=/bin/kill -HUP $MAINPID [Install] @@ -4162,7 +4162,7 @@ _EOF_ G_EXEC cd /mnt/dietpi_userdata/synapse # Create initial config - G_EXEC python3 -m synapse.app.homeserver -H "$servername" -c homeserver.yaml --generate-config --report-stats 'no' + G_EXEC /opt/synapse/bin/python3 -m synapse.app.homeserver -H "$servername" -c homeserver.yaml --generate-config --report-stats 'no' # Enable registrations via random shared secret GCI_PASSWORD=1 G_CONFIG_INJECT 'registration_shared_secret:[[:blank:]]' "registration_shared_secret: $(openssl rand -hex 16)" homeserver.yaml @@ -4183,7 +4183,7 @@ _EOF_ G_EXEC systemctl daemon-reload G_EXEC systemctl start synapse G_EXEC_PRE_FUNC(){ acommand[4]="$GLOBAL_PW"; } # Mask password in console output - G_EXEC_OUTPUT=1 G_EXEC register_new_matrix_user -u "$username" -p "${GLOBAL_PW//?/X}" -a -c homeserver.yaml 'http://127.0.0.1:8008' + G_EXEC_OUTPUT=1 G_EXEC /opt/synapse/bin/register_new_matrix_user -u "$username" -p "${GLOBAL_PW//?/X}" -a -c homeserver.yaml 'http://127.0.0.1:8008' G_EXEC cd "$G_WORKING_DIR" unset -v servername username @@ -5113,9 +5113,12 @@ _EOF_ # APT package local deps=() (( $G_DISTRO == 8 )) && deps=('patch') # Trixie: Patch for Python 3.13: https://github.com/MichaIng/DietPi/issues/7866 - G_AGI mopidy gstreamer1.0-alsa mopidy-local "${deps[@]}" + G_AGI mopidy gstreamer1.0-alsa mopidy-local python3-pip "${deps[@]}" G_EXEC systemctl stop mopidy + # Temporary fix for Debian package: https://salsa.debian.org/python-team/packages/mopidy/-/merge_requests/3 + [[ -e '/usr/bin/mopidy' ]] || G_EXEC ln -s /usr/share/mopidy/mopidy-cmd /usr/bin/mopidy + (( $G_DISTRO == 8 )) && ! grep -q '_get_structure_name' /lib/python3/dist-packages/mopidy/audio/scan.py && G_EXEC patch -d/ -p0 << '_EOF_' --- /lib/python3/dist-packages/mopidy/audio/scan.py +++ /lib/python3/dist-packages/mopidy/audio/scan.py @@ -5148,7 +5151,8 @@ _EOF_ raise exceptions.ScannerError(str(error)) elif msg.type == Gst.MessageType.EOS: _EOF_ - G_EXEC_OUTPUT=1 G_EXEC pip3 install -U Mopidy-MusicBox-Webclient + # Install additional Python modules with --break-system-packages as Mopidy itself is an APT package + G_EXEC_OUTPUT=1 G_EXEC pip3 install --break-system-packages --root-user-action=ignore -U Mopidy-MusicBox-Webclient # Assure user home, data and cache dir as well on custom configs G_CONFIG_INJECT 'data_dir[[:blank:]]*=' 'data_dir = /mnt/dietpi_userdata/mopidy/data' /etc/mopidy/mopidy.conf '\[core\]' @@ -8998,10 +9002,15 @@ _EOF_ (( $G_HW_MODEL > 9 )) || /boot/dietpi/func/dietpi-set_hardware rpi-camera 1 # motionEye - G_EXEC_OUTPUT=1 G_EXEC pip3 install -U motioneye - G_EXEC_OUTPUT=1 G_EXEC motioneye_init --skip-apt-update + Remove_old_venv /opt/motioneye + G_EXEC python3 -m venv --upgrade-deps /opt/motioneye + G_EXEC_OUTPUT=1 G_EXEC /opt/motioneye/bin/pip3 install -U motioneye + G_EXEC_OUTPUT=1 G_EXEC /opt/motioneye/bin/motioneye_init --skip-apt-update G_EXEC systemctl stop motioneye + # Update systemd service to use venv (handle both /usr/local/bin and /usr/bin paths) + G_EXEC sed -i 's|ExecStart=.*/meyectl|ExecStart=/opt/motioneye/bin/meyectl|' /etc/systemd/system/motioneye.service + # Prevent the conflicting motion daemon from starting G_EXEC systemctl --no-reload disable --now motion G_EXEC systemctl --no-reload mask motion @@ -9069,9 +9078,9 @@ _EOF_ if [[ ${aSOFTWARE_INSTALL_STATE[153]} == 2 && -f '/mnt/dietpi_userdata/octoprint/.octoprint/config.yaml' ]] then G_DIETPI-NOTIFY 2 'Configuring OctoPrint to use mjpg-streamer for webcam support' - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.stream "http://$(G_GET_NET ip):8082/?action=stream" - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.snapshot 'http://127.0.0.1:8082/?action=snapshot' - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.ffmpeg "$(command -v ffmpeg)" + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set webcam.stream "http://$(G_GET_NET ip):8082/?action=stream" + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set webcam.snapshot 'http://127.0.0.1:8082/?action=snapshot' + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set webcam.ffmpeg "$(command -v ffmpeg)" fi fi @@ -9137,8 +9146,10 @@ _EOF_ G_EXEC mv sabnzbd-master /etc/sabnzbd # Python deps + Remove_old_venv /opt/sabnzbd + G_EXEC python3 -m venv --upgrade-deps /opt/sabnzbd G_EXEC cd /etc/sabnzbd - G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur requirements.txt + G_EXEC_OUTPUT=1 G_EXEC /opt/sabnzbd/bin/pip3 install -Ur requirements.txt # User Create_User -g dietpi -d /etc/sabnzbd sabnzbd @@ -9164,7 +9175,7 @@ StartLimitBurst=3 [Service] SyslogIdentifier=SABnzbd User=sabnzbd -ExecStart=/usr/bin/python3 -OO /etc/sabnzbd/SABnzbd.py -f /etc/sabnzbd/sabnzbd.ini -n --disable-file-log +ExecStart=/opt/sabnzbd/bin/python3 -OO /etc/sabnzbd/SABnzbd.py -f /etc/sabnzbd/sabnzbd.ini -n --disable-file-log Restart=on-failure [Install] @@ -9648,9 +9659,11 @@ _EOF_ Download_Install 'https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip' bazarr # Python deps + Remove_old_venv /opt/bazarr_venv + G_EXEC python3 -m venv --upgrade-deps /opt/bazarr_venv # - Allow Pillow to be compiled G_EXEC sed --follow-symlinks -i 's/ --only-binary=Pillow$//' bazarr/requirements.txt - G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur bazarr/requirements.txt + G_EXEC_OUTPUT=1 G_EXEC /opt/bazarr_venv/bin/pip3 install -Ur bazarr/requirements.txt # Install: Remove previous instance on reinstall [[ -d '/opt/bazarr' ]] && G_EXEC rm -R /opt/bazarr @@ -9682,7 +9695,7 @@ User=bazarr UMask=002 LogsDirectory=bazarr WorkingDirectory=/mnt/dietpi_userdata/bazarr -ExecStart=/usr/bin/python3 /opt/bazarr/bazarr.py -c /mnt/dietpi_userdata/bazarr +ExecStart=/opt/bazarr_venv/bin/python3 /opt/bazarr/bazarr.py -c /mnt/dietpi_userdata/bazarr KillSignal=SIGINT TimeoutStopSec=20 @@ -10045,20 +10058,20 @@ _EOF_ G_EXEC cd /mnt/dietpi_userdata/htpc-manager G_EXEC_OUTPUT=1 G_EXEC git remote set-url origin "$url" G_EXEC_OUTPUT=1 G_EXEC git fetch --depth=1 origin - G_EXEC_OUTPUT=1 G_EXEC git reset --hard origin - G_EXEC_OUTPUT=1 G_EXEC git clean -dxfe '/userdata' else G_EXEC_OUTPUT=1 G_EXEC git clone --depth=1 "$url" G_EXEC mkdir -p /mnt/dietpi_userdata/htpc-manager G_EXEC cp -a HTPC-Manager/. /mnt/dietpi_userdata/htpc-manager/ G_EXEC rm -R HTPC-Manager G_EXEC cd /mnt/dietpi_userdata/htpc-manager - G_EXEC_OUTPUT=1 G_EXEC git reset --hard origin - G_EXEC_OUTPUT=1 G_EXEC git clean -dxfe '/userdata' fi + G_EXEC_OUTPUT=1 G_EXEC git reset --hard origin + G_EXEC_OUTPUT=1 G_EXEC git clean -dxfe '/userdata' # Python deps - G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur requirements.txt + Remove_old_venv /opt/htpc-manager + G_EXEC python3 -m venv --upgrade-deps /opt/htpc-manager + G_EXEC_OUTPUT=1 G_EXEC /opt/htpc-manager/bin/pip3 install -Ur requirements.txt # Service cat << '_EOF_' > /etc/systemd/system/htpc-manager.service @@ -10069,7 +10082,7 @@ After=network-online.target [Service] SyslogIdentifier=HTPC Manager -ExecStart=/usr/bin/python3 -OO /mnt/dietpi_userdata/htpc-manager/Htpc.py +ExecStart=/opt/htpc-manager/bin/python3 -OO /mnt/dietpi_userdata/htpc-manager/Htpc.py [Install] WantedBy=multi-user.target @@ -10090,8 +10103,10 @@ _EOF_ [[ -d '/mnt/dietpi_userdata/octoprint/.cache' ]] && G_EXEC rm -R /mnt/dietpi_userdata/octoprint/.cache # Install OctoPrint + Remove_old_venv /mnt/dietpi_userdata/octoprint/venv + G_EXEC runuser -u octoprint -- python3 -m venv --upgrade-deps /mnt/dietpi_userdata/octoprint/venv # shellcheck disable=SC2016 - G_EXEC_OUTPUT=1 G_EXEC runuser -u octoprint -- dash -c 'PATH="$HOME/.cargo/bin:$PATH" pip3 install -U --user --no-warn-script-location octoprint' + G_EXEC_OUTPUT=1 G_EXEC runuser -u octoprint -- dash -c 'PATH="$HOME/.cargo/bin:$PATH" /mnt/dietpi_userdata/octoprint/venv/bin/pip3 install -U octoprint' # Service: https://github.com/OctoPrint/OctoPrint/blob/master/scripts/octoprint.service cat << '_EOF_' > /etc/systemd/system/octoprint.service @@ -10104,31 +10119,31 @@ After=network-online.target mjpg-streamer.service [Service] Environment="LC_ALL=C.UTF-8" "LANG=C.UTF-8" User=octoprint -ExecStart=/mnt/dietpi_userdata/octoprint/.local/bin/octoprint serve +ExecStart=/mnt/dietpi_userdata/octoprint/venv/bin/octoprint serve [Install] WantedBy=multi-user.target _EOF_ # CLI alias - echo "alias octoprint='sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint'" > /etc/bashrc.d/dietpi-octoprint.sh + echo "alias octoprint='sudo -u octoprint /mnt/dietpi_userdata/octoprint/venv/bin/octoprint'" > /etc/bashrc.d/dietpi-octoprint.sh # On fresh installs, change listening port to 5001 to avoid conflict with Shairport Sync. - [[ -f '/mnt/dietpi_userdata/octoprint/.octoprint/config.yaml' ]] || G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.port '5001' + [[ -f '/mnt/dietpi_userdata/octoprint/.octoprint/config.yaml' ]] || G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set server.port '5001' # Apply service and system commands: Allow execution via specific sudoers config, use "which" for "reboot" and "poweroff", since we create shell functions in dietpi-globals to bypass logind calls if logind is not running. # shellcheck disable=SC2230 echo "octoprint ALL=NOPASSWD: $(command -v systemctl) restart octoprint, $(which reboot), $(which poweroff)" > /etc/sudoers.d/octoprint - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.serverRestartCommand 'sudo systemctl restart octoprint' - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.systemRestartCommand 'sudo reboot' - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.systemShutdownCommand 'sudo poweroff' + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set server.commands.serverRestartCommand 'sudo systemctl restart octoprint' + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set server.commands.systemRestartCommand 'sudo reboot' + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set server.commands.systemShutdownCommand 'sudo poweroff' # mjpg-streamer: Configure OctoPrint to use it if installed if (( ${aSOFTWARE_INSTALL_STATE[137]} > 0 )) then G_DIETPI-NOTIFY 2 'Configuring OctoPrint to use mjpg-streamer for webcam support' - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.stream "http://$(G_GET_NET ip):8082/?action=stream" - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.snapshot 'http://127.0.0.1:8082/?action=snapshot' - G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.ffmpeg "$(command -v ffmpeg)" + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set webcam.stream "http://$(G_GET_NET ip):8082/?action=stream" + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set webcam.snapshot 'http://127.0.0.1:8082/?action=snapshot' + G_EXEC runuser -u octoprint -- /mnt/dietpi_userdata/octoprint/venv/bin/octoprint config set webcam.ffmpeg "$(command -v ffmpeg)" fi fi @@ -11618,7 +11633,8 @@ _EOF_ if To_Install 141 adsb-setup adsb-docker # ADS-B Feeder then - Python_Deps cryptography + # Deps + G_AGI python3-{cryptography,flask,requests} # clone the adsb-feeder repo into /tmp G_EXEC_OUTPUT=1 G_EXEC git clone -b dietpi 'https://github.com/dirkhh/adsb-feeder-image' /tmp/adsb-feeder @@ -11628,8 +11644,6 @@ _EOF_ G_EXEC rm ./usr/lib/systemd/system/adsb-bootstrap.service G_EXEC rm ./usr/lib/systemd/system/adsb-update.service G_EXEC rm ./usr/lib/systemd/system/adsb-update.timer - # Fix bash path on potentially non-usr-merged systems - [[ -f '/usr/bin/bash' ]] || G_EXEC sed --follow-symlinks -i 's|/usr/bin/bash|/bin/bash|' ./usr/lib/systemd/system/adsb-*.service G_EXEC mv ./usr/lib/systemd/system/* /etc/systemd/system/ # determine the version @@ -11655,9 +11669,6 @@ _EOF_ G_EXEC rm -f os.adsb.feeder.image G_EXEC touch app.adsb.feeder.image - # get the Python modules - G_EXEC_OUTPUT=1 G_EXEC pip3 install -U flask requests - # finally ensure that /run allows executables (this is needed for the containers to be able to not do excessive # writes to physical storage - which might be an SD card) G_EXEC mount -o remount,exec /run @@ -11875,7 +11886,6 @@ _EOF_ if To_Install 169 lazylibrarian # LazyLibrarian then # Dependencies - aDEPS=('python3-venv') Python_Deps cryptography pillow # Download @@ -11889,8 +11899,8 @@ _EOF_ G_EXEC mv LazyLibrarian-master /opt/lazylibrarian # Python venv - G_EXEC python3 -m venv /opt/lazylibrarian/venv - G_EXEC_OUTPUT=1 G_EXEC /opt/lazylibrarian/venv/bin/pip install /opt/lazylibrarian + G_EXEC python3 -m venv --upgrade-deps /opt/lazylibrarian/venv + G_EXEC_OUTPUT=1 G_EXEC /opt/lazylibrarian/venv/bin/pip3 install /opt/lazylibrarian # User Create_User -g dietpi lazylibrarian @@ -11929,7 +11939,7 @@ SyslogIdentifier=LazyLibrarian User=lazylibrarian UMask=002 LogsDirectory=lazylibrarian -ExecStart=/opt/lazylibrarian/venv/bin/python /opt/lazylibrarian/LazyLibrarian.py --datadir=/mnt/dietpi_userdata/lazylibrarian --nolaunch +ExecStart=/opt/lazylibrarian/venv/bin/python3 /opt/lazylibrarian/LazyLibrarian.py --datadir=/mnt/dietpi_userdata/lazylibrarian --nolaunch ExitType=cgroup # Hardening @@ -12742,9 +12752,9 @@ _EOF_ if To_Uninstall 125 # Synapse then Remove_Service synapse 1 1 - [[ -d '/mnt/dietpi_userdata/synapse' ]] && G_EXEC rm -R /mnt/dietpi_userdata/synapse + G_EXEC rm -Rf /opt/synapse + G_EXEC rm -Rf /mnt/dietpi_userdata/synapse - command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y matrix-synapse command -v dropdb > /dev/null && runuser -u postgres -- dropdb synapse command -v dropuser > /dev/null && runuser -u postgres -- dropuser synapse fi @@ -12800,11 +12810,11 @@ _EOF_ if To_Uninstall 136 # motionEye then Remove_Service motioneye - command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y motioneye + G_EXEC rm -Rf /opt/motioneye + G_EXEC rm -Rf /etc/motioneye + G_EXEC rm -Rf /var/log/motioneye + G_EXEC rm -Rf /var/lib/motioneye G_AGP motion - [[ -d '/etc/motioneye' ]] && G_EXEC rm -R /etc/motioneye - [[ -d '/var/log/motioneye' ]] && G_EXEC rm -R /var/log/motioneye - [[ -d '/var/lib/motioneye' ]] && G_EXEC rm -R /var/lib/motioneye [[ -d '/mnt/dietpi_userdata/motioneye' ]] && G_DIETPI-NOTIFY 2 'The motionEye media directory is left in place. You can manually remove it via:\n rm -R /mnt/dietpi_userdata/motioneye' fi @@ -12833,9 +12843,10 @@ _EOF_ if To_Uninstall 139 # SABnzbd then Remove_Service sabnzbd 1 1 # group for pre-v6.33 - [[ -d '/etc/sabnzbd' ]] && G_EXEC rm -R /etc/sabnzbd - [[ -d '/mnt/dietpi_userdata/downloads/sabnzbd_admin' ]] && G_EXEC rm -R /mnt/dietpi_userdata/downloads/sabnzbd_admin - [[ -d '/mnt/dietpi_userdata/downloads/sabnzbd_nzb_backup' ]] && G_EXEC rm -R /mnt/dietpi_userdata/downloads/sabnzbd_nzb_backup + G_EXEC rm -Rf /opt/sabnzbd + G_EXEC rm -Rf /etc/sabnzbd + G_EXEC rm -Rf /mnt/dietpi_userdata/downloads/sabnzbd_admin + G_EXEC rm -Rf /mnt/dietpi_userdata/downloads/sabnzbd_nzb_backup [[ -d '/var/log/sabnzbd' ]] && G_EXEC rm -R /var/log/sabnzbd # Pre-v7.9 fi @@ -12952,7 +12963,7 @@ _EOF_ if To_Uninstall 180 # Bazarr then Remove_Service bazarr 1 - G_EXEC rm -Rf /opt/bazarr /mnt/dietpi_userdata/bazarr /var/log/bazarr + G_EXEC rm -Rf /opt/bazarr_venv /opt/bazarr /mnt/dietpi_userdata/bazarr /var/log/bazarr fi if To_Uninstall 200 # DietPi-Dashboard @@ -13010,7 +13021,8 @@ _EOF_ if To_Uninstall 155 # HTPC Manager then Remove_Service htpc-manager - [[ -d '/mnt/dietpi_userdata/htpc-manager' ]] && G_EXEC rm -R /mnt/dietpi_userdata/htpc-manager + G_EXEC rm -Rf /opt/htpc-manager + G_EXEC rm -Rf /mnt/dietpi_userdata/htpc-manager fi if To_Uninstall 150 # Mono @@ -13132,7 +13144,7 @@ _EOF_ [[ -f '/etc/apt/sources.list.d/dietpi-mopidy.list' ]] && G_EXEC rm /etc/apt/sources.list.d/dietpi-mopidy.list [[ -f '/etc/apt/trusted.gpg.d/dietpi-mopidy.gpg' ]] && G_EXEC rm /etc/apt/trusted.gpg.d/dietpi-mopidy.gpg - command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y Mopidy-MusicBox-Webclient + command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y --break-system-packages --root-user-action=ignore Mopidy-MusicBox-Webclient getent passwd mopidy > /dev/null && G_EXEC userdel mopidy [[ -d '/mnt/dietpi_userdata/mopidy' ]] && G_EXEC rm -R /mnt/dietpi_userdata/mopidy @@ -13861,8 +13873,6 @@ _EOF_ if To_Uninstall 134 # Docker Compose then G_AGP docker-compose-plugin docker-compose - [[ -f '/usr/local/bin/docker-compose' ]] && G_EXEC rm /usr/local/bin/docker-compose # Pre-v8.14 - command -v docker-compose > /dev/null && command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y docker-compose # Pre-v8.2 fi if To_Uninstall 162 # Docker @@ -14231,9 +14241,9 @@ _EOF_ if To_Uninstall 130 # Python 3 then - command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y pip setuptools wheel - G_AGP python3-dev python3-pip # python3-pip: Pre-v6.32 - [[ -f '/etc/pip.conf' ]] && G_EXEC rm /etc/pip.conf + command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y --break-system-packages --root-user-action=ignore pip setuptools wheel # Pre-v10.1 + G_AGP python3-{dev,venv,pip} + G_EXEC rm -f /etc/pip.conf G_EXEC rm -Rf /{root,home/*}/.cache/pip fi