diff --git a/.conf/desktop/apps/dietpi-justboom.desktop b/.conf/desktop/apps/dietpi-justboom.desktop index 1a899643f7..ce5c19a4de 100644 --- a/.conf/desktop/apps/dietpi-justboom.desktop +++ b/.conf/desktop/apps/dietpi-justboom.desktop @@ -2,7 +2,7 @@ Version=1.0 Name=DietPi-JustBoom Type=Application -Comment=Tweak audio options for your JustBoom (and others) soundcard +Comment=Tweak your sound card, MPD and CAVA settings Terminal=true Exec=/boot/dietpi/misc/dietpi-justboom Icon=/var/lib/dietpi/dietpi-software/installed/desktop/icons/justboom.png diff --git a/.conf/dps_182/unbound.conf b/.conf/dps_182/unbound.conf index fae6b564d5..f393d0781f 100644 --- a/.conf/dps_182/unbound.conf +++ b/.conf/dps_182/unbound.conf @@ -47,7 +47,6 @@ server: do-tcp: yes do-ip4: yes do-ip6: yes - prefer-ip6: no # DNS root server information file. Updated monthly via cron job: /etc/cron.monthly/dietpi-unbound root-hints: "/var/lib/unbound/root.hints" diff --git a/.meta/dietpi-build b/.meta/dietpi-build index 843c49597f..463c1b960b 100644 --- a/.meta/dietpi-build +++ b/.meta/dietpi-build @@ -37,24 +37,26 @@ done # Check for valid target hardware model and set variables accordingly WIFI_REQUIRED=1 -partition_start=4 +partition_start=1 efi_size=64 -boot_size=128 -root_size=892 +boot_size=0 +root_size=1023 CLONING_TOOL='dd' case $HW_MODEL in - 0) iname='RPi';; - 20) iname='VM' WIFI_REQUIRED=0 boot_size=0;; - 21) iname='NativePC-BIOS' HW_ARCH=10 root_size=1152;; + 0) iname='RPi' partition_start=4 boot_size=128 root_size=892;; + 20) iname='VM' WIFI_REQUIRED=0;; + 21) iname='NativePC-BIOS' HW_ARCH=10 root_size=1215;; *) G_DIETPI-NOTIFY 1 "Invalid hardware model \"$HW_MODEL\" passed, aborting..."; exit 1;; esac # Check for valid target architecture and set variables accordingly +repo='https://deb.debian.org/debian/' +keyring='/usr/share/keyrings/debian-archive-keyring.gpg' case $HW_ARCH in - 1) iarch='ARMv6' parch='armhf' repo='http://raspbian.raspberrypi.org/raspbian/';; - 2) iarch='ARMv7' parch='armhf' repo='https://deb.debian.org/debian/';; - 3) iarch='ARMv8' parch='arm64' repo='https://deb.debian.org/debian/';; - 10) iarch='x86_64' parch='amd64' repo='https://deb.debian.org/debian/' partition_start=1;; + 1) iarch='ARMv6' parch='armhf' repo='http://raspbian.raspberrypi.org/raspbian/' keyring='/usr/share/keyrings/raspbian-archive-keyring.gpg';; + 2) iarch='ARMv7' parch='armhf';; + 3) iarch='ARMv8' parch='arm64';; + 10) iarch='x86_64' parch='amd64';; *) G_DIETPI-NOTIFY 1 "Invalid architecture \"$HW_ARCH\" passed, aborting..."; exit 1;; esac @@ -86,7 +88,7 @@ G_EXEC fallocate -l "$((partition_start+efi_size+boot_size+root_size))M" "$OUTPU if [[ $PTTYPE == 'gpt' ]] then G_EXEC parted -s "$OUTPUT_IMG_NAME.img" unit MiB mklabel gpt mkpart 'EFI' fat32 $partition_start $((partition_start+efi_size)) set 1 esp on - # Create boot partition it set + # Create boot partition if set (( $boot_size )) && G_EXEC parted -s "$OUTPUT_IMG_NAME.img" unit MiB mkpart 'boot' fat32 $((partition_start+efi_size)) $((partition_start+efi_size+boot_size)) # root partition G_EXEC parted -s "$OUTPUT_IMG_NAME.img" unit MiB mkpart 'root' "$FSTYPE" $((partition_start+efi_size+boot_size)) 100% @@ -94,7 +96,7 @@ then # MBR: Set partition types instead of labels else G_EXEC parted -s "$OUTPUT_IMG_NAME.img" unit MiB mklabel msdos - # Create boot partition it set + # Create boot partition if set (( $boot_size )) && G_EXEC parted -s "$OUTPUT_IMG_NAME.img" unit MiB mkpart primary fat32 $((partition_start)) $((partition_start+boot_size)) # root partition G_EXEC parted -s "$OUTPUT_IMG_NAME.img" unit MiB mkpart primary "$FSTYPE" $((partition_start+boot_size)) 100% @@ -200,7 +202,7 @@ exit 0 _EOF_ # Bootstrap -G_EXEC_OUTPUT=1 G_EXEC debootstrap --arch="$parch" --variant=minbase --exclude='gcc-7-base,gcc-8-base,gcc-9-base' --include='bash-completion,bzip2,ca-certificates,console-setup,cron,curl,dropbear,ethtool,fake-hwclock,fdisk,gnupg,htop,ifupdown,isc-dhcp-client,kmod,locales,nano,p7zip,parted,procps,psmisc,rfkill,sudo,systemd-sysv,systemd-timesyncd,tzdata,udev,unzip,usbutils,wget,whiptail' bullseye ./rootfs "$repo" +G_EXEC_OUTPUT=1 G_EXEC debootstrap --variant=minbase --exclude='gcc-7-base,gcc-8-base,gcc-9-base' --include='bash-completion,bzip2,ca-certificates,console-setup,cron,curl,dropbear,ethtool,fake-hwclock,fdisk,gnupg,htop,ifupdown,isc-dhcp-client,kmod,locales,nano,p7zip,parted,procps,psmisc,rfkill,sudo,systemd-sysv,systemd-timesyncd,tzdata,udev,unzip,usbutils,wget,whiptail' --arch="$parch" --keyring="$keyring" bullseye ./rootfs "$repo" # Remove cached archives and list files created by debootstrap G_EXEC rm -Rf rootfs/var/{cache/apt,lib/apt/lists}/* @@ -215,11 +217,10 @@ then G_EXEC systemctl start dbus.socket dbus fi # - Bind mounts required to allow container reading its own drive info, /dev/disk for GRUB and probably other tools to detect UUIDs -# - CAP_IPC_LOCK required for mlock/mlockall, used by vmtouch abind=() [[ -b '/dev/loop0p2' ]] && abind=('--bind=/dev/loop0p2') [[ -b '/dev/loop0p3' ]] && abind+=('--bind=/dev/loop0p3') -systemd-nspawn -bD rootfs --bind=/dev/loop0 --bind=/dev/loop0p1 "${abind[@]}" --bind=/dev/disk --capability=CAP_IPC_LOCK || exit 1 +systemd-nspawn -bD rootfs --bind=/dev/loop0 --bind=/dev/loop0p1 "${abind[@]}" --bind=/dev/disk || exit 1 [[ -f 'rootfs/success' ]] || { G_DIETPI-NOTIFY 1 'The container setup did not finish successfully, aborting...'; exit 1; } G_EXEC rm rootfs/success G_EXEC sync @@ -233,8 +234,5 @@ G_EXEC losetup -d /dev/loop0 export FP_ROOT_DEV CLONING_TOOL OUTPUT_IMG_NAME MOUNT_IT='Off' bash -c "$(curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.meta/dietpi-imager")" 'DietPi-Imager' "$OUTPUT_IMG_NAME.img" || exit 1 -# Upload -[[ -x 'upload.sh' ]] && ./upload.sh "$OUTPUT_IMG_NAME.7z" - exit 0 } diff --git a/.meta/dietpi-imager b/.meta/dietpi-imager index 4b2879d914..2da6df9633 100755 --- a/.meta/dietpi-imager +++ b/.meta/dietpi-imager @@ -345,8 +345,12 @@ then # Disable and enable journal to clear it and allow further size reduction G_EXEC tune2fs -O '^has_journal' "$FP_ROOT_DEV" + G_EXEC sync + G_EXEC sleep 1 G_EXEC tune2fs -O 'has_journal' "$FP_ROOT_DEV" - + G_EXEC sync + G_EXEC sleep 1 + # Run multiple times until no change is done any more G_DIETPI-NOTIFY 2 'Shrinking root filesystem to minimum size...' local out diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index 1c060493f5..b79af96024 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -265,7 +265,7 @@ shopt -s extglob [80]='Ubooquity' [81]='LLSP' [82]='LLMP' - [83]='Apache2' + [83]='Apache' [84]='Lighttpd' [85]='Nginx' [86]='Roon Extension Manager' @@ -577,8 +577,15 @@ shopt -s extglob unset -v 'aSOFTWARE_NAME7_8[99]' # emonHub aSOFTWARE_NAME7_8[200]='DietPi-Dashboard' + # v7.9 + aSOFTWARE_NAME7_9=() + for i in "${!aSOFTWARE_NAME7_8[@]}" + do + aSOFTWARE_NAME7_9[$i]=${aSOFTWARE_NAME7_8[$i]} + done + # Pre-create software counter array so that we can see also software (available in newest version) with 0 installs - for i in "${aSOFTWARE_NAME7_8[@]}" + for i in "${aSOFTWARE_NAME7_9[@]}" do aSOFTWARE["$i"]=0 done @@ -1232,12 +1239,17 @@ _EOF_ # Move HTML page in place mv index.html /var/www/survey/index.html + # Get current total system count and calculate new system count + local total=$(influx -database 'survey' -execute 'select total from systems order by desc limit 1' | mawk 'END{print $2}') + local new=$(( $SURVEY_COUNT_TOTAL - $total + $SURVEY_COUNT_INACTIVE - $SURVEY_COUNT_REACTIVE )) + # Create InfluxDB query query=("insert systems total=$SURVEY_COUNT_TOTAL") query+=("insert systems optin=$SURVEY_COUNT_OPTIN") query+=("insert systems optout=$SURVEY_COUNT_OPTOUT") query+=("insert systems inactive=$SURVEY_COUNT_INACTIVE") query+=("insert systems reactive=$SURVEY_COUNT_REACTIVE") + query+=("insert systems new=$new") for i in "${!aDIETPI_VERSION[@]}" do query+=("insert version $i=${aDIETPI_VERSION[$i]}") diff --git a/.update/patches b/.update/patches index 93ecf9b4cb..10fedc9cfe 100644 --- a/.update/patches +++ b/.update/patches @@ -543,7 +543,10 @@ Patch_7_8() \nNew DietPi-Backup log files are now created within the chosen backup directory. The existing old log is moved from /var/log/dietpi-backup.log to /tmp/dietpi-backup.log in case you need to review it.' G_EXEC mv /{var/log,tmp}/dietpi-backup.log fi +} +Patch_7_9() +{ # On Raspberry Pi, for backwards compatibility with software compiled against older libraspberrypi0, create symlinks from old to new filenames if (( $G_HW_MODEL < 10 && $G_HW_ARCH < 3 )) && dpkg-query -s 'libraspberrypi0' &> /dev/null then @@ -557,6 +560,21 @@ Patch_7_8() done < <(dpkg -L 'libraspberrypi0' | grep '^/usr/lib/arm-linux-gnueabihf/.*\.so.0$') fi + + # Update choice and preference index variables + [[ -f '/boot/dietpi/.installed' ]] && G_EXEC sed -Ei -e 's/INDEX_(LOGGING|WEBSERVER|DESKTOP|BROWSER)_CURRENT/INDEX_\1/g' -e '/INDEX_(LOGGING|WEBSERVER|DESKTOP|BROWSER|SSHSERVER|FILESERVER)_TARGET/d' -e '/INDEX_(SSHSERVER|FILESERVER)_CURRENT/d' /boot/dietpi/.installed + + # Offer to update DietPi-Dashboard TCP port: https://github.com/MichaIng/DietPi/issues/4966 + if [[ -f '/opt/dietpi-dashboard/config.toml' ]] && grep -Eq '^[[:blank:]]*port[[:blank:]]+=[[:blank:]]+8088$' /opt/dietpi-dashboard/config.toml + then + G_WHIP_BUTTON_CANCEL_TEXT='No' G_WHIP_YESNO '[ INFO ] Changed DietPi-Dashboard TCP port +\nThe default TCP network port for the DietPi-Dashboard has been changed from 8088 to 5252 to resolve a port conflict with InfluxDB. However, if you do not use or plan to use InfluxDB, port 8088 does not cause any issues. +\nDo you want to apply this change as well to your DietPi-Dashboard installation?' && G_CONFIG_INJECT 'port[[:blank:]]' 'port = 5252' /opt/dietpi-dashboard/config.toml + fi + + # ownCloud/Nextcloud: Disable maintenance mode once manually, since DietPi-Services enabled of before this update but doesn't handle/disable it anymore afterwards. + [[ -f '/var/www/owncloud/config/config.php' ]] && grep -Eq "^[[:blank:]]*'maintenance'[[:blank:]]+=>[[:blank:]]+true,\$" /var/www/owncloud/config/config.php && G_EXEC sed -Ei "s/^[[:blank:]]*'maintenance'[[:blank:]]+=>[[:blank:]]+true,\$/ 'maintenance' => false,/" /var/www/owncloud/config/config.php + [[ -f '/var/www/nextcloud/config/config.php' ]] && grep -Eq "^[[:blank:]]*'maintenance'[[:blank:]]+=>[[:blank:]]+true,\$" /var/www/nextcloud/config/config.php && G_EXEC sed -Ei "s/^[[:blank:]]*'maintenance'[[:blank:]]+=>[[:blank:]]+true,\$/ 'maintenance' => false,/" /var/www/nextcloud/config/config.php } # v6.35 => v7 migration diff --git a/.update/version b/.update/version index 49953c4a6b..78d236ecf9 100644 --- a/.update/version +++ b/.update/version @@ -1,7 +1,7 @@ # Available DietPi version G_REMOTE_VERSION_CORE=7 -G_REMOTE_VERSION_SUB=8 -G_REMOTE_VERSION_RC=2 +G_REMOTE_VERSION_SUB=9 +G_REMOTE_VERSION_RC=3 # Minimum DietPi version to allow update G_MIN_VERSION_CORE=6 G_MIN_VERSION_SUB=0 @@ -12,18 +12,6 @@ G_MIN_DEBIAN=4 # Alternative Git branch to automatically migrate to when Debian version is too low G_OLD_DEBIAN_BRANCH='jessie-support' # Live patches -G_LIVE_PATCH_DESC=( - [0]='Fix ReadyMedia, Deluge, Sonarr and Jellyfin installs' - [1]='Fix DietPi-Backup when using a location other than /mnt/dietpi-backup' - [2]='Fix Transmission install' -) -G_LIVE_PATCH_COND=( - [0]='! grep -q "G_EXEC systemctl stop minidlna" /boot/dietpi/dietpi-software' - [1]='grep -q "aRSYNC_LOGGING_OPTIONS" /boot/dietpi/dietpi-backup' - [2]='! grep -q "G_EXEC systemctl stop transmission-daemon" /boot/dietpi/dietpi-software' -) -G_LIVE_PATCH=( - [0]='sed -Ei "s/(G_AGI (minidlna|deluged|sonarr|jellyfin).*$)/\\1\\nG_EXEC systemctl stop \\2/" /boot/dietpi/dietpi-software' - [1]='curl -sSfL "https://raw.githubusercontent.com/MichaIng/DietPi/live-patch-1-v78/dietpi/dietpi-backup" -o /boot/dietpi/dietpi-backup' - [2]='sed -i "/G_AGI transmission-daemon/a\G_EXEC systemctl stop transmission-daemon" /boot/dietpi/dietpi-software' -) +G_LIVE_PATCH_DESC=() +G_LIVE_PATCH_COND=() +G_LIVE_PATCH=() diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 41ae71afcd..5133387b13 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,51 @@ +v7.9 +(2021-12-11) + +Stretch support: +- This is the last DietPi release with support for Debian Stretch. Next release will be DietPi v8.0 which requires Debian Buster or newer. Read our article about why we need to make this move and how you can easily upgrade your system to Debian Buster and even further to current stable Debian Bullseye: https://dietpi.com/blog/?p=1001 + +Changes: +- Raspberry Pi | Since Bullseye, some media software titles, most importantly FFmpeg and those which make use of FFmpeg libraries compiled for Raspberry Pi firmware (Kodi, Jellyfin, Chromium), utilise the Raspberry Pi V4L2 codec drivers. Those were previously enabled/disabled with the RPi camera module switch in dietpi-config. The hardware codec drivers have now become an own CLI command and menu switch in the dietpi-config display options and are enabled automatically when one of the mentioned software titles is installed or reinstalled on Bullseye (or above). +- DietPi-Dashboard | On fresh installs, password protection is now enabled by default, using the global software password. You can apply or change this manually by following the instructions in our documentation: https://dietpi.com/docs/software/system_stats/#dietpi-dashboard +- DietPi-Dashboard | The default TCP network port has been changed from 8088 to 5252 to resolve a port conflict with InfluxDB. This does not affect existing installs, but you will be asked whether to apply this change during DietPi update. Many thanks to @blablazzz for reporting this issue: https://github.com/MichaIng/DietPi/issues/4966 +- DietPi-Backup | A backup archive with a selectable amount of backups to keep can be created now. Backups are rotated automatically and if the maximum amount has been reached, the oldest backup is used as basis for the incremental new backup sync, to reduce writes and increase speed. Many thanks to @johnvick and many others for requesting this feature: https://dietpi.com/phpbb/viewtopic.php?t=3593 +- DietPi-Backup | Backups can now be stored outside of /mnt into any directory or mount point as long as the filesystem supports symlinks and UNIX permissions. +- DietPi-Software | The file server choice menu has been removed. Most file servers can run concurrently, hence it is not required to remove e.g. a Samba server to install an FTP server, so that a dedicated menu lost its reason. File servers can be selected the regular way via "Browse/Search Software" menus or CLI. The related dietpi.txt setting has been removed for new images as well, but it will still be respected when present. For an automated install with new images, use the "AUTO_SETUP_INSTALL_SOFTWARE_ID" setting instead. +- DietPi-Software | SABnzbd: For fresh installs, file logging has been disabled in favour of journal logging. All service and process logs can hence now be reviewed via: journalctl -u sabnzbd +- DietPi-Software | Apache: Fresh installs and reinstalls will be configured with PHP-FPM instead of mod_php. As a requirement, the event MPM is used instead of prefork. This reduces memory usage and increases access performance significantly on concurrent requests, as the Apache parent process does not need to fork a new child process for every single process. We further optimised it by spawning a single static child process only while handling concurrent requests by a sufficient amount of process threads. This allows Apache to share memory efficiently and makes it quite lightweight. There are no downsides known when using a single process only, compared to multiple processes with less threads each. Related StackExchange questions: https://superuser.com/questions/1611015/apache2-mpm-event-more-threads-vs-more-processes +- DietPi-Software | Apache: Our default/base configuration is now added as separate file, so that the main apache2.conf is not touched anymore. Furthermore the default vhost is now pre-created before the package install, so that it can be skipped on a reinstall to not overwrite user customisations. These in combination allow for a safe and clean reinstall without breaking any changes done by the admin, with the little exception that the webroot is set to /var/www which is required for all our software options which make use of an external webserver. +- DietPi-Software | Apache: Our new default config provides maximum privacy settings and security headers. It is trivial to override these with own configurations, on vhost or directory level. +- DietPi-Software | Apache: Logging is now done to journal (journalctl -u apache2) by default and the ServerName directive added with the local IP, to mute related startup warnings. This may imply access and CORS failures when applications check for the server name as allowed hostname but a different external IPs/hostnames was used for access. In such case generally applications provide a way to define a list of permitted hostnames. Without a server name set, usually webserver simply apply the HTTP_HOST header, which bypasses every related check. Apache, according to the logged warning, seems to use 127.0.1.1 then. +- DietPi-Software | Kodi: On Raspberry Pi Bullseye systems, the new official Raspberry Pi repository build for Kodi 19.3 is now installed. You can apply the upgrade manually by reinstalling Kodi: dietpi-software reinstall 31 +- DietPi-Software | Kodi: The addon repository is now installed by default with all Kodi installs, which previously was the case only on RPi and Odroids. When currently missing, it can be manually installed: apt install kodi-repository-kodi +- DietPi-Software | Gitea: The service runs now as dedicated user "gitea" with its home directory "/mnt/dietpi_userdata/gitea" to allow easy transfer and usage of SSH keys for remote access. This applies to newly installed or reinstalled Gitea instances. Many thanks to @LilTrublMakr for reporting the related limitation with the previously used "dietpi" user: https://github.com/MichaIng/DietPi/issues/4620 +- DietPi-Software | Chromium: On Raspberry Pi, the chromium-codecs-ffmpeg-extra package is now installed together with Chromium, which adds additional codecs for patented video/audio formats. Many thanks to @Krawei for identifying this Chromium video playback enhancement: https://github.com/MichaIng/DietPi/issues/5013 +- DietPi-Software | rTorrent: By default on fresh installs, rTorrent now listens on TCP port 49164 for incoming BitTorrent connections. Aside of DHT, listening for incoming connections was completely disabled before, which lead to slow or no peer connections, depending on the tracker used. Many thanks to @Camry2731 for reporting this inconsistency with our other BitTorrent server options. + +Fixes: +- Raspberry Pi | Resolved an issue in our images where on first boot two serial login consoles on the generic symlinked and actual serial devices could have been started. This doubled inputs and in turn broke successful username and password login via serial console on first boot. Many thanks to @ad7718 for reporting this issue: https://github.com/MichaIng/DietPi/issues/5014 +- DietPi-Backup | Resolved an issue where backup and restore failed if a non-default backup location is used, as a wrong log file path was used. This is a v7.8 regression. Many thanks to @Malinka for reporting this issue: https://dietpi.com/phpbb/viewtopic.php?p=39909#p39909 +- DietPi-Config | Resolved an issue where enabling the "odroid-lcd35" LCD panel on Odroids failed as SPI is enabled by default, blocking the same GPIO ports. Many thanks to @MarcProux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4154 +- DietPi-Config | Resolved an issue where the network adapter menu did not show the static DNS server(s) effetively applied at first boot based on dietpi.txt settings. Many thanks to @nils-trubkin for reporting this issue: https://github.com/MichaIng/DietPi/issues/5054 +- DietPi-Software | Resolved a v7.8 regression where ReadyMedia, Deluge, Sonarr and Jellyfin installs failed with an error on "usermod", since the services were not stopped first. This has been loved via live patches for v7.8 as well. +- DietPi-Software | Transmission: Resolved a v7.8 regression where on fresh installs the intended configuration was not deployed. Many thanks to @kannz and @alessandro.psrt for reporting this issue: https://dietpi.com/phpbb/viewtopic.php?t=9567, https://dietpi.com/phpbb/viewtopic.php?t=9683 +- DietPi-Software | SABnzbd: Resolved an issue where installs failed on ARMv6 and ARMv7 Stretch systems. Many thanks to @bensp for reporting this issue: https://github.com/MichaIng/DietPi/issues/4997 +- DietPi-Software | Deluge: Worked around an issue on Raspberry Pi ARMv6 userland systems where the service failed to start. Deluge has hence been re-enabled for this systems. Many thanks to @themagicbullet for providing the workaround: https://github.com/MichaIng/DietPi/issues/4944 +- DietPi-Software | UnRAR: Resolved an issue on Raspberry Pi 1 an Zero (1) where an incompatible "unrar" binary was installed. "unrar-free" from Raspbian is installed now on these models, but note that it does not fully support all RAR formats and may hence fail to extract archives in some cases. +- DietPi-Software | rTorrent: Resolved an issue where with Apache webserver the /RPC2 proxy to the rTorrent UNIX socket did not work due to invalid syntax. Many thanks to @Camry2731 for reporting this issue. +- DietPi-Software | RealVNC: Updated/fixed the workaround for a failing first start of RealVNC due to a cleared password file. Many thanks to @xmicky for reporting this issue: https://github.com/MichaIng/DietPi/issues/5050 + +As always, many smaller code performance and stability improvements, visual and spelling fixes have been done, too much to list all of them here. Check out all code changes of this release on GitHub: https://github.com/MichaIng/DietPi/pull/5053 + +Known/Outstanding Issues: +- DietPi-Config | Enabling WiFi + Ethernet adapters, both on different subnets, breaks WiFi connection in some cases: https://github.com/MichaIng/DietPi/issues/2103 + +For all additional issues that may appear after release, please see the following link for active tickets: https://github.com/MichaIng/DietPi/issues + +----------------------------------------------------------------------------------------------------------- + v7.8 -(2021-10-13) +(2021-11-13) New SBC support: - Radxa Zero | Initial support for this Raspberry Pi Zero form factored (but way more powerful) SBC has been added to DietPi with the hardware ID 74. Many thanks to @almirus and @dhry for helping with testing and debugging an early image: https://github.com/MichaIng/DietPi/issues/4831 @@ -47,11 +93,6 @@ Fixes: As always, many smaller code performance and stability improvements, visual and spelling fixes have been done, too much to list all of them here. Check out all code changes of this release on GitHub: https://github.com/MichaIng/DietPi/pull/4951 -Known/Outstanding Issues: -- DietPi-Config | Enabling WiFi + Ethernet adapters, both on different subnets, breaks WiFi connection in some cases: https://github.com/MichaIng/DietPi/issues/2103 - -For all additional issues that may appear after release, please see the following link for active tickets: https://github.com/MichaIng/DietPi/issues - ----------------------------------------------------------------------------------------------------------- v7.7 @@ -1493,7 +1534,7 @@ ASUS TB | Resolved square (broken) X11 fonts. Raspberry Pi | Removed "initial_turbo" setting from DietPi-Config and config.txt, as it prevents CPU governor from throttling down: https://github.com/MichaIng/DietPi/issues/1836 DietPi-Drive_Manager | Resolved incorrect detection of available drives: https://github.com/MichaIng/DietPi/issues/1858 DietPi-Software | GMrender: Resolved an issue where two systems on the same network would nullify the other. Hostname is now used for the server name, UUID used is applied via DietPi generated UUID during 1st run: https://dietpi.com/phpbb/viewtopic.php?p=12985#p12985 -DietPi-Software | Apache2: Fixed a syntax error that leads to Apache logging to "/error.log" instead of "/var/log/apache2/error.log" +DietPi-Software | Apache: Fixed a syntax error that leads to Apache logging to "/error.log" instead of "/var/log/apache2/error.log" DietPi-Software | Nukkit: Fixed the broken download link on installation. Many thanks to @symbios24 for reporting bug and providing solution: https://github.com/MichaIng/DietPi/issues/1875 DietPi-Software | Linux software: Resolved an issue with NULL entry being displayed: https://github.com/MichaIng/DietPi/pull/1830#issuecomment-401612168 DietPi-Config | Fixed an issue, where IPv6 could not be disabled on RPi. On current kernel version it is no dedicated kernel module any more and needs to be toggled via "/boot/cmdline.txt". @@ -1626,7 +1667,7 @@ DietPi-Software | Sonarr: Resolved failed installation for ARMv8 devices: https: DietPi-Software | Mono: Uninstalling this program, will now also uninstall the mono APT packages. DietPi-Software | Node-RED: User is now added to the GPIO group automatically: https://github.com/MichaIng/DietPi/issues/1687 DietPi-Software | Deluge: Resolved multiple issues where the deluge service would sometimes fail to run: https://github.com/MichaIng/DietPi/issues/1689#issuecomment-379017388 -DietPi-Software | Pi-hole: Workaround applied to prevent Lighttpd install during Pi-hole script, when Apache2/Nginx is installed: https://github.com/MichaIng/DietPi/issues/1696 +DietPi-Software | Pi-hole: Workaround applied to prevent Lighttpd install during Pi-hole script, when Apache/Nginx is installed: https://github.com/MichaIng/DietPi/issues/1696 ----------------------------------------------------------------------------------------------------------- diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index d24272a26b..b9d688f6fd 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -180,12 +180,12 @@ _EOF_ # Detect the distro version of this operating system distro=$( /etc/apt/sources.list.d/dietpi-radxa.list" + G_EXEC eval "curl -sSfL 'https://apt.radxa.com/${DISTRO_TARGET_NAME/bullseye/buster}-stable/public.key' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-radxa.gpg --yes" + G_EXEC eval "echo 'deb https://apt.radxa.com/${DISTRO_TARGET_NAME/bullseye/buster}-stable/ ${DISTRO_TARGET_NAME/bullseye/buster} main' > /etc/apt/sources.list.d/dietpi-radxa.list" G_AGUP # Remove obsolete combined keyring @@ -998,8 +980,8 @@ _EOF_ # Install Radxa APT repo cleanly: No Bullseye repo available yet G_EXEC rm -Rf /etc/apt/{trusted.gpg,sources.list.d/{,.??,.[^.]}*} - G_EXEC eval "curl -sSfL https://apt.radxa.com/${DISTRO_TARGET_NAME/bullseye/buster}-stable/public.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-radxa.gpg --yes" - G_EXEC eval "echo -e 'deb https://apt.radxa.com/${DISTRO_TARGET_NAME/bullseye/buster}-stable/ ${DISTRO_TARGET_NAME/bullseye/buster} main\n#deb https://apt.radxa.com/${DISTRO_TARGET_NAME/bullseye/buster}-testing/ ${DISTRO_TARGET_NAME/bullseye/buster} main' > /etc/apt/sources.list.d/dietpi-radxa.list" + G_EXEC eval "curl -sSfL 'https://apt.radxa.com/${DISTRO_TARGET_NAME/bullseye/buster}-stable/public.key' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-radxa.gpg --yes" + G_EXEC eval "echo 'deb https://apt.radxa.com/${DISTRO_TARGET_NAME/bullseye/buster}-stable/ ${DISTRO_TARGET_NAME/bullseye/buster} main' > /etc/apt/sources.list.d/dietpi-radxa.list" G_AGUP # Remove obsolete combined keyring @@ -1080,13 +1062,14 @@ _EOF_ unset -v apackages # Purging additional packages, that (in some cases) do not get autoremoved: + # - Purge the "important" e2fsprogs if no ext[2-4] filesystem is present on the root partition table # - dbus: Not required for headless images, but sometimes marked as "important", thus not autoremoved. # + Workaround for "The following packages have unmet dependencies: glib-networking libgtk-3-0" and alike # - dhcpcd5: https://github.com/MichaIng/DietPi/issues/1560#issuecomment-370136642 # - mountall: https://github.com/MichaIng/DietPi/issues/2613 # - initscripts: Pre-installed on Jessie systems (?), superseded and masked by systemd, but never autoremoved # - chrony: Found left with strange "deinstall ok installed" mark left on Armbian images - G_AGP dbus dhcpcd5 mountall initscripts chrony '*office*' '*xfce*' '*qt5*' '*xserver*' '*xorg*' glib-networking libgtk-3-0 libsoup2.4-1 libglib2.0-0 + G_AGP "${ae2fsprogs[@]}" dbus dhcpcd5 mountall initscripts chrony '*office*' '*xfce*' '*qt5*' '*xserver*' '*xorg*' glib-networking libgtk-3-0 libsoup2.4-1 libglib2.0-0 # Remove any autoremove prevention rm -fv /etc/apt/apt.conf.d/*autoremove* G_AGA @@ -1153,11 +1136,6 @@ _EOF_ fi - # Install vmtouch to lock DietPi scripts and config in file system cache - G_EXEC curl -sSfLO "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/vmtouch_$G_HW_ARCH_NAME.deb" - G_EXEC dpkg --force-hold,confnew -i "vmtouch_$G_HW_ARCH_NAME.deb" - rm -v "vmtouch_$G_HW_ARCH_NAME.deb" - G_DIETPI-NOTIFY 2 'Restoring default base files:' # shellcheck disable=SC2114 rm -Rfv /etc/{motd,profile,update-motd.d,issue{,.net}} /root /home /media /var/mail @@ -1258,7 +1236,7 @@ _EOF_ G_EXEC systemctl mask "${j##*/}" else - G_EXEC rm -R "$j" + [[ -e $j || -L $j ]] && G_EXEC rm -R "$j" fi done @@ -1447,7 +1425,7 @@ _EOF_' G_EXEC systemctl mask $i done - if (( $G_DISTRO > 5 )) + if command -v e2scrub > /dev/null then G_DIETPI-NOTIFY 2 'Disabling e2scrub services which are for LVM and require lvm2/lvcreate being installed' G_EXEC systemctl disable --now e2scrub_{all.timer,reap} @@ -1534,7 +1512,10 @@ _EOF_' if (( $G_HW_MODEL < 10 )); then /boot/dietpi/func/dietpi-set_hardware serialconsole disable ttyAMA0 + # The actual serial console services need to be masked explicitly to ensure they are not autostarted when the image is created within a container or without both serial devices present, since masks are only placed by dietpi-set_hardware for existing devices: : https://github.com/MichaIng/DietPi/issues/5014 + G_EXEC systemctl mask serial-getty@ttyAMA0 /boot/dietpi/func/dietpi-set_hardware serialconsole disable ttyS0 + G_EXEC systemctl mask serial-getty@ttyS0 /boot/dietpi/func/dietpi-set_hardware serialconsole enable serial0 # ROCK Pi S: Enable on ttyS0 only @@ -1703,8 +1684,9 @@ _EOF_ # Apply minimum GPU memory split for server usage: This applies a custom dtoverlay to disable VCSM: https://github.com/MichaIng/DietPi/pull/3900 /boot/dietpi/func/dietpi-set_hardware gpumemsplit 16 - # Disable RPi camera to add modules blacklist + # Disable RPi camera and codecs to add modules blacklist /boot/dietpi/func/dietpi-set_hardware rpi-camera disable + /boot/dietpi/func/dietpi-set_hardware rpi-codec disable # Update USBridgeSig Ethernet driver via postinst kernel script, until it has been merged into official RPi kernel: https://github.com/allocom/USBridgeSig/tree/master/ethernet cat << '_EOF_' > /etc/kernel/postinst.d/dietpi-USBridgeSig @@ -1750,6 +1732,23 @@ _EOF_ done G_EXEC sed -i 's/^#grep/grep/' /etc/kernel/postinst.d/dietpi-USBridgeSig + # Create RPi Zero 2 W device tree if not existent + [[ -f '/boot/bcm2710-rpi-zero-2.dtb' ]] || G_EXEC cp -a /boot/bcm2710-rpi-{3-b,zero-2}.dtb + + # For backwards compatibility with software compiled against older libraspberrypi0, create symlinks from old to new filenames + if (( $G_HW_ARCH < 3 )) + then + G_DIETPI-NOTIFY 2 'Applying workaround for compiled against older libraspberrypi0' + G_EXEC cd /usr/lib/arm-linux-gnueabihf + while read -r line + do + [[ ! -f $line || -f ${line%.0} ]] && continue + line=${line#/usr/lib/arm-linux-gnueabihf/} + G_EXEC ln -sf "$line" "${line%.0}" + + done < <(dpkg -L 'libraspberrypi0' | grep '^/usr/lib/arm-linux-gnueabihf/.*\.so.0$') + fi + # - PINE A64 (and possibly others): Cursor fix for FB elif (( $G_HW_MODEL == 40 )); then @@ -1779,6 +1778,13 @@ _EOF_ # Disable Docker optimisations, since this has some performance drawbacks, enable on Docker install instead G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=off' /boot/uEnv.txt fi + + # - NanoPi R1 + elif [[ $G_HW_MODEL == 48 && -f '/boot/armbianEnv.txt' ]] + then + # Enable second USB port by default + local current=$(sed -n '/^[[:blank:]]*overlays=/{s/^[^=]*=//p;q}' /boot/armbianEnv.txt) + [[ $current == *'usbhost2'* ]] || G_CONFIG_INJECT 'overlays=' "overlays=$current usbhost2" /boot/armbianEnv.txt fi # - Armbian special diff --git a/README.md b/README.md index 7190b2daf0..77de0be283 100644 --- a/README.md +++ b/README.md @@ -214,7 +214,6 @@ Links to hardware and software manufacturers, sources and build instructions use - [Radxa](https://github.com/radxa/apt) - [Armbian](https://github.com/armbian) - [curl](https://github.com/curl/curl) -- [vmtouch](https://github.com/hoytech/vmtouch) - [X.Org-X-Server](https://www.x.org/archive//individual/) - [LXDE desktop](https://github.com/LXDE) - [LXQt desktop](https://github.com/lxqt) @@ -234,7 +233,7 @@ Links to hardware and software manufacturers, sources and build instructions use - [MPD](https://github.com/MusicPlayerDaemon/MPD) - [YMPD](https://github.com/notandy/ympd) - [myMPD](https://github.com/jcorporation/myMPD) -- [Apache2](https://github.com/apache) +- [Apache](https://github.com/apache) - [Nginx](https://hg.nginx.org/nginx/) - [Lighttpd](https://redmine.lighttpd.net/projects/lighttpd/repository) - [PHP](https://git.php.net/) diff --git a/boot_c2.ini b/boot_c2.ini index f6fece247f..f279aac47e 100644 --- a/boot_c2.ini +++ b/boot_c2.ini @@ -31,7 +31,7 @@ setenv display_autodetect "true" setenv m "720p60hz" # Custom modeline! -# To use custom modeline you need to disable all the above resolutions. +# To use custom modeline you need to disable the above resolution # and setup your own! # For more information check our wiki: # http://odroid.com/dokuwiki/doku.php?id=en:c2_hdmi_autosetting @@ -61,18 +61,16 @@ setenv monitor_onoff "false" setenv cec "1" # Force HDMI to use RGB colorspace regardless of TV request -# 0 Disable -# 1 Enable +# 0 = Disable +# 1 = Enable setenv hdmi_forcergb "0" # Default console settings setenv condev "consoleblank=0 console=tty0 console=ttyS0,115200n8" # Meson Timer -# 1 - Meson Timer -# 0 - Arch Timer -# Using meson_timer improves the video playback however it breaks KVM (virtualization). -# Using arch timer allows KVM/Virtualization to work however you'll experience poor video +# 1 = Meson Timer: improves the video playback but breaks KVM/virtualization +# 0 = Arch Timer: allows KVM/virtualization to work but you'll experience poor video setenv mesontimer "1" # Disable video output @@ -126,7 +124,6 @@ if test "${hdmi_forcergb}" = "1"; then setenv forcergb "hdmitx=forcergb"; fi setenv bootargs "root=/dev/mmcblk0p2 rootwait ro ${condev} no_console_suspend hdmitx=${cec} ${forcergb} hdmimode=${m} m_bpp=${m_bpp} vout=${vout} fsck.repair=yes max_freq=${max_freq} maxcpus=${maxcpus} monitor_onoff=${monitor_onoff} disableuhs=${disableuhs} mmc_removable=${mmc_removable} usbmulticam=${usbmulticam} ${hid_quirks} net.ifnames=0 elevator=noop disablehpd=${hpd} ${cmode} systemd.unified_cgroup_hierarchy=0" # Booting - setenv loadaddr "0x11000000" setenv dtb_loadaddr "0x1000000" setenv initrd_loadaddr "0x13000000" diff --git a/boot_n2.ini b/boot_n2.ini index 7eb8bd5b1c..14fb409691 100644 --- a/boot_n2.ini +++ b/boot_n2.ini @@ -133,7 +133,7 @@ if test "x${max_freq_a53}" != "x"; then setenv a53_freq "max_freq_a53=${max_freq setenv bootlabel "DietPi (64-bit)" # Boot args -setenv bootargs "root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro ${condev} ${amlogic} no_console_suspend fsck.repair=yes net.ifnames=0 elevator=noop hdmimode=${hdmimode} cvbsmode=${cvbsmode} maxcpus=${maxcpus} voutmode=${voutmode} disablehpd=${disablehpd} enable_wol=${enable_wol} ${cec_enable} sdrmode=${sdrmode} consoleblank=0 logo=osd0,loaded monitor_onoff=${monitor_onoff} ${hid_quirks} ${cmode} overscan=${overscan} cvbscable=${cvbscable} systemd.unified_cgroup_hierarchy=0 ${a73_freq} ${a53_freq}" +setenv bootargs "root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro fsck.repair=yes elevator=noop net.ifnames=0 ${condev} no_console_suspend consoleblank=0 logo=osd0,loaded systemd.unified_cgroup_hierarchy=0 hdmimode=${hdmimode} cvbsmode=${cvbsmode} maxcpus=${maxcpus} voutmode=${voutmode} disablehpd=${disablehpd} enable_wol=${enable_wol} sdrmode=${sdrmode} monitor_onoff=${monitor_onoff} overscan=${overscan} cvbscable=${cvbscable} ${hid_quirks} ${cec_enable} ${cmode} ${amlogic} ${a73_freq} ${a53_freq}" # Set load addresses setenv dtb_loadaddr "0x1000000" diff --git a/boot_xu4.ini b/boot_xu4.ini index 1d74ec8745..6de4568a82 100644 --- a/boot_xu4.ini +++ b/boot_xu4.ini @@ -24,7 +24,7 @@ setenv vout "hdmi" # - DietPi will override this setting to user configured in dietpi-config > Performance Options > CPU governor setenv governor "performance" -# ODROID-VU7 touchsreen: "false" or "true", defaults to "true" +# ODROID-VU7 touchscreen: "false" or "true", defaults to "true" #setenv disable_vu7 "false" # DDR frequency [MHz]: "933", "825", "728" or "633", defaults to "825" @@ -63,9 +63,11 @@ setenv hdmi_clk_amp_lvl "31" # TMDS data source termination resistor control # - tx_res : 0 = Source Termination OFF(Min), 1 = 200 ohm, 2 = 300 ohm, 3 = 120 ohm(Max) -# - Hardkernrel default hdmi_tx_res = 0 (Source Termination OFF) +# - Hardkernel default hdmi_tx_res = 0 (Source Termination OFF) setenv hdmi_tx_res "0" +### DO NOT EDIT ANYTHING BELOW THIS LINE ### + setenv hdmi_phy_control "hdmi_tx_amp_lvl=${hdmi_tx_amp_lvl} hdmi_tx_lvl_ch0=${hdmi_tx_lvl_ch0} hdmi_tx_lvl_ch1=${hdmi_tx_lvl_ch1} hdmi_tx_lvl_ch2=${hdmi_tx_lvl_ch2} hdmi_tx_emp_lvl=${hdmi_tx_emp_lvl} hdmi_clk_amp_lvl=${hdmi_clk_amp_lvl} hdmi_tx_res=${hdmi_tx_res} HPD=${HPD} vout=${vout}" # Load kernel, initrd and dtb in that sequence @@ -86,8 +88,8 @@ if test "${disable_vu7}" = "false"; then setenv hid_quirks "usbhid.quirks=0x0eef # Set DDR frequency if test "x${ddr_freq}" != "x"; then dmc "${ddr_freq}"; fi -# Final boot args +# Final boot args (DRM debugging: drm.debug=0xff) setenv bootargs "${bootrootfs} ${videoconfig} smsc95xx.macaddr=${macaddr} governor=${governor} ${hdmi_phy_control} ${hid_quirks} systemd.unified_cgroup_hierarchy=0" -# drm.debug=0xff" + # Boot the board bootz 0x40008000 0x42000000 0x44000000 diff --git a/config.txt b/config.txt index 9c845e71ac..f8ee13cb23 100644 --- a/config.txt +++ b/config.txt @@ -38,8 +38,8 @@ # Set "hdmi_blanking=1" to allow the display going into standby after 10 minutes without input. # With default value "0", the display shows a blank screen instead, but will not go into standby. -# NB: With "1" some applications (e.g. Kodi, OMXPlayer) cannot prevent display standby due to missing DPMS signal. -#hdmi_blanking=1 +# NB: With "1" some legacy OpenMAX applications (OMXPlayer) cannot prevent display standby due to missing DPMS signal. +hdmi_blanking=1 # Set to "1" if your display has a black border of unused pixels visible. disable_overscan=1 diff --git a/dietpi.txt b/dietpi.txt index e73af71bab..3086536dea 100644 --- a/dietpi.txt +++ b/dietpi.txt @@ -56,7 +56,7 @@ AUTO_SETUP_SWAPFILE_SIZE=1 # Swap space location: "zram" => swap space on /dev/zram0 (auto-size = 50% of RAM size) | /path/to/file => swap file at location (auto-size = 2 GiB minus RAM size) AUTO_SETUP_SWAPFILE_LOCATION=/var/swap -# Set to "1" to disable HDMI output (and GPU/VPU where supported) for supported devices: RPi, Odroid C1, Odroid C2 +# Set to "1" to disable HDMI/video output and framebuffers on Raspberry Pi, to reduce power consumption and memory usage: Works on RPi only! AUTO_SETUP_HEADLESS=0 # Unmask (enable) systemd-logind service (including dbus), which is masked by default on DietPi @@ -82,15 +82,12 @@ AUTO_SETUP_BACKUP_RESTORE=0 # SSH server choice: 0=none/custom | -1=Dropbear | -2=OpenSSH AUTO_SETUP_SSH_SERVER_INDEX=-1 -# File server choice: 0=none/custom | -1=ProFTP | -2=Samba -AUTO_SETUP_FILE_SERVER_INDEX=0 - # Logging mode choice: 0=none/custom | -1=RAMlog 1h clear | -2=RAMlog 1h save clear | -3=rsyslog + logrotate AUTO_SETUP_LOGGING_INDEX=-1 # RAMlog max tmpfs size (MB). 50MB should be fine for single use. 200MB+ for heavy webserver and access log etc. AUTO_SETUP_RAMLOG_MAXSIZE=50 -# Webserver preference: 0=Apache2 | -1=Nginx | -2=Lighttpd +# Webserver preference: 0=Apache | -1=Nginx | -2=Lighttpd # - This defines the webserver to install (only) when another selected software requires one. # - It won't be installed if no other software requires a webserver and a manual webserver stack selection will override it. AUTO_SETUP_WEB_SERVER_INDEX=-2 diff --git a/dietpi/dietpi-backup b/dietpi/dietpi-backup index 50d0e7b7f4..13e82aacca 100644 --- a/dietpi/dietpi-backup +++ b/dietpi/dietpi-backup @@ -18,8 +18,8 @@ # - dietpi-backup 1 = Backup # # $2 = optional directory location to use with backup/restore input: - # - dietpi-backup -1 /mnt/MyDirectoryTarget = Restore - # - dietpi-backup 1 /mnt/MyDirectoryTarget = Backup + # - dietpi-backup -1 /path/to/target = Restore + # - dietpi-backup 1 /path/to/target = Backup #//////////////////////////////////// # Import DietPi-Globals -------------------------------------------------------------- @@ -36,13 +36,12 @@ #///////////////////////////////////////////////////////////////////////////////////// # Backup System #///////////////////////////////////////////////////////////////////////////////////// - readonly FP_LOG='dietpi-backup.log' - # Backup file paths FP_SOURCE='/' FP_TARGET='/mnt/dietpi-backup' - # File applied to successful backups, stored in "$FP_TARGET/$FP_STATS" + # Stats and transfer logs, stored to: $FP_TARGET/ + readonly FP_LOG='dietpi-backup.log' readonly FP_STATS='.dietpi-backup_stats' # Include/exclude file @@ -54,7 +53,6 @@ readonly aRSYNC_RUN_OPTIONS_BACKUP=('-aH' '--info=name0' '--info=progress2' '--delete-excluded' "--exclude-from=$FP_FILTER") # - Restore: Delete files in target which are not present in source, but after the transfer has finished, and leave excluded files untouched readonly aRSYNC_RUN_OPTIONS_RESTORE=('-aH' '--info=name0' '--info=progress2' '--delete-after' "--exclude-from=$FP_FILTER") - readonly aRSYNC_LOGGING_OPTIONS=('-v' "--log-file=$FP_TARGET/$FP_LOG") # Date format for logs Print_Date(){ date '+%Y-%m-%d_%T'; } @@ -71,38 +69,29 @@ Check_Supported_Directory_Location(){ - # Check location contains /mnt/ - if [[ $FP_TARGET == '/mnt/'* ]] + # Obtain filesystem type. Create directory temporarily for this if missing. + if [[ ! -d $FP_TARGET ]] then - # Check file system type. Create directory temporarily, if necessary. - if [[ ! -d $FP_TARGET ]] - then - G_EXEC mkdir -p "$FP_TARGET" - local fs_type=$(df -T "$FP_TARGET" | mawk 'NR==2 {print $2}') - G_EXEC rmdir "$FP_TARGET" - else - local fs_type=$(df -T "$FP_TARGET" | mawk 'NR==2 {print $2}') - fi - - # Check for supported filesystem type - if [[ $fs_type =~ ^(ext[2-4]|(f2|btr|x|z)fs)$ ]] - then - return 0 + G_EXEC mkdir -p "$FP_TARGET" + local fs_type=$(df -T "$FP_TARGET" | mawk 'NR==2 {print $2}') + G_EXEC rmdir "$FP_TARGET" + else + local fs_type=$(df -T "$FP_TARGET" | mawk 'NR==2 {print $2}') + fi - elif [[ $fs_type =~ ^nfs4?$ ]] - then - G_CHECK_FS_PERMISSION_SUPPORT "$FP_TARGET" && return 0 - G_DIETPI-NOTIFY 1 "NFS mount $FP_TARGET does not support UNIX permissions" - G_WHIP_MSG "Unsupported NFS share:\n\n$FP_TARGET is an NFS share which does not support UNIX permissions.\n\nMake sure that the NFS share at the server is located on a filesystem with native symlink and UNIX permissions support." - else - G_DIETPI-NOTIFY 1 "Filesystem type $fs_type not supported in $FP_TARGET" - G_WHIP_MSG "Filesystem type not supported:\n\n$FP_TARGET has a filesystem type of $fs_type, which is not supported.\n\nThe filesystem type must be ext2/3/4, F2FS, Btrfs, XFS, ZFS or a proper NFS mount with native symlink and UNIX permissions support." - fi + # Check for supported filesystem type + if [[ $fs_type =~ ^(ext[2-4]|(f2|btr|x|z)fs)$ ]] + then + return 0 - # Not inside /mnt + elif [[ $fs_type =~ ^nfs4?$ ]] + then + G_CHECK_FS_PERMISSION_SUPPORT "$FP_TARGET" && return 0 + G_DIETPI-NOTIFY 1 "NFS mount $FP_TARGET does not support UNIX permissions" + G_WHIP_MSG "Unsupported NFS share:\n\n$FP_TARGET is an NFS share which does not support UNIX permissions.\n\nMake sure that the NFS share at the server is located on a filesystem with native symlink and UNIX permissions support." else - G_DIETPI-NOTIFY 1 "Target directory is not inside /mnt ($FP_TARGET)" - G_WHIP_MSG "Directory not supported:\n- $FP_TARGET\n\nThe location must be inside the /mnt/* directory.\n - E.g.: /mnt/dietpi-backup" + G_DIETPI-NOTIFY 1 "Filesystem type $fs_type not supported in $FP_TARGET" + G_WHIP_MSG "Filesystem type not supported:\n\n$FP_TARGET has a filesystem type of $fs_type, which is not supported.\n\nThe filesystem type must be ext2/3/4, F2FS, Btrfs, XFS, ZFS or a proper NFS mount with native symlink and UNIX permissions support." fi return 1 @@ -144,81 +133,104 @@ _EOF_ # Check valid FS Check_Supported_Directory_Location || return 1 - # Generate target dir - G_EXEC_NOHALT=1 G_EXEC mkdir -p "$FP_TARGET/data" - - # Error: Unable to create target folder. - if [[ ! -d $FP_TARGET/data ]]; then - - G_WHIP_MSG "Backup failed:\n\nUnable to create $FP_TARGET/data" + # Rotate backups with more than 1 shall be kept + if (( $AMOUNT > 1 )) + then + G_DIETPI-NOTIFY 2 'Rotating backup archive' + if [[ -d $FP_TARGET/data_$AMOUNT ]] + then + [[ -d $FP_TARGET/data_tmp ]] && G_EXEC rm -R "$FP_TARGET/data_tmp" # Failsafe + G_EXEC mv "$FP_TARGET/data_$AMOUNT" "$FP_TARGET/data_tmp" + fi + if [[ -d $FP_TARGET/data ]] + then + for ((i=$AMOUNT-1;i>1;i--)) + do + [[ -d $FP_TARGET/data_$i ]] && G_EXEC mv "$FP_TARGET/data_$i" "$FP_TARGET/data_$((i+1))" + done + G_EXEC mv "$FP_TARGET/data" "$FP_TARGET/data_2" + fi + [[ -d $FP_TARGET/data_tmp ]] && G_EXEC mv "$FP_TARGET/data_tmp" "$FP_TARGET/data" + fi - else + # Remove backups above selected amount + local number + for i in "$FP_TARGET/data_"* + do + number=${i#"$FP_TARGET/data_"} + disable_error=1 G_CHECK_VALIDINT "$number" $(($AMOUNT+1)) || continue + G_EXEC_DESC="Removing backup number $number which is above the selected amount $AMOUNT" G_EXEC rm -R "$i" + done - /boot/dietpi/dietpi-services stop - - # Check if rsync is already running, while the daemon should have been stopped above - pgrep 'rsync' &> /dev/null && { Error_Rsync_Already_Running 'Backup'; return 1; } - - # Install required rsync if missing - G_AG_CHECK_INSTALL_PREREQ rsync - - # Generate Exclude/Include lists - Create_Filter_Include_Exclude - - # Check for sufficient free space - local old_backup_size=$(du -sB1 "$FP_TARGET/data" | mawk '{print $1}') # Actual disk usage in bytes - # - Dry run to obtain transferred data size - rsync --dry-run --stats "${aRSYNC_RUN_OPTIONS_BACKUP[@]}" "$FP_SOURCE" "$FP_TARGET/data/" > .dietpi-backup_result - local new_backup_size=$(grep -m1 '^Total file size:' .dietpi-backup_result | sed 's/[^0-9]*//g') # Apparent data size without block size related overhead - local total_file_count=$(mawk '/^Number of files:/{print $6;exit}' .dietpi-backup_result | sed 's/[^0-9]*//g') - local total_folder_count=$(mawk '/^Number of files:/{print $8;exit}' .dietpi-backup_result | sed 's/[^0-9]*//g') - rm .dietpi-backup_result - local target_fs_blocksize=$(stat -fc '%s' "$FP_TARGET/data") - new_backup_size=$(( $new_backup_size + ( $total_file_count + $total_folder_count ) * $target_fs_blocksize )) # Add one block size for each file + dir as worst case result - local end_result=$(( ( $new_backup_size - $old_backup_size ) / 1024**2 + 1 )) # bytes => MiB rounded up - # - Perform check - if ! G_CHECK_FREESPACE "$FP_TARGET/data" $end_result; then - - G_WHIP_BUTTON_OK_TEXT='Ignore' - G_WHIP_BUTTON_CANCEL_TEXT='Exit' - if ! G_WHIP_YESNO 'The backup target location appears to have insufficient free space to successfully finish the backup. + # Generate target directory if missing + [[ -d $FP_TARGET/data ]] || G_EXEC mkdir -p "$FP_TARGET/data" + + /boot/dietpi/dietpi-services stop + + # Check if rsync is already running, while the daemon should have been stopped above + pgrep 'rsync' &> /dev/null && { Error_Rsync_Already_Running 'Backup'; return 1; } + + # Install required rsync if missing + G_AG_CHECK_INSTALL_PREREQ rsync + + # Generate Exclude/Include lists + Create_Filter_Include_Exclude + + # Check for sufficient free space + local old_backup_size=$(du -sB1 "$FP_TARGET/data" | mawk '{print $1}') # Actual disk usage in bytes + # - Dry run to obtain transferred data size + rsync --dry-run --stats "${aRSYNC_RUN_OPTIONS_BACKUP[@]}" "$FP_SOURCE" "$FP_TARGET/data/" > .dietpi-backup_result + local new_backup_size=$(grep -m1 '^Total file size:' .dietpi-backup_result | sed 's/[^0-9]*//g') # Apparent data size without block size related overhead + local total_file_count=$(mawk '/^Number of files:/{print $6;exit}' .dietpi-backup_result | sed 's/[^0-9]*//g') + local total_folder_count=$(mawk '/^Number of files:/{print $8;exit}' .dietpi-backup_result | sed 's/[^0-9]*//g') + rm .dietpi-backup_result + local target_fs_blocksize=$(stat -fc '%s' "$FP_TARGET/data") + new_backup_size=$(( $new_backup_size + ( $total_file_count + $total_folder_count ) * $target_fs_blocksize )) # Add one block size for each file + dir as worst case result + local end_result=$(( ( $new_backup_size - $old_backup_size ) / 1024**2 + 1 )) # bytes => MiB rounded up + # - Perform check + if ! G_CHECK_FREESPACE "$FP_TARGET/data" $end_result; then + + G_WHIP_BUTTON_OK_TEXT='Ignore' + G_WHIP_BUTTON_CANCEL_TEXT='Exit' + if ! G_WHIP_YESNO 'The backup target location appears to have insufficient free space to successfully finish the backup. However, this check is a rough estimation in reasonable time, thus it could be marginally incorrect. \nWould you like to override this warning and continue with the backup?'; then - echo -e "Backup cancelled due to insufficient free space : $(Print_Date)" >> "$FP_TARGET/$FP_STATS" - /boot/dietpi/dietpi-services start - return 1 - - fi + echo -e "Backup cancelled due to insufficient free space : $(Print_Date)" >> "$FP_TARGET/$FP_STATS" + /boot/dietpi/dietpi-services start + return 1 fi - G_DIETPI-NOTIFY 2 "Backup to $FP_TARGET in progress, please wait..." + fi - # Init log file - echo -e "Backup log from $(Print_Date)\n" > "$FP_TARGET/$FP_LOG" + G_DIETPI-NOTIFY 2 "Backup to $FP_TARGET in progress, please wait..." - rsync "${aRSYNC_RUN_OPTIONS_BACKUP[@]}" "${aRSYNC_LOGGING_OPTIONS[@]}" "$FP_SOURCE" "$FP_TARGET/data/" - EXIT_CODE=$? + # Init log file + echo -e "Backup log from $(Print_Date)\n" > "$FP_TARGET/$FP_LOG" - /boot/dietpi/dietpi-services start + rsync "${aRSYNC_RUN_OPTIONS_BACKUP[@]}" -v --log-file="$FP_TARGET/$FP_LOG" "$FP_SOURCE" "$FP_TARGET/data/" + EXIT_CODE=$? - G_DIETPI-NOTIFY -1 $EXIT_CODE "$G_PROGRAM_NAME: Backup" - if (( $EXIT_CODE == 0 )); then + # touch target directory to show the correct last update timestamp when restoring one of multiple backups from the archive. This needs to be done after the backup since it applies the root / timestamps. + G_EXEC touch "$FP_TARGET/data" - echo -e "Backup completed : $(Print_Date)" >> "$FP_TARGET/$FP_STATS" - G_WHIP_MSG "Backup completed:\n - $FP_TARGET" + /boot/dietpi/dietpi-services start - else + G_DIETPI-NOTIFY -1 $EXIT_CODE "$G_PROGRAM_NAME: Backup" + if (( $EXIT_CODE == 0 )); then - G_WHIP_MSG "Backup failed:\n - $FP_TARGET\n\nYou will see the log file on the next screen. Please check it for information and/or errors." + echo -e "Backup completed : $(Print_Date)" >> "$FP_TARGET/$FP_STATS" + G_WHIP_MSG "Backup completed:\n - $FP_TARGET" - fi + else - log=1 G_WHIP_VIEWFILE "$FP_TARGET/$FP_LOG" + G_WHIP_MSG "Backup failed:\n - $FP_TARGET\n\nYou will see the log file on the next screen. Please check it for information and/or errors." fi + log=1 G_WHIP_VIEWFILE "$FP_TARGET/$FP_LOG" + } # When restoring a backup, assure that either the UUIDs stored in the backup fstab/boot config matches the current system drive, or that we know all relevant files to adjust afterwards. @@ -229,7 +241,7 @@ However, this check is a rough estimation in reasonable time, thus it could be m PARTUUID_ROOT=$(findmnt -Ufnro PARTUUID -M /) # If the current rootfs' UUID or PARTUUID can be found in the the backups fstab, it can be assumed that it was created from the same drives. - grep -q "^UUID=${UUID_ROOT}[[:blank:]]" "$FP_TARGET/data/etc/fstab" || grep -q "^PARTUUID=${PARTUUID_ROOT}[[:blank:]]" "$FP_TARGET/data/etc/fstab" && return 0 + grep -q "^UUID=${UUID_ROOT}[[:blank:]]" "$FP_TARGET/$DATA/etc/fstab" || grep -q "^PARTUUID=${PARTUUID_ROOT}[[:blank:]]" "$FP_TARGET/$DATA/etc/fstab" && return 0 UPDATE_UUIDs=1 @@ -240,22 +252,22 @@ However, this check is a rough estimation in reasonable time, thus it could be m UPDATE_GRUB=1 # - RPi - elif (( $G_HW_MODEL < 10 )) && [[ -f $FP_TARGET/data/boot/cmdline.txt ]] + elif (( $G_HW_MODEL < 10 )) && [[ -f $FP_TARGET/$DATA/boot/cmdline.txt ]] then UPDATE_RPI=1 # - Armbian - elif [[ -f $FP_TARGET/data/boot/armbianEnv.txt ]] + elif [[ -f $FP_TARGET/$DATA/boot/armbianEnv.txt ]] then UPDATE_ARMBIAN=1 # - Odroids / classic U-Boot - elif [[ -f $FP_TARGET/data/boot/boot.ini ]] + elif [[ -f $FP_TARGET/$DATA/boot/boot.ini ]] then UPDATE_ODROID=1 # - Modern U-Boot - elif [[ -f $FP_TARGET/data/boot/boot.cmd ]] && command -v mkimage > /dev/null + elif [[ -f $FP_TARGET/$DATA/boot/boot.cmd ]] && command -v mkimage > /dev/null then UPDATE_UBOOT=1 @@ -326,63 +338,61 @@ However, this check is a rough estimation in reasonable time, thus it could be m fi } + # $1: Optional restore point from the archive Run_Restore(){ + local DATA='data' + (( $1 > 1 )) && DATA="data_$1" + G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Restore' # Check valid FS Check_Supported_Directory_Location || return 1 # Error: Backup not found - if [[ ! -f $FP_TARGET/$FP_STATS ]]; then - - G_WHIP_MSG "Restore failed:\n\n$FP_TARGET/$FP_STATS does not exist\n\nHave you created a backup?" - - # Restore - else - - Check_UUIDs || return 1 - - /boot/dietpi/dietpi-services stop + [[ -f $FP_TARGET/$FP_STATS ]] || { G_WHIP_MSG "Restore failed:\n\n$FP_TARGET/$FP_STATS does not exist\n\nHave you created a backup?"; return 1; } - # Check if rsync is already running, while the daemon should have been stopped above - pgrep 'rsync' &> /dev/null && { Error_Rsync_Already_Running 'Restore'; return 1; } + # Check for matching filesystem UUIDs of backup and running system + Check_UUIDs || return 1 - # Install required rsync if missing - G_AG_CHECK_INSTALL_PREREQ rsync + /boot/dietpi/dietpi-services stop - # Generate Exclude/Include lists - Create_Filter_Include_Exclude + # Check if rsync is already running, while the daemon should have been stopped above + pgrep 'rsync' &> /dev/null && { Error_Rsync_Already_Running 'Restore'; return 1; } - G_DIETPI-NOTIFY 2 "Restore from $FP_TARGET in progress, please wait..." + # Install required rsync if missing + G_AG_CHECK_INSTALL_PREREQ rsync - # Init log file - echo -e "Restore log from $(Print_Date)\n" > "$FP_TARGET/$FP_LOG" + # Generate Exclude/Include lists + Create_Filter_Include_Exclude - rsync "${aRSYNC_RUN_OPTIONS_RESTORE[@]}" "${aRSYNC_LOGGING_OPTIONS[@]}" "$FP_TARGET/data/" "$FP_SOURCE" - EXIT_CODE=$? + G_DIETPI-NOTIFY 2 "Restore from $FP_TARGET in progress, please wait..." - hash -r # Clear PATH cache - (( $UPDATE_UUIDs )) && Update_UUIDs + # Init log file + echo -e "Restore log from $(Print_Date)\n" > "$FP_TARGET/$FP_LOG" - /boot/dietpi/dietpi-services start + rsync "${aRSYNC_RUN_OPTIONS_RESTORE[@]}" -v --log-file="$FP_TARGET/$FP_LOG" "$FP_TARGET/$DATA/" "$FP_SOURCE" + EXIT_CODE=$? - G_DIETPI-NOTIFY -1 $EXIT_CODE "$G_PROGRAM_NAME: Restore" - if (( $EXIT_CODE == 0 )); then + hash -r # Clear PATH cache + (( $UPDATE_UUIDs )) && Update_UUIDs - echo -e "Restore completed : $(Print_Date)" >> "$FP_TARGET/$FP_STATS" - G_WHIP_MSG "Restore completed:\n - $FP_TARGET\n\nNB: A Reboot is highly recommended." + /boot/dietpi/dietpi-services start - else + G_DIETPI-NOTIFY -1 $EXIT_CODE "$G_PROGRAM_NAME: Restore" + if (( $EXIT_CODE == 0 )); then - G_WHIP_MSG "Restore failed:\n - $FP_TARGET\n\nYou will see the log file on the next screen. Please check it for information and/or errors." + echo -e "Restore completed : $(Print_Date)" >> "$FP_TARGET/$FP_STATS" + G_WHIP_MSG "Restore completed:\n - $FP_TARGET\n\nNB: A Reboot is highly recommended." - fi + else - log=1 G_WHIP_VIEWFILE "$FP_TARGET/$FP_LOG" + G_WHIP_MSG "Restore failed:\n - $FP_TARGET\n\nYou will see the log file on the next screen. Please check it for information and/or errors." fi + log=1 G_WHIP_VIEWFILE "$FP_TARGET/$FP_LOG" + } #///////////////////////////////////////////////////////////////////////////////////// @@ -390,12 +400,14 @@ However, this check is a rough estimation in reasonable time, thus it could be m #///////////////////////////////////////////////////////////////////////////////////// readonly FP_SETTINGS='/boot/dietpi/.dietpi-backup_settings' DAILY_BACKUP=0 + AMOUNT=1 Write_Settings_File() { cat << _EOF_ > $FP_SETTINGS FP_TARGET=$FP_TARGET DAILY_BACKUP=$DAILY_BACKUP +AMOUNT=$AMOUNT _EOF_ } @@ -425,6 +437,7 @@ _EOF_ 'Location' ': Change where your backup will be saved and restored from.' 'Filter' ': Modify include/exclude filter for backups.' 'Daily Backup' ": [$daily_backup_text] Daily backups via cron job" + 'Amount' ": [$AMOUNT] The amount of backups to keep" ) if [[ -f $FP_TARGET/$FP_STATS ]] then @@ -455,15 +468,32 @@ _EOF_ 'Location') TARGETMENUID=1;; + 'Filter') nano $FP_FILTER_CUSTOM;; + 'Daily Backup') DAILY_BACKUP=$(( ! $DAILY_BACKUP ));; - 'Filter') nano $FP_FILTER_CUSTOM;; + 'Amount') G_WHIP_DEFAULT_ITEM=$AMOUNT G_WHIP_INPUTBOX 'Please enter the amount of backups to keep.\n - Needs to be 1 or greater.' && G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 1 && AMOUNT=$G_WHIP_RETURNED_VALUE;; 'Delete') G_WHIP_YESNO "Do you wish to DELETE the following backup?\n - $FP_TARGET" && G_EXEC_NOEXIT=1 G_EXEC rm -R "$FP_TARGET";; 'Backup') G_WHIP_YESNO "The system will be backed up to:\n - $FP_TARGET\n\nDo you wish to continue and start the backup?" && Run_Backup;; - 'Restore') G_WHIP_YESNO "The system will be restored from:\n - $FP_TARGET\n\nDo you wish to continue and start the restore?" && Run_Restore;; + 'Restore') + if (( $AMOUNT > 1 )) + then + G_WHIP_MENU_ARRAY=('1' "$(stat -c '%y' "$FP_TARGET/data")") + for ((i=2;i<=$AMOUNT;i++)) + do + [[ -d $FP_TARGET/data_$i ]] && G_WHIP_MENU_ARRAY+=("$i" "$(stat -c '%y' "$FP_TARGET/data_$i")") + done + if (( ${#G_WHIP_MENU_ARRAY[@]} > 2 )) + then + G_WHIP_MENU 'Please select the backup from the archive you wish to restore:' && Run_Restore "$G_WHIP_RETURNED_VALUE" + return + fi + fi + G_WHIP_YESNO "The system will be restored from:\n - $FP_TARGET\n\nDo you wish to continue and start the restore?" && Run_Restore + ;; esac @@ -482,7 +512,7 @@ _EOF_ G_WHIP_MENU_ARRAY=( - 'Search' ': Find previous backups in /mnt/*' + 'Search' ': Find previous backups' 'List' ': Select from a list of available mounts/drives' 'Manual' ': Manually type a directory to use' @@ -496,9 +526,9 @@ _EOF_ 'Search') - G_DIETPI-NOTIFY 2 'Searching /mnt/* for previous backups, please wait...' + G_DIETPI-NOTIFY 2 'Searching for previous backups, please wait...' local alist=() - mapfile -t alist < <(find /mnt -type f -name "$FP_STATS") + mapfile -t alist < <(find / -type f -name "$FP_STATS") # Do we have any results? if [[ ${alist[0]} ]]; then @@ -508,17 +538,17 @@ _EOF_ for i in "${alist[@]}" do local last_backup_date=$(sed -n '/ompleted/s/^.*: //p' "$i" | tail -1) # Date of last backup for this backup - local backup_directory=${i%/$FP_STATS} # Backup directory (minus the backup file), that we can use for target backup directory. + local backup_directory=${i%"/$FP_STATS"} # Backup directory (minus the backup file), that we can use for target backup directory. G_WHIP_MENU_ARRAY+=("$backup_directory" ": $last_backup_date") done - G_WHIP_MENU 'Please select a previous backup to use:' || return + G_WHIP_MENU 'Please select a previous backup to use:' || return 0 FP_TARGET=$G_WHIP_RETURNED_VALUE else - G_WHIP_MSG 'No previous backups were found in /mnt/*' - return + G_WHIP_MSG 'No previous backups were found.' + return 0 fi @@ -527,14 +557,14 @@ _EOF_ 'Manual') G_WHIP_DEFAULT_ITEM=$FP_TARGET - G_WHIP_INPUTBOX 'Please enter the filepath to your directory.\nE.g.: /mnt/dietpi-backup\n - Must be located inside /mnt/*\n - Must be a symlink and UNIX permissions compatible file system, like ext4, Btrfs, F2FS or valid NFS mount' || return + G_WHIP_INPUTBOX 'Please enter the absolute path to the backup directory.\nE.g.: /mnt/dietpi-backup\n - Must be a filesystem which supports symlinks and UNIX permissions, like ext4, F2FS, Btrfs, XFS, ZFS or a proper NFS mount' || return 0 FP_TARGET=$G_WHIP_RETURNED_VALUE ;; 'List') - /boot/dietpi/dietpi-drive_manager 1 || return + /boot/dietpi/dietpi-drive_manager 1 || return 0 FP_TARGET=$( 2 || ( $G_HW_MODEL > 9 && ${#G_WHIP_MENU_ARRAY[@]} ) )) || { G_WHIP_MSG 'No serial/UART devices have been found on your system.'; TARGETMENUID=3; return; } G_WHIP_BUTTON_CANCEL_TEXT='Back' if G_WHIP_MENU "Select an available serial/UART device to toggle a login console on it.$rpi_text"; then @@ -1181,7 +1118,7 @@ Re-enabling HDMI requires a reboot. If you need emergency HDMI output, edit the # TARGETMENUID=3 Menu_AdvancedOptions(){ - TARGETMENUID=0 + TARGETMENUID=0 # Return to main menu # Swap file local swap_size=$(free -m | mawk '/Swap:/ {print $2;exit}') @@ -1289,30 +1226,30 @@ Re-enabling HDMI requires a reboot. If you need emergency HDMI output, edit the fi - if G_WHIP_MENU 'Please select an option:'; then + G_WHIP_MENU 'Please select an option:' || return 0 - TARGETMENUID=3 # Return to this menu + TARGETMENUID=3 # Stay in this menu - if [[ $G_WHIP_RETURNED_VALUE == 'Swap file' ]]; then + if [[ $G_WHIP_RETURNED_VALUE == 'Swap file' ]]; then - G_WHIP_YESNO 'Swapfile control has been moved to DietPi-Drive_Manager, would you like to run the application now? + G_WHIP_YESNO 'Swapfile control has been moved to DietPi-Drive_Manager, would you like to run the application now? \nOnce finished, exit to resume DietPi-Config' && /boot/dietpi/dietpi-drive_manager - elif [[ $G_WHIP_RETURNED_VALUE == 'APT cache' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'APT cache' ]]; then - TARGETMENUID=19 + TARGETMENUID=19 - elif [[ $G_WHIP_RETURNED_VALUE == 'RTC mode' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'RTC mode' ]]; then - G_WHIP_MENU_ARRAY=( + G_WHIP_MENU_ARRAY=( - 'Emulated' ': Use "fake-hwclock" to apply system clock on early boot' - 'Hardware' ': Device has an active hardware RTC, purge "fake-hwclock"' + 'Emulated' ': Use "fake-hwclock" to apply system clock on early boot' + 'Hardware' ': Device has an active hardware RTC, purge "fake-hwclock"' - ) + ) - G_WHIP_DEFAULT_ITEM=$rtc_text - if G_WHIP_MENU 'Before network is available and network time sync can update the system clock, some implementation is required to do this on early boot stage.\n + G_WHIP_DEFAULT_ITEM=$rtc_text + if G_WHIP_MENU 'Before network is available and network time sync can update the system clock, some implementation is required to do this on early boot stage.\n RTC hardware clock: - Most x86 PCs and some SBCs have a hardware clock with battery attached, or, have a socket where it can optionally be attached to. - If active, this hardware clock will apply the correct system time during kernel boot stage.\n @@ -1321,116 +1258,114 @@ fake-hwclock: - This means that the time is outdated if the system was shut down for a while, but without this implementation the system time would be 01/01/1970 until network time sync corrects it.\n Please choose whether your device have an active RTC or requires "fake-hwclock":'; then - if [[ $G_WHIP_RETURNED_VALUE == 'Emulated' ]]; then - - G_AGI fake-hwclock - G_EXEC systemctl enable --now fake-hwclock + if [[ $G_WHIP_RETURNED_VALUE == 'Emulated' ]]; then - else + G_AGI fake-hwclock + G_EXEC systemctl enable --now fake-hwclock - G_AGP fake-hwclock + else - fi + G_AGP fake-hwclock fi - elif [[ $G_WHIP_RETURNED_VALUE == 'Time sync mode' ]]; then + fi - G_WHIP_MENU_ARRAY=( + elif [[ $G_WHIP_RETURNED_VALUE == 'Time sync mode' ]]; then - '0' ': Custom' - '1' ': Boot Only' - '2' ': Boot + Daily (Recommended)' - '3' ': Boot + Hourly' - '4' ': Daemon + Drift' + G_WHIP_MENU_ARRAY=( - ) + '0' ': Custom' + '1' ': Boot Only' + '2' ': Boot + Daily (Recommended)' + '3' ': Boot + Hourly' + '4' ': Daemon + Drift' + + ) - G_WHIP_DEFAULT_ITEM=$ntpd_mode_current - if G_WHIP_MENU 'Here you can adjust the frequency of network time syncs.\n + G_WHIP_DEFAULT_ITEM=$ntpd_mode_current + if G_WHIP_MENU 'Here you can adjust the frequency of network time syncs.\n - Modes 1-3:\nDietPi will launch systemd-timesyncd as a program, rather than a daemon. Once the time has been updated on your system, timesyncd will exit to reduce resource usage.\n - Mode 4:\nsystemd-timesyncd will run as a background daemon/service. Differences in time will be gradually adjusted over time, rather than instantly.\n - Mode 0:\nIf you use a custom time sync method, e.g. the NTP package for high precision demand, select custom mode to avoid systemd-timesyncd interference.'; then - /boot/dietpi/func/dietpi-set_software ntpd-mode "$G_WHIP_RETURNED_VALUE" - # Run time sync only, if not currently running, to avoid concurrent execution if dietpi-config was called from DietPi-Run_NTPD error handler - # - Run non-interactively to avoid its internal error handler allowing to open a concurrent dietpi-config instance - pgrep -cif /dietpi/func/run_ntpd > /dev/null || G_INTERACTIVE=0 MAX_LOOPS_CHECK=10 /boot/dietpi/func/run_ntpd 1 + /boot/dietpi/func/dietpi-set_software ntpd-mode "$G_WHIP_RETURNED_VALUE" + # Run time sync only, if not currently running, to avoid concurrent execution if dietpi-config was called from DietPi-Run_NTPD error handler + # - Run non-interactively to avoid its internal error handler allowing to open a concurrent dietpi-config instance + pgrep -cif /dietpi/func/run_ntpd > /dev/null || G_INTERACTIVE=0 MAX_LOOPS_CHECK=10 /boot/dietpi/func/run_ntpd 1 - fi + fi - elif [[ $G_WHIP_RETURNED_VALUE == 'Update firmware' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'Update firmware' ]]; then - local old_firmware=$(ls /lib/modules/) + local old_firmware=$(ls /lib/modules/) - # Pine A64: Non-ARMbian only - if [[ $G_HW_MODEL == 40 && -f '/usr/local/sbin/pine64_update_uboot.sh' && -f '/usr/local/sbin/pine64_update_kernel.sh' ]]; then + # Pine A64: Non-ARMbian only + if [[ $G_HW_MODEL == 40 && -f '/usr/local/sbin/pine64_update_uboot.sh' && -f '/usr/local/sbin/pine64_update_kernel.sh' ]]; then - if G_WHIP_YESNO "Would you like to update the firmware/kernel for $G_HW_MODEL_NAME? + if G_WHIP_YESNO "Would you like to update the firmware/kernel for $G_HW_MODEL_NAME? - This will run longsleep's update scripts to update the U-Boot and kernel."; then - /usr/local/sbin/pine64_update_uboot.sh - /usr/local/sbin/pine64_update_kernel.sh + /usr/local/sbin/pine64_update_uboot.sh + /usr/local/sbin/pine64_update_kernel.sh - fi + fi - # G_AGDUG based (not all devices support this) - elif G_WHIP_YESNO "Would you like to update the firmware/kernel for $G_HW_MODEL_NAME? + # G_AGDUG based (not all devices support this) + elif G_WHIP_YESNO "Would you like to update the firmware/kernel for $G_HW_MODEL_NAME? - This will run G_AGDUG, a wrapper for 'apt-get dist-upgrade'\n - Most (but not all) devices allow APT based firmware updates \nNB: If requested to overwrite the current kernel, press TAB and then ENTER (to confirm)."; then - G_AGUP - G_AGDUG + G_AGUP + G_AGDUG - fi + fi - # Reboot required only, if firmware got actually updated - [[ $old_firmware != $(ls /lib/modules/) ]] && REBOOT_REQUIRED=1 + # Reboot required only, if firmware got actually updated + [[ $old_firmware != $(ls /lib/modules/) ]] && REBOOT_REQUIRED=1 - elif [[ $G_WHIP_RETURNED_VALUE == 'Update RPi4 EEPROM firmware' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'Update RPi4 EEPROM firmware' ]]; then - G_WHIP_YESNO '[ INFO ] EEPROM firmware update + G_WHIP_YESNO '[ INFO ] EEPROM firmware update \nThis will, if required, install or upgrade the rpi-eeprom APT package and update bootloader and VL805 USB firmware on the RPi4 EEPROM. Further information: https://www.raspberrypi.org/documentation/hardware/raspberrypi/booteeprom.md \nDo you want to continue?' || return - /boot/dietpi/func/dietpi-set_hardware rpi-eeprom + /boot/dietpi/func/dietpi-set_hardware rpi-eeprom - elif [[ $G_WHIP_RETURNED_VALUE == 'I2C state' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'I2C state' ]]; then - /boot/dietpi/func/dietpi-set_hardware i2c $(( ! $rpi_i2c_enabled )) && REBOOT_REQUIRED=1 + /boot/dietpi/func/dietpi-set_hardware i2c $(( ! $rpi_i2c_enabled )) && REBOOT_REQUIRED=1 - elif [[ $G_WHIP_RETURNED_VALUE == 'I2C frequency' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'I2C frequency' ]]; then - # Remove kHz from current - G_WHIP_DEFAULT_ITEM=$rpi_i2c_baudrate - if G_WHIP_INPUTBOX 'Please enter the required I2C baudrate frequency (kHz).' && G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 0; then + # Remove kHz from current + G_WHIP_DEFAULT_ITEM=$rpi_i2c_baudrate + if G_WHIP_INPUTBOX 'Please enter the required I2C baudrate frequency (kHz).' && G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 0; then - /boot/dietpi/func/dietpi-set_hardware i2c "$G_WHIP_RETURNED_VALUE" && REBOOT_REQUIRED=1 + /boot/dietpi/func/dietpi-set_hardware i2c "$G_WHIP_RETURNED_VALUE" && REBOOT_REQUIRED=1 - fi + fi - elif [[ $G_WHIP_RETURNED_VALUE == 'SPI state' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'SPI state' ]]; then - /boot/dietpi/func/dietpi-set_hardware spi $(( ! $rpi_spi_enabled )) && REBOOT_REQUIRED=1 + /boot/dietpi/func/dietpi-set_hardware spi $(( ! $rpi_spi_enabled )) && REBOOT_REQUIRED=1 - elif [[ $G_WHIP_RETURNED_VALUE == 'Serial/UART' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'Serial/UART' ]]; then - TARGETMENUID=18 + TARGETMENUID=18 - elif [[ $G_WHIP_RETURNED_VALUE == 'Bluetooth' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'Bluetooth' ]]; then - /boot/dietpi/func/dietpi-set_hardware bluetooth $(( ! $bluetooth_state )) - # On RPi, when enabling onboard Bluetooth, a reboot is required to have the device tree changes taking effect. - (( $bluetooth_state || G_HW_MODEL > 9 )) || (( ! $G_HW_ONBOARD_WIFI )) || REBOOT_REQUIRED=1 + /boot/dietpi/func/dietpi-set_hardware bluetooth $(( ! $bluetooth_state )) + # On RPi, when enabling onboard Bluetooth, a reboot is required to have the device tree changes taking effect. + (( $bluetooth_state || G_HW_MODEL > 9 )) || (( ! $G_HW_ONBOARD_WIFI )) || REBOOT_REQUIRED=1 - elif [[ $G_WHIP_RETURNED_VALUE == 'USB boot support' && $rpi3_usb_boot_bit_enabled == 0 ]] && - G_WHIP_YESNO 'The following will enable the RPi 3 to boot from USB mass storage devices. A hardware bit "17:3020000a" is set on next boot to enable the feature. + elif [[ $G_WHIP_RETURNED_VALUE == 'USB boot support' && $rpi3_usb_boot_bit_enabled == 0 ]] && + G_WHIP_YESNO 'The following will enable the RPi 3 to boot from USB mass storage devices. A hardware bit "17:3020000a" is set on next boot to enable the feature. \nNB:\n - Not all USB mass storage devices are supported.\n - The hardware bit which enables this setting is non-reversible. \nDo you wish to enable USB mass storage boot support?'; then - /boot/dietpi/func/dietpi-set_hardware rpi3_usb_boot enable && REBOOT_REQUIRED=1 - - fi + /boot/dietpi/func/dietpi-set_hardware rpi3_usb_boot enable && REBOOT_REQUIRED=1 fi @@ -1439,7 +1374,7 @@ Further information: https://www.raspberrypi.org/documentation/hardware/raspberr # TARGETMENUID=4 Menu_PerformanceOptions(){ - TARGETMENUID=0 + TARGETMENUID=0 # Return to main menu # All devices local current_cpu_governor='N/A' @@ -1834,57 +1769,34 @@ Current setting: $user_frequency_min_text" && G_CONFIG_INJECT 'CONFIG_CPU_MIN_FR } - Change_Hostname(){ - - local hostname_current=$( $fp_log - local start_time=$(date) - local start_time_epoch=$(date +%s) - local memory_per_thread=$(( $(free -m | mawk '/^Mem:/ {print $2;exit}') / ( $G_HW_CPU_CORES * 2 ) )) - local fp_log='/root/dietpi-config_stress.log' - [[ -f $fp_log ]] && rm $fp_log + # Check if system supports temp readouts + local cpu_supports_temp=0 cpu_temp=$(G_OBTAIN_CPU_TEMP) + disable_error=1 G_CHECK_VALIDINT "$cpu_temp" && cpu_supports_temp=1 + STRESS_TEST_RESULTS_TEMP_MIN=$cpu_temp + STRESS_TEST_RESULTS_TEMP_MAX=$cpu_temp - if (( $STRESS_TEST_MODE == 0 )); then + G_DIETPI-NOTIFY 3 'Stress Test' "Running stress test for $STRESS_TEST_DURATION seconds" + G_DIETPI-NOTIFY 2 'To terminate, type: killall stress' - stress -c $(( $G_HW_CPU_CORES * 2 )) -t "$STRESS_TEST_DURATION"s & + local start_time=$(date) start_time_epoch=$(date '+%s') + local memory_per_thread=$(( $(free -m | mawk '/^Mem:/{print $2;exit}') / ( $G_HW_CPU_CORES * 2 ) )) - elif (( $STRESS_TEST_MODE == 1 )); then + if (( $STRESS_TEST_MODE == 0 )); then - stress -c $(( $G_HW_CPU_CORES * 2 )) -i "$G_HW_CPU_CORES" -m "$G_HW_CPU_CORES" --vm-bytes "$memory_per_thread"M -t "$STRESS_TEST_DURATION"s & + stress -t "$STRESS_TEST_DURATION"s -c $(( $G_HW_CPU_CORES * 2 )) & - elif (( $STRESS_TEST_MODE == 2 )); then + elif (( $STRESS_TEST_MODE == 1 )); then - stress -c $(( $G_HW_CPU_CORES * 2 )) -i "$G_HW_CPU_CORES" -m "$G_HW_CPU_CORES" --vm-bytes "$memory_per_thread"M -d 2 -t "$STRESS_TEST_DURATION"s & + stress -t "$STRESS_TEST_DURATION"s -c $(( $G_HW_CPU_CORES * 2 )) -i "$G_HW_CPU_CORES" -m "$G_HW_CPU_CORES" --vm-bytes "$memory_per_thread"M & - fi + elif (( $STRESS_TEST_MODE == 2 )); then - # Reset - STRESS_TEST_RESULTS_TEMP_MIN=1000 - STRESS_TEST_RESULTS_TEMP_MAX=0 + stress -t "$STRESS_TEST_DURATION"s -c $(( $G_HW_CPU_CORES * 2 )) -i "$G_HW_CPU_CORES" -m "$G_HW_CPU_CORES" --vm-bytes "$memory_per_thread"M -d 2 & - # Check if system supports temp readouts - local cpu_supports_temp=0 - local cpu_temp=$(G_OBTAIN_CPU_TEMP) - disable_error=1 G_CHECK_VALIDINT "$cpu_temp" && cpu_supports_temp=1 + fi - # Loop until stress completed - local remaning_time=0 - while pgrep 'stress' &> /dev/null - do + # Loop until stress completed + while pgrep 'stress' &> /dev/null + do + log_text=$(date) + if (( $cpu_supports_temp )) + then cpu_temp=$(G_OBTAIN_CPU_TEMP) - remaning_time=$(( $STRESS_TEST_DURATION + ( $start_time_epoch - $(date +%s) ) )) - - echo -e "$(date) | $cpu_temp'c | $remaning_time seconds remaining" - echo -e "$(date) | $cpu_temp'c" >> "$fp_log" - - if (( $cpu_supports_temp )); then - - (( $cpu_temp > $STRESS_TEST_RESULTS_TEMP_MAX )) && STRESS_TEST_RESULTS_TEMP_MAX=$cpu_temp - (( $cpu_temp < $STRESS_TEST_RESULTS_TEMP_MIN )) && STRESS_TEST_RESULTS_TEMP_MIN=$cpu_temp + if (( $cpu_temp > $STRESS_TEST_RESULTS_TEMP_MAX )) + then + STRESS_TEST_RESULTS_TEMP_MAX=$cpu_temp + elif (( $cpu_temp < $STRESS_TEST_RESULTS_TEMP_MIN )) + then + STRESS_TEST_RESULTS_TEMP_MIN=$cpu_temp fi + log_text+=" | $cpu_temp °C" + fi + log_text+=" | $(( $STRESS_TEST_DURATION + $start_time_epoch - $(date '+%s') )) seconds remaining" + echo "$log_text" + echo "$log_text" > $fp_log + sleep 1 + done - sleep 1 - ((time_since_start++)) - done - - local end_time=$(date) - local end_time_epoch=$(date +%s) - local duration_seconds=$(( $end_time_epoch - $start_time_epoch )) - - local output_string=" - Start Time: $start_time - - End Time : $end_time - - Duration : $duration_seconds seconds - - Min Temp : $STRESS_TEST_RESULTS_TEMP_MIN 'c - - Max Temp : $STRESS_TEST_RESULTS_TEMP_MAX 'c - - log : $fp_log" - - G_DIETPI-NOTIFY 0 'Stress Test Completed' - G_DIETPI-NOTIFY 2 "$output_string" + local output_string=" - Start Time: $start_time + - End Time : $(date) + - Duration : $(( $(date '+%s') - $start_time_epoch )) seconds + - Min Temp : $STRESS_TEST_RESULTS_TEMP_MIN °C + - Max Temp : $STRESS_TEST_RESULTS_TEMP_MAX °C + - Log : $fp_log" - G_WHIP_MSG "Stress test results:\n$output_string" + G_DIETPI-NOTIFY 0 'Stress Test Completed' + G_DIETPI-NOTIFY 2 "$output_string" - fi + G_WHIP_MSG "Stress test results:\n$output_string" fi diff --git a/dietpi/dietpi-drive_manager b/dietpi/dietpi-drive_manager index 82c25c228a..2b1265c001 100644 --- a/dietpi/dietpi-drive_manager +++ b/dietpi/dietpi-drive_manager @@ -317,7 +317,7 @@ $swap_mounts [[ $line == $i* ]] && continue 2 done - G_DIETPI-NOTIFY 2 " - Detected unformated drive: /dev/$line" + G_DIETPI-NOTIFY 2 " - Detected unformatted drive: /dev/$line" Init_New_Device @@ -334,7 +334,11 @@ $swap_mounts [[ ${aDRIVE_MOUNT_SOURCE[$i]} == '/dev/sr'* ]] && aDRIVE_ISROM[$i]=1 # Collect required APT packages for FS R/W access - if [[ ${aDRIVE_FSTYPE[$i]} == 'ntfs' ]]; then + if [[ ${aDRIVE_FSTYPE[$i]} == 'ext'[2-4] ]]; then + + local need_ext='e2fsprogs' + + elif [[ ${aDRIVE_FSTYPE[$i]} == 'ntfs' ]]; then local need_ntfs='ntfs-3g' @@ -369,7 +373,7 @@ $swap_mounts G_EXEC systemctl daemon-reload # Install required APT packages for FS R/W access - [[ $APT_CHECK == 0 && $need_ntfs$need_hfs$need_exfat ]] && G_AG_CHECK_INSTALL_PREREQ $need_ntfs $need_hfs $need_exfat && APT_CHECK=1 + [[ $APT_CHECK == 0 && $need_ext$need_ntfs$need_hfs$need_exfat ]] && G_AG_CHECK_INSTALL_PREREQ $need_ext $need_ntfs $need_hfs $need_exfat && APT_CHECK=1 G_EXEC sync @@ -461,7 +465,7 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return fi G_EXEC_NOEXIT=1 G_EXEC mkdir -p "$target" || return 1 - G_EXEC_NOEXIT=1 G_EXEC mount "$source" "$target" -o "$options" || return 1 + G_EXEC_NOEXIT=1 G_EXEC mount -o "$options" "$source" "$target" || return 1 MENU_DRIVE_TARGET=$target Init_Drives_and_Refresh @@ -620,7 +624,7 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return # Format FAT32 elif (( $FORMAT_FILESYSTEM_TYPE == 2 )); then - # -I: Use 1 parition on whole device + # -I: Use 1 partition on whole device info_format_fs_type='FAT' G_EXEC mkfs.fat -I "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" @@ -630,7 +634,7 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return info_format_fs_type='HFS+' G_EXEC mkfs.hfsplus "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" - # Format btrfs + # Format Btrfs elif (( $FORMAT_FILESYSTEM_TYPE == 4 )); then # -f: force @@ -967,7 +971,7 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return { # Install FUSE driver if kernel does not support exFAT natively and on Bullseye exfatprogs if it does, else exfat-utils local apackages=() - if modprobe -nq exfat + if modprobe -q exfat then (( $G_DISTRO > 5 )) && apackages=('exfatprogs') || apackages=('exfat-utils') dpkg-query -s 'exfat-fuse' &> /dev/null && G_AGP exfat-fuse @@ -1388,6 +1392,7 @@ Please enter the desired percentage of reserved blocks, e.g. "0.05" for 0.05% or if [[ ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} == ext[2-4] ]]; then + G_AG_CHECK_INSTALL_PREREQ e2fsprogs local fsck_dry='e2fsck -n -f' local fsck_fix='e2fsck -y -f' @@ -1648,8 +1653,13 @@ NB: If you are planning to dedicate the drive to this system, it is recommended \nFull list of different filesystem types:\nhttps://dietpi.com/docs/dietpi_tools/#dietpi-drive-manager'; then # Install FS pre-reqs + # - ext + if (( $G_WHIP_RETURNED_VALUE == 0 )); then + + G_AG_CHECK_INSTALL_PREREQ e2fsprogs + # - NTFS - if (( $G_WHIP_RETURNED_VALUE == 1 )); then + elif (( $G_WHIP_RETURNED_VALUE == 1 )); then G_AG_CHECK_INSTALL_PREREQ ntfs-3g diff --git a/dietpi/dietpi-letsencrypt b/dietpi/dietpi-letsencrypt index 3616f8f9fb..27b55e9575 100644 --- a/dietpi/dietpi-letsencrypt +++ b/dietpi/dietpi-letsencrypt @@ -49,15 +49,15 @@ local fp_cert_dir="/etc/letsencrypt/live/$primary_domain" #------------------------------------------------------------------------------------------------------ - # Apache2 + # Apache if systemctl cat 'apache2.service' &> /dev/null; then - G_DIETPI-NOTIFY 0 'Apache2 webserver detected' + G_DIETPI-NOTIFY 0 'Apache webserver detected' # Add ServerName if it doesn't exist. This is required to prevent Certbot complaining about vhost with no domain and mutes a warning on Apache start about a missing global server name. G_CONFIG_INJECT 'ServerName[[:blank:]]' "ServerName $primary_domain" /etc/apache2/apache2.conf '^[[:blank:]]*[^#]' - # Restart Apache2 to apply ServerName change + # Restart Apache to apply ServerName change G_EXEC systemctl restart apache2 local aoptions=('--apache') diff --git a/dietpi/dietpi-services b/dietpi/dietpi-services index 975e508de0..98ebbad448 100644 --- a/dietpi/dietpi-services +++ b/dietpi/dietpi-services @@ -233,8 +233,9 @@ Available services: #aSERVICE_NAME+=('wg-quick@wg0') # WireGuard: Currently instantiated services are not supported # DietPi - aSERVICE_NAME+=('dietpi-vpn') # NordVPN install + client - aSERVICE_NAME+=('dietpi-dashboard') # Web Dashboard + aSERVICE_NAME+=('dietpi-vpn') # VPN client + aSERVICE_NAME+=('dietpi-cloudshell') # Console monitoring + aSERVICE_NAME+=('dietpi-dashboard') # Web dashboard if [[ $INPUT_CMD == 'status' ]]; then aSERVICE_NAME+=('dietpi-ramlog') @@ -269,7 +270,6 @@ Available services: # The service will be in disabled form, and, you can start and stop it manually #- cron #- transmission-daemon - _EOF_ aSERVICE_EXCLUDED=() local i @@ -281,13 +281,12 @@ _EOF_ line=${line: +2} - # - Skip known services + # Skip known services for i in "${aSERVICE_NAME[@]}" do [[ $line == "$i" ]] && continue 2 done - [[ $G_DEBUG == 1 ]] && G_DIETPI-NOTIFY 2 "Including custom service: $line" aSERVICE_NAME+=("$line") # Exclude @@ -302,7 +301,6 @@ _EOF_ # Show in menu, but mark as excluded if [[ $INPUT_CMD ]]; then - [[ $G_DEBUG == 1 ]] && G_DIETPI-NOTIFY 2 "Excluding service: $line" unset -v "aSERVICE_NAME[$i]" else @@ -323,8 +321,6 @@ _EOF_ # Load array of available/chosen services Load_Service_Array(){ - [[ $G_DEBUG == 1 ]] && G_DIETPI-NOTIFY 2 'Generating service list, please wait...' - # Load all services array, skip in case of single service input # shellcheck disable=SC2015 [[ $INPUT_SERVICE ]] && aSERVICE_NAME=("$INPUT_SERVICE") || Load_All_Services_Array @@ -364,9 +360,7 @@ _EOF_ # $2 = service index (optional) Set_Running_State(){ - local command=${1,,} - local index=$2 - local services i + local command=${1,,} index=$2 services i # Add and order services to be handled # - Single service input @@ -389,14 +383,6 @@ _EOF_ fi - # Enable ownCloud and Nextcloud maintenance mode before all services being stopped or restarted - if [[ $command == 'stop' || $command == 'restart' ]] && [[ ! $index ]]; then - - [[ -f '/var/www/owncloud/config/config.php' ]] && grep -q "'maintenance' => false," /var/www/owncloud/config/config.php && G_EXEC_NOHALT=1 G_EXEC occ maintenance:mode --on - [[ -f '/var/www/nextcloud/config/config.php' ]] && grep -q "'maintenance' => false," /var/www/nextcloud/config/config.php && G_EXEC_NOHALT=1 G_EXEC ncc maintenance:mode --on - - fi - # Apply command for i in $services do @@ -406,23 +392,13 @@ _EOF_ Print_Status "$command" "${aSERVICE_NAME[$i]}" $? done - # Disable ownCloud and Nextcloud maintenance mode after all services being started or restarted - if [[ $command == 'start' || $command == 'restart' ]] && [[ ! $index ]]; then - - [[ -f '/var/www/owncloud/config/config.php' ]] && grep -q "'maintenance' => true," /var/www/owncloud/config/config.php && G_EXEC_NOHALT=1 G_EXEC occ maintenance:mode --off - [[ -f '/var/www/nextcloud/config/config.php' ]] && grep -q "'maintenance' => true," /var/www/nextcloud/config/config.php && G_EXEC_NOHALT=1 G_EXEC ncc maintenance:mode --off - - fi - } # $1 = command # $2 = service index (optional) Apply_Service_State(){ - local command=${1,,} - local index=$2 - local services i + local command=${1,,} index=$2 services i [[ $index ]] && services=$index || services=${!aSERVICE_NAME[*]} @@ -509,12 +485,7 @@ _EOF_ readonly FP_PROCESS_TOOL_CONF='dietpi-process_tool.conf' Apply_Process_Tool(){ - local index=$1 - local setting=$2 - local value=${3,,} - local dp="/etc/systemd/system/${aSERVICE_NAME[$index]}.service.d" - local fp="$dp/$FP_PROCESS_TOOL_CONF" - local i + local index=$1 setting=$2 value=${3,,} dp="/etc/systemd/system/${aSERVICE_NAME[$index]}.service.d" fp="$dp/$FP_PROCESS_TOOL_CONF" i # Arrays to translate $2 integer to settings names local asetting=('CPUAffinity' 'CPUSchedulingPolicy' 'Nice' 'CPUSchedulingPriority' 'IOSchedulingClass' 'IOSchedulingPriority') @@ -563,12 +534,11 @@ _EOF_ # $1 = service index Load_Process_Tool(){ - local index=$1 - local fp="/etc/systemd/system/${aSERVICE_NAME[$index]}.service.d/$FP_PROCESS_TOOL_CONF" + local index=$1 fp="/etc/systemd/system/${aSERVICE_NAME[$index]}.service.d/$FP_PROCESS_TOOL_CONF" [[ -f $fp ]] || return # Source values from config file - # - [Service] line throws an effectless error that we can simply hide. + # - [Service] line throws a harmless error that we can simply hidden. # - All values are single word strings, so bash assigns them correctly. local CPUAffinity CPUSchedulingPolicy Nice CPUSchedulingPriority IOSchedulingClass IOSchedulingPriority . "$fp" &> /dev/null @@ -594,11 +564,11 @@ _EOF_ aIO_CLASS=() aIO_PRIORITY=() - # https://manpages.debian.org/stretch/manpages/sched.7.en.html + # https://manpages.debian.org/sched aCPU_POLICY_TYPE=('fifo' 'rr' 'other' 'batch' 'idle') aCPU_POLICY_DESC=('First In, First Out (Real-time, time-critical)' 'Round Robin (Real-time, time-critical)' 'Normal (Default)' 'Batch style execution' 'Background Jobs (Very low priority)') - # https://manpages.debian.org/stretch/util-linux/ionice.1.en.html + # https://manpages.debian.org/ionice aIO_CLASS_TYPE=('realtime' 'best-effort' 'idle') aIO_CLASS_DESC=('Time-critical (Highest priority)' 'Normal (Default)' 'Background Jobs (Very low priority)') @@ -917,8 +887,7 @@ This affects starts/stops/restarts during DietPi-Software installs, DietPi-Updat 'Edit') - local dp="/etc/systemd/system/${aSERVICE_NAME[$MENU_SERVICE_INDEX]}.service.d" - local fp="$dp/dietpi-services_edit.conf" + local dp="/etc/systemd/system/${aSERVICE_NAME[$MENU_SERVICE_INDEX]}.service.d" fp="$dp/dietpi-services_edit.conf" if [[ ! -f $fp ]]; then @@ -1020,7 +989,6 @@ Please uncomment and edit only the lines that you need to change.\n\nTo undo cha # Note: Whiptail will not work with negative numbers. The string cannot start with "-" as it throws subscript error. G_WHIP_MENU_ARRAY+=("Nice : $i" " $desc") - done G_WHIP_DEFAULT_ITEM="Nice : $cpu_nice" diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 85f26a3806..cda275a641 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -38,6 +38,39 @@ Available commands: Write_InstallFileList(){ + # Update webserver stack meta install states + # - Apache + aSOFTWARE_INSTALL_STATE[75]=0 aSOFTWARE_INSTALL_STATE[76]=0 + aSOFTWARE_INSTALL_STATE[78]=0 aSOFTWARE_INSTALL_STATE[79]=0 + aSOFTWARE_INSTALL_STATE[81]=0 aSOFTWARE_INSTALL_STATE[82]=0 + if (( ${aSOFTWARE_INSTALL_STATE[83]} == 2 )); then + + # SQLite: LASP + (( ${aSOFTWARE_INSTALL_STATE[87]} == 2 )) && aSOFTWARE_INSTALL_STATE[75]=2 + + # MariaDB: LAMP + (( ${aSOFTWARE_INSTALL_STATE[88]} == 2 )) && aSOFTWARE_INSTALL_STATE[76]=2 + + # - Nginx + elif (( ${aSOFTWARE_INSTALL_STATE[85]} == 2 )); then + + # SQLite: LESP + (( ${aSOFTWARE_INSTALL_STATE[87]} == 2 )) && aSOFTWARE_INSTALL_STATE[78]=2 + + # MariaDB: LEMP + (( ${aSOFTWARE_INSTALL_STATE[88]} == 2 )) && aSOFTWARE_INSTALL_STATE[79]=2 + + # - Lighttpd + elif (( ${aSOFTWARE_INSTALL_STATE[84]} == 2 )); then + + # SQLite: LLSP + (( ${aSOFTWARE_INSTALL_STATE[87]} == 2 )) && aSOFTWARE_INSTALL_STATE[81]=2 + + # MariaDB: LLMP + (( ${aSOFTWARE_INSTALL_STATE[88]} == 2 )) && aSOFTWARE_INSTALL_STATE[82]=2 + + fi + local install_states # Save installed states @@ -56,31 +89,11 @@ Available commands: fi done - # Choice and preference systems - install_states+=" -# DietPi Choice System: SSH Server -INDEX_SSHSERVER_CURRENT=$INDEX_SSHSERVER_CURRENT -INDEX_SSHSERVER_TARGET=$INDEX_SSHSERVER_TARGET - -# DietPi Choice System: File Server -INDEX_FILESERVER_CURRENT=$INDEX_FILESERVER_CURRENT -INDEX_FILESERVER_TARGET=$INDEX_FILESERVER_TARGET - -# DietPi Choice System: Logging -INDEX_LOGGING_CURRENT=$INDEX_LOGGING_CURRENT -INDEX_LOGGING_TARGET=$INDEX_LOGGING_TARGET - -# DietPi Preference System: Webserver -INDEX_WEBSERVER_CURRENT=$INDEX_WEBSERVER_CURRENT -INDEX_WEBSERVER_TARGET=$INDEX_WEBSERVER_TARGET - -# DietPi Preference System: Desktop -INDEX_DESKTOP_CURRENT=$INDEX_DESKTOP_CURRENT -INDEX_DESKTOP_TARGET=$INDEX_DESKTOP_TARGET - -# DietPi Preference System: Browser -INDEX_BROWSER_CURRENT=$INDEX_BROWSER_CURRENT -INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" + # Choice and preference indices + install_states+="INDEX_LOGGING=$INDEX_LOGGING +INDEX_WEBSERVER=$INDEX_WEBSERVER +INDEX_DESKTOP=$INDEX_DESKTOP +INDEX_BROWSER=$INDEX_BROWSER" echo "$install_states" > $FP_INSTALLED_FILE @@ -113,36 +126,11 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" # Run Install flag to trigger Run_Installations() GOSTARTINSTALL=0 - # Run uninstall flag, used in software installs + removals to trigger Uninstall_Software() - UNINSTALL_REQUIRED=0 - - # Choices made flag - INSTALL_SOFTWARE_CHOICESMADE=0 - - # DietPi Choice System - # - SSH Server - INSTALL_SSHSERVER_CHOICESMADE=0 - INDEX_SSHSERVER_CURRENT=-1 - INDEX_SSHSERVER_TARGET=-1 - # - File server - INSTALL_FILESERVER_CHOICESMADE=0 - INDEX_FILESERVER_CURRENT=0 - INDEX_FILESERVER_TARGET=0 - # - Logging - INSTALL_LOGGING_CHOICESMADE=0 - INDEX_LOGGING_CURRENT=-1 - INDEX_LOGGING_TARGET=-1 - - # DietPi Preference System - # - Webserver - INDEX_WEBSERVER_CURRENT=-2 - INDEX_WEBSERVER_TARGET=-2 - # - Desktop - INDEX_DESKTOP_CURRENT=0 - INDEX_DESKTOP_TARGET=0 - # - Browser - INDEX_BROWSER_CURRENT=-1 - INDEX_BROWSER_TARGET=-1 + # DietPi choice and preference systems + INDEX_LOGGING=-1 + INDEX_WEBSERVER=-2 + INDEX_DESKTOP=0 + INDEX_BROWSER=-1 # Since no automated reboot is done anymore after installs, collect services to start manually, when not controlled by DietPi-Services aSTART_SERVICES=() @@ -324,6 +312,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=1 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/remote_desktop/#tigervnc-server' aSOFTWARE_DEPS[$software_id]='desktop' + aSOFTWARE_CONFLICTS[$software_id]='120' #------------------ software_id=29 @@ -348,7 +337,8 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=1 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/remote_desktop/#realvnc-server' aSOFTWARE_DEPS[$software_id]='desktop' - # RPi only (archive.raspberrypi.org repo, libraspberrypi dependency, license) + aSOFTWARE_CONFLICTS[$software_id]='28' + # RPi only (archive.raspberrypi.org repo, libraspberrypi0 dependency, license) for ((i=10; i<=$MAX_G_HW_MODEL; i++)) do aSOFTWARE_AVAIL_G_HW_MODEL[$software_id,$i]=0 @@ -359,7 +349,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=31 aSOFTWARE_NAME[$software_id]='Kodi' - aSOFTWARE_DESC[$software_id]='the media centre for linux' + aSOFTWARE_DESC[$software_id]='The media centre for Linux' aSOFTWARE_CATX[$software_id]=2 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/media/#kodi' aSOFTWARE_DEPS[$software_id]='5 152' @@ -393,7 +383,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=33 aSOFTWARE_NAME[$software_id]='Airsonic' - aSOFTWARE_DESC[$software_id]='web interface media streaming server' + aSOFTWARE_DESC[$software_id]='Web interface media streaming server' aSOFTWARE_CATX[$software_id]=2 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/media/#airsonic' aSOFTWARE_DEPS[$software_id]='5 7 196' @@ -638,7 +628,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=2 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/media/#snapcast-server' aSOFTWARE_DEPS[$software_id]='5' - # Not currently available on arm64: https://github.com/badaix/snapcast/issues/706 + # - ARMv8: https://github.com/badaix/snapcast/issues/706 aSOFTWARE_AVAIL_G_HW_ARCH[$software_id,3]=0 #------------------ software_id=192 @@ -649,7 +639,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/media/#snapcast-client' aSOFTWARE_DEPS[$software_id]='5' aSOFTWARE_INTERACTIVE[$software_id]=1 - # Not currently available on arm64: https://github.com/badaix/snapcast/issues/706 + # - ARMv8: https://github.com/badaix/snapcast/issues/706 aSOFTWARE_AVAIL_G_HW_ARCH[$software_id,3]=0 #------------------ software_id=199 @@ -677,8 +667,6 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='BitTorrent server with web interface (Python)' aSOFTWARE_CATX[$software_id]=3 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/bittorrent/#deluge' - # - Raspbian Bullseye: https://github.com/MichaIng/DietPi/issues/4944 - (( $G_HW_MODEL < 10 )) && (( $G_RASPBIAN )) && aSOFTWARE_AVAIL_G_DISTRO[$software_id,6]=0 #------------------ software_id=46 @@ -720,8 +708,6 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=3 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/bittorrent/#sabnzbd' aSOFTWARE_DEPS[$software_id]='130 170' - # Pre-compiling required on ARM - (( $G_HW_ARCH > 9 )) || aSOFTWARE_DEPS[$software_id]+=' 16' #------------------ software_id=144 @@ -815,11 +801,11 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=168 aSOFTWARE_NAME[$software_id]='Nextcloud Talk' - aSOFTWARE_DESC[$software_id]='Video calls with configured coTURN server' + aSOFTWARE_DESC[$software_id]='Video calls with configured Coturn server' aSOFTWARE_CATX[$software_id]=4 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/cloud/#nextcloud-talk' aSOFTWARE_DEPS[$software_id]='114' - # Currently requires manual domain and coTURN server port input. + # Currently requires manual domain and Coturn server port input. # - To resolve: Default port 5349 could be used, but reliable method to get external domain/static IP is required. aSOFTWARE_INTERACTIVE[$software_id]=1 #------------------ @@ -846,7 +832,8 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='personal github server with web interface' aSOFTWARE_CATX[$software_id]=4 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/cloud/#gogs' - aSOFTWARE_DEPS[$software_id]='17 88' + aSOFTWARE_DEPS[$software_id]='17 88 0' + aSOFTWARE_CONFLICTS[$software_id]='165' #------------------ software_id=50 @@ -877,7 +864,8 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='Git with a cup of tea' aSOFTWARE_CATX[$software_id]=4 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/cloud/#gitea' - aSOFTWARE_DEPS[$software_id]='17 88' + aSOFTWARE_DEPS[$software_id]='17 88 0' + aSOFTWARE_CONFLICTS[$software_id]='49' #------------------ software_id=177 @@ -1192,7 +1180,6 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=8 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/programming/#docker-compose' aSOFTWARE_DEPS[$software_id]='130 162' - #------------------ software_id=193 @@ -1200,12 +1187,11 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='The certified Kubernetes distribution built for IoT & Edge computing' aSOFTWARE_CATX[$software_id]=8 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/cloud/#k3s' - #------------------ software_id=200 aSOFTWARE_NAME[$software_id]='DietPi-Dashboard (beta)' - aSOFTWARE_DESC[$software_id]='Official lightweight standalone DietPi web interface (Rust)' + aSOFTWARE_DESC[$software_id]='Official lightweight DietPi web interface (Rust)' aSOFTWARE_CATX[$software_id]=8 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/system_stats/#dietpi-dashboard' @@ -1370,18 +1356,20 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=75 aSOFTWARE_NAME[$software_id]='LASP' - aSOFTWARE_DESC[$software_id]='Apache2 | SQLite | PHP' + aSOFTWARE_DESC[$software_id]='Apache | SQLite | PHP' aSOFTWARE_CATX[$software_id]=12 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#lasp-web-stack' aSOFTWARE_DEPS[$software_id]='83 87 89' + aSOFTWARE_CONFLICTS[$software_id]='78 79 81 82 84 85' #------------------ software_id=76 aSOFTWARE_NAME[$software_id]='LAMP' - aSOFTWARE_DESC[$software_id]='Apache2 | MariaDB | PHP' + aSOFTWARE_DESC[$software_id]='Apache | MariaDB | PHP' aSOFTWARE_CATX[$software_id]=12 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#lamp-web-stack' aSOFTWARE_DEPS[$software_id]='83 88 89' + aSOFTWARE_CONFLICTS[$software_id]='78 79 81 82 84 85' #------------------ software_id=78 @@ -1390,6 +1378,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=12 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#lesp-web-stack' aSOFTWARE_DEPS[$software_id]='85 87 89' + aSOFTWARE_CONFLICTS[$software_id]='75 76 81 82 83 84' #------------------ software_id=79 @@ -1398,6 +1387,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=12 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#lemp-web-stack' aSOFTWARE_DEPS[$software_id]='85 88 89' + aSOFTWARE_CONFLICTS[$software_id]='75 76 81 82 83 84' #------------------ software_id=81 @@ -1406,6 +1396,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=12 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#llsp-web-stack' aSOFTWARE_DEPS[$software_id]='84 87 89' + aSOFTWARE_CONFLICTS[$software_id]='75 76 78 79 83 85' #------------------ software_id=82 @@ -1414,14 +1405,16 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=12 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#llmp-web-stack' aSOFTWARE_DEPS[$software_id]='84 88 89' + aSOFTWARE_CONFLICTS[$software_id]='75 76 78 79 83 85' #------------------ software_id=83 - aSOFTWARE_NAME[$software_id]='Apache2' + aSOFTWARE_NAME[$software_id]='Apache' aSOFTWARE_DESC[$software_id]='Popular webserver' aSOFTWARE_CATX[$software_id]=-1 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#apache2' aSOFTWARE_DEPS[$software_id]='89' + aSOFTWARE_CONFLICTS[$software_id]='78 79 81 82 84 85' #------------------ software_id=84 @@ -1430,6 +1423,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=-1 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#lighttpd' aSOFTWARE_DEPS[$software_id]='89' + aSOFTWARE_CONFLICTS[$software_id]='75 76 78 79 83 85' #------------------ software_id=85 @@ -1438,6 +1432,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=-1 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/webserver_stack/#nginx' aSOFTWARE_DEPS[$software_id]='89' + aSOFTWARE_CONFLICTS[$software_id]='75 76 81 82 83 84' #------------------ software_id=89 @@ -1463,13 +1458,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/dns_servers/#pi-hole' aSOFTWARE_DEPS[$software_id]='17 87 89 webserver' aSOFTWARE_INTERACTIVE[$software_id]=1 - #------------------ - software_id=182 - - aSOFTWARE_NAME[$software_id]='Unbound' - aSOFTWARE_DESC[$software_id]='validating, recursive, caching DNS resolver' - aSOFTWARE_CATX[$software_id]=13 - aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/dns_servers/#unbound' + aSOFTWARE_CONFLICTS[$software_id]='126' #------------------ software_id=126 @@ -1477,6 +1466,14 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='powerful network-wide ads & trackers blocking DNS server' aSOFTWARE_CATX[$software_id]=13 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/dns_servers/#adguard-home' + aSOFTWARE_CONFLICTS[$software_id]='93' + #------------------ + software_id=182 + + aSOFTWARE_NAME[$software_id]='Unbound' + aSOFTWARE_DESC[$software_id]='validating, recursive, caching DNS resolver' + aSOFTWARE_CATX[$software_id]=13 + aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/dns_servers/#unbound' # File Servers #-------------------------------------------------------------------------------- @@ -1486,13 +1483,15 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='Efficient, lightweight FTP server' aSOFTWARE_CATX[$software_id]=14 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/file_servers/#proftpd' + aSOFTWARE_CONFLICTS[$software_id]='95' #------------------ software_id=95 aSOFTWARE_NAME[$software_id]='vsftpd' - aSOFTWARE_DESC[$software_id]='Alternative FTP server' + aSOFTWARE_DESC[$software_id]='Very secure FTP server' aSOFTWARE_CATX[$software_id]=14 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/file_servers/#vsftpd' + aSOFTWARE_CONFLICTS[$software_id]='94' #------------------ software_id=96 @@ -1551,7 +1550,6 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/vpn/#pivpn' aSOFTWARE_DEPS[$software_id]='17' aSOFTWARE_INTERACTIVE[$software_id]=1 - aSOFTWARE_RECOMMENDS_AUTOMATED_UPGRADES[$software_id]=1 # Advanced Networking #-------------------------------------------------------------------------------- @@ -1569,6 +1567,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_CATX[$software_id]=16 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/advanced_networking/#tor-hotspot' aSOFTWARE_DEPS[$software_id]='60' + aSOFTWARE_CONFLICTS[$software_id]='184' #------------------ software_id=98 @@ -1655,8 +1654,8 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='add a node to the Tor network' aSOFTWARE_CATX[$software_id]=19 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/distributed_projects/#tor-relay' + aSOFTWARE_CONFLICTS[$software_id]='61' aSOFTWARE_INTERACTIVE[$software_id]=1 - aSOFTWARE_RECOMMENDS_AUTOMATED_UPGRADES[$software_id]=1 # - Stretch: https://github.com/MichaIng/DietPi/issues/4925 aSOFTWARE_AVAIL_G_DISTRO[$software_id,4]=0 #------------------ @@ -2007,6 +2006,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='Feature-rich SSH server with SFTP and SCP support' aSOFTWARE_CATX[$software_id]=-1 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/ssh/#openssh' + aSOFTWARE_DEPS[$software_id]='0' #-------------------------------------------------------------------------------- # Init install state for defined software @@ -2024,93 +2024,156 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" } # Unmark software installs for automated installs, if user input is required - Unmark_Unattended(){ - + Unmark_Unattended() + { (( $G_INTERACTIVE )) && return for i in "${!aSOFTWARE_NAME[@]}" do if (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 && ${aSOFTWARE_INTERACTIVE[$i]:-0} == 1 )) then - # Unmark aSOFTWARE_INSTALL_STATE[$i]=0 G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$i]}: Install requires user input and cannot be automated." G_DIETPI-NOTIFY 1 "${aSOFTWARE_NAME[$i]}: Please run 'dietpi-software' to install manually." fi done + } + + # Unmark software which requires to load kernel modules on install, but modules are missing e.g. due to a kernel upgrade with outstanding reboot + Unmark_On_Missing_Kernel_Modules() + { + # Docker: https://github.com/MichaIng/DietPi/issues/3126 + if [[ ${aSOFTWARE_INSTALL_STATE[162]} == 1 || ${aSOFTWARE_INSTALL_STATE[134]} == 1 || ${aSOFTWARE_INSTALL_STATE[185]} == 1 || ${aSOFTWARE_INSTALL_STATE[86]} == 1 && ! -d /lib/modules/$(uname -r) ]] + then + G_WHIP_MSG '[WARNING] Docker and its dependants will be deselected +\nModules for the loaded kernel are missing. This is usually the case when the kernel was recently upgraded but a reboot is outstanding. The Docker install however will fail if it cannot load kernel modules. +\nPlease do a reboot first and reselect Docker or its dependant for install.' + (( ${aSOFTWARE_INSTALL_STATE[162]} == 1 )) && aSOFTWARE_INSTALL_STATE[162]=0 + (( ${aSOFTWARE_INSTALL_STATE[134]} == 1 )) && aSOFTWARE_INSTALL_STATE[134]=0 + (( ${aSOFTWARE_INSTALL_STATE[185]} == 1 )) && aSOFTWARE_INSTALL_STATE[185]=0 + (( ${aSOFTWARE_INSTALL_STATE[86]} == 1 )) && aSOFTWARE_INSTALL_STATE[86]=0 + fi + } + # Unmark all dependants of a software title + # $1: software ID + Unmark_Dependants() + { + aSOFTWARE_INSTALL_STATE[$1]=0 + local i + for i in "${!aSOFTWARE_NAME[@]}" + do + # NB: This does not work for dependencies given as "webserver", "desktop" or "browser". However, there are no conflicts among desktops and browser, and webservers only conflict with other webservers, hence obviously one is installed already which satisfies the dependency. + [[ ${aSOFTWARE_INSTALL_STATE[$i]} == 1 && ${aSOFTWARE_DEPS[$i]} =~ (^|[[:blank:]])$1([[:blank:]]|$) ]] || continue + aSOFTWARE_INSTALL_STATE[$i]=0 + [[ $dependants_text ]] || dependants_text='\n\nThe following dependants will be unmarked as well:' + dependants_text+="\n\n - ${aSOFTWARE_NAME[$i]}: It depends on ${aSOFTWARE_NAME[$1]}." + # Recursive call to unmark all dependants of this dependant + Unmark_Dependants "$i" + done } - # $1 : software ID - Resolve_Dependencies(){ + # Unmark conflicting software titles + CONFLICTS_RESOLVED=0 + Unmark_Conflicts() + { + # Loop through marked software + local i j unmarked_text dependants_text + for i in "${!aSOFTWARE_NAME[@]}" + do + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) || continue + + # Loop through installed or marked conflicts + for j in ${aSOFTWARE_CONFLICTS[$i]} + do + (( ${aSOFTWARE_INSTALL_STATE[$j]} > 0 )) || continue + + # At least one conflict is installed or marked: Unmark software + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && { unmarked_text+="\n\n${aSOFTWARE_NAME[$i]} won't be installed, as it conflicts with:"; Unmark_Dependants "$i"; } + + # Unmark all marked conflicts + if (( ${aSOFTWARE_INSTALL_STATE[$j]} == 1 )) + then + unmarked_text+="\n\n - ${aSOFTWARE_NAME[$j]}: It won't be installed either." + Unmark_Dependants "$j" + else + unmarked_text+="\n\n - ${aSOFTWARE_NAME[$j]}: It is installed already." + fi + done + done - # Set flag when software recommends automated APT upgrades, so that we only ask user once. - # - The flag value is the software ID, so we can tell which software did recommend it. - # - This overwrites previous IDs, but it's fine for now to print only the last software name that recommended it. - (( ${aSOFTWARE_RECOMMENDS_AUTOMATED_UPGRADES[$1]} )) && recommends_automated_upgrades=$1 + CONFLICTS_RESOLVED=1 + [[ $unmarked_text ]] || return 0 + + # Conflicts have been unmarked: Inform user! + G_WHIP_MSG "[WARNING] Conflicting installs have been detected!$unmarked_text$dependants_text" + } + + # $1: software ID + Resolve_Dependencies(){ # Loop through dependencies - local j - for j in ${aSOFTWARE_DEPS[$1]} + local i + for i in ${aSOFTWARE_DEPS[$1]} do # Resolve webserver dependency based on install state and user preference - if [[ $j == 'webserver' ]] + if [[ $i == 'webserver' ]] then - # Check for existing webserver (Apache2, Nginx, Lighttpd) installation + # Check for existing webserver (Apache, Nginx, Lighttpd) installation # - Do no reinstalls, as those are currently too intrusive, overriding custom configs (( ${aSOFTWARE_INSTALL_STATE[83]} < 1 && ${aSOFTWARE_INSTALL_STATE[84]} < 1 && ${aSOFTWARE_INSTALL_STATE[85]} < 1 )) || continue # No webserver installed, select one based on user preference # - Apache - if (( $INDEX_WEBSERVER_TARGET == 0 )) + if (( $INDEX_WEBSERVER == 0 )) then - j=83 + i=83 # - Nginx - elif (( $INDEX_WEBSERVER_TARGET == -1 )) + elif (( $INDEX_WEBSERVER == -1 )) then - j=85 + i=85 # - Lighttpd else - j=84 + i=84 fi # Resolve desktop dependency based on install state - elif [[ $j == 'desktop' ]] + elif [[ $i == 'desktop' ]] then # Check for existing desktop (LXDE, MATE, Xfce, GNUstep, LXQt) installation # - Do no reinstalls, as those are loose dependencies (( ${aSOFTWARE_INSTALL_STATE[23]} < 1 && ${aSOFTWARE_INSTALL_STATE[24]} < 1 && ${aSOFTWARE_INSTALL_STATE[25]} < 1 && ${aSOFTWARE_INSTALL_STATE[26]} < 1 && ${aSOFTWARE_INSTALL_STATE[173]} < 1 )) || continue # No desktop installed, select one based on user preference - # - LXDE - if (( $INDEX_DESKTOP_TARGET == 0 )) + # - GNUstep + if (( $INDEX_DESKTOP == -4 )) then - j=23 + i=26 # - Xfce - elif (( $INDEX_DESKTOP_TARGET == -1 )) + elif (( $INDEX_DESKTOP == -1 )) then - j=25 + i=25 # - MATE - elif (( $INDEX_DESKTOP_TARGET == -2 )) + elif (( $INDEX_DESKTOP == -2 )) then - j=24 + i=24 # - LXQt - elif (( $INDEX_DESKTOP_TARGET == -3 )) + elif (( $INDEX_DESKTOP == -3 )) then - j=173 + i=173 - # - GNUstep + # - LXDE else - j=26 + i=23 fi # Resolve browser dependency based on install state - elif [[ $j == 'browser' ]] + elif [[ $i == 'browser' ]] then # Check for existing browser (Firefox, Chromium) installation # - Do no reinstalls, as those are loose dependencies @@ -2118,32 +2181,32 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" # No browser installed, select one based on user preference # - None - if (( $INDEX_BROWSER_TARGET == 0 )) + if (( $INDEX_BROWSER == 0 )) then continue - # - Firefox - elif (( $INDEX_BROWSER_TARGET == -1 )) + # - Chromium + elif (( $INDEX_BROWSER == -2 )) then - j=67 + i=113 - # - Chromium + # - Firefox else - j=113 + i=67 fi fi # Skip if dependency is marked for install already - (( ${aSOFTWARE_INSTALL_STATE[$j]} == 1 )) && continue + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && continue # Is it reinstalled or freshly installed? local re_installed='installed' - (( ${aSOFTWARE_INSTALL_STATE[$j]} == 2 )) && re_installed='reinstalled' + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 2 )) && re_installed='reinstalled' - aSOFTWARE_INSTALL_STATE[$j]=1 - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$j]} will be $re_installed" + aSOFTWARE_INSTALL_STATE[$i]=1 + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$i]} will be $re_installed" # Recursive call to resolve dependencies of this dependency - Resolve_Dependencies "$j" + Resolve_Dependencies "$i" done } @@ -2154,104 +2217,21 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Checking for prerequisite software' - local software_id=-1 - - #------------------------------------------------------------------------- - # Conflicts and special pre-req software cases - - # Don't let Pi-hole and AdGuard Home be installed at the same time - if (( ${aSOFTWARE_INSTALL_STATE[93]} > 0 && ${aSOFTWARE_INSTALL_STATE[126]} > 0 )) - then - (( ${aSOFTWARE_INSTALL_STATE[93]} == 1 )) && aSOFTWARE_INSTALL_STATE[93]=0 - (( ${aSOFTWARE_INSTALL_STATE[126]} == 1 )) && aSOFTWARE_INSTALL_STATE[126]=0 - G_WHIP_MSG "[WARNING] Conflicting software selection -\n${aSOFTWARE_NAME[93]} and ${aSOFTWARE_NAME[126]} cannot be installed at the same time. -\nThese pieces of software will be skipped. Other DietPi-Software installations will continue." - fi - - # Don't let Tor Relay and Tor Hotspot be installed at the same time - if (( ${aSOFTWARE_INSTALL_STATE[184]} > 0 && ${aSOFTWARE_INSTALL_STATE[61]} > 0 )) - then - (( ${aSOFTWARE_INSTALL_STATE[61]} == 1 )) && aSOFTWARE_INSTALL_STATE[61]=0 - (( ${aSOFTWARE_INSTALL_STATE[184]} == 1 )) && aSOFTWARE_INSTALL_STATE[184]=0 - G_WHIP_MSG "[WARNING] Conflicting software selection -\n${aSOFTWARE_NAME[61]} and ${aSOFTWARE_NAME[184]} cannot be installed at the same time. -\nThese pieces of software will be skipped. Other DietPi-Software installations will continue." - fi - - # Prevent Docker install if kernel has just been upgraded and old one overwritten/purged: https://github.com/MichaIng/DietPi/issues/3126 - if [[ ${aSOFTWARE_INSTALL_STATE[162]} == 1 && ! -d /lib/modules/$(uname -r) ]] - then - G_WHIP_MSG '[WARNING] Docker install will be deselected -\nIt seems that your kernel has just been upgraded. The mismatch between loaded and installed kernel versions would cause a failure during Docker install. -\nPlease reselect Docker from dietpi-software after next reboot, or run: -# dietpi-software install 162' - aSOFTWARE_INSTALL_STATE[162]=0 - # Unmark Docker dependants as well - (( ${aSOFTWARE_INSTALL_STATE[134]} == 1 )) && aSOFTWARE_INSTALL_STATE[134]=0 - (( ${aSOFTWARE_INSTALL_STATE[185]} == 1 )) && aSOFTWARE_INSTALL_STATE[185]=0 - (( ${aSOFTWARE_INSTALL_STATE[86]} == 1 )) && aSOFTWARE_INSTALL_STATE[86]=0 - fi - # If OctoPrint and mjpg-streamer both are installed, OctoPrint is automatically configured to use mjpg-streamer. For the integrated time-lapse feature, FFmpeg is required. - software_id=7 if (( ${aSOFTWARE_INSTALL_STATE[137]} > 0 && ${aSOFTWARE_INSTALL_STATE[153]} > 0 && ${aSOFTWARE_INSTALL_STATE[137]} + ${aSOFTWARE_INSTALL_STATE[153]} < 4 )) then - aSOFTWARE_INSTALL_STATE[$software_id]=1 - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} will be installed" + aSOFTWARE_INSTALL_STATE[7]=1 + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[7]} will be installed" fi - # Flag for software that recommends automated APT upgrades - local recommends_automated_upgrades= - # Loop through marked software to resolve dependencies each + local i for i in "${!aSOFTWARE_NAME[@]}" do (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) || continue Resolve_Dependencies "$i" done - # Offer user to enable automated APT upgrades when any software recommends it. - if [[ $recommends_automated_upgrades ]] && ! grep -q '^[[:blank:]]*CONFIG_CHECK_APT_UPDATES=2' /boot/dietpi.txt - then - G_WHIP_BUTTON_OK_TEXT='YES' G_WHIP_BUTTON_CANCEL_TEXT='NO' - if G_WHIP_YESNO "Would you like to enable automated daily upgrades for APT packages?\n\nThis is recommended for ${aSOFTWARE_NAME[$recommends_automated_upgrades]}. -\nDaily APT upgrade logs can be found at: /var/tmp/dietpi/logs/dietpi-update_apt.log" - then - G_CONFIG_INJECT 'CONFIG_CHECK_APT_UPDATES=' 'CONFIG_CHECK_APT_UPDATES=2' /boot/dietpi.txt - fi - fi - - # Webserver - Check for stacks and flag as installing - # - Apache - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - - # SQLite: LASP - (( ${aSOFTWARE_INSTALL_STATE[87]} > 0 )) && aSOFTWARE_INSTALL_STATE[75]=1 - - # MariaDB: LAMP - (( ${aSOFTWARE_INSTALL_STATE[88]} > 0 )) && aSOFTWARE_INSTALL_STATE[76]=1 - - # - Nginx - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - - # SQLite: LESP - (( ${aSOFTWARE_INSTALL_STATE[87]} > 0 )) && aSOFTWARE_INSTALL_STATE[78]=1 - - # MariaDB: LEMP - (( ${aSOFTWARE_INSTALL_STATE[88]} > 0 )) && aSOFTWARE_INSTALL_STATE[79]=1 - - # - Lighttpd - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then - - # SQLite: LLSP - (( ${aSOFTWARE_INSTALL_STATE[87]} > 0 )) && aSOFTWARE_INSTALL_STATE[81]=1 - - # MariaDB: LLMP - (( ${aSOFTWARE_INSTALL_STATE[88]} > 0 )) && aSOFTWARE_INSTALL_STATE[82]=1 - - fi - # Update PHP variables after all software titles have been marked # - Never install PHP7.2 if PHP7.3 or PHP7.4 is already present if (( ${aSOFTWARE_INSTALL_STATE[89]} > 0 )) && ! command -v php7.3 > /dev/null && ! command -v php7.4 > /dev/null; then @@ -2377,7 +2357,7 @@ _EOF_ if [[ ! -d $i/Desktop ]] then # shellcheck disable=SC2012 - read -r uid gid <<< "$(ls -dn "$i" | mawk '{print $3" "$4}')" + read -r uid gid < <(ls -dn "$i" | mawk '{print $3,$4}') G_EXEC mkdir -p "$i/Desktop" G_EXEC chown "$uid:$gid" "$i/Desktop" fi @@ -2385,7 +2365,7 @@ _EOF_ done } - Create_UserContent_Folders(){ + Create_Required_Dirs(){ G_EXEC mkdir -p /mnt/dietpi_userdata/{Music,Pictures,Video,downloads} /var/www /opt /usr/local/bin G_EXEC chown dietpi:dietpi /mnt/dietpi_userdata/{Music,Pictures,Video,downloads} @@ -2604,7 +2584,7 @@ _EOF_ # Validate input # - User name needs to be given G_EXEC_DESC="Verifying user \"${user:-}\" to run ${aSOFTWARE_NAME[$software_id]}" G_EXEC test "$user" - # - Pre-create given primary group as useradd and usermod fail if it does not exist + # - Pre-create given primary group, as useradd and usermod fail if it does not exist [[ $group_primary ]] && ! getent group "$group_primary" > /dev/null && G_EXEC groupadd -r "$group_primary" # - Only add to supplementary groups that do exist local group groups @@ -2946,9 +2926,6 @@ _EOF_ Banner_Installing - # Mark target SSH server choice, if not selected via menu or first run setup - INDEX_SSHSERVER_TARGET=-1 - # Stop OpenSSH service to unbind port 22 systemctl -q is-active ssh && G_EXEC systemctl stop ssh @@ -2968,9 +2945,8 @@ _EOF_ G_EXEC systemctl enable dropbear aSTART_SERVICES+=('dropbear') - # Mark OpenSSH for uninstall and update choice system - dpkg-query -s 'openssh-server' &> /dev/null && aSOFTWARE_INSTALL_STATE[105]=-1 && UNINSTALL_REQUIRED=1 - INDEX_SSHSERVER_CURRENT=-1 + # Mark OpenSSH for uninstall + dpkg-query -s 'openssh-server' &> /dev/null && aSOFTWARE_INSTALL_STATE[105]=-1 fi @@ -2979,15 +2955,10 @@ _EOF_ Banner_Installing - # Mark target SSH server choice, if not selected via menu or first run setup - INDEX_SSHSERVER_TARGET=-2 - # Stop Dropbear service to unbind port 22 systemctl -q is-active dropbear && G_EXEC systemctl stop dropbear - # SSH server package pulls client as dependency. Mark client hence as installed and mark it explicitly so that it is not autoremoved with the server but must be marked for uninstall instead. - G_AGI openssh-server openssh-client - aSOFTWARE_INSTALL_STATE[0]=2 + G_AGI openssh-server # Allow root login G_CONFIG_INJECT 'PermitRootLogin[[:blank:]]' 'PermitRootLogin yes' /etc/ssh/sshd_config @@ -2999,9 +2970,8 @@ _EOF_ G_EXEC systemctl enable ssh aSTART_SERVICES+=('ssh') - # Mark Dropbear for uninstall and update choice system - grep -q '^dropbear[^[:blank:]]*[[:blank:]]' <<< "$(dpkg --get-selections)" && aSOFTWARE_INSTALL_STATE[104]=-1 && UNINSTALL_REQUIRED=1 - INDEX_SSHSERVER_CURRENT=-2 + # Mark Dropbear for uninstall + grep -q '^dropbear[^[:blank:]]*[[:blank:]]' < <(dpkg --get-selections) && aSOFTWARE_INSTALL_STATE[104]=-1 fi @@ -3037,6 +3007,7 @@ _EOF_ G_EXEC ln -s /mnt/dietpi_userdata/postgresql /var/lib/postgresql G_AGI postgresql + G_EXEC systemctl stop postgresql # Disable TCP/IP listener and assure that UNIX domain socket is enabled at expected path # NB: On Stretch (PGSQL v9.6) conf.d is not yet included by default and we skip the step there. It listens on localhost only, hence has no security impact. @@ -3064,9 +3035,12 @@ unix_socket_directories = '/run/postgresql'" > "$i/00dietpi.conf" # Enable DietPi-RAMlog service G_EXEC systemctl enable dietpi-ramlog + # Apply logging choice index + [[ $INDEX_LOGGING == -[12] ]] || INDEX_LOGGING=-1 + # Sync logs to disk once local acommand=('/boot/dietpi/func/dietpi-ramlog' '1') - systemctl is-active dietpi-ramlog > /dev/null && acommand=('systemctl' 'stop' 'dietpi-ramlog') + systemctl -q is-active dietpi-ramlog && acommand=('systemctl' 'stop' 'dietpi-ramlog') G_EXEC_DESC='Storing /var/log metadata to disk' G_EXEC "${acommand[@]}" unset -v acommand @@ -3118,16 +3092,23 @@ unix_socket_directories = '/run/postgresql'" > "$i/00dietpi.conf" Banner_Installing # Workaround for dpkg failure on 1st install if service is already running but APT not installed: https://github.com/MichaIng/DietPi/pull/2277/#issuecomment-441460925 - systemctl stop rsyslog 2> /dev/null + systemctl -q is-active rsyslog && G_EXEC systemctl stop rsyslog G_AGI rsyslog G_EXEC systemctl enable --now rsyslog + # Apply logging choice index + grep -q '[[:blank:]]/var/log[[:blank:]]' /etc/fstab || findmnt -t tmpfs -M /var/log > /dev/null || INDEX_LOGGING=-3 + fi software_id=7 # FFmpeg if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing + + # Raspberry Pi Bullseye: Enable hardware codecs + (( $G_HW_MODEL > 9 )) || (( $G_DISTRO < 6 )) || /boot/dietpi/func/dietpi-set_hardware rpi-codec 1 + G_AGI ffmpeg fi @@ -3213,7 +3194,7 @@ unix_socket_directories = '/run/postgresql'" > "$i/00dietpi.conf" # Create piwheels config file for ARMv6 and ARMv7 [[ $G_HW_ARCH != [12] || -f '/etc/pip.conf' ]] || G_EXEC eval "echo -e '[global]\nextra-index-url=https://www.piwheels.org/simple/' > /etc/pip.conf" - # Perform pip3 installation + # Perform pip3 install (which includes setuptools and wheel modules) local url='https://bootstrap.pypa.io/pip/get-pip.py' (( $G_DISTRO > 4 )) || url='https://bootstrap.pypa.io/pip/3.5/get-pip.py' # https://pip.pypa.io/en/stable/news/#id1 DEPS_LIST='python3-dev' Download_Install "$url" @@ -3264,8 +3245,8 @@ unix_socket_directories = '/run/postgresql'" > "$i/00dietpi.conf" fi # Get latest version - local file=$(curl -sfL 'https://golang.org/dl/?mode=json' | grep -wom1 "go[0-9.]*\.linux-$arch\.tar\.gz") - [[ $file ]] || { file="go1.16.3.linux-$arch.tar.gz"; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. \"$file\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } + local file=$(curl -sSfL 'https://golang.org/dl/?mode=json' | grep -wo "go[0-9.]*\.linux-$arch\.tar\.gz" | head -1) + [[ $file ]] || { file="go1.17.4.linux-$arch.tar.gz"; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. \"$file\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } # Reinstall: Remove previous instance [[ -d '/usr/local/go' ]] && G_EXEC rm -R /usr/local/go @@ -3288,15 +3269,16 @@ _EOF_ Banner_Installing - # On Raspbian, only "unrar-free" is available in repos, but does not support all rar formats, thus we use "unrar" [non-free] from Debian repo: http://raspbian.raspberrypi.org/raspbian/pool/non-free/u/unrar-nonfree/ - if (( $G_HW_MODEL < 10 )) && (( $G_RASPBIAN )); then + # On Raspbian, only "unrar-free" is available which does not support all RAR formats, thus we use "unrar" [non-free] from Debian on ARMv7+ models: http://raspbian.raspberrypi.org/raspbian/pool/non-free/u/unrar-nonfree/ + if (( $G_HW_ARCH == 1 )) + then + G_AGI unrar-free + elif (( $G_HW_MODEL < 10 )) && (( $G_RASPBIAN )) + then Download_Install "https://dietpi.com/downloads/binaries/rpi/unrar-armhf-$G_DISTRO_NAME.deb" - else - G_AGI unrar - fi fi @@ -3307,7 +3289,7 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_DESKTOP_TARGET=0 INDEX_DESKTOP_CURRENT=0 + INDEX_DESKTOP=0 # RPi: Block packages from RPi desktop which conflict with a native LXDE desktop: # - https://github.com/MichaIng/DietPi/issues/1558#issuecomment-691206284 @@ -3382,7 +3364,7 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_DESKTOP_TARGET=-3 INDEX_DESKTOP_CURRENT=-3 + INDEX_DESKTOP=-3 # Buster: No leafpad available, use featherpad instead: https://github.com/MichaIng/DietPi/issues/1918#issuecomment-489319719 local editor='leafpad' @@ -3410,7 +3392,7 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_DESKTOP_TARGET=-2 INDEX_DESKTOP_CURRENT=-2 + INDEX_DESKTOP=-2 # Add xterm, as the mate-terminal is not compatible with desktop console shortcuts: https://github.com/MichaIng/DietPi/issues/3160#issuecomment-828305136 G_AGI mate-desktop-environment-core mate-media upower xterm @@ -3425,7 +3407,7 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_DESKTOP_TARGET=-4 INDEX_DESKTOP_CURRENT=-4 + INDEX_DESKTOP=-4 G_AGI wmaker gnustep gnustep-devel gnustep-games upower policykit-1 xterm @@ -3439,7 +3421,7 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_DESKTOP_TARGET=-1 INDEX_DESKTOP_CURRENT=-1 + INDEX_DESKTOP=-1 G_AGI xfce4 xfce4-terminal gnome-icon-theme tango-icon-theme upower policykit-1 @@ -3472,7 +3454,7 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_BROWSER_TARGET=-1 INDEX_BROWSER_CURRENT=-1 + INDEX_BROWSER=-1 G_AGI firefox-esr @@ -3504,9 +3486,9 @@ Pin-Priority: 500 _EOF_ G_AGI xrdp xorgxrdp - # Workaround for failing mouse and keyboard input: https://github.com/MichaIng/DietPi/issues/3022 - G_CONFIG_INJECT 'Option "CoreKeyboard"' ' Option "CoreKeyboard"' /etc/X11/xrdp/xorg.conf 'Driver "xrdpkeyb"' - G_CONFIG_INJECT 'Option "CorePointer"' ' Option "CorePointer"' /etc/X11/xrdp/xorg.conf 'Driver "xrdpmouse"' + # Workaround for failing mouse and keyboard input: https://github.com/neutrinolabs/xorgxrdp/issues/164 + # - Solved on Bookworm, but G_CONFIG_INJECT detects and skips it then, and keeping it covers dist-upgraded systems. + GGI_PRESERVE=1 G_CONFIG_INJECT 'Option[[:blank:]]+"DefaultServerLayout"' ' Option "DefaultServerLayout" "X11 Server"' /etc/X11/xrdp/xorg.conf 'Section[[:blank:]]+"ServerFlags"' G_EXEC systemctl enable xrdp aSTART_SERVICES+=('xrdp') @@ -3541,26 +3523,31 @@ _EOF_ G_WHIP_DEFAULT_ITEM=$version G_WHIP_MENU 'Please choose which version of DietPi-Dashboard should be installed.' && version=$G_WHIP_RETURNED_VALUE + # Download binary and set config URL + local url if [[ $version == 'Stable' ]] then Download_Install "$(curl -sSfL 'https://api.github.com/repos/ravenclaw900/dietpi-dashboard/releases/latest' | mawk -F\" "/\"browser_download_url\": \".*dietpi-dashboard-$G_HW_ARCH_NAME\"/{print \$4}")" /opt/dietpi-dashboard/dietpi-dashboard + url="https://raw.githubusercontent.com/ravenclaw900/DietPi-Dashboard/$(curl -sSfL 'https://api.github.com/repos/ravenclaw900/dietpi-dashboard/releases/latest' | mawk -F\" '/"tag_name": ".*"/{print $4}')/config.toml" elif [[ $version == 'Nightly' ]] then no_check_url=1 Download_Install "https://nightly.link/ravenclaw900/DietPi-Dashboard/workflows/push-build/main/dietpi-dashboard-$G_HW_ARCH_NAME.zip" /opt/dietpi-dashboard + url='https://raw.githubusercontent.com/ravenclaw900/DietPi-Dashboard/main/config.toml' fi - G_EXEC chmod +x /opt/dietpi-dashboard/dietpi-dashboard - [[ -f '/opt/dietpi-dashboard/config.toml' ]] || cat << '_EOF_' > /opt/dietpi-dashboard/config.toml -# TCP network port -port = 8088 + # Config + if [[ ! -f '/opt/dietpi-dashboard/config.toml' ]] + then + G_EXEC curl -sSfL "$url" -o /opt/dietpi-dashboard/config.toml + # Enable password protection with global software password by default + G_CONFIG_INJECT 'pass[[:blank:]]' 'pass = true' /opt/dietpi-dashboard/config.toml + G_CONFIG_INJECT 'hash[[:blank:]]' "hash = \"$(echo -n "$GLOBAL_PW" | sha512sum | mawk '{print $1}')\"" /opt/dietpi-dashboard/config.toml + G_CONFIG_INJECT 'secret[[:blank:]]' "secret = \"$(openssl rand -hex 32)\"" /opt/dietpi-dashboard/config.toml + fi -# TLS for HTTPS -tls = false -cert = "/path/to/cert" -key = "/path/to/key" -_EOF_ + # Service cat << '_EOF_' > /etc/systemd/system/dietpi-dashboard.service [Unit] Description=Web Dashboard (DietPi) @@ -3577,7 +3564,7 @@ StandardOutput=journal [Install] WantedBy=multi-user.target _EOF_ - # Dashboard service needs to be started by systemd, as dietpi-services must not control it to prevent it from stopping during software installs. + # Service needs to be started by systemd, as dietpi-services must not control it to prevent it from stopping during software installs done via dashboard itself. G_EXEC systemctl enable dietpi-dashboard aSTART_SERVICES+=('dietpi-dashboard') @@ -3589,10 +3576,11 @@ _EOF_ Banner_Installing G_AGI transmission-daemon + G_EXEC systemctl stop transmission-daemon # Remove obsolete service and environment files Remove_SysV transmission-daemon 1 - [[ -f '/etc/init/transmission-daemon.conf' ]] && rm -v /etc/init/transmission-daemon.conf + [[ -f '/etc/init/transmission-daemon.conf' ]] && G_EXEC rm /etc/init/transmission-daemon.conf # Make "dietpi" the primary group and "debian-transmission" a supplementary group, to make downloads R/W accessible for other media software and network shares. G_EXEC usermod -g dietpi -aG debian-transmission debian-transmission @@ -3632,6 +3620,7 @@ _EOF_ G_EXEC eval "debconf-set-selections <<< 'proftpd-basic shared/proftpd/inetd_or_standalone select standalone'" G_AGI proftpd-basic + G_EXEC systemctl stop proftpd # Config G_BACKUP_FP /etc/proftpd/proftpd.conf @@ -3661,6 +3650,7 @@ _EOF_ echo 'd /run/samba-cache' > /etc/tmpfiles.d/dietpi-samba_cache.conf G_AGI samba + G_EXEC systemctl stop nmbd smbd echo -e "$GLOBAL_PW\n$GLOBAL_PW" | smbpasswd -s -a dietpi @@ -3681,6 +3671,7 @@ _EOF_ [[ -f '/etc/vsftpd.conf' ]] || dps_index=$software_id Download_Install 'conf' /etc/vsftpd.conf G_AGI vsftpd + G_EXEC systemctl stop vsftpd # Do not allow root access via FTP G_EXEC sed -i 's/^[[:blank:]]*root/#root/' /etc/ftpusers @@ -3693,6 +3684,7 @@ _EOF_ Banner_Installing G_AGI nfs-kernel-server + G_EXEC systemctl stop nfs-kernel-server [[ -d '/etc/exports.d' ]] || G_EXEC mkdir /etc/exports.d [[ -f '/etc/exports.d/dietpi.exports' ]] || echo '/mnt/dietpi_userdata *(rw,async,no_root_squash,fsid=0,crossmnt,no_subtree_check)' > /etc/exports.d/dietpi.exports @@ -3705,39 +3697,85 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_WEBSERVER_TARGET=0 INDEX_WEBSERVER_CURRENT=0 + INDEX_WEBSERVER=0 + + # Pre-create a dummy port 80 vhost if it does not exist yet, so we can avoid overwriting it on reinstalls. + if [[ ! -f '/etc/apache2/sites-available/000-default.conf' ]] + then + [[ -d '/etc/apache2/sites-available' ]] || G_EXEC mkdir -p /etc/apache2/sites-available + cat << '_EOF_' > /etc/apache2/sites-available/000-default.conf +# /etc/apache2/sites-available/000-default.conf + + # Define directives here which shall apply for port 80 requests only + +_EOF_ + # Otherwise assure that the webroot is changed, as all our install options depend on it. + else + G_EXEC sed -i 's|/var/www/html|/var/www|g' /etc/apache2/sites-available/000-default.conf + fi local apackages=('apache2') - # Install certbot module, if certbot was already installed + # Install Certbot module, if Certbot was already installed (( ${aSOFTWARE_INSTALL_STATE[92]} == 2 )) && apackages+=('python3-certbot-apache') G_AGI "${apackages[@]}" + G_EXEC systemctl stop apache2 + apachectl -M | grep -q 'cache_disk' || G_EXEC systemctl disable --now apache-htcacheclean + + # Enable event MPM and headers module + G_EXEC a2dismod -fq mpm_prefork + G_EXEC a2enmod -q mpm_event headers + + # Disable obsolete default configs + for i in 'charset' 'localized-error-pages' 'other-vhosts-access-log' 'security' 'serve-cgi-bin' + do + [[ -L /etc/apache2/conf-enabled/$i.conf ]] && G_EXEC a2disconf "$i" + done # Config - G_BACKUP_FP /etc/apache2/apache2.conf - dps_index=$software_id Download_Install 'apache2.conf' /etc/apache2/apache2.conf - cat << '_EOF_' > /etc/apache2/sites-available/000-default.conf - - DocumentRoot /var/www - ErrorLog ${APACHE_LOG_DIR}/error.log - #CustomLog ${APACHE_LOG_DIR}/access.log combined - -_EOF_ - cat << _EOF_ > /etc/apache2/mods-available/mpm_prefork.conf - - StartServers $G_HW_CPU_CORES - MinSpareServers 1 - MaxSpareServers $G_HW_CPU_CORES - MaxRequestWorkers 50 - MaxConnectionsPerChild 0 - + cat << _EOF_ > /etc/apache2/conf-available/dietpi.conf +# /etc/apache2/conf-available/dietpi.conf +# Default server name and webroot +ServerName $(G_GET_NET ip) +DocumentRoot /var/www + +# Logging to: journalctl -u apache2 +ErrorLog syslog:local7 + +# Allow unlimited Keep-Alive requests +MaxKeepAliveRequests 0 + +# MPM event configuration +# - Run a single process which does not expire +# - Limit request handler threads to 64 +StartServers 1 +ServerLimit 1 +MaxConnectionsPerChild 0 +ThreadsPerChild 64 +ThreadLimit 64 +MinSpareThreads 1 +MaxSpareThreads 64 +MaxRequestWorkers 64 + +# Minimize public info +ServerTokens Prod +ServerSignature Off +TraceEnable Off + +# Security headers +Header set X-Content-Type-Options "nosniff" +Header set X-Frame-Options "sameorigin" +Header set X-XSS-Protection "1; mode=block" +Header set X-Robots-Tag "none" +Header set X-Download-Options "noopen" +Header set X-Permitted-Cross-Domain-Policies "none" +Header set Referrer-Policy "no-referrer" _EOF_ + G_EXEC a2enconf dietpi + # Webroot - [[ -f '/var/www/html/index.html' ]] && G_EXEC mv /var/www/html/index.html /var/www/ + [[ -f '/var/www/html/index.html' && ! -f '/var/www/index.html' ]] && G_EXEC mv /var/www/html/index.html /var/www/ [[ -d '/var/www/html' ]] && G_EXEC rmdir --ignore-fail-on-non-empty /var/www/html - # Change error log level - G_EXEC sed -i '/LogLevel[[:blank:]]/c\ LogLevel error' /etc/apache2/sites-available/* - fi software_id=85 # Nginx @@ -3746,12 +3784,13 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_WEBSERVER_TARGET=-1 INDEX_WEBSERVER_CURRENT=-1 + INDEX_WEBSERVER=-1 local apackages=('nginx-light') - # Install certbot module, if certbot was already installed + # Install Certbot module, if Certbot was already installed (( ${aSOFTWARE_INSTALL_STATE[92]} == 2 )) && apackages+=('python3-certbot-nginx') G_AGI "${apackages[@]}" + G_EXEC systemctl stop nginx # Custom configs, included by sites-enabled/default within server directive, while nginx/(conf.d|sites-enabled) is included by nginx.conf outside server directive [[ -d '/etc/nginx/sites-dietpi' ]] || G_EXEC mkdir /etc/nginx/sites-dietpi @@ -3810,10 +3849,11 @@ _EOF_ fi # Apply preference index - INDEX_WEBSERVER_TARGET=-2 INDEX_WEBSERVER_CURRENT=-2 + INDEX_WEBSERVER=-2 # perl is required for lighty-enable-mod, it has been degraded to recommends only with Buster. G_AGI lighttpd perl $deflate $openssl + G_EXEC systemctl stop lighttpd Remove_SysV lighttpd @@ -3879,9 +3919,10 @@ _EOF_ G_EXEC ln -s /mnt/dietpi_userdata/mysql /var/lib/mysql local apackages=('mariadb-server') - # Install PHP module, if PHP was already installed + # Install PHP module if PHP was already installed (( ${aSOFTWARE_INSTALL_STATE[89]} == 2 )) && apackages+=("$PHP_NAME-mysql") G_AGI "${apackages[@]}" + G_EXEC systemctl stop mariadb Remove_SysV mysql 1 @@ -3889,8 +3930,8 @@ _EOF_ [[ $(stat -c '%U' /mnt/dietpi_userdata/mysql/mysql) == 'mysql' ]] || G_EXEC chown -R mysql:mysql /mnt/dietpi_userdata/mysql # Stretch: Since Buster (MariaDB 10.3) the following settings are removed and default to our needs: - # - innodb_large_prefix: https://mariadb.com/kb/en/library/innodb-system-variables/#innodb_large_prefix - # - innodb_file_format: https://mariadb.com/kb/en/library/innodb-system-variables/#innodb_file_format + # - innodb_large_prefix: https://mariadb.com/kb/en/innodb-system-variables/#innodb_large_prefix + # - innodb_file_format: https://mariadb.com/kb/en/innodb-system-variables/#innodb_file_format if (( $G_DISTRO < 5 )) then G_DIETPI-NOTIFY 2 'Switch to modern InnoDB Barracuda file format' @@ -3908,7 +3949,7 @@ _EOF_ Banner_Installing local apackages=('sqlite3') - # Install PHP module, if PHP was already installed + # Install PHP module if PHP was already installed (( ${aSOFTWARE_INSTALL_STATE[89]} == 2 )) && apackages+=("$PHP_NAME-sqlite3") G_AGI "${apackages[@]}" @@ -3920,11 +3961,12 @@ _EOF_ Banner_Installing local apackages=('redis-server') - # Install PHP module, if PHP was already installed + # Install PHP module if PHP was already installed (( ${aSOFTWARE_INSTALL_STATE[89]} == 2 )) && apackages+=("$PHP_NAME-redis") G_AGI "${apackages[@]}" + G_EXEC systemctl stop redis-server - # Enable redis php module, if installed + # Enable Redis php module if installed command -v phpenmod > /dev/null && G_EXEC phpenmod redis # Disable file logging and enable syslog instead, which resolves reported startup issues in cases as well: https://github.com/MichaIng/DietPi/issues/3291 @@ -3936,16 +3978,16 @@ _EOF_ fi software_id=89 # PHP - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then Banner_Installing # Stretch: Add Ondrej's PHP repository for latest PHP version (currently PHP7.3) - if (( $G_DISTRO < 5 )); then - + if (( $G_DISTRO < 5 )) + then # Debian (+sury.org) armhf is not ARMv6 compatible: https://github.com/MichaIng/DietPi/issues/2794 - if (( $G_HW_ARCH < 2 )); then - + if (( $G_HW_ARCH < 2 )) + then local url='http://raspbian.raspberrypi.org/raspbian/' # Actually we do not support any non-RPi ARMv6 devices currently, but lets be failsafe here (( $G_HW_MODEL > 9 )) && url='https://deb.debian.org/debian/' @@ -3959,9 +4001,7 @@ Package: php libapache2-mod-php php-* libssl* libc6* libc-* libgssapi-krb5-2 lib Pin: release n=buster\nPin-Priority: 501\n # Pin down all other Buster packages to only allow upgrades of already installed ones via: "apt upgrade" Package: *\nPin: release n=buster\nPin-Priority: 100' > /etc/apt/preferences.d/dietpi-php - else - # APT key G_EXEC curl -sSfL 'https://packages.sury.org/php/apt.gpg' -o /etc/apt/trusted.gpg.d/dietpi-php.gpg # APT source @@ -3969,30 +4009,21 @@ Package: *\nPin: release n=buster\nPin-Priority: 100' > /etc/apt/preferences.d/d # Pin down libssl1.1 version from this repo on Stretch: https://github.com/MichaIng/DietPi/issues/2734 echo -e '# libssl1.1 from sury.org breaks Lighttpd install Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /etc/apt/preferences.d/dietpi-openssl - fi # APT list update G_AGUP - fi # Base PHP modules - # - Apache: mod_php - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - - local apackages=("libapache2-mod-$PHP_NAME") - - # - Lighttpd and Nginx: PHP-FPM - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - + # - Webserver: PHP-FPM + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 || ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )) + then local apackages=("$PHP_NAME-fpm") # - No webserver: CLI usage only (php binary) else - local apackages=("$PHP_NAME-cli") - fi # Additional PHP modules, commonly used by most web applications @@ -4008,37 +4039,31 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et (( ${aSOFTWARE_INSTALL_STATE[91]} > 0 )) && apackages+=("$PHP_NAME-redis") G_AGI "${apackages[@]}" + systemctl -q is-active "$PHP_NAME-fpm" && G_EXEC systemctl stop "$PHP_NAME-fpm" - # PHP-FPM - if (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - - # Base - sed -i '/cgi.fix_pathinfo=/c\cgi.fix_pathinfo=1' "$FP_PHP_BASE_DIR/fpm/php.ini" + # Assure that mod_php is purged in favour of PHP-FPM + G_AGP 'libapache2-mod-php*' + G_EXEC rm -Rf /{etc/php,var/lib/php/modules}/*/apache2 + # PHP-FPM + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 || ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )) + then # Optimisations based on total cores - sed -i "/pm.max_children = /c\pm.max_children = $(( $G_HW_CPU_CORES * 3 ))" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" - sed -i "/pm.start_servers = /c\pm.start_servers = $G_HW_CPU_CORES" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" - sed -i "/pm.min_spare_servers = /c\pm.min_spare_servers = $G_HW_CPU_CORES" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" - sed -i "/pm.max_spare_servers = /c\pm.max_spare_servers = $G_HW_CPU_CORES" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" - - # Environment settings - sed -i "/env\[HOSTNAME\]/c\env\[HOSTNAME\] = \$HOSTNAME" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" - sed -i "/env\[PATH\]/c\env\[PATH\] = /usr/local/bin:/usr/bin:/bin" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" - + G_CONFIG_INJECT 'pm.max_children[[:blank:]=]' "pm.max_children = $(( $G_HW_CPU_CORES * 3 ))" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" + G_CONFIG_INJECT 'pm.start_servers[[:blank:]=]' "pm.start_servers = $G_HW_CPU_CORES" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" + G_CONFIG_INJECT 'pm.min_spare_servers[[:blank:]=]' "pm.min_spare_servers = $G_HW_CPU_CORES" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" + G_CONFIG_INJECT 'pm.max_spare_servers[[:blank:]=]' "pm.max_spare_servers = $G_HW_CPU_CORES" "$FP_PHP_BASE_DIR/fpm/pool.d/www.conf" fi # We create our own PHP mod to add DietPi specific configs. target_php_ini="$FP_PHP_BASE_DIR/mods-available/dietpi.ini" echo -e '; DietPi PHP settings\n; priority=97' > $target_php_ini - # Set UTF-8 - G_CONFIG_INJECT 'default_charset[[:blank:]]*=' 'default_charset="UTF-8"' $target_php_ini - # Session files need to be outside of /tmp and /var/tmp due to PrivateTmp=true, else phpsessionclean.service cannot clean sessions G_EXEC mkdir -p /run/php_sessions G_EXEC chmod 1733 /run/php_sessions echo -e '# Pre-create PHP sessions dir\nd /run/php_sessions 1733' > /etc/tmpfiles.d/dietpi-php_sessions.conf - G_CONFIG_INJECT 'session.save_path[[:blank:]]*=' 'session.save_path="/run/php_sessions"' $target_php_ini + G_CONFIG_INJECT 'session.save_path[[:blank:]=]' 'session.save_path="/run/php_sessions"' $target_php_ini # File uploads: https://github.com/MichaIng/DietPi/issues/546 # - This is especially relevant for cloud software like ownCloud/Nextcloud. @@ -4047,23 +4072,22 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et # - ownCloud/Nextcloud do/did override this limit to 512 MiB, a reasonable limit which can usually still be hold in RAM without issues. # - Low RAM devices (RPi1 256 MiB model) require a swap file for this, however, it is still better to cause disk writes through swap file during large file uploads only, then doing this for each and every uploaded file. # - When larger file uploads are required, it depends on the system total RAM, rootfs disk and available external drives if/where to move tmp file uploads, resize or move swap file. This should be then left to user. - G_CONFIG_INJECT 'upload_tmp_dir=[[:blank:]]*' 'upload_tmp_dir="/tmp"' $target_php_ini - G_CONFIG_INJECT 'upload_max_filesize[[:blank:]]*=' 'upload_max_filesize=512M' $target_php_ini - G_CONFIG_INJECT 'post_max_size[[:blank:]]*=' 'post_max_size=512M' $target_php_ini + G_CONFIG_INJECT 'upload_tmp_dir[[:blank:]=]' 'upload_tmp_dir="/tmp"' $target_php_ini + G_CONFIG_INJECT 'upload_max_filesize[[:blank:]=]' 'upload_max_filesize=512M' $target_php_ini + G_CONFIG_INJECT 'post_max_size[[:blank:]=]' 'post_max_size=512M' $target_php_ini # - Nginx: https://github.com/MichaIng/DietPi/issues/546 => https://github.com/MichaIng/DietPi/blob/dev/.conf/dps_85/nginx.conf # Cache settings - local target_php_cachesize=$(( $RAM_PHYS / 30 )) - (( $target_php_cachesize < 10 )) && target_php_cachesize=10 + local cache_size=$(( $RAM_PHYS / 30 )) + (( $cache_size < 10 )) && cache_size=10 # - OPcache - G_CONFIG_INJECT 'opcache.enable[[:blank:]]*=' 'opcache.enable=1' $target_php_ini - G_CONFIG_INJECT 'opcache.memory_consumption[[:blank:]]*=' "opcache.memory_consumption=$target_php_cachesize" $target_php_ini + G_CONFIG_INJECT 'opcache.memory_consumption[[:blank:]=]' "opcache.memory_consumption=$cache_size" $target_php_ini # Assure that interned_strings_buffer is never larger than half of memory_consumption: https://github.com/MichaIng/DietPi/issues/2293 - (( $($PHP_NAME -i | mawk '/^opcache.interned_strings_buffer/{print $5;exit}') > $target_php_cachesize / 2 )) && G_CONFIG_INJECT 'opcache.interned_strings_buffer[[:blank:]]*=' "opcache.interned_strings_buffer=$(( $target_php_cachesize / 2 ))" $target_php_ini - G_CONFIG_INJECT 'opcache.revalidate_freq[[:blank:]]*=' 'opcache.revalidate_freq=60' $target_php_ini # 1 minute + (( $($PHP_NAME -i | mawk '/^opcache.interned_strings_buffer/{print $5;exit}') > $cache_size / 2 )) && G_CONFIG_INJECT 'opcache.interned_strings_buffer[[:blank:]=]' "opcache.interned_strings_buffer=$(( $cache_size / 2 ))" $target_php_ini + G_CONFIG_INJECT 'opcache.revalidate_freq[[:blank:]=]' 'opcache.revalidate_freq=60' $target_php_ini # 1 minute # - APCu - G_CONFIG_INJECT 'apc.shm_size[[:blank:]]*=' "apc.shm_size=${target_php_cachesize}M" $target_php_ini - G_CONFIG_INJECT 'apc.ttl[[:blank:]]*=' 'apc.ttl=259200' $target_php_ini # 3 days + G_CONFIG_INJECT 'apc.shm_size[[:blank:]=]' "apc.shm_size=${cache_size}M" $target_php_ini + G_CONFIG_INJECT 'apc.ttl[[:blank:]=]' 'apc.ttl=259200' $target_php_ini # 3 days # Enable all available PHP modules local amodules=() @@ -4072,8 +4096,8 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et unset -v amodules # Create PHP info pages within webroot if webserver is installed - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 || ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 || ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )) + then # PHP info page echo '' > /var/www/phpinfo.php # OPcache info page @@ -4082,9 +4106,10 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et G_THREAD_START curl -sSfL 'https://raw.githubusercontent.com/krakjoe/apcu/master/apc.php' -o /var/www/apc.php G_THREAD_WAIT - fi + # Apache: Enable PHP-FPM + command -v a2enconf > /dev/null && { G_EXEC a2enmod proxy_fcgi setenvif; G_EXEC a2enconf "$PHP_NAME-fpm"; } fi software_id=90 # phpMyAdmin @@ -4450,7 +4475,7 @@ _EOF_ else - Download_Install 'https://download.phpbb.com/pub/release/3.3/3.3.4/phpBB-3.3.4.tar.bz2' + Download_Install 'https://download.phpbb.com/pub/release/3.3/3.3.5/phpBB-3.3.5.tar.bz2' G_EXEC mv phpBB3 /var/www/phpbb # Files are shipped with strange UID:GID 1000:1000 while for security reasons it should be root:root. G_EXEC chown -R root:root /var/www/phpbb @@ -4497,7 +4522,7 @@ _EOF_ G_EXEC_NOHALT=1 G_EXEC rm -Rf .cache src bin fi - # Init OB to have config file available, if not yet the case, and edit to allow remote client access + # Init OpenBazaar to have config file available, if not yet the case, and edit to allow remote client access if [[ ! -f '/mnt/dietpi_userdata/openbazaar/config' ]]; then # Data dir @@ -4567,7 +4592,7 @@ _EOF_ Banner_Installing # Get latest download - local file=$(curl -sfL 'https://download.yacy.net/?C=N;O=D' | grep -wom1 'yacy_v[0-9._]*\.tar\.gz' | head -1) + local file=$(curl -sSfL 'https://download.yacy.net/?C=N;O=D' | grep -wo 'yacy_v[0-9._]*\.tar\.gz' | head -1) [[ $file ]] || { file='yacy_v1.924_20210209_10069.tar.gz'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. \"$file\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } Download_Install "https://download.yacy.net/$file" /etc @@ -4611,8 +4636,8 @@ _EOF_ fi # Download latest version - local version=$(curl -sSfL 'https://dist.ipfs.io/go-ipfs/versions' | tail -n 1) - [[ $version ]] || { version='v0.9.0'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } + local version=$(curl -sSfL 'https://dist.ipfs.io/go-ipfs/versions' | tail -1) + [[ $version ]] || { version='v0.11.0-rc2'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } Download_Install "https://dist.ipfs.io/go-ipfs/$version/go-ipfs_${version}_linux-$arch.tar.gz" # Install @@ -4682,6 +4707,7 @@ _EOF_ else Download_Install 'https://download.foldingathome.org/releases/public/release/fahclient/debian-stable-64bit/v7.6/latest.deb' fi + G_EXEC systemctl stop FAHClient # Remove obsolete config + data directories and SysV service + config [[ -d '/var/lib/fahclient' ]] && G_EXEC rm -R /var/lib/fahclient @@ -4759,7 +4785,7 @@ _EOF_ local oc_version_major=$(sed -n '/OC_VersionString/{s/^[^0-9]*//;s/\..*$//p;q}' /var/www/owncloud/version.php) [[ $oc_version_major ]] || oc_version_major=10 local oc_version_minor=$(sed -n '/OC_VersionString/{s/^[^.]*\.//;s/\..*$//p;q}' /var/www/owncloud/version.php) - [[ $oc_version_minor ]] || oc_version_minor=3 + [[ $oc_version_minor ]] || oc_version_minor=8 if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then @@ -4974,9 +5000,6 @@ The install script will now exit. After applying one of the the above, rerun die crontab -u www-data -l 2> /dev/null | grep -q '/var/www/owncloud/.*cron' || ( crontab -u www-data -l 2> /dev/null ; echo "*/15 * * * * php /var/www/owncloud/$occ_command" ) | crontab -u www-data - occ background:cron - # Enable maintenance mode to allow handling by dietpi-services: - grep -q "^[[:blank:]]*'maintenance' => true," $config_php || occ maintenance:mode --on - # On <1 GiB devices assure at least 512 MiB swap space are available to stand 512 MiB file uploads + increased PHP cache and session file usage: https://github.com/MichaIng/DietPi/issues/2293 (( $RAM_PHYS < 924 && $(free -m | mawk '/^Swap:/{print $2;exit}') < 512 )) && /boot/dietpi/func/dietpi-set_swapfile 512 @@ -5005,7 +5028,10 @@ The install script will now exit. After applying one of the the above, rerun die else - Download_Install 'https://download.nextcloud.com/server/releases/latest.tar.bz2' /var/www + # Nextcloud 24 won't support PHP7.3 anymore: https://github.com/nextcloud/server/pull/29286 + local version='latest' + (( $G_DISTRO > 5 )) || version='latest-23' + Download_Install "https://download.nextcloud.com/server/releases/$version.tar.bz2" /var/www fi @@ -5017,8 +5043,10 @@ The install script will now exit. After applying one of the the above, rerun die G_EXEC phpenmod ctype curl dom gd iconv intl json mbstring pdo_mysql posix simplexml xmlreader xmlwriter zip fileinfo opcache apcu redis exif G_DIETPI-NOTIFY 2 'Apply PHP override settings for Nextcloud.' # https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/server_tuning.html#enable-php-opcache - echo -e '; Nextcloud PHP settings\n; priority=98\napc.enable_cli=1\nopcache.enable=1\nopcache.interned_strings_buffer=8 -opcache.max_accelerated_files=10000\nopcache.memory_consumption=128\nopcache.save_comments=1\nopcache.revalidate_freq=5\nmemory_limit=512M' > $FP_PHP_BASE_DIR/mods-available/dietpi-nextcloud.ini + local interned_strings_buffer='' memory_consumption='' + (( $($PHP_NAME -i | mawk '/^opcache.interned_strings_buffer/{print $5;exit}') < 8 )) && interned_strings_buffer='\nopcache.interned_strings_buffer=8' + (( $($PHP_NAME -i | mawk '/^opcache.memory_consumption/{print $5;exit}') < 8 )) && memory_consumption='\nopcache.memory_consumption=128' + echo -e "; Nextcloud PHP settings\n; priority=98\nmemory_limit=512M$memory_consumption$interned_strings_buffer\nopcache.revalidate_freq=5\napc.enable_cli=1" > $FP_PHP_BASE_DIR/mods-available/dietpi-nextcloud.ini G_EXEC phpenmod dietpi-nextcloud if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then @@ -5257,9 +5285,6 @@ The install script will now exit. After applying one of the the above, rerun die ncc db:add-missing-indices ncc db:add-missing-primary-keys - # Enable maintenance mode to allow handling by dietpi-services: - grep -q "^[[:blank:]]*'maintenance' => true," $config_php || ncc maintenance:mode --on - # On <1 GiB devices assure at least 512 MiB swap space are available to stand 512 MiB file uploads + increased PHP cache and session file usage: https://github.com/MichaIng/DietPi/issues/2293 (( $RAM_PHYS < 924 && $(free -m | mawk '/^Swap:/{print $2;exit}') < 512 )) && /boot/dietpi/func/dietpi-set_swapfile 512 @@ -5283,7 +5308,7 @@ The install script will now exit. After applying one of the the above, rerun die G_EXEC mkdir -p /etc/systemd/system/coturn.service.d echo -e "[Service]\nExecStart=\n$(grep -m1 "^[[:blank:]]*ExecStart=" /lib/systemd/system/coturn.service) -l stdout --no-stdout-log --simple-log" > /etc/systemd/system/coturn.service.d/dietpi-logging.conf - # Stretch: sysvinit service + # Stretch: SysV service else # Enable init.d service @@ -5328,7 +5353,7 @@ NB: This port needs to be forwarded by your router and/or opened in your firewal fi done - # Adjust coTURN settings + # Adjust Coturn settings # - If /etc/turnserver.conf is not present, use default or create empty file if [[ ! -f '/etc/turnserver.conf' ]]; then @@ -5336,7 +5361,7 @@ NB: This port needs to be forwarded by your router and/or opened in your firewal [[ -f '/usr/share/doc/coturn/examples/etc/turnserver.conf.gz' ]] && gzip -cd /usr/share/doc/coturn/examples/etc/turnserver.conf.gz > /etc/turnserver.conf || > /etc/turnserver.conf fi - # - Estimate coTURN version to handle outdated settings correctly + # - Estimate Coturn version to handle outdated settings correctly local version=$(dpkg-query -Wf '${Version}' coturn); version=${version:0:7}; version=${version//./} # https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 G_CONFIG_INJECT 'listening-port=' "listening-port=$port" /etc/turnserver.conf @@ -5380,7 +5405,7 @@ NB: This port needs to be forwarded by your router and/or opened in your firewal fi ncc app:enable spreed - # Adjust Nextcloud Talk settings to use coturn + # Adjust Nextcloud Talk settings to use Coturn ncc config:app:set spreed stun_servers --value="[\"$domain:$port\"]" # - Generate random secret to secure TURN server access local secret=$(openssl rand -hex 32) @@ -5461,6 +5486,7 @@ _EOF_ # Build and install myMPD G_EXEC cd myMPD-master G_EXEC ./build.sh releaseinstall + G_EXEC systemctl stop mympd # Cleanup G_EXEC cd /tmp/$G_PROGRAM_NAME @@ -5614,6 +5640,7 @@ _EOF_ G_AGI mopidy gstreamer1.0-alsa mopidy-local G_EXEC_OUTPUT=1 G_EXEC pip3 install --no-cache-dir -U Mopidy-MusicBox-Webclient fi + G_EXEC systemctl stop mopidy # 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\]' @@ -5661,8 +5688,9 @@ _EOF_ Banner_Installing - # CEC + NFS support - local apackages=() # Fixed package dependencies since Bullseye + local apackages=() + + # Stretch/Buster: CEC + NFS support if (( $G_DISTRO < 5 )) then apackages=('libcec4' 'libnfs8') @@ -5672,44 +5700,87 @@ _EOF_ apackages=('libcec4' 'libnfs12') fi + # RPi + if (( $G_HW_MODEL < 10 )) + then + # Purge DietPi Bullseye build with higher epoch version + [[ $G_DISTRO == 6 && $(dpkg-query -Wf '${Version}' kodi 2> /dev/null) == '3:19.1-dietpi'[1-3] ]] && G_EXEC_OUTPUT=1 G_EXEC dpkg -P kodi + + # Bullseye, RPi 4 and 64-bit userland: Use KMS driver: https://www.raspberrypi.org/forums/viewtopic.php?t=251645 + if [[ $G_DISTRO -ge 6 || $G_HW_MODEL == 4 || $(dpkg --print-architecture) == 'arm64' ]] + then + # Enhance 4k support on RPi 4 + local cma= + (( $G_HW_MODEL == 4 )) && cma=512 + /boot/dietpi/func/dietpi-set_hardware rpi-opengl vc4-kms-v3d $cma + + # Else legacy framebuffer driver + else + /boot/dietpi/func/dietpi-set_hardware rpi-opengl disable + fi + + # 64-bit Stretch/Buster: Debian repo: https://github.com/MichaIng/DietPi/issues/4194 + if [[ $G_DISTRO -le 5 && $(dpkg --print-architecture) == 'arm64' ]] + then + echo -e 'Package: kodi*\nPin: origin archive.raspberrypi.org\nPin-Priority: -1' > /etc/apt/preferences.d/dietpi-kodi + apackages+=('kodi-repository-kodi') + + # Else: RPi repo + else + [[ -f '/etc/apt/preferences.d/dietpi-kodi' ]] && G_EXEC rm /etc/apt/preferences.d/dietpi-kodi + + # 32-bit Buster: Apply missing dir workaround: https://github.com/RPi-Distro/repo/issues/153 + [[ $G_DISTRO == 5 && $(dpkg --print-architecture) == 'armhf' && ! -d '/etc/polkit-1/localauthority/50-local.d' ]] && G_EXEC mkdir -p /etc/polkit-1/localauthority/50-local.d + + # Stretch/Buster: fbset required to recover desktop with custom resolution and fix startup warning: https://dietpi.com/phpbb/viewtopic.php?p=17550#p17550 + # Bullseye: Enable hardware codecs + (( $G_DISTRO < 6 )) && apackages+=('fbset') || /boot/dietpi/func/dietpi-set_hardware rpi-codec 1 + fi + + apackages+=('kodi') + # Odroids - if [[ $G_HW_MODEL == 1[0-9] ]]; then + elif [[ $G_HW_MODEL == 1[0-9] ]] + then + local package_list=$(apt-cache dumpavail | mawk '/^Package: /{print $2}') # Odroid C1/C2/N2/C4 - [[ $G_HW_MODEL == 1[0256] ]] && apt-cache dumpavail | grep -q '^Package: aml-libs-odroid$' && apackages+=('aml-libs-odroid') + [[ $G_HW_MODEL == 1[0256] ]] && grep -q '^aml-libs-odroid$' <<< "$package_list" && apackages+=('aml-libs-odroid') # Odroid C1 if (( $G_HW_MODEL == 10 )) then - apt-cache dumpavail | grep -q '^Package: mali400-odroid$' && apackages+=('mali400-odroid') || apackages+=('libgles2') + grep -q '^mali400-odroid$' <<< "$package_list" && apackages+=('mali400-odroid') || apackages+=('libgles2') # Odroid XU4 elif (( $G_HW_MODEL == 11 )) then - apt-cache dumpavail | grep -q '^Package: malit628-odroid$' && apackages+=('malit628-odroid') || apackages+=('libgles2') - apt-cache dumpavail | grep -q '^Package: firmware-samsung$' && apackages+=('firmware-samsung') + grep -q '^malit628-odroid$' <<< "$package_list" && apackages+=('malit628-odroid') || apackages+=('libgles2') + grep -q '^firmware-samsung$' <<< "$package_list" && apackages+=('firmware-samsung') # Odroid C2 elif (( $G_HW_MODEL == 12 )) then - apt-cache dumpavail | grep -q '^Package: mali450-odroid$' && apackages+=('mali450-odroid') || apackages+=('libgles2') + grep -q '^mali450-odroid$' <<< "$package_list" && apackages+=('mali450-odroid') || apackages+=('libgles2') # Odroid N2 elif (( $G_HW_MODEL == 15 )) then - apt-cache dumpavail | grep -q '^Package: malig52-fbdev-opencl-odroid$' && apackages+=('malig52-fbdev-opencl-odroid') || apackages+=('libgles2') + grep -q '^malig52-fbdev-opencl-odroid$' <<< "$package_list" && apackages+=('malig52-fbdev-opencl-odroid') || apackages+=('libgles2') # Odroid C4 elif (( $G_HW_MODEL == 16 )) then - apt-cache dumpavail | grep -q '^Package: malig31-fbdev-opencl-odroid$' && apackages+=('malig31-fbdev-opencl-odroid') || apackages+=('libgles2') + grep -q '^malig31-fbdev-opencl-odroid$' <<< "$package_list" && apackages+=('malig31-fbdev-opencl-odroid') || apackages+=('libgles2') fi # Odroid N2/C4 if [[ $G_HW_MODEL == 1[56] ]] then - apt-cache dumpavail | grep -q '^Package: kodi-aml-fbdev-odroid$' && apackages+=('kodi-aml-fbdev-odroid') || apackages=('kodi') - echo 'media_clock + if grep -q '^kodi-aml-fbdev-odroid$' <<< "$package_list" + then + apackages+=('kodi-aml-fbdev-odroid') + echo 'media_clock firmware decoder_common stream_input @@ -5727,68 +5798,38 @@ amvdec_mmpeg4 amvdec_real amvdec_vc1 amvdec_vp9' > /etc/modules-load.d/dietpi-n2-kodi.conf - (( $G_HW_MODEL == 16 )) && G_EXEC mv /etc/modules-load.d/dietpi-{n2,c4}-kodi.conf + (( $G_HW_MODEL == 16 )) && G_EXEC mv /etc/modules-load.d/dietpi-{n2,c4}-kodi.conf + else + apackages+=('kodi' 'kodi-repository-kodi') + fi # Other Odroids else # libcurl3-gnutls missing as dependency for kodi-odroid on arm64 Stretch (Odroid C2): https://github.com/MichaIng/DietPi/issues/446 (( $G_HW_ARCH == 3 && $G_DISTRO < 5 )) && apackages+=('libcurl3-gnutls') - apt-cache dumpavail | grep -q '^Package: kodi-odroid$' && apackages+=('kodi-odroid') || apackages=('kodi') + grep -q '^kodi-odroid$' <<< "$package_list" && apackages+=('kodi-odroid') || apackages+=('kodi' 'kodi-repository-kodi') fi - # RPi Raspbian Bullseye - elif [[ $G_HW_MODEL -le 9 && $G_DISTRO == 6 && $(dpkg --print-architecture) == 'armhf' ]] - then - /boot/dietpi/func/dietpi-set_hardware rpi-opengl vc4-kms-v3d - Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/kodi_$G_HW_ARCH_NAME.deb" + unset -v package_list # Everything else else - apackages+=('kodi') - - # RPi - if (( $G_HW_MODEL < 10 )) - then - # fbset required to recover desktop with custom resolution and fix startup warning: https://dietpi.com/phpbb/viewtopic.php?p=17550#p17550 - apackages+=('fbset') - - # RPi4: fake KMS driver required: https://www.raspberrypi.org/forums/viewtopic.php?t=251645 - if (( $G_HW_MODEL == 4 )) - then - /boot/dietpi/func/dietpi-set_hardware rpi-opengl vc4-fkms-v3d - - # Else legacy (non-GL) driver required - else - /boot/dietpi/func/dietpi-set_hardware rpi-opengl disable - fi - - # 32-bit: Apply missing dir workaround: https://github.com/MichaIng/DietPi/issues/3031#issuecomment-540477241 - if [[ $(dpkg --print-architecture) == 'armhf' ]] - then - [[ -d '/etc/polkit-1/localauthority/50-local.d' ]] || G_EXEC mkdir -p /etc/polkit-1/localauthority/50-local.d - - # 64-bit: Assure that APT does not try to install Kodi from RPi repo: https://github.com/MichaIng/DietPi/issues/4194 - else - echo -e 'Package: kodi*\nPin: origin archive.raspberrypi.org\nPin-Priority: -1' > /etc/apt/preferences.d/dietpi-kodi - fi - fi + (( $G_HW_ARCH == 10 )) || apackages+=('libgles2') + apackages+=('kodi' 'kodi-repository-kodi') fi G_AGI "${apackages[@]}" + unset -v apackages # Desktop entry - [[ -d '/var/lib/dietpi/dietpi-software/installed/desktop/icons' ]] && G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/icons/kodi-icon.png" -o /var/lib/dietpi/dietpi-software/installed/desktop/icons/kodi-icon.png - [[ -d '/usr/share/applications' ]] && G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/apps/kodi.desktop" -o /usr/share/applications/kodi.desktop + [[ -d '/var/lib/dietpi/dietpi-software/installed/desktop/icons' ]] || G_EXEC mkdir -p /var/lib/dietpi/dietpi-software/installed/desktop/icons + G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/icons/kodi-icon.png" -o /var/lib/dietpi/dietpi-software/installed/desktop/icons/kodi-icon.png + [[ -d '/usr/share/applications' ]] || G_EXEC mkdir -p /usr/share/applications + G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/apps/kodi.desktop" -o /usr/share/applications/kodi.desktop - # Copy udev rules, probably not needed for root, but we'll do it anyway + # Grant R/W access to all input and console devices for members of the "input" respectively "tty" group dps_index=$software_id Download_Install '99-dietpi-kodi.rules' /etc/udev/rules.d/99-dietpi-kodi.rules - # Run Kodi as root - [[ -f '/etc/default/kodi' ]] && G_CONFIG_INJECT 'USER=' 'USER=root' /etc/default/kodi - - # Remove Kodi user (Whilst waving) - getent passwd kodi > /dev/null && G_EXEC userdel kodi - G_THREAD_WAIT # Desktop shortcut @@ -5802,15 +5843,16 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-n2-kodi.conf Banner_Installing G_AGI minidlna - - # User: Make "dietpi" the primary group to enable cross-access to media files - Create_User -g dietpi -G minidlna -d /var/lib/minidlna minidlna + G_EXEC systemctl stop minidlna # Remove obsolete service files Remove_SysV minidlna 1 [[ -f '/lib/systemd/system/minidlna.service' ]] && G_EXEC rm /lib/systemd/system/minidlna.service [[ -d '/var/log/minidlna' ]] && G_EXEC rm -R /var/log/minidlna + # User: Make "dietpi" the primary group to enable cross-access to media files + Create_User -g dietpi -G minidlna -d /var/lib/minidlna minidlna + # Service cat << _EOF_ > /etc/systemd/system/minidlna.service [Unit] @@ -5948,19 +5990,19 @@ _EOF_ # ARMv7 local fallback_url="https://hndl.urbackup.org/Server/$latest/urbackup-server_${latest}_armhf.deb" - local file=$(curl -sfL "$url" | grep -m1 'urbackup-server_.*_armhf\.deb' | cut -d \" -f 8) + local file=$(curl -sSfL "$url" | mawk -F\" '/"urbackup-server_.*_armhf\.deb"/{print $8}') # ARMv8 if (( $G_HW_ARCH == 3 )); then fallback_url="https://hndl.urbackup.org/Server/$latest/urbackup-server_${latest}_arm64.deb" - file=$(curl -sfL "$url" | grep -m1 'urbackup-server-.*_arm64\.deb' | cut -d \" -f 8) + file=$(curl -sSfL "$url" | mawk -F\" '/"urbackup-server_.*_arm64\.deb"/{print $8}') # x86_64 elif (( $G_HW_ARCH == 10 )); then fallback_url="https://hndl.urbackup.org/Server/$latest/urbackup-server_${latest}_amd64.deb" - file=$(curl -sfL "$url" | grep -m1 'urbackup-server_.*_amd64\.deb' | cut -d \" -f 8) + file=$(curl -sSfL "$url" | mawk -F\" '/"urbackup-server_.*_amd64\.deb"/{print $8}') fi @@ -5969,9 +6011,10 @@ _EOF_ debconf-set-selections <<< 'urbackup-server urbackup/backuppath string /mnt/dietpi_userdata/urbackup' Download_Install "$url" + G_EXEC systemctl stop urbackupsrv # As we have /tmp mounted to RAM, change tmp location - [[ -d '/mnt/dietpi_userdata/urbackup/tmp' ]] || mkdir -p /mnt/dietpi_userdata/urbackup/tmp + [[ -d '/mnt/dietpi_userdata/urbackup/tmp' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/urbackup/tmp G_EXEC chown -R urbackup:urbackup /mnt/dietpi_userdata/urbackup G_CONFIG_INJECT 'DAEMON_TMPDIR=' "DAEMON_TMPDIR='/mnt/dietpi_userdata/urbackup/tmp'" /etc/default/urbackupsrv @@ -6041,8 +6084,14 @@ _EOF_ G_EXEC ln -sf /run/shm/mjpeg/status_mjpeg.txt /var/www/rpicam/status_mjpeg.txt # Setup Raspimjpeg binary - # - Use Stretch binary on Stretch - (( $G_DISTRO < 5 )) && G_EXEC mv bin/raspimjpeg{-stretch,} + if (( $G_DISTRO < 5 )) + then + G_EXEC mv bin/raspimjpeg{-stretch,} + + elif (( $G_DISTRO < 6 )) + then + G_EXEC mv bin/raspimjpeg{-buster,} + fi G_EXEC cp {,/usr/local/}bin/raspimjpeg G_EXEC chmod +x /usr/local/bin/raspimjpeg @@ -6101,6 +6150,7 @@ _EOF_ # Packages G_AGI deluged deluge-web deluge-console + G_EXEC systemctl stop deluged # Remove SysV service leftovers, installed by Debian APT package Remove_SysV deluged 1 @@ -6191,6 +6241,7 @@ _EOF_ # APT package G_AGI webmin + G_EXEC systemctl stop webmin # Service Remove_SysV webmin @@ -6288,6 +6339,7 @@ _EOF_ Banner_Installing G_AGI darkice icecast2 + G_EXEC systemctl stop darkice icecast2 # IceCast: Set passwords, if not yet done (default found) sed -i "/hackme/c\ $GLOBAL_PW" /etc/icecast2/icecast.xml @@ -6359,6 +6411,7 @@ _EOF_ Banner_Installing G_AGI tor + G_EXEC systemctl stop tor local nickname= G_WHIP_BUTTON_CANCEL_TEXT='Skip' @@ -6568,13 +6621,11 @@ _EOF_ [[ -f '/etc/unbound/unbound.conf.d/dietpi.conf' ]] || dps_index=$software_id Download_Install 'unbound.conf' /etc/unbound/unbound.conf.d/dietpi.conf # Toggle IPv6 preference based on dietpi.txt settings - if grep -q 'CONFIG_ENABLE_IPV6=0' /boot/dietpi.txt + if grep -q '^[[:blank:]]*CONFIG_ENABLE_IPV6=0' /boot/dietpi.txt then G_CONFIG_INJECT 'do-ip6:[[:blank:]]' ' do-ip6: no' /etc/unbound/unbound.conf.d/dietpi.conf - - elif grep -q 'CONFIG_PREFER_IPV4=0' /boot/dietpi.txt - then - G_CONFIG_INJECT 'prefer-ip6:[[:blank:]]' ' prefer-ip6: yes' /etc/unbound/unbound.conf.d/dietpi.conf + else + G_CONFIG_INJECT 'do-ip6:[[:blank:]]' ' do-ip6: yes' /etc/unbound/unbound.conf.d/dietpi.conf fi # Stretch: Remove incompatible setting @@ -6872,8 +6923,7 @@ _EOF_ Banner_Installing - local fallback_url='https://github.com/airsonic/airsonic/releases/download/v10.6.2/airsonic.war' - Download_Install "$(curl -sSfL 'https://api.github.com/repos/airsonic/airsonic/releases/latest' | mawk -F\" '/"browser_download_url": .*\/airsonic\.war"/{print $4}')" /mnt/dietpi_userdata/airsonic/airsonic.war + Download_Install 'https://github.com/airsonic/airsonic/releases/download/v10.6.2/airsonic.war' /mnt/dietpi_userdata/airsonic/airsonic.war # User Create_User -g dietpi -G audio -d /mnt/dietpi_userdata/airsonic airsonic @@ -6899,8 +6949,8 @@ ExecStart=$(command -v java) -Xmx${memory_limit}m -Dairsonic.home=/mnt/dietpi_us WantedBy=multi-user.target _EOF_ # Enable FFmpeg transcode - G_EXEC mkdir -p /mnt/dietpi_userdata/airsonic/transcode - command -v ffmpeg > /dev/null && G_EXEC ln -sf "$(command -v ffmpeg)" /mnt/dietpi_userdata/airsonic/transcode + [[ -d '/mnt/dietpi_userdata/airsonic/transcode' ]] || G_EXEC mkdir /mnt/dietpi_userdata/airsonic/transcode + [[ -f '/mnt/dietpi_userdata/airsonic/transcode/ffmpeg' ]] || G_EXEC ln -sf "$(command -v ffmpeg)" /mnt/dietpi_userdata/airsonic/transcode # Permissions G_EXEC chmod +x /mnt/dietpi_userdata/airsonic/airsonic.war @@ -6990,8 +7040,9 @@ _EOF_ then G_AGI pijuice-base else - Download_Install 'http://archive.raspberrypi.org/debian/pool/main/p/pijuice-base/pijuice-base_1.7_all.deb' + Download_Install 'https://archive.raspberrypi.org/debian/pool/main/p/pijuice-base/pijuice-base_1.7_all.deb' fi + G_EXEC systemctl stop pijuice G_EXEC mkdir -p /var/lib/dietpi/dietpi-software/installed/pijuice echo -e '#!/bin/dash\npoweroff' > /var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func1.sh @@ -7082,9 +7133,8 @@ _EOF_ fi # Download - local fallback_url="https://github.com/fatedier/frp/releases/download/v0.37.1/frp_0.37.1_linux_$arch.tar.gz" - local pattern="\"browser_download_url\": .*\/frp_[0-9.]*_linux_$arch\.tar\.gz\"" - Download_Install "$(curl -sSfL 'https://api.github.com/repos/fatedier/frp/releases/latest' | mawk -v pat="$pattern" -F\" '$0 ~ pat {print $4}')" + local fallback_url="https://github.com/fatedier/frp/releases/download/v0.38.0/frp_0.38.0_linux_$arch.tar.gz" + Download_Install "$(curl -sSfL 'https://api.github.com/repos/fatedier/frp/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/frp_[0-9.]*_linux_$arch\.tar\.gz\"/{print \$4}")" G_EXEC cd frp_* @@ -7221,7 +7271,7 @@ _EOF_ Banner_Installing # Pre-configure user and data directory to allow a local service user install # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/node-red + [[ -d '/mnt/dietpi_userdata/node-red' ]] || G_EXEC mkdir /mnt/dietpi_userdata/node-red # User Create_User -G gpio,i2c -d /mnt/dietpi_userdata/node-red nodered @@ -7267,7 +7317,7 @@ _EOF_ # APT key local url='https://repo.mosquitto.org/debian/mosquitto-repo.gpg.key' G_CHECK_URL "$url" - G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-mosquitto.gpg --yes" + G_EXEC eval "curl -sSfL '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-mosquitto.gpg --yes" # APT list G_EXEC eval "echo 'deb https://repo.mosquitto.org/debian/ ${G_DISTRO_NAME/bookworm/bullseye} main' > /etc/apt/sources.list.d/dietpi-mosquitto.list" @@ -7276,6 +7326,7 @@ _EOF_ fi G_AGI mosquitto + G_EXEC systemctl stop mosquitto Remove_SysV mosquitto @@ -7432,8 +7483,9 @@ _EOF_ # Install no_check_url=1 Download_Install "$url/$distro/$package" + G_EXEC systemctl stop networkaudiod - unset url arch distro package + unset -v url arch distro package fi @@ -7497,7 +7549,7 @@ _EOF_ Banner_Installing - local version='2.4.3' # https://www.haproxy.org/download/ + local version='2.5.0' # https://www.haproxy.org/download/ DEPS_LIST='libpcre3-dev libssl-dev zlib1g-dev libsystemd-dev' Download_Install "https://www.haproxy.org/download/${version%.*}/src/haproxy-$version.tar.gz" @@ -7852,15 +7904,13 @@ $GLOBAL_PW" > /root/.vnc/passwd fi # RealVNC: Set virtual + shared desktop passwords, repeat virtual password command two times: https://github.com/MichaIng/DietPi/pull/4679#issuecomment-908196511 - if [[ ${aSOFTWARE_INSTALL_STATE[120]} == 1 && ! -f '/root/.vnc/config.d/Xvnc' ]] + if [[ ${aSOFTWARE_INSTALL_STATE[120]} == 1 && ! -s '/root/.vnc/config.d/Xvnc' ]] then vncpasswd -virtual <<< "$GLOBAL_PW -$GLOBAL_PW" - vncpasswd -virtual <<< "$GLOBAL_PW $GLOBAL_PW" vncpasswd -service <<< "$GLOBAL_PW $GLOBAL_PW" - [[ -s '/root/.vnc/config.d/Xvnc' ]] || G_EXEC cp -a /root/.vnc/config.d/{vncserver-x11-virtual,Xvnc} + [[ -f '/root/.vnc/config.d/.Xvnc-v5-marker' ]] || > /root/.vnc/config.d/.Xvnc-v5-marker fi fi @@ -7916,7 +7966,7 @@ _EOF_ # APT key local url='https://repos.influxdata.com/influxdb.key' G_CHECK_URL "$url" - G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-influxdb.gpg --yes" + G_EXEC eval "curl -sSfL '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-influxdb.gpg --yes" # APT list G_EXEC eval "echo 'deb https://repos.influxdata.com/debian/ ${G_DISTRO_NAME/bookworm/bullseye} stable' > /etc/apt/sources.list.d/influxdb.list" @@ -7924,6 +7974,7 @@ _EOF_ # APT package G_AGI influxdb + G_EXEC systemctl stop influxdb # Move DB/datadir to userdata location [[ -d '/mnt/dietpi_userdata/influxdb' ]] || G_EXEC mv /var/lib/influxdb /mnt/dietpi_userdata/ @@ -7951,7 +8002,7 @@ _EOF_ # APT key local url='https://packages.grafana.com/gpg.key' G_CHECK_URL "$url" - G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-grafana.gpg --yes" + G_EXEC eval "curl -sSfL '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-grafana.gpg --yes" # APT list G_EXEC eval "echo 'deb https://packages.grafana.com/oss/deb/ stable main' > /etc/apt/sources.list.d/grafana.list" @@ -7961,6 +8012,7 @@ _EOF_ G_AGI grafana fi + G_EXEC systemctl stop grafana-server Remove_SysV grafana-server @@ -7983,7 +8035,7 @@ _EOF_ G_EXEC ln -s /mnt/dietpi_userdata/grafana /var/lib/grafana # Config: Apply our defaults only if nothing was set before - # - Set password, wrap into trippled double quotes in case of ; or # being contained, according to docs: http://docs.grafana.org/installation/configuration/#password + # - Set password, wrap into tripled double quotes in case of ; or # being contained, according to docs: http://docs.grafana.org/installation/configuration/#password GCI_PRESERVE=1 GCI_PASSWORD=1 G_CONFIG_INJECT 'admin_password[[:blank:]]*=' "admin_password = \"\"\"$GLOBAL_PW\"\"\"" /etc/grafana/grafana.ini # - Set port to 3001 (away from default 3000) to avoid conflict with Gogs and Gitea GCI_PRESERVE=1 G_CONFIG_INJECT 'http_port[[:blank:]]*=' 'http_port = 3001' /etc/grafana/grafana.ini @@ -8065,7 +8117,7 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - local fallback_url='https://github.com/gotson/komga/releases/download/v0.120.1/komga-0.120.1.jar' + local fallback_url='https://github.com/gotson/komga/releases/download/v0.134.1/komga-0.134.1.jar' Download_Install "$(curl -sSfL 'https://api.github.com/repos/gotson/komga/releases/latest' | mawk -F\" '/"browser_download_url": .*\/komga-[^"\/]*\.jar"/{print $4}')" /mnt/dietpi_userdata/komga/komga.jar # User @@ -8164,7 +8216,7 @@ _EOF_ # Bullseye+ if (( $G_DISTRO > 5 )) then - local fallback_url='https://github.com/ampache/ampache/releases/download/4.4.3/ampache-4.4.3_all.zip' + local fallback_url='https://github.com/ampache/ampache/releases/download/5.1.1/ampache-5.1.1_all.zip' Download_Install "$(curl -sSfL 'https://api.github.com/repos/ampache/ampache/releases/latest' | mawk -F\" '/"browser_download_url": ".*\/ampache-[0-9\.]*_all.zip"/{print $4}')" ampache # Ampache v5 requires PHP7.4, hence pull latest Ampache v4 on Buster and below: https://github.com/ampache/ampache/wiki/Ampache-Next-Changes @@ -8678,6 +8730,7 @@ If no WireGuard (auto)start is included, but you require it, please do the follo lsusb | grep -qi 'RTL8188C' && apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* hostapd-realtek(,|$)' && packages[0]='hostapd-realtek' G_AGI "${packages[@]}" + G_EXEC systemctl stop hostapd isc-dhcp-server # Enable WiFi modules /boot/dietpi/func/dietpi-set_hardware wifimodules enable @@ -8775,6 +8828,7 @@ _EOF_ Banner_Installing G_AGI tor + G_EXEC systemctl stop tor Remove_SysV tor 1 @@ -8855,7 +8909,7 @@ _EOF_ else Download_Install 'https://download.pydio.com/pub/core/ci/pydio-latest.tar.gz' /var/www - mv /var/www/pydio-latest /var/www/pydio + G_EXEC mv /var/www/pydio-latest /var/www/pydio fi @@ -8863,13 +8917,13 @@ _EOF_ G_EXEC phpenmod apcu gd intl pdo_mysql dom mbstring xml # Webserver config - # - Apache2 + # - Apache if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - # Enable Apache2 rewrite engine + # Enable Apache rewrite engine a2enmod rewrite - # Move Pydio Apache2 config in place + # Move Pydio Apache config in place dps_index=$software_id Download_Install 'apache.pydio.conf' /etc/apache2/sites-available/dietpi-pydio.conf a2ensite dietpi-pydio @@ -8902,19 +8956,19 @@ _EOF_ if [[ -d $target_data_dir ]]; then G_DIETPI-NOTIFY 2 "Existing $target_data_dir found, will migrate..." - [[ -e '/var/www/pydio/data' ]] && rm -R /var/www/pydio/data + [[ -e '/var/www/pydio/data' ]] && G_EXEC rm -R /var/www/pydio/data else # - Move data structure [[ -e $target_data_dir ]] && rm -R $target_data_dir - mv /var/www/pydio/data $target_data_dir + G_EXEC mv /var/www/pydio/data $target_data_dir fi # Create symlink - ln -sf $target_data_dir /var/www/pydio/data - chown -R www-data:www-data $target_data_dir + G_EXEC ln -sf $target_data_dir /var/www/pydio/data + G_EXEC chown -R www-data:www-data $target_data_dir fi @@ -8923,6 +8977,7 @@ _EOF_ Banner_Installing Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/squeezelite_$G_HW_ARCH_NAME.deb" + G_EXEC systemctl stop squeezelite fi @@ -8932,6 +8987,7 @@ _EOF_ Banner_Installing Download_Install 'https://raw.githubusercontent.com/XavierBerger/RPi-Monitor-deb/develop/packages/rpimonitor_2.13-beta6_all.deb' + G_EXEC systemctl stop rpimonitor # Update APT package status G_EXEC /usr/share/rpimonitor/scripts/updatePackagesStatus.pl @@ -8997,7 +9053,7 @@ _EOF_ Download_Install "https://dietpi.com/downloads/binaries/stretch/netdata_$G_HW_ARCH_NAME.7z" G_AGI ./netdata{-core,-plugins-bash,-web,}_*.deb G_AGF - rm netdata* + G_EXEC rm netdata* fi @@ -9006,6 +9062,7 @@ _EOF_ G_AGI netdata fi + G_EXEC systemctl stop netdata # Only required for our self-compiled package, leave defaults for Debian APT package otherwise if (( $G_HW_ARCH == 1 && $G_DISTRO < 5 )); then @@ -9014,20 +9071,20 @@ _EOF_ dps_index=$software_id Download_Install 'netdata.service' /etc/systemd/system/netdata.service # Dir (failsafe) - mkdir -p /var/lib/netdata + G_EXEC mkdir -p /var/lib/netdata # User Create_User -d /var/lib/netdata netdata # Permissions: https://docs.netdata.cloud/docs/netdata-security/#netdata-directories # - R/O - chown -R root:netdata /etc/netdata /usr/lib/netdata /usr/libexec/netdata /usr/share/netdata - chmod -R 0750 /etc/netdata /usr/lib/netdata /usr/libexec/netdata /usr/share/netdata + G_EXEC chown -R root:netdata /etc/netdata /usr/lib/netdata /usr/libexec/netdata /usr/share/netdata + G_EXEC chmod -R 0750 /etc/netdata /usr/lib/netdata /usr/libexec/netdata /usr/share/netdata # - apps.plugin requires root privileges to read disk I/O - chmod 4750 /usr/libexec/netdata/plugins.d/apps.plugin + G_EXEC chmod 4750 /usr/libexec/netdata/plugins.d/apps.plugin # - R/W (web access: https://github.com/MichaIng/DietPi/issues/2336#issuecomment-450196178) - chown -R netdata:netdata /var/cache/netdata /var/lib/netdata /var/log/netdata /usr/share/netdata/web - chmod -R 0770 /var/cache/netdata /var/lib/netdata /var/log/netdata + G_EXEC chown -R netdata:netdata /var/cache/netdata /var/lib/netdata /var/log/netdata /usr/share/netdata/web + G_EXEC chmod -R 0770 /var/cache/netdata /var/lib/netdata /var/log/netdata fi @@ -9106,6 +9163,7 @@ location = /.well-known/caldav { return 301 /baikal/html/dav.php; }' > /etc/ngi Banner_Installing G_AGI mumble-server + G_EXEC systemctl stop mumble-server # Cap total connections local max_users=$(( $G_HW_CPU_CORES * 8 )) @@ -9142,8 +9200,9 @@ location = /.well-known/caldav { return 301 /baikal/html/dav.php; }' > /etc/ngi fi - local fallback_url="https://github.com/MediaBrowser/Emby.Releases/releases/download/4.6.4.0/emby-server-deb_4.6.4.0_$arch.deb" + local fallback_url="https://github.com/MediaBrowser/Emby.Releases/releases/download/4.6.7.0/emby-server-deb_4.6.7.0_$arch.deb" Download_Install "$(curl -sSfL 'https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/emby-server-deb_[^\"\/]*_$arch\.deb\"/{print \$4}")" + G_EXEC systemctl stop emby-server # User: The DEB package install overrides this, hence the method needs to be changed when using an APT repository! Create_User -g dietpi -G emby,video,render -d /var/lib/emby emby @@ -9160,7 +9219,7 @@ location = /.well-known/caldav { return 301 /baikal/html/dav.php; }' > /etc/ngi # APT key local url='https://downloads.plex.tv/plex-keys/PlexSign.key' G_CHECK_URL "$url" - G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-plexmediaserver.gpg --yes" + G_EXEC eval "curl -sSfL '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-plexmediaserver.gpg --yes" # APT list G_EXEC eval "echo 'deb https://downloads.plex.tv/repo/deb/ public main' > /etc/apt/sources.list.d/plexmediaserver.list" @@ -9168,6 +9227,7 @@ location = /.well-known/caldav { return 301 /baikal/html/dav.php; }' > /etc/ngi # APT package G_AGI plexmediaserver + G_EXEC systemctl stop plexmediaserver # User: Run service as "dietpi" group: https://github.com/MichaIng/DietPi/issues/350#issuecomment-423763518 Create_User -g dietpi -G plex,video,render -d /var/lib/plexmediaserver plex @@ -9335,12 +9395,11 @@ _EOF_ Download_Install "$url" # Remove old install dir, but preserve existing configs - if [[ -d '/etc/gogs' ]]; then - + if [[ -d '/etc/gogs' ]] + then [[ -d '/etc/gogs/custom' ]] && G_EXEC mv /etc/gogs/custom gogs G_EXEC mv /etc/gogs/.??* gogs # dot files = SSH and Git user configs G_EXEC rm -R /etc/gogs - fi G_EXEC mv gogs /etc/gogs @@ -9353,13 +9412,7 @@ _EOF_ G_EXEC chown -R gogs:gogs /etc/gogs /mnt/dietpi_userdata/gogs-repo /var/log/gogs # Database - if [[ ! -d '/var/lib/mysql/gogs' ]]; then - - G_EXEC systemctl restart mariadb - mysql -f < /etc/gogs/scripts/mysql.sql # -f until: https://github.com/gogs/gogs/pull/6424 - mysql -e "grant all privileges on gogs.* to gogs@localhost identified by '$GLOBAL_PW'" - - fi + /boot/dietpi/func/create_mysql_db gogs gogs "$GLOBAL_PW" # Service: https://github.com/gogs/gogs/blob/main/scripts/systemd/gogs.service cat << '_EOF_' > /etc/systemd/system/gogs.service @@ -9536,7 +9589,7 @@ _EOF_ fi # ruTorrent: Enable HTTP authentication and RPC - # - Apache2 + # - Apache if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then # Enable SCGI module @@ -9560,7 +9613,7 @@ _EOF_ AuthUserFile "/etc/.rutorrent-htaccess" Require valid-user -ProxyPass "/RPC2" "scgi:///mnt/dietpi_userdata/downloads/.session/rpc.socket" +ProxyPass "/RPC2" "unix:/mnt/dietpi_userdata/downloads/.session/rpc.socket|scgi://127.0.0.1" _EOF_ G_EXEC a2ensite dietpi-rutorrent @@ -9573,10 +9626,7 @@ _EOF_ grep -q '^#RUTORRENT_DIETPI' /etc/lighttpd/lighttpd.conf && G_EXEC sed -i '/#RUTORRENT_DIETPI/,/#RUTORRENT_DIETPI/d' /etc/lighttpd/lighttpd.conf cat << '_EOF_' > /etc/lighttpd/conf-available/98-dietpi-rtorrent.conf -server.modules += ( "mod_fastcgi" ) -server.modules += ( "mod_scgi" ) -server.modules += ( "mod_auth" ) -auth.debug = 0 +server.modules += ( "mod_auth", "mod_authn_file", "mod_scgi" ) auth.backend = "htdigest" auth.backend.htdigest.userfile = "/etc/.rutorrent-htaccess" auth.require = ( "/rutorrent" => @@ -9672,13 +9722,13 @@ _EOF_ # - Deprecated commands: # https://github.com/rakshasa/rtorrent/wiki/rTorrent-0.9-Comprehensive-Command-list-(WIP) # https://github.com/rakshasa/rtorrent/blob/master/doc/scripts/update_commands_0.9.sed - G_EXEC mkdir -p /mnt/dietpi_userdata/rtorrent + [[ -d '/mnt/dietpi_userdata/rtorrent' ]] || G_EXEC mkdir /mnt/dietpi_userdata/rtorrent if [[ -f '/mnt/dietpi_userdata/rtorrent/.rtorrent.rc' ]] then # Reinstall: Assure that rpi.socket is used, else ruTorrent connection would fail - G_EXEC sed -i '/^[[:blank:]]*network.scgi.open_port/d' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc - G_CONFIG_INJECT 'network.scgi.open_local' 'network.scgi.open_local = /mnt/dietpi_userdata/downloads/.session/rpc.socket' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc - G_CONFIG_INJECT 'execute.nothrow = chmod,666,/mnt/dietpi_userdata/downloads/.session/rpc.socket' 'execute.nothrow = chmod,666,/mnt/dietpi_userdata/downloads/.session/rpc.socket' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc + G_EXEC sed -i '/^[[:blank:]]*network.scgi.open_port[[:blank:]=]/d' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc + G_CONFIG_INJECT 'network.scgi.open_local[[:blank:]=]' 'network.scgi.open_local = /mnt/dietpi_userdata/downloads/.session/rpc.socket' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc + G_CONFIG_INJECT 'execute.nothrow[[:blank:]]*=[[:blank:]]*chmod,666,/mnt/dietpi_userdata/downloads/.session/rpc.socket' 'execute.nothrow = chmod,666,/mnt/dietpi_userdata/downloads/.session/rpc.socket' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc 'network.scgi.open_local[[:blank:]=]' else cat << _EOF_ > /mnt/dietpi_userdata/rtorrent/.rtorrent.rc ### Miscellaneous settings @@ -9698,9 +9748,9 @@ pieces.hash.on_completion.set = no ### Connection settings # Incoming connection ports -network.port_open.set = no +network.port_open.set = yes network.port_random.set = no -#network.port_range.set = 33101-33199 +network.port_range.set = 49164-49164 # SCGI connection, e.g. for ruTorrent web UI network.scgi.open_local = /mnt/dietpi_userdata/downloads/.session/rpc.socket execute.nothrow = chmod,666,/mnt/dietpi_userdata/downloads/.session/rpc.socket @@ -9739,9 +9789,9 @@ _EOF_ (( $G_DISTRO > 4 )) && G_CONFIG_INJECT 'system.daemon.set[[:blank:]=]' 'system.daemon.set = true' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc # Permissions - G_EXEC chown -R rtorrent:dietpi /mnt/dietpi_userdata/rtorrent /mnt/dietpi_userdata/downloads/.session + G_EXEC chown -R rtorrent:root /mnt/dietpi_userdata/rtorrent /mnt/dietpi_userdata/downloads/.session # - ruTorrent: https://github.com/Novik/ruTorrent/wiki/Config - G_EXEC chown -R www-data:dietpi /var/www/rutorrent/share + G_EXEC chown -R www-data:root /var/www/rutorrent/share G_EXEC chown root:root /var/www/rutorrent/share/.htaccess fi @@ -9915,7 +9965,7 @@ _EOF_ fi - local fallback_url="https://github.com/syncthing/syncthing/releases/download/v1.18.1/syncthing-linux-$arch-v1.18.1.tar.gz" + local fallback_url="https://github.com/syncthing/syncthing/releases/download/v1.18.5/syncthing-linux-$arch-v1.18.5.tar.gz" Download_Install "$(curl -sSfL 'https://api.github.com/repos/syncthing/syncthing/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/syncthing-linux-$arch-[^\"\/]*\.tar\.gz\"/{print \$4}")" G_EXEC mv syncthing-* /opt/syncthing @@ -9982,21 +10032,22 @@ _EOF_ Banner_Installing # Apply preference index - INDEX_BROWSER_TARGET=-2 INDEX_BROWSER_CURRENT=-2 + INDEX_BROWSER=-2 if (( $G_HW_MODEL > 9 )) then G_AGI chromium - # RPi: Use RPi repo package + # RPi: Use RPi repo package including non-free FFmpeg codecs integration else - # Bullseye workaround: https://github.com/RPi-Distro/chromium-browser/issues/22 - local apackages=('chromium-browser') - (( $G_DISTRO < 6 )) || apackages+=('libgtk-3-0') - G_AGI "${apackages[@]}" + G_AGI chromium-browser chromium-codecs-ffmpeg-extra + + # Bullseye: Enable hardware codecs + (( $G_DISTRO < 6 )) || /boot/dietpi/func/dietpi-set_hardware rpi-codec 1 + fi - # Allow root, start maximized and disable sandbox under root (blank screen without) + # Allow root and disable sandbox under root (blank screen without): https://peter.sh/experiments/chromium-command-line-switches/ local export_options="export CHROMIUM_FLAGS=\"\$CHROMIUM_FLAGS \ --test-type \ --no-sandbox \ @@ -10015,7 +10066,7 @@ _EOF_ : # x86_64: OpenGL - elif [[ $G_HW_ARCH == 1 ]] + elif [[ $G_HW_ARCH == 10 ]] then : @@ -10026,7 +10077,7 @@ _EOF_ export_options+='"' - G_EXEC mkdir -p /etc/chromium.d + [[ -d '/etc/chromium.d' ]] || G_EXEC mkdir /etc/chromium.d echo "$export_options" > /etc/chromium.d/custom_flags # Chromium 60+ @@ -10040,14 +10091,14 @@ _EOF_ Create_Desktop_Shortcut chromium-browser fi - # Autostart run script for Kiosk mode, based on @AYapejian https://github.com/MichaIng/DietPi/issues/1737#issue-318697621 + # Autostart run script for kiosk mode, based on @AYapejian: https://github.com/MichaIng/DietPi/issues/1737#issue-318697621 [[ -d '/var/lib/dietpi/dietpi-software/installed' ]] || G_EXEC mkdir -p /var/lib/dietpi/dietpi-software/installed cat << '_EOF_' > /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh -#!/bin/bash -# Autostart run script for Kiosk mode, based on @AYapejian https://github.com/MichaIng/DietPi/issues/1737#issue-318697621 -# - Please see /root/.chromium-browser.init (and /etc/chromium.d/custom_flags) for additional egl/gl init options +#!/bin/dash +# Autostart run script for kiosk mode, based on @AYapejian: https://github.com/MichaIng/DietPi/issues/1737#issue-318697621 +# - Please see /root/.chromium-browser.init (and /etc/chromium.d/custom_flags) for additional EGL/GL init options -# Command line switches https://peter.sh/experiments/chromium-command-line-switches/ +# Command line switches: https://peter.sh/experiments/chromium-command-line-switches/ # --test-type gets rid of some of the chromium warnings that you may or may not care about in kiosk on a LAN # --pull-to-refresh=1 # --ash-host-window-bounds="400,300" @@ -10057,23 +10108,18 @@ RES_X=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_RES_X=/{s/^[^=]*=//p;q}' /boot/d RES_Y=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_RES_Y=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) CHROMIUM_OPTS="--kiosk --test-type --window-size=$RES_X,$RES_Y --start-fullscreen --start-maximized --window-position=0,0" + # If you want tablet mode, uncomment the next line. #CHROMIUM_OPTS+=' --force-tablet-mode --tablet-ui' -# Add URL for first run: +# Home page URL=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_AUTOSTART_URL=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) -CHROMIUM_OPTS+=" --homepage $URL" -# Find absolute filepath location of Chromium binary. -FP_CHROMIUM=$(command -v chromium) -if [[ ! $FP_CHROMIUM ]]; then +# RPi or Debian Chromium package +FP_CHROMIUM=$(command -v chromium-browser) +[ $FP_CHROMIUM ] || FP_CHROMIUM=$(command -v chromium-browser) - # Assume RPi - FP_CHROMIUM="$(command -v chromium-browser)" - -fi - -xinit $FP_CHROMIUM $CHROMIUM_OPTS +exec xinit "$FP_CHROMIUM" $CHROMIUM_OPTS --homepage "$URL" _EOF_ G_EXEC chmod +x /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh @@ -10092,7 +10138,7 @@ _EOF_ G_EXEC_OUTPUT=1 G_EXEC pip2 install --no-cache-dir -U motioneye # RPi: Enable camera module - (( $G_HW_MODEL < 10 )) && /boot/dietpi/func/dietpi-set_hardware rpi-camera enable + (( $G_HW_MODEL > 9 )) || /boot/dietpi/func/dietpi-set_hardware rpi-camera enable # Config if [[ ! -f '/etc/motioneye/motioneye.conf' ]] @@ -10230,25 +10276,26 @@ _EOF_ Banner_Installing # https://sabnzbd.org/wiki/installation/install-off-modules + # Stretch: SABnzbd v3.2.0 raised the Python dependency to v3.6: https://github.com/sabnzbd/sabnzbd/tree/3.2.0 + local python_version=$(python3 -V | tr -cd '0-9') version='master' + (( $python_version < 360 )) && version='3.1.1' + # APT deps DEPS_LIST='par2 p7zip-full' - # - Pre-compiling required on ARM - (( $G_HW_ARCH > 9 )) || DEPS_LIST+=' libffi-dev libssl-dev' - - # Stretch: SABnzbd v3.2.0 raised the Python dependency to v3.6: https://github.com/sabnzbd/sabnzbd/tree/3.2.0 - local version='master' - (( $(python3 -V | tr -cd '0-9') < 360 )) && version='3.1.1' + # Stretch on ARMv8/x86_64: No cffi wheels available for Python 3.5 in PyPI: https://pypi.org/project/cffi/#files + (( $G_HW_ARCH > 2 && $python_version < 360 )) && DEPS_LIST+=' gcc libffi-dev' + # ARMv8: No sabyenc3 wheels available: https://pypi.org/project/sabyenc3/#files + (( $G_HW_ARCH == 3 && $python_version >= 360 )) && DEPS_LIST+=' gcc' # Download Download_Install "https://github.com/sabnzbd/sabnzbd/archive/$version.tar.gz" # Reinstall: Remove old install dir - if [[ -d '/etc/sabnzbd' ]]; then - + if [[ -d '/etc/sabnzbd' ]] + then # Preserve old config file [[ -f '/etc/sabnzbd/sabnzbd.ini' ]] && G_EXEC mv /etc/sabnzbd/sabnzbd.ini sabnzbd-$version/sabnzbd.ini G_EXEC rm -R /etc/sabnzbd - fi # Install @@ -10256,18 +10303,22 @@ _EOF_ # Python deps G_EXEC cd /etc/sabnzbd + # Stretch on ARMv6/7: Use last cryptography version available as pre-compiled wheel for Python 3.5 in piwheels: https://www.piwheels.org/project/cryptography/ + [[ $G_HW_ARCH == [12] && $python_version -lt 370 ]] && G_CONFIG_INJECT 'cryptography' 'cryptography==3.2.1' requirements.txt G_EXEC_OUTPUT=1 G_EXEC pip3 install --no-cache-dir -Ur requirements.txt - G_EXEC cd /tmp/$G_PROGRAM_NAME # User Create_User -g dietpi -d /etc/sabnzbd sabnzbd + # Permissions + G_EXEC chown -R sabnzbd:root . + # Service: https://github.com/sabnzbd/sabnzbd/blob/master/linux/sabnzbd%40.service # - Options: https://sabnzbd.org/wiki/advanced/command-line-parameters # "-OO": Optimise code and remove doc lines (default shebang of SABnzbd.py, but we run python3 explicitly to avoid version conflicts) - # "-d": Run in daemon mode without terminal and browser start (requires "-f ") - # NB: In systemd unit leads to unreliable long taking webserver start. A new process is forked which allows web access, but sometimes after very long time, sometimes never: https://github.com/sabnzbd/sabnzbd/issues/1283 - # "-b 0": Do no start browser with daemon + # "-d": Run in daemon mode without terminal and browser start (requires "-f ") + # NB: In systemd unit leads to unreliable long taking webserver start. A new process is forked which allows web access, but sometimes after very long time, sometimes never: https://github.com/sabnzbd/sabnzbd/issues/1283 + # "-n": Do no start browser with daemon cat << _EOF_ > /etc/systemd/system/sabnzbd.service [Unit] Description=SABnzbd (DietPi) @@ -10276,42 +10327,41 @@ Wants=network-online.target After=network-online.target [Service] +SyslogIdentifier=SABnzbd User=sabnzbd -ExecStart=$(command -v python3) -OO /etc/sabnzbd/SABnzbd.py -b 0 -f /etc/sabnzbd/sabnzbd.ini +ExecStart=$(command -v python3) -OO /etc/sabnzbd/SABnzbd.py -f /etc/sabnzbd/sabnzbd.ini -n --disable-file-log Restart=on-failure [Install] WantedBy=multi-user.target _EOF_ - # Log dir and permissions - G_EXEC mkdir -p /var/log/sabnzbd - G_EXEC chown -R sabnzbd:root /{etc,var/log}/sabnzbd - # Config # - Touch only if it does not yet exist, assume reinstall otherwise and preserve custom changes # - API keys and initial config are only generated during 1st run # - We need to launch program, then apply our config tweaks, else, wizard setup in web interface simply loops without API keys. - if [[ ! -f '/etc/sabnzbd/sabnzbd.ini' ]]; then - - Create_Config /etc/sabnzbd/sabnzbd.ini sabnzbd + if [[ ! -f '/etc/sabnzbd/sabnzbd.ini' ]] && Create_Config /etc/sabnzbd/sabnzbd.ini sabnzbd + then sleep 1 # Additional wait, config being overwritten after below changes: https://dietpi.com/phpbb/viewtopic.php?p=7082#p7082 - G_CONFIG_INJECT 'download_dir =' 'download_dir = /mnt/dietpi_userdata/downloads/incomplete' /etc/sabnzbd/sabnzbd.ini - G_CONFIG_INJECT 'complete_dir =' 'complete_dir = /mnt/dietpi_userdata/downloads/complete' /etc/sabnzbd/sabnzbd.ini - G_CONFIG_INJECT 'nzb_backup_dir =' 'nzb_backup_dir = /mnt/dietpi_userdata/downloads/sabnzbd_nzb_backup' /etc/sabnzbd/sabnzbd.ini - G_CONFIG_INJECT 'admin_dir =' 'admin_dir = /mnt/dietpi_userdata/downloads/sabnzbd_admin' /etc/sabnzbd/sabnzbd.ini - G_CONFIG_INJECT 'log_dir =' 'log_dir = /var/log/sabnzbd' /etc/sabnzbd/sabnzbd.ini - G_CONFIG_INJECT 'log_level =' 'log_level = 0' /etc/sabnzbd/sabnzbd.ini # Warning errors only - G_CONFIG_INJECT 'refresh_rate =' 'refresh_rate = 2' /etc/sabnzbd/sabnzbd.ini - G_CONFIG_INJECT 'host =' 'host = 0.0.0.0' /etc/sabnzbd/sabnzbd.ini - G_CONFIG_INJECT 'permissions =' 'permissions = 0775' /etc/sabnzbd/sabnzbd.ini - G_CONFIG_INJECT 'auto_browser =' 'auto_browser = 0' /etc/sabnzbd/sabnzbd.ini + G_CONFIG_INJECT 'log_level[[:blank:]]+=' 'log_level = 0' /etc/sabnzbd/sabnzbd.ini # Warnings and errors only + G_CONFIG_INJECT 'auto_browser[[:blank:]]+=' 'auto_browser = 0' /etc/sabnzbd/sabnzbd.ini + G_CONFIG_INJECT 'host[[:blank:]]+=' 'host = 0.0.0.0' /etc/sabnzbd/sabnzbd.ini + G_CONFIG_INJECT 'admin_dir[[:blank:]]+=' 'admin_dir = /mnt/dietpi_userdata/downloads/sabnzbd_admin' /etc/sabnzbd/sabnzbd.ini + G_CONFIG_INJECT 'download_dir[[:blank:]]+=' 'download_dir = /mnt/dietpi_userdata/downloads/incomplete' /etc/sabnzbd/sabnzbd.ini + G_CONFIG_INJECT 'complete_dir[[:blank:]]+=' 'complete_dir = /mnt/dietpi_userdata/downloads/complete' /etc/sabnzbd/sabnzbd.ini + G_CONFIG_INJECT 'nzb_backup_dir[[:blank:]]+=' 'nzb_backup_dir = /mnt/dietpi_userdata/downloads/sabnzbd_nzb_backup' /etc/sabnzbd/sabnzbd.ini + G_CONFIG_INJECT 'permissions[[:blank:]]+=' 'permissions = 0775' /etc/sabnzbd/sabnzbd.ini + G_CONFIG_INJECT 'refresh_rate[[:blank:]]+=' 'refresh_rate = 2' /etc/sabnzbd/sabnzbd.ini + [[ -d '/mnt/dietpi_userdata/downloads/sabnzbd_admin' ]] && G_EXEC chown -R sabnzbd:root /mnt/dietpi_userdata/downloads/sabnzbd_admin + [[ -d '/mnt/dietpi_userdata/downloads/sabnzbd_nzb_backup' ]] && G_EXEC chown -R sabnzbd:root /mnt/dietpi_userdata/downloads/sabnzbd_nzb_backup + [[ -d '/mnt/dietpi_userdata/downloads/incomplete' ]] && G_EXEC chown -R sabnzbd:dietpi /mnt/dietpi_userdata/downloads/incomplete + [[ -d '/mnt/dietpi_userdata/downloads/complete' ]] && G_EXEC chown -R sabnzbd:dietpi /mnt/dietpi_userdata/downloads/complete fi # Install language packs: https://github.com/MichaIng/DietPi/issues/1917#issue-340631943 - G_EXEC cd /etc/sabnzbd - G_EXEC python3 tools/make_mo.py + G_EXEC python3 -OO tools/make_mo.py + G_EXEC chown -R sabnzbd:root . G_EXEC cd /tmp/$G_PROGRAM_NAME fi @@ -10400,7 +10450,7 @@ _EOF_ # Download local version=$(curl -sSfL 'https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest' | mawk -F\" '/"tag_name": /{print $4}') - [[ $version ]] || { version='1.22.2'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } + [[ $version ]] || { version='1.23.0'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } Download_Install "https://github.com/dani-garcia/vaultwarden/archive/$version.tar.gz" # Replace old instance on reinstall using new project name @@ -10531,7 +10581,7 @@ _EOF_ G_EXEC chmod +x install.sh export INSTALL_K3S_SKIP_ENABLE=true export INSTALL_K3S_EXEC=$(sed -n '/^[[:blank:]]*SOFTWARE_K3S_EXEC=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - G_EXEC_NOEXIT=1 G_EXEC_OUTPUT=1 G_EXEC ./install.sh || aSOFTWARE_INSTALL_STATE[$software_id]=-1 UNINSTALL_REQUIRED=1 + G_EXEC_NOEXIT=1 G_EXEC_OUTPUT=1 G_EXEC ./install.sh || aSOFTWARE_INSTALL_STATE[$software_id]=-1 G_EXEC_NOHALT=1 G_EXEC rm install.sh # Do not enter into a server restart loop on failure @@ -10583,7 +10633,7 @@ _EOF_ DEPS_LIST="$PHP_NAME-bcmath $PHP_NAME-json $PHP_NAME-mbstring $PHP_NAME-xml $PHP_NAME-curl $PHP_NAME-sqlite3" # Grab latest release - local fallback_url='https://github.com/koel/koel/releases/download/v5.1.5/koel-v5.1.5.tar.gz' + local fallback_url='https://github.com/koel/koel/releases/download/v5.1.8/koel-v5.1.8.tar.gz' Download_Install "$(curl -sSfL 'https://api.github.com/repos/koel/koel/releases/latest' | mawk -F\" '/"browser_download_url": .*\/koel-[^"\/]*\.tar\.gz"/{print $4}')" # Reinstall: Clear previous install, but keep existing config file @@ -10674,7 +10724,7 @@ _EOF_ Banner_Installing # https://sonarr.tv/#downloads-v3-linux-debian # APT repo key - G_EXEC apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 + G_EXEC apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-keys '2009837CBFFD68F45BC180471F4F90DE2A9B4BF8' # APT repo list G_EXEC eval "echo 'deb https://apt.sonarr.tv/debian/ ${G_DISTRO_NAME/bullseye/buster} main' > /etc/apt/sources.list.d/sonarr.list" @@ -10688,6 +10738,7 @@ _EOF_ # Install Sonarr and mediainfo G_AGI sonarr mediainfo + G_EXEC systemctl stop sonarr # Pre-v7.1: Remove Sonarr v2 key, PID file and database backups from DietPi-Arr_to_RAM [[ $(apt-key list 'A236C58F409091A18ACA53CBEBFF6B99D9B78493' 2> /dev/null) ]] && G_EXEC_NOEXIT=1 G_EXEC apt-key del 'A236C58F409091A18ACA53CBEBFF6B99D9B78493' @@ -11096,6 +11147,7 @@ Wants=network-online.target After=network-online.target [Service] +SyslogIdentifier=Tautulli User=tautulli ExecStart=$(command -v python3) /opt/tautulli/Tautulli.py -q --nolaunch --config /mnt/dietpi_userdata//tautulli/config.ini --datadir /mnt/dietpi_userdata/tautulli @@ -11116,7 +11168,7 @@ _EOF_ # - ARMv6: Requires Mono: https://github.com/Jackett/Jackett#installation-on-linux-armv6-or-below local url=$(curl -sSfL 'https://api.github.com/repos/Jackett/Jackett/releases/latest' | mawk -F\" '/"browser_download_url": .*\/Jackett\.Binaries\.Mono\.tar\.gz"/{print $4}') - local fallback_url='https://github.com/Jackett/Jackett/releases/download/v0.18.636/Jackett.Binaries.Mono.tar.gz' + local fallback_url='https://github.com/Jackett/Jackett/releases/download/v0.20.123/Jackett.Binaries.Mono.tar.gz' # - ARMv7 if (( $G_HW_ARCH == 2 )); then @@ -11386,6 +11438,7 @@ _EOF_ [[ -f '/etc/cups/cupsd.conf' ]] || dps_index=$software_id Download_Install 'cupsd.conf' /etc/cups/cupsd.conf G_AGI cups + G_EXEC systemctl stop cups G_EXEC chown root:lp /etc/cups/ /etc/cups/ppd/ /etc/cups/ssl/ fi @@ -11523,7 +11576,7 @@ _EOF_ Create_User -d /mnt/dietpi_userdata/minio-data minio-user # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/minio-data + [[ -d '/mnt/dietpi_userdata/minio-data' ]] || G_EXEC mkdir /mnt/dietpi_userdata/minio-data G_EXEC chown -R minio-user:minio-user /mnt/dietpi_userdata/minio-data # Config @@ -11557,6 +11610,7 @@ _EOF_ # APT package G_AGI docker-ce + G_EXEC systemctl stop docker # Change Docker service type to "simple": https://github.com/MichaIng/DietPi/issues/2238#issuecomment-439474766 [[ -d '/lib/systemd/system/docker.service.d' ]] || G_EXEC mkdir /lib/systemd/system/docker.service.d @@ -11681,32 +11735,31 @@ _EOF_ Banner_Installing - # Binary + data dir - [[ -d '/mnt/dietpi_userdata/gitea/gitea-repositories' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/gitea/gitea-repositories - # ARMv6 + ARMv7 since as of v1.8 there are issues with ARMv7 binaries on Raspbian which are hence not provided anymore: https://github.com/MichaIng/DietPi/issues/2959 (Troubleshooting) local arch='arm-6' # ARMv8 - if (( $G_HW_ARCH == 3 )); then - + if (( $G_HW_ARCH == 3 )) + then arch='arm64' # x86_64 - elif (( $G_HW_ARCH == 10 )); then - + elif (( $G_HW_ARCH == 10 )) + then arch='amd64' - fi - local fallback_url="https://github.com/go-gitea/gitea/releases/download/v1.15.0/gitea-1.15.0-linux-$arch" + local fallback_url="https://github.com/go-gitea/gitea/releases/download/v1.15.7/gitea-1.15.7-linux-$arch" Download_Install "$(curl -sSfL 'https://api.github.com/repos/go-gitea/gitea/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/gitea-[^\"\/]*-linux-$arch\"/{print \$4}")" /mnt/dietpi_userdata/gitea/gitea # Logs [[ -d '/var/log/gitea' ]] || G_EXEC mkdir /var/log/gitea + # User + Create_User -d /mnt/dietpi_userdata/gitea gitea + # Permissions - G_EXEC chown -R dietpi:dietpi /var/log/gitea /mnt/dietpi_userdata/gitea + G_EXEC chown -R gitea:gitea /mnt/dietpi_userdata/gitea /var/log/gitea G_EXEC chmod +x /mnt/dietpi_userdata/gitea/gitea # Database @@ -11716,13 +11769,20 @@ _EOF_ cat << '_EOF_' > /etc/systemd/system/gitea.service [Unit] Description=Gitea (DietPi) +Wants=network-online.target +After=network-online.target mariadb.service [Service] -User=dietpi -WorkingDirectory=/mnt/dietpi_userdata/gitea/gitea-repositories -Environment=USER=dietpi HOME=/mnt/dietpi_userdata/gitea +User=gitea +WorkingDirectory=/mnt/dietpi_userdata/gitea ExecStart=/mnt/dietpi_userdata/gitea/gitea web +# Hardening +ProtectSystem=full +PrivateDevices=yes +PrivateTmp=yes +NoNewPrivileges=true + [Install] WantedBy=multi-user.target _EOF_ @@ -11875,7 +11935,7 @@ _EOF_ # APT key local url='https://dtcooper.github.io/raspotify/key.asc' G_CHECK_URL "$url" - G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-raspotify.gpg --yes" + G_EXEC eval "curl -sSfL '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-raspotify.gpg --yes" # APT list G_EXEC eval "echo 'deb https://dtcooper.github.io/raspotify/ raspotify main' > /etc/apt/sources.list.d/raspotify.list" @@ -11883,6 +11943,7 @@ _EOF_ # APT package G_AGI raspotify + G_EXEC systemctl stop raspotify fi @@ -12021,6 +12082,8 @@ _EOF_ G_EXEC_OUTPUT=1 G_EXEC ./rem-setup.sh G_EXEC_NOHALT=1 G_EXEC rm rem-setup.sh + G_EXEC systemctl stop roon-extension-manager + fi software_id=178 # Jellyfin @@ -12028,6 +12091,9 @@ _EOF_ Banner_Installing + # Raspberry Pi Bullseye: Enable hardware codecs + (( $G_HW_MODEL > 9 )) || (( $G_DISTRO < 6 )) || /boot/dietpi/func/dietpi-set_hardware rpi-codec 1 + # APT key local url='https://repo.jellyfin.org/jellyfin_team.gpg.key' G_CHECK_URL "$url" @@ -12039,22 +12105,22 @@ _EOF_ # APT meta package: Server, web component and FFmpeg implementation G_AGI jellyfin + G_EXEC systemctl stop jellyfin # Grant dietpi group permissions and assure video access Create_User -G dietpi,video,render -d /mnt/dietpi_userdata/jellyfin jellyfin # Config: Only apply on fresh install, assumed when /mnt/dietpi_userdata/jellyfin does not yet exist - if [[ ! -d '/mnt/dietpi_userdata/jellyfin' ]]; then - + if [[ ! -d '/mnt/dietpi_userdata/jellyfin' ]] + then # Data dir # shellcheck disable=SC2015 - [[ -d '/var/lib/jellyfin' ]] && G_EXEC mv /var/lib/jellyfin /mnt/dietpi_userdata/jellyfin || G_EXEC mkdir -p /mnt/dietpi_userdata/jellyfin + [[ -d '/var/lib/jellyfin' ]] && G_EXEC mv /var/lib/jellyfin /mnt/dietpi_userdata/jellyfin || G_EXEC mkdir /mnt/dietpi_userdata/jellyfin G_CONFIG_INJECT 'JELLYFIN_DATA_DIR=' 'JELLYFIN_DATA_DIR=/mnt/dietpi_userdata/jellyfin' /etc/default/jellyfin # Cache dir # shellcheck disable=SC2015 - [[ -d '/var/cache/jellyfin' ]] && G_EXEC mv /var/cache/jellyfin /mnt/dietpi_userdata/jellyfin/cache || G_EXEC mkdir -p /mnt/dietpi_userdata/jellyfin/cache + [[ -d '/var/cache/jellyfin' ]] && G_EXEC mv /var/cache/jellyfin /mnt/dietpi_userdata/jellyfin/cache || G_EXEC mkdir /mnt/dietpi_userdata/jellyfin/cache G_CONFIG_INJECT 'JELLYFIN_CACHE_DIR=' 'JELLYFIN_CACHE_DIR=/mnt/dietpi_userdata/jellyfin/cache' /etc/default/jellyfin - fi # Permissions @@ -12074,7 +12140,7 @@ _EOF_ # Download local version=$(curl -sSfL 'https://api.github.com/repos/ptitSeb/box86/tags' | mawk -F\" '/"name": /{print $4;exit}') - [[ $version ]] || { version='v0.2.2'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } + [[ $version ]] || { version='v0.2.4'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } Download_Install "https://github.com/ptitSeb/box86/archive/$version.tar.gz" # Build @@ -12118,7 +12184,7 @@ _EOF_ # Download local version=$(curl -sSfL 'https://api.github.com/repos/ptitSeb/box64/tags' | mawk -F\" '/"name": /{print $4;exit}') - [[ $version ]] || { version='v0.1.4'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } + [[ $version ]] || { version='v0.1.6'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; } Download_Install "https://github.com/ptitSeb/box64/archive/$version.tar.gz" # Build @@ -12225,7 +12291,7 @@ _EOF_ local ha_user='homeassistant' local ha_home="/home/$ha_user" local ha_pyenv_activation=". $ha_home/pyenv-activate.sh" - local ha_python_version='3.9.8' + local ha_python_version='3.9.9' G_DIETPI-NOTIFY 2 "Home Assistant user: $ha_user" G_DIETPI-NOTIFY 2 "Home Assistant home: $ha_home" @@ -12499,9 +12565,10 @@ _EOF_ local fallback_url="https://github.com/badaix/snapcast/releases/download/v0.25.0/snapserver_0.25.0-1_$arch.deb" Download_Install "$(curl -sSfL 'https://api.github.com/repos/badaix/snapcast/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/snapserver_[^\"\/]*_$arch.deb\"/{print \$4}")" + G_EXEC systemctl stop snapserver # Disable JSON RPC by default, if setting was never touched yet - sed -i '/^\[tcp\]/,/^\[/s/^#enabled = true$/enabled = false/' /etc/snapserver.conf + G_EXEC sed -i '/^\[tcp\]/,/^\[/s/^#enabled = true$/enabled = false/' /etc/snapserver.conf fi @@ -12515,6 +12582,7 @@ _EOF_ local fallback_url="https://github.com/badaix/snapcast/releases/download/v0.25.0/snapclient_0.25.0-1_without-pulse_$arch.deb" Download_Install "$(curl -sSfL 'https://api.github.com/repos/badaix/snapcast/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/snapclient_[^\"\/]*_without-pulse_$arch.deb\"/{print \$4}")" + G_EXEC systemctl stop snapclient # Client IP needs to be added to allowed IP list local snapcast_server_ip @@ -12570,7 +12638,7 @@ _EOF_ fi - local fallback_url="https://github.com/filebrowser/filebrowser/releases/download/v2.17.1/linux-$arch-filebrowser.tar.gz" + local fallback_url="https://github.com/filebrowser/filebrowser/releases/download/v2.19.0/linux-$arch-filebrowser.tar.gz" Download_Install "$(curl -sSfL 'https://api.github.com/repos/filebrowser/filebrowser/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/linux-$arch-filebrowser\.tar\.gz\"/{print \$4}")" ./filebrowser/ # Reinstall @@ -12619,18 +12687,18 @@ _EOF_ Banner_Installing # ARMv6 - local fallback_url='https://github.com/Spotifyd/spotifyd/releases/download/v0.3.2/spotifyd-linux-armv6-slim.tar.gz' + local fallback_url='https://github.com/Spotifyd/spotifyd/releases/download/v0.3.3/spotifyd-linux-armv6-slim.tar.gz' local file='spotifyd-linux-armv6-slim' case $G_HW_ARCH in # ARMv7 2) - fallback_url="https://github.com/Spotifyd/spotifyd/releases/download/v0.3.2/spotifyd-linux-armhf-full.tar.gz" + fallback_url="https://github.com/Spotifyd/spotifyd/releases/download/v0.3.3/spotifyd-linux-armhf-full.tar.gz" file='spotifyd-linux-armhf-full' ;; # x86_64 10) - fallback_url="https://github.com/Spotifyd/spotifyd/releases/download/v0.3.2/spotifyd-linux-full.tar.gz" + fallback_url="https://github.com/Spotifyd/spotifyd/releases/download/v0.3.3/spotifyd-linux-full.tar.gz" file='spotifyd-linux-full' ;; esac @@ -12700,111 +12768,54 @@ _EOF_ } - Apply_SSHServer_Choices(){ - - # Work out which SSH server needs installing from IDs (if any) - # Work out which SSH server needs removing (if any) - if (( $INDEX_SSHSERVER_TARGET != $INDEX_SSHSERVER_CURRENT )); then - - # No SSH server - if (( $INDEX_SSHSERVER_TARGET == 0 )); then - - # Check currently installed SSH servers via "dpkg --get-selections" to be failsafe - local dpkg_out=$(dpkg --get-selections) - - grep -q '^dropbear[^[:blank:]]*[[:blank:]]' <<< "$dpkg_out" && aSOFTWARE_INSTALL_STATE[104]=-1 UNINSTALL_REQUIRED=1 - grep -q '^openssh-server[[:blank:]]' <<< "$dpkg_out" && aSOFTWARE_INSTALL_STATE[105]=-1 UNINSTALL_REQUIRED=1 - - # Dropbear - elif (( $INDEX_SSHSERVER_TARGET == -1 )); then - - aSOFTWARE_INSTALL_STATE[104]=1 - - # OpenSSH - elif (( $INDEX_SSHSERVER_TARGET == -2 )); then - - aSOFTWARE_INSTALL_STATE[105]=1 - - fi - - fi - - } - - Apply_FileServer_Choices(){ - - # Work out which file Server needs installing from IDs (if any) - # Work out which file server needs removing (if any) - if (( $INDEX_FILESERVER_TARGET != $INDEX_FILESERVER_CURRENT )); then - - # No file server - if (( $INDEX_FILESERVER_TARGET == 0 )); then - - (( ${aSOFTWARE_INSTALL_STATE[94]} == 2 )) && aSOFTWARE_INSTALL_STATE[94]=-1 UNINSTALL_REQUIRED=1 - (( ${aSOFTWARE_INSTALL_STATE[96]} == 2 )) && aSOFTWARE_INSTALL_STATE[96]=-1 UNINSTALL_REQUIRED=1 - - # ProFTPD - elif (( $INDEX_FILESERVER_TARGET == -1 )); then - - aSOFTWARE_INSTALL_STATE[94]=1 - (( ${aSOFTWARE_INSTALL_STATE[96]} == 2 )) && aSOFTWARE_INSTALL_STATE[96]=-1 UNINSTALL_REQUIRED=1 - - # Samba - elif (( $INDEX_FILESERVER_TARGET == -2 )); then - - aSOFTWARE_INSTALL_STATE[96]=1 - (( ${aSOFTWARE_INSTALL_STATE[94]} == 2 )) && aSOFTWARE_INSTALL_STATE[94]=-1 UNINSTALL_REQUIRED=1 - - fi - - # Update current file server index - INDEX_FILESERVER_CURRENT=$INDEX_FILESERVER_TARGET + # $1: 0=None -1=Dropbear -2=OpenSSH + Apply_SSHServer_Choices() + { + if (( $1 == 0 )) + then + [[ ${aSOFTWARE_INSTALL_STATE[104]} == [01] ]] && aSOFTWARE_INSTALL_STATE[104]=0 || aSOFTWARE_INSTALL_STATE[104]=-1 + [[ ${aSOFTWARE_INSTALL_STATE[105]} == [01] ]] && aSOFTWARE_INSTALL_STATE[105]=0 || aSOFTWARE_INSTALL_STATE[105]=-1 + elif (( $1 == -2 )) + then + [[ ${aSOFTWARE_INSTALL_STATE[104]} == [01] ]] && aSOFTWARE_INSTALL_STATE[104]=0 || aSOFTWARE_INSTALL_STATE[104]=-1 + [[ ${aSOFTWARE_INSTALL_STATE[105]} == [01] ]] && aSOFTWARE_INSTALL_STATE[105]=1 || aSOFTWARE_INSTALL_STATE[105]=2 + else + [[ ${aSOFTWARE_INSTALL_STATE[104]} == [01] ]] && aSOFTWARE_INSTALL_STATE[104]=1 || aSOFTWARE_INSTALL_STATE[104]=2 + [[ ${aSOFTWARE_INSTALL_STATE[105]} == [01] ]] && aSOFTWARE_INSTALL_STATE[105]=0 || aSOFTWARE_INSTALL_STATE[105]=-1 fi - } - Apply_Logging_Choices(){ - - # Work out which logging system needs installing from IDs (if any) - # Work out which logging system needs removing (if any) - if (( $INDEX_LOGGING_TARGET != $INDEX_LOGGING_CURRENT )); then - - # None - if (( $INDEX_LOGGING_TARGET == 0 )); then - - (( ${aSOFTWARE_INSTALL_STATE[101]} == 2 )) && aSOFTWARE_INSTALL_STATE[101]=-1 UNINSTALL_REQUIRED=1 - (( ${aSOFTWARE_INSTALL_STATE[102]} == 2 )) && aSOFTWARE_INSTALL_STATE[102]=-1 UNINSTALL_REQUIRED=1 - (( ${aSOFTWARE_INSTALL_STATE[103]} == 2 )) && aSOFTWARE_INSTALL_STATE[103]=-1 UNINSTALL_REQUIRED=1 - - # RAMlog - clear every hour - elif (( $INDEX_LOGGING_TARGET == -1 )); then - - aSOFTWARE_INSTALL_STATE[103]=1 - (( ${aSOFTWARE_INSTALL_STATE[101]} == 2 )) && aSOFTWARE_INSTALL_STATE[101]=-1 UNINSTALL_REQUIRED=1 - (( ${aSOFTWARE_INSTALL_STATE[102]} == 2 )) && aSOFTWARE_INSTALL_STATE[102]=-1 UNINSTALL_REQUIRED=1 - - # RAMlog - backup every hour to /root/logfile_storage, then clear - elif (( $INDEX_LOGGING_TARGET == -2 )); then - - aSOFTWARE_INSTALL_STATE[103]=1 - (( ${aSOFTWARE_INSTALL_STATE[101]} == 2 )) && aSOFTWARE_INSTALL_STATE[101]=-1 UNINSTALL_REQUIRED=1 - (( ${aSOFTWARE_INSTALL_STATE[102]} == 2 )) && aSOFTWARE_INSTALL_STATE[102]=-1 UNINSTALL_REQUIRED=1 - - # Logrotate + Rsyslog - logs to disk - elif (( $INDEX_LOGGING_TARGET == -3 )); then - - aSOFTWARE_INSTALL_STATE[101]=1 - aSOFTWARE_INSTALL_STATE[102]=1 - (( ${aSOFTWARE_INSTALL_STATE[103]} == 2 )) && aSOFTWARE_INSTALL_STATE[103]=-1 UNINSTALL_REQUIRED=1 - - fi + # $1: 0=None -1=DietPi-RAMlog #1 -2=DietPi-RAMlog #2 -3=Full + Apply_Logging_Choices() + { + if (( $1 == 0 )) + then + [[ ${aSOFTWARE_INSTALL_STATE[101]} == [01] ]] && aSOFTWARE_INSTALL_STATE[101]=0 || aSOFTWARE_INSTALL_STATE[101]=-1 + [[ ${aSOFTWARE_INSTALL_STATE[102]} == [01] ]] && aSOFTWARE_INSTALL_STATE[102]=0 || aSOFTWARE_INSTALL_STATE[102]=-1 + [[ ${aSOFTWARE_INSTALL_STATE[103]} == [01] ]] && aSOFTWARE_INSTALL_STATE[103]=0 || aSOFTWARE_INSTALL_STATE[103]=-1 - # Update current logging index - INDEX_LOGGING_CURRENT=$INDEX_LOGGING_TARGET + elif (( $1 == -2 )) + then + [[ ${aSOFTWARE_INSTALL_STATE[101]} == [01] ]] && aSOFTWARE_INSTALL_STATE[101]=0 || aSOFTWARE_INSTALL_STATE[101]=-1 + [[ ${aSOFTWARE_INSTALL_STATE[102]} == [01] ]] && aSOFTWARE_INSTALL_STATE[102]=0 || aSOFTWARE_INSTALL_STATE[102]=-1 + [[ ${aSOFTWARE_INSTALL_STATE[103]} == [01] ]] && aSOFTWARE_INSTALL_STATE[103]=1 || aSOFTWARE_INSTALL_STATE[103]=2 + elif (( $1 == -3 )) + then + [[ ${aSOFTWARE_INSTALL_STATE[101]} == [01] ]] && aSOFTWARE_INSTALL_STATE[101]=1 || aSOFTWARE_INSTALL_STATE[101]=2 + [[ ${aSOFTWARE_INSTALL_STATE[102]} == [01] ]] && aSOFTWARE_INSTALL_STATE[102]=1 || aSOFTWARE_INSTALL_STATE[102]=2 + [[ ${aSOFTWARE_INSTALL_STATE[103]} == [01] ]] && aSOFTWARE_INSTALL_STATE[103]=0 || aSOFTWARE_INSTALL_STATE[103]=-1 + else + set -- '-1' + [[ ${aSOFTWARE_INSTALL_STATE[101]} == [01] ]] && aSOFTWARE_INSTALL_STATE[101]=0 || aSOFTWARE_INSTALL_STATE[101]=-1 + [[ ${aSOFTWARE_INSTALL_STATE[102]} == [01] ]] && aSOFTWARE_INSTALL_STATE[102]=0 || aSOFTWARE_INSTALL_STATE[102]=-1 + [[ ${aSOFTWARE_INSTALL_STATE[103]} == [01] ]] && aSOFTWARE_INSTALL_STATE[103]=1 || aSOFTWARE_INSTALL_STATE[103]=2 fi + INDEX_LOGGING=$1 + # If DietPi-RAMlog is and stays installed, apply logging index now to make the change permanent for DietPi-LogClear even if no actual install is required. + [[ $INDEX_LOGGING == -[12] && ${aSOFTWARE_INSTALL_STATE[103]} == 2 ]] && G_CONFIG_INJECT 'INDEX_LOGGING=' "INDEX_LOGGING=$INDEX_LOGGING" /boot/dietpi/.installed } Install_Apply_GPU_Settings(){ @@ -12812,8 +12823,8 @@ _EOF_ # RPi: Define minimal memory split based on installed software local gpu_memory=0 - # Kodi, Jellyfin - if (( ${aSOFTWARE_INSTALL_STATE[31]} == 1 || ${aSOFTWARE_INSTALL_STATE[178]} == 1 )); then + # Kodi prior to Bullseye, Jellyfin + if (( ( ${aSOFTWARE_INSTALL_STATE[31]} == 1 && $G_DISTRO < 6 ) || ${aSOFTWARE_INSTALL_STATE[178]} == 1 )); then gpu_memory=256 (( ${G_HW_MEMORY_SIZE:-0} > 256 )) || gpu_memory=128 @@ -12830,30 +12841,32 @@ _EOF_ gpu_memory=96 - # Desktops, OpenTyrian + # Desktops, OpenTyrian, Kodi since Bullseye elif (( ${aSOFTWARE_INSTALL_STATE[23]} == 1 || ${aSOFTWARE_INSTALL_STATE[24]} == 1 || ${aSOFTWARE_INSTALL_STATE[25]} == 1 || ${aSOFTWARE_INSTALL_STATE[26]} == 1 || + ${aSOFTWARE_INSTALL_STATE[31]} == 1 || ${aSOFTWARE_INSTALL_STATE[51]} == 1 )); then - gpu_memory=64 + gpu_memory=1 # default fi # Disable headless/enable GPU when graphics software was installed - (( $gpu_memory )) || return + (( $gpu_memory )) || return 0 /boot/dietpi/func/dietpi-set_hardware headless 0 # RPi: Apply memory split - (( $G_HW_MODEL < 10 )) || return + (( $G_HW_MODEL < 10 )) || return 0 # Never override a higher existing value local current_gpu_mem=$(sed -n '/^[[:blank:]]*gpu_mem_1024=/{s/^[^=]*=//p;q}' /boot/config.txt) [[ $current_gpu_mem ]] || { (( $G_HW_MEMORY_SIZE < 1024 )) && current_gpu_mem=64 || current_gpu_mem=76; } + (( $gpu_memory == 1 )) && gpu_memory=$current_gpu_mem (( $current_gpu_mem < $gpu_memory )) && G_WHIP_DEFAULT_ITEM='Ok' G_WHIP_YESNO "[ INFO ] DietPi has detected an increased GPU memory is required for your installed software: - - Current: $current_gpu_mem MiB\n - Recommended: $gpu_memory MiB\n\nWould you like DietPi to apply the recommended GPU memory split?\n\nIf unsure, select 'Ok'." || return + - Current: $current_gpu_mem MiB\n - Recommended: $gpu_memory MiB\n\nWould you like DietPi to apply the recommended GPU memory split?\n\nIf unsure, select 'Ok'." || return 0 /boot/dietpi/func/dietpi-set_hardware gpumemsplit $gpu_memory @@ -12874,6 +12887,9 @@ _EOF_ G_EXEC rm -Rf /{root,home/*}/.{config,cache}/{lxpanel,lxsession,lxterminal,openbox,pcmanfm,dconf} [[ -f '/etc/apt/preferences.d/dietpi-lxde' ]] && G_EXEC rm /etc/apt/preferences.d/dietpi-lxde + # Update desktop preference index + (( $INDEX_DESKTOP == 0 )) && INDEX_DESKTOP=-1 + fi software_id=173 # LXQt @@ -12884,6 +12900,9 @@ _EOF_ G_AGP lxqt rm -Rf /{root,home/*}/.config/lxqt + # Update desktop preference index + (( $INDEX_DESKTOP == -3 )) && INDEX_DESKTOP=0 + fi software_id=174 # GIMP @@ -12909,6 +12928,9 @@ _EOF_ apt-mark auto upower policykit-1 2> /dev/null G_AGP mate-desktop-environment-core mate-media + # Update desktop preference index + (( $INDEX_DESKTOP == -2 )) && INDEX_DESKTOP=0 + fi software_id=26 # GNUstep @@ -12918,6 +12940,9 @@ _EOF_ apt-mark auto upower policykit-1 2> /dev/null G_AGP x-window-system-core wmaker gnustep gnustep-devel gnustep-games + # Update desktop preference index + (( $INDEX_DESKTOP == -4 )) && INDEX_DESKTOP=0 + fi software_id=25 # Xfce @@ -12927,6 +12952,9 @@ _EOF_ apt-mark auto gnome-icon-theme tango-icon-theme upower policykit-1 2> /dev/null G_AGP xfce4 xfce4-terminal + # Update desktop preference index + (( $INDEX_DESKTOP == -1 )) && INDEX_DESKTOP=0 + fi software_id=22 # QuiteRSS @@ -13015,7 +13043,7 @@ _EOF_ fi - software_id=168 # Nextcloud Talk + coTURN server + software_id=168 # Nextcloud Talk + Coturn server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -13101,11 +13129,15 @@ _EOF_ fi - software_id=83 # Apache2 + software_id=83 # Apache if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - G_AGP apache2 + G_AGP apache2 libapache2-mod-php* + G_EXEC rm -Rf /{etc,var/{lib,log}}/apache2 /{etc/php,var/lib/php/modules}/*/apache2 + + # Adjust webserver preference index + (( $INDEX_WEBSERVER == 0 )) && INDEX_WEBSERVER=-2 fi @@ -13115,6 +13147,9 @@ _EOF_ Banner_Uninstalling G_AGP nginx 'nginx-*' + # Adjust webserver preference index + (( $INDEX_WEBSERVER == -1 )) && INDEX_WEBSERVER=-2 + fi software_id=84 # Lighttpd @@ -13139,6 +13174,9 @@ _EOF_ [[ -f 'etc/systemd/system/certbot.service.d/dietpi-lighttpd.conf' ]] && G_EXEC rm /etc/systemd/system/certbot.service.d/dietpi-lighttpd.conf [[ -d '/etc/systemd/system/certbot.service.d' ]] && G_EXEC rmdir --ignore-fail-on-non-empty /etc/systemd/system/certbot.service.d + # Adjust webserver preference index + (( $INDEX_WEBSERVER == -2 )) && INDEX_WEBSERVER=0 + fi software_id=87 # SQLite @@ -13162,20 +13200,12 @@ _EOF_ Banner_Uninstalling G_AGP 'php*-*' 'libapache2-mod-php*' - [[ -d '/etc/php' ]] && rm -R /etc/php - [[ -f '/var/www/phpinfo.php' ]] && rm /var/www/phpinfo.php - [[ -f '/var/www/apc.php' ]] && rm /var/www/apc.php - [[ -f '/var/www/opcache.php' ]] && rm /var/www/opcache.php - # temp php uploads, if it was created - [[ -d '/var/tmp/php_upload_tmp' ]] && rm -R /var/tmp/php_upload_tmp - - ## Leave PHP repo in place to avoid issues with remaining dependency packages that were pulled from this repo - # APT repo - #[[ -f '/etc/apt/sources.list.d/dietpi-php.list' ]] && rm /etc/apt/sources.list.d/dietpi-php.list - #[[ -f '/etc/apt/trusted.gpg.d/dietpi-php.gpg' ]] && rm /etc/apt/trusted.gpg.d/dietpi-php.gpg - # APT preferences - #[[ -f '/etc/apt/preferences.d/dietpi-openssl' ]] && rm /etc/apt/preferences.d/dietpi-openssl - #[[ -f '/etc/apt/preferences.d/dietpi-php' ]] && rm /etc/apt/preferences.d/dietpi-php + G_EXEC rm -Rf /{etc,var/lib}/php + [[ -f '/etc/tmpfiles.d/dietpi-php_sessions.conf' ]] && G_EXEC rm /etc/tmpfiles.d/dietpi-php_sessions.conf + [[ -f '/var/www/phpinfo.php' ]] && G_EXEC rm /var/www/phpinfo.php + [[ -f '/var/www/apc.php' ]] && G_EXEC rm /var/www/apc.php + [[ -f '/var/www/opcache.php' ]] && G_EXEC rm /var/www/opcache.php + [[ -d '/var/tmp/php_upload_tmp' ]] && G_EXEC rm -R /var/tmp/php_upload_tmp # Pre-v6.32 fi @@ -13536,17 +13566,18 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - if [[ -f '/etc/systemd/system/sabnzbd.service' ]]; then - + if [[ -f '/etc/systemd/system/sabnzbd.service' ]] + then G_EXEC systemctl disable --now sabnzbd G_EXEC rm /etc/systemd/system/sabnzbd.service - fi [[ -d '/etc/systemd/system/sabnzbd.service.d' ]] && G_EXEC rm -R /etc/systemd/system/sabnzbd.service.d getent passwd sabnzbd > /dev/null && G_EXEC userdel sabnzbd getent group sabnzbd > /dev/null && G_EXEC groupdel sabnzbd # Pre-v6.33 [[ -d '/etc/sabnzbd' ]] && G_EXEC rm -R /etc/sabnzbd - [[ -d '/var/log/sabnzbd' ]] && G_EXEC rm -R /var/log/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 + [[ -d '/var/log/sabnzbd' ]] && G_EXEC rm -R /var/log/sabnzbd # Pre-v7.9 fi @@ -14211,11 +14242,10 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - if [[ -f '/etc/systemd/system/airsonic.service' ]]; then - + if [[ -f '/etc/systemd/system/airsonic.service' ]] + then G_EXEC systemctl disable --now airsonic G_EXEC rm /etc/systemd/system/airsonic.service - fi [[ -d '/etc/systemd/system/airsonic.service.d' ]] && G_EXEC rm -R /etc/systemd/system/airsonic.service.d getent passwd airsonic > /dev/null && G_EXEC userdel airsonic @@ -14348,7 +14378,7 @@ _EOF_ systemctl unmask vncserver-virtuald 2> /dev/null systemctl disable --now vncserver-virtuald 2> /dev/null - apt-mark auto dbus-user-session 2> /dev/null + dpkg-query -s 'dbus-user-session' &> /dev/null && G_EXEC apt-mark auto dbus-user-session G_AGP 'tigervnc-*' x11vnc realvnc-vnc-server @@ -14377,7 +14407,7 @@ _EOF_ Banner_Uninstalling G_AGP fail2ban - dpkg-query -s python3-systemd &> /dev/null && G_EXEC apt-mark auto python3-systemd + dpkg-query -s 'python3-systemd' &> /dev/null && G_EXEC apt-mark auto python3-systemd [[ -d '/etc/fail2ban' ]] && G_EXEC rm -R /etc/fail2ban fi @@ -14515,9 +14545,9 @@ _EOF_ Banner_Uninstalling G_AGP tor - [[ -d '/var/log/tor' ]] && rm -R /var/log/tor # pre-v6.27 + [[ -d '/var/log/tor' ]] && G_EXEC rm -R /var/log/tor # pre-v6.27 - # Uninstall WIFIHOTSPOT ALSO. Due to IPtables needing reset + # Uninstall WiFi Hotspot too, due to IPtables needing reset aSOFTWARE_INSTALL_STATE[60]=-1 fi @@ -14769,20 +14799,23 @@ _EOF_ Banner_Uninstalling - if [[ -f '/etc/systemd/system/gogs.service' ]]; then - + # Service + if [[ -f '/etc/systemd/system/gogs.service' ]] + then G_EXEC systemctl disable --now gogs G_EXEC rm /etc/systemd/system/gogs.service - fi [[ -d '/etc/systemd/system/gogs.service.d' ]] && G_EXEC rm -R /etc/systemd/system/gogs.service.d + # User getent passwd gogs > /dev/null && G_EXEC userdel gogs getent group gogs > /dev/null && G_EXEC groupdel gogs + # Data [[ -d '/etc/gogs' ]] && G_EXEC rm -R /etc/gogs [[ -d '/var/log/gogs' ]] && G_EXEC rm -R /var/log/gogs + # Database systemctl start mariadb mysqladmin drop gogs -f mysql -e 'drop user gogs@localhost' @@ -14861,7 +14894,7 @@ _EOF_ # - Nginx [[ -f '/etc/nginx/sites-dietpi/dietpi-rutorrent.conf' ]] && G_EXEC rm /etc/nginx/sites-dietpi/dietpi-rutorrent.conf - # - Apache2 + # - Apache command -v a2dissite &> /dev/null && a2dissite dietpi-rutorrent [[ -f '/etc/apache2/sites-available/dietpi-rutorrent.conf' ]] && G_EXEC rm /etc/apache2/sites-available/dietpi-rutorrent.conf @@ -14921,10 +14954,12 @@ _EOF_ G_AGP 'chromium*' # Files [[ -d '/etc/chromium.d' ]] && G_EXEC rm -R /etc/chromium.d - [[ -f '/root/.chromium-browser.init' ]] && G_EXEC rm /root/.chromium-browser.init + G_EXEC rm -f /{root,home/*}/.chromium-browser.init [[ -f '/var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh' ]] && G_EXEC rm /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh # Autostart index: If currently Chromium, revert to console login [[ -f '/boot/dietpi/.dietpi-autostart_index' && $( /dev/null && G_EXEC userdel gitea + getent group gitea > /dev/null && G_EXEC groupdel gitea + + # Data [[ -d '/mnt/dietpi_userdata/gitea' ]] && G_EXEC rm -R /mnt/dietpi_userdata/gitea [[ -d '/var/log/gitea' ]] && G_EXEC rm -R /var/log/gitea - # Drop/delete database + # Database systemctl start mariadb mysqladmin drop gitea -f mysql -e 'drop user gitea@localhost' @@ -15157,7 +15195,7 @@ _EOF_ [[ -f '/etc/apt/trusted.gpg.d/dietpi-docker.gpg' ]] && G_EXEC rm /etc/apt/trusted.gpg.d/dietpi-docker.gpg # Service adjustments - [[ -d '/lib/systemd/system/docker.service.d' ]] && G_EXEC rm -R /lib/systemd/system/docker.service.d + [[ -d '/etc/systemd/system/docker.service.d' ]] && G_EXEC rm -R /etc/systemd/system/docker.service.d # DietPi data dir [[ -d '/mnt/dietpi_userdata/docker-data' ]] && G_EXEC rm -R /mnt/dietpi_userdata/docker-data # Default data dir @@ -15188,13 +15226,13 @@ _EOF_ Banner_Uninstalling - # Check if docker is still installed + # Check if Docker is still installed if [[ -d '/mnt/dietpi_userdata/docker-data' ]] then # Restart Docker service to be able to remove the container G_EXEC systemctl restart docker - # Remove portainer container, image & volume + # Remove Portainer container, image & volume local container=$(docker ps -a | mawk '/portainer\/portainer(-ce)?( |$)/{print $1;exit}') [[ $container ]] && G_EXEC docker rm -f "$container" local image=$(docker images -a | mawk '/portainer\/portainer(-ce)?( |$)/{print $3;exit}') @@ -15250,6 +15288,9 @@ _EOF_ Banner_Uninstalling G_AGP firefox-esr + # Update browser preference index + (( $INDEX_BROWSER == -1 )) && INDEX_BROWSER=0 + fi software_id=159 # Allo web UI @@ -15343,11 +15384,10 @@ _EOF_ Banner_Uninstalling - if [[ -f '/etc/systemd/system/komga.service' ]]; then - + if [[ -f '/etc/systemd/system/komga.service' ]] + then G_EXEC systemctl disable --now komga G_EXEC rm /etc/systemd/system/komga.service - fi [[ -d '/etc/systemd/system/komga.service.d' ]] && G_EXEC rm -R /etc/systemd/system/komga.service.d getent passwd komga > /dev/null && G_EXEC userdel komga @@ -15371,7 +15411,7 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - G_AGP jellyfin jellyfin-ffmpeg + G_AGP jellyfin 'jellyfin-*' [[ -f '/etc/apt/sources.list.d/dietpi-jellyfin.list' ]] && G_EXEC rm /etc/apt/sources.list.d/dietpi-jellyfin.list [[ -f '/etc/apt/trusted.gpg.d/dietpi-jellyfin.gpg' ]] && G_EXEC rm /etc/apt/trusted.gpg.d/dietpi-jellyfin.gpg [[ -d '/etc/systemd/system/jellyfin.service.d' ]] && G_EXEC rm -R /etc/systemd/system/jellyfin.service.d @@ -15471,8 +15511,8 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - # This also removes OpenSSH server. So lets check OpenSSH server isn't installed before hand. - dpkg-query -s 'openssh-server' &> /dev/null || G_AGP openssh-client + # The OpenSSH server depends on the OpenSSH client, hence only mark it for autoremoval only. + dpkg-query -s 'openssh-client' &> /dev/null && G_EXEC apt-mark auto openssh-client fi @@ -15669,6 +15709,28 @@ _EOF_ [[ -f '/usr/local/bin/mcrcon' ]] && G_EXEC rm /usr/local/bin/mcrcon fi + software_id=101 # Logrotate + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + + Banner_Uninstalling + G_AGP logrotate + + fi + + software_id=102 # Rsyslog + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + + Banner_Uninstalling + dpkg-query -s 'rsyslog' &> /dev/null && G_EXEC apt-mark auto rsyslog # https://github.com/MichaIng/DietPi/issues/2454 + + # Update logging choice index + if [[ $INDEX_LOGGING == -3 ]] + then + grep -q '[[:blank:]]/var/log[[:blank:]]' /etc/fstab || findmnt -t tmpfs -M /var/log > /dev/null && INDEX_LOGGING=-1 || INDEX_LOGGING=0 + fi + + fi + software_id=103 # DietPi-RAMlog if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then @@ -15683,6 +15745,12 @@ _EOF_ systemctl disable dietpi-ramlog systemctl stop dietpi-ramlog rm -R /var/tmp/dietpi/logs/dietpi-ramlog_store + if systemctl -q is-enabled rsyslog 2> /dev/null + then + sed -i '/^[[:blank:]]*INDEX_LOGGING=/c\INDEX_LOGGING=-3' /boot/dietpi/.installed + else + sed -i '/^[[:blank:]]*INDEX_LOGGING=/c\INDEX_LOGGING=0' /boot/dietpi/.installed + fi systemctl disable dietpi-ramlog_disable rm /etc/systemd/system/dietpi-ramlog_disable.service rm /var/lib/dietpi/dietpi-ramlog/disable.sh @@ -15709,23 +15777,6 @@ _EOF_ fi - software_id=101 # Logrotate - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then - - Banner_Uninstalling - G_AGP logrotate - - fi - - software_id=102 # Rsyslog - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then - - Banner_Uninstalling - G_DIETPI-NOTIFY 2 'Marking rsyslog for autoremoval, hence it stays installed if any other package depends on it' - apt-mark auto rsyslog 2> /dev/null # https://github.com/MichaIng/DietPi/issues/2454 - - fi - software_id=9 # Node.js if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then @@ -15773,8 +15824,8 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - command -v pip3 > /dev/null && G_EXEC_OUTPUT=1 G_EXEC pip3 uninstall -y pip - G_AGP python3-pip # Pre-v6.32 + 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 G_EXEC rm -Rf /{root,home/*}/.cache/pip @@ -15856,7 +15907,7 @@ _EOF_ # Uninstall finished, set all uninstalled software to state 0 (not installed) # - Apply same states to Allo and Allo_update (( ${aSOFTWARE_INSTALL_STATE[159]} == -1 || ${aSOFTWARE_INSTALL_STATE[160]} == -1 )) && { aSOFTWARE_INSTALL_STATE[159]=0; aSOFTWARE_INSTALL_STATE[160]=0; } - for i in "${!aSOFTWARE_INSTALL_STATE[@]}" + for i in "${!aSOFTWARE_NAME[@]}" do (( ${aSOFTWARE_INSTALL_STATE[$i]} == -1 )) && aSOFTWARE_INSTALL_STATE[$i]=0 done @@ -15864,37 +15915,10 @@ _EOF_ # apt-get autoremove G_AGA - # Check if we need to clear DietPi choices - local fp_temp='.dietpi-uninstall_dpkg' - dpkg --get-selections | mawk '{print $1}' > $fp_temp - if ! grep -qE '^(openssh-server|dropbear)' $fp_temp; then - - INDEX_SSHSERVER_CURRENT=0 - INDEX_SSHSERVER_TARGET=0 - - fi - - if ! grep -qE '^(samba$|proftpd-basic)' $fp_temp; then - - INDEX_FILESERVER_CURRENT=0 - INDEX_FILESERVER_TARGET=0 - - fi - - if ! grep -q '[[:blank:]]/var/log[[:blank:]]' /etc/fstab && ! grep -q '^rsyslog' $fp_temp; then - - INDEX_LOGGING_CURRENT=0 - INDEX_LOGGING_TARGET=0 - - fi - - rm $fp_temp - G_EXEC systemctl daemon-reload #---------------------------------------------------------------------- - # Done, reset uninstall flag - UNINSTALL_REQUIRED=0 + # Done G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Uninstall completed' #---------------------------------------------------------------------- @@ -15904,41 +15928,59 @@ _EOF_ G_NOTIFY_3_MODE='Step' #------------------------------------------------------------ - # Prevent continue if Network or NTPD is not completed: https://github.com/MichaIng/DietPi/issues/786 - Check_Net_and_Time_sync + G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Checking for conflicts and missing inputs' + + # Unmark software which requires user input during automated installs + Unmark_Unattended + + # Unmark software which loads kernel modules on install, if the loaded kernel version is not installed anymore + Unmark_On_Missing_Kernel_Modules + + # Unmark conflicting software if not done after interactive software selection already + (( $CONFLICTS_RESOLVED )) || Unmark_Conflicts + + # Abort install if no selections are left and not first run setup + if (( $G_DIETPI_INSTALL_STAGE == 2 )) + then + local abort=1 + for i in "${!aSOFTWARE_NAME[@]}" + do + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) || continue + abort=0 + break + done + (( $abort )) && { G_DIETPI-NOTIFY 1 'No software installs are done. Aborting...'; exit 1; } + fi #------------------------------------------------------------ # Disable powersaving on main screen during installation command -v setterm > /dev/null && setterm -blank 0 -powersave off 2> /dev/null - #------------------------------------------------------------ + + # Mark dependencies for install + Mark_Dependencies + + # Prevent continue if Network or NTPD is not completed: https://github.com/MichaIng/DietPi/issues/786 + Check_Net_and_Time_sync + # Unmask all services: https://github.com/MichaIng/DietPi/issues/1320 /boot/dietpi/dietpi-services unmask - # Stop services + + # Stop all services [[ $G_SERVICE_CONTROL == 0 ]] || /boot/dietpi/dietpi-services stop - #------------------------------------------------------------ - # Generate userdata folders - Create_UserContent_Folders - #------------------------------------------------------------ + # Update package cache G_AGUP # Full package upgrade on first run installs: https://github.com/MichaIng/DietPi/issues/3098 - (( $G_DIETPI_INSTALL_STAGE == 2 )) || G_AGDUG - - # Unmark software installs for automated installs, if user input is required - Unmark_Unattended - - # Apply DietPi choice systems - Apply_FileServer_Choices - Apply_SSHServer_Choices - Apply_Logging_Choices + if (( $G_DIETPI_INSTALL_STAGE != 2 )) + then + G_AGDUG - # Apply DietPi preference systems - INDEX_WEBSERVER_CURRENT=$INDEX_WEBSERVER_TARGET - INDEX_DESKTOP_CURRENT=$INDEX_DESKTOP_TARGET - INDEX_BROWSER_CURRENT=$INDEX_BROWSER_TARGET + # Check again for missing kernel modules after full package upgrade + Unmark_On_Missing_Kernel_Modules + fi - # Mark dependencies for install - Mark_Dependencies + # Pre-create directories which are required for many software installs + Create_Required_Dirs # Read global software password Update_Global_Pw @@ -15947,7 +15989,12 @@ _EOF_ Install_Software # Uninstall software, if required by e.g. DietPi choice system - (( $UNINSTALL_REQUIRED )) && Uninstall_Software + for i in "${!aSOFTWARE_NAME[@]}" + do + (( ${aSOFTWARE_INSTALL_STATE[$i]} == -1 )) || continue + Uninstall_Software + break + done G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Finalising install' @@ -16005,13 +16052,13 @@ This requires an account at: https://remote.it/ # Install finished, set all installed software to state 2 (installed) # - Apply same states to Allo and Allo_update - (( ${aSOFTWARE_INSTALL_STATE[159]} == 1 || ${aSOFTWARE_INSTALL_STATE[160]} == 1 )) && { aSOFTWARE_INSTALL_STATE[159]=2 aSOFTWARE_INSTALL_STATE[160]=2; } + (( ${aSOFTWARE_INSTALL_STATE[159]} == 1 || ${aSOFTWARE_INSTALL_STATE[160]} == 1 )) && aSOFTWARE_INSTALL_STATE[159]=2 aSOFTWARE_INSTALL_STATE[160]=2 for i in "${!aSOFTWARE_NAME[@]}" do (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && aSOFTWARE_INSTALL_STATE[$i]=2 done - # Write to .install File + # Write to .installed state file Write_InstallFileList } @@ -16029,23 +16076,23 @@ This requires an account at: https://remote.it/ # Get settings AUTOINSTALL_ENABLED=$(sed -n '/^[[:blank:]]*AUTO_SETUP_AUTOMATED=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) AUTOINSTALL_AUTOSTARTTARGET=$(sed -n '/^[[:blank:]]*AUTO_SETUP_AUTOSTART_TARGET_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_SSHINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_SSH_SERVER_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_FILESERVERINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_FILE_SERVER_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_LOGGINGINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_LOGGING_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_WEBSERVERINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_WEB_SERVER_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_DESKTOPINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_DESKTOP_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_BROWSERINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_BROWSER_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + local AUTOINSTALL_SSHINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_SSH_SERVER_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + local AUTOINSTALL_FILESERVERINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_FILE_SERVER_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) # pre-v7.9 + local AUTOINSTALL_LOGGINGINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_LOGGING_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + local AUTOINSTALL_WEBSERVERINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_WEB_SERVER_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + local AUTOINSTALL_DESKTOPINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_DESKTOP_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + local AUTOINSTALL_BROWSERINDEX=$(sed -n '/^[[:blank:]]*AUTO_SETUP_BROWSER_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) AUTOINSTALL_CUSTOMSCRIPTURL=$(sed -n '/^[[:blank:]]*AUTO_SETUP_CUSTOM_SCRIPT_EXEC=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_TIMESYNCMODE=$(sed -n '/^[[:blank:]]*CONFIG_NTP_MODE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_RESTORE=$(sed -n '/^[[:blank:]]*AUTO_SETUP_BACKUP_RESTORE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - AUTOINSTALL_RAMLOG_SIZE=$(sed -n '/^[[:blank:]]*AUTO_SETUP_RAMLOG_MAXSIZE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + local AUTOINSTALL_TIMESYNCMODE=$(sed -n '/^[[:blank:]]*CONFIG_NTP_MODE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + local AUTOINSTALL_RESTORE=$(sed -n '/^[[:blank:]]*AUTO_SETUP_BACKUP_RESTORE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + local AUTOINSTALL_RAMLOG_SIZE=$(sed -n '/^[[:blank:]]*AUTO_SETUP_RAMLOG_MAXSIZE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) AUTO_SETUP_DHCP_TO_STATIC=$(sed -n '/^[[:blank:]]*AUTO_SETUP_DHCP_TO_STATIC=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) # Else set defaults [[ $AUTOINSTALL_ENABLED ]] || AUTOINSTALL_ENABLED=0 [[ $AUTOINSTALL_AUTOSTARTTARGET ]] || AUTOINSTALL_AUTOSTARTTARGET=0 [[ $AUTOINSTALL_SSHINDEX ]] || AUTOINSTALL_SSHINDEX=-1 - [[ $AUTOINSTALL_FILESERVERINDEX ]] || AUTOINSTALL_FILESERVERINDEX=0 + [[ $AUTOINSTALL_FILESERVERINDEX ]] || AUTOINSTALL_FILESERVERINDEX=0 # pre-v7.9 [[ $AUTOINSTALL_LOGGINGINDEX ]] || AUTOINSTALL_LOGGINGINDEX=-1 [[ $AUTOINSTALL_WEBSERVERINDEX ]] || AUTOINSTALL_WEBSERVERINDEX=-2 [[ $AUTOINSTALL_DESKTOPINDEX ]] || AUTOINSTALL_DESKTOPINDEX=0 @@ -16154,45 +16201,42 @@ This requires an account at: https://remote.it/ fi # Disable serial console? - local keep_serial0=1 - if grep -q '^[[:blank:]]*CONFIG_SERIAL_CONSOLE_ENABLE=1' /boot/dietpi.txt && + if ! grep -q '^[[:blank:]]*CONFIG_SERIAL_CONSOLE_ENABLE=0' /boot/dietpi.txt && [[ ! $(readlink -f /proc/$$/fd/1) =~ ^/dev/tty(S|AMA|SAC)[0-9]$ ]] && G_WHIP_YESNO 'A serial console is currently enabled, would you like to disable it? - - Disabling serial console will reduce memory consumption slightly. - - If you are unsure on what a serial console is, it is safe to disable it. + - Disabling the serial console will reduce memory consumption slightly. + - If you are unsure what a serial console is, it is safe to disable it. - But if this is a headless device and it is difficult or impossible to attach a screen and keyboard, we recommend to leave it enabled so that you can debug and fix early boot issues or when the network/SSH server is not coming up. All you need is a serial USB adapter cable and a notebook with e.g. PuTTY.' then /boot/dietpi/func/dietpi-set_hardware serialconsole disable - keep_serial0=0 fi - # RPi: Convert "serial0" to its actual symlink target - if (( $G_HW_MODEL < 10 && $keep_serial0 )); then - - if [[ -L '/dev/serial0' ]]; then - + # RPi: Convert "serial0" to its actual symlink target without breaking the possibly currently used serial connection or starting a doubled console on the same serial device. + if (( $G_HW_MODEL < 10 )) + then + if [[ -e '/dev/serial0' ]] && ! grep -q '^[[:blank:]]*CONFIG_SERIAL_CONSOLE_ENABLE=0' /boot/dietpi.txt + then local tty=$(readlink -f /dev/serial0); tty=${tty#/dev/} - if [[ $( 0 )); then + G_WHIP_INPUTBOX 'Please enter a software title, index or keyword to search, e.g.: desktop/cloud/media/torrent' || return 0 - selected='on' - (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && aSOFTWARE_INSTALL_STATE[$i]=0 # Reset pending state to 0. Menu checklists will apply back to 1 - - fi + G_WHIP_CHECKLIST_ARRAY=() + for i in "${!aSOFTWARE_NAME[@]}" + do + if (( ${aSOFTWARE_AVAIL_G_HW_MODEL[$i,$G_HW_MODEL]:=1} && ${aSOFTWARE_AVAIL_G_HW_ARCH[$i,$G_HW_ARCH]:=1} && ${aSOFTWARE_AVAIL_G_DISTRO[$i,$G_DISTRO]:=1} )) && + [[ $G_WHIP_RETURNED_VALUE == "$i" || ${aSOFTWARE_NAME[$i],,} == *"${G_WHIP_RETURNED_VALUE,,}"* || ${aSOFTWARE_DESC[$i],,} == *"${G_WHIP_RETURNED_VALUE,,}"* ]]; then - # Add this software title to whiptail menu - G_WHIP_CHECKLIST_ARRAY+=("$i" "${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" "$selected") + # Set checkbox selection based on install state + local selected='off' + if (( ${aSOFTWARE_INSTALL_STATE[$i]} > 0 )); then - # Result was found, hence display checklist - display_software_menu=1 + selected='on' + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && aSOFTWARE_INSTALL_STATE[$i]=0 # Reset pending state to 0. Menu checklists will apply back to 1 fi - done - (( $display_software_menu )) || G_WHIP_MSG "Search was unable to find any items for \"$G_WHIP_RETURNED_VALUE\"" + # Add this software title to whiptail menu + G_WHIP_CHECKLIST_ARRAY+=("$i" "${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" "$selected") - fi + fi + done + + (( ${#G_WHIP_CHECKLIST_ARRAY[@]} )) || { G_WHIP_MSG "We couldn't find any available software title for the search term: \"$G_WHIP_RETURNED_VALUE\""; return 0; } # Generate whiptail menu list of all software titles, sorted by category else @@ -16628,50 +16674,51 @@ This requires an account at: https://remote.it/ fi - if (( $display_software_menu )); then - - G_WHIP_SIZE_X_MAX=93 # Assure this is enough to show full software descriptions + scroll bar - G_WHIP_BUTTON_CANCEL_TEXT='Back' - G_WHIP_CHECKLIST 'Please use the spacebar to select the software you wish to install. Then press ENTER/RETURN or select "Ok" to confirm. - - Pressing ESC or selecting "Back" will clear all changed selections. + G_WHIP_SIZE_X_MAX=93 # Assure this is enough to show full software descriptions + scroll bar + G_WHIP_BUTTON_CANCEL_TEXT='Back' + G_WHIP_CHECKLIST 'Please use the spacebar to select the software you wish to install. Then press ENTER/RETURN to confirm. + - Pressing ESC will clear all changed selections. - Software and usage details: https://dietpi.com/docs/software/' || return 0 - # Reset flag - INSTALL_SOFTWARE_CHOICESMADE=0 + # Check for selected items + for i in $G_WHIP_RETURNED_VALUE + do + # Skip already installed items + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 2 )) && continue + # Mark newly selected items for install + aSOFTWARE_INSTALL_STATE[$i]=1 + done - # Check for selected items - for i in $G_WHIP_RETURNED_VALUE - do - # Skip already installed items - (( ${aSOFTWARE_INSTALL_STATE[$i]} == 2 )) && continue - # Selected and not installed item found, mark for install and set flag - aSOFTWARE_INSTALL_STATE[$i]=1 - INSTALL_SOFTWARE_CHOICESMADE=1 - done + # Unmark software which loads kernel modules on install, if the loaded kernel version is not installed anymore + Unmark_On_Missing_Kernel_Modules + + # Unmark conflicting software + Unmark_Conflicts - #----------------------------------------------------------------------------- - # Install info/warnings/inputs + #----------------------------------------------------------------------------- + # Install info/warnings/inputs - # DietPi-Drive_Manager can be used to setup Samba/NFS shares with ease! - if (( ${aSOFTWARE_INSTALL_STATE[1]} == 1 || ${aSOFTWARE_INSTALL_STATE[110]} == 1 )); then + # DietPi-Drive_Manager can be used to setup Samba/NFS shares with ease! + if (( ${aSOFTWARE_INSTALL_STATE[1]} == 1 || ${aSOFTWARE_INSTALL_STATE[110]} == 1 )); then - G_WHIP_MSG "NFS/Samba client info:\n\nDietPi-Drive_Manager is a powerful tool which vastly simplifies the mounting of NFS and Samba shares. + G_WHIP_MSG "[ INFO ] Mount NFS/Samba shares via DietPi-Drive_Manager +\nDietPi-Drive_Manager is a powerful tool which vastly simplifies the mounting of NFS and Samba shares. \nOnce $G_PROGRAM_NAME has finished installation, simply run 'dietpi-drive_manager' to setup required network mounts." - fi + fi - # PaperMC: Inform user about long install/startup time and possible swap file usage - if (( ${aSOFTWARE_INSTALL_STATE[181]} == 1 )) - then - local swap_info= - (( $RAM_PHYS < 924 )) && swap_info='\n\nThe server will be started with with minimal required memory usage, but a swap file will be created to assure that no out-of-memory crash can happen. + # PaperMC: Inform user about long install/startup time and possible swap file usage + if (( ${aSOFTWARE_INSTALL_STATE[181]} == 1 )) + then + local swap_info= + (( $RAM_PHYS < 924 )) && swap_info='\n\nThe server will be started with with minimal required memory usage, but a swap file will be created to assure that no out-of-memory crash can happen. On servers with less than 1 GiB physical memory, we strongly recommend to move the swap file to an external drive, if your system runs on an SD card, since during normal PaperMC operation this swap space will be heavily used.' - G_WHIP_MSG "PaperMC will be started during install to allow pre-configuring it's default configuration files. Especially on smaller SBCs, like Raspberry Pi Zero, this can take a long time. + G_WHIP_MSG "PaperMC will be started during install to allow pre-configuring it's default configuration files. Especially on smaller SBCs, like Raspberry Pi Zero, this can take a long time. We allow it to take up to 30 minutes, it's process can be followed, please be patient.$swap_info" - fi + fi - # mjpg-streamer: Warn about unprotected stream and inform about additional plugins - (( ${aSOFTWARE_INSTALL_STATE[137]} == 1 )) && G_WHIP_MSG '[ WARN ] The mjpg-streamer camera stream will be accessible unprotected at port 8082 by default. + # mjpg-streamer: Warn about unprotected stream and inform about additional plugins + (( ${aSOFTWARE_INSTALL_STATE[137]} == 1 )) && G_WHIP_MSG '[ WARN ] The mjpg-streamer camera stream will be accessible unprotected at port 8082 by default. \nYou can configure a password protection, but this will break embedding the stream into other web interfaces, like OctoPrint. \nWe hence recommend to not forward port 8082 through your NAT and/or block public access via firewall. \nIf you require access from outside your local network to a web interface that embeds the camera stream, we recommend to setup a VPN connection for this. @@ -16680,206 +16727,140 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa \nIf you require other input or output plugins, simply install the required dependencies. Plugins will be compiled automatically if dependencies are met. \nFor available plugins and their dependencies, watch the info printed during the build and check out the official GitHub repository: https://github.com/jacksonliam/mjpg-streamer' - # Gogs: Requires OpenSSH for ssh-keygen binary: https://github.com/MichaIng/DietPi/issues/442 - if (( ${aSOFTWARE_INSTALL_STATE[49]} == 1 && $INDEX_SSHSERVER_TARGET != -2 )); then - - if G_WHIP_YESNO "Gogs requires OpenSSH server to function.\n\nIf you continue, OpenSSH will be selected for install on your system. OpenSSH will also replace Dropbear (if currently installed). -\nWould you like to continue with the Gogs installation?"; then - - # Use SSH target index to ensure Dropbear gets removed if installed. - INDEX_SSHSERVER_TARGET=-2 - - else - - aSOFTWARE_INSTALL_STATE[49]=0 - - fi - - fi - - # Webserver stacks - for i in 75 76 78 79 81 82 - do - # Please let DietPi install them for you... - (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) || continue - - G_WHIP_MSG 'DietPi will automatically install a webserver stack (based on your Webserver Preference) when any software that requires a webserver is selected for installation (eg: ownCloud, Pi-hole etc). -\nIt is highly recommended that you allow DietPi to do this for you, ensuring compatibility and stability across DietPi installed programs.\n\nPlease only select a webserver stack if you specifically require it, and, no other webserver stack is installed. -\nTLDR: You do NOT need to select a webserver stack for installation with DietPi. Its all automatic.' - - break - done - - # RPi Cam Interface: Warn user of locking out camera: https://github.com/MichaIng/DietPi/issues/249 - (( ${aSOFTWARE_INSTALL_STATE[59]} == 1 )) && G_WHIP_MSG 'RPi Cam Control Interface will automatically start and activate the camera during boot. This will prevent other programs (like raspistill) from using the camera. + # RPi Cam Interface: Warn user of locking out camera: https://github.com/MichaIng/DietPi/issues/249 + (( ${aSOFTWARE_INSTALL_STATE[59]} == 1 )) && G_WHIP_MSG 'RPi Cam Control Interface will automatically start and activate the camera during boot. This will prevent other programs (like raspistill) from using the camera. \nYou can free up the camera by selecting "Stop Camera" from the web interface:\n - http://myip/rpicam' - # Avoid having AdGuard Home installed in parallel to Pi-hole - if (( ${aSOFTWARE_INSTALL_STATE[93]} > 0 )) && (( ${aSOFTWARE_INSTALL_STATE[126]} > 0 )) - then - # AdGuard Home selected together with Pi-hole - if (( ${aSOFTWARE_INSTALL_STATE[93]} == 1 )) && (( ${aSOFTWARE_INSTALL_STATE[126]} == 1 )) - then - (( ${aSOFTWARE_INSTALL_STATE[126]} == 1 )) && aSOFTWARE_INSTALL_STATE[126]=0 - G_WHIP_MSG 'AdGuard Home selected together with Pi-hole. AdGuard Home will be unselected.' - - # AdGuard Home already installed - elif (( ${aSOFTWARE_INSTALL_STATE[126]} == 2 )) - then - (( ${aSOFTWARE_INSTALL_STATE[93]} == 1 )) && aSOFTWARE_INSTALL_STATE[93]=0 - G_WHIP_MSG 'AdGuard Home already installed. Pi-hole will be unselected.' - - # Pi-hole already installed - else - (( ${aSOFTWARE_INSTALL_STATE[126]} == 1 )) && aSOFTWARE_INSTALL_STATE[126]=0 - G_WHIP_MSG 'Pi-hole already installed. AdGuard Home will be unselected.' - fi - fi - - # Offer to install Unbound along with AdGuard Home and Pi-hole - if (( ${aSOFTWARE_INSTALL_STATE[93]} == 1 || ${aSOFTWARE_INSTALL_STATE[126]} == 1 )) + # Offer to install Unbound along with AdGuard Home and Pi-hole + if (( ${aSOFTWARE_INSTALL_STATE[93]} == 1 || ${aSOFTWARE_INSTALL_STATE[126]} == 1 )) + then + # Add option to use Unbound as upstream DNS server + if (( ${aSOFTWARE_INSTALL_STATE[182]} == 0 )) then - # Add option to use Unbound as upstream DNS server - if (( ${aSOFTWARE_INSTALL_STATE[182]} == 0 )) - then - G_WHIP_YESNO 'Would you like to use Unbound, a tiny recursive DNS server hosted on your device, as your upstream DNS server? + G_WHIP_YESNO 'Would you like to use Unbound, a tiny recursive DNS server hosted on your device, as your upstream DNS server? \nThis will increase privacy, because you will not be sending data to Google etc. \nHowever, the downside is that some websites may load slower the first time you visit them.' && aSOFTWARE_INSTALL_STATE[182]=1 - fi + fi - # Prompt for static IP - if G_WHIP_YESNO 'A static IP address is essential for a DNS server installations. DietPi-Config can be used to quickly setup your static IP address. + # Prompt for static IP + if G_WHIP_YESNO 'A static IP address is essential for a DNS server installations. DietPi-Config can be used to quickly setup your static IP address. \nIf you have already setup your static IP, please ignore this message.\n\nWould you like to setup your static IP address now?' - then - G_WHIP_MSG 'DietPi-Config will now be launched. Simply select your Ethernet or Wifi connection from the menu to access the IP address settings. + then + G_WHIP_MSG 'DietPi-Config will now be launched. Simply select your Ethernet or Wifi connection from the menu to access the IP address settings. \nThe "copy current address to STATIC" menu option can be used to quickly setup your static IP. Please ensure you change the mode "DHCP" to "STATIC". \nOnce completed, select "Apply Save Changes", then exit DietPi-Config to resume setup.' - /boot/dietpi/dietpi-config 8 1 - fi + /boot/dietpi/dietpi-config 8 1 fi + fi - # WiFi Hotspot Criteria - if (( ${aSOFTWARE_INSTALL_STATE[60]} == 1 || ${aSOFTWARE_INSTALL_STATE[61]} == 1 )); then + # WiFi Hotspot Criteria + if (( ${aSOFTWARE_INSTALL_STATE[60]} == 1 || ${aSOFTWARE_INSTALL_STATE[61]} == 1 )); then - # Enable WiFi modules - /boot/dietpi/func/dietpi-set_hardware wifimodules enable + # Enable WiFi modules + /boot/dietpi/func/dietpi-set_hardware wifimodules enable - while : - do - local criteria_passed=1 - local output_string='The following criteria must be met for the installation of WiFi Hotspot to succeed:' + while : + do + local criteria_passed=1 + local output_string='The following criteria must be met for the installation of WiFi Hotspot to succeed:' - if [[ $(G_GET_NET -q -t eth ip) ]]; then + if [[ $(G_GET_NET -q -t eth ip) ]]; then - output_string+='\n\n - Ethernet online: PASSED' + output_string+='\n\n - Ethernet online: PASSED' - else + else - criteria_passed=0 - output_string+='\n\n - Ethernet online: FAILED.\nUse dietpi-config to connect and configure Ethernet.' + criteria_passed=0 + output_string+='\n\n - Ethernet online: FAILED.\nUse dietpi-config to connect and configure Ethernet.' - fi + fi - if [[ $(G_GET_NET -q -t wlan iface) ]]; then + if [[ $(G_GET_NET -q -t wlan iface) ]]; then - output_string+='\n\n - WiFi adapter detected: PASSED' + output_string+='\n\n - WiFi adapter detected: PASSED' - else + else - criteria_passed=0 - output_string+='\n\n - WiFi adapter detected: FAILED.\nPlease connect a WiFi adapter and try again.' + criteria_passed=0 + output_string+='\n\n - WiFi adapter detected: FAILED.\nPlease connect a WiFi adapter and try again.' - fi + fi - # Passed - if (( $criteria_passed )); then + # Passed + if (( $criteria_passed )); then - output_string+='\n\nPASSED: Criteria met. Good to go.' - G_WHIP_MSG "$output_string" - break + output_string+='\n\nPASSED: Criteria met. Good to go.' + G_WHIP_MSG "$output_string" + break - # Failed, retry? - else + # Failed, retry? + else - output_string+='\n\nFAILED: Criteria not met. Would you like to check again?' - G_WHIP_YESNO "$output_string" && continue + output_string+='\n\nFAILED: Criteria not met. Would you like to check again?' + G_WHIP_YESNO "$output_string" && continue - (( ${aSOFTWARE_INSTALL_STATE[60]} == 1 )) && aSOFTWARE_INSTALL_STATE[60]=0 - (( ${aSOFTWARE_INSTALL_STATE[61]} == 1 )) && aSOFTWARE_INSTALL_STATE[61]=0 - G_WHIP_MSG 'WiFi Hotspot criteria were not met. The software will not be installed.' - break + (( ${aSOFTWARE_INSTALL_STATE[60]} == 1 )) && aSOFTWARE_INSTALL_STATE[60]=0 + (( ${aSOFTWARE_INSTALL_STATE[61]} == 1 )) && aSOFTWARE_INSTALL_STATE[61]=0 + G_WHIP_MSG 'WiFi Hotspot criteria were not met. The software will not be installed.' + break - fi - done + fi + done - fi + fi - # Let's Encrypt - (( ${aSOFTWARE_INSTALL_STATE[92]} == 1 )) && G_WHIP_MSG 'The DietPi installation of Certbot supports all offered web servers.\n\nOnce the installation has finished, you can setup your free SSL cert with: - - DietPi-LetsEncrypt\n\nThis is a easy to use frontend for Certbot and allows integration into DietPi systems.\n\nMore information:\n - https://dietpi.com/docs/software/system_security/#lets-encrypt' + # Let's Encrypt + (( ${aSOFTWARE_INSTALL_STATE[92]} == 1 )) && G_WHIP_MSG 'The DietPi installation of Certbot supports all offered web servers.\n\nOnce the installation has finished, you can setup your free SSL cert with: + - DietPi-LetsEncrypt\n\nThis is an easy to use frontend for Certbot and allows integration into DietPi systems.\n\nMore information:\n - https://dietpi.com/docs/software/system_security/#lets-encrypt' - # Box86 warning - (( ${aSOFTWARE_INSTALL_STATE[156]} == 1 && $G_HW_ARCH == 2 )) && G_WHIP_MSG 'WARNING: The piece of software you are about to install is meant for the x86 platform.\n\nBox86 will be used to run it on ARM, however there may be performance and compatibility issues.' + # Steam on ARMv7 via Box86 warning + (( ${aSOFTWARE_INSTALL_STATE[156]} == 1 && $G_HW_ARCH == 2 )) && G_WHIP_MSG '[WARNING] Steam natively only runs on the x86 systems.\n\nBox86 will be used to run it on ARM, however there may be performance and compatibility issues.' - # Home Assistant: Inform about long install/build time: https://github.com/MichaIng/DietPi/issues/2897 - (( ${aSOFTWARE_INSTALL_STATE[157]} == 1 )) && G_WHIP_MSG '[ INFO ] Home Assistant: Grab yourself a coffee + # Home Assistant: Inform about long install/build time: https://github.com/MichaIng/DietPi/issues/2897 + (( ${aSOFTWARE_INSTALL_STATE[157]} == 1 )) && G_WHIP_MSG '[ INFO ] Home Assistant: Grab yourself a coffee \nThe install process of Home Assistant within the virtual environment, especially the Python build, can take more than one hour, especially on slower SBCs like RPi Zero and similar. \nPlease be patient. In the meantime you may study the documentation: - https://dietpi.com/docs/software/home_automation/#home-assistant' - fi - } Menu_Main(){ # Selected SSH server choice - local index_sshserver_text='None' - if (( $INDEX_SSHSERVER_TARGET == -1 )); then + local sshserver_text='None' + if (( ${aSOFTWARE_INSTALL_STATE[104]} > 0 )); then - index_sshserver_text=${aSOFTWARE_NAME[104]} # Dropbear + sshserver_text=${aSOFTWARE_NAME[104]} # Dropbear - elif (( $INDEX_SSHSERVER_TARGET == -2 )); then + elif (( ${aSOFTWARE_INSTALL_STATE[105]} > 0 )); then - index_sshserver_text=${aSOFTWARE_NAME[105]} # OpenSSH - - fi - - # Selected file server choice - local index_fileserver_text='None' - if (( $INDEX_FILESERVER_TARGET == -1 )); then - - index_fileserver_text=${aSOFTWARE_NAME[94]} # ProFTPD - - elif (( $INDEX_FILESERVER_TARGET == -2 )); then - - index_fileserver_text=${aSOFTWARE_NAME[96]} # Samba + sshserver_text=${aSOFTWARE_NAME[105]} # OpenSSH fi # Selected logging system choice local index_logging_text='None' - if (( $INDEX_LOGGING_TARGET == -1 )); then + if (( $INDEX_LOGGING == -1 )); then index_logging_text='DietPi-RAMlog #1' - elif (( $INDEX_LOGGING_TARGET == -2 )); then + elif (( $INDEX_LOGGING == -2 )); then index_logging_text='DietPi-RAMlog #2' - elif (( $INDEX_LOGGING_TARGET == -3 )); then + elif (( $INDEX_LOGGING == -3 )); then index_logging_text='Full' fi # Selected webserver preference - local index_webserver_text=${aSOFTWARE_NAME[83]} # Apache2 - if (( $INDEX_WEBSERVER_TARGET == -1 )); then + local index_webserver_text=${aSOFTWARE_NAME[83]} # Apache + if (( $INDEX_WEBSERVER == -1 )); then index_webserver_text=${aSOFTWARE_NAME[85]} # Nginx - elif (( $INDEX_WEBSERVER_TARGET == -2 )); then + elif (( $INDEX_WEBSERVER == -2 )); then index_webserver_text=${aSOFTWARE_NAME[84]} # Lighttpd @@ -16887,19 +16868,19 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa # Selected desktop preference local index_desktop_text=${aSOFTWARE_NAME[23]} # LXDE - if (( $INDEX_DESKTOP_TARGET == -1 )); then + if (( $INDEX_DESKTOP == -1 )); then index_desktop_text=${aSOFTWARE_NAME[25]} # Xfce - elif (( $INDEX_DESKTOP_TARGET == -2 )); then + elif (( $INDEX_DESKTOP == -2 )); then index_desktop_text=${aSOFTWARE_NAME[24]} # MATE - elif (( $INDEX_DESKTOP_TARGET == -3 )); then + elif (( $INDEX_DESKTOP == -3 )); then index_desktop_text=${aSOFTWARE_NAME[173]} # LXQt - elif (( $INDEX_DESKTOP_TARGET == -4 )); then + elif (( $INDEX_DESKTOP == -4 )); then index_desktop_text=${aSOFTWARE_NAME[26]} # GNUstep @@ -16907,11 +16888,11 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa # Selected browser preference local index_browser_text='None' - if (( $INDEX_BROWSER_TARGET == -1 )); then + if (( $INDEX_BROWSER == -1 )); then index_browser_text=${aSOFTWARE_NAME[67]} # Firefox - elif (( $INDEX_BROWSER_TARGET == -2 )); then + elif (( $INDEX_BROWSER == -2 )); then index_browser_text=${aSOFTWARE_NAME[113]} # Chromium @@ -16931,8 +16912,8 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa fi - # Automatically uninstalled software based on choice system - local toberemoved_text + # Software to be installed or removed based on choice system + local tobeinstalled_text toberemoved_text G_WHIP_MENU_ARRAY=( @@ -16941,8 +16922,7 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa '' '●─ Select Software ' 'Search Software' ': Find software to install via search box' 'Browse Software' ': Select software from the full list' - 'SSH Server' ": [$index_sshserver_text]" - 'File Server' ": [$index_fileserver_text]" + 'SSH Server' ": [$sshserver_text]" 'Log System' ": [$index_logging_text]" 'Webserver Preference' ": [$index_webserver_text]" 'Desktop Preference' ": [$index_desktop_text]" @@ -16979,95 +16959,32 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa ) - G_WHIP_DEFAULT_ITEM=$index_sshserver_text + G_WHIP_DEFAULT_ITEM=$sshserver_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Please select desired SSH server: + G_WHIP_MENU 'Please select desired SSH server: \n- None: Selecting this option will uninstall all SSH servers. This reduces system resources and improves performance. Useful for users who do NOT require networked/remote terminal access. \n- Dropbear (recommended): Lightweight SSH server, installed by default on DietPi systems. -\n- OpenSSH: A feature-rich SSH server with SFTP/SCP support, at the cost of increased resource usage.'; then - - # Assign target index - if [[ $G_WHIP_RETURNED_VALUE == 'None' ]]; then - - INDEX_SSHSERVER_TARGET=0 - toberemoved_text="${aSOFTWARE_NAME[104]} and ${aSOFTWARE_NAME[105]}" - - elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[104]}" ]]; then - - INDEX_SSHSERVER_TARGET=-1 - toberemoved_text=${aSOFTWARE_NAME[105]} - - elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[105]}" ]]; then - - INDEX_SSHSERVER_TARGET=-2 - toberemoved_text=${aSOFTWARE_NAME[104]} - - # Reset to current - else - - INDEX_SSHSERVER_TARGET=$INDEX_SSHSERVER_CURRENT - - fi - - fi - - # Check for changes - INSTALL_SSHSERVER_CHOICESMADE=0 - if (( $INDEX_SSHSERVER_TARGET != $INDEX_SSHSERVER_CURRENT )); then - - INSTALL_SSHSERVER_CHOICESMADE=1 - G_WHIP_MSG "$G_WHIP_RETURNED_VALUE has been selected:\n- Your choice will be applied when 'Install Go >> Start installation' is selected.\n- $toberemoved_text installations will be automatically uninstalled." - - fi +\n- OpenSSH: A feature-rich SSH server with SFTP/SCP support, at the cost of increased resource usage.' || return 0 - ;; - - 'File Server') - - G_WHIP_MENU_ARRAY=( - - 'None' ': Not required / manual setup' - "${aSOFTWARE_NAME[94]}" ": ${aSOFTWARE_DESC[94]} (recommended)" - "${aSOFTWARE_NAME[96]}" ": ${aSOFTWARE_DESC[96]}" - - ) + # Apply selection + case "$G_WHIP_RETURNED_VALUE" in - G_WHIP_DEFAULT_ITEM=$index_fileserver_text - G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Please select desired fileserver: -\n- None: Select this option if you do NOT require a method of accessing files and folders on this device, over a network. -\n- ProFTPD (recommended for RPi v1): Allows you to access/share files on this device efficiently with minimal CPU usage. Uses FTP protocol. -\n- Samba (recommended for RPi v2): Allows you to easily access/share files on this device, at the cost of higher CPU usage. -\nMore info: https://dietpi.com/docs/dietpi_tools/#quick-selections'; then - - # Assign target index - if [[ $G_WHIP_RETURNED_VALUE == 'None' ]]; then - - INDEX_FILESERVER_TARGET=0 - toberemoved_text="${aSOFTWARE_NAME[94]} and ${aSOFTWARE_NAME[96]}" - - elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[94]}" ]]; then - - INDEX_FILESERVER_TARGET=-1 - toberemoved_text=${aSOFTWARE_NAME[96]} - - elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[96]}" ]]; then - - INDEX_FILESERVER_TARGET=-2 - toberemoved_text=${aSOFTWARE_NAME[94]} - - fi - - fi + 'None') Apply_SSHServer_Choices 0;; + "${aSOFTWARE_NAME[105]}") Apply_SSHServer_Choices -2;; + *) Apply_SSHServer_Choices -1;; + esac # Check for changes - INSTALL_FILESERVER_CHOICESMADE=0 - if (( $INDEX_FILESERVER_TARGET != $INDEX_FILESERVER_CURRENT )); then - - INSTALL_FILESERVER_CHOICESMADE=1 - G_WHIP_MSG "$G_WHIP_RETURNED_VALUE has been selected:\n- Your choice will be applied when 'Install Go >> Start installation' is selected.\n- $toberemoved_text installations will be automatically uninstalled." + for i in 104 105 + do + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && tobeinstalled_text+="\n - ${aSOFTWARE_NAME[$i]}" + (( ${aSOFTWARE_INSTALL_STATE[$i]} == -1 )) && toberemoved_text+="\n - ${aSOFTWARE_NAME[$i]}" + done + [[ $tobeinstalled_text || $toberemoved_text ]] || return 0 + [[ $tobeinstalled_text ]] && tobeinstalled_text="\n\nThe following software will be installed:$tobeinstalled_text" + [[ $toberemoved_text ]] && toberemoved_text="\n\nThe following software will be uninstalled:$toberemoved_text" - fi + G_WHIP_MSG "$G_WHIP_RETURNED_VALUE has been selected:\n- Your choice will be applied when 'Install Go >> Start installation' is selected.$tobeinstalled_text$toberemoved_text" ;; @@ -17084,45 +17001,33 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa G_WHIP_DEFAULT_ITEM=$index_logging_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Please select desired logging system: -\n- None: Selecting this option will uninstall DietPi-RAMlog, Logrotate, Rsyslog. -\n- DietPi-RAMlog #1 (Max performance): Mounts /var/log to RAM, reducing filesystem IO. Logfiles are cleared every hour. Does NOT save logfiles to disk. -\n- DietPi-RAMlog #2: Same as #1, with the added feature of saving logfile contents to disk (/root/logfile_storage/*), before being cleared. -\n- Full (Reduces performance): Mounts /var/log to DISK, reduces SDcard lifespan. Full logging system with Logrotate and Rsyslog.'; then - - # Assign target index - if [[ $G_WHIP_RETURNED_VALUE == 'None' ]]; then + G_WHIP_MENU 'Please select desired logging system: +\n- None: Selecting this option will uninstall DietPi-RAMlog, Logrotate and Rsyslog. +\n- DietPi-RAMlog #1 (Max performance): Mounts /var/log to RAM, reducing filesystem I/O. Logfiles are cleared every hour. Does NOT save logfiles to disk. +\n- DietPi-RAMlog #2: Same as #1, with the added feature of appending logfile contents to disk at /root/logfile_storage, before being cleared. +\n- Full (Reduces performance): Leaves /var/log on DISK, reduces SD card lifespan. Full logging system with Logrotate and Rsyslog.' || return 0 - INDEX_LOGGING_TARGET=0 - toberemoved_text='DietPi-RAMlog, Logrotate, Rsyslog' + # Apply selection + case "$G_WHIP_RETURNED_VALUE" in - elif [[ $G_WHIP_RETURNED_VALUE == 'DietPi-RAMlog #1' ]]; then + 'None') Apply_Logging_Choices 0;; + 'DietPi-RAMlog #2') Apply_Logging_Choices -2;; + 'Full') Apply_Logging_Choices -3;; + *) Apply_Logging_Choices -1;; - INDEX_LOGGING_TARGET=-1 - toberemoved_text='Logrotate, Rsyslog' - - elif [[ $G_WHIP_RETURNED_VALUE == 'DietPi-RAMlog #2' ]]; then - - INDEX_LOGGING_TARGET=-2 - toberemoved_text='Logrotate, Rsyslog' - - elif [[ $G_WHIP_RETURNED_VALUE == 'Full' ]]; then - - INDEX_LOGGING_TARGET=-3 - toberemoved_text='DietPi-RAMlog' - - fi - - fi + esac # Check for changes - INSTALL_LOGGING_CHOICESMADE=0 - if (( $INDEX_LOGGING_TARGET != $INDEX_LOGGING_CURRENT )); then - - INSTALL_LOGGING_CHOICESMADE=1 - G_WHIP_MSG "$G_WHIP_RETURNED_VALUE has been selected:\n - Your choice will be applied when 'Install Go >> Start installation' is selected.\n - $toberemoved_text installations will be automatically uninstalled." + for i in 101 102 103 + do + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && tobeinstalled_text+="\n - ${aSOFTWARE_NAME[$i]}" + (( ${aSOFTWARE_INSTALL_STATE[$i]} == -1 )) && toberemoved_text+="\n - ${aSOFTWARE_NAME[$i]}" + done + [[ $tobeinstalled_text || $toberemoved_text ]] || return 0 + [[ $tobeinstalled_text ]] && tobeinstalled_text="\n\nThe following software will be installed:$tobeinstalled_text" + [[ $toberemoved_text ]] && toberemoved_text="\n\nThe following software will be uninstalled:$toberemoved_text" - fi + G_WHIP_MSG "$G_WHIP_RETURNED_VALUE has been selected:\n- Your choice will be applied when 'Install Go >> Start installation' is selected.$tobeinstalled_text$toberemoved_text" ;; @@ -17140,53 +17045,51 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa ) G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Choose where to store your user data. User data includes software such as ownCloud data store, BitTorrent downloads etc. + G_WHIP_MENU 'Choose where to store your user data. User data includes software such as ownCloud data store, BitTorrent downloads etc. \nMore information on user data in DietPi:\n- https://dietpi.com/docs/dietpi_tools/#quick-selections -\n- DietPi-Drive_Manager: Launch DietPi-Drive_Manager to setup external drives, and, move user data to different locations.'; then +\n- DietPi-Drive_Manager: Launch DietPi-Drive_Manager to setup external drives, and, move user data to different locations.' || return 0 - # DriveMan - if [[ $G_WHIP_RETURNED_VALUE == 'Drive' ]]; then + # DriveMan + if [[ $G_WHIP_RETURNED_VALUE == 'Drive' ]]; then - /boot/dietpi/dietpi-drive_manager - return 0 + /boot/dietpi/dietpi-drive_manager + return 0 - # List - elif [[ $G_WHIP_RETURNED_VALUE == 'List' ]]; then + # List + elif [[ $G_WHIP_RETURNED_VALUE == 'List' ]]; then - /boot/dietpi/dietpi-drive_manager 1 || return 1 + /boot/dietpi/dietpi-drive_manager 1 || return 1 - local return_value=$( /dev/null; then + + webserver_installed=1 preference_index=0 webserver_name=${aSOFTWARE_NAME[83]} + + elif (( ${aSOFTWARE_INSTALL_STATE[85]} == 2 )) || dpkg-query -s 'nginx-common' &> /dev/null; then + + webserver_installed=1 preference_index=-1 webserver_name=${aSOFTWARE_NAME[85]} + + elif (( ${aSOFTWARE_INSTALL_STATE[84]} == 2 )) || dpkg-query -s 'lighttpd' &> /dev/null; then + + webserver_installed=1 preference_index=-2 webserver_name=${aSOFTWARE_NAME[84]} + + fi + + if (( $webserver_installed == 1 )) + then + G_WHIP_MSG "[ INFO ] $webserver_name is installed already. +\nThe webserver preference has no effect and cannot be changed as long as a webserver is installed already. +\nIf you want to install a different webserver, uninstall $webserver_name first." + (( $INDEX_WEBSERVER == $preference_index )) || G_CONFIG_INJECT 'INDEX_WEBSERVER=' "INDEX_WEBSERVER=$preference_index" /boot/dietpi/.installed + INDEX_WEBSERVER=$preference_index + return 0 + fi + G_WHIP_MENU_ARRAY=( "${aSOFTWARE_NAME[83]}" ": ${aSOFTWARE_DESC[83]}" @@ -17204,71 +17134,67 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa G_WHIP_DEFAULT_ITEM=$index_webserver_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Please select your preferred webserver, which will be installed (only) when another selected software requires any webserver: -\n- Apache2: Feature-rich and popular. Recommended for beginners and users who are looking to follow Apache2 based guides. -\n- Nginx: Lightweight alternative to Apache2. Nginx claims faster webserver performance compared to Apache2. + G_WHIP_MENU 'Which webserver shall be installed when you select software that requires a webserver? +\n- Apache: Feature-rich and popular. Recommended for beginners and users who are looking to follow Apache based guides. +\n- Nginx: Lightweight alternative to Apache. Nginx claims faster webserver performance compared to Apache. \n- Lighttpd: Extremely lightweight and is generally considered to offer the \"best\" webserver performance for SBCs. Recommended for users who expect low webserver traffic. -\n- More info: https://dietpi.com/docs/software/webserver_stack/'; then +\n- More info: https://dietpi.com/docs/software/webserver_stack/' || return 0 - # Assign target index - if [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[83]}" ]]; then + # Apply preference index + if [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[83]}" ]]; then - INDEX_WEBSERVER_TARGET=0 + preference_index=0 - elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[85]}" ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[85]}" ]]; then - INDEX_WEBSERVER_TARGET=-1 + preference_index=-1 - elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[84]}" ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[84]}" ]]; then - INDEX_WEBSERVER_TARGET=-2 + preference_index=-2 - fi - - # Do not allow to change preference, when another webserver is installed already - if (( $INDEX_WEBSERVER_TARGET != $INDEX_WEBSERVER_CURRENT )); then + fi + (( $INDEX_WEBSERVER == $preference_index )) || G_CONFIG_INJECT 'INDEX_WEBSERVER=' "INDEX_WEBSERVER=$preference_index" /boot/dietpi/.installed + INDEX_WEBSERVER=$preference_index - local incompatible_webserver_preference=0 - local info_currently_installed_webserver='None' + ;; - if dpkg-query -s 'apache2' &> /dev/null; then + 'Desktop Preference') - INDEX_WEBSERVER_CURRENT=0 - info_currently_installed_webserver=${aSOFTWARE_NAME[83]} - (( $INDEX_WEBSERVER_TARGET != 0 )) && incompatible_webserver_preference=1 + # Do not allow to change preference if a desktop is installed already + local desktop_installed=0 preference_index desktop_name - elif dpkg-query -s 'nginx-common' &> /dev/null; then + if (( ${aSOFTWARE_INSTALL_STATE[23]} == 2 )) || dpkg-query -s 'lxde' &> /dev/null; then - INDEX_WEBSERVER_CURRENT=-1 - info_currently_installed_webserver=${aSOFTWARE_NAME[85]} - (( $INDEX_WEBSERVER_TARGET != -1 )) && incompatible_webserver_preference=1 + desktop_installed=1 preference_index=0 desktop_name=${aSOFTWARE_NAME[23]} - elif dpkg-query -s 'lighttpd' &> /dev/null; then + elif (( ${aSOFTWARE_INSTALL_STATE[25]} == 2 )) || dpkg-query -s 'xfce4' &> /dev/null; then - INDEX_WEBSERVER_CURRENT=-2 - info_currently_installed_webserver=${aSOFTWARE_NAME[84]} - (( $INDEX_WEBSERVER_TARGET != -2 )) && incompatible_webserver_preference=1 + desktop_installed=1 preference_index=-1 desktop_name=${aSOFTWARE_NAME[25]} - fi + elif (( ${aSOFTWARE_INSTALL_STATE[24]} == 2 )) || dpkg-query -s 'mate-desktop-environment-core' &> /dev/null; then - # Reset preference selection - if (( $incompatible_webserver_preference == 1 )); then + desktop_installed=1 preference_index=-2 desktop_name=${aSOFTWARE_NAME[24]} - INDEX_WEBSERVER_TARGET=$INDEX_WEBSERVER_CURRENT + elif (( ${aSOFTWARE_INSTALL_STATE[173]} == 2 )) || dpkg-query -s 'lxqt' &> /dev/null; then - # Inform user - G_WHIP_MSG "Error: Incompatible Webserver Preference:\n\nUnable to change your webserver preference to $G_WHIP_RETURNED_VALUE. -\nThis is due to an existing and incompatible webserver installation on your system ($info_currently_installed_webserver). Please remove all webserver based software (using dietpi-software > uninstall), before trying again." + desktop_installed=1 preference_index=-3 desktop_name=${aSOFTWARE_NAME[173]} - fi + elif (( ${aSOFTWARE_INSTALL_STATE[26]} == 2 )) || dpkg-query -s 'gnustep' &> /dev/null; then - fi + desktop_installed=1 preference_index=-4 desktop_name=${aSOFTWARE_NAME[26]} fi - ;; - - 'Desktop Preference') + if (( $desktop_installed == 1 )) + then + G_WHIP_MSG "[ INFO ] $desktop_name is installed already. +\nThe desktop preference has no effect and cannot be changed as long as a desktop is installed already. +\nYou can however select any additional desktop from 'Browse software' or 'Search software' menus." + (( $INDEX_DESKTOP == $preference_index )) || G_CONFIG_INJECT 'INDEX_DESKTOP=' "INDEX_DESKTOP=$preference_index" /boot/dietpi/.installed + INDEX_DESKTOP=$preference_index + return 0 + fi G_WHIP_MENU_ARRAY=( @@ -17282,35 +17208,60 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa G_WHIP_DEFAULT_ITEM=$index_desktop_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - G_WHIP_MENU 'Please select your preferred desktop environment, which will be installed (only) when another selected software requires any desktop:' || return 0 + G_WHIP_MENU 'Which desktop shall be installed when you select software that requires a desktop?' || return 0 - # Assign target index + # Apply preference index if [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[23]}" ]]; then - INDEX_DESKTOP_TARGET=0 + preference_index=0 elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[25]}" ]]; then - INDEX_DESKTOP_TARGET=-1 + preference_index=-1 elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[24]}" ]]; then - INDEX_DESKTOP_TARGET=-2 + preference_index=-2 elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[173]}" ]]; then - INDEX_DESKTOP_TARGET=-3 + preference_index=-3 elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[26]}" ]]; then - INDEX_DESKTOP_TARGET=-4 + preference_index=-4 fi + (( $INDEX_DESKTOP == $preference_index )) || G_CONFIG_INJECT 'INDEX_DESKTOP=' "INDEX_DESKTOP=$preference_index" /boot/dietpi/.installed + INDEX_DESKTOP=$preference_index ;; 'Browser Preference') + # Do not allow to change preference if a browser is installed already + local browser_installed=0 preference_index browser_name + + if (( ${aSOFTWARE_INSTALL_STATE[67]} == 2 )) || dpkg-query -s 'firefox-esr' &> /dev/null; then + + browser_installed=1 preference_index=-1 browser_name=${aSOFTWARE_NAME[67]} + + elif (( ${aSOFTWARE_INSTALL_STATE[113]} == 2 )) || dpkg-query -s 'chromium' &> /dev/null || dpkg-query -s 'chromium-browser' &> /dev/null; then + + browser_installed=1 preference_index=-2 browser_name=${aSOFTWARE_NAME[25]} + + fi + + if (( $browser_installed == 1 )) + then + G_WHIP_MSG "[ INFO ] $browser_name is installed already. +\nThe browser preference has no effect and cannot be changed as long as a browser is installed already. +\nYou can however select any additional browser from 'Browse software' or 'Search software' menus." + (( $INDEX_BROWSER == $preference_index )) || G_CONFIG_INJECT 'INDEX_BROWSER=' "INDEX_BROWSER=$preference_index" /boot/dietpi/.installed + INDEX_BROWSER=$preference_index + return 0 + fi + G_WHIP_MENU_ARRAY=( 'None' ': No browser will be installed with desktops' @@ -17321,22 +17272,24 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa G_WHIP_DEFAULT_ITEM=$index_browser_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - G_WHIP_MENU 'Please select your preferred web browser, which will be installed (only) when a desktop is installed:' || return 0 + G_WHIP_MENU 'When a desktop is installed, which browser shall it contain?' || return 0 - # Assign target index + # Apply preference index if [[ $G_WHIP_RETURNED_VALUE == 'None' ]]; then - INDEX_BROWSER_TARGET=0 + preference_index=0 elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[67]}" ]]; then - INDEX_BROWSER_TARGET=-1 + preference_index=-1 elif [[ $G_WHIP_RETURNED_VALUE == "${aSOFTWARE_NAME[113]}" ]]; then - INDEX_BROWSER_TARGET=-2 + preference_index=-2 fi + (( $INDEX_BROWSER == $preference_index )) || G_CONFIG_INJECT 'INDEX_BROWSER=' "INDEX_BROWSER=$preference_index" /boot/dietpi/.installed + INDEX_BROWSER=$preference_index ;; @@ -17344,7 +17297,6 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa 'Help!') - # Populate help to text file so we can read it back to whiptail, as a scrollbox. local string='─────────────────────────────────────────────────────────────── Welcome to DietPi: ─────────────────────────────────────────────────────────────── @@ -17359,7 +17311,7 @@ List of installed software and their online documentation URLs: ───────────────────────────────────────────────────────────────\n' # Installed software - for i in "${!aSOFTWARE_INSTALL_STATE[@]}" + for i in "${!aSOFTWARE_NAME[@]}" do [[ ${aSOFTWARE_INSTALL_STATE[i]} -gt 0 && ${aSOFTWARE_DOCS[$i]} ]] || continue string+="\n${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}\n${aSOFTWARE_DOCS[$i]}\n" @@ -17391,43 +17343,46 @@ List of installed software and their online documentation URLs: if (( $G_DIETPI_INSTALL_STAGE == 2 )); then G_WHIP_YESNO 'Do you wish to exit DietPi-Software?\n\nAll changes to software selections will be cleared.' || return 0 - - Banner_Aborted exit 0 fi - # 1st run install + # Prevent exit on 1st run setup G_WHIP_MSG 'DietPi has not fully been installed.\nThis must be completed prior to using DietPi by selecting:\n - Go Start Install.' } - Menu_ConfirmInstall(){ + Menu_StartInstall(){ - # Obtain list of pending software installation: - local string_output - for i in "${!aSOFTWARE_INSTALL_STATE[@]}" + local tobeinstalled_text toberemoved_text summary_text + + # Obtain list of pending software installs and uninstalls + for i in "${!aSOFTWARE_NAME[@]}" do - (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && string_output+="\n - ${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && tobeinstalled_text+="\n - ${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" + (( ${aSOFTWARE_INSTALL_STATE[$i]} == -1 )) && toberemoved_text+="\n - ${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" done - [[ $G_SERVICE_CONTROL == 0 ]] || string_output+='\n\nNB: Software services will be temporarily controlled (stopped) by DietPi during this process. Please inform connected users, before continuing. SSH and VNC is not affected.' - - # Confirm Software install - G_WHIP_YESNO "DietPi is now ready to install your software choices: $string_output -\nSoftware details, usernames, passwords etc:\n - https://dietpi.com/dietpi-software.html\n\nWould you like to begin?" || return 0 - - TARGETMENUID=-1 # Exit menu loop - GOSTARTINSTALL=1 # Set install start flag - - } - - Menu_StartInstall(){ # Check if user made/changed software selections - if (( $INSTALL_SOFTWARE_CHOICESMADE || $INSTALL_SSHSERVER_CHOICESMADE || $INSTALL_FILESERVER_CHOICESMADE || $INSTALL_LOGGING_CHOICESMADE )); then + if [[ $tobeinstalled_text || $toberemoved_text ]]; then # List selections and ask for confirmation - Menu_ConfirmInstall + [[ $tobeinstalled_text ]] && tobeinstalled_text="\n\nThe following software will be installed:$tobeinstalled_text" + [[ $toberemoved_text ]] && toberemoved_text="\n\nThe following software will be uninstalled:$toberemoved_text" + [[ $G_SERVICE_CONTROL == 0 ]] || summary_text='\n\nNB: Software services will be temporarily controlled (stopped) by DietPi during this process. Please inform connected users, before continuing. SSH and VNC are not affected.' + + G_WHIP_YESNO "DietPi is now ready to apply your software choices:$tobeinstalled_text$toberemoved_text$summary_text +\nSoftware details, usernames, passwords etc:\n - https://dietpi.com/docs/software/\n\nWould you like to begin?" || return 0 + + # If due to choice changes only uninstalls are done and it is not the first run setup, skip the install function and call the uninstall function directly. + if [[ $G_DIETPI_INSTALL_STAGE == 2 && ! $tobeinstalled_text ]] + then + Uninstall_Software + Write_InstallFileList + else + GOSTARTINSTALL=1 # Set install start flag + fi + TARGETMENUID=-1 # Exit menu loop # After first run setup has finished, abort install without any selections elif (( $G_DIETPI_INSTALL_STAGE == 2 )); then @@ -17454,55 +17409,49 @@ List of installed software and their online documentation URLs: G_WHIP_CHECKLIST_ARRAY=() # Obtain list of installed software - local i software_available_for_uninstall=0 - for i in "${!aSOFTWARE_INSTALL_STATE[@]}" + local i + for i in "${!aSOFTWARE_NAME[@]}" do (( ${aSOFTWARE_INSTALL_STATE[$i]} == 2 )) || continue - - G_WHIP_CHECKLIST_ARRAY+=("$i" "${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" 'off') - software_available_for_uninstall=1 + # Skip webserver stacks: Their install states will be aligned with webserver/database install states automatically. + [[ $i =~ ^(75|76|78|79|81|82)$ ]] || G_WHIP_CHECKLIST_ARRAY+=("$i" "${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" 'off') done # No software installed - if (( ! $software_available_for_uninstall )); then + if (( ! ${#G_WHIP_CHECKLIST_ARRAY[@]} )); then - G_WHIP_MSG 'No software is currently installed, or, available for removal.' + G_WHIP_MSG 'No software is currently installed.' # Run menu else G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_CHECKLIST 'Use the spacebar to select the software you would like to remove:'; then + G_WHIP_CHECKLIST 'Use the spacebar to select the software you would like to remove:' && [[ $G_WHIP_RETURNED_VALUE ]] || return 0 - # Create list for user to review before removal - local output_string='The following software will be REMOVED from your system:' - for i in $G_WHIP_RETURNED_VALUE - do - output_string+="\n - ${aSOFTWARE_NAME[$i]} (ID=$i): ${aSOFTWARE_DESC[$i]}" - UNINSTALL_REQUIRED=1 - done - - (( $UNINSTALL_REQUIRED )) || return 0 + # Create list for user to review before removal + local output_string='The following software will be REMOVED from your system:' + for i in $G_WHIP_RETURNED_VALUE + do + output_string+="\n - ${aSOFTWARE_NAME[$i]} (ID=$i): ${aSOFTWARE_DESC[$i]}" + done - G_WHIP_YESNO "$output_string + G_WHIP_YESNO "$output_string \nNB: Uninstalling usually PURGES any related userdata and configs. If you only need to repair or update software, please use \"dietpi-software reinstall \" instead. -\nDo you wish to continue?" || { UNINSTALL_REQUIRED=0; return 0; } +\nDo you wish to continue?" || return 0 - # Mark for uninstall - for i in $G_WHIP_RETURNED_VALUE - do - aSOFTWARE_INSTALL_STATE[$i]=-1 - done - - # Run uninstall - Uninstall_Software + # Mark for uninstall + for i in $G_WHIP_RETURNED_VALUE + do + aSOFTWARE_INSTALL_STATE[$i]=-1 + done - # Save install states - Write_InstallFileList + # Run uninstall + Uninstall_Software - G_WHIP_MSG 'Uninstall completed' + # Save install states + Write_InstallFileList - fi + G_WHIP_MSG 'Uninstall completed' fi @@ -17513,22 +17462,6 @@ List of installed software and their online documentation URLs: #///////////////////////////////////////////////////////////////////////////////////// Banner_Installing(){ G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" "Installing ${aSOFTWARE_NAME[$software_id]}: ${aSOFTWARE_DESC[$software_id]}"; } Banner_Uninstalling(){ G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" "Uninstalling ${aSOFTWARE_NAME[$software_id]}: ${aSOFTWARE_DESC[$software_id]}"; } - Banner_Aborted(){ - - # Standard abort - if (( $G_DIETPI_INSTALL_STAGE == 2 )); then - - /boot/dietpi/func/dietpi-banner 1 - - # 1st run abort - else - - /boot/dietpi/func/dietpi-banner 0 - G_DIETPI-NOTIFY 1 '\n Installation aborted by user.\n Installation must be completed prior to using DietPi.\n Please run dietpi-software to restart the installation.\n' - - fi - - } #///////////////////////////////////////////////////////////////////////////////////// # Main Loop @@ -17563,9 +17496,6 @@ List of installed software and their online documentation URLs: # Start DietPi-Software installs (( $GOSTARTINSTALL )) || exit 0 - # Check for sufficient free space, 500 MiB should be enough for most software selections - G_CHECK_FREESPACE / 500 || { G_DIETPI-NOTIFY 1 'Install aborted due to insufficient free space'; exit 1; } - # Userdata location verify G_CHECK_USERDATA @@ -17578,10 +17508,10 @@ List of installed software and their online documentation URLs: G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Install completed' # Upload DietPi-Survey Data, if opted in, prompt user choice, if no settings file exists - # - Skip, if G_SERVICE_CONTROL == 0, which is exported by patch_file (DietPi-Update) which sends survey already + # - Skip, if G_SERVICE_CONTROL == 0, which is exported by "patches" (DietPi-Update) which sends survey already [[ $G_SERVICE_CONTROL == 0 ]] || /boot/dietpi/dietpi-survey 1 - # Start services (restart to reload configs of possible running services) + # Start services (restart to reload configs of possibly running services) [[ $G_SERVICE_CONTROL == 0 ]] || /boot/dietpi/dietpi-services restart # Start installed services, not controlled by DietPi-Services diff --git a/dietpi/dietpi-update b/dietpi/dietpi-update index 647fd3baaf..4579075853 100644 --- a/dietpi/dietpi-update +++ b/dietpi/dietpi-update @@ -249,7 +249,7 @@ for i in "${1:-${!G_LIVE_PATCH[@]}}" do [[ ${G_LIVE_PATCH_STATUS[$i]} == 'not applied' ]] || continue - G_DIETPI-NOTIFY 2 "Applying live patch $i" + G_DIETPI-NOTIFY 2 "Applying live patch $i: ${G_LIVE_PATCH_DESC[$i]}" eval "${G_LIVE_PATCH[$i]}" # Store new status of live patch to /boot/dietpi/.version @@ -437,7 +437,7 @@ Do you wish to continue and update DietPi to v$G_REMOTE_VERSION_CORE.$G_REMOTE_V G_WHIP_MENU_ARRAY=() for i in "${!G_LIVE_PATCH[@]}" do - G_WHIP_MENU_ARRAY+=("$i" "[${G_LIVE_PATCH_STATUS[$i]}]") + G_WHIP_MENU_ARRAY+=("$i" ": [${G_LIVE_PATCH_STATUS[$i]}] ${G_LIVE_PATCH_DESC[$i]}") done G_WHIP_BUTTON_CANCEL_TEXT='Exit' diff --git a/dietpi/dietpi-vpn b/dietpi/dietpi-vpn index cbf037c524..8c2cca166c 100644 --- a/dietpi/dietpi-vpn +++ b/dietpi/dietpi-vpn @@ -144,6 +144,7 @@ Available commands: elif [[ $VPN_PROVIDER == 'Custom' ]] then + [[ -d '/etc/openvpn' ]] || G_EXEC mkdir /etc/openvpn G_WHIP_MSG "Please select your custom .ovpn client config file from the next file browser dialogue. It will be copied to $FP_CLIENT_OVPN and loaded from there." /boot/dietpi/dietpi-explorer 1 /etc/openvpn || return 1 G_EXEC umask 0077 @@ -274,6 +275,7 @@ _EOF_ [[ -f $FP_CUSTOM_DOWN ]] && G_CONFIG_INJECT 'route-pre-down[[:blank:]]' "route-pre-down $FP_CUSTOM_DOWN" $FP_CLIENT_OVPN 'down[[:blank:]]' || G_EXEC sed -i '/^[[:blank:]]*route-pre-down[[:blank:]]/d' $FP_CLIENT_OVPN # Establish and test connection + G_AG_CHECK_INSTALL_PREREQ openvpn G_EXEC systemctl restart dietpi-vpn local i=1 until Check_Connected || (( $i > $CONNECTION_TIMEOUT )) @@ -322,13 +324,13 @@ _EOF_ { # Obtain connection status local text_status="WAN IP : $WAN_IP\nState : " - if ! Check_Connected + if Check_Connected then - text_status+='Disconnected' - [[ $VPN_PROVIDER == 'NordVPN' ]] && text_status+='\nNordVPN Subscription : https://go.nordvpn.net/aff_c?offer_id=15&aff_id=5305&url_id=902' - else Get_Connection_Info text_status+="Connected\nTraffic : Sent = $TX | Received = $RX" + else + text_status+='Disconnected' + [[ $VPN_PROVIDER == 'NordVPN' ]] && text_status+='\nNordVPN Subscription : https://go.nordvpn.net/aff_c?offer_id=15&aff_id=5305&url_id=902' fi # Obtain connection settings @@ -353,8 +355,8 @@ _EOF_ 'Reset' ': Remove and reset ALL configs and settings' '' '●─ Advanced Options ' - 'Autostart' ": [$autostart_text]" - 'Killswitch' ": [$killswitch_text]" + 'Autostart' ": [$autostart_text] Connect to VPN at boot" + 'Killswitch' ": [$killswitch_text] Block traffic on connection loss via iptables" 'Edit Up' ': This script gets executed right after the VPN is connected' 'Edit Down' ': This script gets executed right before the VPN is disconnected' '' '●─ Save Settings ' @@ -501,7 +503,7 @@ _EOF_ G_EXEC systemctl disable --now dietpi-vpn G_EXEC rm -Rf $FP_CLIENT_OVPN $FP_SETTINGS $FP_NORDVPN $FP_PROTONVPN $FP_IPVANISH $FP_PIA # Offer to purge OpenVPN, if neither OpenVPN (server) nor PiVPN is installed - ! grep -qE '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[(9|11)7\]=2' /boot/dietpi/.installed && G_WHIP_YESNO 'Do you want to have the underlying OpenVPN package removed as well?' && G_AGP openvpn + ! grep -qE '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[(9|11)7\]=2' /boot/dietpi/.installed && G_WHIP_YESNO 'Do you want to have the underlying OpenVPN package purged as well?' && G_AGP openvpn exit 0 fi else @@ -519,12 +521,12 @@ _EOF_ then echo -e "\e[33m$G_PROGRAM_NAME is not configured! Please run: \"dietpi-vpn\"\e[0m" - elif ! Check_Connected + elif Check_Connected then - echo -e '\e[1;31mDisconnected\e[0m' - else Get_Connection_Info echo -e "\e[1;32mConnected\e[0m - Sent = $TX | Received = $RX" + else + echo -e '\e[1;31mDisconnected\e[0m' fi elif [[ $INPUT ]] @@ -533,7 +535,6 @@ _EOF_ echo -e "\e[90m[\e[0m\e[31mFAILURE\e[0m\e[90m]\e[0m \e[90m$G_PROGRAM_NAME | \e[0mInvalid input command ($INPUT). Aborting...\n$USAGE" exit 1 else - G_AG_CHECK_INSTALL_PREREQ openvpn Read_Settings [[ -d $FP_SETTINGS ]] || G_EXEC mkdir -p $FP_SETTINGS [[ $VPN_PROVIDER ]] || Menu_Provider || exit 0 @@ -545,6 +546,6 @@ _EOF_ done fi #----------------------------------------------------------------------------------- - exit + exit 0 #----------------------------------------------------------------------------------- } diff --git a/dietpi/func/change_hostname b/dietpi/func/change_hostname index e5d0a5e7da..79d42f177d 100644 --- a/dietpi/func/change_hostname +++ b/dietpi/func/change_hostname @@ -26,12 +26,12 @@ then EXIT_CODE=0 G_CONFIG_INJECT '127.0.1.1[[:blank:]]' "127.0.1.1 $*" /etc/hosts || EXIT_CODE=1 - echo "$*" > /etc/hostname || EXIT_CODE=1 + G_EXEC_NOEXIT=1 G_EXEC eval "echo '$*' > /etc/hostname" || EXIT_CODE=1 G_EXEC_NOEXIT=1 G_EXEC hostname "$*" || EXIT_CODE=1 else EXIT_CODE=1 G_DIETPI-NOTIFY 1 "Invalid hostname input ($*). Aborting..." - G_DIETPI-NOTIFY 0 'Further info: https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_hostnames' + G_DIETPI-NOTIFY 0 'Further info: https://en.wikipedia.org/wiki/Hostname#Syntax' fi #----------------------------------------------------------------------------------- diff --git a/dietpi/func/create_mysql_db b/dietpi/func/create_mysql_db index 38ef740d84..367f694c74 100644 --- a/dietpi/func/create_mysql_db +++ b/dietpi/func/create_mysql_db @@ -39,8 +39,9 @@ G_DIETPI-NOTIFY 2 "$MESSAGE" # Generate DB - # - 'identified by' can overwrite unix_socket authentication, thus use this for non-root users only. - grant_privileges="grant all privileges on \`$DATABASE_NAME\`.* to \`$DATABASE_USER\`@localhost identified by '$DATABASE_PW';flush privileges" + # - 'identified by' overwrites unix_socket authentication, thus use this for non-root users only. + # - Database names can only be quotes via backticks, passwords only via single quotes. + grant_privileges="grant all privileges on \`$DATABASE_NAME\`.* to '$DATABASE_USER'@localhost identified by '$DATABASE_PW';flush privileges" [[ $DATABASE_USER != 'root' ]] || grant_privileges= mysql -e "create database \`$DATABASE_NAME\`;$grant_privileges" exit_code=$? diff --git a/dietpi/func/dietpi-benchmark b/dietpi/func/dietpi-benchmark index 5fc2e52008..9f18517342 100644 --- a/dietpi/func/dietpi-benchmark +++ b/dietpi/func/dietpi-benchmark @@ -38,8 +38,6 @@ #///////////////////////////////////////////////////////////////////////////////////// # Global #///////////////////////////////////////////////////////////////////////////////////// - SURVEY_OPTED_IN=0 - IPERF_SERVER_IP= SHOW_RESULTS=${SHOW_RESULTS:-1} # Optional input: Show results for individual tests? CPUBENCH_INT_MAX=${CPUBENCH_INT_MAX:-1000000} # Optional input @@ -63,9 +61,6 @@ G_EXEC mkdir -p /var/lib/dietpi/dietpi-benchmark cat << _EOF_ > /var/lib/dietpi/dietpi-benchmark/results -# ------------------------- -# DietPi-Benchmark -# ------------------------- BENCH_VERSION=2 BENCH_HW_MODEL=$G_HW_MODEL BENCH_CPU='$BENCH_CPU' @@ -81,13 +76,9 @@ BENCH_NET_LAN_SPEED='$BENCH_NET_LAN_SPEED' _EOF_ } - Update_Survey_Opted_Status(){ SURVEY_OPTED_IN=$(sed -n '/^[[:blank:]]*SURVEY_OPTED_IN=[01]$/{s/^[^=]*=//p;q}' /boot/dietpi.txt); } - Upload_Survey(){ - Update_Survey_Opted_Status - - if [[ $SURVEY_OPTED_IN == 1 ]]; then + if grep -q '^[[:blank:]]*SURVEY_OPTED_IN=1$' /boot/dietpi.txt; then /boot/dietpi/dietpi-survey 1 diff --git a/dietpi/func/dietpi-globals b/dietpi/func/dietpi-globals index 1ee34c5149..5d45d1fd8a 100644 --- a/dietpi/func/dietpi-globals +++ b/dietpi/func/dietpi-globals @@ -56,8 +56,8 @@ [[ -f '/boot/dietpi/.version' ]] && . /boot/dietpi/.version # - Assign defaults/code version as fallback [[ $G_DIETPI_VERSION_CORE ]] || G_DIETPI_VERSION_CORE=7 - [[ $G_DIETPI_VERSION_SUB ]] || G_DIETPI_VERSION_SUB=8 - [[ $G_DIETPI_VERSION_RC ]] || G_DIETPI_VERSION_RC=2 + [[ $G_DIETPI_VERSION_SUB ]] || G_DIETPI_VERSION_SUB=9 + [[ $G_DIETPI_VERSION_RC ]] || G_DIETPI_VERSION_RC=3 [[ $G_GITBRANCH ]] || G_GITBRANCH='master' [[ $G_GITOWNER ]] || G_GITOWNER='MichaIng' # - Save current version and Git branch @@ -79,7 +79,7 @@ G_GITOWNER='$G_GITOWNER'" > /boot/dietpi/.version G_INIT(){ # Set locale to prevent incorrect scraping due to translated command outputs - # Set PATH to expected default to rule out issues due to borken environment, e.g. in combination with "su" or "sudo -E" + # Set PATH to expected default to rule out issues due to broken environment, e.g. in combination with "su" or "sudo -E" export LC_ALL='C.UTF-8' LANG='C.UTF-8' PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' # Set G_PROGRAM_NAME to originating script file (or shell executable) name if it was not set by originating script @@ -155,7 +155,7 @@ $(ps f -eo pid,user,tty,cmd | grep -i '[d]ietpi')" && continue # Without an input terminal, there is no point in doing this. [[ -t 0 ]] || return - # Printing terminal height - 1 newlines seems to be the fastes method that is compatible with all terminal types. + # Printing terminal height - 1 newlines seems to be the fastest method that is compatible with all terminal types. local lines=$(stty size) i newlines for ((i=1;i<${lines% *};i++)); do newlines+='\n'; done echo -ne "\e[0m$newlines\e[H" @@ -181,7 +181,7 @@ $(ps f -eo pid,user,tty,cmd | grep -i '[d]ietpi')" && continue G_DIETPI-NOTIFY(){ local i ainput_string=("$@") output_string grey green red reset yellow dietpi_green - # If this is a terminal, it understands ANSI escape sequences, so use colour, always start left-aligned with colour reset and clear screen from cursor til end. + # If this is a terminal, it understands ANSI escape sequences, so use colour, always start left-aligned with colour reset and clear screen from cursor to end. # - Assume if STDIN is a terminal that STDOUT is one as well, e.g. covered by "tee" if [[ -t 0 || -t 1 ]] then @@ -273,7 +273,7 @@ $(ps f -eo pid,user,tty,cmd | grep -i '[d]ietpi')" && continue Print 1 # If redirect to existent PID file fails due to noclobber, don't start processing animation. - # - This method prevents a tiny condition race from checking file existance until creating it, when doing: [[ ! -e file ]] && > file + # - This method prevents a tiny condition race from checking file existence until creating it, when doing: [[ ! -e file ]] && > file set -C if { > /tmp/dietpi-process.pid; } &> /dev/null; then @@ -347,7 +347,7 @@ $(ps f -eo pid,user,tty,cmd | grep -i '[d]ietpi')" && continue elif (( $1 == 2 )); then output_string+="$bracket_l INFO $bracket_r " - # Keep info messages in gray, even if "$G_PROGRAM_NAME | \e[0m" is added: + # Keep info messages in grey, even if "$G_PROGRAM_NAME | \e[0m" is added: ainput_string[1]="$grey${ainput_string[1]}" ainput_string+=('\n') Print 1 @@ -1073,7 +1073,7 @@ $log_content" || break # Exit error handler menu loop on cancel local i waiting_for exit_code - # Wait until all theads finished + # Wait until all threads finished while : do for i in "${!G_THREAD_COMMAND[@]}" @@ -1244,7 +1244,7 @@ $log_content" || break # Exit error handler menu loop on cancel declare -F G_EXEC_PRE_FUNC &> /dev/null && eval "G_EXEC_PRE_FUNC_ORIG()$(declare -f G_EXEC_PRE_FUNC | tail -n +2)" G_EXEC_PRE_FUNC(){ acommand[2]=$G_CHECK_URL_TIMEOUT; declare -F G_EXEC_PRE_FUNC_ORIG &> /dev/null && G_EXEC_PRE_FUNC_ORIG; } - # "--retry" only applies on "a timeout, an FTP 4xx response code or an HTTP 5xx response code", hence we loop outself. + # "--retry" only applies on "a timeout, an FTP 4xx response code or an HTTP 5xx response code", hence we loop ourself. G_EXEC_DESC="Checking URL: $*" G_EXEC curl -ILfvm $G_CHECK_URL_TIMEOUT "$@" local exit_code=$? @@ -1443,7 +1443,7 @@ $log_content" || break # Exit error handler menu loop on cancel fi - # Apply and check permissions support, twice (just incase the current value is already set) + # Apply and check permissions support, twice (just in case the current value is already set) local permissions_failed=0 chmod 600 "$fp_target" @@ -1634,34 +1634,25 @@ $log_content" || break # Exit error handler menu loop on cancel G_AG_CHECK_INSTALL_PREREQ(){ # Return if no argument given - (( $# )) || { G_DIETPI-NOTIFY 2 'No input package given. Aborting...'; return 0; } - - G_CHECK_ROOT_USER 1 - - local i apackages=() exit_code=0 + (( $# )) || return 0 G_DIETPI-NOTIFY 2 "Checking for required APT packages: \e[33m$*" + G_CHECK_ROOT_USER 1 + + local i apackages=() for i in "$@" do dpkg-query -s "$i" &> /dev/null && continue - G_DIETPI-NOTIFY 2 "Flagged for install: \e[33m$i" apackages+=("$i") done - if [[ ${apackages[0]} ]]; then + [[ ${apackages[0]} ]] || return 0 - G_AGUP - G_AGI "${apackages[@]}" - exit_code=$? - - else - - G_DIETPI-NOTIFY 0 'All required APT packages are already installed.' - - fi - - return $exit_code + G_AGUP + G_AGI "${apackages[@]}" + exit_code=$? + return $? } @@ -1737,27 +1728,27 @@ $log_content" || break # Exit error handler menu loop on cancel local temp_f=$(( $temp * 9/5 + 32 )) if (( $temp >= 70 )); then - temp="\e[1;31mWARNING: $temp'C : $temp_f'F (Reducing the life of your device)\e[0m" + temp="\e[1;31mWARNING: $temp °C / $temp_f °F : Reducing the life of your device\e[0m" elif (( $temp >= 60 )); then - temp="\e[38;5;202m$temp'C : $temp_f'F \e[90m(Running hot, not recommended)\e[0m" + temp="\e[38;5;202m$temp °C / $temp_f °F \e[90m: Running hot, not recommended\e[0m" elif (( $temp >= 50 )); then - temp="\e[1;33m$temp'C : $temp_f'F \e[90m(Running warm, but safe)\e[0m" + temp="\e[1;33m$temp °C / $temp_f °F \e[90m: Running warm, but safe\e[0m" elif (( $temp >= 40 )); then - temp="\e[1;32m$temp'C : $temp_f'F \e[90m(Optimal temperature)\e[0m" + temp="\e[1;32m$temp °C / $temp_f °F \e[90m: Optimal temperature\e[0m" elif (( $temp >= 30 )); then - temp="\e[1;36m$temp'C : $temp_f'F \e[90m(Cool runnings)\e[0m" + temp="\e[1;36m$temp °C / $temp_f °F \e[90m: Cool runnings\e[0m" else - temp="\e[1;36m$temp'C : $temp_f'F \e[90m(Who put me in the freezer!)\e[0m" + temp="\e[1;36m$temp °C / $temp_f °F \e[90m: Who put me in the freezer!\e[0m" fi @@ -1775,14 +1766,14 @@ $log_content" || break # Exit error handler menu loop on cancel local usage=0 # ps: inaccurate but fast - while read -r line # Aside reasing raw, -r removes leading and trailing white spaces each line + while read -r line # Aside reading raw, -r removes leading and trailing white spaces each line do line=${line/.} # Remove decimal dot ((usage+=${line#0})) # Remove leading zero, if present, then sum up done < <(ps --no-headers -eo %cpu) # Single core usage in xy.z - # ps returns single core usage, so we devide by core count + # ps returns single core usage, so we divide by core count usage=$(printf '%.1f' "$(($usage*10/$G_HW_CPU_CORES+1))e-2") # Divide by 10 to compensate decimal dot removal, re-add decimal dot via printf conversion but assure last digit is rounded correctly echo "$usage" @@ -1828,7 +1819,7 @@ $log_content" || break # Exit error handler menu loop on cancel # $1=input # $2=Optional Min value range # $3=Optional Max value range - # disable_error=1 to disable notify/whiptail invalid value when recieved + # disable_error=1 to disable notify/whiptail invalid value when received # 1=no | scripts killed automatically # 0=yes # Usage = if G_CHECK_VALIDINT input; then @@ -1883,34 +1874,28 @@ $log_content" || break # Exit error handler menu loop on cancel } - # Verifies the integrity of the DietPi userdata folder/symlink, based on where it should be psyhically. Basically, checks if user removed the USB drive with userdata on it. + # Verifies the integrity of the DietPi userdata folder/symlink, based on where it should be physically. Basically, checks if user removed the USB drive with userdata on it. # NB: As this is considered a critical (if failed), current scripts will be exited automatically # 1=fail # 0=ok G_CHECK_USERDATA(){ - local return_value=0 - local fp_actual='/mnt/dietpi_userdata' + local return_value=0 fp_actual='/mnt/dietpi_userdata' # Symlinked? - if [[ -L '/mnt/dietpi_userdata' ]]; then - - # Check physical location exists and is mounted + if [[ -L '/mnt/dietpi_userdata' ]] + then + # Check physical location exists (is mounted) fp_actual=$(readlink -f /mnt/dietpi_userdata) - df -P "$fp_actual" &> /dev/null || return_value=1 - + [[ -d $fp_actual ]] || return_value=1 fi G_DIETPI-NOTIFY $return_value "DietPi-Userdata validation: $fp_actual" - if (( $return_value )); then - - G_WHIP_MSG "[FAILED] DietPi-Userdata validation\n\nDietPi was unable to verify the existance of the userdata directory ($fp_actual).\n\nPlease ensure all previous external drives are connected and functional, before trying again.\n\nUnable to continue, exiting." - kill -INT $$ # kill all current scripts, excluding shell - - fi + (( $return_value )) || return 0 + G_WHIP_MSG "[FAILED] DietPi-Userdata validation\n\nDietPi was unable to verify the existence of the userdata directory ($fp_actual).\n\nPlease ensure all previous external drives are connected and functional, before trying again.\n\nUnable to continue, exiting." + kill -INT $$ # kill all current scripts, excluding shell return $return_value - } # Prompt user to create a backup before system changes. Exit existing scripts if failed. @@ -2007,7 +1992,7 @@ $log_content" || break # Exit error handler menu loop on cancel local after=${4//\//\\\/} local error - # Clouring output + # Colouring output local yellow reset [[ -t 0 || -t 1 ]] && yellow='\e[33m' reset='\e[0m' diff --git a/dietpi/func/dietpi-set_hardware b/dietpi/func/dietpi-set_hardware index 2f370f26d6..c1ab4af018 100644 --- a/dietpi/func/dietpi-set_hardware +++ b/dietpi/func/dietpi-set_hardware @@ -27,6 +27,7 @@ $FP_SCRIPT lcdpanel target_panel (\"none\" to remove all) $FP_SCRIPT headless enable/disable $FP_SCRIPT gpumemsplit 64/128/256... Range: 16-944, RPi only $FP_SCRIPT rpi-camera enable/disable +$FP_SCRIPT rpi-codec enable/disable $FP_SCRIPT rpi-opengl vc4-kms-v3d/vc4-fkms-v3d/disable $FP_SCRIPT rpi3_usb_boot enable $FP_SCRIPT rpi-eeprom @@ -120,13 +121,47 @@ $FP_SCRIPT rpi-eeprom local gpu_mem=$(sed -n '/^[[:blank:]]*gpu_mem[_0-9]*=/{s/^[^=]*=//p;q}' /boot/config.txt) (( ${gpu_mem:-76} < 96 )) && INPUT_DEVICE_VALUE=96 Gpu_Memory_Split_Main + # Enable V4L2 codec as well + INPUT_DEVICE_VALUE='enable' RPi_Codec_Main + elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then # Comment extended start setting G_EXEC sed -i '/^[[:blank:]]*start_x=/c\#start_x=1' /boot/config.txt # Add modules blacklist, which are otherwise loaded by default since kernel 4.19/5.10 - echo -e 'blacklist bcm2835_codec\nblacklist bcm2835_v4l2\nblacklist bcm2835_isp' > /etc/modprobe.d/dietpi-disable_rpi_camera.conf + G_EXEC eval "echo -e 'blacklist bcm2835_v4l2\nblacklist bcm2835_isp' > /etc/modprobe.d/dietpi-disable_rpi_camera.conf" + + else + + Unknown_Input_Mode + + fi + + } + + #///////////////////////////////////////////////////////////////////////////////////// + # rpi-codec + #///////////////////////////////////////////////////////////////////////////////////// + RPi_Codec_Main(){ + + (( $G_HW_MODEL > 9 )) && { Unsupported_Input_Name; return 1; } # Exit path for non-RPi + + if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then + + # Remove modules blacklist + [[ -f '/etc/modprobe.d/dietpi-disable_rpi_codec.conf' ]] && G_EXEC rm /etc/modprobe.d/dietpi-disable_rpi_codec.conf + + # RPi 4: Enable HEVC decoder + (( $G_HW_MODEL == 4 )) && G_CONFIG_INJECT 'dtoverlay=rpivid-v4l2' 'dtoverlay=rpivid-v4l2' /boot/config.txt + + elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then + + # Add module blacklist, which is otherwise loaded by default since kernel 4.19/5.10 + G_EXEC eval "echo 'blacklist bcm2835_codec' > /etc/modprobe.d/dietpi-disable_rpi_codec.conf" + + # Disable HEVC decoder + G_EXEC sed -i '/^[[:blank:]]*dtoverlay=rpivid-v4l2$/d' /boot/config.txt else @@ -272,7 +307,7 @@ _EOF_ # Disable SDTV on RPi4 (default) G_EXEC sed -i '/^[[:blank:]]*enable_tvout=/c\#enable_tvout=0' /boot/config.txt - # Odroid C2 + # Odroid C2 legacy image, provided until December 2021 elif [[ $G_HW_MODEL == 12 && -f '/boot/boot.ini' ]]; then G_CONFIG_INJECT 'setenv[[:blank:]]+nographics[[:blank:]]' 'setenv nographics "1"' /boot/boot.ini 'ODROIDC2-UBOOT-CONFIG' @@ -292,11 +327,11 @@ _EOF_ G_EXEC sed -i '/^[[:blank:]]*max_framebuffers=/c\#max_framebuffers=2' /boot/config.txt #G_EXEC sed -i '/^[[:blank:]]*disable_splash=/c\#disable_splash=0' /boot/config.txt - G_EXEC sed -i '/^[[:blank:]]*hdmi_blanking=/c\#hdmi_blanking=0' /boot/config.txt + #G_EXEC sed -i '/^[[:blank:]]*hdmi_blanking=/c\#hdmi_blanking=0' /boot/config.txt G_EXEC sed -i '/^[[:blank:]]*hdmi_ignore_hotplug=/c\#hdmi_ignore_hotplug=0' /boot/config.txt G_EXEC sed -i '/^[[:blank:]]*enable_tvout=/c\#enable_tvout=0' /boot/config.txt - # Odroid C2 + # Odroid C2 legacy image, provided until December 2021 elif [[ $G_HW_MODEL == 12 && -f '/boot/boot.ini' ]]; then G_CONFIG_INJECT 'setenv[[:blank:]]+nographics[[:blank:]]' 'setenv nographics "0"' /boot/boot.ini 'ODROIDC2-UBOOT-CONFIG' @@ -602,8 +637,11 @@ _EOF_ (( $G_HW_MODEL > 9 )) && { Unsupported_Input_Name; return 1; } # Exit path for non-RPi + # Get overlay params + local params=$(sed -En '/^[[:blank:]]*dtoverlay=vc4-f?kms-v3d(-pi4)?,/{s/^[^,]*//p;q}' /boot/config.txt) + # Always remove previous VC4 overlay entry - G_EXEC sed -i '/^[[:blank:]]*dtoverlay=vc4-/d' /boot/config.txt + G_EXEC sed -Ei '/^[[:blank:]]*dtoverlay=vc4-f?kms-v3d/d' /boot/config.txt if [[ $INPUT_DEVICE_VALUE == 'vc4-kms-v3d' || $INPUT_DEVICE_VALUE == 'vc4-fkms-v3d' ]]; then @@ -612,7 +650,21 @@ _EOF_ (( $G_DISTRO < 5 )) && libegl1+='-mesa' G_AG_CHECK_INSTALL_PREREQ libgl1-mesa-dri libgles2 $libegl1 mesa-utils - G_CONFIG_INJECT "dtoverlay=$INPUT_DEVICE_VALUE" "dtoverlay=$INPUT_DEVICE_VALUE" /boot/config.txt + # Fake KMS supports only CMA params + [[ $params && $INPUT_DEVICE_VALUE == 'vc4-fkms-v3d' ]] && params=$(mawk -F, '{for(i=1; i<=NF; i++) {if($i~/^cma-*/){print $i;exit}}}' <<< "$params") + + # Use additional argument for CMA size + if [[ $INPUT_ADDITIONAL ]] + then + if [[ $params =~ ',cma-'[^,]*(,|\$) ]] + then + params=$(sed -E "s/,cma-[^,]*(,|$)/,cma-$INPUT_ADDITIONAL\1/" <<< "$params") + else + params+=",cma-$INPUT_ADDITIONAL" + fi + fi + + G_CONFIG_INJECT "dtoverlay=$INPUT_DEVICE_VALUE" "dtoverlay=$INPUT_DEVICE_VALUE$params" /boot/config.txt elif [[ $INPUT_DEVICE_VALUE != 'disable' ]]; then @@ -623,7 +675,7 @@ _EOF_ } #///////////////////////////////////////////////////////////////////////////////////// - # lcdpanel eg: All non-HDMI/VGA based displays and monitors. + # lcdpanel: All non-HDMI/VGA based displays and monitors #///////////////////////////////////////////////////////////////////////////////////// Lcd_Panel_Main(){ @@ -711,14 +763,6 @@ _EOF_ # Waveshare32 Lcd_Panel_Waveshare32_Enable_X11(){ - cat << '_EOF_' > /etc/X11/xorg.conf.d/99-waveshare32_xorg.conf -Section "Device" - Identifier "Allwinner A10/A13 FBDEV" - Driver "fbdev" - Option "fbdev" "/dev/fb1" - Option "SwapbuffersWait" "true" -EndSection -_EOF_ cat << '_EOF_' > /etc/X11/xorg.conf.d/99-waveshare32_calibration.conf Section "InputClass" Identifier "calibration" @@ -734,17 +778,17 @@ _EOF_ (( $G_HW_MODEL > 19 )) && { Unsupported_Input_Mode; return 1; } # Exit path for non-RPi/non-Odroid - # Disable 1st to reset any existing installations: + # Disable 1st to reset any existing installations Lcd_Panel_Waveshare32_Disable + # X11 + Lcd_Panel_Xorg_All_Enable + Lcd_Panel_Waveshare32_Enable_X11 + # RPi if (( $G_HW_MODEL < 10 )); then - # X11 - Lcd_Panel_Xorg_All_Enable - Lcd_Panel_Waveshare32_Enable_X11 - - G_EXEC curl -sSfL https://github.com/waveshare/LCD-show/raw/master/waveshare32b-overlay.dtb -o /boot/overlays/waveshare32b.dtbo + G_EXEC curl -sSfL 'https://raw.githubusercontent.com/waveshare/LCD-show/master/waveshare32b-overlay.dtb' -o /boot/overlays/waveshare32b.dtbo #consoleblank=0 no effect G_EXEC sed -i 's/rootwait/rootwait fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo/' /boot/cmdline.txt @@ -760,19 +804,21 @@ _EOF_ G_CONFIG_INJECT 'dtoverlay=waveshare32b' 'dtoverlay=waveshare32b:rotate=270' /boot/config.txt - # Swap input axis - G_EXEC sed -i '/"SwapAxes"/c\ Option "SwapAxes" "1"' /etc/X11/xorg.conf.d/99-waveshare32_calibration.conf - # Move fb0 xorg.conf out the way: https://github.com/MichaIng/DietPi/issues/767 [[ -f '/usr/share/X11/xorg.conf.d/99-fbturbo.conf' ]] && G_EXEC mv /usr/share/X11/xorg.conf.d/99-fbturbo.conf /usr/share/X11/99-fbturbo.conf + # X11 + cat << '_EOF_' > /etc/X11/xorg.conf.d/99-waveshare32_xorg.conf +Section "Device" + Identifier "Allwinner A10/A13 FBDEV" + Driver "fbdev" + Option "fbdev" "/dev/fb1" + Option "SwapbuffersWait" "true" +EndSection +_EOF_ # Odroids else - # X11 - Lcd_Panel_Xorg_All_Enable - Lcd_Panel_Waveshare32_Enable_X11 - # con2fbmap, maps console (1) to panel(2). Run during boot. cat << _EOF_ > /etc/systemd/system/con2fbmap.service [Unit] @@ -801,7 +847,6 @@ Section "Device" Identifier "FBDEV" Driver "fbdev" Option "fbdev" "/dev/fb2" - #Option "SwapbuffersWait" "true" EndSection _EOF_ fi @@ -836,12 +881,12 @@ _EOF_ # Odroids elif (( $G_HW_MODEL < 20 )); then - if [[ -f '/etc/systemd/system/con2fbmap.service' ]]; then - + if [[ -f '/etc/systemd/system/con2fbmap.service' ]] + then G_EXEC systemctl disable --now con2fbmap - G_EXEC rm -R /etc/systemd/system/con2fbmap.service* - + G_EXEC rm /etc/systemd/system/con2fbmap.service fi + [[ -d '/etc/systemd/system/con2fbmap.service.d' ]] && G_EXEC rm -R /etc/systemd/system/con2fbmap.service.d [[ -f '/etc/modprobe.d/waveshare32.conf' ]] && G_EXEC rm /etc/modprobe.d/waveshare32.conf G_EXEC sed -i '/^[[:blank:]]*spicc/d' /etc/modules G_EXEC sed -i '/^[[:blank:]]*fbtft_device/d' /etc/modules @@ -850,7 +895,7 @@ _EOF_ } - # Odroid Cloudshell + # Odroid CloudShell Lcd_Panel_Odroidcloudshell_Enable(){ echo 'options fbtft_device name=hktft9340 busnum=1 rotate=270' > /etc/modprobe.d/odroid-cloudshell.conf @@ -867,11 +912,6 @@ _EOF_ G_EXEC sed -i '/^[[:blank:]]*spi_s3c64xx/d' /etc/modules G_EXEC sed -i '/^[[:blank:]]*fbtft_device/d' /etc/modules - # Cant run it on the fly, locks up device. - #root@DietPi-XU4:~# modprobe -rf spi_s3c64xx - #root@DietPi-XU4:~# modprobe -rf fbtft_device - #Segmentation fault - } # Odroid LCD 3.5 @@ -884,7 +924,11 @@ _EOF_ Lcd_Panel_Xorg_All_Enable + # SPI needs to be disabled: https://github.com/MichaIng/DietPi/issues/4154 cat << '_EOF_' > /etc/modprobe.d/odroid-lcd35.conf +blacklist spidev +blacklist spi_gpio +blacklist spi_bitbang options fbtft_device name=flexpfb rotate=90 options flexfb chip=ili9488 _EOF_ @@ -895,13 +939,14 @@ _EOF_ for i in "${amodules[@]}" do - - # Enable modules now, as we need to detect pwm path for service + # Enable modules now, as we need to detect PWM path for service G_EXEC modprobe "$i" G_CONFIG_INJECT "$i" "$i" /etc/modules - done + # Rebuild initramfs to exclude SPI modules: https://github.com/MichaIng/DietPi/issues/4154 + G_EXEC update-initramfs -u + # Service # - XU4 if (( $G_HW_MODEL == 11 )); then @@ -954,7 +999,7 @@ _EOF_ G_EXEC systemctl daemon-reload G_EXEC systemctl enable odroid-lcd35 - # X.org + # X11 [[ -f '/etc/X11/xorg.conf.d/exynos.conf' ]] && G_EXEC rm /etc/X11/xorg.conf.d/exynos.conf # XU4 G_EXEC mkdir -p /etc/X11/xorg.conf.d @@ -980,11 +1025,10 @@ _EOF_ [[ -f '/etc/X11/xorg.conf.d/99-calibration.conf' ]] && G_EXEC rm /etc/X11/xorg.conf.d/99-calibration.conf [[ -f '/etc/modprobe.d/odroid-lcd35.conf' ]] && G_EXEC rm /etc/modprobe.d/odroid-lcd35.conf - if [[ -f '/etc/systemd/system/odroid-lcd35.service' ]]; then - + if [[ -f '/etc/systemd/system/odroid-lcd35.service' ]] + then G_EXEC systemctl disable --now odroid-lcd35 G_EXEC rm /etc/systemd/system/odroid-lcd35.service - fi [[ -d '/etc/systemd/system/odroid-lcd35.service.d' ]] && G_EXEC rm -R /etc/systemd/system/odroid-lcd35.service.d [[ -f '/etc/X11/xorg.conf.d/99-odroid-lcd35.conf' ]] && G_EXEC rm /etc/X11/xorg.conf.d/99-odroid-lcd35.conf @@ -1139,7 +1183,6 @@ _EOF_ #///////////////////////////////////////////////////////////////////////////////////// # Bluetooth #///////////////////////////////////////////////////////////////////////////////////// - Bluetooth_Main(){ local aBLUETOOTH_MODULES=( @@ -1261,7 +1304,6 @@ Do you want to continue and disable the serial login console?' || return 1 #///////////////////////////////////////////////////////////////////////////////////// # Network #///////////////////////////////////////////////////////////////////////////////////// - Enable_IPv6(){ if [[ ! -d '/proc/sys/net/ipv6' ]]; then @@ -1457,7 +1499,6 @@ _EOF_ #///////////////////////////////////////////////////////////////////////////////////// # serialconsole #///////////////////////////////////////////////////////////////////////////////////// - Serial_Main(){ #------------------------------------------------------------------------------------- @@ -1557,13 +1598,15 @@ Do you want to continue and DISABLE Bluetooth now?' || return 1 if [[ $INPUT_ADDITIONAL ]]; then G_DIETPI-NOTIFY 2 "Disabling serial-getty on: /dev/$INPUT_ADDITIONAL" + G_EXEC systemctl unmask "serial-getty@$INPUT_ADDITIONAL" # Stop getty only if not currently attached, failsafe estimation in case of symlinks local stop='--now' [[ $(readlink -f "$(tty)") == $(readlink -f "/dev/$INPUT_ADDITIONAL") ]] && stop= # shellcheck disable=SC2086 G_EXEC systemctl disable $stop "serial-getty@$INPUT_ADDITIONAL" + unset -v stop # Place a mask only if device exists - [[ -e /dev/$INPUT_ADDITIONAL ]] && systemctl mask "serial-getty@$INPUT_ADDITIONAL" + [[ -e /dev/$INPUT_ADDITIONAL ]] && G_EXEC systemctl mask "serial-getty@$INPUT_ADDITIONAL" # Disable boot messages depending on device # - RPi @@ -1785,24 +1828,18 @@ Do you want to continue and DISABLE Bluetooth now?' || return 1 if [[ $INPUT_DEVICE_VALUE == *'-eq' ]]; then ALSA_EQ_ENABLED=1 - # Remove suffic so it doesn't get sent as a dtoverlay on RPi + # Remove suffix so it doesn't get sent as a dtoverlay on RPi INPUT_DEVICE_VALUE=${INPUT_DEVICE_VALUE%-eq} # - ALSA automatic conversion (plug) enabled? elif [[ $INPUT_DEVICE_VALUE == *'-plug' ]]; then ALSA_PLUG_ENABLED=1 - # Remove suffic so it doesn't get sent as a dtoverlay on RPi + # Remove suffix so it doesn't get sent as a dtoverlay on RPi INPUT_DEVICE_VALUE=${INPUT_DEVICE_VALUE%-plug} fi - # Workaround for RPi VC4 full KMS driver - # - RPi: An additional HDMI sound device exists as card 0: https://github.com/MichaIng/DietPi/issues/3356#issuecomment-578215611 - (( $G_HW_MODEL < 10 )) && grep -q '^[[:blank:]]*dtoverlay=vc4-kms-v3d' /boot/config.txt && ((SOUNDCARD_TARGET_CARD++)) - # - RPi4: card 1 is additionally used for the second HDMI port: https://github.com/MichaIng/DietPi/issues/4059 - (( $G_HW_MODEL == 4 )) && grep -q '^[[:blank:]]*dtoverlay=vc4-kms-v3d-pi4' /boot/config.txt && ((SOUNDCARD_TARGET_CARD++)) - # - Cards case "$INPUT_DEVICE_VALUE" in @@ -1929,7 +1966,7 @@ _EOF_ brcm,disable-hdmi = <1>; }; }; -};'\''' +};'\' G_CONFIG_INJECT 'dtoverlay=dietpi-disable_hdmi_audio' 'dtoverlay=dietpi-disable_hdmi_audio' /boot/config.txt # Force HDMI output? @@ -1947,7 +1984,7 @@ _EOF_ brcm,disable-headphones = <1>; }; }; -};'\''' +};'\' G_CONFIG_INJECT 'dtoverlay=dietpi-disable_headphones' 'dtoverlay=dietpi-disable_headphones' /boot/config.txt G_CONFIG_INJECT 'hdmi_drive=' 'hdmi_drive=2' /boot/config.txt (( $G_HW_MODEL == 4 )) && G_CONFIG_INJECT 'hdmi_drive:1=' 'hdmi_drive:1=2' /boot/config.txt 'hdmi_drive=' @@ -2029,8 +2066,7 @@ _EOF_ cat << _EOF_ > /etc/systemd/system/odroid-hifishield2.service [Unit] -Description=odroid-hifishield2 -After=local-fs.target +Description=Odroid HiFi Shield 2 activation [Service] Type=oneshot @@ -2247,6 +2283,11 @@ _EOF_ RPi_Camera_Main + elif [[ $INPUT_DEVICE_NAME == 'rpi-codec' ]]; then + + RPi_Codec_Main + + elif [[ $INPUT_DEVICE_NAME == 'rpi3_usb_boot' ]]; then RPi_USB_Boot_Main diff --git a/dietpi/func/dietpi-set_software b/dietpi/func/dietpi-set_software index c3fe3678a3..724613dad6 100644 --- a/dietpi/func/dietpi-set_software +++ b/dietpi/func/dietpi-set_software @@ -250,9 +250,6 @@ deb $INPUT_MODE_VALUE $G_DISTRO_NAME-backports main contrib non-free' > /etc/apt [[ $INPUT_MODE_VALUE ]] || INPUT_MODE_VALUE=$(sed -n '/^[[:blank:]]*CONFIG_NTP_MODE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) [[ $INPUT_MODE_VALUE ]] || INPUT_MODE_VALUE=2 - # Disable temporarily, prevents run_ntpd in dietpi-software - sed -i '/CONFIG_NTP_MODE=/c\CONFIG_NTP_MODE=0' /boot/dietpi.txt - local ntp_mirror=$(sed -n '/^[[:blank:]]*CONFIG_NTP_MIRROR=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) [[ $ntp_mirror ]] || ntp_mirror='default' @@ -302,23 +299,28 @@ deb $INPUT_MODE_VALUE $G_DISTRO_NAME-backports main contrib non-free' > /etc/apt fi - # Daemon mode: dbus required for timedatectl, that users may expect + # Since Bullseye, systemd-timesyncd is a dedicated package + local timesyncd + (( $G_DISTRO < 6 )) || timesyncd='systemd-timesyncd' + + # Daemon mode: dbus required for timedatectl which users may expect if [[ $INPUT_MODE_VALUE == 4 ]] then - G_AG_CHECK_INSTALL_PREREQ dbus + G_AG_CHECK_INSTALL_PREREQ $timesyncd dbus G_EXEC systemctl unmask systemd-timesyncd # Failsafe G_EXEC systemctl enable --now systemd-timesyncd # Oneshot modes: Enable systemd-timesyncd to start early at boot, but stop it now elif [[ $INPUT_MODE_VALUE == [123] ]] then + [[ $timesyncd ]] && G_AG_CHECK_INSTALL_PREREQ $timesyncd G_EXEC systemctl unmask systemd-timesyncd # Failsafe G_EXEC systemctl enable systemd-timesyncd G_EXEC systemctl stop systemd-timesyncd # Custom mode: Disable systemd-timesyncd to let other time sync system take control else - G_EXEC systemctl disable --now systemd-timesyncd + systemctl -q is-enabled systemd-timesyncd 2> /dev/null || systemctl -q is-active systemd-timesyncd && G_EXEC systemctl disable --now systemd-timesyncd fi # Update dietpi.txt diff --git a/dietpi/func/run_ntpd b/dietpi/func/run_ntpd index 4a58da9ce9..bea5b92c96 100644 --- a/dietpi/func/run_ntpd +++ b/dietpi/func/run_ntpd @@ -29,15 +29,15 @@ EXIT_CODE=1 MAX_LOOPS_CHECK=${MAX_LOOPS_CHECK:-60} # seconds - Update_NTPD(){ - + Update_NTPD() + { NTP_UPDATE_MODE=$(sed -n '/^[[:blank:]]*CONFIG_NTP_MODE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) # Assume status okay when manual mode is detected if [[ $NTP_UPDATE_MODE != [1-4] ]] then G_DIETPI-NOTIFY 2 'Manual mode detected, skipping time sync' EXIT_CODE=0 - return + return 0 fi # Loop NTP check until success, or, non-G_INTERACTIVE and timeout @@ -52,16 +52,12 @@ then G_DIETPI-NOTIFY 2 'Time sync completed' EXIT_CODE=0 - (( $NTP_UPDATE_MODE < 4 )) && systemctl stop systemd-timesyncd break 2 elif [[ $i == "$MAX_LOOPS_CHECK" ]] then G_DIETPI-NOTIFY 2 'Time sync timed out' - # Exit if non-interactive - [[ $G_INTERACTIVE == 1 ]] || break 2 - G_WHIP_MENU_ARRAY=( 'Retry' ': (Recommended) Rerun network time sync' @@ -70,9 +66,9 @@ ) - G_WHIP_BUTTON_CANCEL_TEXT='Retry' + G_WHIP_DEFAULT_ITEM='Retry' G_WHIP_MENU 'Network time sync has not yet completed or failed to update.\nTo prevent issues with outdated system time during installations, please select an option below.\n -NB: We highly recommend choosing "Retry" first. Failing that, try to change the "NTP mirror".\n"Override" is a last resort and may cause follow-up issues due to incorrect system clock time.' +NB: We highly recommend choosing "Retry" first. Failing that, try to change the "NTP mirror".\n"Override" is a last resort and may cause follow-up issues due to incorrect system clock time.' || break 2 if [[ $G_WHIP_RETURNED_VALUE == 'NTP mirror' ]] then @@ -90,13 +86,13 @@ NB: We highly recommend choosing "Retry" first. Failing that, try to change the done done - # Create flag file on success - if [[ $EXIT_CODE == 0 && ! -f '/run/systemd/timesync/synchronized' ]] - then - [[ -d '/run/systemd/timesync' ]] || G_EXEC mkdir -p /run/systemd/timesync - > /run/systemd/timesync/synchronized - fi + # Stop service on oneshot modes + (( $NTP_UPDATE_MODE < 4 )) && systemctl stop systemd-timesyncd + # Create flag file on success: Since Buster this is created by systemd-timesyncd already, but removed on service stop. + [[ $EXIT_CODE == 0 && ! -f '/run/systemd/timesync/synchronized' ]] || return $EXIT_CODE + [[ -d '/run/systemd/timesync' ]] || G_EXEC mkdir -p /run/systemd/timesync + > /run/systemd/timesync/synchronized } #///////////////////////////////////////////////////////////////////////////////////// diff --git a/dietpi/misc/dietpi-justboom b/dietpi/misc/dietpi-justboom index 5e5f49961d..778d3ad555 100644 --- a/dietpi/misc/dietpi-justboom +++ b/dietpi/misc/dietpi-justboom @@ -9,7 +9,7 @@ #//////////////////////////////////// # # Info: - # - Tweak your high-end JustBoom soundcard + # - Tweak your sound card, MPD and CAVA settings # Usage: # - /boot/dietpi/misc/dietpi-justboom #//////////////////////////////////// @@ -25,8 +25,8 @@ # Prereq ALSA installed from dietpi-software if [[ ! -f '/etc/asound.conf' ]] || ! dpkg-query -s alsa-utils &> /dev/null; then - G_WHIP_MSG "$G_PROGRAM_NAME requires ALSA to be installed and a soundcard to be configured.\n -Please select a soundcard via 'dietpi-config' or install ALSA, or ideally an audio application, through 'dietpi-software' before use." + G_WHIP_MSG "$G_PROGRAM_NAME requires ALSA to be installed and a sound card to be configured.\n +Please select a sound card via 'dietpi-config' or install ALSA, or ideally an audio application, through 'dietpi-software' before use." exit 1 fi diff --git a/dietpi/patch_file b/dietpi/patch_file index d0ca6a7333..e28570b225 100644 --- a/dietpi/patch_file +++ b/dietpi/patch_file @@ -585,7 +585,7 @@ _EOF_' fi #------------------------------------------------------------------------------- - # Fix Apache2 logging to "/error.log" instead of "/var/log/apache2/error.log": https://github.com/MichaIng/DietPi/commit/c991bd7dc579dbdc7c239e4c887b0962fa204006 + # Fix Apache logging to "/error.log" instead of "/var/log/apache2/error.log": https://github.com/MichaIng/DietPi/commit/c991bd7dc579dbdc7c239e4c887b0962fa204006 for vhost in /etc/apache2/sites-available/*.conf do @@ -2124,11 +2124,6 @@ _EOF_ G_DIETPI-NOTIFY 2 'Removing old DietPi-LED_control config and script location' rm -fv /boot/dietpi/{.,func/}dietpi-led_control #------------------------------------------------------------------------------- - G_DIETPI-NOTIFY 2 'Installing vmtouch as replacement for DietPi-RAMdisk' # https://github.com/MichaIng/DietPi/issues/3288 - G_EXEC curl -sSfLO "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/vmtouch_$G_HW_ARCH_NAME.deb" - G_AGI "./vmtouch_$G_HW_ARCH_NAME.deb" - rm "vmtouch_$G_HW_ARCH_NAME.deb" - #------------------------------------------------------------------------------- G_DIETPI-NOTIFY 2 'Removing obsolete flag files' rm -fv /boot/dietpi/.{update_available,timesync_exit_status,network} /var/lib/dietpi/.ntpd_override /tmp/.dietpi_motd #------------------------------------------------------------------------------- diff --git a/rootfs/etc/cron.hourly/dietpi b/rootfs/etc/cron.hourly/dietpi index 223ceea7bb..8fcc994754 100644 --- a/rootfs/etc/cron.hourly/dietpi +++ b/rootfs/etc/cron.hourly/dietpi @@ -20,14 +20,14 @@ grep -q '^[[:blank:]]*CONFIG_NTP_MODE=3' /boot/dietpi.txt && /boot/dietpi/func/run_ntpd 1 #---------------------------------------------------------------- # Clear /var/log files, if DietPi-RAMlog is detected - [[ -f '/boot/dietpi/.installed' ]] && LOGGING_MODE=$(sed -n '/^[[:blank:]]*INDEX_LOGGING_CURRENT=/{s/^[^=]*=//p;q}' /boot/dietpi/.installed) + [[ -f '/boot/dietpi/.installed' ]] && INDEX_LOGGING=$(sed -n '/^[[:blank:]]*INDEX_LOGGING=/{s/^[^=]*=//p;q}' /boot/dietpi/.installed) # - Mode -1: Clear only - if (( ${LOGGING_MODE:=0} == -1 )); then + if (( ${INDEX_LOGGING:=0} == -1 )); then /boot/dietpi/func/dietpi-logclear 1 - # - Mode -2: Append logs to /root/logfile_storage/*, then clear - elif (( $LOGGING_MODE == -2 )); then + # - Mode -2: Append logs at /root/logfile_storage, then clear + elif (( $INDEX_LOGGING == -2 )); then /boot/dietpi/func/dietpi-logclear 0 diff --git a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash index 44b0b502ba..672a4199f5 100755 --- a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash +++ b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash @@ -148,7 +148,7 @@ # Apply headless mode if set in dietpi.txt (RPi, Odroid C1/C2) (( $G_HW_MODEL < 11 || $G_HW_MODEL == 12 )) && /boot/dietpi/func/dietpi-set_hardware headless "$(grep -cm1 '^[[:blank:]]*AUTO_SETUP_HEADLESS=1' /boot/dietpi.txt)" - # Apply forced eth speed, if set in dietpi.txt + # Apply forced Ethernet link speed if set in dietpi.txt /boot/dietpi/func/dietpi-set_hardware eth-forcespeed "$(sed -n '/^[[:blank:]]*AUTO_SETUP_NET_ETH_FORCE_SPEED=/{s/^[^=]*=//p;q}' /boot/dietpi.txt)" # Set hostname @@ -251,7 +251,7 @@ _EOF_ # - Ethernet elif (( $ethernet_enabled )); then - # Enable Eth, disable WiFi + # Enable Ethernet, disable WiFi wifi_enabled=0 sed -Ei "/(allow-hotplug|auto)[[:blank:]]+eth/c\allow-hotplug $iface_eth" /etc/network/interfaces sed -Ei "/(allow-hotplug|auto)[[:blank:]]+wlan/c\#allow-hotplug $iface_wlan" /etc/network/interfaces @@ -284,14 +284,14 @@ _EOF_ > /etc/resolv.conf for i in $static_dns; do echo "nameserver $i" >> /etc/resolv.conf; done + sed -i "/dns-nameservers/c\#dns-nameservers $static_dns" /etc/network/interfaces fi fi # - IPv6 - local enable_ipv6=$(grep -cm1 '^[[:blank:]]*CONFIG_ENABLE_IPV6=1' /boot/dietpi.txt) - /boot/dietpi/func/dietpi-set_hardware enableipv6 "$enable_ipv6" + /boot/dietpi/func/dietpi-set_hardware enableipv6 "$(( ! $(grep -cm1 '^[[:blank:]]*CONFIG_ENABLE_IPV6=0' /boot/dietpi.txt) ))" # - Configure enabled interfaces now, /etc/network/interfaces will be effective from next boot on # Failsafe: Bring up Ethernet, whenever WiFi is disabled or fails to be configured, e.g. due to wrong credentials @@ -324,7 +324,7 @@ _EOF_ # Set install stage index to trigger automated DietPi-Update on login echo 0 > /boot/dietpi/.install_stage - # Disable originating service to prevent any futher launch of this script + # Disable originating service to prevent any further launch of this script systemctl disable dietpi-firstboot #----------------------------------------------------------------------------------- exit diff --git a/rootfs/var/lib/dietpi/services/fs_partition_resize.sh b/rootfs/var/lib/dietpi/services/fs_partition_resize.sh index a79487d3ec..7e2b419f75 100644 --- a/rootfs/var/lib/dietpi/services/fs_partition_resize.sh +++ b/rootfs/var/lib/dietpi/services/fs_partition_resize.sh @@ -54,7 +54,7 @@ # Maximise root partition size sfdisk --no-reread --no-tell-kernel -fN"$ROOT_PART" "$ROOT_DRIVE" <<< ',+' - # Inform kernel about changed partition table, be failsafe by using two differet methods and reboot if any fails + # Inform kernel about changed partition table, be failsafe by using two different methods and reboot if any fails partprobe "$ROOT_DRIVE" || Reboot_to_load_Partition_table partx -u "$ROOT_DRIVE" || Reboot_to_load_Partition_table else