From d93eb4fa7ee3447a6481470f1d6864b421aec7ff Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 17 Oct 2021 15:41:58 +0200 Subject: [PATCH 01/82] Init v7.8 + General | Init v7.8 development cycle --- .meta/dietpi-survey_report | 9 ++++++++- .update/patches | 7 ++++++- .update/version | 4 ++-- CHANGELOG.txt | 21 ++++++++++++++++----- dietpi/func/dietpi-globals | 4 ++-- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index 9abc89b35d..13eee5e773 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -566,8 +566,15 @@ shopt -s extglob done unset -v 'aSOFTWARE_NAME7_7[142]' # CouchPotato + # v7.8 + aSOFTWARE_NAME7_8=() + for i in "${!aSOFTWARE_NAME7_7[@]}" + do + aSOFTWARE_NAME7_8[$i]=${aSOFTWARE_NAME7_7[$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_7[@]}" + for i in "${aSOFTWARE_NAME7_8[@]}" do aSOFTWARE["$i"]=0 done diff --git a/.update/patches b/.update/patches index a2f371ca65..c478157e43 100644 --- a/.update/patches +++ b/.update/patches @@ -39,7 +39,7 @@ export G_SERVICE_CONTROL=0 # Version-based incremental patches Patch_7_0() { - # Remove obsolete udev rule, as WiFi power saving is disabled via /etc/network/intefaces > "wireless-power off" > /etc/network/if-pre-up.d/wireless-tools (wireless-tools package) when the WiFi interface is configured. + # Remove obsolete udev rule, as WiFi power saving is disabled via /etc/network/interfaces > "wireless-power off" > /etc/network/if-pre-up.d/wireless-tools (wireless-tools package) when the WiFi interface is configured. [[ -f '/etc/udev/rules.d/10-wifi-disable-powermanagement.rules' ]] && G_EXEC rm /etc/udev/rules.d/10-wifi-disable-powermanagement.rules } @@ -460,6 +460,11 @@ _EOF_ fi } +Patch_7_8() +{ + : +} + # v6.35 => v7 migration if (( $G_DIETPI_VERSION_CORE == 6 && $G_DIETPI_VERSION_SUB > 34 )) then diff --git a/.update/version b/.update/version index 98656e703a..f4a522152f 100644 --- a/.update/version +++ b/.update/version @@ -1,7 +1,7 @@ # Available DietPi version G_REMOTE_VERSION_CORE=7 -G_REMOTE_VERSION_SUB=7 -G_REMOTE_VERSION_RC=3 +G_REMOTE_VERSION_SUB=8 +G_REMOTE_VERSION_RC=-1 # Minimum DietPi version to allow update G_MIN_VERSION_CORE=6 G_MIN_VERSION_SUB=0 diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 21ad4457c4..64da8bc5c7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,19 @@ +v7.8 +(2021-10-13) + +Changes: + +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/XXXX + +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 (2021-10-16) @@ -44,11 +60,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/4840 -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.6 diff --git a/dietpi/func/dietpi-globals b/dietpi/func/dietpi-globals index 93ef520a4d..ab9267bf6a 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=7 - [[ $G_DIETPI_VERSION_RC ]] || G_DIETPI_VERSION_RC=3 + [[ $G_DIETPI_VERSION_SUB ]] || G_DIETPI_VERSION_SUB=8 + [[ $G_DIETPI_VERSION_RC ]] || G_DIETPI_VERSION_RC=-1 [[ $G_GITBRANCH ]] || G_GITBRANCH='master' [[ $G_GITOWNER ]] || G_GITOWNER='MichaIng' # - Save current version and Git branch From ced400f252eed52d3b411d6dd0e4c09725d3ca35 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 17 Oct 2021 16:16:33 +0200 Subject: [PATCH 02/82] v7.7 + DietPi-Patches | Fix applying boot wait for network migration --- .update/patches | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.update/patches b/.update/patches index c478157e43..72e7736c88 100644 --- a/.update/patches +++ b/.update/patches @@ -412,7 +412,7 @@ _EOF_ then /boot/dietpi/func/dietpi-set_software boot_wait_for_network 0 - elif ! grep -q 'AUTO_SETUP_BOOT_WAIT_FOR_NETWORK' /boot/dietpi.txt + elif grep -q '^[[:blank:]]*CONFIG_BOOT_WAIT_FOR_NETWORK=' /boot/dietpi.txt then /boot/dietpi/func/dietpi-set_software boot_wait_for_network 1 fi From 347a7c070fed431b4f8835227902398bea9dafb6 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 17 Oct 2021 16:17:53 +0200 Subject: [PATCH 03/82] v7.7 + DietPi-Patches | Fix applying boot wait for network migration --- .update/patches | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.update/patches b/.update/patches index a2f371ca65..6ae3296e23 100644 --- a/.update/patches +++ b/.update/patches @@ -412,7 +412,7 @@ _EOF_ then /boot/dietpi/func/dietpi-set_software boot_wait_for_network 0 - elif ! grep -q 'AUTO_SETUP_BOOT_WAIT_FOR_NETWORK' /boot/dietpi.txt + elif grep -q '^[[:blank:]]*CONFIG_BOOT_WAIT_FOR_NETWORK=' /boot/dietpi.txt then /boot/dietpi/func/dietpi-set_software boot_wait_for_network 1 fi From 23947778bf7d96631cd62ff8f81df8bd43a43e9b Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 17 Oct 2021 19:58:01 +0200 Subject: [PATCH 04/82] v7.8 + DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 --- CHANGELOG.txt | 1 + dietpi/dietpi-software | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 64da8bc5c7..a6830e51d9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,7 @@ v7.8 Changes: Fixes: +- DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 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/XXXX diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 61364fe7bb..d6aaac2695 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -12321,6 +12321,7 @@ _EOF_ [[ -f '/etc/default/icecast2' ]] && G_EXEC rm /etc/default/icecast2 # DarkIce + [[ -f '/etc/darkice.cfg' ]] || > /etc/darkice.cfg G_EXEC chmod 0600 /etc/darkice.cfg local input_device_index=$(arecord -l | mawk -F'[ :]' '/card/{print $2;exit}') cat << _EOF_ > /etc/darkice.cfg From 1d8c8a3dcf27a5ff879c76a1c682536c8102080f Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 14:39:08 +0200 Subject: [PATCH 05/82] v7.8 + DietPi-PREP | Do not try to enable removed DietPi-Boot service --- PREP_SYSTEM_FOR_DIETPI.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 903662f33e..9687c6909a 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1339,7 +1339,6 @@ _EOF_ G_DIETPI-NOTIFY 2 'Enabling DietPi services' G_EXEC systemctl enable dietpi-ramlog G_EXEC systemctl enable dietpi-preboot - G_EXEC systemctl enable dietpi-boot G_EXEC systemctl enable dietpi-postboot G_EXEC systemctl enable dietpi-kill_ssh From 66da0cc92323ffcde8bc3bdd43bb918fac7512fd Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 16:09:23 +0200 Subject: [PATCH 06/82] v7.8 + DietPi-PREP | Add support for older Bullseye images where it was still the "testing" version --- PREP_SYSTEM_FOR_DIETPI.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 9687c6909a..3afb6934eb 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -189,7 +189,7 @@ _EOF_ G_DISTRO=5 G_DISTRO_NAME='buster' - elif [[ $distro == '11.'* ]]; then + elif [[ $distro == '11.'* || $distro == 'bullseye/sid' ]]; then G_DISTRO=6 G_DISTRO_NAME='bullseye' From 07069bd8d788f9ade244780038c16d1876eea44c Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 16:23:52 +0200 Subject: [PATCH 07/82] v7.7 + DietPi-PREP | Do not try to enable the removed dietpi-boot.service --- PREP_SYSTEM_FOR_DIETPI.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 903662f33e..9687c6909a 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1339,7 +1339,6 @@ _EOF_ G_DIETPI-NOTIFY 2 'Enabling DietPi services' G_EXEC systemctl enable dietpi-ramlog G_EXEC systemctl enable dietpi-preboot - G_EXEC systemctl enable dietpi-boot G_EXEC systemctl enable dietpi-postboot G_EXEC systemctl enable dietpi-kill_ssh From c0630f12bf654289e5e9e51c6bc84fa350beb2be Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 16:36:47 +0200 Subject: [PATCH 08/82] v7.8 + DietPi-Imager | Upload archive automatically if there is an upload.sh in the same directory --- .meta/dietpi-imager | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.meta/dietpi-imager b/.meta/dietpi-imager index 28505d1221..0f31881f84 100755 --- a/.meta/dietpi-imager +++ b/.meta/dietpi-imager @@ -623,6 +623,9 @@ _EOF_ Final image file: $PWD/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT Final 7z archive: $PWD/$OUTPUT_IMG_NAME.7z" + # Upload archive automatically if there is an upload.sh in the same directory + [[ -x 'upload.sh' ]] && ./upload.sh "$OUTPUT_IMG_NAME.7z" + } #///////////////////////////////////////////////////////////////////////////////////// From 30eab8e6203217b3436735105fb9b0f7fafba03f Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 16:53:07 +0200 Subject: [PATCH 09/82] v7.8 + DietPi-FirstBoot | Update service to start before dietpi-postboot.service instead of before removed dietpi-boot.service --- rootfs/etc/systemd/system/dietpi-firstboot.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootfs/etc/systemd/system/dietpi-firstboot.service b/rootfs/etc/systemd/system/dietpi-firstboot.service index 3796aef851..a7c6a7c62e 100644 --- a/rootfs/etc/systemd/system/dietpi-firstboot.service +++ b/rootfs/etc/systemd/system/dietpi-firstboot.service @@ -3,7 +3,7 @@ Description=DietPi-FirstBoot setup # Order 2.5 Requisite=dietpi-preboot.service After=dietpi-preboot.service -Before=network-pre.target dietpi-boot.service +Before=network-pre.target dietpi-postboot.service [Service] Type=oneshot From 9bcd9b0a96145d075ac56a3950f378a711ee1414 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 18:10:27 +0200 Subject: [PATCH 10/82] v7.8 + DietPi-Survey_report | Be more verbose about why a survey upload was found to be invalid --- .meta/dietpi-survey_report | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index 13eee5e773..74d535a8b9 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -617,20 +617,34 @@ shopt -s extglob 'BENCH_CPU_TEMP_START='*) BENCH_CPU_TEMP_START=${line#*\'} BENCH_CPU_TEMP_START=${BENCH_CPU_TEMP_START%\'};; 'BENCH_CPU_TEMP_END='*) BENCH_CPU_TEMP_END=${line#*\'} BENCH_CPU_TEMP_END=${BENCH_CPU_TEMP_END%\'};; 'BENCH_NET_LAN_SPEED='*) BENCH_NET_LAN_SPEED=${line#*\'} BENCH_NET_LAN_SPEED=${BENCH_NET_LAN_SPEED%\'};; - *) mv -v "/home/dietpi-survey/survey/$file" /home/dietpi-survey/invalid/; return 1;; # Invalid line + *) + echo "Invalid line: $line" + mv -v "/home/dietpi-survey/survey/$file" /home/dietpi-survey/invalid/ + return 1 + ;; esac # Validate and process software name if present [[ $software ]] || continue eval "software=\${aSOFTWARE_NAME${version/./_}[$software]}" - [[ $software ]] || { mv -v "/home/dietpi-survey/survey/$file" /home/dietpi-survey/invalid/; return 1; } + if [[ ! $software ]] + then + echo "Invalid software ID for DietPi version $version" + mv -v "/home/dietpi-survey/survey/$file" /home/dietpi-survey/invalid/ + return 1 + fi asoftware+=("$software") unset -v software done < "$file" # Values that must exist - [[ $version && $device && $arch && $cpu_count && $distro && $autostart && ${aAUTOSTART_NAME[$autostart]} && $automated && $iface ]] || { mv -v "/home/dietpi-survey/survey/$file" /home/dietpi-survey/invalid/; return 1; } + if ! [[ $version && $device && $arch && $cpu_count && $distro && $autostart && ${aAUTOSTART_NAME[$autostart]} && $automated && $iface ]] + then + echo 'Missing survey value' + mv -v "/home/dietpi-survey/survey/$file" /home/dietpi-survey/invalid/ + return 1 + fi # Sort out files that are > 6 months old (( $DATE_NOW - $(date -u '+%s' -r "$file") < 15724800 )) || { mv "/home/dietpi-survey/survey/$file" /home/dietpi-survey/old/; ((SURVEY_COUNT_INACTIVE++)); return 0; } @@ -738,7 +752,12 @@ shopt -s extglob for file in * do # Skip and move away match with invalid name or when not a file - [[ $file =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.txt$ && -f $file ]] || { mv -v "/home/dietpi-survey/survey/$file" /home/dietpi-survey/invalid/; continue; } + if ! [[ $file =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.txt$ && -f $file ]] + then + echo 'Invalid file name' + mv -v "/home/dietpi-survey/survey/$file" /home/dietpi-survey/invalid/ + continue + fi # Optout files if [[ ! -s $file ]] From de64f6d25403eaa4d37affba20b6acd6b70837d7 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 18:39:54 +0200 Subject: [PATCH 11/82] v7.8 + DietPi-FirstBoot | Mute error messages when obtaining an interface for a non-existing type --- rootfs/var/lib/dietpi/services/dietpi-firstboot.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash index e298c6cf4d..73417492a6 100755 --- a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash +++ b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash @@ -217,9 +217,9 @@ _EOF_ # Network setup # - Grab available network interfaces - local iface_eth=$(G_GET_NET -t eth iface) + local iface_eth=$(G_GET_NET -q -t eth iface) [[ $iface_eth ]] || iface_eth='eth0' - local iface_wlan=$(G_GET_NET -t wlan iface) + local iface_wlan=$(G_GET_NET -q -t wlan iface) [[ $iface_wlan ]] || iface_wlan='wlan0' # - Replace interface names with the ones obtained above From 75eda7963faafabc135f9645a138826f6a014d96 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 18:42:17 +0200 Subject: [PATCH 12/82] v7.8 + DietPi-Globals | G_GET_NET: Print errors as error messages to STDERR --- dietpi/func/dietpi-globals | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dietpi/func/dietpi-globals b/dietpi/func/dietpi-globals index ab9267bf6a..3746a4be57 100644 --- a/dietpi/func/dietpi-globals +++ b/dietpi/func/dietpi-globals @@ -462,7 +462,7 @@ $grey───────────────────────── # Update backtitle WHIP_BACKTITLE=$G_HW_MODEL_NAME - local active_ip=$(G_GET_NET ip) + local active_ip=$(G_GET_NET -q ip) [[ $active_ip ]] && WHIP_BACKTITLE+=" | IP: $active_ip" # Set default button text, if not defined @@ -1291,25 +1291,25 @@ $log_content" || break # Exit error handler menu loop on cancel '-t') shift; type=$1;; '-i') shift; iface=$1;; 'gateway'|'iface'|'ip') command=$1;; - *) G_DIETPI-NOTIFY 2 "An invalid argument \"${1:-}\" was given."; return 1;; + *) G_DIETPI-NOTIFY 1 "An invalid argument \"${1:-}\" was given."; return 1;; esac shift done # A command is required - [[ $command ]] || { G_DIETPI-NOTIFY 2 "No command was given."; return 1; } + [[ $command ]] || { G_DIETPI-NOTIFY 1 "No command was given."; return 1; } # Early return if given interface does not exists or does not match given type if [[ $iface ]] then if [[ ! -e /sys/class/net/$iface ]] then - (( $quite )) || G_DIETPI-NOTIFY 2 "The given interface \"$iface\" does not exist." + (( $quite )) || G_DIETPI-NOTIFY 1 "The given interface \"$iface\" does not exist." return 1 elif [[ $type && $iface != $type* ]] then - (( $quite )) || G_DIETPI-NOTIFY 2 "The given interface \"$iface\" is not of type \"$type\"." + (( $quite )) || G_DIETPI-NOTIFY 1 "The given interface \"$iface\" is not of type \"$type\"." return 1 fi fi @@ -1333,12 +1333,12 @@ $log_content" || break # Exit error handler menu loop on cancel # Check for interface type if [[ $type && $if != $type* ]] then - (( $quite )) || G_DIETPI-NOTIFY 2 "The default gateway is not assigned to any interface of type \"$type\"." + (( $quite )) || G_DIETPI-NOTIFY 1 "The default gateway is not assigned to any interface of type \"$type\"." return 1 fi echo "$gateway" else - (( $quite )) || G_DIETPI-NOTIFY 2 "A default gateway${fam:+ for IPv${fam#-}}${iface:+ on interface \"$iface\"} does not exist." + (( $quite )) || G_DIETPI-NOTIFY 1 "A default gateway${fam:+ for IPv${fam#-}}${iface:+ on interface \"$iface\"} does not exist." return 1 fi return 0 @@ -1388,12 +1388,12 @@ $log_content" || break # Exit error handler menu loop on cancel ip=$ip_final ip=${ip%%/*} if [[ $command == 'ip' && ! $ip ]] then - (( $quite )) || G_DIETPI-NOTIFY 2 "An interface${iface:+ named \"$iface\"}${type:+ of type \"$type\"} with an IP${fam:+v${fam#-}} address does not exist." + (( $quite )) || G_DIETPI-NOTIFY 1 "An interface${iface:+ named \"$iface\"}${type:+ of type \"$type\"} with an IP${fam:+v${fam#-}} address does not exist." return 1 elif [[ $command == 'iface' && ! $iface ]] then - (( $quite )) || G_DIETPI-NOTIFY 2 "An interface${iface:+ named \"$iface\"}${type:+ of type \"$type\"}${fam:+ with an IPv${fam#-} address} does not exist." + (( $quite )) || G_DIETPI-NOTIFY 1 "An interface${iface:+ named \"$iface\"}${type:+ of type \"$type\"}${fam:+ with an IPv${fam#-} address} does not exist." return 1 fi echo "${!command}" From 444a368768202ddde3c0e5b39881eb05bd861703 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 19:02:05 +0200 Subject: [PATCH 13/82] v7.8 + DietPi-PREP | Temporary fix for invalid interfaces at DietPi-FirstBoot --- PREP_SYSTEM_FOR_DIETPI.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 3afb6934eb..b8222531d3 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -620,6 +620,9 @@ Currently installed: $G_DISTRO_NAME (ID: $G_DISTRO)"; then G_CONFIG_INJECT "G_LIVE_PATCH_STATUS\[$i\]=" "G_LIVE_PATCH_STATUS[$i]='${G_LIVE_PATCH_STATUS[$i]}'" /boot/dietpi/.version done + # Temporary fix for invalid interfaces at DietPi-FirstBoot + G_EXEC sed -i 's/G_GET_NET -t/G_GET_NET -q -t/' /var/lib/dietpi/services/dietpi-firstboot.bash + G_EXEC cp /boot/dietpi/.version /var/lib/dietpi/.dietpi_image_version G_EXEC systemctl daemon-reload From 4b7b66f052eb9ba4e22d2ba567fe29d5b09037d2 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 19:03:26 +0200 Subject: [PATCH 14/82] v7.7 + DietPi-PREP | Temporary fix for invalid interfaces at DietPi-FirstBoot --- PREP_SYSTEM_FOR_DIETPI.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 9687c6909a..7ee7c4e907 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -620,6 +620,9 @@ Currently installed: $G_DISTRO_NAME (ID: $G_DISTRO)"; then G_CONFIG_INJECT "G_LIVE_PATCH_STATUS\[$i\]=" "G_LIVE_PATCH_STATUS[$i]='${G_LIVE_PATCH_STATUS[$i]}'" /boot/dietpi/.version done + # Temporary fix for invalid interfaces at DietPi-FirstBoot + G_EXEC sed -i 's/G_GET_NET -t/G_GET_NET -q -t/' /var/lib/dietpi/services/dietpi-firstboot.bash + G_EXEC cp /boot/dietpi/.version /var/lib/dietpi/.dietpi_image_version G_EXEC systemctl daemon-reload From 2f098222720bdbce411c3a7e5ad267d8aa33c733 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 19:45:20 +0200 Subject: [PATCH 15/82] v7.8 + DietPi-PREP | Assure sufficiently large /tmp tmpfs mount. Running PREP in an ARMv7 Raspberry Pi somehow leads to a 98 MiB /tmp mount, for a currently unknown reason since on the host system the default for tmpfs is ~512 MiB. --- PREP_SYSTEM_FOR_DIETPI.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index b8222531d3..3148d0976e 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -50,7 +50,12 @@ export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' # Make /tmp a tmpfs if it is not yet a dedicated mount - findmnt -M /tmp > /dev/null || mount -t tmpfs tmpfs /tmp + if findmnt -M /tmp > /dev/null + then + (( $(findmnt -Ufnrbo SIZE -M /tmp) < 536870912 )) && mount -o remount,size=536870912 /tmp + else + mount -t tmpfs -o size=536870912 tmpfs /tmp + fi # Work inside /tmp tmpfs to reduce disk I/O and speed up download and unpacking # - Save full script path beforehand: https://github.com/MichaIng/DietPi/pull/2341#discussion_r241784962 From 2ae0e054ace81b89108e7223b2b9fc9b4cdea3bc Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 20:14:49 +0200 Subject: [PATCH 16/82] v7.8 + DietPi-PREP | Add U-Boot package auto-detection for generic images --- PREP_SYSTEM_FOR_DIETPI.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 3148d0976e..096794a8f7 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1010,10 +1010,10 @@ _EOF_ # NB: rockpis-dtbo is not required as it doubles the overlays that are already provided (among others) with the kernel package G_AGI rockpis-rk-ubootimg linux-4.4-rock-pi-s-latest rockchip-overlay u-boot-tools - # - Generic kernel + device tree package auto detect + # - Generic kernel + device tree + U-Boot package auto detect else - mapfile -t apackages < <(dpkg-query -Wf '${Package}\n' | grep -E '^linux-(image|dtb)') + mapfile -t apackages < <(dpkg-query -Wf '${Package}\n' | grep -E '^linux-(image|dtb|u-boot)-|^u-boot') if [[ ${apackages[0]} ]]; then G_AGI "${apackages[@]}" From 85d5723ac86044b57999448d0411228d8719bf6f Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 20:49:47 +0200 Subject: [PATCH 17/82] v7.8 + DietPi-PREP | Wait for network at boot by default --- PREP_SYSTEM_FOR_DIETPI.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 096794a8f7..844b54225d 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1418,6 +1418,9 @@ _EOF_' # Prefer IPv4 by default /boot/dietpi/func/dietpi-set_hardware preferipv4 enable + # Wait for network at boot by default + /boot/dietpi/func/dietpi-set_hardware boot_wait_for_network 1 + #----------------------------------------------------------------------------------- # MISC G_DIETPI-NOTIFY 2 'Disabling apt-daily services to prevent random APT cache lock' From 367b289d2fb8437537f3bfb85399d3a1a1452b8a Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 20:50:57 +0200 Subject: [PATCH 18/82] v7.8 + DietPi-Login | Remove trailing tabs --- dietpi/dietpi-login | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dietpi/dietpi-login b/dietpi/dietpi-login index 2a1550cac3..1985a8f26d 100644 --- a/dietpi/dietpi-login +++ b/dietpi/dietpi-login @@ -88,7 +88,7 @@ elif (( $auto_start_index == 11 )); then exec /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh - + # Custom script after autologin elif [[ $auto_start_index == 17 && -f '/var/lib/dietpi/dietpi-autostart/custom.sh' ]]; then From 10d652c2a4a0e67e3de61008f295b99e3c35568c Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 18 Oct 2021 21:43:20 +0200 Subject: [PATCH 19/82] v7.8 + DietPi-PREP | Fix boot wait for network script call --- PREP_SYSTEM_FOR_DIETPI.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 844b54225d..baf69c5f13 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1419,7 +1419,7 @@ _EOF_' /boot/dietpi/func/dietpi-set_hardware preferipv4 enable # Wait for network at boot by default - /boot/dietpi/func/dietpi-set_hardware boot_wait_for_network 1 + /boot/dietpi/func/dietpi-set_software boot_wait_for_network 1 #----------------------------------------------------------------------------------- # MISC From 76ead2e52858c0b132be91ff5cc94ce3b7d4e745 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Tue, 19 Oct 2021 00:21:52 +0200 Subject: [PATCH 20/82] v7.8 + DietPi-Software | Jellyfin: The meta package depends on jellyfin-ffmpeg now, hence it doesn't need to be installed explicitly. --- dietpi/dietpi-software | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index d6aaac2695..be5e7f5948 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -8186,8 +8186,8 @@ _EOF_ G_EXEC eval "echo 'deb https://repo.jellyfin.org/debian/ $G_DISTRO_NAME main' > /etc/apt/sources.list.d/dietpi-jellyfin.list" G_AGUP - # APT packages: Jellyfin + FFmpeg implementation - G_AGI jellyfin jellyfin-ffmpeg + # APT meta package: Server, web component and FFmpeg implementation + G_AGI jellyfin fi From 7431afa9f2c72cc5c127038cd4705c739bab23ff Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 20 Oct 2021 01:15:13 +0200 Subject: [PATCH 21/82] v7.8 + DietPi-PREP | Remove old dpkg cache before the script ends: At least the old status file is re-created. Skip the identical removals done earlier in the script. --- PREP_SYSTEM_FOR_DIETPI.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index baf69c5f13..5852a8545f 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1201,10 +1201,6 @@ _EOF_ #[[ -d '/usr/share/doc-base' ]] && rm -vR /usr/share/doc-base [[ -d '/usr/share/calendar' ]] && rm -vR /usr/share/calendar - # - Previous debconfs - rm -fv /var/cache/debconf/*-old - rm -fv /var/lib/dpkg/*-old - # - Unused DEB package config files find /etc \( -name '?*\.dpkg-dist' -o -name '?*\.dpkg-old' -o -name '?*\.dpkg-new' \) -exec rm -v {} + @@ -1923,7 +1919,7 @@ _EOF_ G_EXEC rmdir /mnt/tmp_root G_DIETPI-NOTIFY 2 'Running general cleanup of misc files' - rm -Rfv /{root,home/*}/.{bash_history,nano_history,wget-hsts,cache,local,config,gnupg,viminfo,dbus,gconf,nano,vim,zshrc,oh-my-zsh} /etc/*- /var/cache/debconf/*-old + rm -Rfv /{root,home/*}/.{bash_history,nano_history,wget-hsts,cache,local,config,gnupg,viminfo,dbus,gconf,nano,vim,zshrc,oh-my-zsh} /etc/*- /var/{cache/debconf,lib/dpkg}/*-old # Remove PREP script [[ -f $FP_PREP_SCRIPT ]] && rm -v "$FP_PREP_SCRIPT" From b6f483914c69466fb8ffe756e9768934b1072a03 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 20 Oct 2021 12:52:27 +0200 Subject: [PATCH 22/82] v7.8 + DietPi-Survey_report | Add support fore new foreground+login autostart option --- .meta/dietpi-survey_report | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index 74d535a8b9..2987b63bf0 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -174,9 +174,10 @@ shopt -s extglob [9]='DXX-Rebirth' [10]='CAVA Spectrum' [11]='Chromium' - [14]='Custom' + [14]='Custom (background)' [15]='JRiver' [16]='Desktop LightDM login' + [17]='Custom (foreground)' ) # Convert software index to title array From ef074f73c564c28c721108f8c7c2968dc8e2d549 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 20 Oct 2021 16:17:21 +0200 Subject: [PATCH 23/82] v7.8 + DietPi-Software | Deluge: Fix failing services --- CHANGELOG.txt | 1 + dietpi/dietpi-software | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a6830e51d9..22ec0d12e9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -10,6 +10,7 @@ As always, many smaller code performance and stability improvements, visual and 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 +- DietPi-Software | Deluge: Resolved an issue where on fresh installs the services failed due to an invalid config file syntax. Many thanks to @bookedirl for reporting this issue: https://dietpi.com/phpbb/viewtopic.php?t=9553 For all additional issues that may appear after release, please see the following link for active tickets: https://github.com/MichaIng/DietPi/issues diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index be5e7f5948..797a6d240f 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -4886,15 +4886,15 @@ _EOF_ # Apply optimised settings # - Cache size in 16 KiB units G_CONFIG_INJECT '"cache_size":' " \"cache_size\": $(( $(Optimise_BitTorrent 0) * 1024 / 16 ))," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf - G_CONFIG_INJECT '"max_active_limit":' " \"max_active_limit\": $(Optimise_BitTorrent 1)'," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf + G_CONFIG_INJECT '"max_active_limit":' " \"max_active_limit\": $(Optimise_BitTorrent 1)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf G_CONFIG_INJECT '"max_active_downloading":' " \"max_active_downloading\": $(Optimise_BitTorrent 1)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf G_CONFIG_INJECT '"max_connections_global":' " \"max_connections_global\": $(Optimise_BitTorrent 2)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf G_CONFIG_INJECT '"max_upload_slots_global":' " \"max_upload_slots_global\": $(Optimise_BitTorrent 3)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf # Web UI access local salt=$(tr -dc '0-9a-f' < /dev/random | head -c40) - GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_salt":' " \"pwd_salt\": $salt," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf - GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_sha1":' " \"pwd_sha1\": $(echo -n "$salt$GLOBAL_PW" | sha1sum | mawk '{print $1}')," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf + GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_salt":' " \"pwd_salt\": \"$salt\"," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf + GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_sha1":' " \"pwd_sha1\": \"$(echo -n "$salt$GLOBAL_PW" | sha1sum | mawk '{print $1}')\"," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf # Remote access > /mnt/dietpi_userdata/deluge/.config/deluge/auth From 730f652d425ab796c1d75b3365c643da75a1d89e Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 20 Oct 2021 16:49:04 +0200 Subject: [PATCH 24/82] v7.8 + DietPi-Software | Deluge: Resolve first web UI service startup on Bullseye by pre-creating a localclient API login with a random 40 hex char password: The same is done by deluged, but written to the file only on first service stop, so that the web service cannot read it yet. --- dietpi/dietpi-software | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 797a6d240f..d9c80628e3 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -4897,9 +4897,10 @@ _EOF_ GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_sha1":' " \"pwd_sha1\": \"$(echo -n "$salt$GLOBAL_PW" | sha1sum | mawk '{print $1}')\"," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf # Remote access + local localpass=$(tr -dc '0-9a-f' < /dev/random | head -c40) > /mnt/dietpi_userdata/deluge/.config/deluge/auth G_EXEC chmod 0600 /mnt/dietpi_userdata/deluge/.config/deluge/auth - echo "root:$GLOBAL_PW:10" > /mnt/dietpi_userdata/deluge/.config/deluge/auth + echo -e "root:$GLOBAL_PW:10\nlocalclient:$localpass:10" >> /mnt/dietpi_userdata/deluge/.config/deluge/auth fi # Permissions From 0d1c9097c3c8f916d02391b29469038e5c13e04a Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 20 Oct 2021 16:55:02 +0200 Subject: [PATCH 25/82] v7.8 + DietPi-Software | Deluge: Tiny --- dietpi/dietpi-software | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index d9c80628e3..7581ba218e 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -4900,7 +4900,7 @@ _EOF_ local localpass=$(tr -dc '0-9a-f' < /dev/random | head -c40) > /mnt/dietpi_userdata/deluge/.config/deluge/auth G_EXEC chmod 0600 /mnt/dietpi_userdata/deluge/.config/deluge/auth - echo -e "root:$GLOBAL_PW:10\nlocalclient:$localpass:10" >> /mnt/dietpi_userdata/deluge/.config/deluge/auth + echo -e "root:$GLOBAL_PW:10\nlocalclient:$localpass:10" > /mnt/dietpi_userdata/deluge/.config/deluge/auth fi # Permissions From f488501b95b9f2b15518b73c207f9489ffba781b Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 20 Oct 2021 17:57:55 +0200 Subject: [PATCH 26/82] v7.7 + DietPi-Live-patches | Patch 0: Deluge services fail on fresh installs --- .update/version | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.update/version b/.update/version index 98656e703a..5dcf101b05 100644 --- a/.update/version +++ b/.update/version @@ -12,6 +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=() -G_LIVE_PATCH_COND=() -G_LIVE_PATCH=() +G_LIVE_PATCH_DESC=('Deluge services fail on fresh installs') +G_LIVE_PATCH_COND=('grep -q " \\\$salt," /boot/dietpi/dietpi-software') +G_LIVE_PATCH=('sed -Ei -e "/max_active_limit/s/1\)'\'',\"/1\),\"/" -e "/pwd_salt/s/ \\\$salt,/ \\\\\"\\\$salt\\\\\",/" -e "/pwd_sha1/s/ \\\$\(echo (.*)\),/ \\\\\"\\\$\(echo \1\)\\\\\",/" /boot/dietpi/dietpi-software') From 226db29a952011a4b2b46427e906f4144d5461a9 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 20 Oct 2021 22:55:21 +0200 Subject: [PATCH 27/82] v7.8 + Odroid N1 | Removed support: We don't have a single reported system, which makes sense as this model was never really released. Only a small number of developer samples are floating around, not worth to keep maintaining an image and dedicated code. If there is really an Odroid N1 DietPi system out there, it will be automatically migrated to the Generic Rockchip RK3399 device ID on DietPi update. --- .meta/dietpi-survey_report | 3 +-- .update/patches | 4 ++-- CHANGELOG.txt | 1 + PREP_SYSTEM_FOR_DIETPI.sh | 10 ---------- dietpi/dietpi-software | 12 +----------- dietpi/func/dietpi-obtain_hw_model | 6 ------ 6 files changed, 5 insertions(+), 31 deletions(-) diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index 2987b63bf0..5900661ae5 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -21,7 +21,6 @@ shopt -s extglob [11]='Odroid XU3/XU4/MC1/HC1/HC2' [12]='Odroid C2' [13]='Odroid U3' - [14]='Odroid N1' [15]='Odroid N2' [16]='Odroid C4/HC4' [20]='x86_64 VM' @@ -811,7 +810,7 @@ shopt -s extglob [[ $i == 'NanoPi NEO 2 (aarch64)' ]] && ((aDEVICE_NAME['NanoPi NEO2 (aarch64)']+=aDEVICE_NAME["$i"])) && unset -v "aDEVICE_NAME[$i]" [[ $i == 'NanoPi M3/T3/F3 (aarch64)' ]] && ((aDEVICE_NAME['NanoPi M3/T3/Fire3 (aarch64)']+=aDEVICE_NAME["$i"])) && unset -v "aDEVICE_NAME[$i]" [[ $i == 'NanoPi M3/T3/F3 (armv7l)' ]] && ((aDEVICE_NAME['NanoPi M3/T3/Fire3 (armv7l)']+=aDEVICE_NAME["$i"])) && unset -v "aDEVICE_NAME[$i]" - [[ $i == 'BBB (armv7l)' ]] && ((aDEVICE_NAME['BeagleBone Black (armv7l)']+=aDEVICE_NAME["$i"])) && unset -v "aDEVICE_NAME[$i]" + [[ $i == 'BBB (armv7l)' ]] && ((aDEVICE_NAME['BeagleBone Black (armv7l)']+=aDEVICE_NAME["$i"])) && unset -v "aDEVICE_NAME[$i]" # v7.1 [[ $i == 'Unknown Device (armv7l)' ]] && ((aDEVICE_NAME['Generic Device (armv7l)']+=aDEVICE_NAME["$i"])) && unset -v "aDEVICE_NAME[$i]" [[ $i == 'Unknown Device (aarch64)' ]] && ((aDEVICE_NAME['Generic Device (aarch64)']+=aDEVICE_NAME["$i"])) && unset -v "aDEVICE_NAME[$i]" done diff --git a/.update/patches b/.update/patches index 72e7736c88..9dff071d5a 100644 --- a/.update/patches +++ b/.update/patches @@ -4,12 +4,12 @@ # Created by MichaIng / micha@dietpi.com / https://dietpi.com/ # License: GPLv2 / https://github.com/MichaIng/DietPi#license -# v7.1: Update changed hardware IDs before dietpi-obtain_hw_model would reset them to 22 +# v7.1 + v7.8: Update changed hardware IDs before dietpi-obtain_hw_model would reset them to 22 if [[ -f '/etc/.dietpi_hw_model_identifier' ]] then G_HW_MODEL=$( /etc/.dietpi_hw_model_identifier # Generic Rockchip RK3399 diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 22ec0d12e9..5e02ffff7c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -2,6 +2,7 @@ v7.8 (2021-10-13) Changes: +- Odroid N1 | Removed support: We don't have a single reported system, which makes sense as this model was never really released. Only a small number of developer samples are floating around, not worth to keep maintaining an image and dedicated code. If there is really an Odroid N1 DietPi system out there, it will be automatically migrated to the Generic Rockchip RK3399 device ID on DietPi update. Fixes: - DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 5852a8545f..ffa8ababb2 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -377,7 +377,6 @@ _EOF_ '' '●─ ARM ─ Limited GPU acceleration ' '10' ': Odroid C1' '13' ': Odroid U3' - '14' ': Odroid N1' '70' ': Sparky SBC' '52' ': ASUS Tinker Board' '40' ': PINE A64' @@ -967,15 +966,6 @@ _EOF_ [[ -f '/etc/apt/trusted.gpg' ]] && G_EXEC rm /etc/apt/trusted.gpg [[ -f '/etc/apt/trusted.gpg~' ]] && G_EXEC rm '/etc/apt/trusted.gpg~' - # Odroid N1 - elif (( $G_HW_MODEL == 14 )); then - - G_AGI linux-image-arm64-odroid-n1 meveric-keyring - - # Remove obsolete combined keyring - [[ -f '/etc/apt/trusted.gpg' ]] && G_EXEC rm /etc/apt/trusted.gpg - [[ -f '/etc/apt/trusted.gpg~' ]] && G_EXEC rm '/etc/apt/trusted.gpg~' - # Odroid C2 elif (( $G_HW_MODEL == 12 )); then diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 7581ba218e..693560c61c 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -4561,11 +4561,6 @@ _EOF_ then apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali450-odroid(,|$)' && apackages+=('mali450-odroid') - # Odroid N1 - elif (( $G_HW_MODEL == 14 )) - then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* librockchip-mpp1(,|$)' && apackages+=('librockchip-mpp1') - # Odroid N2 elif (( $G_HW_MODEL == 15 )) then @@ -6282,11 +6277,6 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- apackages=('linux-image-arm64-odroid-c2' 'linux-headers-arm64-odroid-c2') - # Odroid N1 - elif (( $G_HW_MODEL == 14 )); then - - apackages=('linux-image-arm64-odroid-n1' 'linux-headers-arm64-odroid-n1') - # Odroid N2 elif (( $G_HW_MODEL == 15 )); then @@ -6307,7 +6297,7 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- unset -v apackages # Workaround for missing /lib/modules//build symlink: https://github.com/MichaIng/DietPi/issues/3577 - # - Known as issue currently on Odroid C2/N1/N2, check for new build system if linux-/ holds current headers instead of linux-source-/: https://dietpi.com/meveric/pool/c2/l/ + # - Known as issue currently on Odroid C2/N2, check for new build system if linux-/ holds current headers instead of linux-source-/: https://dietpi.com/meveric/pool/c2/l/ for i in /lib/modules/* do [[ -d $i/build ]] && continue diff --git a/dietpi/func/dietpi-obtain_hw_model b/dietpi/func/dietpi-obtain_hw_model index 9cbaeb7f10..441a367ea7 100644 --- a/dietpi/func/dietpi-obtain_hw_model +++ b/dietpi/func/dietpi-obtain_hw_model @@ -56,7 +56,6 @@ # G_HW_MODEL 20 x86_64 VM # G_HW_MODEL 16 Odroid C4/HC4 # G_HW_MODEL 15 Odroid N2 - # G_HW_MODEL 14 Odroid N1 # G_HW_MODEL 13 Odroid U3 # G_HW_MODEL 12 Odroid C2 # G_HW_MODEL 11 Odroid XU3/XU4/MC1/HC1/HC2 @@ -487,11 +486,6 @@ G_HW_MODEL_NAME='Odroid N2' G_HW_CPUID=4 - elif (( $G_HW_MODEL == 14 )); then - - G_HW_MODEL_NAME='Odroid N1' - G_HW_CPUID=3 - elif (( $G_HW_MODEL == 13 )); then G_HW_MODEL_NAME='Odroid U3' From 78fbbd0aabec5e8edd0d7021b7cab386a9b3d0c9 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Thu, 21 Oct 2021 01:30:46 +0200 Subject: [PATCH 28/82] v7.8 + DietPi-PREP | Add additional cleanup for Armbian based images --- PREP_SYSTEM_FOR_DIETPI.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index ffa8ababb2..bfa501eebd 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1071,6 +1071,7 @@ _EOF_ # - 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: Fround left with strange "deinstall ok installed" mark left on Armbian images G_AGP dbus dhcpcd5 mountall initscripts '*office*' '*xfce*' '*qt5*' '*xserver*' '*xorg*' glib-networking libgtk-3-0 libgirepository-1.0-1 # Remove any autoremove prevention rm -fv /etc/apt/apt.conf.d/*autoremove* @@ -1209,6 +1210,14 @@ _EOF_ 'rockchip-adbd' 'rtl8723ds-btfw-load' 'install-module-hci-uart' + # Armbian + 'chrony' + 'chronyd' + 'armbian-resize-filesystem' + 'bootsplash-hide-when-booted' + 'bootsplash-show-on-shutdown' + 'armbian-firstrun-config' + 'bootsplash-ask-password-console' ) @@ -1218,14 +1227,14 @@ _EOF_ for j in /etc/init.d/$i /{etc,lib,usr/lib,usr/local/lib}/systemd/system/{$i.service{,.d},*.wants/$i.service} do [[ -e $j || -L $j ]] || continue - [[ -f $j ]] && systemctl disable --now "${j##*/}" + [[ -f $j ]] && G_EXEC systemctl disable --now "${j##*/}" # Remove if not attached to any DEB package, else mask if dpkg -S "$j" &> /dev/null; then - systemctl mask "${j##*/}" + G_EXEC systemctl mask "${j##*/}" else - rm -Rv "$j" + G_EXEC rm -R "$j" fi done @@ -1264,6 +1273,7 @@ _EOF_ [[ -d '/etc/armbianmonitor' ]] && rm -R /etc/armbianmonitor rm -vf /etc/{default,logrotate.d}/armbian* [[ -f '/lib/firmware/bootsplash.armbian' ]] && rm -v /lib/firmware/bootsplash.armbian + [[ -L '/etc/systemd/system/sysinit.target.wants/bootsplash-ask-password-console.path' ]] && G_EXEC rm /etc/systemd/system/sysinit.target.wants/bootsplash-ask-password-console.path # - OMV: https://github.com/MichaIng/DietPi/issues/2994 [[ -d '/etc/openmediavault' ]] && rm -vR /etc/openmediavault From b6f9f252c57dd2cf0f5ddd205de6b11b4d74f86f Mon Sep 17 00:00:00 2001 From: MichaIng Date: Thu, 21 Oct 2021 19:10:47 +0200 Subject: [PATCH 29/82] v7.8 + DietPi-PREP | Really do purge chrony --- PREP_SYSTEM_FOR_DIETPI.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index bfa501eebd..b249b42925 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1072,7 +1072,7 @@ _EOF_ # - mountall: https://github.com/MichaIng/DietPi/issues/2613 # - initscripts: Pre-installed on Jessie systems (?), superseded and masked by systemd, but never autoremoved # - chrony: Fround left with strange "deinstall ok installed" mark left on Armbian images - G_AGP dbus dhcpcd5 mountall initscripts '*office*' '*xfce*' '*qt5*' '*xserver*' '*xorg*' glib-networking libgtk-3-0 libgirepository-1.0-1 + G_AGP dbus dhcpcd5 mountall initscripts chrony '*office*' '*xfce*' '*qt5*' '*xserver*' '*xorg*' glib-networking libgtk-3-0 libgirepository-1.0-1 # Remove any autoremove prevention rm -fv /etc/apt/apt.conf.d/*autoremove* G_AGA From 20a996aee4338c817b0f2a18c4bca4b4a185a8eb Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 22 Oct 2021 16:22:59 +0200 Subject: [PATCH 30/82] v7.8 + DietPi-Config | The option to prefer IPv4 connections when IPv6 is enabled has been removed: This only worked for APT and wget, while e.g. cURL and ping were never affected by this setting, which meant an inconsistent behaviour. If one faces issues with IPv6 enabled, it should be simply disabled instead of preferring/forcing IPv4 only for specific tools. --- .update/patches | 5 ++- CHANGELOG.txt | 1 + PREP_SYSTEM_FOR_DIETPI.sh | 7 --- dietpi.txt | 3 -- dietpi/dietpi-config | 20 --------- dietpi/func/dietpi-set_hardware | 44 ------------------- dietpi/patch_file | 2 - .../lib/dietpi/services/dietpi-firstboot.bash | 1 - 8 files changed, 5 insertions(+), 78 deletions(-) diff --git a/.update/patches b/.update/patches index 9dff071d5a..8a68584b30 100644 --- a/.update/patches +++ b/.update/patches @@ -462,7 +462,10 @@ _EOF_ Patch_7_8() { - : + # Remove IPv4 preference + G_EXEC sed -i '/CONFIG_PREFER_IPV4/d' /boot/dietpi.txt + [[ -f '/etc/wgetrc' ]] && G_EXEC sed -i 's/^[[:blank:]]*prefer-family[[:blank:]]*=/#&/' /etc/wgetrc + [[ -f '/etc/apt/apt.conf.d/99-dietpi-force-ipv4' ]] && G_EXEC rm /etc/apt/apt.conf.d/99-dietpi-force-ipv4 } # v6.35 => v7 migration diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5e02ffff7c..8f50a60ffe 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,7 @@ v7.8 Changes: - Odroid N1 | Removed support: We don't have a single reported system, which makes sense as this model was never really released. Only a small number of developer samples are floating around, not worth to keep maintaining an image and dedicated code. If there is really an Odroid N1 DietPi system out there, it will be automatically migrated to the Generic Rockchip RK3399 device ID on DietPi update. +- DietPi-Config | The option to prefer IPv4 connections when IPv6 is enabled has been removed: This only worked for APT and wget, while e.g. cURL and ping were never affected by this setting, which meant an inconsistent behaviour. If one faces issues with IPv6 enabled, it should be simply disabled instead of preferring/forcing IPv4 only for specific tools. Fixes: - DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index b249b42925..6d9feb679b 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -100,10 +100,6 @@ Dir::State::extended_states "/var/lib/apt/extended_states"; Dir::State::status "/var/lib/dpkg/status"; Dir::Cache::pkgcache ""; _EOF_ - # - Force IPv4 by default to avoid hanging access attempts in some cases, e.g. WiFi bridges - # NB: This needs to match the method in: /boot/dietpi/func/dietpi-set_hardware preferipv4 enable - echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99-dietpi-force-ipv4 - apt-get clean apt-get update @@ -1411,9 +1407,6 @@ gateway 192.168.0.1 wireless-power off wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf _EOF_' - # Prefer IPv4 by default - /boot/dietpi/func/dietpi-set_hardware preferipv4 enable - # Wait for network at boot by default /boot/dietpi/func/dietpi-set_software boot_wait_for_network 1 diff --git a/dietpi.txt b/dietpi.txt index 36bc550a78..6b94b45f36 100644 --- a/dietpi.txt +++ b/dietpi.txt @@ -207,9 +207,6 @@ CONFIG_LCDPANEL=none # IPv6 CONFIG_ENABLE_IPV6=1 -# Prefer IPv4 with APT and wget, NB: This has no effect if IPv6 is disabled anyway! -CONFIG_PREFER_IPV4=1 - # APT mirrors which are applied to /etc/apt/sources.list | Values here will also be applied during 1st run setup # - Raspbian: https://www.raspbian.org/RaspbianMirrors CONFIG_APT_RASPBIAN_MIRROR=http://raspbian.raspberrypi.org/raspbian/ diff --git a/dietpi/dietpi-config b/dietpi/dietpi-config index ecabc67f33..35035f3844 100644 --- a/dietpi/dietpi-config +++ b/dietpi/dietpi-config @@ -2659,20 +2659,6 @@ NB: All Ethernet connections will be dropped!' && Network_ApplyChanges fi G_WHIP_MENU_ARRAY+=('IPv6' ": [$ipv6_status_text]") - # Only offer to prefer IPv4, if IPv6 is enabled - if (( $ipv6_enabled )); then - - local ipv4_preferred=0 - local ipv4_status_text='Off' - if [[ -f '/etc/apt/apt.conf.d/99-dietpi-force-ipv4' ]]; then - - ipv4_preferred=1 - ipv4_status_text='On' - - fi - G_WHIP_MENU_ARRAY+=('Prefer IPv4' ": [$ipv4_status_text]") - - fi fi @@ -2704,12 +2690,6 @@ NB: All Ethernet connections will be dropped!' && Network_ApplyChanges ;; - 'Prefer IPv4') - - /boot/dietpi/func/dietpi-set_hardware preferipv4 $(( ! $ipv4_preferred )) - - ;; - 'Ethernet') # No hardware found diff --git a/dietpi/func/dietpi-set_hardware b/dietpi/func/dietpi-set_hardware index 539ca30f4c..03f468da50 100644 --- a/dietpi/func/dietpi-set_hardware +++ b/dietpi/func/dietpi-set_hardware @@ -14,7 +14,6 @@ readonly AVAIABLE_COMMANDS=" Available commands: $FP_SCRIPT enableipv6 enable/disable -$FP_SCRIPT preferipv4 enable/disable $FP_SCRIPT eth-forcespeed 10/100/1000/disable $FP_SCRIPT wifimodules enable/disable/onboard_enable/onboard_disable $FP_SCRIPT wificountrycode GB/US/DE/... @@ -1300,8 +1299,6 @@ Do you want to continue and disable the serial login console?' || return 1 sed -i 's/^ff02::2[[:blank:]]/#ff02::2 /' /etc/hosts # - dietpi.txt entry G_CONFIG_INJECT 'CONFIG_ENABLE_IPV6=' 'CONFIG_ENABLE_IPV6=0' /boot/dietpi.txt - # - Stop preferring IPv4, if IPv6 is disabled, to reduce obsolete/confusing entries - INPUT_DEVICE_VALUE='disable' Prefer_IPv4 else @@ -1322,43 +1319,6 @@ Do you want to continue and disable the serial login console?' || return 1 } - Prefer_IPv4(){ - - if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then - - # APT force IPv4 - echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99-dietpi-force-ipv4 - # Wget prefer IPv4 - G_CONFIG_INJECT 'prefer-family[[:blank:]]*=' 'prefer-family = IPv4' /etc/wgetrc - # dietpi.txt entry - G_CONFIG_INJECT 'CONFIG_PREFER_IPV4=' 'CONFIG_PREFER_IPV4=1' /boot/dietpi.txt - - elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then - - # APT allow IPv6 - [[ -f '/etc/apt/apt.conf.d/99-dietpi-force-ipv4' ]] && rm /etc/apt/apt.conf.d/99-dietpi-force-ipv4 - # Wget back to default - sed -i 's/^[[:blank:]]*prefer-family[[:blank:]]*=/#&/' /etc/wgetrc - # dietpi.txt entry - G_CONFIG_INJECT 'CONFIG_PREFER_IPV4=' 'CONFIG_PREFER_IPV4=0' /boot/dietpi.txt - - else - - Unknown_Input_Mode - return 1 - - fi - - # Failsafe: Comment "ForceIPv[46]" entries in all other APT config files - local i - for i in /etc/apt/apt.conf.d/* - do - [[ ! -f $i || $i == *'99-dietpi-force-ipv4' ]] && continue - sed -i 's/^[[:blank:]]*Acquire::ForceIPv[46][[:blank:]]*=/#&/' "$i" - done - - } - Wifi_Modules_Main(){ # Estimate module list @@ -2255,10 +2215,6 @@ _EOF_ Enable_IPv6 - elif [[ $INPUT_DEVICE_NAME == 'preferipv4' ]]; then - - Prefer_IPv4 - elif [[ $INPUT_DEVICE_NAME == 'wificountrycode' ]]; then Wifi_Countrycode_Main diff --git a/dietpi/patch_file b/dietpi/patch_file index afcf9defc2..d0ca6a7333 100644 --- a/dietpi/patch_file +++ b/dietpi/patch_file @@ -936,8 +936,6 @@ We strongly recommend you select "0 : Re-enable IPv6 on kernel level". By doing # Disable IPv6 via sysctl echo -e 'net.ipv6.conf.all.disable_ipv6=1\nnet.ipv6.conf.default.disable_ipv6=1' > /etc/sysctl.d/dietpi-disable_ipv6.conf G_CONFIG_INJECT 'CONFIG_ENABLE_IPV6=' 'CONFIG_ENABLE_IPV6=0' /boot/dietpi.txt - # - Do not prefer IPv4, if IPv6 is disabled anyway - /boot/dietpi/func/dietpi-set_hardware preferipv4 0 fi diff --git a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash index 73417492a6..23ed486126 100755 --- a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash +++ b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash @@ -293,7 +293,6 @@ _EOF_ # - IPv6 local enable_ipv6=$(grep -cm1 '^[[:blank:]]*CONFIG_ENABLE_IPV6=1' /boot/dietpi.txt) /boot/dietpi/func/dietpi-set_hardware enableipv6 "$enable_ipv6" - (( $enable_ipv6 )) && /boot/dietpi/func/dietpi-set_hardware preferipv4 "$(grep -cm1 '^[[:blank:]]*CONFIG_PREFER_IPV4=1' /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 From f951ed252bcd478dec6116980399a56a0725f814 Mon Sep 17 00:00:00 2001 From: Joulinar <47155374+Joulinar@users.noreply.github.com> Date: Fri, 22 Oct 2021 16:28:32 +0200 Subject: [PATCH 31/82] v7.8 (#4879) + DietPi-Software | AdGuardHome: Add some hardening for main configuration file --- dietpi/dietpi-software | 1 + 1 file changed, 1 insertion(+) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 693560c61c..98be21a70a 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -10358,6 +10358,7 @@ _EOF_ # Permissions G_EXEC chown -R adguardhome:adguardhome /mnt/dietpi_userdata/adguardhome G_EXEC chmod 0755 /mnt/dietpi_userdata/adguardhome/AdGuardHome + G_EXEC chmod 0600 /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml # Service cat << '_EOF_' > /etc/systemd/system/adguardhome.service From 45ee69f14ea827be46f0724e8ddab18894d8e439 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 22 Oct 2021 17:40:59 +0200 Subject: [PATCH 32/82] v7.8 + DietPi-Imager | Clear journal to allow further size reduction and purge possible previous filesystem changes --- .meta/dietpi-imager | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.meta/dietpi-imager b/.meta/dietpi-imager index 0f31881f84..a6c3edf8de 100755 --- a/.meta/dietpi-imager +++ b/.meta/dietpi-imager @@ -342,6 +342,10 @@ # Shrink filesystem to minimum if [[ $ROOT_FS_TYPE == 'ext4' ]] then + # Disable and enable journal to clear it and allow further size reduction + G_EXEC tune2fs -O '^has_journal' "$FP_ROOT_DEV" + G_EXEC tune2fs -O 'has_journal' "$FP_ROOT_DEV" + # Run multiple times until no change is done any more G_DIETPI-NOTIFY 2 'Shrinking root filesystem to minimum size...' local out @@ -414,6 +418,12 @@ [[ $type ]] || continue if [[ $type == 'ext'[234] ]] then + # Disable and enable journal on ext3 and ext3 to clear it, when not root filesystem (where it was done already) + if [[ $type != 'ext2' && $path != "$FP_ROOT_DEV" ]] + then + G_EXEC tune2fs -O '^has_journal' "$path" + G_EXEC tune2fs -O 'has_journal' "$path" + fi G_EXEC_OUTPUT=1 G_EXEC zerofree -v "$path" else G_EXEC mount "$path" $FP_MNT_TMP From 81c281c97bfca401d91e54345198e1889928f50e Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 22 Oct 2021 18:03:01 +0200 Subject: [PATCH 33/82] v7.8 + DietPi-Imager | Sometimes after the a loop device was attached, the root filesystem menu does not find any filesystem yet. Give it hence a little extra time to appear. --- .meta/dietpi-imager | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.meta/dietpi-imager b/.meta/dietpi-imager index a6c3edf8de..fb0bdfe17c 100755 --- a/.meta/dietpi-imager +++ b/.meta/dietpi-imager @@ -131,7 +131,8 @@ G_EXEC_NOEXIT=1 G_EXEC losetup "$FP_SOURCE" "$FP_SOURCE_IMG" || return G_EXEC_NOEXIT=1 G_EXEC partprobe "$FP_SOURCE" || return G_EXEC_NOEXIT=1 G_EXEC partx -u "$FP_SOURCE" || return - G_DIETPI-NOTIFY 0 "Mounted the image ($FP_SOURCE_IMG) as loopback device: $FP_SOURCE" + G_DIETPI-NOTIFY 0 "Attached the image ($FP_SOURCE_IMG) as loopback device: $FP_SOURCE" + sleep 0.5 # Give the root filesystem a little time to be detected fi Menu_Source_RootFS # Directly open this menu next From 127899e5d1c802165706a96044d2673f745a92fd Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 22 Oct 2021 18:10:53 +0200 Subject: [PATCH 34/82] v7.8 + DietPi-Imager | Assure that the SOURCE_TYPE variable is always initialised --- .meta/dietpi-imager | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.meta/dietpi-imager b/.meta/dietpi-imager index fb0bdfe17c..83372042e2 100755 --- a/.meta/dietpi-imager +++ b/.meta/dietpi-imager @@ -31,9 +31,9 @@ readonly DIETPI_REPO="https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH" # Inputs + SOURCE_TYPE='Drive' if [[ -b $1 ]] then - SOURCE_TYPE='Drive' FP_SOURCE=$1 elif [[ -f $1 ]] From 330d2d546ad4d9eff2f2a5718ff1bcaa3eada6a6 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 22 Oct 2021 20:44:46 +0200 Subject: [PATCH 35/82] v7.8 + DietPi-PREP | Further cleanup --- PREP_SYSTEM_FOR_DIETPI.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 6d9feb679b..1efb873bca 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1165,16 +1165,17 @@ _EOF_ G_DIETPI-NOTIFY 2 'Removing misc files/folders/services, not required by DietPi' - [[ -d '/selinux' ]] && rm -Rv /selinux - [[ -d '/var/cache/apparmor' ]] && rm -Rv /var/cache/apparmor - [[ -d '/var/lib/udisks2' ]] && rm -Rv /var/lib/udisks2 - [[ -d '/var/lib/bluetooth' ]] && rm -Rv /var/lib/bluetooth - [[ -d '/usr/lib/firefox-esr' ]] && rm -Rv /usr/lib/firefox-esr # Armbian desktop images - rm -Rfv /var/lib/dhcp/{,.??,.[^.]}* - rm -Rfv /var/lib/misc/*.leases - rm -Rfv /var/backups/{,.??,.[^.]}* - [[ -f '/etc/udhcpd.conf.org' ]] && rm -v /etc/udhcpd.conf.org - [[ -f '/etc/fs.resized' ]] && rm -v /etc/fs.resized + [[ -d '/selinux' ]] && G_EXEC rm -R /selinux + [[ -d '/var/cache/apparmor' ]] && G_EXEC rm -R /var/cache/apparmor + [[ -d '/var/lib/udisks2' ]] && G_EXEC rm -R /var/lib/udisks2 + [[ -d '/var/lib/bluetooth' ]] && G_EXEC rm -R /var/lib/bluetooth + [[ -d '/usr/lib/firefox-esr' ]] && G_EXEC rm -R /usr/lib/firefox-esr # Armbian desktop images + G_EXEC rm -Rf /var/lib/dhcp/{,.??,.[^.]}* + G_EXEC rm -f /var/lib/misc/*.leases + G_EXEC rm -Rf /var/backups/{,.??,.[^.]}* + G_EXEC rm -f /etc/*.org + [[ -f '/etc/fs.resized' ]] && G_EXEC rm /etc/fs.resized + [[ -d '/etc/chromium.d' ]] && G_EXEC rm -R /etc/chromium.d # Armbian desktop images # - www [[ -d '/var/www' ]] && rm -vRf /var/www/{,.??,.[^.]}* From e20df06af6151db9774a4a0a262bbad13273c4a7 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 22 Oct 2021 20:47:02 +0200 Subject: [PATCH 36/82] v7.8 + DietPi-PREP | Add another left config dir --- PREP_SYSTEM_FOR_DIETPI.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 1efb873bca..e1f3066fa5 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1169,13 +1169,15 @@ _EOF_ [[ -d '/var/cache/apparmor' ]] && G_EXEC rm -R /var/cache/apparmor [[ -d '/var/lib/udisks2' ]] && G_EXEC rm -R /var/lib/udisks2 [[ -d '/var/lib/bluetooth' ]] && G_EXEC rm -R /var/lib/bluetooth - [[ -d '/usr/lib/firefox-esr' ]] && G_EXEC rm -R /usr/lib/firefox-esr # Armbian desktop images G_EXEC rm -Rf /var/lib/dhcp/{,.??,.[^.]}* G_EXEC rm -f /var/lib/misc/*.leases G_EXEC rm -Rf /var/backups/{,.??,.[^.]}* G_EXEC rm -f /etc/*.org [[ -f '/etc/fs.resized' ]] && G_EXEC rm /etc/fs.resized - [[ -d '/etc/chromium.d' ]] && G_EXEC rm -R /etc/chromium.d # Armbian desktop images + # Armbian desktop images + [[ -d '/usr/lib/firefox-esr' ]] && G_EXEC rm -R /usr/lib/firefox-esr + [[ -d '/etc/chromium.d' ]] && G_EXEC rm -R /etc/chromium.d + [[ -d '/etc/lightdm' ]] G_EXEC rm -R /etc/lightdm # - www [[ -d '/var/www' ]] && rm -vRf /var/www/{,.??,.[^.]}* From dd714f5a4d536e0a04d8034e79051af0ede1d30d Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 22 Oct 2021 20:49:19 +0200 Subject: [PATCH 37/82] v7.8 + DietPi-PREP | Remove dpkg backup config files as well, which are those which are not used by new packages anymore --- PREP_SYSTEM_FOR_DIETPI.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index e1f3066fa5..a2252c0627 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1192,7 +1192,7 @@ _EOF_ [[ -d '/usr/share/calendar' ]] && rm -vR /usr/share/calendar # - Unused DEB package config files - find /etc \( -name '?*\.dpkg-dist' -o -name '?*\.dpkg-old' -o -name '?*\.dpkg-new' \) -exec rm -v {} + + find /etc \( -name '?*\.dpkg-dist' -o -name '?*\.dpkg-old' -o -name '?*\.dpkg-new' -o -name '?*\.dpkg-bak' \) -exec rm -v {} + # - Fonts [[ -d '/usr/share/fonts' ]] && rm -vR /usr/share/fonts From 3df2d003f6fffbefeda53640878d3a4a9db3af51 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 23 Oct 2021 00:23:37 +0200 Subject: [PATCH 38/82] v7.8 + DietPi-PREP | Extend pre-removals a little to better cover possible "unmet dependencies" errors --- PREP_SYSTEM_FOR_DIETPI.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index a2252c0627..f222e7ec2c 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1063,12 +1063,12 @@ _EOF_ # Purging additional packages, that (in some cases) do not get autoremoved: # - 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 libgirepository-1.0-1" + # + 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: Fround 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 libgirepository-1.0-1 + G_AGP 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 From 4730833d42308914c7958312fb25d7935fde4e93 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 23 Oct 2021 01:16:17 +0200 Subject: [PATCH 39/82] v7.8 + DietPi-PREP | Syntax --- PREP_SYSTEM_FOR_DIETPI.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index f222e7ec2c..9537d37d12 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1177,7 +1177,7 @@ _EOF_ # Armbian desktop images [[ -d '/usr/lib/firefox-esr' ]] && G_EXEC rm -R /usr/lib/firefox-esr [[ -d '/etc/chromium.d' ]] && G_EXEC rm -R /etc/chromium.d - [[ -d '/etc/lightdm' ]] G_EXEC rm -R /etc/lightdm + [[ -d '/etc/lightdm' ]] && G_EXEC rm -R /etc/lightdm # - www [[ -d '/var/www' ]] && rm -vRf /var/www/{,.??,.[^.]}* From 30f647ebb394aaa129fccb90c03c4723ae015ab9 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 23 Oct 2021 03:34:42 +0200 Subject: [PATCH 40/82] v7.8 + DietPi-PREP | Keep serial console setting enabled on ROCK Pi S --- PREP_SYSTEM_FOR_DIETPI.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 9537d37d12..31e04ee543 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1517,6 +1517,7 @@ _EOF_' /boot/dietpi/func/dietpi-set_hardware serialconsole disable /boot/dietpi/func/dietpi-set_hardware serialconsole enable ttyS0 + G_CONFIG_INJECT 'CONFIG_SERIAL_CONSOLE_ENABLE=' 'CONFIG_SERIAL_CONSOLE_ENABLE=1' /boot/dietpi.txt fi From a51193ef52bd5e3fd774a3300421e95ef2da1472 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 23 Oct 2021 17:35:28 +0200 Subject: [PATCH 41/82] v7.8 + DietPi-Login | Remove dedicated connection and time sync check on first login, as this is now included in DietPi-Update --- dietpi/dietpi-login | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/dietpi/dietpi-login b/dietpi/dietpi-login index 1985a8f26d..e8cf5205e1 100644 --- a/dietpi/dietpi-login +++ b/dietpi/dietpi-login @@ -194,17 +194,6 @@ Please login again as user "root" with password "dietpi", respectively the one y # 1st run dietpi-update if (( $G_DIETPI_INSTALL_STAGE == 0 )); then - # Checking network connectivity - # shellcheck disable=SC2119 - G_CHECK_CON - - # Checking DNS resolver - # shellcheck disable=SC2119 - G_CHECK_DNS - - # Network time sync - /boot/dietpi/func/run_ntpd - # Start DietPi-Update /boot/dietpi/dietpi-update 1 # Sets /boot/dietpi/.install_stage > G_DIETPI_INSTALL_STAGE=1 From df8e914c475604de4ec15a17d1a2d06c71d72da9 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 24 Oct 2021 22:37:50 +0200 Subject: [PATCH 42/82] v7.8 + DietPi-PREP | Remove the separation between "core" and "limited" ARM devices, it is not accurate anymore --- PREP_SYSTEM_FOR_DIETPI.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 31e04ee543..a7077c0947 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -355,30 +355,26 @@ _EOF_ G_WHIP_DEFAULT_ITEM=0 G_WHIP_MENU_ARRAY=( - '' '●─ ARM ─ Core devices with GPU acceleration ' + '' '●─ ARM ' '0' ': Raspberry Pi (all models)' #'0' ': Raspberry Pi 1 (256 MiB) #'1' ': Raspberry Pi 1/Zero (512 MiB)' #'2' ': Raspberry Pi 2' #'3' ': Raspberry Pi 3/3+' #'4' ': Raspberry Pi 4' + '13' ': Odroid U3' + '10' ': Odroid C1' '11' ': Odroid XU3/XU4/MC1/HC1/HC2' '12' ': Odroid C2' '15' ': Odroid N2' '16' ': Odroid C4/HC4' - '44' ': Pinebook' - '' '●─ x86_64 ' - '21' ': x86_64 Native PC' - '20' ': x86_64 Virtual Machine' - '' '●─ ARM ─ Limited GPU acceleration ' - '10' ': Odroid C1' - '13' ': Odroid U3' '70' ': Sparky SBC' '52' ': ASUS Tinker Board' '40' ': PINE A64' + '45' ': PINE H64' '43' ': ROCK64' '42' ': ROCKPro64' - '45' ': PINE H64' + '44' ': Pinebook' '46' ': Pinebook Pro' '59' ': ZeroPi' '60' ': NanoPi NEO' @@ -399,6 +395,9 @@ _EOF_ '47' ': NanoPi R4S' '72' ': ROCK Pi 4' '73' ': ROCK Pi S' + '' '●─ x86_64 ' + '21' ': x86_64 Native PC' + '20' ': x86_64 Virtual Machine' '' '●─ Other ' '29' ': Generic Amlogic S922X' '28' ': Generic Amlogic S905' From 63e431968510c6ce5dc4d47ad823ffef74bbf924 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 24 Oct 2021 23:31:29 +0200 Subject: [PATCH 43/82] v7.8 (#4895) + DietPi-Software | Subonic: Remove + DietPi-Software | emonHub: Remove + DietPi-Software | RPi-Monitor: Merge install and config code blocks + DietPi-Software | RPi-Monitor: Remove left config, data and log file on uninstall --- .meta/dietpi-survey_report | 2 + .update/patches | 40 ++++- CHANGELOG.txt | 4 + README.md | 2 - dietpi.txt | 4 - dietpi/dietpi-services | 2 - dietpi/dietpi-software | 301 ++++++------------------------------- 7 files changed, 89 insertions(+), 266 deletions(-) diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index 5900661ae5..d75c168e57 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -572,6 +572,8 @@ shopt -s extglob do aSOFTWARE_NAME7_8[$i]=${aSOFTWARE_NAME7_7[$i]} done + unset -v 'aSOFTWARE_NAME7_8[34]' # Subsonic + unset -v 'aSOFTWARE_NAME7_8[99]' # emonHub # 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[@]}" diff --git a/.update/patches b/.update/patches index 8a68584b30..d965fa2e25 100644 --- a/.update/patches +++ b/.update/patches @@ -330,7 +330,7 @@ Patch_7_7() G_EXEC sed -Ei 's#http://(repo.mosquitto.org|download.webmin.com)#https://\1#' /etc/apt/sources.list [[ $(find /etc/apt/sources.list/*.list 2> /dev/null) ]] && G_EXEC sed -Ei 's#http://(repo.mosquitto.org|download.webmin.com)#https://\1#' /etc/apt/sources.list.d/*.list - # Inform users about abandoned CouchPotato and in case add systemd service to DietPi-Services includes, at it has been removed from the hardcoded list + # Inform users about abandoned CouchPotato and in case add service to DietPi-Services includes, as it has been removed from the hardcoded list if [[ -f '/boot/dietpi/.installed' ]] && grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[142\]=2' /boot/dietpi/.installed then G_WHIP_MSG '[ INFO ] CouchPotato has been abandoned @@ -466,6 +466,44 @@ Patch_7_8() G_EXEC sed -i '/CONFIG_PREFER_IPV4/d' /boot/dietpi.txt [[ -f '/etc/wgetrc' ]] && G_EXEC sed -i 's/^[[:blank:]]*prefer-family[[:blank:]]*=/#&/' /etc/wgetrc [[ -f '/etc/apt/apt.conf.d/99-dietpi-force-ipv4' ]] && G_EXEC rm /etc/apt/apt.conf.d/99-dietpi-force-ipv4 + + # Inform users about removed Subsonic and in case add service to DietPi-Services includes, as it has been removed from the hardcoded list + if [[ -f '/boot/dietpi/.installed' ]] && grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[34\]=2' /boot/dietpi/.installed + then + G_WHIP_MSG '[ INFO ] Subsonic has been removed from DietPi-Software +\nSince it is not developed anymore and due to shared library dependencies only compatible with Debian Stretch, we removed Subsonic from DietPi-Software. +\nThe instance installed on your system will remain, but it cannot be installed, reinstalled or uninstalled anymore. +\nWe recommend to migrate to Airsonic-Advanced, which can be found in DietPi-Software was well. +\nManual Subsonic uninstall instructions: https://github.com/MichaIng/DietPi/pull/4895 +' + if [[ -f '/etc/init.d/subsonic' ]] + then + # shellcheck disable=SC2015 + [[ -f '/boot/dietpi/.dietpi-services_include_exclude' ]] && grep -q 'subsonic' /boot/dietpi/.dietpi-services_include_exclude || G_EXEC eval "echo '+ subsonic' >> /boot/dietpi/.dietpi-services_include_exclude" + fi + fi + # Remove obsolete Subsonic install state + [[ -f '/boot/dietpi/.installed' ]] && grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[34\]=' /boot/dietpi/.installed && G_EXEC sed -i '/^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[34\]=/d' /boot/dietpi/.installed + + # Inform users about removed emonHub and in case add service to DietPi-Services includes, as it has been removed from the hardcoded list + if [[ -f '/boot/dietpi/.installed' ]] && grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[99\]=2' /boot/dietpi/.installed + then + G_WHIP_MSG '[ INFO ] emonHub has been removed from DietPi-Software +\nSince we do not have a single reported installation, we removed emonHub from DietPi-Software. +\nThe instance installed on your system will remain, but it cannot be installed, reinstalled or uninstalled anymore. +\nIf you want to keep using and updating it, have a look at the official repository: https://github.com/openenergymonitor/emonhub +\nManual emonHub uninstall instructions: https://github.com/MichaIng/DietPi/pull/4895 +' + if [[ -f '/etc/systemd/system/emonhub.service' ]] + then + # shellcheck disable=SC2015 + [[ -f '/boot/dietpi/.dietpi-services_include_exclude' ]] && grep -q 'emonhub' /boot/dietpi/.dietpi-services_include_exclude || G_EXEC eval "echo '+ emonhub' >> /boot/dietpi/.dietpi-services_include_exclude" + fi + fi + # Remove obsolete emonHub install state + [[ -f '/boot/dietpi/.installed' ]] && grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[99\]=' /boot/dietpi/.installed && G_EXEC sed -i '/^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[99\]=/d' /boot/dietpi/.installed + # Remove obsolete emonHub API key setting from dietpi.txt + grep -q 'SOFTWARE_EMONHUB_APIKEY' /boot/dietpi.txt && G_EXEC sed -Ei '/(SOFTWARE_EMONHUB_APIKEY|^#.*EmonCMS)/d' /boot/dietpi.txt } # v6.35 => v7 migration diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8f50a60ffe..9c85b42bf9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,10 @@ v7.8 (2021-10-13) +Removed software: +- Subsonic | Since it is not developed anymore and due to shared library dependencies only compatible with Debian Stretch, we removed Subsonic from DietPi-Software. With Airsonic-Advanced, we'll provide a well maintained and Bullseye-compatible alternative. If you currently have Subsonic installed, it will remain. If you want to uninstall it, follow the instructions here: https://github.com/MichaIng/DietPi/pull/4895 +- emonHub | Since we do not have a single reported installation, we removed emonHub from DietPi-Software. If you currently have emonHub installed, it will remain. If you want to keep using and updating it, have a look at the official repository: https://github.com/openenergymonitor/emonhub. If you want to uninstall it, follow the instructions here: https://github.com/MichaIng/DietPi/pull/4895 + Changes: - Odroid N1 | Removed support: We don't have a single reported system, which makes sense as this model was never really released. Only a small number of developer samples are floating around, not worth to keep maintaining an image and dedicated code. If there is really an Odroid N1 DietPi system out there, it will be automatically migrated to the Generic Rockchip RK3399 device ID on DietPi update. - DietPi-Config | The option to prefer IPv4 connections when IPv6 is enabled has been removed: This only worked for APT and wget, while e.g. cURL and ping were never affected by this setting, which meant an inconsistent behaviour. If one faces issues with IPv6 enabled, it should be simply disabled instead of preferring/forcing IPv4 only for specific tools. diff --git a/README.md b/README.md index 8bfc6dcc20..3ecb41cb38 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,6 @@ Links to hardware and software manufacturers, sources and build instructions use - [OpenTyrian](https://bitbucket.org/opentyrian/opentyrian/wiki/Home) - [RPi Cam Control](https://github.com/silvanmelchior/RPi_Cam_Web_Interface) - [Deluge](https://dev.deluge-torrent.org/wiki/Development#SourceCode) -- [Subsonic](https://sourceforge.net/projects/subsonic/) - [Airsonic](https://github.com/airsonic/airsonic) - [Logitech Media Server](https://github.com/Logitech/slimserver) - [Squeezelite](https://github.com/ralph-irving/squeezelite) @@ -302,7 +301,6 @@ Links to hardware and software manufacturers, sources and build instructions use - [VSCodium](https://github.com/VSCodium/vscodium) - [WebIOPi](https://github.com/Freenove/WebIOPi) - [WiringPi](https://github.com/WiringPi/WiringPi) -- [emonHub](https://github.com/openenergymonitor/emonhub) - [Firefox](https://hg.mozilla.org/mozilla-unified) - [Beets](https://github.com/beetbox/beets) - [frp](https://github.com/fatedier/frp) diff --git a/dietpi.txt b/dietpi.txt index 6b94b45f36..03eaab7c17 100644 --- a/dietpi.txt +++ b/dietpi.txt @@ -221,10 +221,6 @@ CONFIG_NTP_MIRROR=debian.pool.ntp.org #------------------------------------------------------------------------------------------------------ ##### DietPi-Software settings ##### #------------------------------------------------------------------------------------------------------ -# Enter your EmonCMS.org write API key here. It will be applied automatically during EmonPi/Hub install. -# - E.g.: SOFTWARE_EMONHUB_APIKEY=b4dfmk2o203mmxx93a -SOFTWARE_EMONHUB_APIKEY= - # VNC Server SOFTWARE_VNCSERVER_WIDTH=1280 SOFTWARE_VNCSERVER_HEIGHT=720 diff --git a/dietpi/dietpi-services b/dietpi/dietpi-services index 858b86fe3e..311116c2a4 100644 --- a/dietpi/dietpi-services +++ b/dietpi/dietpi-services @@ -115,7 +115,6 @@ Available services: 'ympd' 'mympd' 'logitechmediaserver' - 'subsonic' 'airsonic' 'mopidy' 'koel' @@ -178,7 +177,6 @@ Available services: 'node-red' 'blynkserver' 'webiopi' - 'emonhub' 'influxdb' 'grafana-server' diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 98be21a70a..ce24b98b97 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -401,18 +401,6 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_AVAIL_G_DISTRO[$software_id,6]=0 aSOFTWARE_AVAIL_G_DISTRO[$software_id,7]=0 #------------------ - software_id=34 - - aSOFTWARE_NAME[$software_id]='Subsonic' - aSOFTWARE_DESC[$software_id]='web interface media streaming server' - aSOFTWARE_CATX[$software_id]=2 - aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/media/#subsonic' - aSOFTWARE_DEPS[$software_id]='5 7 196' - # - Buster: https://github.com/MichaIng/DietPi/issues/2787 - aSOFTWARE_AVAIL_G_DISTRO[$software_id,5]=0 - aSOFTWARE_AVAIL_G_DISTRO[$software_id,6]=0 - aSOFTWARE_AVAIL_G_DISTRO[$software_id,7]=0 - #------------------ software_id=35 aSOFTWARE_NAME[$software_id]='Logitech Media Server' @@ -1164,7 +1152,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=66 aSOFTWARE_NAME[$software_id]='RPi-Monitor' - aSOFTWARE_DESC[$software_id]='web interface system stats' + aSOFTWARE_DESC[$software_id]='Web interface for Raspberry Pi real time monitoring' aSOFTWARE_CATX[$software_id]=8 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/system_stats/#rpi-monitor' # RPi only @@ -1590,19 +1578,6 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" # Home Automation #-------------------------------------------------------------------------------- - software_id=99 - - aSOFTWARE_NAME[$software_id]='emonHub' - aSOFTWARE_DESC[$software_id]='Data collector for the emonPi energy monitor addon board' - aSOFTWARE_CATX[$software_id]=17 - aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/home_automation/#emonpi' - aSOFTWARE_DEPS[$software_id]='69 130' - # RPi only - for ((i=10; i<=$MAX_G_HW_MODEL; i++)) - do - aSOFTWARE_AVAIL_G_HW_MODEL[$software_id,$i]=0 - done - #------------------ software_id=157 aSOFTWARE_NAME[$software_id]='Home Assistant' @@ -5376,15 +5351,6 @@ _EOF_ fi - software_id=34 # Subsonic - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - #DEPS_LIST='lame' # Conflicts with our ffmpeg package: https://github.com/MichaIng/DietPi/issues/946#issuecomment-300738228 - Download_Install 'https://dietpi.com/downloads/binaries/all/subsonic.deb' - - fi - software_id=68 # Remot3.it if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -6428,49 +6394,54 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- fi - software_id=99 # emonHub + software_id=66 # RPi-Monitor if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Installing # https://github.com/openenergymonitor/emonhub/blob/master/install.sh + Banner_Installing - DEPS_LIST='python3-serial python3-configobj python3-pymodbus bluetooth libbluetooth-dev' - Download_Install 'https://github.com/openenergymonitor/emonhub/archive/stable.tar.gz' + Download_Install 'https://raw.githubusercontent.com/XavierBerger/RPi-Monitor-deb/develop/packages/rpimonitor_2.13-beta6_all.deb' - G_EXEC_OUTPUT=1 G_EXEC pip3 install -U paho-mqtt requests pybluez py-sds011 sdm_modbus + # Update APT package status + G_EXEC /usr/share/rpimonitor/scripts/updatePackagesStatus.pl - # Config: Preserve old - if [[ ! -f '/mnt/dietpi_userdata/emonhub/emonhub.conf' ]] + # USB drive stats implementation by Rich + if [[ ! -f '/etc/rpimonitor/template/usb_hdd.conf' ]] && findmnt -S /dev/sda1 > /dev/null then - G_EXEC mkdir -p /mnt/dietpi_userdata/emonhub - - # Pre-v7.2: Preserve old - if [[ -f '/etc/emonhub/conf/emonhub.conf' ]] - then - G_EXEC mv /{etc/emonhub/conf,mnt/dietpi_userdata/emonhub}/emonhub.conf - G_EXEC mv {emonhub-stable/conf,/mnt/dietpi_userdata/emonhub}/emonpi.default.emonhub.conf - else - G_EXEC mv {emonhub-stable/conf/emonpi.default.,/mnt/dietpi_userdata/emonhub/}emonhub.conf - local apikey=$(sed -n '/^[[:blank:]]*SOFTWARE_EMONHUB_APIKEY=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - [[ ! $apikey ]] && G_WHIP_BUTTON_CANCEL_TEXT='Skip' G_WHIP_INPUTBOX 'Please enter your https://emoncms.org/ API key: -\nNB: You may skip this when using a local emonCMS instance or none at all.' && apikey=$G_WHIP_RETURNED_VALUE - G_CONFIG_INJECT 'apikey[[:blank:]]*=' " apikey = $apikey" /mnt/dietpi_userdata/emonhub/emonhub.conf - G_CONFIG_INJECT 'loglevel[[:blank:]]*=' ' loglevel = WARNING' /mnt/dietpi_userdata/emonhub/emonhub.conf - fi - fi - - # Install to /opt/emonhub - [[ -d '/etc/emonhub' ]] && G_EXEC rm -R /etc/emonhub # pre-v7.2 - [[ -d '/opt/emonhub' ]] && G_EXEC rm -R /opt/emonhub # Reinstall - G_EXEC mv emonhub-stable/src /opt/emonhub - G_EXEC_NOHALT=1 G_EXEC rm -R emonhub-stable + G_EXEC sed -i '\|include=/etc/rpimonitor/template/sdcard.conf|a\include=/etc/rpimonitor/template/usb_hdd.conf' /etc/rpimonitor/data.conf + cat << '_EOF_' > /etc/rpimonitor/template/usb_hdd.conf +######################################################################## +# Extract USB HDD (sda1) information +# Page: 1 +# Information Status Statistics +# - USBHDD1 total - yes - yes +# - USBHDD1 used - yes - yes +######################################################################## +static.10.name=usbhdd_total +static.10.source=df -t ext4 +static.10.regexp=sda1\s+(\d+) +static.10.postprocess=$1/1024 - fi +dynamic.14.name=usbhdd_used +dynamic.14.source=df -t ext4 +dynamic.14.regexp=sda1\s+\d+\s+(\d+) +dynamic.14.postprocess=$1/1024 +dynamic.14.rrd=GAUGE - software_id=66 # RPi Monitor - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then +web.status.1.content.9.name=USB HDD +web.status.1.content.9.icon=usb_hdd.png +web.status.1.content.9.line.1="/sda1 Used: "+KMG(data.usbhdd_used,'M')+" ("+Percent(data.udbhdd_used,data.usbhdd_total,'M')+") Free: "+KMG(data.usbhdd_total-data.usbhdd_used,'M')+ " Total: "+ KMG(data.usbhdd_total,'M') +"" +web.status.1.content.9.line.2=ProgressBar(data.usbhdd_used,data.usbhdd_total) - Banner_Installing - Download_Install 'https://github.com/XavierBerger/RPi-Monitor-deb/raw/master/packages/rpimonitor_2.12-r0_all.deb' +web.statistics.1.content.9.name=USB HDD +web.statistics.1.content.9.graph.1=usbhdd_total +web.statistics.1.content.9.graph.2=usbhdd_used +web.statistics.1.content.9.ds_graph_options.usbhdd_total.label=USB HDD total space (MB) +web.statistics.1.content.9.ds_graph_options.usbhdd_total.color="#FF7777" +web.statistics.1.content.9.ds_graph_options.usbhdd_used.label=USB HDD used space (MB) +web.statistics.1.content.9.ds_graph_options.usbhdd_used.lines={ fill: true } +web.statistics.1.content.9.ds_graph_options.usbhdd_used.color="#7777FF" +_EOF_ + fi fi @@ -10429,30 +10400,6 @@ _EOF_ fi - software_id=34 # Subsonic - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # User - Create_User -G dietpi,audio -d /var/subsonic subsonic - - # Config - # - Optimise memory limit - local memory_limit=$(( $RAM_PHYS / 5 )) - (( $memory_limit < 200 )) && memory_limit=200 - G_CONFIG_INJECT 'SUBSONIC_USER=' 'SUBSONIC_USER=subsonic' /etc/default/subsonic - G_CONFIG_INJECT 'SUBSONIC_ARGS=' "SUBSONIC_ARGS='--quiet --pidfile=/run/subsonic.pid --max-memory=$memory_limit --default-music-folder=/mnt/dietpi_userdata/Music --default-podcast-folder=/mnt/dietpi_userdata/Music --default-playlist-folder=/mnt/dietpi_userdata/Music'" /etc/default/subsonic - - # Enable FFmpeg transcode - G_EXEC mkdir -p /var/subsonic/transcode - command -v ffmpeg > /dev/null && G_EXEC ln -sf "$(command -v ffmpeg)" /var/subsonic/transcode - - # Grab our test media for user - Download_Test_Media - - fi - software_id=98 # HAProxy if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -11537,102 +11484,6 @@ _EOF_ fi - software_id=99 # emonHub - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # User - Create_User -g gpio -G dialout,tty emonhub - - # Permissions - G_EXEC chown emonhub /mnt/dietpi_userdata/emonhub/emonhub.conf - - # Service - Remove_SysV emonhub 1 # pre-v7.2 - cat << _EOF_ > /etc/systemd/system/emonhub.service -[Unit] -Description=emonHub (DietPi) -Documentation=https://github.com/openenergymonitor/emonhub/blob/stable/configuration.md -Wants=network-online.target -After=network-online.target - -[Service] -SyslogIdentifier=emonHub -User=emonhub -Type=exec -ExecStart=$(command -v python3) -OO /opt/emonhub/emonhub.py --config-file=/mnt/dietpi_userdata/emonhub/emonhub.conf - -[Install] -WantedBy=multi-user.target -_EOF_ - # Disable onboard Bluetooth, if present, to recover ttyAMA0 - if (( $G_HW_ONBOARD_WIFI )); then - - /boot/dietpi/func/dietpi-set_hardware bluetooth disable - - # Else, assure that primary UART is enabled, which is ttyAMA0 on non-onboard WiFi/BT models - else - - G_CONFIG_INJECT 'enable_uart=' 'enable_uart=1' /boot/config.txt - - fi - - # Disable console on ttyAMA0 - /boot/dietpi/func/dietpi-set_hardware serialconsole disable ttyAMA0 - - fi - - software_id=66 # RPi Monitor - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Update apt package stats - /usr/share/rpimonitor/scripts/updatePackagesStatus.pl - - # USB drive stats implementation by Rich - if findmnt -S /dev/sda1 > /dev/null; then - - sed -i '\/include=\/etc\/rpimonitor\/template\/sdcard.conf/a include=\/etc\/rpimonitor\/template\/usb_hdd.conf' /etc/rpimonitor/data.conf - - cat << '_EOF_' > /etc/rpimonitor/template/usb_hdd.conf -######################################################################## -# Extract USB HDD (sda1) information -# Page: 1 -# Information Status Statistics -# - USBHDD1 total - yes - yes -# - USBHDD1 used - yes - yes -######################################################################## -static.10.name=usbhdd_total -static.10.source=df -t ext4 -static.10.regexp=sda1\s+(\d+) -static.10.postprocess=$1/1024 - -dynamic.14.name=usbhdd_used -dynamic.14.source=df -t ext4 -dynamic.14.regexp=sda1\s+\d+\s+(\d+) -dynamic.14.postprocess=$1/1024 -dynamic.14.rrd=GAUGE - -web.status.1.content.9.name=USB HDD -web.status.1.content.9.icon=usb_hdd.png -web.status.1.content.9.line.1="/sda1 Used: "+KMG(data.usbhdd_used,'M')+" ("+Percent(data.udbhdd_used,data.usbhdd_total,'M')+") Free: "+KMG(data.usbhdd_total-data.usbhdd_used,'M')+ " Total: "+ KMG(data.usbhdd_total,'M') +"" -web.status.1.content.9.line.2=ProgressBar(data.usbhdd_used,data.usbhdd_total) - -web.statistics.1.content.9.name=USB HDD -web.statistics.1.content.9.graph.1=usbhdd_total -web.statistics.1.content.9.graph.2=usbhdd_used -web.statistics.1.content.9.ds_graph_options.usbhdd_total.label=USB HDD total space (MB) -web.statistics.1.content.9.ds_graph_options.usbhdd_total.color="#FF7777" -web.statistics.1.content.9.ds_graph_options.usbhdd_used.label=USB HDD used space (MB) -web.statistics.1.content.9.ds_graph_options.usbhdd_used.lines={ fill: true } -web.statistics.1.content.9.ds_graph_options.usbhdd_used.color="#7777FF" -_EOF_ - fi - - fi - software_id=65 # Netdata if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -14883,18 +14734,6 @@ _EOF_ fi - software_id=34 # Subsonic - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then - - Banner_Uninstalling - G_AGP subsonic - [[ -d '/etc/systemd/system/subsonic.service.d' ]] && G_EXEC rm -R /etc/systemd/system/subsonic.service.d - getent passwd subsonic > /dev/null && G_EXEC userdel subsonic - getent group subsonic > /dev/null && G_EXEC groupdel subsonic - [[ -d '/var/subsonic' ]] && G_EXEC rm -R /var/subsonic - - fi - software_id=71 # WebIOPi if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then @@ -15264,40 +15103,14 @@ _EOF_ fi - software_id=99 # emonHub - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then - - Banner_Uninstalling - if [[ -f '/etc/systemd/system/emonhub.service' ]]; then - - G_EXEC systemctl disable --now emonhub - G_EXEC rm /etc/systemd/system/emonhub.service - - fi - [[ -d '/etc/systemd/system/emonhub.service.d' ]] && G_EXEC rm -R /etc/systemd/system/emonhub.service.d - getent passwd emonhub > /dev/null && G_EXEC userdel emonhub - [[ -d '/opt/emonhub' ]] && G_EXEC rm -R /opt/emonhub - [[ -d '/mnt/dietpi_userdata/emonhub' ]] && G_EXEC rm -R /mnt/dietpi_userdata/emonhub - - # Pre-v7.2 - if [[ -f '/etc/init.d/emonhub' ]]; then - - G_EXEC systemctl unmask emonhub - G_EXEC systemctl disable --now emonhub - G_EXEC rm /etc/init.d/emonhub - G_EXEC update-rc.d -f emonhub remove - - fi - [[ -f '/etc/default/emonhub' ]] && G_EXEC rm /etc/default/emonhub - [[ -d '/etc/emonhub' ]] && G_EXEC rm -R /etc/emonhub - - fi - - software_id=66 + software_id=66 # RPi-Monitor if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling G_AGP rpimonitor + [[ -d '/etc/rpimonitor' ]] && G_EXEC rm -R /etc/rpimonitor + [[ -d '/var/lib/rpimonitor' ]] && G_EXEC rm -R /var/lib/rpimonitor + [[ -f '/var/log/rpimonitor.log' ]] && G_EXEC rm /var/log/rpimonitor.log fi @@ -17408,32 +17221,6 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa (( ${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' - # emonHub - if (( ${aSOFTWARE_INSTALL_STATE[99]} == 1 )); then - - # Grab key from dietpi.txt - local apikey=$(sed -n '/^[[:blank:]]*SOFTWARE_EMONHUB_APIKEY=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - - # Offer to enter if it has not yet been done - [[ $apikey ]] || while : - do - G_WHIP_DEFAULT_ITEM=$apikey G_WHIP_BUTTON_CANCEL_TEXT='Skip' - G_WHIP_INPUTBOX 'Please enter your emonHub "Write API key": -- Visit https://emoncms.org/ to register an account and login. -- Select "Setup" from the top right of screen, then select "My Account". -- Enter the "Write API key" into the box below. -\nNB: You may skip this when using a local emonCMS instance or none at all.' || break - - apikey=$G_WHIP_RETURNED_VALUE - G_WHIP_YESNO "The following \"Write API key\" will be applied during installation:\n$apikey\n\nIs this key correct?" || continue - - # Update dietpi.txt so the value will be applied during installation. - sed -i "/^[[:blank:]]*SOFTWARE_EMONHUB_APIKEY=/c\SOFTWARE_EMONHUB_APIKEY=$apikey" /boot/dietpi.txt - break - done - - fi - # Avoid having AdGuard Home installed in parallel to Pi-hole if (( ${aSOFTWARE_INSTALL_STATE[93]} > 0 )) && (( ${aSOFTWARE_INSTALL_STATE[126]} > 0 )) then From 3c947e3b8a1fc706540fd6ec9ca7cf1be5e67d2e Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 25 Oct 2021 19:36:54 +0200 Subject: [PATCH 44/82] v7.8 + DietPi-Imager | Workaround for missing STDIN console in while loop --- .meta/dietpi-imager | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.meta/dietpi-imager b/.meta/dietpi-imager index 83372042e2..049a4e2f8a 100755 --- a/.meta/dietpi-imager +++ b/.meta/dietpi-imager @@ -422,16 +422,16 @@ # Disable and enable journal on ext3 and ext3 to clear it, when not root filesystem (where it was done already) if [[ $type != 'ext2' && $path != "$FP_ROOT_DEV" ]] then - G_EXEC tune2fs -O '^has_journal' "$path" - G_EXEC tune2fs -O 'has_journal' "$path" + G_EXEC tune2fs -O '^has_journal' "$path" < /dev/tty + G_EXEC tune2fs -O 'has_journal' "$path" < /dev/tty fi - G_EXEC_OUTPUT=1 G_EXEC zerofree -v "$path" + G_EXEC_OUTPUT=1 G_EXEC zerofree -v "$path" < /dev/tty else - G_EXEC mount "$path" $FP_MNT_TMP - G_EXEC_OUTPUT=1 G_EXEC fstrim -v $FP_MNT_TMP - Unmount_tmp + G_EXEC mount "$path" $FP_MNT_TMP < /dev/tty + G_EXEC_OUTPUT=1 G_EXEC fstrim -v $FP_MNT_TMP < /dev/tty + Unmount_tmp < /dev/tty # shellcheck disable=SC2015 - [[ $path == "$FP_ROOT_DEV" ]] && Run_fsck || G_EXEC_OUTPUT=1 G_EXEC fsck "$path" + [[ $path == "$FP_ROOT_DEV" ]] && Run_fsck < /dev/tty || G_EXEC_OUTPUT=1 G_EXEC fsck "$path" < /dev/tty fi done < <(lsblk -rnpo NAME,FSTYPE "$FP_SOURCE"?*) From 14f32b798a1337adcf9467a7329ae789e12aab33 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 25 Oct 2021 19:40:45 +0200 Subject: [PATCH 45/82] v7.8 + DietPi-PREP | Assure that DHCP leases are removed from final image, which can be recreated during PREP run --- PREP_SYSTEM_FOR_DIETPI.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index a7077c0947..4973292447 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1915,7 +1915,7 @@ _EOF_ G_EXEC rmdir /mnt/tmp_root G_DIETPI-NOTIFY 2 'Running general cleanup of misc files' - rm -Rfv /{root,home/*}/.{bash_history,nano_history,wget-hsts,cache,local,config,gnupg,viminfo,dbus,gconf,nano,vim,zshrc,oh-my-zsh} /etc/*- /var/{cache/debconf,lib/dpkg}/*-old + rm -Rfv /{root,home/*}/.{bash_history,nano_history,wget-hsts,cache,local,config,gnupg,viminfo,dbus,gconf,nano,vim,zshrc,oh-my-zsh} /etc/*- /var/{cache/debconf,lib/dpkg}/*-old /var/lib/dhcp/{,.??,.[^.]}* # Remove PREP script [[ -f $FP_PREP_SCRIPT ]] && rm -v "$FP_PREP_SCRIPT" From c5201706b6fde25ae2d3167819e7f39c9346f104 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 25 Oct 2021 20:55:42 +0200 Subject: [PATCH 46/82] v7.8 + DietPi-Imager | Remove DHCP leases as well here since those are created on shutdown when stopping dhclient it seems --- .meta/dietpi-imager | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.meta/dietpi-imager b/.meta/dietpi-imager index 049a4e2f8a..4b2879d914 100755 --- a/.meta/dietpi-imager +++ b/.meta/dietpi-imager @@ -318,8 +318,8 @@ # Remount image for any required edits G_EXEC mkdir $FP_MNT_TMP G_EXEC mount "$FP_ROOT_DEV" $FP_MNT_TMP - # - Remove bash history, which is stored on shutdown, hence cannot be removed via DietPi-PREP - rm -fv $FP_MNT_TMP/{root,home/*}/.bash_history + # - Remove bash history and DHCP leases, which are stored on shutdown, hence cannot be removed via DietPi-PREP + G_EXEC rm -f $FP_MNT_TMP/{root,home/*}/.bash_history $FP_MNT_TMP/var/lib/dhcp/*.leases if [[ $MOUNT_IT == 'On' ]] && G_WHIP_MSG "The ${SOURCE_TYPE,,} has been mounted to allow you reviewing or editing its content: - $FP_ROOT_DEV > $FP_MNT_TMP \nAn interactive bash subshell will open. From 696327422c594b5477ed80620a7d92da99ce90b0 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 25 Oct 2021 21:30:05 +0200 Subject: [PATCH 47/82] v7.8 + DietPi-PREP | Adjust Dropbear package marks when Buster was upgraded to Bullseye, so that no transitional dummy package remains --- PREP_SYSTEM_FOR_DIETPI.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 4973292447..6fd686d853 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -1089,6 +1089,13 @@ _EOF_ G_AGI "${aPACKAGES_REQUIRED_INSTALL[@]}" unset -v aPACKAGES_REQUIRED_INSTALL + # Adjust Dropbear package marks when Buster was upgraded to Bullseye + if (( $G_DISTRO > 5 )) && dpkg-query -s 'dropbear-run' &> /dev/null + then + G_EXEC apt-mark manual dropbear + G_EXEC apt-mark auto dropbear-run + fi + G_EXEC apt-get clean G_AGA From 825845ebb035b362229457b86c7fea3bb64f0268 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Tue, 26 Oct 2021 19:18:19 +0200 Subject: [PATCH 48/82] v7.8 (#4900) + Radxa Zero | Add initial support with hardware ID 74 + DietPi-PREP | Radxa Zero: Add "file" package which is used to detect whether the kernel image is compressed and in case uncompress it + DietPi-PREP | Radxa Zero: Disable Docker optimisation by default. It will be enabled instead within DietPi-Software when Docker or K3s are installed + DietPi-Software | Docker/K3s: Apply Docker optimisation in U-Boot environment file on Armbian based systems and Radxa Zero, which enables the cgroups used by virtualisation software + DietPi-Software | Docker: Merge install and config code blocks --- .meta/dietpi-survey_report | 1 + CHANGELOG.txt | 3 + PREP_SYSTEM_FOR_DIETPI.sh | 41 +++++++++- README.md | 1 + dietpi/dietpi-software | 116 +++++++++++++++-------------- dietpi/func/dietpi-obtain_hw_model | 7 +- 6 files changed, 112 insertions(+), 57 deletions(-) diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index d75c168e57..dde3fa841c 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -76,6 +76,7 @@ shopt -s extglob [71]='BeagleBone Black' [72]='ROCK Pi 4' [73]='ROCK Pi S' + [74]='Radxa Zero' ) ## Benchmark data arrays: aBENCH_XX[$HW_MODEL,${aBENCH_XX_INDEX[$HW_MODEL]}] diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9c85b42bf9..432eba77df 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,9 @@ v7.8 (2021-10-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 + Removed software: - Subsonic | Since it is not developed anymore and due to shared library dependencies only compatible with Debian Stretch, we removed Subsonic from DietPi-Software. With Airsonic-Advanced, we'll provide a well maintained and Bullseye-compatible alternative. If you currently have Subsonic installed, it will remain. If you want to uninstall it, follow the instructions here: https://github.com/MichaIng/DietPi/pull/4895 - emonHub | Since we do not have a single reported installation, we removed emonHub from DietPi-Software. If you currently have emonHub installed, it will remain. If you want to keep using and updating it, have a look at the official repository: https://github.com/openenergymonitor/emonhub. If you want to uninstall it, follow the instructions here: https://github.com/MichaIng/DietPi/pull/4895 diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index 6fd686d853..f5144503c8 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -395,6 +395,7 @@ _EOF_ '47' ': NanoPi R4S' '72' ': ROCK Pi 4' '73' ': ROCK Pi S' + '74' ': Radxa Zero' '' '●─ x86_64 ' '21' ': x86_64 Native PC' '20' ': x86_64 Virtual Machine' @@ -721,7 +722,7 @@ Currently installed: $G_DISTRO_NAME (ID: $G_DISTRO)"; then fi # - Entropy daemon: Use modern rng-tools5 on all devices where it has been proven to work, else haveged: https://github.com/MichaIng/DietPi/issues/2806 - if [[ $G_HW_MODEL -lt 10 || $G_HW_MODEL =~ ^(14|15|16|24|29|42|46|58|68|72)$ ]]; then # RPi, S922X, Odroid C4, RK3399 - 47 NanoPi R4S + if [[ $G_HW_MODEL -lt 10 || $G_HW_MODEL =~ ^(14|15|16|24|29|42|46|58|68|72|74)$ ]]; then # RPi, S922X, Odroid C4, RK3399 - 47 NanoPi R4S, Radxa Zero aPACKAGES_REQUIRED_INSTALL+=('rng-tools5') @@ -995,6 +996,25 @@ _EOF_ # NB: rockpis-dtbo is not required as it doubles the overlays that are already provided (among others) with the kernel package G_AGI rockpis-rk-ubootimg linux-4.4-rock-pi-s-latest rockchip-overlay u-boot-tools + # Radxa Zero (official Radxa Debian image) + elif (( $G_HW_MODEL == 74 )) && grep -q 'apt\.radxa\.com' /etc/apt/sources.list.d/*.list; then + + # 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_AGUP + + # Remove obsolete combined keyring + [[ -f '/etc/apt/trusted.gpg' ]] && G_EXEC rm /etc/apt/trusted.gpg + [[ -f '/etc/apt/trusted.gpg~' ]] && G_EXEC rm '/etc/apt/trusted.gpg~' + + # Preserve all installed kernel, device tree and bootloader packages, until fixed meta packages are available: https://github.com/radxa/apt + # Additionally install bc, required to calculate the initramfs size via custom hook (by Radxa) which updates /boot/uEnv.txt accordingly on initramfs updates + # And install "file" which is used to detect whether the kernel image is compressed and in case uncompress it + # shellcheck disable=SC2046 + G_AGI $(dpkg-query -Wf '${Package}\n' | grep -E '^linux-(image|dtb|u-boot)-|^u-boot') bc file + # - Generic kernel + device tree + U-Boot package auto detect else @@ -1018,7 +1038,9 @@ _EOF_ aPACKAGES_REQUIRED_INSTALL+=('armbian-firmware') - else + # - Do not install additional firmware on Radxa Zero for now + elif [[ $G_HW_MODEL != 74 ]] + then # Usually no firmware should be necessary for VMs. If user manually passes though some USB device, user might need to install the firmware then. if (( $G_HW_MODEL != 20 )); then @@ -1745,6 +1767,21 @@ _EOF_ # Ensure WiFi module pre-exists G_CONFIG_INJECT '8723bs' '8723bs' /etc/modules + # - Radxa Zero + elif (( $G_HW_MODEL == 74 )) + then + # Use ondemand CPU governor since schedutil currently causes kernel errors and hangs + G_CONFIG_INJECT 'CONFIG_CPU_GOVERNOR=' 'CONFIG_CPU_GOVERNOR=ondemand' /boot/dietpi.txt + + # uEnv.txt version (Radxa Debian image) + if [[ -d '/boot/uEnv.txt' ]] + then + # Reduce console log verbosity to default 4 to mute regular USB detection info messages + G_CONFIG_INJECT 'verbosity=' 'verbosity=4' /boot/uEnv.txt + + # 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 fi # - Armbian special diff --git a/README.md b/README.md index 3ecb41cb38..b0577fb335 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,7 @@ Links to hardware and software manufacturers, sources and build instructions use - [Sparky](https://github.com/sparkysbc?tab=repositories) [SBC](https://github.com/sparky-sbc/sparky-test) - [PINE64](https://www.pine64.org/) - [FriendlyARM](https://github.com/friendlyarm?tab=repositories) +- [Radxa](https://github.com/radxa/apt) - [Armbian](https://github.com/armbian) - [curl](https://github.com/curl/curl) - [vmtouch](https://github.com/hoytech/vmtouch) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index ce24b98b97..c5c81ce47b 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -7255,9 +7255,18 @@ _EOF_ G_EXEC_NOHALT=1 G_EXEC rm install.sh # Do not enter into a server restart loop on failure - [[ -d '/etc/systemd/system/k3s.service.d' ]] || G_EXEC mkdir -p /etc/systemd/system/k3s.service.d + [[ -d '/etc/systemd/system/k3s.service.d' ]] || G_EXEC mkdir /etc/systemd/system/k3s.service.d echo -e '[Service]\nRestart=on-success' > /etc/systemd/system/k3s.service.d/dietpi.conf + # Enable cgroups used by Docker and alike + if [[ -f '/boot/boot.cmd' ]] && grep -q 'docker_optimizations' /boot/boot.cmd + then + # Armbian + [[ -f '/boot/armbianEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/armbianEnv.txt + # Radxa Zero + [[ -f '/boot/uEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/uEnv.txt + fi + fi software_id=141 # Spotify Connect Web @@ -7836,6 +7845,42 @@ If you want to update ${aSOFTWARE_NAME[$software_id]}, please use its internal u # APT package G_AGI docker-ce + # 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 + G_EXEC eval "echo -e '[Service]\nType=simple' > /lib/systemd/system/docker.service.d/dietpi-simple.conf" + + # Config: https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file + # - Move Docker containers to dietpi_userdata + # - Log to systemd-journald (journalctl) by default with reduced log level: https://github.com/MichaIng/DietPi/issues/2388 + # + containerd: https://github.com/docker/docker.github.io/issues/9091 + [[ -d '/mnt/dietpi_userdata/docker-data' ]] || G_EXEC mkdir /mnt/dietpi_userdata/docker-data + if [[ -f '/etc/docker/daemon.json' ]] + then + GCI_PRESERVE=1 G_CONFIG_INJECT '"data-root":' ' "data-root": "/mnt/dietpi_userdata/docker-data",' /etc/docker/daemon.json '^\{([[:space:]]|$)' + GCI_PRESERVE=1 G_CONFIG_INJECT '"log-driver":' ' "log-driver": "journald",' /etc/docker/daemon.json '^\{([[:space:]]|$)' + GCI_PRESERVE=1 G_CONFIG_INJECT '"log-level":' ' "log-level": "warn",' /etc/docker/daemon.json '^\{([[:space:]]|$)' + GCI_PRESERVE=1 G_CONFIG_INJECT '"debug":' ' "debug": false,' /etc/docker/daemon.json '^\{([[:space:]]|$)' + else + [[ -d '/etc/docker' ]] || G_EXEC mkdir /etc/docker + echo '{ + "data-root": "/mnt/dietpi_userdata/docker-data", + "log-driver": "journald", + "log-level": "warn", + "debug": false +}' > /etc/docker/daemon.json + fi + G_CONFIG_INJECT '\[debug\]' '[debug]' /etc/containerd/config.toml + GCI_PRESERVE=1 G_CONFIG_INJECT 'level[[:blank:]]*=' ' level = "warn"' /etc/containerd/config.toml '^\[debug\]' + + # Enable cgroups used by Docker and alike + if [[ -f '/boot/boot.cmd' ]] && grep -q 'docker_optimizations' /boot/boot.cmd + then + # Armbian + [[ -f '/boot/armbianEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/armbianEnv.txt + # Radxa Zero + [[ -f '/boot/uEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/uEnv.txt + fi + fi software_id=134 # Docker Compose @@ -13069,43 +13114,6 @@ MINIO_VOLUMES="/mnt/dietpi_userdata/minio-data" _EOF_ fi - software_id=162 # Docker - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Set Docker service to "simple": https://github.com/MichaIng/DietPi/issues/2238#issuecomment-439474766 - G_EXEC mkdir -p /lib/systemd/system/docker.service.d - echo -e '[Service]\nType=simple' > /lib/systemd/system/docker.service.d/dietpi-simple.conf - - # Config: https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file - # - Move Docker containers to dietpi_userdata - # - Log to systemd-journald (journalctl) by default with reduced log level: https://github.com/MichaIng/DietPi/issues/2388 - # + containerd: https://github.com/docker/docker.github.io/issues/9091 - G_CONFIG_INJECT '\[debug\]' '[debug]' /etc/containerd/config.toml - GCI_PRESERVE=1 G_CONFIG_INJECT 'level[[:blank:]]*=' ' level = "warn"' /etc/containerd/config.toml '^\[debug\]' - G_EXEC mkdir -p /mnt/dietpi_userdata/docker-data - if [[ -f '/etc/docker/daemon.json' ]]; then - - GCI_PRESERVE=1 G_CONFIG_INJECT '"data-root":' ' "data-root": "/mnt/dietpi_userdata/docker-data",' /etc/docker/daemon.json '^\{([[:space:]]|$)' - GCI_PRESERVE=1 G_CONFIG_INJECT '"log-driver":' ' "log-driver": "journald",' /etc/docker/daemon.json '^\{([[:space:]]|$)' - GCI_PRESERVE=1 G_CONFIG_INJECT '"log-level":' ' "log-level": "warn",' /etc/docker/daemon.json '^\{([[:space:]]|$)' - GCI_PRESERVE=1 G_CONFIG_INJECT '"debug":' ' "debug": false,' /etc/docker/daemon.json '^\{([[:space:]]|$)' - - else - - G_EXEC mkdir -p /etc/docker - echo '{ - "data-root": "/mnt/dietpi_userdata/docker-data", - "log-driver": "journald", - "log-level": "warn", - "debug": false -}' > /etc/docker/daemon.json - - fi - - fi - software_id=185 # Portainer if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -15661,19 +15669,19 @@ _EOF_ Banner_Uninstalling - # Remove docker, all its unused dependencies and custom repository + # Packages, repo and key G_AGP docker-ce docker-ce-cli docker-engine - [[ -f '/etc/apt/sources.list.d/docker.list' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /etc/apt/sources.list.d/docker.list - [[ -f '/etc/apt/trusted.gpg.d/dietpi-docker.gpg' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /etc/apt/trusted.gpg.d/dietpi-docker.gpg - - # Remove service adjustments - [[ -d '/lib/systemd/system/docker.service.d' ]] && G_EXEC_NOEXIT=1 G_EXEC rm -R /lib/systemd/system/docker.service.d - # Delete data files - dietpi - [[ -d '/mnt/dietpi_userdata/docker-data' ]] && G_EXEC_NOEXIT=1 G_EXEC rm -R /mnt/dietpi_userdata/docker-data - # Remove default unused folder - [[ -d '/var/lib/docker' ]] && G_EXEC_NOEXIT=1 G_EXEC rm -R /var/lib/docker - # Remove configuration file - [[ -d '/etc/docker' ]] && G_EXEC_NOEXIT=1 G_EXEC rm -R /etc/docker + [[ -f '/etc/apt/sources.list.d/docker.list' ]] && G_EXEC rm /etc/apt/sources.list.d/docker.list + [[ -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 + # DietPi data dir + [[ -d '/mnt/dietpi_userdata/docker-data' ]] && G_EXEC rm -R /mnt/dietpi_userdata/docker-data + # Default data dir + [[ -d '/var/lib/docker' ]] && G_EXEC rm -R /var/lib/docker + # Config dir + [[ -d '/etc/docker' ]] && G_EXEC rm -R /etc/docker # Set Portainer as not installed aSOFTWARE_INSTALL_STATE[185]=0 @@ -15686,10 +15694,10 @@ _EOF_ Banner_Uninstalling G_AGP codium - [[ -f '/etc/apt/sources.list.d/dietpi-vscodium.list' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /etc/apt/sources.list.d/dietpi-vscodium.list - [[ -f '/etc/apt/trusted.gpg.d/dietpi-vscodium.gpg' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /etc/apt/trusted.gpg.d/dietpi-vscodium.gpg - rm -f /{usr/share/applications,{root,home/*}/Desktop}/codium.desktop - rm -Rf /{root,home/*}/{.config/VSCodium,.vscode-oss} + [[ -f '/etc/apt/sources.list.d/dietpi-vscodium.list' ]] && G_EXEC rm /etc/apt/sources.list.d/dietpi-vscodium.list + [[ -f '/etc/apt/trusted.gpg.d/dietpi-vscodium.gpg' ]] && G_EXEC rm /etc/apt/trusted.gpg.d/dietpi-vscodium.gpg + G_EXEC rm -f /{usr/share/applications,{root,home/*}/Desktop}/codium.desktop + G_EXEC rm -Rf /{root,home/*}/{.config/VSCodium,.vscode-oss} fi diff --git a/dietpi/func/dietpi-obtain_hw_model b/dietpi/func/dietpi-obtain_hw_model index 441a367ea7..8cc9008d17 100644 --- a/dietpi/func/dietpi-obtain_hw_model +++ b/dietpi/func/dietpi-obtain_hw_model @@ -17,6 +17,7 @@ # - MAX_G_HW_ARCH=10 # - MAX_G_DISTRO=7 # + # G_HW_MODEL 74 Radxa Zero # G_HW_MODEL 73 ROCK Pi S # G_HW_MODEL 72 ROCK Pi 4 # G_HW_MODEL 70 Sparky SBC @@ -304,7 +305,11 @@ G_HW_MODEL=$(mawk 'NR==1' $FP_G_HW_MODEL_IDENTIFIER) - if (( $G_HW_MODEL == 73 )); then + if (( $G_HW_MODEL == 74 )); then + + G_HW_MODEL_NAME='Radxa Zero' + + elif (( $G_HW_MODEL == 73 )); then G_HW_MODEL_NAME='ROCK Pi S' From 276b37fa93302abd4c325ff94c306ae3db1bf4ff Mon Sep 17 00:00:00 2001 From: MichaIng Date: Tue, 26 Oct 2021 21:52:27 +0200 Subject: [PATCH 49/82] v7.8 + DietPi-Software | Kodi: Remove user's configs on uninstall and minor coding in the install code block --- dietpi/dietpi-software | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index c5c81ce47b..889a8537c1 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -4500,18 +4500,14 @@ _EOF_ Banner_Installing # CEC + NFS support - if (( $G_DISTRO < 5 )); then - - local apackages=('libcec4' 'libnfs8') - - elif (( $G_DISTRO == 5 )); then - - local apackages=('libcec4' 'libnfs12') - - elif (( $G_DISTRO == 6 )); then - - local apackages=() # Fixed package dependencies + local apackages=() # Fixed package dependencies since Bullseye + if (( $G_DISTRO < 5 )) + then + apackages=('libcec4' 'libnfs8') + elif (( $G_DISTRO == 5 )) + then + apackages=('libcec4' 'libnfs12') fi # Odroids @@ -4548,8 +4544,8 @@ _EOF_ fi # Odroid N2/C4 - if [[ $G_HW_MODEL == 1[56] ]]; then - + if [[ $G_HW_MODEL == 1[56] ]] + then apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* kodi-aml-fbdev-odroid(,|$)' && apackages+=('kodi-aml-fbdev-odroid') || apackages=('kodi') echo 'media_clock firmware @@ -4573,11 +4569,9 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-n2-kodi.conf # 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 -qE '^P(ackage|rovides):.* kodi-odroid(,|$)' && apackages+=('kodi-odroid') || apackages=('kodi') - fi # RPi Raspbian Bullseye @@ -4588,39 +4582,34 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-n2-kodi.conf # Everything else else - apackages+=('kodi') # RPi - if (( $G_HW_MODEL < 10 )); then - + 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 - + 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 - G_EXEC mkdir -p /etc/polkit-1/localauthority/50-local.d + [[ -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 - fi G_AGI "${apackages[@]}" @@ -14514,7 +14503,7 @@ _EOF_ Banner_Uninstalling G_AGP kodi kodi-odroid kodi-aml-fbdev-odroid - G_EXEC rm -f /{root,home/*}/Desktop/kodi.desktop + G_EXEC rm -Rf /{root,home/*}/{.kodi,Desktop/kodi.desktop} [[ -f '/usr/share/applications/kodi.desktop' ]] && G_EXEC rm /usr/share/applications/kodi.desktop [[ -f '/etc/udev/rules.d/99-dietpi-kodi.rules' ]] && G_EXEC rm /etc/udev/rules.d/99-dietpi-kodi.rules [[ -f '/etc/modules-load.d/dietpi-n2-kodi.conf' ]] && G_EXEC rm /etc/modules-load.d/dietpi-n2-kodi.conf From fcfc30783be97738c0e3a3810b508ab9362405c9 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Tue, 26 Oct 2021 23:13:52 +0200 Subject: [PATCH 50/82] v7.8 + DietPi-Software | Logitech Media Server: Fix uninstall by stopping and removing the service before trying to uninstall the package, else the postinst script tries to remove the user, failing as it is still used by the service + DietPi-Software | Logitech Media Server: Merge install and config code blocks + DietPi-Software | Mosquitto: Merge install and config code blocks --- CHANGELOG.txt | 1 + dietpi/dietpi-software | 152 +++++++++++++++++++---------------------- 2 files changed, 70 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 432eba77df..9b5068ad40 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -14,6 +14,7 @@ Changes: Fixes: - DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 +- DietPi-Software | Logitech Media Server: Resolved an issue where the uninstall failed as the package postinst script tried to remove the service user before the service was stopped. 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/XXXX diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 889a8537c1..25f28d6125 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -5706,6 +5706,49 @@ _EOF_ G_AGI mosquitto + Remove_SysV mosquitto + + # Password file + if [[ ! -f '/etc/mosquitto/passwd' ]] + then + G_EXEC umask 0037 + > /etc/mosquitto/passwd # Pre-create file, required for pre-v1.6.10 (ARMv8 up to Buster): https://github.com/MichaIng/DietPi/issues/4424 + G_EXEC_PRE_FUNC(){ acommand[4]=$GLOBAL_PW; } + G_EXEC mosquitto_passwd -b /etc/mosquitto/passwd mosquitto "${GLOBAL_PW//?/X}" + G_EXEC chown root:mosquitto /etc/mosquitto/passwd + G_EXEC umask 0022 + fi + + # Config: /etc/mosquitto/conf.d exists, but doubled settings do not override each other and lead to a startup failure instead, which breaks the purpose we want to use it for. + # - Disable PID file, not required for systemd handling + G_EXEC sed -i '/^[[:blank:]]*pid_file[[:blank:]]/d' /etc/mosquitto/mosquitto.conf + [[ -d '/run/mosquitto' ]] && G_EXEC rm -R /run/mosquitto + # - Log to default STDERR > systemd-journald + G_EXEC sed -i '/^[[:blank:]]*log_dest[[:blank:]]/d' /etc/mosquitto/mosquitto.conf + [[ -d '/var/log/mosquitto' ]] && G_EXEC rm -R /var/log/mosquitto + # - Add default password file for authenticated requests: https://github.com/MichaIng/DietPi/issues/4133 + GCI_PRESERVE=1 G_CONFIG_INJECT 'password_file[[:blank:]]' 'password_file /etc/mosquitto/passwd' /etc/mosquitto/mosquitto.conf + # - Add default listener at port 1883 not bound to loopback IP: https://github.com/MichaIng/DietPi/issues/4133 + GCI_PRESERVE=1 G_CONFIG_INJECT 'listener[[:blank:]]' 'listener 1883' /etc/mosquitto/mosquitto.conf + + # Add/override default systemd unit: https://github.com/eclipse/mosquitto/tree/master/service/systemd + cat << '_EOF_' > /etc/systemd/system/mosquitto.service +[Unit] +Description=Mosquitto MQTT Broker (DietPi) +Documentation=man:mosquitto.conf(5) man:mosquitto(8) +Wants=network-online.target +After=network-online.target + +[Service] +Type=notify +NotifyAccess=main +User=mosquitto +ExecStart=/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target +_EOF_ fi software_id=131 # Blynk Server @@ -5920,6 +5963,31 @@ _EOF_ local fallback_url="https://downloads.slimdevices.com/LogitechMediaServer_v8.2.0/logitechmediaserver_8.2.0_$arch.deb" Download_Install "$(curl -sSfL "https://www.mysqueezebox.com/update/?version=8.2&geturl=1&os=deb$arch" | sed 's|^http://|https://|')" + # Remove bundled SysVinit service + systemctl -q is-enabled logitechmediaserver 2> /dev/null || systemctl -q is-active logitechmediaserver && G_EXEC systemctl disable --now logitechmediaserver + killall -qwr squeezeboxserver* # Provided service may not wait for exit, kill: https://github.com/MichaIng/DietPi/issues/1613#issuecomment-372787574 + Remove_SysV logitechmediaserver 1 + + # Grant user access to DietPi media files + G_EXEC usermod -aG dietpi squeezeboxserver + + # systemd service + cat << _EOF_ > /etc/systemd/system/logitechmediaserver.service +[Unit] +Description=Logitech Media Server (DietPi) + +[Service] +User=squeezeboxserver +ExecStart=$(command -v squeezeboxserver) --prefsdir /var/lib/squeezeboxserver/prefs --logdir /var/log/squeezeboxserver/ --cachedir /var/lib/squeezeboxserver/cache --charset=utf8 --logfile /var/log/squeezeboxserver/error.log +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +_EOF_ + # Grab our test media for user + Download_Test_Media + fi software_id=55 # Wordpress @@ -10509,38 +10577,6 @@ backend nodes _EOF_ fi - software_id=35 # Logitech Media Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Remove bundled SysVinit service - systemctl -q is-enabled logitechmediaserver 2> /dev/null || systemctl -q is-active logitechmediaserver && G_EXEC systemctl disable --now logitechmediaserver - killall -qwr squeezeboxserver* # Provided service may not wait for exit, kill: https://github.com/MichaIng/DietPi/issues/1613#issuecomment-372787574 - Remove_SysV logitechmediaserver 1 - - # Grant user access to DietPi media files - G_EXEC usermod -aG dietpi squeezeboxserver - - # systemd service - cat << _EOF_ > /etc/systemd/system/logitechmediaserver.service -[Unit] -Description=Logitech Media Server (DietPi) - -[Service] -User=squeezeboxserver -ExecStart=$(command -v squeezeboxserver) --prefsdir /var/lib/squeezeboxserver/prefs --logdir /var/log/squeezeboxserver/ --cachedir /var/lib/squeezeboxserver/cache --charset=utf8 --logfile /var/log/squeezeboxserver/error.log -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target -_EOF_ - # Grab our test media for user - Download_Test_Media - - fi - software_id=55 # Wordpress if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -12238,56 +12274,6 @@ After=icecast2.service [Service] ExecStart=$(command -v darkice) -[Install] -WantedBy=multi-user.target -_EOF_ - fi - - software_id=123 # Mosquitto - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - Remove_SysV mosquitto - - # Password file - if [[ ! -f '/etc/mosquitto/passwd' ]] - then - G_EXEC umask 0037 - > /etc/mosquitto/passwd # Pre-create file, required for pre-v1.6.10 (ARMv8 up to Buster): https://github.com/MichaIng/DietPi/issues/4424 - G_EXEC_PRE_FUNC(){ acommand[4]=$GLOBAL_PW; } - G_EXEC mosquitto_passwd -b /etc/mosquitto/passwd mosquitto "${GLOBAL_PW//?/X}" - G_EXEC chown root:mosquitto /etc/mosquitto/passwd - G_EXEC umask 0022 - fi - - # Config: /etc/mosquitto/conf.d exists, but doubled settings do not override each other and lead to a startup failure instead, which breaks the purpose we want to use it for. - # - Disable PID file, not required for systemd handling - G_EXEC sed -i '/^[[:blank:]]*pid_file[[:blank:]]/d' /etc/mosquitto/mosquitto.conf - [[ -d '/run/mosquitto' ]] && G_EXEC rm -R /run/mosquitto - # - Log to default STDERR > systemd-journald - G_EXEC sed -i '/^[[:blank:]]*log_dest[[:blank:]]/d' /etc/mosquitto/mosquitto.conf - [[ -d '/var/log/mosquitto' ]] && G_EXEC rm -R /var/log/mosquitto - # - Add default password file for authenticated requests: https://github.com/MichaIng/DietPi/issues/4133 - GCI_PRESERVE=1 G_CONFIG_INJECT 'password_file[[:blank:]]' 'password_file /etc/mosquitto/passwd' /etc/mosquitto/mosquitto.conf - # - Add default listener at port 1883 not bound to loopback IP: https://github.com/MichaIng/DietPi/issues/4133 - GCI_PRESERVE=1 G_CONFIG_INJECT 'listener[[:blank:]]' 'listener 1883' /etc/mosquitto/mosquitto.conf - - # Add/override default systemd unit: https://github.com/eclipse/mosquitto/tree/master/service/systemd - cat << '_EOF_' > /etc/systemd/system/mosquitto.service -[Unit] -Description=Mosquitto MQTT Broker (DietPi) -Documentation=man:mosquitto.conf(5) man:mosquitto(8) -Wants=network-online.target -After=network-online.target - -[Service] -Type=notify -NotifyAccess=main -User=mosquitto -ExecStart=/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf -ExecReload=/bin/kill -HUP $MAINPID - [Install] WantedBy=multi-user.target _EOF_ @@ -14798,13 +14784,13 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - G_AGP logitechmediaserver if [[ -f '/etc/systemd/system/logitechmediaserver.service' ]] then G_EXEC systemctl disable --now logitechmediaserver G_EXEC rm /etc/systemd/system/logitechmediaserver.service fi [[ -d '/etc/systemd/system/logitechmediaserver.service.d' ]] && G_EXEC rm -R /etc/systemd/system/logitechmediaserver.service.d + G_AGP logitechmediaserver getent passwd squeezeboxserver > /dev/null && G_EXEC userdel squeezeboxserver getent group squeezeboxserver > /dev/null && G_EXEC groupdel squeezeboxserver [[ -d '/var/lib/squeezeboxserver' ]] && G_EXEC rm -R /var/lib/squeezeboxserver From 17adf321e3631c9c3accb7e18932844ed9087a6e Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 27 Oct 2021 19:09:14 +0200 Subject: [PATCH 51/82] v7.8 + DietPi-Pre-patches | Apply the suite change update last, since it can only succeed when all other list patches have been applied --- .update/pre-patches | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.update/pre-patches b/.update/pre-patches index 08888dac12..e42841f95b 100644 --- a/.update/pre-patches +++ b/.update/pre-patches @@ -77,13 +77,6 @@ Package: linux-image-* linux-headers-* linux-dtb-* linux-u-boot-* armbian-firmwa \nPackage: *\nPin: origin apt.armbian.com\nPin-Priority: -1' > /etc/apt/preferences.d/dietpi-armbian" fi -# v7.5: Perform Debian suite change once, if the installed APT version does not allow it by default yet -if (( $G_DIETPI_VERSION_CORE < 7 || ( $G_DIETPI_VERSION_CORE == 7 && $G_DIETPI_VERSION_SUB < 5 ) )) && dpkg --compare-versions "$(dpkg-query -Wf '${VERSION}' apt)" lt 1.8.2.3 -then - G_DIETPI-NOTIFY 2 'Debian Bullseye has been released, so we accept the repository suite change once.' - G_EXEC apt-get -o 'Acquire::AllowReleaseInfoChange::Suite=true' -q update -fi - # v7.4 if getent passwd debian-transmission > /dev/null && ! getent group debian-transmission > /dev/null then @@ -144,5 +137,12 @@ then [[ -f '/etc/kernel/preinst.d/dietpi-initramfs_cleanup' && ! -x '/etc/kernel/preinst.d/dietpi-initramfs_cleanup' ]] && G_EXEC chmod +x /etc/kernel/preinst.d/dietpi-initramfs_cleanup fi +# v7.5: Perform Debian suite change once, if the installed APT version does not allow it by default yet +if (( $G_DIETPI_VERSION_CORE < 7 || ( $G_DIETPI_VERSION_CORE == 7 && $G_DIETPI_VERSION_SUB < 5 ) )) && dpkg --compare-versions "$(dpkg-query -Wf '${VERSION}' apt)" lt 1.8.2.3 +then + G_DIETPI-NOTIFY 2 'Debian Bullseye has been released, so we accept the repository suite change once.' + G_EXEC apt-get -o 'Acquire::AllowReleaseInfoChange::Suite=true' -q update +fi + exit 0 } From a15f07039cd07c438eb0f5c26e32c08dad78162b Mon Sep 17 00:00:00 2001 From: MichaIng Date: Thu, 28 Oct 2021 21:36:48 +0200 Subject: [PATCH 52/82] v7.8 + DietPi-LetsEncrypt | Do not set HSTS header in ownCloud/Nextcloud (subdir) configs. This is set for the whole domain in the parent configuration, the only place where it makes sense as it forcefully affects the whole host. --- .conf/dps_114/nginx.nextcloud.conf | 1 - .conf/dps_47/nginx.owncloud.conf | 1 - dietpi/dietpi-letsencrypt | 8 -------- 3 files changed, 10 deletions(-) diff --git a/.conf/dps_114/nginx.nextcloud.conf b/.conf/dps_114/nginx.nextcloud.conf index c048c41a12..7c27faf5af 100644 --- a/.conf/dps_114/nginx.nextcloud.conf +++ b/.conf/dps_114/nginx.nextcloud.conf @@ -24,7 +24,6 @@ location ^~ /nextcloud { #pagespeed off; # HTTP response headers borrowed from Nextcloud `.htaccess` - #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always; add_header Referrer-Policy "no-referrer" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Download-Options "noopen" always; diff --git a/.conf/dps_47/nginx.owncloud.conf b/.conf/dps_47/nginx.owncloud.conf index e99901a6b0..ed13b5ce24 100644 --- a/.conf/dps_47/nginx.owncloud.conf +++ b/.conf/dps_47/nginx.owncloud.conf @@ -3,7 +3,6 @@ location ^~ /owncloud { # Add headers to serve security related headers - #add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; add_header X-Content-Type-Options nosniff always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; diff --git a/dietpi/dietpi-letsencrypt b/dietpi/dietpi-letsencrypt index aaa8cecb90..3616f8f9fb 100644 --- a/dietpi/dietpi-letsencrypt +++ b/dietpi/dietpi-letsencrypt @@ -250,14 +250,6 @@ _EOF_ fi - # Apply HSTS header to ownCloud/Nextcloud config - if (( $LETSENCRYPT_HSTS )); then - - [[ -f '/etc/nginx/sites-dietpi/dietpi-owncloud.conf' ]] && G_EXEC sed -i 's/#add_header Strict-Transport-Security/add_header Strict-Transport-Security/g' /etc/nginx/sites-dietpi/dietpi-owncloud.conf - [[ -f '/etc/nginx/sites-dietpi/dietpi-nextcloud.conf' ]] && G_EXEC sed -i 's/#add_header Strict-Transport-Security/add_header Strict-Transport-Security/g' /etc/nginx/sites-dietpi/dietpi-nextcloud.conf - - fi - Apply_To_Web_Applications # Apply changes by restarting Nginx From 52224f0bf27b1da43f0491be58bc57b7f866fbfc Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 30 Oct 2021 18:35:41 +0200 Subject: [PATCH 53/82] v7.8 + DietPi-Software | Single File PHP Gallery: Merge install and config code blocks and minor coding, reinstall and uninstall enhencements --- dietpi/dietpi-software | 54 +++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 25f28d6125..08bf78bcdd 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -1055,7 +1055,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=56 aSOFTWARE_NAME[$software_id]='Single File PHP Gallery' - aSOFTWARE_DESC[$software_id]='website to host and browse your images' + aSOFTWARE_DESC[$software_id]='Website to host and browse your images' aSOFTWARE_CATX[$software_id]=6 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/social/#single-file-php-gallery' aSOFTWARE_DEPS[$software_id]='89 webserver' @@ -6177,10 +6177,30 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing + # Install required PHP modules: https://sye.dk/sfpg/ DEPS_LIST="$PHP_NAME-gd" Download_Install 'https://dietpi.com/downloads/binaries/all/Single_File_PHP_Gallery.7z' /var/www/gallery + # Enable required PHP modules + G_EXEC phpenmod gd + + # Cache/thumbnails/database + [[ -d '/var/www/gallery/_sfpg_data' ]] || G_EXEC mkdir /var/www/gallery/_sfpg_data + G_EXEC chown www-data /var/www/gallery/_sfpg_data + + # Enable (Some type of security trigger) + G_EXEC sed -i "/define('SECURITY_PHRASE'/c\\\tdefine('SECURITY_PHRASE', 'true');" /var/www/gallery/index.php + + # Create test galleries + [[ -d '/var/www/gallery/DietPi' ]] || G_EXEC mkdir /var/www/gallery/DietPi + [[ -f '/var/www/gallery/DietPi/logo_256.png' ]] || G_THREAD_START curl -sSfL 'https://dietpi.com/images/dietpi-logo_256x256.png' -o /var/www/gallery/DietPi/logo_256.png + [[ -d '/var/www/gallery/Tr-Zero' ]] || G_EXEC mkdir /var/www/gallery/Tr-Zero + [[ -f '/var/www/gallery/Tr-Zero/SS_0.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/SS_0.jpg' -o /var/www/gallery/Tr-Zero/SS_0.jpg + [[ -f '/var/www/gallery/Tr-Zero/SS_1.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/SS_44.jpg' -o /var/www/gallery/Tr-Zero/SS_1.jpg + [[ -f '/var/www/gallery/Tr-Zero/SS_2.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/3.png' -o /var/www/gallery/Tr-Zero/SS_2.jpg + G_THREAD_WAIT + fi software_id=40 # Ampache @@ -10983,32 +11003,6 @@ _EOF_ fi - software_id=56 # Single File PHP Gallery - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Enable required PHP modules: https://sye.dk/sfpg/ - G_EXEC phpenmod gd - - # Get test images - G_EXEC mkdir -p /var/www/gallery/DietPi - G_EXEC curl -sSfL https://dietpi.com/images/dietpi-logo_256x256.png -o /var/www/gallery/DietPi/logo_256.png - - G_EXEC mkdir -p /var/www/gallery/Tr-Zero - G_EXEC curl -sSfL https://media.indiedb.com/images/games/1/25/24673/SS_0.jpg -o /var/www/gallery/Tr-Zero/SS_0.jpg - G_EXEC curl -sSfL https://media.indiedb.com/images/games/1/25/24673/SS_44.jpg -o /var/www/gallery/Tr-Zero/SS_1.jpg - G_EXEC curl -sSfL https://media.indiedb.com/images/games/1/25/24673/3.png -o /var/www/gallery/Tr-Zero/SS_2.jpg - - # Permissions for cache/thumbnail/database - G_EXEC mkdir -p /var/www/gallery/_sfpg_data - G_EXEC chown www-data:www-data /var/www/gallery/_sfpg_data - - # Enable (Some type of security trigger) - G_EXEC sed -i "/define('SECURITY_PHRASE'/c\\\tdefine('SECURITY_PHRASE', 'true');" /var/www/gallery/index.php - - fi - software_id=40 # Ampache if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -14887,9 +14881,9 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - [[ -f '/var/www/gallery/index.php' ]] && rm /var/www/gallery/index.php - [[ -f '/var/www/gallery/readme.txt' ]] && rm /var/www/gallery/readme.txt - [[ -d '/var/www/gallery/_sfpg_data' ]] && rm -R /var/www/gallery/_sfpg_data + [[ -f '/var/www/gallery/index.php' ]] && G_EXEC rm /var/www/gallery/index.php + [[ -f '/var/www/gallery/readme.txt' ]] && G_EXEC rm /var/www/gallery/readme.txt + [[ -d '/var/www/gallery/_sfpg_data' ]] && G_EXEC rm -R /var/www/gallery/_sfpg_data fi From 9545e5243464420fd1487f480894558448d07329 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 30 Oct 2021 19:25:30 +0200 Subject: [PATCH 54/82] v7.8 + DietPi-Start_Kodi | Pass through "kodi" command arguments --- dietpi/misc/start_kodi | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/dietpi/misc/start_kodi b/dietpi/misc/start_kodi index 730400097e..d7ce72ad3c 100644 --- a/dietpi/misc/start_kodi +++ b/dietpi/misc/start_kodi @@ -13,7 +13,7 @@ # - Starts Kodi the correct way for various HW models from desktop and console # # Usage: - # - /boot/dietpi/misc/start_kodi + # - /boot/dietpi/misc/start_kodi #//////////////////////////////////// # Load $G_HW_MODEL @@ -23,21 +23,19 @@ # Main Loop #///////////////////////////////////////////////////////////////////////////////////// # Bullseye + RPi 32-bit + Odroid N2 + Odroid C4: Kodi starts without X server - if [ "$G_HW_MODEL" -lt 10 ] && [ "$(dpkg --print-architecture)" = 'armhf' ] || [ "$G_DISTRO" -ge 6 ] || [ "$G_HW_MODEL" = 15 ] || [ "$G_HW_MODEL" = 16 ]; then - - exec kodi --standalone + if [ "$G_HW_MODEL" -lt 10 ] && [ "$(dpkg --print-architecture)" = 'armhf' ] || [ "$G_DISTRO" -ge 6 ] || [ "$G_HW_MODEL" = 15 ] || [ "$G_HW_MODEL" = 16 ] + then + exec kodi --standalone "$@" # Everything else # - From desktop - elif [ "$DISPLAY" ]; then - - exec kodi + elif [ "$DISPLAY" ] + then + exec kodi "$@" # - From console else - - exec xinit "$(command -v kodi)" --standalone - + exec xinit "$(command -v kodi)" --standalone "$@" fi #------------------------------------------------------------------------------------- From 9841e04e93ff35ef4ef1ee1965dc456c56151dd4 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 31 Oct 2021 02:22:00 +0200 Subject: [PATCH 55/82] v7.8 + DietPi-Software | NZBGet: Merge install and config code blocks and use G_CONFIG_INJECT to more transparently edit the configuration file. Also apply stricter modes to the config file as it contains the control password in plain text. --- dietpi/dietpi-software | 94 ++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 08bf78bcdd..8daec9f75e 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -773,7 +773,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=149 aSOFTWARE_NAME[$software_id]='NZBGet' - aSOFTWARE_DESC[$software_id]='nzb download manager' + aSOFTWARE_DESC[$software_id]='NZB download manager' aSOFTWARE_CATX[$software_id]=3 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/bittorrent/#nzbget' #------------------ @@ -7742,6 +7742,50 @@ _EOF_ G_EXEC_OUTPUT=1 G_EXEC dash package.run --destdir /mnt/dietpi_userdata/nzbget G_EXEC_NOHALT=1 G_EXEC rm package.run + # User + Create_User -g dietpi -d /mnt/dietpi_userdata/nzbget nzbget + + # Permissions + G_EXEC chown -R nzbget:root /mnt/dietpi_userdata/nzbget + G_EXEC chmod 0600 /mnt/dietpi_userdata/nzbget/nzbget.conf + + # Config + G_BACKUP_FP /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'MainDir=' 'MainDir=/mnt/dietpi_userdata/downloads' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'DestDir=' 'DestDir=/mnt/dietpi_userdata/downloads/complete' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'LogFile=' 'LogFile=/var/log/nzbget.log' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ControlUsername=' 'ControlUsername=admin' /mnt/dietpi_userdata/nzbget/nzbget.conf + GCI_PASSWORD=1 G_CONFIG_INJECT 'ControlPassword=' "ControlPassword=$GLOBAL_PW" /mnt/dietpi_userdata/nzbget/nzbget.conf + + # Umask: https://github.com/MichaIng/DietPi/issues/1999 + G_CONFIG_INJECT 'UMask=' 'UMask=0002' /mnt/dietpi_userdata/nzbget/nzbget.conf + + # Optimisations + G_CONFIG_INJECT 'Server1.Cipher=' 'Server1.Cipher=RC4-MD5' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'CrcCheck=' 'CrcCheck=no' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ParScan=' 'ParScan=limited' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ParThreads=' "ParThreads=$G_HW_CPU_CORES" /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'DebugTarget=' 'DebugTarget=none' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'CrashTrace=' 'CrashTrace=no' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'DetailTarget=' 'DetailTarget=none' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ParBuffer=' "ParBuffer=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ArticleCache=' "ArticleCache=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'WriteBuffer=' "WriteBuffer=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf + + # Service + cat << '_EOF_' > /etc/systemd/system/nzbget.service +[Unit] +Description=NZBGet (DietPi) + +[Service] +Type=forking +User=nzbget +WorkingDirectory=/mnt/dietpi_userdata/nzbget +ExecStart=/mnt/dietpi_userdata/nzbget/nzbget -D + +[Install] +WantedBy=multi-user.target +_EOF_ fi software_id=155 # HTPC Manager @@ -12846,54 +12890,6 @@ _EOF_ fi - software_id=149 # NZBGet - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - Create_User -g dietpi -d /mnt/dietpi_userdata/nzbget nzbget - - G_BACKUP_FP /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/MainDir=/c\MainDir=/mnt/dietpi_userdata/downloads' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/DestDir=/c\DestDir=/mnt/dietpi_userdata/downloads/complete' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/LogFile=/c\LogFile=/var/log/nzbget.log' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/ControlUsername=/c\ControlUsername=admin' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i "/ControlPassword=/c\ControlPassword=$GLOBAL_PW" /mnt/dietpi_userdata/nzbget/nzbget.conf - - # Umask: https://github.com/MichaIng/DietPi/issues/1999 - sed -i '/UMask=/c\UMask=0002' /mnt/dietpi_userdata/nzbget/nzbget.conf - - # Optimisations - sed -i '/Server1.Cipher=/c\Server1.Cipher=RC4-MD5' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/CrcCheck=/c\CrcCheck=no' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/ParScan=/c\ParScan=limited' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i "/ParThreads=/c\ParThreads=$G_HW_CPU_CORES" /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/DebugTarget=/c\DebugTarget=none' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/CrashTrace=/c\CrashTrace=no' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i '/DetailTarget=/c\DetailTarget=none' /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i "/ParBuffer=/c\ParBuffer=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i "/ArticleCache=/c\ArticleCache=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf - sed -i "/WriteBuffer=/c\WriteBuffer=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf - - # Service - cat << '_EOF_' > /etc/systemd/system/nzbget.service -[Unit] -Description=NZBget (DietPi) - -[Service] -Type=forking -User=nzbget -WorkingDirectory=/mnt/dietpi_userdata/nzbget -ExecStart=/mnt/dietpi_userdata/nzbget/nzbget -D - -[Install] -WantedBy=multi-user.target -_EOF_ - # Permissions - G_EXEC chown -R nzbget:root /mnt/dietpi_userdata/nzbget - - fi - software_id=155 # HTPC Manager if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then From a9cf719ace1a61a1208e4cf9d16547484def93b2 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 31 Oct 2021 02:57:09 +0100 Subject: [PATCH 56/82] v7.8 + META | Use new shortened PayPal donation URL --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 6cf67a4e2e..b6cdb8cce1 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,3 @@ # https://help.github.com/en/github/administering-a-repository/displaying-a-sponsor-button-in-your-repository patreon: DietPi -custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6DVBECXRW3TAA \ No newline at end of file +custom: https://www.paypal.com/donate?hosted_button_id=6DVBECXRW3TAA From 3f418a6e01e12b04bccb805c6bd4db4e7cad40b0 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 31 Oct 2021 16:25:35 +0100 Subject: [PATCH 57/82] v7.8 + DietPi-Software | Chromium: Remove obsolete chromium-browser package check on RPi for 64-bit systems. It is now available for both architectures on Buster and Bullseye. --- dietpi/dietpi-software | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 8daec9f75e..7c2d1f72fd 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -6997,18 +6997,16 @@ _EOF_ # Apply preference index INDEX_BROWSER_TARGET=-2 INDEX_BROWSER_CURRENT=-2 - # RPi: Use RPi repo package, on 64-bit system - if (( $G_HW_MODEL < 10 )) && { [[ $(dpkg --print-architecture) == 'armhf' ]] || apt-cache dumpavail | grep -q '^Filename: .*/chromium-browser_.*_arm64.deb$'; }; then + if (( $G_HW_MODEL > 9 )) + then + G_AGI chromium + # RPi: Use RPi repo package + 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[@]}" - - else - - G_AGI chromium - fi # Allow root, start maximized and disable sandbox under root (blank screen without) @@ -7025,20 +7023,18 @@ _EOF_ --disable-composited-antialiasing" # RPi: Leave OpenGL choice to user, as it also depends on RPi model - if (( $G_HW_MODEL < 10 )); then - + if (( $G_HW_MODEL < 10 )) + then : # x86_64: OpenGL - elif [[ $G_HW_MODEL == 2[01] ]]; then - + elif [[ $G_HW_ARCH == 1 ]] + then : # GLES else - export_options+=' --use-gl=egl' - fi export_options+='"' From 003838b62571cf92941c60d76e8fd79cc513bc03 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 31 Oct 2021 22:12:06 +0100 Subject: [PATCH 58/82] v7.8 (#4903) + DietPi-Software | Roon Server: Resolved an issue where the internal updater purged all Roon Server data and configs, since the data directory was located within the install directory. Roon Server will now be installed to /opt/roonserver while the data directory remains at /mnt/dietpi_userdata/roonserver. This change will be applied via DietPi update as well, your data and configs will remain untouched. Many thanks to @JanKoudijs for reporting this issue and providing a solution: https://github.com/MichaIng/DietPi/pull/4897 + DietPi-Software | Roon Server: Merge install and config code blocks + DietPi-Patches | Roon Server: Instead of removing and reinstalling the old Roon Server instance, it is now moved to the new location, so that possible issues due to version changes are omitted. + DietPi-Software | Roon Server: Use Samba Client as dependency instead of installing cifs-utils independantly. + DietPi-Software | Samba/NFS Client: Do not deal with the network drive info files, as this is all done in dietpi-drive_manager. Also do not re-create it on uninstall: Not necessary when users obviously managed to set it up already. Consequently remove the default mount points on uninstall if it is empty, hence a network drive has been mounted on it already. Also add some more error handling and use failsafe unmount flags. + DietPi-Drive_Manager | Set Samba/NFS Client install states on mount, since all relevant install steps (package installs) are done. + DietPi-Software | Roon Server: Add .NET core dependency for the upcoming release, planned at November 3rd. Add Bookworm support for it and all other cases where .NET core is used and dependencies required. + CHANGELOG | Roon Server: Added support for the new .NET core based version, released on November 3rd, which is expected to have improved performance compared to the old Mono based version. To resolve an old issue with our Roon Server implementation (see below), a reinstall is done during the DietPi update, which pulls in the .NET core dependencies as well. But this will NOT update the Roon Server version to prevent issues with potentially required migration steps. After updating DietPi, use Roon's internal updater to benefit from the new version. --- .update/patches | 12 +++ CHANGELOG.txt | 2 + dietpi/dietpi-drive_manager | 14 ++-- dietpi/dietpi-software | 149 +++++++++++++++++------------------- 4 files changed, 91 insertions(+), 86 deletions(-) diff --git a/.update/patches b/.update/patches index d965fa2e25..2eff6bc8a3 100644 --- a/.update/patches +++ b/.update/patches @@ -504,6 +504,18 @@ Patch_7_8() [[ -f '/boot/dietpi/.installed' ]] && grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[99\]=' /boot/dietpi/.installed && G_EXEC sed -i '/^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[99\]=/d' /boot/dietpi/.installed # Remove obsolete emonHub API key setting from dietpi.txt grep -q 'SOFTWARE_EMONHUB_APIKEY' /boot/dietpi.txt && G_EXEC sed -Ei '/(SOFTWARE_EMONHUB_APIKEY|^#.*EmonCMS)/d' /boot/dietpi.txt + + # Reinstall Roon Server + if [[ -f '/boot/dietpi/.installed' && ! -d '/opt/roonserver' ]] && grep -q '^[[:blank:]]*aSOFTWARE_INSTALL_STATE\[154\]=2' /boot/dietpi/.installed + then + G_DIETPI-NOTIFY 2 'Reinstalling Roon Server to resolve an issue where the internal updater purges all Roon data and configs' + G_EXEC mkdir -p /opt/roonserver + for i in /mnt/dietpi_userdata/roonserver/{Appliance,RoonMono,Server,check.sh,start.sh,VERSION} + do + [[ -e $i ]] && G_EXEC mv "$i" "/opt${i#/mnt/dietpi_userdata}" + done + /boot/dietpi/dietpi-software reinstall 154 + fi } # v6.35 => v7 migration diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9b5068ad40..1d42ca295f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -11,10 +11,12 @@ Removed software: Changes: - Odroid N1 | Removed support: We don't have a single reported system, which makes sense as this model was never really released. Only a small number of developer samples are floating around, not worth to keep maintaining an image and dedicated code. If there is really an Odroid N1 DietPi system out there, it will be automatically migrated to the Generic Rockchip RK3399 device ID on DietPi update. - DietPi-Config | The option to prefer IPv4 connections when IPv6 is enabled has been removed: This only worked for APT and wget, while e.g. cURL and ping were never affected by this setting, which meant an inconsistent behaviour. If one faces issues with IPv6 enabled, it should be simply disabled instead of preferring/forcing IPv4 only for specific tools. +- DietPi-Software | Roon Server: Added support for the new .NET core based version, released on November 3rd, which is expected to have improved performance compared to the old Mono based version. To resolve an old issue with our Roon Server implementation (see below), a reinstall is done during the DietPi update, which pulls in the .NET core dependencies as well. But this will NOT update the Roon Server version to prevent issues with potentially required migration steps. After updating DietPi, use Roon's internal updater to benefit from the new version. Fixes: - DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 - DietPi-Software | Logitech Media Server: Resolved an issue where the uninstall failed as the package postinst script tried to remove the service user before the service was stopped. +- DietPi-Software | Roon Server: Resolved an issue where the internal updater purged all Roon Server data and configs, since the data directory was located within the install directory. Roon Server will now be installed to /opt/roonserver while the data directory remains at /mnt/dietpi_userdata/roonserver. This change will be applied via DietPi update as well, your data and configs will remain untouched. Many thanks to @JanKoudijs for reporting this issue and providing a solution: https://github.com/MichaIng/DietPi/pull/4897 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/XXXX diff --git a/dietpi/dietpi-drive_manager b/dietpi/dietpi-drive_manager index 94773ad638..3849ddc5b2 100644 --- a/dietpi/dietpi-drive_manager +++ b/dietpi/dietpi-drive_manager @@ -1715,8 +1715,8 @@ NB: If you are planning to dedicate the drive to this system, it is recommended local samba_fp_mount_target='samba' # Remove info file and default mount dir - [[ -f '/mnt/samba/readme.txt' ]] && rm /mnt/samba/readme.txt - [[ -d '/mnt/samba' ]] && rmdir --ignore-fail-on-non-empty /mnt/samba + [[ -f '/mnt/samba/readme.txt' ]] && G_EXEC rm /mnt/samba/readme.txt + [[ -d '/mnt/samba' ]] && G_EXEC rmdir --ignore-fail-on-non-empty /mnt/samba # User inputs G_WHIP_DEFAULT_ITEM=$samba_clientname @@ -1733,7 +1733,7 @@ NB: If you are planning to dedicate the drive to this system, it is recommended G_WHIP_PASSWORD 'Please enter the fileservers password\n - eg: LetMeIn' || return samba_clientpassword=$result - unset result + unset -v result G_WHIP_DEFAULT_ITEM=$samba_fp_mount_target G_WHIP_INPUTBOX 'Please enter a unique folder name for the mount location (eg: samba). This will be placed in /mnt/' || return @@ -1747,7 +1747,8 @@ NB: If you are planning to dedicate the drive to this system, it is recommended # Unmount if connected umount "$samba_fp_mount_target" 2> /dev/null - G_AG_CHECK_INSTALL_PREREQ smbclient cifs-utils + G_AG_CHECK_INSTALL_PREREQ cifs-utils smbclient + G_CONFIG_INJECT 'aSOFTWARE_INSTALL_STATE\[1\]=' 'aSOFTWARE_INSTALL_STATE[1]=2' /boot/dietpi/.installed # Mount now G_EXEC mkdir -p "$samba_fp_mount_target" @@ -1805,8 +1806,8 @@ _EOF_ local nfs_fp_server_share='/' # Remove info file and default mount dir - [[ -f '/mnt/nfs_client/readme.txt' ]] && rm /mnt/nfs_client/readme.txt - [[ -d '/mnt/nfs_client' ]] && rmdir --ignore-fail-on-non-empty /mnt/nfs_client + [[ -f '/mnt/nfs_client/readme.txt' ]] && G_EXEC rm /mnt/nfs_client/readme.txt + [[ -d '/mnt/nfs_client' ]] && G_EXEC rmdir --ignore-fail-on-non-empty /mnt/nfs_client # User inputs G_WHIP_DEFAULT_ITEM=$nfs_server_ip @@ -1827,6 +1828,7 @@ _EOF_ umount "$nfs_fp_mount_target" 2> /dev/null G_AG_CHECK_INSTALL_PREREQ nfs-common netbase + G_CONFIG_INJECT 'aSOFTWARE_INSTALL_STATE\[110\]=' 'aSOFTWARE_INSTALL_STATE[110]=2' /boot/dietpi/.installed # Mount now G_EXEC mkdir -p "$nfs_fp_mount_target" diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 7c2d1f72fd..19a16db74d 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -550,7 +550,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" aSOFTWARE_DESC[$software_id]='Roon capable audio player and core' aSOFTWARE_CATX[$software_id]=2 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/media/#roon-server' - aSOFTWARE_DEPS[$software_id]='5 7' + aSOFTWARE_DEPS[$software_id]='1 5 7' # x86_64 only for ((i=1; i<=$MAX_G_HW_ARCH; i++)) do @@ -2395,7 +2395,7 @@ _EOF_ Download_Test_Media(){ [[ -f '/mnt/dietpi_userdata/Music/fourdee_tech.ogg' ]] && return - G_EXEC curl -sSfL https://dietpi.com/downloads/audio/fourdee_tech.ogg -o /mnt/dietpi_userdata/Music/fourdee_tech.ogg + G_EXEC curl -sSfL 'https://dietpi.com/downloads/audio/fourdee_tech.ogg' -o /mnt/dietpi_userdata/Music/fourdee_tech.ogg G_EXEC chown dietpi:dietpi /mnt/dietpi_userdata/Music/fourdee_tech.ogg G_EXEC chmod 0664 /mnt/dietpi_userdata/Music/fourdee_tech.ogg @@ -2928,11 +2928,7 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - - # Remove Information file - [[ -f '/mnt/samba/readme.txt' ]] && G_EXEC rm /mnt/samba/readme.txt - - G_AGI smbclient cifs-utils + G_AGI cifs-utils smbclient fi @@ -2941,9 +2937,6 @@ _EOF_ Banner_Installing - # Remove information file - [[ -f '/mnt/nfs_client/readme.txt' ]] && G_EXEC rm /mnt/nfs_client/readme.txt - # "netbase" is needed for mounting NFSv3: https://github.com/MichaIng/DietPi/issues/1898#issuecomment-406247814 G_AGI nfs-common netbase @@ -7448,9 +7441,7 @@ _EOF_ elif (( $G_DISTRO == 5 )) then DEPS_LIST+=' libicu63' - - elif (( $G_DISTRO == 6 )) - then + else DEPS_LIST+=' libicu67' fi fi @@ -7516,9 +7507,7 @@ _EOF_ elif (( $G_DISTRO == 5 )) then DEPS_LIST+=' libicu63' - - elif (( $G_DISTRO == 6 )) - then + else DEPS_LIST+=' libicu67' fi fi @@ -7707,9 +7696,7 @@ _EOF_ elif (( $G_DISTRO == 5 )) then DEPS_LIST+=' libicu63' - - elif (( $G_DISTRO == 6 )) - then + else DEPS_LIST+=' libicu67' fi fi @@ -7862,25 +7849,55 @@ _EOF_ Banner_Installing # https://help.roonlabs.com/portal/en/kb/articles/linux-install#Downloads - DEPS_LIST='cifs-utils' - - # Skip download and install, if already existent, manual removal or internal updater can be used: - if [[ ! -d '/mnt/dietpi_userdata/roonserver' ]]; then - - Download_Install 'https://download.roonlabs.com/builds/RoonServer_linuxx64.tar.bz2' - G_EXEC mv RoonServer /mnt/dietpi_userdata/roonserver + # .NET dependency: https://packages.microsoft.com/debian/ + if (( $G_DISTRO < 5 )) + then + DEPS_LIST='libicu57' + elif (( $G_DISTRO == 5 )) + then + DEPS_LIST='libicu63' else + DEPS_LIST='libicu67' + fi + # Skip download and install, if already existent, manual removal or internal updater can be used: + if [[ -d '/opt/roonserver' ]] + then G_AGI $DEPS_LIST DEPS_LIST= G_DIETPI-NOTIFY 2 "Existing install found\n -The ${aSOFTWARE_NAME[$software_id]} target install directory /mnt/dietpi_userdata/roonserver already exists. This will not be overwritten.\n +The ${aSOFTWARE_NAME[$software_id]} target install directory /opt/roonserver already exists. This will not be overwritten.\n If the existing instance is broken or obsolete, please manually backup config files and data, then remove this directory and rerun \"dietpi-software\".\n If you want to update ${aSOFTWARE_NAME[$software_id]}, please use its internal updater." + else + Download_Install 'https://download.roonlabs.com/builds/RoonServer_linuxx64.tar.bz2' + G_EXEC mv RoonServer /opt/roonserver fi + # Data dir + [[ -d '/mnt/dietpi_userdata/roonserver' ]] || G_EXEC mkdir /mnt/dietpi_userdata/roonserver + + # Service + cat << '_EOF_' > /etc/systemd/system/roonserver.service +[Unit] +Description=Roon Server (DietPi) +Wants=network-online.target +After=network-online.target + +[Service] +SyslogIdentifier=roonserver +Environment=ROON_DATAROOT=/mnt/dietpi_userdata/roonserver +#Environment=ROON_ID_DIR=/mnt/dietpi_userdata/roonserver +Group=dietpi +ExecStart=/opt/roonserver/start.sh + +[Install] +WantedBy=multi-user.target +_EOF_ + Download_Test_Media + fi software_id=156 # Steam @@ -12956,32 +12973,6 @@ _EOF_ G_EXEC chown root:lp /etc/cups/ /etc/cups/ppd/ /etc/cups/ssl/ fi - software_id=154 # Roon Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Service - cat << '_EOF_' > /etc/systemd/system/roonserver.service -[Unit] -Description=Roon Server (DietPi) -Wants=network-online.target -After=network-online.target - -[Service] -SyslogIdentifier=roonserver -Environment=ROON_DATAROOT=/mnt/dietpi_userdata/roonserver -Group=dietpi -ExecStart=/mnt/dietpi_userdata/roonserver/start.sh - -[Install] -WantedBy=multi-user.target -_EOF_ - # Permissions - #chown -R roon:dietpi /mnt/dietpi_userdata/roonserver - - fi - software_id=156 # Steam if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -14404,13 +14395,13 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - if [[ -f '/etc/systemd/system/roonserver.service' ]]; then - + if [[ -f '/etc/systemd/system/roonserver.service' ]] + then G_EXEC systemctl disable --now roonserver G_EXEC rm /etc/systemd/system/roonserver.service - fi [[ -d '/etc/systemd/system/roonserver.service.d' ]] && G_EXEC rm -R /etc/systemd/system/roonserver.service.d + [[ -d '/opt/roonserver' ]] && G_EXEC rm -R /opt/roonserver [[ -d '/mnt/dietpi_userdata/roonserver' ]] && G_EXEC rm -R /mnt/dietpi_userdata/roonserver fi @@ -15954,15 +15945,32 @@ _EOF_ Banner_Uninstalling # Unmount default mount point - umount -f /mnt/samba + findmnt /mnt/samba > /dev/null && G_EXEC umount -Rfl /mnt/samba # Remove from fstab - sed -i '/\/mnt\/samba/d' /etc/fstab + G_EXEC sed -i '\|/mnt/samba|d' /etc/fstab - G_AGP smbclient + G_AGP cifs-utils smbclient - # Add info file for installation method - echo -e 'Samba client can be installed and setup by DietPi-Drive_Manager.\nSimply run: dietpi-drive_manager and select the "Add network drive" option.' > /mnt/samba/readme.txt + [[ -d '/mnt/samba' ]] && G_EXEC rmdir --ignore-fail-on-non-empty /mnt/samba + + fi + + software_id=110 # NFS Client + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + + Banner_Uninstalling + + # Unmount default mount point + findmnt /mnt/nfs_client > /dev/null && G_EXEC umount -Rfl /mnt/nfs_client + + # Remove from fstab + G_EXEC sed -i '\|/mnt/nfs_client|d' /etc/fstab + + # nfs-kernel-server depends on nfs-common + dpkg-query -s 'nfs-common' &> /dev/null && G_EXEC apt-mark auto nfs-common + + [[ -d '/mnt/nfs_client' ]] && G_EXEC rmdir --ignore-fail-on-non-empty /mnt/nfs_client fi @@ -15992,25 +16000,6 @@ _EOF_ fi - software_id=110 # NFS Client - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then - - Banner_Uninstalling - - # Unmount default mount point - umount -f /mnt/nfs_client - - # Remove from fstab - sed -i '/\/mnt\/nfs_client/d' /etc/fstab - - # nfs-kernel-server depends on nfs-common - (( ${aSOFTWARE_INSTALL_STATE[109]} == 0 )) && G_AGP nfs-common - - # Add info file for installation method - echo -e 'NFS client can be installed and setup by DietPi-Drive_Manager.\nSimply run: dietpi-drive_manager and select the "Add network drive" option.' > /mnt/nfs_client/readme.txt - - fi - software_id=16 # Build-Essential if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then From 78937a2238b3953ba49af5c69ec32911a219104b Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sun, 31 Oct 2021 22:50:39 +0100 Subject: [PATCH 59/82] v7.8 (#4907) + Raspberry Pi Zero 2 W | Add initial support + DietPi-Config | Add overclocking profiles and correct defaults for Raspberry Pi 400 and Zero 2 + DietPi-Config | Adjust RPi overclocking profiles: Newer firmware only applies 100 MHz steps and does rounding in case. Add a power saving profile in more case and reduce minimum (idle) voltage as well. On RPi 4, generally raise the clocks as at least with newer firmware it runs more stable with higher clocks respectively lower voltage. + DietPi-Config | Tweak RPi 2 overclocking profiles, tested and compared with raspi-config. 1050 MHz is rounded up to 1.1 GHz which isn't stable or even unbootable, but RAM frequency can be raised instead. Would be good to have this tested on bcm2710 RPi 2 v1.2 model, but should be fine. + CHANGELOG | Add credits for RPi Zero 2 W testing + CHANGELOG | DietPi-Config: Overclocking profiles for most Raspberry Pi models have been updated to match the effective 100 MHz ARM/CPU frequency steps used by current firmware. Also an energy saving profile has been added to some models, which reduces minimum and maximum voltage a little, reducing energy consumption and heat emission a little on idle and on load. --- .meta/dietpi-survey_report | 2 +- CHANGELOG.txt | 2 + dietpi/dietpi-config | 403 ++++++++++-------- dietpi/func/dietpi-obtain_hw_model | 3 +- .../lib/dietpi/services/dietpi-firstboot.bash | 2 +- 5 files changed, 234 insertions(+), 178 deletions(-) diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index dde3fa841c..cc1736a9b1 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -15,7 +15,7 @@ shopt -s extglob [0]='Raspberry Pi 1 256M' [1]='Raspberry Pi 1/Zero 512M' [2]='Raspberry Pi 2' - [3]='Raspberry Pi 3/3+' + [3]='Raspberry Pi 3/3+/Zero 2' [4]='Raspberry Pi 4' [10]='Odroid C1' [11]='Odroid XU3/XU4/MC1/HC1/HC2' diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1d42ca295f..827428546f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,7 @@ v7.8 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 +- Raspberry Pi Zero 2 W | Initial support for this Raspberry Pi Zero/Zero W successor has been added, using hardware ID 3 for now (shared with RPi 3/3+), including overclocking profiles. Many thank to @CassTG for providing early hardware information and doing intensive overclocking tests: https://dietpi.com/phpbb/viewtopic.php?t=9599 Removed software: - Subsonic | Since it is not developed anymore and due to shared library dependencies only compatible with Debian Stretch, we removed Subsonic from DietPi-Software. With Airsonic-Advanced, we'll provide a well maintained and Bullseye-compatible alternative. If you currently have Subsonic installed, it will remain. If you want to uninstall it, follow the instructions here: https://github.com/MichaIng/DietPi/pull/4895 @@ -10,6 +11,7 @@ Removed software: Changes: - Odroid N1 | Removed support: We don't have a single reported system, which makes sense as this model was never really released. Only a small number of developer samples are floating around, not worth to keep maintaining an image and dedicated code. If there is really an Odroid N1 DietPi system out there, it will be automatically migrated to the Generic Rockchip RK3399 device ID on DietPi update. +- DietPi-Config | Overclocking profiles for most Raspberry Pi models have been updated to match the effective 100 MHz ARM/CPU frequency steps used by current firmware. Also an energy saving profile has been added to some models, which reduces minimum and maximum voltage a little, reducing energy consumption and heat emission a little on idle and on load. - DietPi-Config | The option to prefer IPv4 connections when IPv6 is enabled has been removed: This only worked for APT and wget, while e.g. cURL and ping were never affected by this setting, which meant an inconsistent behaviour. If one faces issues with IPv6 enabled, it should be simply disabled instead of preferring/forcing IPv4 only for specific tools. - DietPi-Software | Roon Server: Added support for the new .NET core based version, released on November 3rd, which is expected to have improved performance compared to the old Mono based version. To resolve an old issue with our Roon Server implementation (see below), a reinstall is done during the DietPi update, which pulls in the .NET core dependencies as well. But this will NOT update the Roon Server version to prevent issues with potentially required migration steps. After updating DietPi, use Roon's internal updater to benefit from the new version. diff --git a/dietpi/dietpi-config b/dietpi/dietpi-config index 35035f3844..62d093a2b7 100644 --- a/dietpi/dietpi-config +++ b/dietpi/dietpi-config @@ -3337,54 +3337,59 @@ Additional benchmarks: Reset_Overclocking(){ - # Defaults: https://github.com/raspberrypi/documentation/blob/master/configuration/config-txt/overclocking.md + # Defaults: https://github.com/raspberrypi/documentation/blob/develop/documentation/asciidoc/computers/config_txt/overclocking.adoc sed -i '/over_voltage=/c\#over_voltage=0' /boot/config.txt + sed -i '/over_voltage_min=/c\#over_voltage_min=0' /boot/config.txt - if (( $G_HW_MODEL == 4 )); then - - sed -i '/arm_freq=/c\#arm_freq=1500' /boot/config.txt + if (( $G_HW_MODEL == 4 )) + then sed -i '/core_freq=/c\#core_freq=500' /boot/config.txt sed -i '/sdram_freq=/d' /boot/config.txt - elif (( $G_HW_MODEL == 3 )); then + if [[ $G_HW_MODEL_NAME == *'400'* ]] + then + sed -i '/arm_freq=/c\#arm_freq=1800' /boot/config.txt + else + sed -i '/arm_freq=/c\#arm_freq=1500' /boot/config.txt + fi + elif (( $G_HW_MODEL == 3 )) + then sed -i '/core_freq=/c\#core_freq=400' /boot/config.txt - if [[ $G_HW_MODEL_NAME == *'+'* ]]; then - + if [[ $G_HW_MODEL_NAME == *'+'* ]] + then sed -i '/arm_freq=/c\#arm_freq=1400' /boot/config.txt sed -i '/sdram_freq=/c\#sdram_freq=500' /boot/config.txt + elif [[ $G_HW_MODEL_NAME == *'Zero'* ]] + then + sed -i '/arm_freq=/c\#arm_freq=1000' /boot/config.txt + sed -i '/sdram_freq=/c\#sdram_freq=450' /boot/config.txt else - sed -i '/arm_freq=/c\#arm_freq=1200' /boot/config.txt sed -i '/sdram_freq=/c\#sdram_freq=450' /boot/config.txt - fi - elif (( $G_HW_MODEL == 2 )); then - + elif (( $G_HW_MODEL == 2 )) + then sed -i '/arm_freq=/c\#arm_freq=900' /boot/config.txt sed -i '/core_freq=/c\#core_freq=250' /boot/config.txt sed -i '/sdram_freq=/c\#sdram_freq=450' /boot/config.txt - elif (( $G_HW_MODEL < 2 )); then - - if [[ $G_HW_MODEL_NAME == *'Zero'* ]]; then - + elif (( $G_HW_MODEL < 2 )) + then + if [[ $G_HW_MODEL_NAME == *'Zero'* ]] + then sed -i '/arm_freq=/c\#arm_freq=1000' /boot/config.txt sed -i '/core_freq=/c\#core_freq=400' /boot/config.txt sed -i '/sdram_freq=/c\#sdram_freq=450' /boot/config.txt - else - sed -i '/arm_freq=/c\#arm_freq=700' /boot/config.txt sed -i '/core_freq=/c\#core_freq=250' /boot/config.txt sed -i '/sdram_freq=/c\#sdram_freq=400' /boot/config.txt - fi - fi REBOOT_REQUIRED=1 @@ -3409,21 +3414,19 @@ Additional benchmarks: (( $G_HW_MODEL == 4 )) || local sdram_freq_value=$(sed -n '/sdram_freq=/{s/^[^=]*=//p;q}' /boot/config.txt) # RPi Zero - if [[ $G_HW_MODEL_NAME == 'RPi Zero'* ]]; then + if [[ $G_HW_MODEL == 1 && $G_HW_MODEL_NAME == *'Zero'* ]]; then G_WHIP_MENU_ARRAY=('none' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt') - if G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt"; then + G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 - TARGETMENUID=13 # Return to this menu + TARGETMENUID=13 # Return to this menu - case "$G_WHIP_RETURNED_VALUE" in + case "$G_WHIP_RETURNED_VALUE" in - 'none') Reset_Overclocking;; + 'none') Reset_Overclocking;; - esac - - fi + esac # RPi 1 elif (( $G_HW_MODEL < 2 )); then @@ -3433,178 +3436,241 @@ Additional benchmarks: 'none' ': 700 MHz ARM | 250 MHz core | 400 MHz SDRAM | 0 overvolt' 'safe' ': 900 MHz ARM | 250 MHz core | 400 MHz SDRAM | 2 overvolt' 'high' ': 900 MHz ARM | 500 MHz core | 400 MHz SDRAM | 4 overvolt' - 'extreme' ': 1025 MHz ARM | 500 MHz core | 400 MHz SDRAM | 6 overvolt' + 'extreme' ': 1000 MHz ARM | 500 MHz core | 400 MHz SDRAM | 6 overvolt' ) - if G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt"; then + G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 - TARGETMENUID=13 # Return to this menu + TARGETMENUID=13 # Return to this menu - case "$G_WHIP_RETURNED_VALUE" in - - 'none') Reset_Overclocking;; + case "$G_WHIP_RETURNED_VALUE" in - 'safe') + 'none') Reset_Overclocking;; - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=900' /boot/config.txt + 'safe') + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=900' /boot/config.txt + ;; - ;; + 'high') + Warning_Overclocking || return + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=900' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + ;; - 'high') + 'extreme') + Warning_Overclocking || return + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=6' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + ;; - Warning_Overclocking || return - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=900' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + esac - ;; + # RPi 2 + elif (( $G_HW_MODEL == 2 )); then - 'extreme') + G_WHIP_MENU_ARRAY=( - Warning_Overclocking || return - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=6' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1025' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + 'energy saving' ': 900 MHz ARM | 250 MHz core | 450 MHz SDRAM | -2 overvolt' + 'none' ': 900 MHz ARM | 250 MHz core | 450 MHz SDRAM | 0 overvolt' + 'low' ': 1000 MHz ARM | 450 MHz core | 450 MHz SDRAM | 2 overvolt' + 'med' ': 1000 MHz ARM | 500 MHz core | 450 MHz SDRAM | 3 overvolt' + 'extreme' ': 1000 MHz ARM | 500 MHz core | 500 MHz SDRAM | 4 overvolt' - ;; + ) - esac + G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 - fi + TARGETMENUID=13 # Return to this menu - # RPi 2 - elif (( $G_HW_MODEL == 2 )); then + case "$G_WHIP_RETURNED_VALUE" in - G_WHIP_MENU_ARRAY=( + 'energy saving') + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt + G_CONFIG_INJECT 'over_voltage_min=' 'over_voltage_min=-2' /boot/config.txt + ;; - 'none' ': 900 MHz ARM | 250 MHz core | 450 MHz SDRAM | 0 overvolt' - 'low' ': 1000 MHz ARM | 250 MHz core | 450 MHz SDRAM | 3 overvolt' - 'med' ': 1000 MHz ARM | 500 MHz core | 450 MHz SDRAM | 5 overvolt' - 'extreme' ': 1050 MHz ARM | 500 MHz core | 450 MHz SDRAM | 6 overvolt' + 'none') Reset_Overclocking;; - ) + 'low') + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=450' /boot/config.txt + ;; - if G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt"; then + 'med') + Warning_Overclocking || return + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=3' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + ;; - TARGETMENUID=13 # Return to this menu + 'extreme') + Warning_Overclocking || return + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + G_CONFIG_INJECT 'sdram_freq=' 'sdram_freq=500' /boot/config.txt + ;; - case "$G_WHIP_RETURNED_VALUE" in + esac - 'none') Reset_Overclocking;; + # RPi Zero 2 + elif [[ $G_HW_MODEL == 3 && $G_HW_MODEL_NAME == *'Zero'* ]]; then - 'low') + G_WHIP_MENU_ARRAY=( - Warning_Overclocking || return - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=3' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt + 'energy saving' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | -2 overvolt' + 'none' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt' + 'low' ': 1200 MHz ARM | 400 MHz core | 450 MHz SDRAM | 2 overvolt' + 'med' ': 1200 MHz ARM | 450 MHz core | 450 MHz SDRAM | 3 overvolt' + 'high' ': 1300 MHz ARM | 500 MHz core | 450 MHz SDRAM | 5 overvolt' - ;; + ) - 'med') + G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 - Warning_Overclocking || return - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + TARGETMENUID=13 # Return to this menu + Reset_Overclocking - ;; + case "$G_WHIP_RETURNED_VALUE" in - 'extreme') + 'energy saving') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt + G_CONFIG_INJECT 'over_voltage_min=' 'over_voltage_min=-2' /boot/config.txt + ;; - Warning_Overclocking || return - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=6' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1050' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + 'low') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1200' /boot/config.txt + ;; - ;; + 'med') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=3' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1200' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=450' /boot/config.txt + ;; - esac + 'high') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + ;; - fi + esac # RPi 3/3+ elif (( $G_HW_MODEL == 3 )); then # RPi 3+ - if [[ $G_HW_MODEL_NAME == *'+'* ]]; then - + if [[ $G_HW_MODEL_NAME == *'+'* ]] + then G_WHIP_MENU_ARRAY=( 'none' ': 1400 MHz ARM | 400 MHz core | 500 MHz SDRAM | 0 overvolt' - 'safe' ': 1450 MHz ARM | 400 MHz core | 500 MHz SDRAM | 0 overvolt' + 'safe' ': 1500 MHz ARM | 400 MHz core | 500 MHz SDRAM | 1 overvolt' ) # RPi 3 else - G_WHIP_MENU_ARRAY=( 'none' ': 1200 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt' 'low' ': 1300 MHz ARM | 400 MHz core | 450 MHz SDRAM | 3 overvolt' - 'med' ': 1325 MHz ARM | 400 MHz core | 450 MHz SDRAM | 4 overvolt' - 'high' ': 1350 MHz ARM | 400 MHz core | 450 MHz SDRAM | 5 overvolt' + 'med' ': 1300 MHz ARM | 450 MHz core | 450 MHz SDRAM | 4 overvolt' + 'high' ': 1300 MHz ARM | 500 MHz core | 450 MHz SDRAM | 5 overvolt' ) - fi - if G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt"; then + G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 - TARGETMENUID=13 # Return to this menu + TARGETMENUID=13 # Return to this menu - case "$G_WHIP_RETURNED_VALUE" in + case "$G_WHIP_RETURNED_VALUE" in - 'none') Reset_Overclocking;; + 'none') Reset_Overclocking;; - 'safe') + 'safe') + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=1' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1500' /boot/config.txt + ;; - Reset_Overclocking - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1450' /boot/config.txt + 'low') + Warning_Overclocking || return + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=3' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=400' /boot/config.txt + ;; - ;; + 'med') + Warning_Overclocking || return + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=450' /boot/config.txt + ;; - 'low') + 'high') + Warning_Overclocking || return + Reset_Overclocking + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + ;; - Warning_Overclocking || return - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=3' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=400' /boot/config.txt + esac - ;; + # RPi 400 + elif [[ $G_HW_MODEL == 4 && $G_HW_MODEL_NAME == *'400'* ]]; then - 'med') + G_WHIP_MENU_ARRAY=( - Warning_Overclocking || return - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1325' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=400' /boot/config.txt + 'energy saving' ': 1800 MHz ARM | 500 MHz core | -2 overvolt' + 'default' ': 1800 MHz ARM | 500 MHz core | 0 overvolt' + 'high GPU' ': 1900 MHz ARM | 600 MHz core | 5 overvolt' + 'high ARM' ': 2000 MHz ARM | 500 MHz core | 5 overvolt' - ;; + ) - 'high') + G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $over_voltage_value overvolt" || return 0 - Warning_Overclocking || return - Reset_Overclocking - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1350' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=400' /boot/config.txt + TARGETMENUID=13 # Return to this menu + Reset_Overclocking - ;; + case "$G_WHIP_RETURNED_VALUE" in - esac + 'energy saving') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt + G_CONFIG_INJECT 'over_voltage_min=' 'over_voltage_min=-2' /boot/config.txt + ;; - fi + 'high GPU') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1900' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=600' /boot/config.txt + ;; + + 'high ARM') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=2000' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + ;; + + esac # RPi 4 elif (( $G_HW_MODEL == 4 )); then @@ -3614,67 +3680,54 @@ Additional benchmarks: 'energy saving' ': 1500 MHz ARM | 500 MHz core | -2 overvolt' 'default' ': 1500 MHz ARM | 500 MHz core | 0 overvolt' 'safe' ': 1600 MHz ARM | 500 MHz core | 0 overvolt' - 'medium GPU' ': 1600 MHz ARM | 600 MHz core | 2 overvolt' - 'medium ARM' ': 1750 MHz ARM | 500 MHz core | 2 overvolt' - 'high GPU' ': 1750 MHz ARM | 600 MHz core | 4 overvolt' - 'high ARM' ': 1900 MHz ARM | 500 MHz core | 4 overvolt' + 'medium GPU' ': 1700 MHz ARM | 600 MHz core | 2 overvolt' + 'medium ARM' ': 1800 MHz ARM | 500 MHz core | 2 overvolt' + 'high GPU' ': 1800 MHz ARM | 700 MHz core | 4 overvolt' + 'high ARM' ': 1900 MHz ARM | 600 MHz core | 4 overvolt' ) - if G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $over_voltage_value overvolt"; then - - TARGETMENUID=13 # Return to this menu - Reset_Overclocking - - case "$G_WHIP_RETURNED_VALUE" in - - 'energy saving') - - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt - - ;; - - 'safe') - - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1600' /boot/config.txt - - ;; - - 'medium GPU') - - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1600' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=600' /boot/config.txt + G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $over_voltage_value overvolt" || return 0 - ;; + TARGETMENUID=13 # Return to this menu + Reset_Overclocking - 'medium ARM') - - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1750' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt - - ;; - - 'high GPU') + case "$G_WHIP_RETURNED_VALUE" in - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1750' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=600' /boot/config.txt + 'energy saving') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt + G_CONFIG_INJECT 'over_voltage_min=' 'over_voltage_min=-2' /boot/config.txt + ;; - ;; + 'safe') + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1600' /boot/config.txt + ;; - 'high ARM') + 'medium GPU') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1700' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=600' /boot/config.txt + ;; - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1900' /boot/config.txt - G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + 'medium ARM') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1800' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt + ;; - ;; + 'high GPU') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1800' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=700' /boot/config.txt + ;; - esac + 'high ARM') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1900' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=600' /boot/config.txt + ;; - fi + esac fi diff --git a/dietpi/func/dietpi-obtain_hw_model b/dietpi/func/dietpi-obtain_hw_model index 8cc9008d17..2fbe334937 100644 --- a/dietpi/func/dietpi-obtain_hw_model +++ b/dietpi/func/dietpi-obtain_hw_model @@ -62,7 +62,7 @@ # G_HW_MODEL 11 Odroid XU3/XU4/MC1/HC1/HC2 # G_HW_MODEL 10 Odroid C1 # G_HW_MODEL 4 Raspberry Pi 4/400 - # G_HW_MODEL 3 Raspberry Pi 3/3+ + # G_HW_MODEL 3 Raspberry Pi 3/3+/Zero 2 # G_HW_MODEL 2 Raspberry Pi 2 # G_HW_MODEL 1 Raspberry Pi 1/Zero (512 MiB) # G_HW_MODEL 0 Raspberry Pi 1 (256 MiB) @@ -157,6 +157,7 @@ 0e) G_HW_MODEL_NAME='RPi 3 Model A+' G_HW_MODEL=3 G_HW_ONBOARD_WIFI=1;; 10) G_HW_MODEL_NAME='RPi CM 3+' G_HW_MODEL=3;; 11) G_HW_MODEL_NAME='RPi 4 Model B' G_HW_MODEL=4 G_HW_ONBOARD_WIFI=1;; + 12) G_HW_MODEL_NAME='RPi Zero 2 W' G_HW_MODEL=3 G_HW_ONBOARD_WIFI=1;; 13) G_HW_MODEL_NAME='RPi 400' G_HW_MODEL=4 G_HW_ONBOARD_WIFI=1;; 14) G_HW_MODEL_NAME='RPi CM 4' G_HW_MODEL=4;; esac diff --git a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash index 23ed486126..d15b580d2e 100755 --- a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash +++ b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash @@ -30,7 +30,7 @@ # If no manual overclock settings have been applied by user, apply safe overclocking values (RPi1) or update comments to show model-specific defaults: https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md grep -qE '^[[:blank:]]*(over_voltage|(arm|core|gpu|sdram)_freq)=' /boot/config.txt && return - # RPi Zero + # RPi Zero/Zero 2 W if [[ $G_HW_MODEL_NAME == *'Zero'* ]] then sed -i '/#over_voltage=/c\#over_voltage=0' /boot/config.txt From ccd4d32532814f645179b6de59ca61fd16082708 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 1 Nov 2021 01:06:26 +0100 Subject: [PATCH 60/82] v7.8 + DietPi-Drive_Manager | Do not apply rootdelay when moving user data, as rootwait is by default applied which means an infinite wait for the root device already --- dietpi/dietpi-drive_manager | 3 --- 1 file changed, 3 deletions(-) diff --git a/dietpi/dietpi-drive_manager b/dietpi/dietpi-drive_manager index 3849ddc5b2..815fa528bf 100644 --- a/dietpi/dietpi-drive_manager +++ b/dietpi/dietpi-drive_manager @@ -742,9 +742,6 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return local rootfstype_current=$(mawk '{for(i=1;i<=NF;i++) {print $i} }' /boot/cmdline.txt | grep -m1 '^rootfstype=') G_EXEC sed -i "s#$rootfstype_current#rootfstype=${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]}#g" /boot/cmdline.txt - # Add root delay - grep -qE '(^|[[:blank:]])rootdelay=' /boot/cmdline.txt || G_EXEC sed -i "s#rootfstype=${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]}#rootfstype=${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} rootdelay=10#" /boot/cmdline.txt - # C2/XU4/N2: /boot/boot.ini elif [[ $G_HW_MODEL == 1[125] ]]; then From 31441882550728d221eca3a3d6e8d71e0c4dc85f Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 1 Nov 2021 01:22:31 +0100 Subject: [PATCH 61/82] v7.8 + DietPi-Config | RPi 400: Align GPU core frequency for high overclocking profiles with those for Raspberry Pi 4 --- dietpi/dietpi-config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dietpi/dietpi-config b/dietpi/dietpi-config index 62d093a2b7..6f25dccf81 100644 --- a/dietpi/dietpi-config +++ b/dietpi/dietpi-config @@ -3641,8 +3641,8 @@ Additional benchmarks: 'energy saving' ': 1800 MHz ARM | 500 MHz core | -2 overvolt' 'default' ': 1800 MHz ARM | 500 MHz core | 0 overvolt' - 'high GPU' ': 1900 MHz ARM | 600 MHz core | 5 overvolt' - 'high ARM' ': 2000 MHz ARM | 500 MHz core | 5 overvolt' + 'high GPU' ': 1900 MHz ARM | 700 MHz core | 5 overvolt' + 'high ARM' ': 2000 MHz ARM | 600 MHz core | 5 overvolt' ) From fd40aad9c5f4612f12ed4701da9bbc9a459b9bc5 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 1 Nov 2021 01:26:54 +0100 Subject: [PATCH 62/82] v7.8 + DietPi-Patches | RPi 400: Inform user about fixed overclocking profiles --- .update/patches | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.update/patches b/.update/patches index 2eff6bc8a3..8bf553cb87 100644 --- a/.update/patches +++ b/.update/patches @@ -516,6 +516,12 @@ Patch_7_8() done /boot/dietpi/dietpi-software reinstall 154 fi + + # RPi 400: Inform user about fixed overclocking profiles + [[ $G_HW_MODEL == 4 && $G_HW_MODEL_NAME == *'400'* ]] && grep -qE '^[[:blank:]]*(arm|core)_freq=' /boot/config.txt && G_WHIP_MSG '[ INFO ] New overclocking profiles for Raspberry Pi 400 +\ndietpi-config falsely offered Raspberry Pi 4 overclocking profiles on Raspberry Pi 400. This has now been fixed and a new set of profiles dedicated for the Raspberry Pi 400 has been added. +\nYou may try them out via: "dietpi-config" > "Performance Options" > "Overclocking" +\nFeel free to share your own testing results and suggest changes or additional profiles with us via forum or GitHub.' } # v6.35 => v7 migration From 4abd962c02be4ddceb80386404824f734f88b9fc Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 1 Nov 2021 01:28:55 +0100 Subject: [PATCH 63/82] v7.8 + CHANGELOG | DietPi-Config: Resolved an issue where Raspberry Pi 4 overclocking profiles were offered on Raspberry Pi 400. A new set of profiles have now been added dedicated for the Raspberry Pi 400. --- CHANGELOG.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 827428546f..556d8960e9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -16,6 +16,7 @@ Changes: - DietPi-Software | Roon Server: Added support for the new .NET core based version, released on November 3rd, which is expected to have improved performance compared to the old Mono based version. To resolve an old issue with our Roon Server implementation (see below), a reinstall is done during the DietPi update, which pulls in the .NET core dependencies as well. But this will NOT update the Roon Server version to prevent issues with potentially required migration steps. After updating DietPi, use Roon's internal updater to benefit from the new version. Fixes: +- DietPi-Config | Resolved an issue where Raspberry Pi 4 overclocking profiles were offered on Raspberry Pi 400. A new set of profiles have now been added dedicated for the Raspberry Pi 400. - DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 - DietPi-Software | Logitech Media Server: Resolved an issue where the uninstall failed as the package postinst script tried to remove the service user before the service was stopped. - DietPi-Software | Roon Server: Resolved an issue where the internal updater purged all Roon Server data and configs, since the data directory was located within the install directory. Roon Server will now be installed to /opt/roonserver while the data directory remains at /mnt/dietpi_userdata/roonserver. This change will be applied via DietPi update as well, your data and configs will remain untouched. Many thanks to @JanKoudijs for reporting this issue and providing a solution: https://github.com/MichaIng/DietPi/pull/4897 From e941a90a24910d9164f404b9eb2c2d9ef4a2cb72 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 1 Nov 2021 01:50:14 +0100 Subject: [PATCH 64/82] v7.8 + DietPi-Software | RPi: Remove ineffective rootdelay (wait for X seconds) from cmdline if rootwait (wait indefinitely) is present already --- .update/patches | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.update/patches b/.update/patches index 8bf553cb87..d105dba373 100644 --- a/.update/patches +++ b/.update/patches @@ -522,6 +522,13 @@ Patch_7_8() \ndietpi-config falsely offered Raspberry Pi 4 overclocking profiles on Raspberry Pi 400. This has now been fixed and a new set of profiles dedicated for the Raspberry Pi 400 has been added. \nYou may try them out via: "dietpi-config" > "Performance Options" > "Overclocking" \nFeel free to share your own testing results and suggest changes or additional profiles with us via forum or GitHub.' + + # RPi: Remove ineffective rootdelay (wait for X seconds) from cmdline if rootwait (wait indefinitely) is present already + if (( $G_HW_MODEL < 10 )) && grep -Eq '(^|[[:blank:]])rootwait([[:blank:]]|$)' /boot/cmdline.txt && grep -Eq '(^|[[:blank:]])rootdelay=' /boot/cmdline.txt + then + G_DIETPI-NOTIFY 2 'Removing ineffective "rootdelay" argument from /boot/cmdline.txt' + G_EXEC sed -i -e 's/^rootdelay=[^[:blank:]]*[[:blank:]]*//g' -e 's/[[:blank:]]*[[:blank:]]rootdelay=[^[:blank:]]*//g' /boot/cmdline.txt + fi } # v6.35 => v7 migration From a7ca17091782f78ecf4f18c4905c9e5934672806 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 1 Nov 2021 19:11:10 +0100 Subject: [PATCH 65/82] v7.8 (#4917) + DietPi-Drive_Manager | Enforce filesystem type limit for moving the rootfs by only showing supported filesystem types in the format menu. The dedicated Btrfs warning/abortion is obsolete as the the target partition is reformatted. + DietPi-Drive_Manager | Allow moving the rootfs on Odroid C4, which works like on all other Odroids. + DietPi-Drive_Manager | Do not force the user to unmount the rootfs target manually, as this is done automatically when the partition is formatted. + DietPi-Drive_Manager | Check whether the filesystem is supported when moving DietPi user data. Enforce a filesystem type with native UNIX permissions and symlink support. NTFS with emulated features via ntfs-3g driver has been shown to not be reliable in this regards and a network drive is currently ruled out as the option isn't shown in the menu then. We may think about allowing user data on an NFS mount with verified that UNIX permissions and symlinks are both supported. Do the same filesystem type validation in dietpi-set_userdata, just in case it is called manually. + DietPi-Drive_Manager | Do not remove swap file when moving rootfs. If it is a swap file, it is likely intended to be kept and if it is currently located on the SD card, it makes much sense to move it to the external drive. The fstab entry points to a location relative to the root mount, so it stays valid. If it is a swap partition or zram drive, it is not touched by the rootfs transfer, can and will stay as it is. + DietPi-Drive_Manager | Do not create a temporary new fstab file but simply edit the one on the target filesystem after the transfer. If anything fails during transfer or edit, the error handler will abort and keep the kernel command line entry untouched. + DietPi-Drive_Manager | Only update the rootfstype kernel command line entry if it is present and also do this for Odroids. + DietPi-Drive_Manager | Only offer the rootfs transfer when /boot is a dedicated mount. If it is a single-partition image, it may not work as intended: The bootloader will still be loaded from but not updated on the original drive, and if is unplugged, on Odroids the bootloader will be missing on the target drive. This feature in only intended for cases where bootloader (and kernel/device tree/initramfs) is required or intended to remain where it is (usually the SD card) while only the root mount is wanted on an external drive. For single-partition images, the DietPi image should simply be flashed to the intended drive directly, or the whole drive cloned (including bootloader and partition table) to the target drive, the old one unplugged or formatted. We may add an additional feature in the future to do this transfer from a running DietPi system, including a newly formatted drive and flashing the bootloader (on non-RPi). We have code for this in dietpi-backup which checks and adjusts fstab and boot configurations in case they do not match the actual UUIDs/PARTUUIDs. + DietPi-Drive_Manager | When moving the root filesystem, assure that the expected boot/kernel command line config files are present, else we are not able to tell the kernel to mount the new rootfs. + DietPi-Drive_Manager | Show the ext4 reserved blocks option as well on unmounted drives. It can be obtained and changed perfectly fine if the drive isn't mounted. + DietPi-Drive_Manager | If the ext filesystem to be resized isn't currently mounted, do an "e2fsck -f", required at least once in a boot session + DietPi-Drive_Manager | If the mount target input is cancelled, cancel the mount itself as well, as this is most likely what users expect. When doing this after formatting a drive, mounting can be done afterwards from the menu. + DietPi-Drive_Manager | When resizing F2FS, for some reason R/O mounting the drive isn't sufficient, the error message is a bit misleading "Check FS only on RO mounted device". Hence unmount the drive before performing the resize and remount it afterwards. On F2FS as well as Btrfs if the required umount resp mount of the drive fails, do not exit the script but return the function to skip the resize, which then cannot succeed and would throw only more error prompts. + DietPi-Drive_Manager | Do not allow to move the rootfs to a drive which currently contains the DietPi user data, since it is formatted and user data would be lost. + DietPi-Drive_Manager | When transferring the rootfs, do not ask for a mount point after the drive has been formatted, as it is temporary only anyway. + DietPi-Backup | If the target filesystem is an NFS mount, check for UNIX permissions support, which depends on the filesystem at the NFS server + DietPi-Drive_Manager | Show the "Transfer RootFS" option as well if the drive is not currently formatted as it is reformatted anyway --- CHANGELOG.txt | 8 + dietpi/dietpi-backup | 26 +-- dietpi/dietpi-drive_manager | 298 ++++++++++++++++---------------- dietpi/func/dietpi-set_userdata | 78 ++++----- 4 files changed, 208 insertions(+), 202 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 556d8960e9..c8e6e62418 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -13,9 +13,17 @@ Changes: - Odroid N1 | Removed support: We don't have a single reported system, which makes sense as this model was never really released. Only a small number of developer samples are floating around, not worth to keep maintaining an image and dedicated code. If there is really an Odroid N1 DietPi system out there, it will be automatically migrated to the Generic Rockchip RK3399 device ID on DietPi update. - DietPi-Config | Overclocking profiles for most Raspberry Pi models have been updated to match the effective 100 MHz ARM/CPU frequency steps used by current firmware. Also an energy saving profile has been added to some models, which reduces minimum and maximum voltage a little, reducing energy consumption and heat emission a little on idle and on load. - DietPi-Config | The option to prefer IPv4 connections when IPv6 is enabled has been removed: This only worked for APT and wget, while e.g. cURL and ping were never affected by this setting, which meant an inconsistent behaviour. If one faces issues with IPv6 enabled, it should be simply disabled instead of preferring/forcing IPv4 only for specific tools. +- DietPi-Backup | When using an NFS mount as backup target, it is now verified that the NFS share supports UNIX permissions to prevent the creation of a broken system backup in the first place. +- DietPi-Drive_Manager | When transferring the DietPi user data to a different drive, it is now ckecked whether the target location is located within a supported filesystem type, one with native symlink and UNIX permission support. The same is done when using the CLI script /boot/dietpi/func/dietpi-set_userdata. +- DietPi-Drive_Manager | Transferring the root filesystem is now supported on Odroid C4/HC4 models. +- DietPi-Drive_Manager | When transferring the root filesystem, further checks are performed: There needs to be a dedicated boot partition (required on Raspberry Pi and default on our current Odroid images), as this is what the transfer steps expect and the only reason for moving only the root filesystem instead of cloning the whole drive or flashing the DietPi image to an external drive in the first place. The expected boot/kernel configuration files need to be present so that the kernel can be instructed to mount the new root filesystem. The DietPi user data must not currently be located at the target partition as it would be formatted and all data hence lost. +- DietPi-Drive_Manager | The option to transfer the root filesystem is now shown as well when the drive does not contain any filesystem. The process implies formatting with a supported filesystem anyway which makes any condition obsolete. Also it is not needed anymore to unmount the filesystem manually first, as this is done automatically before formatting. In the related format menu, only supported filesystems are listed, i.e. ext4 and additionally F2FS on Raspberry Pi. The input box to enter a custom mount point is omitted as it is only temporarily used anyway until the root filesystem transfer has finished. The swap file is not disabled anymore as it can be copied and reused as is on the new root filesystem without issues. +- DietPi-Drive_Manager | On ext4 filesystems, the reserved blocks percentage is now shown and can be changed as well if the drive is not currently mounted. - DietPi-Software | Roon Server: Added support for the new .NET core based version, released on November 3rd, which is expected to have improved performance compared to the old Mono based version. To resolve an old issue with our Roon Server implementation (see below), a reinstall is done during the DietPi update, which pulls in the .NET core dependencies as well. But this will NOT update the Roon Server version to prevent issues with potentially required migration steps. After updating DietPi, use Roon's internal updater to benefit from the new version. Fixes: +- DietPi-Drive_Manager | Resolved an issue where resizing F2FS filesystems failed when currently mounted. Contradicting the docs and error output, mounting the filesystem read-only is not sufficnet, but it needs to be unmounted instead, which is not done automatically before the resize and remounted afterwards. +- DietPi-Drive_Manager | Resolved an issue where resizing ext4 filesystems could have failed when not currently mounted. Especially if the drive is newly attached, a full fsck needs to be done once before it can be resized. This is now done automatically, allowing to resolve filesystem errors interactively, before resizing an offline ext4 filesystem. - DietPi-Config | Resolved an issue where Raspberry Pi 4 overclocking profiles were offered on Raspberry Pi 400. A new set of profiles have now been added dedicated for the Raspberry Pi 400. - DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 - DietPi-Software | Logitech Media Server: Resolved an issue where the uninstall failed as the package postinst script tried to remove the service user before the service was stopped. diff --git a/dietpi/dietpi-backup b/dietpi/dietpi-backup index ea26b1f643..cbe982f9fc 100644 --- a/dietpi/dietpi-backup +++ b/dietpi/dietpi-backup @@ -72,8 +72,8 @@ Check_Supported_Directory_Location(){ # Check location contains /mnt/ - if [[ $FP_TARGET == '/mnt/'* ]]; then - + if [[ $FP_TARGET == '/mnt/'* ]] + then # Check file system type. Create directory temporarily, if necessary. if [[ ! -d $FP_TARGET ]] then @@ -84,23 +84,25 @@ local fs_type=$(df -T "$FP_TARGET" | mawk 'NR==2 {print $2}') fi - for i in 'ext4' 'ext3' 'ext2' 'nfs' 'nfs4' 'btrfs' 'f2fs' 'xfs' 'zfs' - do - [[ $fs_type == "$i" ]] || continue + # Check for supported filesystem type + if [[ $fs_type =~ ^(ext[2-4]|(f2|btr|x|z)fs)$ ]] + then return 0 - done - - # Not supported - 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 or ZFS for symlink and POSIX permissions compatibilities." + 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 # Not inside /mnt 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" - fi return 1 diff --git a/dietpi/dietpi-drive_manager b/dietpi/dietpi-drive_manager index 815fa528bf..82c25c228a 100644 --- a/dietpi/dietpi-drive_manager +++ b/dietpi/dietpi-drive_manager @@ -47,6 +47,7 @@ FORMAT_FILESYSTEM_TYPE=0 # 0=ext4 1=ntfs 2=fat32 3=hfs+ 4=btrfs 5=f2fs 6=exfat 7=xfs FORMAT_COMPLETED=0 FORMAT_MODE=1 # 0=drive 1=partition + MOVE_ROOTFS=0 # Whether the formatted drive is used as rootfs # Drive data FP_USERDATA_CURRENT= @@ -416,37 +417,34 @@ $swap_mounts local source=$1 local target=$2 - G_WHIP_DEFAULT_ITEM=$target - if G_WHIP_INPUTBOX "Please enter the desired mount point.\n - Default and recommended = $target\n -NB: The path must start with /mnt/ and be unique. Spaces will be converted automatically to underscores (_)."; then - - if [[ $G_WHIP_RETURNED_VALUE == '/mnt/'* ]]; then - - # Replace spaces with underscores - target=${G_WHIP_RETURNED_VALUE//[[:space:]]/_} - - else - - G_WHIP_MSG "Invalid mount target location:\n - $G_WHIP_RETURNED_VALUE\n\nThe drive will now be mounted to:\n - $target" - - fi - + # If formatting is done to move the rootfs, continue with default mount point as it is temporary only anyway + if (( $MOVE_ROOTFS )) + then + G_WHIP_RETURNED_VALUE=$target + else + G_WHIP_DEFAULT_ITEM=$target + G_WHIP_INPUTBOX "Please enter the desired mount point.\n - Default and recommended = $target\n +NB: The path must start with /mnt/ and be unique. Spaces will be converted automatically to underscores (_)." || return 1 fi - if [[ -d $target ]]; then - - if [[ $(ls -A "$target") ]]; then + if [[ $G_WHIP_RETURNED_VALUE == '/mnt/'* ]] + then + # Replace spaces with underscores + target=${G_WHIP_RETURNED_VALUE//[[:space:]]/_} + else + G_WHIP_MSG "Invalid mount target location:\n - $G_WHIP_RETURNED_VALUE\n\nThe drive will now be mounted to:\n - $target" + fi + if [[ -d $target ]] + then + if [[ $(ls -A "$target") ]] + then G_WHIP_MSG "[FAILED]:\n\nThe mount target directory already exists, and, contains data:\n - $target\n\nPlease retry, using a unique mount target location." return 1 - else - G_WHIP_YESNO "[WARNING]:\n\nThe mount target directory already exists, however, it does not contain any files or data at this time:\n - $target\n Do you wish to ignore this warning, and, mount the drive regardless?" || return 1 - fi - fi # FS-specific mount options @@ -462,8 +460,8 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return getent group dietpi > /dev/null && options+=',gid=dietpi,fmask=0002,dmask=0002' fi - G_EXEC_NOHALT=1 G_EXEC mkdir -p "$target" || return 1 - G_EXEC_NOHALT=1 G_EXEC mount "$source" "$target" -o "$options" || return 1 + G_EXEC_NOEXIT=1 G_EXEC mkdir -p "$target" || return 1 + G_EXEC_NOEXIT=1 G_EXEC mount "$source" "$target" -o "$options" || return 1 MENU_DRIVE_TARGET=$target Init_Drives_and_Refresh @@ -494,20 +492,25 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return elif [[ ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} == ext[2-4] ]]; then + if (( ! ${aDRIVE_ISMOUNTED[$MENU_DRIVE_INDEX]} )) + then + G_DIETPI-NOTIFY 2 'Running full interactive fsck, required for unmounted ext filesystems to be resized...' + e2fsck -f "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" + fi G_EXEC_NOEXIT=1 G_EXEC resize2fs "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" elif [[ ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} == 'f2fs' ]]; then - (( ${aDRIVE_ISMOUNTED[$MENU_DRIVE_INDEX]} && ! ${aDRIVE_ISREADONLY_CURRENTLY[$MENU_DRIVE_INDEX]} )) && G_EXEC_NOEXIT=1 G_EXEC mount -o remount,ro "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}" + (( ${aDRIVE_ISMOUNTED[$MENU_DRIVE_INDEX]} )) && G_EXEC_NOEXIT=1 G_EXEC umount "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}" || return 1 G_EXEC_NOEXIT=1 G_EXEC resize.f2fs "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" - (( ${aDRIVE_ISMOUNTED[$MENU_DRIVE_INDEX]} && ! ${aDRIVE_ISREADONLY_CURRENTLY[$MENU_DRIVE_INDEX]} )) && G_EXEC_NOEXIT=1 G_EXEC mount -o remount,rw "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}" + (( ${aDRIVE_ISMOUNTED[$MENU_DRIVE_INDEX]} )) && G_EXEC_NOEXIT=1 G_EXEC mount "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}" elif [[ ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} == 'btrfs' ]]; then if (( ! ${aDRIVE_ISMOUNTED[$MENU_DRIVE_INDEX]} )) then - G_EXEC_NOEXIT=1 G_EXEC mkdir -p /tmp/temporary_f2fs_mountpoint - G_EXEC_NOEXIT=1 G_EXEC mount "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" /tmp/temporary_f2fs_mountpoint + G_EXEC_NOEXIT=1 G_EXEC mkdir -p /tmp/temporary_f2fs_mountpoint || return 1 + G_EXEC_NOEXIT=1 G_EXEC mount "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" /tmp/temporary_f2fs_mountpoint || return 1 fi G_EXEC_NOEXIT=1 G_EXEC btrfs filesystem resize max "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}" if (( ! ${aDRIVE_ISMOUNTED[$MENU_DRIVE_INDEX]} )) @@ -690,18 +693,6 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return # Install rsync G_AG_CHECK_INSTALL_PREREQ rsync - # Disable swap - /boot/dietpi/func/dietpi-set_swapfile 0 - - # Create new fstab - G_EXEC cp -a /etc/fstab /etc/fstab_new - # - Remove automatic entry for new UUID - G_EXEC sed -i "\@[[:blank:]]${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}[[:blank:]]@d" /etc/fstab_new - # - Replace old with new rootfs entry - local dev_entry="UUID=${aDRIVE_UUID[$MENU_DRIVE_INDEX]}" - (( $G_HW_MODEL < 10 )) && dev_entry="PARTUUID=${aDRIVE_PART_UUID[$MENU_DRIVE_INDEX]}" - G_EXEC sed -i "\@UUID=[^[:blank:]]*[[:blank:]]\+/[[:blank:]]@c$dev_entry / ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} noatime,lazytime,rw 0 1" /etc/fstab_new - # Mount rootfs to tmp mount point to allow rsync # - rsync "-x" option prevents copying mounts content, but it copies permissions of mount point dirs according to mount options instead of those of the dir on the parent fs. # - Since mount permissions might not be wanted for the underlying filesystem dir, we copy from a temporary mount point to assure that underlying rootfs content matches 100%. @@ -712,7 +703,6 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return if ! G_EXEC_NOEXIT=1 G_EXEC rsync -aHv --delete /tmp/tmp_rootfs/ "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}/"; then G_DIETPI-NOTIFY 1 'Rsync has failed, RootFS transfer has been aborted.' - rm /etc/fstab_new umount /tmp/tmp_rootfs rmdir /tmp/tmp_rootfs return 1 @@ -723,32 +713,31 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return rm -Rf "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}"/var/tmp/systemd-private-* rmdir "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}" - # Move new fstab in place - G_EXEC mv /etc/fstab_new "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}/etc/fstab" - - # Recreate swap - #/boot/dietpi/func/dietpi-set_swapfile 1 "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}/var/swap" - # - Manually update location - #G_CONFIG_INJECT 'AUTO_SETUP_SWAPFILE_LOCATION=' 'AUTO_SETUP_SWAPFILE_LOCATION=/var/swap' /boot/dietpi.txt - - # RPi: /boot/cmdline.txt - if (( $G_HW_MODEL < 10 )); then + # Update fstab + # - Remove automatic entry for target drive + G_EXEC sed -i "\@[[:blank:]]${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}[[:blank:]]@d" "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}/etc/fstab" + # - Replace old with new rootfs entry + local dev_entry="UUID=${aDRIVE_UUID[$MENU_DRIVE_INDEX]}" + (( $G_HW_MODEL < 10 )) && dev_entry="PARTUUID=${aDRIVE_PART_UUID[$MENU_DRIVE_INDEX]}" + G_EXEC sed -i "\@[[:blank:]]/[[:blank:]]@c$dev_entry / ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} noatime,lazytime,rw 0 1" "${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}/etc/fstab" - # Find current root= and replace + # Find and replace current root and rootfstype kernel command line entries + # - RPi: /boot/cmdline.txt + if (( $G_HW_MODEL < 10 )) + then local rootfs_current=$(mawk '{for(i=1;i<=NF;i++) if($i~/^root=/) {print $i;exit}}' /boot/cmdline.txt) G_EXEC sed -i "s#$rootfs_current#root=PARTUUID=${aDRIVE_PART_UUID[$MENU_DRIVE_INDEX]}#g" /boot/cmdline.txt - # Set FS type - local rootfstype_current=$(mawk '{for(i=1;i<=NF;i++) {print $i} }' /boot/cmdline.txt | grep -m1 '^rootfstype=') - G_EXEC sed -i "s#$rootfstype_current#rootfstype=${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]}#g" /boot/cmdline.txt - - # C2/XU4/N2: /boot/boot.ini - elif [[ $G_HW_MODEL == 1[125] ]]; then + local rootfstype_current=$(mawk '{for(i=1;i<=NF;i++) if($i~/^rootfstype=/) {print $i;exit}}' /boot/cmdline.txt) + [[ $rootfstype_current ]] && G_EXEC sed -i "s#$rootfstype_current#rootfstype=${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]}#g" /boot/cmdline.txt - # Find current root= to replace + # - Odroids: /boot/boot.ini + else local rootfs_current=$(mawk '-F[" ]' '{for(i=1;i<=NF;i++) if($i~/^root=/) {print $i;exit}}' /boot/boot.ini) G_EXEC sed -i "s#$rootfs_current#root=UUID=${aDRIVE_UUID[$MENU_DRIVE_INDEX]}#g" /boot/boot.ini + local rootfstype_current=$(mawk '-F[" ]' '{for(i=1;i<=NF;i++) if($i~/^rootfstype=/) {print $i;exit}}' /boot/boot.ini) + [[ $rootfstype_current ]] && G_EXEC sed -i "s#$rootfstype_current#rootfstype=${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]}#g" /boot/boot.ini fi systemctl daemon-reload @@ -1046,7 +1035,7 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return G_WHIP_MENU_ARRAY+=('' '●─ Benchmark Options ') G_WHIP_MENU_ARRAY+=('Benchmark' ': Test read and write speeds') - # Userdata location/swapfile + # User data location/swapfile if (( ! ${aDRIVE_ISNETWORKED[$MENU_DRIVE_INDEX]} )); then G_WHIP_MENU_ARRAY+=('' '●─ Userdata & Swap options ') @@ -1088,30 +1077,11 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return G_WHIP_MENU_ARRAY+=('' '●─ Advanced options ') # Read only? - local read_only_state='[ ]' - local read_only_state_text='Disabled' - if (( ${aDRIVE_ISREADONLY_CURRENTLY[$MENU_DRIVE_INDEX]} )); then - - read_only_state='[X]' - read_only_state_text='Enabled' - - fi + local read_only_state='[ ]' read_only_state_text='Disabled' + (( ${aDRIVE_ISREADONLY_CURRENTLY[$MENU_DRIVE_INDEX]} )) && read_only_state='[X]' read_only_state_text='Enabled' G_WHIP_MENU_ARRAY+=('Read Only' ": $read_only_state | Select to toggle RW/RO modes") whiptail_desc+="\nRead only: $read_only_state_text" - # Show reserved blocks percentage for ext4 drives behind capacity: - if [[ ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} == 'ext4' ]]; then - - local fp_tmp='.dumpe2fs_out_tmp' reserved_blocks_percent_current=0 - dumpe2fs -h "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" > $fp_tmp - local block_count=$(mawk '/^Block count:/{print $3;exit}' $fp_tmp) - local reserved_block_count=$(mawk '/^Reserved block count:/{print $4;exit}' $fp_tmp) - rm $fp_tmp - reserved_blocks_percent_current=$(printf '%0.2f' "$(($reserved_block_count*100000/$block_count+1))e-3") - G_WHIP_MENU_ARRAY+=('Reserved blocks' ": [$reserved_blocks_percent_current%] | Adjust percentage of reserved blocks on this drive") - - fi - fi fi @@ -1127,6 +1097,15 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return if ! (( ${aDRIVE_ISROM[$MENU_DRIVE_INDEX]} || ${aDRIVE_ISNETWORKED[$MENU_DRIVE_INDEX]} )); then + # Reserved blocks percentage on ext4 filesystems + if [[ ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} == 'ext4' ]] + then + local block_count reserved_block_count + read -r block_count reserved_block_count < <(dumpe2fs -h "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" 2> /dev/null | mawk '$0~/^(Block|Reserved block) count:/ {print $NF}' ORS=' ') + reserved_blocks_percent_current=$(printf '%0.2f' "$(($reserved_block_count*100000/$block_count+1))e-3") + G_WHIP_MENU_ARRAY+=('Reserved blocks' ": [$reserved_blocks_percent_current%] | Adjust percentage of reserved blocks on this filesystem") + fi + # fsck G_WHIP_MENU_ARRAY+=('Check & Repair' ': Check and optionally repair filesystem') @@ -1137,14 +1116,7 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return fi - # Transfer RootFS: Supported on RPi and Odroids C2/XU4/N2 - if [[ ${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]} != "$G_ROOTFS_DEV" && ( $G_HW_MODEL -le 9 || $G_HW_MODEL == 1[125] ) ]]; then - - G_WHIP_MENU_ARRAY+=('Transfer RootFS' ': Transfer RootFS to this drive') - - fi - - # Disable format for /boot /rootfs + # Format: Disabled for /boot and rootfs if [[ ${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]} != '/' && ${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]} != '/boot' ]]; then G_WHIP_MENU_ARRAY+=('Format' ': Select to see formatting options') @@ -1155,6 +1127,16 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return fi + if ! (( ${aDRIVE_ISROM[$MENU_DRIVE_INDEX]} || ${aDRIVE_ISNETWORKED[$MENU_DRIVE_INDEX]} )) + then + # Transfer RootFS: Supported on RPi and Odroids C2/XU4/N2/C4 if /boot is a dedicated mount + if [[ ${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]} != "$G_ROOTFS_DEV" && ( $G_HW_MODEL -le 9 || $G_HW_MODEL == 1[1256] ) ]] && findmnt -M /boot > /dev/null; then + + G_WHIP_MENU_ARRAY+=('Transfer RootFS' ': Transfer RootFS to this drive') + + fi + fi + # I/O scheduler local io_schedulers="/sys/block/${aDRIVE_SOURCE_DEVICE[$MENU_DRIVE_INDEX]}/queue/scheduler" if [[ -e $io_schedulers ]] @@ -1231,13 +1213,13 @@ Please choose another drive or format this one with another filesystem, e.g. ext elif (( $max < $min )); then - G_WHIP_MSG "[FAILED] Insufficent free space on ${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}, a minimum of 2GB is required ($current_freespace MiB available)." + G_WHIP_MSG "[FAILED] Insufficient free space on ${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]}, a minimum of 2GB is required ($current_freespace MiB available)." else G_WHIP_DEFAULT_ITEM=$swapfile_size if G_WHIP_INPUTBOX "Please input a new value for swap file size (MiB): -\nSwap file has a swapiness setting of 1, and, is used only to prevent out of memory errors. +\nSwap file has a swappiness setting of 1, and, is used only to prevent out of memory errors. \n - Recommended value = 1 (auto)\n - 0 = Disable swap file\n - 1 = Auto size swap file (2GB - RAM = size)\n - 2 - $max = Manual size"; then if G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" $min $max; then @@ -1279,28 +1261,36 @@ Please enter the desired percentage of reserved blocks, e.g. "0.05" for 0.05% or elif [[ $G_WHIP_RETURNED_VALUE == 'User data' ]]; then local fp_target_userdata_dir=${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]} - # Assign location if under RootFS + + # Store below /mnt when moved to rootfs [[ ${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]} == '/' ]] && fp_target_userdata_dir='/mnt' + # Always move to dedicated dietpi_userdata subdir fp_target_userdata_dir+='/dietpi_userdata' - if [[ $fp_target_userdata_dir != "$FP_USERDATA_CURRENT" ]]; then + # Do nothing when user data are located here already + [[ $fp_target_userdata_dir == "$FP_USERDATA_CURRENT" ]] && return 0 - if G_WHIP_YESNO "Your user data will be moved:\n - From: $FP_USERDATA_CURRENT\n - To: $fp_target_userdata_dir\n\nDo you wish to continue?"; then + # Check for supported filesystem type + if [[ ! ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} =~ ^(ext[2-4]|(f2|btr|x|z)fs)$ ]] + then + G_DIETPI-NOTIFY 1 "Filesystem type ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} is not supported for transferring DietPi user data" + G_WHIP_MSG "Filesystem type not supported:\n\n${aDRIVE_MOUNT_TARGET[$MENU_DRIVE_INDEX]} has a filesystem type of ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]}, which is not supported.\n\nThe filesystem type must be ext2/3/4, F2FS, Btrfs, XFS or ZFS for native symlink and UNIX permissions compatibilities.\n\nYou may format the partition with a supported filesystem type and retry." + return 1 + fi - (( $SERVICES_STOPPED )) || { /boot/dietpi/dietpi-services stop; SERVICES_STOPPED=1; } - export G_DIETPI_SERVICES_DISABLE=1 - /boot/dietpi/func/dietpi-set_userdata "$FP_USERDATA_CURRENT" "$fp_target_userdata_dir" && FP_USERDATA_CURRENT=$fp_target_userdata_dir - unset G_DIETPI_SERVICES_DISABLE - sleep 1 + # Ask for confirmation + G_WHIP_YESNO "Your user data will be moved:\n - From: $FP_USERDATA_CURRENT\n - To: $fp_target_userdata_dir\n\nDo you wish to continue?" || return 0 - fi - - fi + (( $SERVICES_STOPPED )) || { /boot/dietpi/dietpi-services stop; SERVICES_STOPPED=1; } + export G_DIETPI_SERVICES_DISABLE=1 + /boot/dietpi/func/dietpi-set_userdata "$FP_USERDATA_CURRENT" "$fp_target_userdata_dir" && FP_USERDATA_CURRENT=$fp_target_userdata_dir + unset -v G_DIETPI_SERVICES_DISABLE + sleep 1 elif [[ $G_WHIP_RETURNED_VALUE == 'Format' ]]; then - # Disallow if userdata is located on this drive! + # Disallow if user data is located on this drive! if (( $partition_contains_userdata )); then Notification 0 @@ -1323,41 +1313,44 @@ Please enter the desired percentage of reserved blocks, e.g. "0.05" for 0.05% or # Transfer RootFS elif [[ $G_WHIP_RETURNED_VALUE == 'Transfer RootFS' ]]; then - # Kernel lacks native BTRFS support (enabled as module): https://github.com/MichaIng/DietPi/issues/2909 - if [[ ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} == 'btrfs' ]]; then - - G_WHIP_MSG "[WARNING] Booting from ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} is not supported by this device.\n -We recommend \"ext4\" as filesystem type for the RootFS." - - # User must unmount partition before format - elif (( ${aDRIVE_ISMOUNTED[$MENU_DRIVE_INDEX]} )); then + # Check whether required kernel command line config file is present + if [[ $G_HW_MODEL -le 9 && ! -f '/boot/cmdline.txt' ]] + then + G_WHIP_MSG '[ INFO ] /boot/cmdline.txt not found +\nThe required /boot/cmdline.txt file to adjust the root filesystem entry for the kernel has not been found. +\nTransferring the root filesystem is not supported on your device. Aborting...' + return 1 - G_WHIP_MSG '[WARNING] Partition must be unmounted, before format and RootFS transfer can begin.\n\nPlease unmount the partition, then try again.' + elif [[ $G_HW_MODEL -gt 9 && ! -f '/boot/boot.ini' ]] + then + G_WHIP_MSG '[ INFO ] /boot/boot.ini not found +\nThe required /boot/boot.ini file to adjust the root filesystem entry for the kernel has not been found. +\nTransferring the root filesystem is not supported on your device. Aborting...' + return 1 + fi - else + (( $partition_contains_userdata )) && { Notification 0; return 1; } - if G_WHIP_YESNO 'This process will move the root filesystem data to another location. This may increase R/W performance when using a USB drive over SDcard, however, there are some limitations: -\n - The SD/eMMC card, which holds kernel and bootloader, is still required for the boot process. On RPi3, which supports full USB boot, instead it is recommended to flash the whole DietPi image to a USB drive and boot the system without SDcard. + G_WHIP_YESNO 'This process will move the root filesystem data to another location. This may increase R/W performance when using a USB drive over SDcard, however, there are some limitations: +\n - The SD/eMMC card, which holds kernel and bootloader, is still required for the boot process. On RPi 3 and RPi 4 models, which support full USB boot, instead it is recommended to flash the whole DietPi image to a USB drive and boot the system without SDcard. \n - Custom software installs might use info of the old root mount/filesystem, hence we recommend to move the root filesystem on fresh DietPi systems only. \n - An immediate reboot is done after the transfer has successfully finished to assure that fstab and cmdline cannot be reverted. -\nDo you wish to continue?'; then - - G_WHIP_MSG 'On the next screen, you will be asked to format the target partition. -\nPlease see the following recommendations for RootFS target filesystem type: -\n - Odroid: RootFS transfer supports ONLY EXT4 format\n\n - RPi: RootFS transfer supports EXT4, BTRFS and F2FS' +\nDo you wish to continue?' || return 0 - # NB: We dont enter main loop in this func - TARGETMENUID=2 # Format menu - while (( $TARGETMENUID == 2 )) - do - Menu_Format - done + G_WHIP_MSG 'On the next screen, you will be asked to format the target partition. +\nPlease see the following limitations for the RootFS target filesystem type: +\n - Odroid: ONLY ext4 is supported\n\n - Raspberry Pi: ext4 and F2FS are supported' - (( $FORMAT_COMPLETED )) && RootFS_Move - - fi + # NB: We don't enter main loop in this func + TARGETMENUID=2 # Format menu + MOVE_ROOTFS=1 + while (( $TARGETMENUID == 2 )) + do + Menu_Format + done + MOVE_ROOTFS=0 - fi + (( $FORMAT_COMPLETED )) && RootFS_Move elif [[ $G_WHIP_RETURNED_VALUE == 'Read Only' ]]; then @@ -1581,10 +1574,10 @@ Read more about I/O scheduling: https://wiki.archlinux.org/index.php/Improving_p G_WHIP_MENU_ARRAY=() - # Has partition table, offer to format single partition or whole drive + # Has partition table, offer to format current partition or whole drive if (( ${aDRIVE_ISPARTITIONTABLE[$MENU_DRIVE_INDEX]} )); then - G_WHIP_MENU_ARRAY+=('Format Mode' ": [$format_mode_text]") + G_WHIP_MENU_ARRAY+=('Format Mode' ": [$format_mode_text] Format the whole drive or current partition only") # No partition table, force drive wipe else @@ -1593,8 +1586,8 @@ Read more about I/O scheduling: https://wiki.archlinux.org/index.php/Improving_p fi - (( $FORMAT_MODE )) || G_WHIP_MENU_ARRAY+=('Partition Type' ": [$partition_table_text]") - G_WHIP_MENU_ARRAY+=('Filesystem Type' ": [$format_type_text]") + (( $FORMAT_MODE )) || G_WHIP_MENU_ARRAY+=('Partition Table' ": [$partition_table_text] Format with MBR or GPT partition table") + G_WHIP_MENU_ARRAY+=('Filesystem Type' ": [$format_type_text] Select the new filesystem type") G_WHIP_MENU_ARRAY+=('Format' ': Start the format process with selected options') G_WHIP_DEFAULT_ITEM=$MENU_LASTITEM @@ -1603,7 +1596,7 @@ Read more about I/O scheduling: https://wiki.archlinux.org/index.php/Improving_p MENU_LASTITEM=$G_WHIP_RETURNED_VALUE - if [[ $G_WHIP_RETURNED_VALUE == 'Partition Type' ]]; then + if [[ $G_WHIP_RETURNED_VALUE == 'Partition Table' ]]; then G_WHIP_BUTTON_OK_TEXT='MBR' G_WHIP_BUTTON_CANCEL_TEXT='GPT' G_WHIP_YESNO 'Would you like to use GPT or MBR parition table?\n - GPT is required for 2TB+ drives\n - MBR does NOT support 2TB+ drives\n\nIf unsure, select GPT (default)' && FORMAT_GPT=0 || FORMAT_GPT=1 @@ -1617,7 +1610,7 @@ Read more about I/O scheduling: https://wiki.archlinux.org/index.php/Improving_p ) - if G_WHIP_MENU 'Please select a formatting mode:\n\n - Formatting the drive will DELETE all data on the DRIVE.\n - Formatting the partition, will DELETE all data on the current PARTITION only.\n + if G_WHIP_MENU 'Please select a formatting mode:\n\n - Formatting the drive will DELETE all data on the DRIVE and create a new partition table.\n - Formatting the partition, will DELETE all data on the current PARTITION only.\n NB: If you are planning to dedicate the drive to this system, it is recommended to format the whole drive where possible, this will ensure full drive capacity is available for use.'; then [[ $G_WHIP_RETURNED_VALUE == 'Partition' ]] && FORMAT_MODE=1 || FORMAT_MODE=0 @@ -1626,18 +1619,27 @@ NB: If you are planning to dedicate the drive to this system, it is recommended elif [[ $G_WHIP_RETURNED_VALUE == 'Filesystem Type' ]]; then - G_WHIP_MENU_ARRAY=( - - '0' ': ext4 | Default (Recommended)' - '1' ': NTFS | Windows (High CPU usage)' - '2' ': FAT32 | All OS (4GB filesize limit)' - '3' ': HFS+ | macOS (Apple default filesystem)' - '4' ': Btrfs | Linux (Modern filesystem)' - '5' ': F2FS | Linux (Flash filesystem)' - '6' ': exFAT | Windows (Flash filesystem)' - '7' ': XFS | Linux (Modern filesystem)' - - ) + # Limit available filesystem types when this is used to move the root filesystem to + if (( $MOVE_ROOTFS )) + then + # Odroids only support ext4 + G_WHIP_MENU_ARRAY=('0' ': ext4 | Default (Recommended)') + # RPis additionally support F2FS + (( $G_HW_MODEL > 9 )) || G_WHIP_MENU_ARRAY+=('5' ': F2FS | Linux (Flash filesystem)') + else + G_WHIP_MENU_ARRAY=( + + '0' ': ext4 | Default (Recommended)' + '1' ': NTFS | Windows (High CPU usage)' + '2' ': FAT32 | All OS (4GB filesize limit)' + '3' ': HFS+ | macOS (Apple default filesystem)' + '4' ': Btrfs | Linux (Modern filesystem)' + '5' ': F2FS | Linux (Flash filesystem)' + '6' ': exFAT | Windows (Flash filesystem)' + '7' ': XFS | Linux (Modern filesystem)' + + ) + fi G_WHIP_DEFAULT_ITEM=$FORMAT_FILESYSTEM_TYPE if G_WHIP_MENU 'Please select a filesystem type for this format: diff --git a/dietpi/func/dietpi-set_userdata b/dietpi/func/dietpi-set_userdata index 5cbbd8c106..bdd71be56a 100644 --- a/dietpi/func/dietpi-set_userdata +++ b/dietpi/func/dietpi-set_userdata @@ -13,7 +13,7 @@ # - Allows automated moving of user data in DietPi. Automatically generates a symlink from /mnt/dietpi_userdata to target directory if needed. # # Usage: - # - /boot/dietpi/func/dietpi-set_userdata SOURCE_DIRECTORY TARGET_DIRECTORY | Setup user data directory, move data if needed. If TARGET_DIRECTORY='auto', auto target location. Returns 1 if failed. + # - /boot/dietpi/func/dietpi-set_userdata FP_SOURCE FP_TARGET | Setup user data directory, move data if needed. If FP_TARGET='auto', auto target location. Returns 1 if failed. #//////////////////////////////////// # Import DietPi-Globals -------------------------------------------------------------- @@ -27,11 +27,12 @@ # Grab input # - Remove trailing slashes - SOURCE_DIRECTORY=${1%/} - TARGET_DIRECTORY=${2%/} + FP_SOURCE=${1%/} + FP_TARGET=${2%/} readonly FP_LOG='/var/log/dietpi-move_userdata.log' LOGFILE_OUTPUT_TEXT= + TARGET_FS_TYPE= FREESPACE_REQUIRED_SOURCE=0 Run_Move_Data(){ @@ -39,30 +40,30 @@ # Stop all running services /boot/dietpi/dietpi-services stop - G_DIETPI-NOTIFY 2 "Moving your existing data from $SOURCE_DIRECTORY to $TARGET_DIRECTORY, please wait..." + G_DIETPI-NOTIFY 2 "Moving your existing data from $FP_SOURCE to $FP_TARGET, please wait..." # Begin transfer - if cp -a "$SOURCE_DIRECTORY/." "$TARGET_DIRECTORY/"; then + if cp -a "$FP_SOURCE/." "$FP_TARGET/"; then # Remove source - rm -R "$SOURCE_DIRECTORY" + rm -R "$FP_SOURCE" # Create symlink at /mnt/dietpi_userdata if required - if [[ $TARGET_DIRECTORY != '/mnt/dietpi_userdata' ]]; then + if [[ $FP_TARGET != '/mnt/dietpi_userdata' ]]; then rm -Rf /mnt/dietpi_userdata - ln -s "$TARGET_DIRECTORY" /mnt/dietpi_userdata + ln -s "$FP_TARGET" /mnt/dietpi_userdata fi # Apply dietpi:dietpi owner, used by some software titles like Syncthing and file servers to permit creating files and directories - chown dietpi:dietpi "$TARGET_DIRECTORY" + chown dietpi:dietpi "$FP_TARGET" - LOGFILE_OUTPUT_TEXT="Successfully moved your data from $SOURCE_DIRECTORY to $TARGET_DIRECTORY." + LOGFILE_OUTPUT_TEXT="Successfully moved your data from $FP_SOURCE to $FP_TARGET." else - LOGFILE_OUTPUT_TEXT="Failed to copy $SOURCE_DIRECTORY/ to $TARGET_DIRECTORY." + LOGFILE_OUTPUT_TEXT="Failed to copy $FP_SOURCE/ to $FP_TARGET." EXIT_CODE=1 fi @@ -77,74 +78,67 @@ #///////////////////////////////////////////////////////////////////////////////////// G_DIETPI-NOTIFY 3 'DietPi Updating user data location' - G_DIETPI-NOTIFY 2 " - From : $SOURCE_DIRECTORY" - G_DIETPI-NOTIFY 2 " - To : $TARGET_DIRECTORY" + G_DIETPI-NOTIFY 2 " - From : $FP_SOURCE" + G_DIETPI-NOTIFY 2 " - To : $FP_TARGET" G_DIETPI-NOTIFY 2 'Please wait...' # Sanity checks # - Check for both inputs - if ! [[ $SOURCE_DIRECTORY && $TARGET_DIRECTORY ]]; then + if ! [[ $FP_SOURCE && $FP_TARGET ]]; then - LOGFILE_OUTPUT_TEXT="Please provide a source ($SOURCE_DIRECTORY) and target ($TARGET_DIRECTORY) directory for input." + LOGFILE_OUTPUT_TEXT="Please provide a source ($FP_SOURCE) and target ($FP_TARGET) directory for input." EXIT_CODE=1 # - Check if symlink is already pointing to target directory - elif [[ $(readlink -f /mnt/dietpi_userdata) == "$TARGET_DIRECTORY" ]]; then + elif [[ $(readlink -f /mnt/dietpi_userdata) == "$FP_TARGET" ]]; then - LOGFILE_OUTPUT_TEXT="/mnt/dietpi_userdata has already been moved to $TARGET_DIRECTORY, nothing to do." + LOGFILE_OUTPUT_TEXT="/mnt/dietpi_userdata has already been moved to $FP_TARGET, nothing to do." # - Check if source directory exists - elif [[ ! -d $SOURCE_DIRECTORY ]]; then + elif [[ ! -d $FP_SOURCE ]]; then - LOGFILE_OUTPUT_TEXT="Source directory $SOURCE_DIRECTORY does not exist." + LOGFILE_OUTPUT_TEXT="Source directory $FP_SOURCE does not exist." EXIT_CODE=1 # - Check for disallowed directory match - elif [[ $SOURCE_DIRECTORY == "$TARGET_DIRECTORY" || $SOURCE_DIRECTORY == "$TARGET_DIRECTORY/"* || $TARGET_DIRECTORY == "$SOURCE_DIRECTORY/"* ]]; then + elif [[ $FP_SOURCE == "$FP_TARGET" || $FP_SOURCE == "$FP_TARGET/"* || $FP_TARGET == "$FP_SOURCE/"* ]]; then - LOGFILE_OUTPUT_TEXT="$SOURCE_DIRECTORY and $TARGET_DIRECTORY cannot be within each other. Disallowed directory match." + LOGFILE_OUTPUT_TEXT="$FP_SOURCE and $FP_TARGET cannot be within each other. Disallowed directory match." EXIT_CODE=1 - # - Only allow full filepaths - elif [[ $SOURCE_DIRECTORY != '/'* || $TARGET_DIRECTORY != '/'* ]]; then + # - Only allow full path + elif [[ $FP_SOURCE != '/'* || $FP_TARGET != '/'* ]]; then - LOGFILE_OUTPUT_TEXT="Source ($SOURCE_DIRECTORY) and target directories ($TARGET_DIRECTORY) must be given with absolute path, e.g.: /mnt/drive1" + LOGFILE_OUTPUT_TEXT="Source ($FP_SOURCE) and target directories ($FP_TARGET) must be given with absolute path, e.g.: /mnt/drive1" EXIT_CODE=1 else - # Remove /mnt/dietpi_userdata symlink, if chosen as target - [[ $TARGET_DIRECTORY == '/mnt/dietpi_userdata' && -L '/mnt/dietpi_userdata' ]] && rm /mnt/dietpi_userdata + [[ $FP_TARGET == '/mnt/dietpi_userdata' && -L '/mnt/dietpi_userdata' ]] && G_EXEC rm /mnt/dietpi_userdata # Create target directory - mkdir -p "$TARGET_DIRECTORY" - - # Ensure target directory supports POSIX permissions - if ! G_CHECK_FS_PERMISSION_SUPPORT "$TARGET_DIRECTORY"; then + G_EXEC mkdir -p "$FP_TARGET" - LOGFILE_OUTPUT_TEXT="$TARGET_DIRECTORY does not support POSIX permissions. Transfer aborted." + # Check for supported filesystem type + TARGET_FS_TYPE=$(df -T "$FP_TARGET" | mawk 'NR==2 {print $2}') + if [[ ! $TARGET_FS_TYPE =~ ^(ext[2-4]|(f2|btr|x|z)fs)$ ]] + then + LOGFILE_OUTPUT_TEXT="Filesystem type $TARGET_FS_TYPE of $FP_TARGET is not supported for transferring DietPi user data. Transfer aborted.\n - The filesystem type must be ext2/3/4, F2FS, Btrfs, XFS or ZFS for native symlink and UNIX permissions compatibilities." EXIT_CODE=1 - else - # Check for sufficient free space in target directory # - "-m" => result in MiB actual disk usage, respecting disk block size, e.g. "144" # - Trailing slash required with "du" to correctly check symlink target in case - FREESPACE_REQUIRED_SOURCE=$(du -sm "$SOURCE_DIRECTORY/" | mawk '{print $1}') - if ! G_CHECK_FREESPACE "$TARGET_DIRECTORY" "$FREESPACE_REQUIRED_SOURCE"; then - - LOGFILE_OUTPUT_TEXT="Not enough free space in target directory $TARGET_DIRECTORY.\n - Required: $FREESPACE_REQUIRED_SOURCE MiB" + FREESPACE_REQUIRED_SOURCE=$(du -sm "$FP_SOURCE/" | mawk '{print $1}') + if ! G_CHECK_FREESPACE "$FP_TARGET" "$FREESPACE_REQUIRED_SOURCE" + then + LOGFILE_OUTPUT_TEXT="Not enough free space in target directory $FP_TARGET.\n - Required: $FREESPACE_REQUIRED_SOURCE MiB" EXIT_CODE=1 - else - # Run, attempt to move data. Run_Move_Data - fi - fi - fi #----------------------------------------------------------------------------------- From f985918fed5c5f953be502c5d83733e43d4ab53e Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 1 Nov 2021 19:49:50 +0100 Subject: [PATCH 66/82] v7.8 + DietPi-Software | Remove the block to disable the serial console on specific devices. But check whether the current terminal is a serial console and add an additional notice why it is recommended to keep it enabled when a screen and keyboard are difficult or impossible to attach. --- dietpi/dietpi-software | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 19a16db74d..12cdec590c 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -16617,18 +16617,17 @@ This requires an account at: https://remote.it/ fi - # Disable serial? Must stay enabled for the following: - # - XU4: HC1/HC2 fail to boot into kernel without: https://github.com/MichaIng/DietPi/issues/2038#issuecomment-416089875 - # - ROCKPro64: Fails to boot into kernel without - # - NanoPi NEO Air: Required for end users/debugging/setting up WiFi without automation + # Disable serial console? local keep_serial0=1 if grep -q '^[[:blank:]]*CONFIG_SERIAL_CONSOLE_ENABLE=1' /boot/dietpi.txt && - (( $G_HW_MODEL != 11 && $G_HW_MODEL != 42 && $G_HW_MODEL != 64 )) && - G_WHIP_YESNO 'Serial console is currently enabled, would you like to disable it?\n - Disabling serial console will reduce memory consumption slightly\n - If you are unsure on what serial console is, it is safe to disable it'; then - + [[ ! $(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. + - 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 From 71eb43094e09defa12481aa06ee4db16130a2cc2 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Mon, 1 Nov 2021 22:48:12 +0100 Subject: [PATCH 67/82] v7.8 + DietPi-Config | Add overclocking profiles for Raspberry Pi Zero, freshly tested and stress test proven. More is unlikely to be achievable, especially since on Raspberry Pi Zero the over_voltage cannot be raised as the absolute limit of 1.4V is the default with over_voltage=0 already. + DietPi-Config | Adjust Raspberry Pi 2 overclocking profiles according to the fact that over_voltage=2 is the maximum due to the 1.4V cap. The same should be true on Raspberry Pi 3 and Zero 2, but this should be tested, including the over_voltage required for the individual profiles. + DietPi-Config | Do not show a dedicated overclocking warning on every higher profile selection. Instead of a warning once when entering the overclocking menu. Also make clear that all profiles won't void the warranty and are practically assured to not cause hardware damage due to automatic throttling and capping in case of thermal or voltage issues. To void the warranty, force_turbo=1 would need to be set. --- dietpi/dietpi-config | 127 ++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 86 deletions(-) diff --git a/dietpi/dietpi-config b/dietpi/dietpi-config index 6f25dccf81..122d7d1099 100644 --- a/dietpi/dietpi-config +++ b/dietpi/dietpi-config @@ -1524,9 +1524,13 @@ Further information: https://www.raspberrypi.org/documentation/hardware/raspberr local temp_limit=$(sed -n '/^[[:blank:]]*temp_limit=/{s/^[^=]*=//p;q}' /boot/config.txt) G_WHIP_MENU_ARRAY+=('ARM Temp Limit' ": [${temp_limit:=85}'c]") - local arm_freq_min=$(sed -n '/^[[:blank:]]*arm_freq_min=/{s/^[^=]*=//p;q}' /boot/config.txt) - [[ $arm_freq_min ]] || { [[ $G_HW_MODEL == [01] ]] && arm_freq_min=700 || arm_freq_min=600; } # 700 on RPi1+Zero else 600 - G_WHIP_MENU_ARRAY+=('ARM Idle Frequency' ": [$arm_freq_min MHz]") # https://github.com/MichaIng/DietPi/issues/3690 + # RPi 4 only + if (( $G_HW_MODEL == 4 )) + then + local arm_freq_min=$(sed -n '/^[[:blank:]]*arm_freq_min=/{s/^[^=]*=//p;q}' /boot/config.txt) + [[ $arm_freq_min ]] || arm_freq_min=600 # 700 on RPi1+Zero else 600 + G_WHIP_MENU_ARRAY+=('ARM Idle Frequency' ": [$arm_freq_min MHz]") # https://github.com/MichaIng/DietPi/issues/3690 + fi local initial_turbo=$(sed -n '/^[[:blank:]]*initial_turbo=/{s/^[^=]*=//p;q}' /boot/config.txt) G_WHIP_MENU_ARRAY+=('ARM Initial Turbo' ": [${initial_turbo:=0} seconds]") @@ -1680,6 +1684,13 @@ Current setting: $user_frequency_min_text" && G_CONFIG_INJECT 'CONFIG_CPU_MIN_FR 'Overclocking') + G_WHIP_MSG '[WARNING] Overclocking can make your device unbootable! +\nThe overclocking profiles offered by DietPi have been proven to run stable at a large number of individual Raspberry Pis and they do not void your warranty. +\nHowever, every chip is different, some can be overclocked more, others less and some require a higher voltage to maintain a certain clock rate than others. +\nIt is hence unlikely but possible that your Raspberry Pi will not boot up when applying an overclocking profile. +\nYou then need to manually reduce frequencies or raise voltage a little by editing the config.txt file on the systems FAT partition, which can be mounted also on Windows and macOS. +\nWe recommend to not raise the over_voltage above 6, to maintain warranty and prevent the possibility of any hardware damage. +\nIn any case, DietPi will not be held responsable for any damages due to overclocking.' TARGETMENUID=13 ;; @@ -1773,7 +1784,7 @@ Current setting: $user_frequency_min_text" && G_CONFIG_INJECT 'CONFIG_CPU_MIN_FR if G_WHIP_INPUTBOX "When the ARM temperature ('c) reaches this value, the ARM will underclock to reduce heat. - Recommended value: 65\n - Valid range: $MIN_VALUE - $MAX_VALUE" && G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" $MIN_VALUE $MAX_VALUE; then - (( $G_WHIP_RETURNED_VALUE > 65 )) && G_WHIP_MSG "Higher operating temperatures will reduce the life of your ARM SoC. Heat also dissipates through the PCB into other components, decreasing the lifespan of the whole device. Use at your own risk.\n\nDietPi recommends 65'c as a safe value (75'c for RPi 3/4).\n\nMore info: https://github.com/MichaIng/DietPi/issues/356" + (( $G_WHIP_RETURNED_VALUE > 75 )) && G_WHIP_MSG "Higher operating temperatures will reduce the life of your ARM SoC. Heat also dissipates through the PCB into other components, decreasing the lifespan of the whole device. Use at your own risk.\n\nDietPi recommends 65'c as a safe value (75'c for RPi 3/4).\n\nMore info: https://github.com/MichaIng/DietPi/issues/356" G_CONFIG_INJECT 'temp_limit=' "temp_limit=$G_WHIP_RETURNED_VALUE" /boot/config.txt && REBOOT_REQUIRED=1 fi @@ -1782,8 +1793,7 @@ Current setting: $user_frequency_min_text" && G_CONFIG_INJECT 'CONFIG_CPU_MIN_FR 'ARM Idle Frequency') - MIN_VALUE=100 - [[ $G_HW_MODEL == [01] ]] && DEF_VALUE=700 || DEF_VALUE=600 + MIN_VALUE=100 DEF_VALUE=600 G_WHIP_DEFAULT_ITEM=$arm_freq_min if G_WHIP_INPUTBOX "ARM frequency (MHz) used by CPU governors powersave and schedutil/ondemand/conservative when on idle. - Current value: $arm_freq_min\n - Recommended value: 300\n - Minimum value: $MIN_VALUE @@ -3396,12 +3406,6 @@ Additional benchmarks: } - Warning_Overclocking(){ - - G_WHIP_YESNO 'The selected overclocking choice may void the warranty on this device. Do you wish to continue?\n\nUse of this tool is at your own risk. DietPi will not be held responsable for any damages due to overclocking.\n\nAlthough DietPi overclocks are tested for stability, results are not guaranteed and may differ from device.' - - } - # TARGETMENUID=13 Menu_Overclock(){ @@ -3416,126 +3420,110 @@ Additional benchmarks: # RPi Zero if [[ $G_HW_MODEL == 1 && $G_HW_MODEL_NAME == *'Zero'* ]]; then - G_WHIP_MENU_ARRAY=('none' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt') + G_WHIP_MENU_ARRAY=( + 'energy saving' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | -2 overvolt' + 'default' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt' + 'high' ': 1100 MHz ARM | 450 MHz core | 450 MHz SDRAM | 0 overvolt' + ) G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 TARGETMENUID=13 # Return to this menu + Reset_Overclocking case "$G_WHIP_RETURNED_VALUE" in - 'none') Reset_Overclocking;; - + 'energy saving') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt + ;; + 'high') + G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1100' /boot/config.txt + G_CONFIG_INJECT 'core_freq=' 'core_freq=450' /boot/config.txt + ;; esac # RPi 1 elif (( $G_HW_MODEL < 2 )); then G_WHIP_MENU_ARRAY=( - - 'none' ': 700 MHz ARM | 250 MHz core | 400 MHz SDRAM | 0 overvolt' + 'default' ': 700 MHz ARM | 250 MHz core | 400 MHz SDRAM | 0 overvolt' 'safe' ': 900 MHz ARM | 250 MHz core | 400 MHz SDRAM | 2 overvolt' 'high' ': 900 MHz ARM | 500 MHz core | 400 MHz SDRAM | 4 overvolt' 'extreme' ': 1000 MHz ARM | 500 MHz core | 400 MHz SDRAM | 6 overvolt' - ) G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 TARGETMENUID=13 # Return to this menu + Reset_Overclocking case "$G_WHIP_RETURNED_VALUE" in - 'none') Reset_Overclocking;; - 'safe') - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=900' /boot/config.txt ;; - 'high') - Warning_Overclocking || return - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=900' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt ;; - 'extreme') - Warning_Overclocking || return - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=6' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt ;; - esac # RPi 2 elif (( $G_HW_MODEL == 2 )); then G_WHIP_MENU_ARRAY=( - 'energy saving' ': 900 MHz ARM | 250 MHz core | 450 MHz SDRAM | -2 overvolt' - 'none' ': 900 MHz ARM | 250 MHz core | 450 MHz SDRAM | 0 overvolt' - 'low' ': 1000 MHz ARM | 450 MHz core | 450 MHz SDRAM | 2 overvolt' - 'med' ': 1000 MHz ARM | 500 MHz core | 450 MHz SDRAM | 3 overvolt' - 'extreme' ': 1000 MHz ARM | 500 MHz core | 500 MHz SDRAM | 4 overvolt' - + 'default' ': 900 MHz ARM | 250 MHz core | 450 MHz SDRAM | 0 overvolt' + 'low' ': 1000 MHz ARM | 450 MHz core | 450 MHz SDRAM | 1 overvolt' + 'med' ': 1000 MHz ARM | 500 MHz core | 450 MHz SDRAM | 2 overvolt' + 'extreme' ': 1000 MHz ARM | 500 MHz core | 500 MHz SDRAM | 2 overvolt' ) G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 TARGETMENUID=13 # Return to this menu + Reset_Overclocking case "$G_WHIP_RETURNED_VALUE" in 'energy saving') - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt G_CONFIG_INJECT 'over_voltage_min=' 'over_voltage_min=-2' /boot/config.txt ;; - - 'none') Reset_Overclocking;; - 'low') - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=450' /boot/config.txt ;; - 'med') - Warning_Overclocking || return - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=3' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt ;; - 'extreme') - Warning_Overclocking || return - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1000' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt G_CONFIG_INJECT 'sdram_freq=' 'sdram_freq=500' /boot/config.txt ;; - esac # RPi Zero 2 elif [[ $G_HW_MODEL == 3 && $G_HW_MODEL_NAME == *'Zero'* ]]; then G_WHIP_MENU_ARRAY=( - - 'energy saving' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | -2 overvolt' - 'none' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt' + 'energy saving' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | -2 overvolt' + 'default' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt' 'low' ': 1200 MHz ARM | 400 MHz core | 450 MHz SDRAM | 2 overvolt' 'med' ': 1200 MHz ARM | 450 MHz core | 450 MHz SDRAM | 3 overvolt' 'high' ': 1300 MHz ARM | 500 MHz core | 450 MHz SDRAM | 5 overvolt' - ) G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 @@ -3549,24 +3537,20 @@ Additional benchmarks: G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt G_CONFIG_INJECT 'over_voltage_min=' 'over_voltage_min=-2' /boot/config.txt ;; - 'low') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1200' /boot/config.txt ;; - 'med') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=3' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1200' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=450' /boot/config.txt ;; - 'high') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt ;; - esac # RPi 3/3+ @@ -3576,74 +3560,56 @@ Additional benchmarks: if [[ $G_HW_MODEL_NAME == *'+'* ]] then G_WHIP_MENU_ARRAY=( - - 'none' ': 1400 MHz ARM | 400 MHz core | 500 MHz SDRAM | 0 overvolt' + 'default' ': 1400 MHz ARM | 400 MHz core | 500 MHz SDRAM | 0 overvolt' 'safe' ': 1500 MHz ARM | 400 MHz core | 500 MHz SDRAM | 1 overvolt' - ) # RPi 3 else G_WHIP_MENU_ARRAY=( - - 'none' ': 1200 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt' + 'default' ': 1200 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt' 'low' ': 1300 MHz ARM | 400 MHz core | 450 MHz SDRAM | 3 overvolt' 'med' ': 1300 MHz ARM | 450 MHz core | 450 MHz SDRAM | 4 overvolt' 'high' ': 1300 MHz ARM | 500 MHz core | 450 MHz SDRAM | 5 overvolt' - ) fi G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 TARGETMENUID=13 # Return to this menu + Reset_Overclocking case "$G_WHIP_RETURNED_VALUE" in - 'none') Reset_Overclocking;; - 'safe') - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=1' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1500' /boot/config.txt ;; - 'low') - Warning_Overclocking || return - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=3' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=400' /boot/config.txt ;; - 'med') - Warning_Overclocking || return - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=450' /boot/config.txt ;; - 'high') - Warning_Overclocking || return - Reset_Overclocking G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1300' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt ;; - esac # RPi 400 elif [[ $G_HW_MODEL == 4 && $G_HW_MODEL_NAME == *'400'* ]]; then G_WHIP_MENU_ARRAY=( - 'energy saving' ': 1800 MHz ARM | 500 MHz core | -2 overvolt' 'default' ': 1800 MHz ARM | 500 MHz core | 0 overvolt' 'high GPU' ': 1900 MHz ARM | 700 MHz core | 5 overvolt' 'high ARM' ': 2000 MHz ARM | 600 MHz core | 5 overvolt' - ) G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $over_voltage_value overvolt" || return 0 @@ -3657,26 +3623,22 @@ Additional benchmarks: G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt G_CONFIG_INJECT 'over_voltage_min=' 'over_voltage_min=-2' /boot/config.txt ;; - 'high GPU') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1900' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=600' /boot/config.txt ;; - 'high ARM') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=5' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=2000' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt ;; - esac # RPi 4 elif (( $G_HW_MODEL == 4 )); then G_WHIP_MENU_ARRAY=( - 'energy saving' ': 1500 MHz ARM | 500 MHz core | -2 overvolt' 'default' ': 1500 MHz ARM | 500 MHz core | 0 overvolt' 'safe' ': 1600 MHz ARM | 500 MHz core | 0 overvolt' @@ -3684,7 +3646,6 @@ Additional benchmarks: 'medium ARM' ': 1800 MHz ARM | 500 MHz core | 2 overvolt' 'high GPU' ': 1800 MHz ARM | 700 MHz core | 4 overvolt' 'high ARM' ': 1900 MHz ARM | 600 MHz core | 4 overvolt' - ) G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $over_voltage_value overvolt" || return 0 @@ -3698,35 +3659,29 @@ Additional benchmarks: G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt G_CONFIG_INJECT 'over_voltage_min=' 'over_voltage_min=-2' /boot/config.txt ;; - 'safe') G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1600' /boot/config.txt ;; - 'medium GPU') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1700' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=600' /boot/config.txt ;; - 'medium ARM') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1800' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=500' /boot/config.txt ;; - 'high GPU') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1800' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=700' /boot/config.txt ;; - 'high ARM') G_CONFIG_INJECT 'over_voltage=' 'over_voltage=4' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1900' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=600' /boot/config.txt ;; - esac fi From 05a165897055065f1ad9abc48a113961f9840837 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Tue, 2 Nov 2021 18:57:42 +0100 Subject: [PATCH 68/82] v7.8 (#4920) + DietPi-Software | LXDE: Wallpaper and desktop icon text shadows are now set via global config file instead of applying this via first session script and doing the fragile PCManFM restart. + DietPi-Software | LXDE: Resolve "No session for pid" error prompt on desktop start + DietPi-Software | LXDE: Remove our own Openbox and PCManFM configs and instead apply the settings we want to add/change to the Debian package default. Only for the lxpanel we use our own, as it contains much customisations. However, align the format of the lxpanel config as much as possible with the Debian package's one for better comparison. + DietPi-Software | LXDE: Adjust Firefox app icon if it is not installed, use Chromium or the always installed text editor instead --- .conf/desktop/lxde/panel | 235 +++++++++++++++++++-------------------- CHANGELOG.txt | 2 + dietpi/dietpi-software | 45 +++++--- 3 files changed, 144 insertions(+), 138 deletions(-) diff --git a/.conf/desktop/lxde/panel b/.conf/desktop/lxde/panel index 81a2cc2b3b..90627e392c 100644 --- a/.conf/desktop/lxde/panel +++ b/.conf/desktop/lxde/panel @@ -1,157 +1,152 @@ +# lxpanel config file. Manually editing is not recommended. +# Use preference dialog in lxpanel to adjust config when you can. Global { - edge=bottom - allign=left - margin=0 - widthtype=percent - width=100 - height=36 - transparent=1 - tintcolor=#313131 - alpha=255 - autohide=0 - heightwhenhidden=2 - setdocktype=1 - setpartialstrut=1 - usefontcolor=1 - fontsize=10 - fontcolor=#ffffff - usefontsize=0 - background=0 - iconsize=34 -} -Plugin { - type=space - Config { - Size=5 - } + edge=bottom + align=left + margin=0 + widthtype=percent + width=100 + height=36 + transparent=1 + tintcolor=#313131 + alpha=255 + setdocktype=1 + setpartialstrut=1 + autohide=0 + heightwhenhidden=0 + usefontcolor=1 + fontcolor=#ffffff + background=0 + iconsize=34 } + Plugin { - type=menu - Config { - image=/usr/share/lxde/images/lxde-icon.png - system { - } - separator { + type = space + Config { + Size=5 } - item { - command=run - } - separator { - } - item { - image=gnome-logout - command=logout - } - } -} -Plugin { - type=space - Config { - Size=20 - } } + Plugin { - type=launchbar - Config { - Button { - id=/usr/share/applications/firefox-esr.desktop + type = menu + Config { + image=/usr/share/lxde/images/lxde-icon.png + system { + } + separator { + } + item { + command=run + } + separator { + } + item { + image=gnome-logout + command=logout + } } - } } + Plugin { - type=space - Config { - Size=5 - } + type = space + Config { + Size=10 + } } + Plugin { - type=launchbar - Config { - Button { - id=pcmanfm.desktop + type = launchbar + Config { + Button { + id=firefox-esr.desktop + } + Button { + id=pcmanfm.desktop + } + Button { + id=lxterminal.desktop + } } - } } + Plugin { - type=space - Config { - Size=5 - } + type = space + Config { + Size=10 + } } + Plugin { - type=launchbar - Config { - Button { - id=lxterminal.desktop + type = taskbar + expand=1 + Config { + tooltips=1 + IconsOnly=0 + AcceptSkipPager=1 + ShowIconified=1 + ShowMapped=1 + ShowAllDesks=0 + UseMouseWheel=1 + UseUrgencyHint=1 + FlatButton=0 + MaxTaskWidth=150 + spacing=1 } - } } + Plugin { - type=space - Config { - Size=20 - } + type = space + Config { + Size=10 + } } + Plugin { - type=taskbar - expand=1 - Config { - tooltips=1 - IconsOnly=0 - AcceptSkipPager=1 - ShowIconified=1 - ShowMapped=1 - ShowAllDesks=0 - UseMouseWheel=1 - UseUrgencyHint=1 - FlatButton=0 - MaxTaskWidth=150 - spacing=2 - UseSmallerIcons=-1 - } + type = tray } + Plugin { - type=space - Config { - Size=20 - } + type = space + Config { + Size=5 + } } + Plugin { - type=cpu - Config { - ShowPercent=1 - } + type = cpu } + Plugin { - type=tray - Config { - } + type = space + Config { + Size=5 + } } + Plugin { - type=volumealsa - Config { - } + type = volumealsa } + Plugin { - type=space - Config { - Size=5 - } + type = space + Config { + Size=5 + } } + Plugin { - type=dclock - Config { - ClockFmt=%R - TooltipFmt=%A %x - BoldFont=0 - IconOnly=0 - CenterText=0 - } + type = dclock + Config { + ClockFmt=%R + TooltipFmt=%A %x + BoldFont=0 + } } + Plugin { - type=space - Config { - Size=5 - } + type = space + Config { + Size=5 + } } diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c8e6e62418..ae3a0fb868 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -28,6 +28,8 @@ Fixes: - DietPi-Software | IceCast: Resolved an issue where a new install failed due to an attempted operation on a non-existing file. Many thanks to @killtux for reporting this issue: https://github.com/MichaIng/DietPi/issues/4858 - DietPi-Software | Logitech Media Server: Resolved an issue where the uninstall failed as the package postinst script tried to remove the service user before the service was stopped. - DietPi-Software | Roon Server: Resolved an issue where the internal updater purged all Roon Server data and configs, since the data directory was located within the install directory. Roon Server will now be installed to /opt/roonserver while the data directory remains at /mnt/dietpi_userdata/roonserver. This change will be applied via DietPi update as well, your data and configs will remain untouched. Many thanks to @JanKoudijs for reporting this issue and providing a solution: https://github.com/MichaIng/DietPi/pull/4897 +- DietPi-Software | LXDE: Resolved an issue where on some cases on first desktop start, desktop icons were missing and another issue on Bullseye systems, where a "No session for pid" error message popped up on desktop start. Many thanks to @kerryland for reporting these issues: https://github.com/MichaIng/DietPi/issues/4914 +- DietPi-Software | LXDE: Resolved an issue where the Firefox browser panel icon was present even if no Firefox was installed. In this case now either Chromium or the text editor is added as replacement. 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/XXXX diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 12cdec590c..577235e976 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -2332,19 +2332,8 @@ then fi # Disable this autostart entry -mkdir -p ~/.config/autostart +[ -d ~/.config/autostart ] || mkdir -p ~/.config/autostart echo '[Desktop Entry]\nHidden=true' > ~/.config/autostart/dietpi-desktop_setup.desktop - -# Apply desktop-specific configs -if [ $XDG_CURRENT_DESKTOP = 'LXDE' ] -then - pcmanfm --desktop-off - sleep 0.2 - sed -i '/^desktop_shadow=/c\desktop_shadow=#333333' ~/.config/pcmanfm/LXDE/desktop-items-0.conf - nohup pcmanfm --desktop -p LXDE & - sleep 0.2 - pcmanfm -w /var/lib/dietpi/dietpi-software/installed/desktop/wallpapers/dietpi-logo_inverted_1080p.png -fi _EOF_ cat << '_EOF_' > /etc/xdg/autostart/dietpi-desktop_setup.desktop @@ -3333,15 +3322,35 @@ _EOF_ [[ $display_manager == 0 && -f '/etc/systemd/system/display-manager.service' ]] && G_EXEC rm /etc/systemd/system/display-manager.service - # Openbox + PCmanFM + panel configs - G_EXEC mkdir -p /etc/xdg/{openbox/LXDE,pcmanfm/LXDE,lxpanel/LXDE/panels} - G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/lxde/lxde-rc.xml" -o /etc/xdg/openbox/LXDE/rc.xml - G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/lxde/pcmanfm.conf" -o /etc/xdg/pcmanfm/LXDE/pcmanfm.conf - G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/lxde/panel" -o /etc/xdg/lxpanel/LXDE/panels/panel + # lxpanel + G_EXEC curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/lxde/panel" -o /etc/xdg/lxpanel/LXDE/panels/panel + # - Adjust Firefox app icon if it is not installed + if (( ${aSOFTWARE_INSTALL_STATE[67]} < 1 )) + then + for i in 'chromium-browser' 'chromium' 'mousepad' 'leafpad' + do + [[ -f /usr/share/applications/$i.desktop ]] || continue + G_EXEC sed -i "s/firefox-esr/$i/" /etc/xdg/lxpanel/LXDE/panels/panel + break + done + fi + + # Openbox: Enable only one desktop and disable icon animations + G_CONFIG_INJECT '[0-9]*' '1' /etc/xdg/openbox/LXDE/rc.xml '' + G_CONFIG_INJECT '.*' 'no' /etc/xdg/openbox/LXDE/rc.xml '' + + # PCmanFM: Set wallpaper and desktop icon text shadow color + G_CONFIG_INJECT '\[desktop\]' '[desktop]' /etc/xdg/pcmanfm/LXDE/pcmanfm.conf + G_CONFIG_INJECT 'wallpaper_mode=' 'wallpaper_mode=fit' /etc/xdg/pcmanfm/LXDE/pcmanfm.conf '\[desktop\]' + G_CONFIG_INJECT 'wallpaper=' 'wallpaper=/var/lib/dietpi/dietpi-software/installed/desktop/wallpapers/dietpi-logo_inverted_1080p.png' /etc/xdg/pcmanfm/LXDE/pcmanfm.conf '\[desktop\]' + G_CONFIG_INJECT 'desktop_shadow=' 'desktop_shadow=#333333' /etc/xdg/pcmanfm/LXDE/pcmanfm.conf '\[desktop\]' # Apply better default icon theme: nuoveXT2 has more individual icons than Adwaita, but lower resolution and overrides the Firefox application icon with an old low res version. G_CONFIG_INJECT 'sNet/IconThemeName=' 'sNet/IconThemeName=Adwaita' /etc/xdg/lxsession/LXDE/desktop.conf '\[GTK\]' + # Workaround for "No session for pid" error: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=864402 + G_CONFIG_INJECT 'polkit/command=' 'polkit/command=' /etc/xdg/lxsession/LXDE/desktop.conf '\[Session\]' + # Disable trash G_CONFIG_INJECT 'use_trash=' 'use_trash=0' /etc/xdg/libfm/libfm.conf '\[config\]' @@ -3389,7 +3398,7 @@ _EOF_ # Disable trash # - Skip on Buster since trash seems to be implemented differently: https://github.com/MichaIng/DietPi/issues/1918#issuecomment-488085982 - (( $G_DISTRO < 5 )) && G_CONFIG_INJECT 'use_trash=' 'use_trash=0' /etc/xdg/libfm/libfm.conf + (( $G_DISTRO < 5 )) && G_CONFIG_INJECT 'use_trash=' 'use_trash=0' /etc/xdg/libfm/libfm.conf '\[config\]' Create_Desktop_Shared_Items From b93c388243c5285664f7d6c20e542ed0bf1a9c1f Mon Sep 17 00:00:00 2001 From: MichaIng Date: Tue, 2 Nov 2021 21:19:06 +0100 Subject: [PATCH 69/82] v7.8 + DietPi-Patches | LXDE: Fixing the "No session for pid" error prompt on desktop start --- .update/patches | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.update/patches b/.update/patches index d105dba373..4dd6bdc67d 100644 --- a/.update/patches +++ b/.update/patches @@ -458,6 +458,12 @@ _EOF_ G_EXEC sed -i '/^185.101.93.93/d' /root/.ssh/known_hosts G_CONFIG_INJECT 'ssh.dietpi.com[[:blank:]]' 'ssh.dietpi.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDE6aw3r6aOEqendNu376iiCHr9tGBIWPgfrLkzjXjEsHGyVSUFNnZt6pftrDeK7UX+qX4FxOwQlugG4fymOHbimRCFiv6cf7VpYg1Ednquq9TLb7/cIIbX8a6AuRmX4fjdGuqwmBq3OG7ZksFcYEFKt5U4mAJIaL8hXiM2iXjgY02LqiQY/QWATsHI4ie9ZOnwrQE+Rr6mASN1BVFuIgyHIbwX54jsFSnZ/7CdBMkuAd9B8JkxppWVYpYIFHE9oWNfjh/epdK8yv9Oo6r0w5Rb+4qaAc5g+RAaknHeV6Gp75d2lxBdCm5XknKKbGma2+/DfoE8WZTSgzXrYcRlStYN' /root/.ssh/known_hosts fi + + if [[ -f '/etc/xdg/lxsession/LXDE/desktop.conf' ]] + then + G_DIETPI-NOTIFY 2 'Fixing the "No session for pid" error prompt on LXDE start' + G_CONFIG_INJECT 'polkit/command=' 'polkit/command=' /etc/xdg/lxsession/LXDE/desktop.conf '\[Session\]' + fi } Patch_7_8() From 480254f0dcfec2d9e6af3997b2af63e872613a88 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 3 Nov 2021 14:26:50 +0100 Subject: [PATCH 70/82] v7.8 + General | Whenever calling "ping", prevent reverse DNS resolving if IPs in output, as we never want to test reverse DNS capabilities but at most forward DNS resolving when pinging a hostname. This potentially reduces lags during connectivity tests quite significantly. --- dietpi/func/dietpi-globals | 4 ++-- dietpi/func/dietpi-optimal_mtu | 4 ++-- rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dietpi/func/dietpi-globals b/dietpi/func/dietpi-globals index 3746a4be57..4520e47775 100644 --- a/dietpi/func/dietpi-globals +++ b/dietpi/func/dietpi-globals @@ -1158,7 +1158,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[4]=$G_CHECK_URL_TIMEOUT; declare -F G_EXEC_PRE_FUNC_ORIG &> /dev/null && G_EXEC_PRE_FUNC_ORIG; } - G_EXEC_DESC='Checking network connectivity' G_EXEC ping -c 1 -W $G_CHECK_URL_TIMEOUT ${ip:-"$@"} + G_EXEC_DESC='Checking network connectivity' G_EXEC ping -nc 1 -W $G_CHECK_URL_TIMEOUT ${ip:-"$@"} local exit_code=$? unset -v G_CHECK_URL_TIMEOUT G_CHECK_URL_ATTEMPTS @@ -1208,7 +1208,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[4]=$G_CHECK_URL_TIMEOUT; declare -F G_EXEC_PRE_FUNC_ORIG &> /dev/null && G_EXEC_PRE_FUNC_ORIG; } - G_EXEC_DESC='Checking DNS resolver' G_EXEC ping -c 1 -W $G_CHECK_URL_TIMEOUT ${domain:-"$@"} + G_EXEC_DESC='Checking DNS resolver' G_EXEC ping -nc 1 -W $G_CHECK_URL_TIMEOUT ${domain:-"$@"} local exit_code=$? unset -v G_CHECK_URL_TIMEOUT G_CHECK_URL_ATTEMPTS diff --git a/dietpi/func/dietpi-optimal_mtu b/dietpi/func/dietpi-optimal_mtu index 079fc41e3c..bde91addb0 100644 --- a/dietpi/func/dietpi-optimal_mtu +++ b/dietpi/func/dietpi-optimal_mtu @@ -27,7 +27,7 @@ # Grab and test input host HOST=${1:-dietpi.com} - if ping -4 -c 1 "$HOST" > /dev/null; then + if ping -n4qc 1 "$HOST" > /dev/null; then G_DIETPI-NOTIFY 2 "Finding optimal MTU size with test host $HOST, please wait..." @@ -47,7 +47,7 @@ G_DIETPI-NOTIFY -2 "Testing MTU size: $MTU_SIZE" # Remove IPv4 ICMP headers from total size - if ping -4 -c 1 -s $(( $MTU_SIZE - 28 )) -M 'do' "$HOST" &> /dev/null; then + if ping -n4qc 1 -s $(( $MTU_SIZE - 28 )) -M 'do' "$HOST" &> /dev/null; then G_DIETPI-NOTIFY 0 "Optimal MTU size = $MTU_SIZE" break diff --git a/rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh b/rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh index 121adc4a3a..f2a238dc3b 100644 --- a/rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh +++ b/rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh @@ -24,7 +24,7 @@ G_DIETPI-NOTIFY 1 "WiFi adapter $ADAPTER has been unplugged. Exiting..." exit 1 - elif ! GATEWAY=$(G_GET_NET -i "$ADAPTER" gateway) || ! ping -qI "$ADAPTER" -c 1 "$GATEWAY" &> /dev/null + elif ! GATEWAY=$(G_GET_NET -i "$ADAPTER" gateway) || ! ping -nqc 1 -I "$ADAPTER" "$GATEWAY" &> /dev/null then G_DIETPI-NOTIFY 2 "Detected $ADAPTER connection loss. Reconnecting..." ifdown "$ADAPTER" From c47a774259897448efea9e0d66794f5835928fae Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 3 Nov 2021 14:57:38 +0100 Subject: [PATCH 71/82] v7.8 + DietPi-FirstBoot | RPi: Always apply commented default overclocking settings, but do this only for the definitely untouched ones with the hash at the beginning of the line. Aside of temperature limit, preserve existing settings when applying new ones. It is then important that e.g. over_voltage is set only when the CPU frequency is set as expected. That way config.txt shows the correct defaults for all overclocking values that have not been set manually by the user before the first boot or actively by us as a reasonably default change. --- .../lib/dietpi/services/dietpi-firstboot.bash | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash index d15b580d2e..44b0b502ba 100755 --- a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash +++ b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash @@ -27,64 +27,63 @@ RPi_Set_Clock_Speeds() { - # If no manual overclock settings have been applied by user, apply safe overclocking values (RPi1) or update comments to show model-specific defaults: https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md - grep -qE '^[[:blank:]]*(over_voltage|(arm|core|gpu|sdram)_freq)=' /boot/config.txt && return + # Update comments to show model-specific defaults and apply safe overclocking profile on RPi 1: https://github.com/raspberrypi/documentation/blob/develop/documentation/asciidoc/computers/config_txt/overclocking.adoc # RPi Zero/Zero 2 W if [[ $G_HW_MODEL_NAME == *'Zero'* ]] then - sed -i '/#over_voltage=/c\#over_voltage=0' /boot/config.txt - sed -i '/#arm_freq=/c\#arm_freq=1000' /boot/config.txt - sed -i '/#core_freq=/c\#core_freq=400' /boot/config.txt - sed -i '/#sdram_freq=/c\#sdram_freq=450' /boot/config.txt + sed -i '/^#over_voltage=/c\#over_voltage=0' /boot/config.txt + sed -i '/^#arm_freq=/c\#arm_freq=1000' /boot/config.txt + sed -i '/^#core_freq=/c\#core_freq=400' /boot/config.txt + sed -i '/^#sdram_freq=/c\#sdram_freq=450' /boot/config.txt # RPi 1: Apply safe overclock mode elif (( $G_HW_MODEL < 2 )) then - G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt - G_CONFIG_INJECT 'arm_freq=' 'arm_freq=900' /boot/config.txt - sed -i '/#core_freq=/c\#core_freq=250' /boot/config.txt - sed -i '/#sdram_freq=/c\#sdram_freq=400' /boot/config.txt + GCI_PRESERVE=1 G_CONFIG_INJECT 'arm_freq=' 'arm_freq=900' /boot/config.txt + grep -q '^arm_freq=900$' /boot/config.txt && G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt + sed -i '/^#core_freq=/c\#core_freq=250' /boot/config.txt + sed -i '/^#sdram_freq=/c\#sdram_freq=400' /boot/config.txt # RPi 2 elif (( $G_HW_MODEL == 2 )) then - sed -i '/#over_voltage=/c\#over_voltage=0' /boot/config.txt - sed -i '/#arm_freq=/c\#arm_freq=900' /boot/config.txt - sed -i '/#core_freq=/c\#core_freq=250' /boot/config.txt - sed -i '/#sdram_freq=/c\#sdram_freq=450' /boot/config.txt + sed -i '/^#over_voltage=/c\#over_voltage=0' /boot/config.txt + sed -i '/^#arm_freq=/c\#arm_freq=900' /boot/config.txt + sed -i '/^#core_freq=/c\#core_freq=250' /boot/config.txt + sed -i '/^#sdram_freq=/c\#sdram_freq=450' /boot/config.txt # RPi 3 elif (( $G_HW_MODEL == 3 )) then - sed -i '/#over_voltage=/c\#over_voltage=0' /boot/config.txt - sed -i '/#core_freq=/c\#core_freq=400' /boot/config.txt - G_CONFIG_INJECT 'temp_limit=' 'temp_limit=75' /boot/config.txt # https://github.com/MichaIng/DietPi/issues/356 + sed -i '/^#over_voltage=/c\#over_voltage=0' /boot/config.txt + sed -i '/^#core_freq=/c\#core_freq=400' /boot/config.txt + grep -q '^temp_limit=65$' /boot/config.txt && G_CONFIG_INJECT 'temp_limit=' 'temp_limit=75' /boot/config.txt # https://github.com/MichaIng/DietPi/issues/356 # A+/B+ if [[ $G_HW_MODEL_NAME == *'+'* ]] then - sed -i '/#arm_freq=/c\#arm_freq=1400' /boot/config.txt - sed -i '/#sdram_freq=/c\#sdram_freq=500' /boot/config.txt + sed -i '/^#arm_freq=/c\#arm_freq=1400' /boot/config.txt + sed -i '/^#sdram_freq=/c\#sdram_freq=500' /boot/config.txt else - sed -i '/#arm_freq=/c\#arm_freq=1200' /boot/config.txt - sed -i '/#sdram_freq=/c\#sdram_freq=450' /boot/config.txt + sed -i '/^#arm_freq=/c\#arm_freq=1200' /boot/config.txt + sed -i '/^#sdram_freq=/c\#sdram_freq=450' /boot/config.txt fi # RPi 4 elif (( $G_HW_MODEL == 4 )) then - sed -i '/#over_voltage=/c\#over_voltage=0' /boot/config.txt - sed -i '/#core_freq=/c\#core_freq=500' /boot/config.txt - sed -i '/#sdram_freq=/d' /boot/config.txt # Not supported on RPi4, defaults to 3200 MHz - G_CONFIG_INJECT 'temp_limit=' 'temp_limit=75' /boot/config.txt # https://github.com/MichaIng/DietPi/issues/3019 + sed -i '/^#over_voltage=/c\#over_voltage=0' /boot/config.txt + sed -i '/^#core_freq=/c\#core_freq=500' /boot/config.txt + sed -i '/^#sdram_freq=/d' /boot/config.txt # Not supported on RPi4, defaults to 3200 MHz + grep -q '^temp_limit=65$' /boot/config.txt && G_CONFIG_INJECT 'temp_limit=' 'temp_limit=75' /boot/config.txt # https://github.com/MichaIng/DietPi/issues/3019 # 400 if [[ $G_HW_MODEL_NAME == *'400'* ]] then - sed -i '/#arm_freq=/c\#arm_freq=1800' /boot/config.txt + sed -i '/^#arm_freq=/c\#arm_freq=1800' /boot/config.txt else - sed -i '/#arm_freq=/c\#arm_freq=1500' /boot/config.txt + sed -i '/^#arm_freq=/c\#arm_freq=1500' /boot/config.txt fi fi } From 94811c7a1d1a241de3bdaed46bdcd28b3a31fd6b Mon Sep 17 00:00:00 2001 From: Joulinar <47155374+Joulinar@users.noreply.github.com> Date: Wed, 3 Nov 2021 20:43:35 +0100 Subject: [PATCH 72/82] v7.8 (#4912) + DietPi-Software | Single File PHP Gallery: Download newest version from official website + DietPi-Software | Single File PHP Gallery: Remove cache dir on reinstalls + DietPi-Software | Single File PHP Gallery: Assign random 30 alphanumerical character security phrase, just like the script itself would try it when unset. We could leave it out, but then PHP required write access to the script, so it is safer to preset it. --- dietpi/dietpi-software | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 577235e976..cd93aa6e95 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -6182,17 +6182,20 @@ _EOF_ # Install required PHP modules: https://sye.dk/sfpg/ DEPS_LIST="$PHP_NAME-gd" - Download_Install 'https://dietpi.com/downloads/binaries/all/Single_File_PHP_Gallery.7z' /var/www/gallery + Download_Install 'https://sye.dk/sfpg/Single_File_PHP_Gallery_4.8.0.zip' /var/www/gallery # Enable required PHP modules G_EXEC phpenmod gd - # Cache/thumbnails/database - [[ -d '/var/www/gallery/_sfpg_data' ]] || G_EXEC mkdir /var/www/gallery/_sfpg_data + # Thumbnails and metadata cache: Remove on reinstalls + [[ -d '/var/www/gallery/_sfpg_data' ]] && G_EXEC rm -R /var/www/gallery/_sfpg_data + G_EXEC mkdir /var/www/gallery/_sfpg_data G_EXEC chown www-data /var/www/gallery/_sfpg_data - # Enable (Some type of security trigger) - G_EXEC sed -i "/define('SECURITY_PHRASE'/c\\\tdefine('SECURITY_PHRASE', 'true');" /var/www/gallery/index.php + # Apply a random security phrase + local phrase=$(tr -dc '[:alnum:]' < /dev/random | head -c30) + GCI_PASSWORD=1 G_CONFIG_INJECT "define\('SECURITY_PHRASE'" "define('SECURITY_PHRASE', '$phrase');" /var/www/gallery/index.php + unset -v phrase # Create test galleries [[ -d '/var/www/gallery/DietPi' ]] || G_EXEC mkdir /var/www/gallery/DietPi From 792a4061b4b76221bb483b5f9da128c7232e3d48 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Wed, 3 Nov 2021 20:46:27 +0100 Subject: [PATCH 73/82] v7.8 (#4922) + DietPi-Backup | Add the option to enable daily system backups via cron job + DietPi-Cron | Assure that whiptail dialogues are skipped, even when the script is called manually, since STDOUT is redirected + DietPi-Backup | Log transfer details to the backup location form now on to assure they are persistent and can be reviewed at a later time and that they remain associated to the individual backup location. This is especially helpful when doing daily backups via cron job, as in this case the log file is not shown directly when the backup finished. + DietPi-Backup | Add an option to the menu to review the last backup/restore log, if present, which is now persistent + DietPi-Patches | Move the DietPi backup log from old /var/log/dietpi-backup.log to the new backup location. Remove it if no backup location exists. + DietPi-Sync | Add short desciptions to menu options --- .update/patches | 13 +++++++ CHANGELOG.txt | 2 + dietpi/dietpi-backup | 73 +++++++++++++++++++++-------------- dietpi/dietpi-sync | 34 ++++++---------- rootfs/etc/cron.daily/dietpi | 11 +++++- rootfs/etc/cron.hourly/dietpi | 3 ++ 6 files changed, 85 insertions(+), 51 deletions(-) diff --git a/.update/patches b/.update/patches index 4dd6bdc67d..aeae3b85af 100644 --- a/.update/patches +++ b/.update/patches @@ -535,6 +535,19 @@ Patch_7_8() G_DIETPI-NOTIFY 2 'Removing ineffective "rootdelay" argument from /boot/cmdline.txt' G_EXEC sed -i -e 's/^rootdelay=[^[:blank:]]*[[:blank:]]*//g' -e 's/[[:blank:]]*[[:blank:]]rootdelay=[^[:blank:]]*//g' /boot/cmdline.txt fi + + # DietPi-Backup: Move logs to persistent backup location + if [[ -f '/var/log/dietpi-backup.log' ]] + then + if [[ -f '/boot/dietpi/.dietpi-backup_settings' ]] && . /boot/dietpi/.dietpi-backup_settings && [[ $FP_TARGET && ! -f $FP_TARGET/dietpi-backup.log ]] + then + G_DIETPI-NOTIFY 2 "Moving DietPi-Backup log file to $FP_TARGET/dietpi-backup.log" + G_EXEC mv /var/log/dietpi-backup.log "$FP_TARGET/dietpi-backup.log" + else + G_DIETPI-NOTIFY 2 'Removing obsolete DietPi-Backup log file /var/log/dietpi-backup.log' + G_EXEC rm /var/log/dietpi-backup.log + fi + fi } # v6.35 => v7 migration diff --git a/CHANGELOG.txt b/CHANGELOG.txt index ae3a0fb868..edd0e4bc99 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -13,6 +13,8 @@ Changes: - Odroid N1 | Removed support: We don't have a single reported system, which makes sense as this model was never really released. Only a small number of developer samples are floating around, not worth to keep maintaining an image and dedicated code. If there is really an Odroid N1 DietPi system out there, it will be automatically migrated to the Generic Rockchip RK3399 device ID on DietPi update. - DietPi-Config | Overclocking profiles for most Raspberry Pi models have been updated to match the effective 100 MHz ARM/CPU frequency steps used by current firmware. Also an energy saving profile has been added to some models, which reduces minimum and maximum voltage a little, reducing energy consumption and heat emission a little on idle and on load. - DietPi-Config | The option to prefer IPv4 connections when IPv6 is enabled has been removed: This only worked for APT and wget, while e.g. cURL and ping were never affected by this setting, which meant an inconsistent behaviour. If one faces issues with IPv6 enabled, it should be simply disabled instead of preferring/forcing IPv4 only for specific tools. +- DietPi-Backup | A feature has been added to enable daily system backup via cron job. Many thanks to @Lycidias93 for suggesting this feature: https://github.com/MichaIng/DietPi/issues/3871 +- DietPi-Backup | Rsync/transfer logs are now done to "dietpi-backup.log" inside of the backup directory. This way they remain persistent even if DietPi-RAMlog is enabled and can be reviewed at a later time. This is helpful especially when daily backups via cron job are enabled, where the log obviously is not presented directly when the backup finished. A related option to review the last transfer log has been added to the dietpi-backup main menu. The old log file /var/log/dietpi-backup.log is moved to the new location if any backup exists during next DietPi update. - DietPi-Backup | When using an NFS mount as backup target, it is now verified that the NFS share supports UNIX permissions to prevent the creation of a broken system backup in the first place. - DietPi-Drive_Manager | When transferring the DietPi user data to a different drive, it is now ckecked whether the target location is located within a supported filesystem type, one with native symlink and UNIX permission support. The same is done when using the CLI script /boot/dietpi/func/dietpi-set_userdata. - DietPi-Drive_Manager | Transferring the root filesystem is now supported on Odroid C4/HC4 models. diff --git a/dietpi/dietpi-backup b/dietpi/dietpi-backup index cbe982f9fc..50d0e7b7f4 100644 --- a/dietpi/dietpi-backup +++ b/dietpi/dietpi-backup @@ -36,9 +36,9 @@ #///////////////////////////////////////////////////////////////////////////////////// # Backup System #///////////////////////////////////////////////////////////////////////////////////// - readonly FP_LOG='/var/log/dietpi-backup.log' + readonly FP_LOG='dietpi-backup.log' - # Backup Filepaths + # Backup file paths FP_SOURCE='/' FP_TARGET='/mnt/dietpi-backup' @@ -54,7 +54,7 @@ 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_LOG") + readonly aRSYNC_LOGGING_OPTIONS=('-v' "--log-file=$FP_TARGET/$FP_LOG") # Date format for logs Print_Date(){ date '+%Y-%m-%d_%T'; } @@ -114,7 +114,6 @@ cat << _EOF_ > $FP_FILTER # Backup data, log and config - $FP_TARGET/ -- $FP_LOG - $FP_SETTINGS # RAM dirs - /dev/ @@ -197,7 +196,7 @@ However, this check is a rough estimation in reasonable time, thus it could be m G_DIETPI-NOTIFY 2 "Backup to $FP_TARGET in progress, please wait..." # Init log file - echo -e "Backup log from $(Print_Date)\n" > $FP_LOG + echo -e "Backup log from $(Print_Date)\n" > "$FP_TARGET/$FP_LOG" rsync "${aRSYNC_RUN_OPTIONS_BACKUP[@]}" "${aRSYNC_LOGGING_OPTIONS[@]}" "$FP_SOURCE" "$FP_TARGET/data/" EXIT_CODE=$? @@ -216,7 +215,7 @@ However, this check is a rough estimation in reasonable time, thus it could be m fi - log=1 G_WHIP_VIEWFILE $FP_LOG + log=1 G_WHIP_VIEWFILE "$FP_TARGET/$FP_LOG" fi @@ -358,7 +357,7 @@ However, this check is a rough estimation in reasonable time, thus it could be m G_DIETPI-NOTIFY 2 "Restore from $FP_TARGET in progress, please wait..." # Init log file - echo -e "Restore log from $(Print_Date)\n" > $FP_LOG + echo -e "Restore log from $(Print_Date)\n" > "$FP_TARGET/$FP_LOG" rsync "${aRSYNC_RUN_OPTIONS_RESTORE[@]}" "${aRSYNC_LOGGING_OPTIONS[@]}" "$FP_TARGET/data/" "$FP_SOURCE" EXIT_CODE=$? @@ -380,7 +379,7 @@ However, this check is a rough estimation in reasonable time, thus it could be m fi - log=1 G_WHIP_VIEWFILE $FP_LOG + log=1 G_WHIP_VIEWFILE "$FP_TARGET/$FP_LOG" fi @@ -390,8 +389,15 @@ However, this check is a rough estimation in reasonable time, thus it could be m # Settings #///////////////////////////////////////////////////////////////////////////////////// readonly FP_SETTINGS='/boot/dietpi/.dietpi-backup_settings' + DAILY_BACKUP=0 - Write_Settings_File(){ echo "FP_TARGET=$FP_TARGET" > $FP_SETTINGS; } + Write_Settings_File() + { + cat << _EOF_ > $FP_SETTINGS +FP_TARGET=$FP_TARGET +DAILY_BACKUP=$DAILY_BACKUP +_EOF_ + } Read_Settings_File(){ [[ -f $FP_SETTINGS ]] && . $FP_SETTINGS; } @@ -406,22 +412,30 @@ However, this check is a rough estimation in reasonable time, thus it could be m Menu_Main(){ local backup_last_completed='Backup not found. Please create one.' + local daily_backup_text='Off' + (( $DAILY_BACKUP )) && daily_backup_text='On' - G_WHIP_MENU_ARRAY=() - G_WHIP_MENU_ARRAY+=('' '●─ Info ') - G_WHIP_MENU_ARRAY+=('Help' "What does $G_PROGRAM_NAME do?") - G_WHIP_MENU_ARRAY+=('' '●─ Options ') - G_WHIP_MENU_ARRAY+=('Location' ': Change where your backup will be saved and restored from.') - G_WHIP_MENU_ARRAY+=('Filter' ': Modify include/exclude filter for backups.') - if [[ -f $FP_TARGET'/'$FP_STATS ]]; then - + G_WHIP_MENU_ARRAY=( + '' '●─ Info ' + 'Help' ": What does $G_PROGRAM_NAME do?" + ) + [[ -f $FP_TARGET/$FP_LOG ]] && G_WHIP_MENU_ARRAY+=('Last log' ': Review last backup/restore log for current location') + G_WHIP_MENU_ARRAY+=( + '' '●─ Options ' + '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" + ) + if [[ -f $FP_TARGET/$FP_STATS ]] + then G_WHIP_MENU_ARRAY+=('Delete' ": Remove backup ($FP_TARGET)") backup_last_completed=$(grep 'ompleted' "$FP_TARGET/$FP_STATS" | tail -1) - fi - G_WHIP_MENU_ARRAY+=('' '●─ Run ') - G_WHIP_MENU_ARRAY+=('Backup' 'Create (or update) a backup of this device.') - G_WHIP_MENU_ARRAY+=('Restore' 'Restore this device from a previous backup.') + G_WHIP_MENU_ARRAY+=( + '' '●─ Run ' + 'Backup' ': Create (or update) a backup of this device.' + 'Restore' ': Restore this device from a previous backup.' + ) G_WHIP_DEFAULT_ITEM=$MENU_LASTITEM G_WHIP_BUTTON_CANCEL_TEXT='Exit' @@ -431,14 +445,19 @@ However, this check is a rough estimation in reasonable time, thus it could be m case "$G_WHIP_RETURNED_VALUE" in + 'Help') G_WHIP_MSG 'DietPi-Backup is a program that allows you to Backup and Restore your DietPi system. +\nIf you have broken your system, or want to reset your system to an earlier date, this can all be done with DietPi-Backup. +\nSimply choose a location where you want to save and restore your backups from, then, select Backup or Restore. +\nEnable a daily system backup to run it once a day via daily cron job. The execution time can be changed in "dietpi-cron". Note that this temporarily stops server services. Also we recommend to configure and test the backup with a manual call before enabling this feature. +\nMore information: https://dietpi.com/docs/dietpi_tools/#dietpi-backup-backuprestore';; + + 'Last log') log=1 G_WHIP_VIEWFILE "$FP_TARGET/$FP_LOG";; + 'Location') TARGETMENUID=1;; - 'Filter') nano $FP_FILTER_CUSTOM;; + 'Daily Backup') DAILY_BACKUP=$(( ! $DAILY_BACKUP ));; - 'Help') G_WHIP_MSG "DietPi-Backup is a program that allows you to Backup and Restore your DietPi system. -\nIf you have broken your system, or want to reset your system to an earlier date, this can all be done with DietPi-Backup. -\nSimply choose a location where you want to save and restore your backups from, then, select Backup or Restore. -\nMore information: https://dietpi.com/docs/dietpi_tools/#dietpi-backup-backuprestore";; + 'Filter') nano $FP_FILTER_CUSTOM;; '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";; @@ -488,11 +507,9 @@ However, this check is a rough estimation in reasonable time, thus it could be m G_WHIP_MENU_ARRAY=() 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. G_WHIP_MENU_ARRAY+=("$backup_directory" ": $last_backup_date") - done G_WHIP_MENU 'Please select a previous backup to use:' || return diff --git a/dietpi/dietpi-sync b/dietpi/dietpi-sync index a9655fb1c9..9d0053448a 100644 --- a/dietpi/dietpi-sync +++ b/dietpi/dietpi-sync @@ -77,10 +77,8 @@ _EOF_ for i in "${aexclude[@]}" do - # Exclude only, if inside source location, via path, relative to source location [[ $i == ${FP_SOURCE}/* ]] && echo "- $(realpath --relative-to="$FP_SOURCE" "$i")" >> $FP_FILTER_INCLUDE_EXCLUDE - done unset aexclude @@ -178,7 +176,6 @@ Continue only if you know what you are doing and after checking the log!" while : do - G_WHIP_MENU_ARRAY=( 'Sync' ': Continue with real sync' @@ -203,7 +200,6 @@ Continue only if you know what you are doing and after checking the log!" return fi - done # Sync @@ -298,10 +294,10 @@ _EOF_ '' '●─ Info ' 'Help' ": What does $G_PROGRAM_NAME do?" '' '●─ Options ' - 'Source Location' ": [$FP_SOURCE]" - 'Target Location' ": [$FP_TARGET]" - 'Delete Mode' ": [$SYNC_MODE_TEXT]" - 'Daily Sync' ": [$SYNC_CRONDAILY_TEXT]" + 'Source Location' ": [$FP_SOURCE] Sync FROM here" + 'Target Location' ": [$FP_TARGET] Sync TO here" + 'Delete Mode' ": [$SYNC_MODE_TEXT] Sync file removals" + 'Daily Sync' ": [$SYNC_CRONDAILY_TEXT] Daily sync via cron job" '' '●─ Run ' 'Dry run + Sync' ': Sync from Source to Target (Dry run included!)' @@ -315,19 +311,15 @@ _EOF_ case "$G_WHIP_RETURNED_VALUE" in - 'Source Location') TARGETMENUID=2;; - - 'Target Location') TARGETMENUID=1;; - - 'Help') - - G_WHIP_MSG 'DietPi-Sync is a program that allows you to duplicate a directory from one location (Source) to another (Target).\n + 'Help') G_WHIP_MSG 'DietPi-Sync is a program that allows you to duplicate a directory from one location (Source) to another (Target).\n For example: If we want to duplicate (sync) the data on our external USB HDD to another location, we simply select the USB HDD as the source, then, select a target location. The target location can be anything from a networked samba fileserver, or even an FTP server.\n Each sync includes a leading dry run, after which you can check the expected result before deciding if you want to continue with the actual sync.\n -More information:\n - https://dietpi.com/docs/dietpi_tools/#dietpi-sync' +More information:\n - https://dietpi.com/docs/dietpi_tools/#dietpi-sync';; - ;; + 'Source Location') TARGETMENUID=2;; + + 'Target Location') TARGETMENUID=1;; 'Delete Mode') Menu_Set_Sync_Delete_Mode;; @@ -479,9 +471,9 @@ If files are in the Target location that do not exist in the Source, they will b ) G_WHIP_DEFAULT_ITEM=$SYNC_CRONDAILY_TEXT - if G_WHIP_MENU 'Off:\nThe user must manually sync using dietpi-sync.\n -On:\nA cron job will automatically run dietpi-sync, once a day.\n -(NOTICE):\nWhen using this feature, please run a manual sync and check the dry run log to verify what will happen.'; then + if G_WHIP_MENU 'Off:\nThe user must manually sync using dietpi-sync. +\nOn:\nA cron job will automatically run dietpi-sync, once a day. +\n(NOTICE):\nWhen using this feature, please run a manual sync and check the dry run log to verify what will happen.'; then [[ $G_WHIP_RETURNED_VALUE == 'On' ]] && SYNC_CRONDAILY=1 || SYNC_CRONDAILY=0 @@ -576,7 +568,6 @@ _EOF_ until (( $TARGETMENUID < 0 )) do - G_TERM_CLEAR if [[ $TARGETMENUID == [12] ]]; then @@ -588,7 +579,6 @@ _EOF_ Menu_Main fi - done Write_Settings_File diff --git a/rootfs/etc/cron.daily/dietpi b/rootfs/etc/cron.daily/dietpi index ce49977262..bf5b4212a2 100644 --- a/rootfs/etc/cron.daily/dietpi +++ b/rootfs/etc/cron.daily/dietpi @@ -10,6 +10,9 @@ # #//////////////////////////////////// + # Assure that whiptail dialogues are skipped, even when the script is called manually, since STDOUT is redirected + export G_INTERACTIVE=0 + #---------------------------------------------------------------- # Main Loop #---------------------------------------------------------------- @@ -39,7 +42,13 @@ if [[ ! -f '/boot/dietpi/.dietpi-banner' ]] || grep -q '^[[:blank:]]*aENABLED\[12\]=1' /boot/dietpi/.dietpi-banner then [[ -f '/run/dietpi/.dietpi_motd' ]] && rm /run/dietpi/.dietpi_motd - curl -sSfL https://dietpi.com/motd -o /run/dietpi/.dietpi_motd + curl -sSfL 'https://dietpi.com/motd' -o /run/dietpi/.dietpi_motd + fi + #---------------------------------------------------------------- + # DietPi-Backup daily + if [[ -f '/boot/dietpi/.dietpi-backup_settings' ]] && grep -q '^[[:blank:]]*DAILY_BACKUP=1' /boot/dietpi/.dietpi-backup_settings + then + /boot/dietpi/dietpi-backup 1 fi #---------------------------------------------------------------- # DietPi-Sync daily diff --git a/rootfs/etc/cron.hourly/dietpi b/rootfs/etc/cron.hourly/dietpi index b3d7741f34..223ceea7bb 100644 --- a/rootfs/etc/cron.hourly/dietpi +++ b/rootfs/etc/cron.hourly/dietpi @@ -10,6 +10,9 @@ # #//////////////////////////////////// + # Assure that whiptail dialogues are skipped, even when the script is called manually, since STDOUT is redirected + export G_INTERACTIVE=0 + #---------------------------------------------------------------- # Main Loop #---------------------------------------------------------------- From 31c715fe76fcbabfc90a5aabed57232387fc5a3b Mon Sep 17 00:00:00 2001 From: MichaIng Date: Thu, 4 Nov 2021 16:23:55 +0100 Subject: [PATCH 74/82] v7.8 + DietPi-Patches | Do not move dietpi-backup.log if the target directory from settings does not exist --- .update/patches | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.update/patches b/.update/patches index aeae3b85af..d0f66a7154 100644 --- a/.update/patches +++ b/.update/patches @@ -539,7 +539,7 @@ Patch_7_8() # DietPi-Backup: Move logs to persistent backup location if [[ -f '/var/log/dietpi-backup.log' ]] then - if [[ -f '/boot/dietpi/.dietpi-backup_settings' ]] && . /boot/dietpi/.dietpi-backup_settings && [[ $FP_TARGET && ! -f $FP_TARGET/dietpi-backup.log ]] + if [[ -f '/boot/dietpi/.dietpi-backup_settings' ]] && . /boot/dietpi/.dietpi-backup_settings && [[ $FP_TARGET && -d $FP_TARGET && ! -f $FP_TARGET/dietpi-backup.log ]] then G_DIETPI-NOTIFY 2 "Moving DietPi-Backup log file to $FP_TARGET/dietpi-backup.log" G_EXEC mv /var/log/dietpi-backup.log "$FP_TARGET/dietpi-backup.log" From 2b92cb2e1e027046a8e8e7dd32fef547ff21af67 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Thu, 4 Nov 2021 18:44:29 +0100 Subject: [PATCH 75/82] v7.8 + DietPi-Live_patches | Drop v7.7 live patch for v7.8 --- .update/version | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.update/version b/.update/version index d96249e91a..f4a522152f 100644 --- a/.update/version +++ b/.update/version @@ -12,6 +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=('Deluge services fail on fresh installs') -G_LIVE_PATCH_COND=('grep -q " \\\$salt," /boot/dietpi/dietpi-software') -G_LIVE_PATCH=('sed -Ei -e "/max_active_limit/s/1\)'\'',\"/1\),\"/" -e "/pwd_salt/s/ \\\$salt,/ \\\\\"\\\$salt\\\\\",/" -e "/pwd_sha1/s/ \\\$\(echo (.*)\),/ \\\\\"\\\$\(echo \1\)\\\\\",/" /boot/dietpi/dietpi-software') +G_LIVE_PATCH_DESC=() +G_LIVE_PATCH_COND=() +G_LIVE_PATCH=() From 3a66d7463832cb43413fec5e3fbbeb0aec319a88 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Thu, 4 Nov 2021 22:11:39 +0100 Subject: [PATCH 76/82] v7.8 + DietPi-Software | Mopidy: Merge install and config code blocks --- dietpi/dietpi-software | 119 ++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 67 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index cd93aa6e95..47bc8229e9 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -467,7 +467,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=118 aSOFTWARE_NAME[$software_id]='Mopidy' - aSOFTWARE_DESC[$software_id]='web interface music & radio player' + aSOFTWARE_DESC[$software_id]='Web interface music & radio player' aSOFTWARE_CATX[$software_id]=2 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/media/#mopidy' aSOFTWARE_DEPS[$software_id]='5' @@ -1581,14 +1581,14 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=157 aSOFTWARE_NAME[$software_id]='Home Assistant' - aSOFTWARE_DESC[$software_id]='open-source home automation platform' + aSOFTWARE_DESC[$software_id]='Open source home automation platform' aSOFTWARE_CATX[$software_id]=17 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/home_automation/#home-assistant' #------------------ software_id=140 aSOFTWARE_NAME[$software_id]='Domoticz' - aSOFTWARE_DESC[$software_id]='open-source home automation platform' + aSOFTWARE_DESC[$software_id]='Open source home automation platform' aSOFTWARE_CATX[$software_id]=17 aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/home_automation/#domoticz' #------------------ @@ -4466,8 +4466,8 @@ _EOF_ [[ -f '/etc/mopidy/mopidy.conf' ]] || dps_index=$software_id Download_Install 'mopidy.conf' /etc/mopidy/mopidy.conf # Official repo does not support ARMv8 + Stretch, using distro repo instead: https://github.com/mopidy/apt/tree/master/dists/stretch/main - if (( $G_HW_ARCH != 3 || $G_DISTRO > 4 )); then - + if (( $G_HW_ARCH != 3 || $G_DISTRO > 4 )) + then # APT key local url='https://apt.mopidy.com/mopidy.gpg' G_CHECK_URL "$url" @@ -4476,24 +4476,60 @@ _EOF_ # APT list G_EXEC curl -sSfL "https://apt.mopidy.com/${G_DISTRO_NAME/bullseye/buster}.list" -o /etc/apt/sources.list.d/mopidy.list G_AGUP - fi # Stretch: Mopidy v2, pip2 and Mopidy-Local-Images - if (( $G_DISTRO < 5 )); then - + if (( $G_DISTRO < 5 )) + then G_AGI mopidy gstreamer1.0-alsa python-pip python-dev G_EXEC_OUTPUT=1 G_EXEC pip2 install -U pip setuptools wheel G_EXEC_OUTPUT=1 G_EXEC pip2 install -U Mopidy-MusicBox-Webclient Mopidy-Local-Images # Buster+: Mopidy v3, pip3 (ID=130) and mopidy-local: https://mopidy.com/ext/local/ else - G_AGI mopidy gstreamer1.0-alsa mopidy-local G_EXEC_OUTPUT=1 G_EXEC pip3 install -U Mopidy-MusicBox-Webclient + fi + # 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\]' + G_CONFIG_INJECT 'cache_dir[[:blank:]]*=' 'cache_dir = /mnt/dietpi_userdata/mopidy/cache' /etc/mopidy/mopidy.conf '\[core\]' + + # Move existing home+data to dietpi_userdata, if not yet existent + if [[ -d '/var/lib/mopidy' && ! -d '/mnt/dietpi_userdata/mopidy' ]] + then + G_EXEC mv /var/lib/mopidy /mnt/dietpi_userdata/mopidy + # Workaround error about moving data dir into itself + G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/.hidden_data + # Non-hidden files/folders are data + G_EXEC mv /mnt/dietpi_userdata/mopidy/* /mnt/dietpi_userdata/mopidy/.hidden_data + G_EXEC mv /mnt/dietpi_userdata/mopidy/.hidden_data /mnt/dietpi_userdata/mopidy/data + else + G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/data + [[ -d '/var/lib/mopidy' ]] && G_EXEC rm -R /var/lib/mopidy fi + # Move existing cache to dietpi_userdata, if not yet existent + if [[ -d '/var/cache/mopidy' && ! -d '/mnt/dietpi_userdata/mopidy/cache' ]] + then + G_EXEC mv /var/cache/mopidy /mnt/dietpi_userdata/mopidy/cache + else + G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/cache + [[ -d '/var/cache/mopidy' ]] && G_EXEC rm -R /var/cache/mopidy + fi + + # Permissions + G_EXEC chown -R mopidy:root /mnt/dietpi_userdata/mopidy + + # User + G_EXEC usermod -g dietpi -aG audio -d /mnt/dietpi_userdata/mopidy mopidy + + # Do not pre-create obsolete cache dir + G_EXEC mkdir -p /etc/systemd/system/mopidy.service.d + echo -e '[Service]\nExecStartPre=' > /etc/systemd/system/mopidy.service.d/dietpi.conf + + Download_Test_Media + fi software_id=31 # Kodi @@ -10175,58 +10211,6 @@ audio_output { _EOF_ fi - software_id=118 # Mopidy - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # 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\]' - G_CONFIG_INJECT 'cache_dir[[:blank:]]*=' 'cache_dir = /mnt/dietpi_userdata/mopidy/cache' /etc/mopidy/mopidy.conf '\[core\]' - - # Move existing home+data to dietpi_userdata, if not yet existent - if [[ -d '/var/lib/mopidy' && ! -d '/mnt/dietpi_userdata/mopidy' ]]; then - - G_EXEC mv /var/lib/mopidy /mnt/dietpi_userdata/mopidy - # Workaround error about moving data dir into itself - G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/.hidden_data - # Non-hidden files/folders are data - G_EXEC mv /mnt/dietpi_userdata/mopidy/* /mnt/dietpi_userdata/mopidy/.hidden_data - G_EXEC mv /mnt/dietpi_userdata/mopidy/.hidden_data /mnt/dietpi_userdata/mopidy/data - - else - - G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/data - [[ -d '/var/lib/mopidy' ]] && rm -R /var/lib/mopidy - - fi - - # Move existing cache to dietpi_userdata, if not yet existent - if [[ -d '/var/cache/mopidy' && ! -d '/mnt/dietpi_userdata/mopidy/cache' ]]; then - - G_EXEC mv /var/cache/mopidy /mnt/dietpi_userdata/mopidy/cache - - else - - G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/cache - [[ -d '/var/cache/mopidy' ]] && rm -R /var/cache/mopidy - - fi - - # Permissions - G_EXEC chown -R mopidy:root /mnt/dietpi_userdata/mopidy - - # User - G_EXEC usermod -g dietpi -aG audio -d /mnt/dietpi_userdata/mopidy mopidy - - # Do not pre-create obsolete cache dir - G_EXEC mkdir -p /etc/systemd/system/mopidy.service.d - echo -e '[Service]\nExecStartPre=' > /etc/systemd/system/mopidy.service.d/dietpi.conf - - Download_Test_Media - - fi - software_id=39 # ReadyMedia if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -14462,14 +14446,15 @@ _EOF_ Banner_Uninstalling G_AGP 'mopidy*' - [[ -f '/etc/apt/sources.list.d/mopidy.list' ]] && rm /etc/apt/sources.list.d/mopidy.list + [[ -f '/etc/apt/sources.list.d/mopidy.list' ]] && G_EXEC rm /etc/apt/sources.list.d/mopidy.list + [[ -f '/etc/apt/trusted.gpg.d/dietpi-mopidy.gpg' ]] && G_EXEC rm /etc/apt/trusted.gpg.d/dietpi-mopidy.gpg command -v pip2 > /dev/null && pip2 uninstall -y Mopidy-MusicBox-Webclient Mopidy-Local-Images command -v pip3 > /dev/null && pip3 uninstall -y Mopidy-MusicBox-Webclient - getent passwd mopidy > /dev/null && userdel mopidy - [[ -d '/mnt/dietpi_userdata/mopidy' ]] && rm -R /mnt/dietpi_userdata/mopidy - [[ -d '/etc/systemd/system/mopidy.service.d' ]] && rm -R /etc/systemd/system/mopidy.service.d + getent passwd mopidy > /dev/null && G_EXEC userdel mopidy + [[ -d '/mnt/dietpi_userdata/mopidy' ]] && G_EXEC rm -R /mnt/dietpi_userdata/mopidy + [[ -d '/etc/systemd/system/mopidy.service.d' ]] && G_EXEC rm -R /etc/systemd/system/mopidy.service.d fi @@ -17300,8 +17285,8 @@ We allow it to take up to 30 minutes, it's process can be followed, please be pa # 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. Meanwhile you might want to participate the discussion about reducing (re)install times, by skipping Python rebuild or installing everything outside of the pyenv environment: - - https://github.com/MichaIng/DietPi/issues/2374' +\nPlease be patient. In the meantime you may study the documentation: + - https://dietpi.com/docs/software/home_automation/#home-assistant' fi From 38f4aa93149443a4d5d88fa81343b3bc38af4a63 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 5 Nov 2021 01:41:31 +0100 Subject: [PATCH 77/82] v7.8 + DietPi-Software | Merge all install and config code blocks --- dietpi/dietpi-software | 13336 +++++++++++++++++++-------------------- 1 file changed, 6381 insertions(+), 6955 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 47bc8229e9..d62d1b1a4c 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -3432,6 +3432,8 @@ _EOF_ G_AGI wmaker gnustep gnustep-devel gnustep-games upower policykit-1 xterm + Create_Desktop_Shared_Items + fi software_id=25 # Xfce @@ -3444,6 +3446,11 @@ _EOF_ G_AGI xfce4 xfce4-terminal gnome-icon-theme tango-icon-theme upower policykit-1 + Create_Desktop_Shared_Items + + # Composition manager: Xfce has one integrated with xfwm4, which is blocked by xcompmgr, breaking settings and leading to ugly results: https://github.com/MichaIng/DietPi/issues/3665 + [[ -f '/etc/xdg/autostart/xcompmgr.desktop' ]] && G_EXEC rm /etc/xdg/autostart/xcompmgr.desktop + fi software_id=22 # QuiteRSS @@ -3505,8 +3512,42 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing + G_AGI 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 + + # 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 + + # Apply optimised settings + G_CONFIG_INJECT '"cache-size-mb"' ' "cache-size-mb": '"$(Optimise_BitTorrent 0)"',' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"download-queue-size"' ' "download-queue-size": '"$(Optimise_BitTorrent 1)"',' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"peer-limit-global"' ' "peer-limit-global": '"$(Optimise_BitTorrent 2)"',' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"upload-slots-per-torrent"' ' "upload-slots-per-torrent": '"$(Optimise_BitTorrent 3)"',' /etc/transmission-daemon/settings.json '^\{$' + + G_CONFIG_INJECT '"port-forwarding-enabled"' ' "port-forwarding-enabled": true,' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"encryption"' ' "encryption": 2,' /etc/transmission-daemon/settings.json '^\{$' + + G_CONFIG_INJECT '"idle-seeding-limit"' ' "idle-seeding-limit": 1,' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"idle-seeding-limit-enabled"' ' "idle-seeding-limit-enabled": true,' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"ratio-limit"' ' "ratio-limit": 1.1,' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"ratio-limit-enabled"' ' "ratio-limit-enabled": true,' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"trash-original-torrent-files"' ' "trash-original-torrent-files": true,' /etc/transmission-daemon/settings.json '^\{$' + + G_CONFIG_INJECT '"download-dir"' ' "download-dir": "/mnt/dietpi_userdata/downloads",' /etc/transmission-daemon/settings.json '^\{$' + # - Double quotes need to be escaped in .json files: https://github.com/MichaIng/DietPi/issues/2484#issuecomment-481374924 + # - ToDo: Hash password directly. Which hash method is used? + GCI_PASSWORD=1 G_CONFIG_INJECT '"rpc-password"' ' "rpc-password": "'"${GLOBAL_PW//\"/\\\"}"'",' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"rpc-username"' ' "rpc-username": "root",' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"rpc-whitelist-enabled"' ' "rpc-whitelist-enabled": false,' /etc/transmission-daemon/settings.json '^\{$' + G_CONFIG_INJECT '"message-level"' ' "message-level": 0,' /etc/transmission-daemon/settings.json '^\{$' + + # To allow access for download managers and media software, files need to be created with 77X/66X permissions. + G_CONFIG_INJECT '"umask"' ' "umask": 7,' /etc/transmission-daemon/settings.json '^\{$' + fi software_id=94 # ProFTPD @@ -3517,6 +3558,16 @@ _EOF_ G_EXEC eval "debconf-set-selections <<< 'proftpd-basic shared/proftpd/inetd_or_standalone select standalone'" G_AGI proftpd-basic + # Config + G_BACKUP_FP /etc/proftpd/proftpd.conf + dps_index=$software_id Download_Install 'conf' /etc/proftpd/proftpd.conf + + # Do not allow root access via FTP + G_EXEC sed -i 's/^[[:blank:]]*root/#root/' /etc/ftpusers + + # Bullseye: Fix ident lookup: https://github.com/MichaIng/DietPi/issues/4666 + (( $G_DISTRO < 6 )) || G_EXEC sed -i '/IdentLookups/c\\nIdentLookups off\n' /etc/proftpd/proftpd.conf + fi software_id=96 # Samba Server @@ -3536,6 +3587,14 @@ _EOF_ G_AGI samba + echo -e "$GLOBAL_PW\n$GLOBAL_PW" | smbpasswd -s -a dietpi + + local fp_conf='/etc/samba/smb.conf' + G_BACKUP_FP $fp_conf + dps_index=$software_id Download_Install 'conf' $fp_conf + + G_CONFIG_INJECT 'max connections =' "max connections = $(( $G_HW_CPU_CORES * 2 ))" $fp_conf + fi software_id=95 # vsftpd @@ -3544,14 +3603,25 @@ _EOF_ Banner_Installing G_AGI vsftpd + # Config + G_BACKUP_FP /etc/vsftpd.conf + dps_index=$software_id Download_Install 'conf' /etc/vsftpd.conf + + # Do not allow root access via FTP + G_EXEC sed -i 's/^[[:blank:]]*root/#root/' /etc/ftpusers + fi software_id=109 # NFS Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing + G_AGI 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 + fi software_id=83 # Apache @@ -3567,6 +3637,32 @@ _EOF_ (( ${aSOFTWARE_INSTALL_STATE[92]} == 2 )) && apackages+=('python3-certbot-apache') G_AGI "${apackages[@]}" + # 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 + +_EOF_ + # Webroot + [[ -f '/var/www/html/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 @@ -3582,6 +3678,24 @@ _EOF_ (( ${aSOFTWARE_INSTALL_STATE[92]} == 2 )) && apackages+=('python3-certbot-nginx') G_AGI "${apackages[@]}" + # Custom configs, included by sites-enabled/default within server directive, while nginx/(conf.d|sites-enabled) is included by nginx.conf outside server directive + G_EXEC mkdir -p /etc/nginx/sites-dietpi + + G_BACKUP_FP /etc/nginx/nginx.conf + dps_index=$software_id Download_Install 'nginx.conf' /etc/nginx/nginx.conf + # Adjust socket name to PHP version + G_EXEC sed -i "s#/run/php/php.*-fpm.sock#/run/php/$PHP_NAME-fpm.sock#g" /etc/nginx/nginx.conf + + # CPU core count + G_EXEC sed -i "/worker_processes/c\worker_processes $G_HW_CPU_CORES;" /etc/nginx/nginx.conf + + # Default site + dps_index=$software_id Download_Install 'nginx.default' /etc/nginx/sites-available/default + + # Webroot + [[ -f '/var/www/html/index.nginx-debian.html' ]] && G_EXEC mv /var/www/html/index.nginx-debian.html /var/www/ + [[ -d '/var/www/html' ]] && G_EXEC rmdir --ignore-fail-on-non-empty /var/www/html + fi software_id=84 # Lighttpd @@ -3731,11 +3845,21 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing + local apackages=('redis-server') # Install PHP module, if PHP was already installed (( ${aSOFTWARE_INSTALL_STATE[89]} == 2 )) && apackages+=("$PHP_NAME-redis") G_AGI "${apackages[@]}" + # Enable redis php module, if installed + phpenmod redis 2> /dev/null + + # Disable file logging and enable syslog instead, which resolves reported startup issues in cases as well: https://github.com/MichaIng/DietPi/issues/3291 + G_CONFIG_INJECT 'loglevel[[:blank:]]' 'loglevel warning' /etc/redis/redis.conf + G_CONFIG_INJECT 'logfile[[:blank:]]' 'logfile ""' /etc/redis/redis.conf + G_CONFIG_INJECT 'syslog-enabled[[:blank:]]' 'syslog-enabled yes' /etc/redis/redis.conf + (( $G_DISTRO < 5 )) || G_CONFIG_INJECT 'always-show-logo[[:blank:]]' 'always-show-logo no' /etc/redis/redis.conf + fi software_id=89 # PHP @@ -3812,6 +3936,82 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et G_AGI "${apackages[@]}" + # 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 + + # 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 + + 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 + + # File uploads: https://github.com/MichaIng/DietPi/issues/546 + # - This is especially relevant for cloud software like ownCloud/Nextcloud. + # - Generally we want to hold tmp upload files in RAM to reduce disk (especially SD card) writes for performance and disk wear reasons. + # - By default only max 2 MiB file uploads are allowed, hold in /tmp tmpfs, which is safe but not usable for usual cloud usage. + # - 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 + # - 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 + # - 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 + # 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 + # - 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 + + # Enable all available PHP modules + local amodules=() + mapfile -t amodules < <(find "$FP_PHP_BASE_DIR/mods-available" -type f -name '*.ini' -printf '%f\n') + G_EXEC phpenmod "${amodules[@]%.ini}" + 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 + + # PHP info page + echo '' > /var/www/phpinfo.php + # OPcache info page + G_THREAD_START curl -sSfL https://raw.githubusercontent.com/amnuts/opcache-gui/master/index.php -o /var/www/opcache.php + # APCu info page + G_THREAD_START curl -sSfL https://raw.githubusercontent.com/krakjoe/apcu/master/apc.php -o /var/www/apc.php + + G_THREAD_WAIT + + fi + fi software_id=90 # phpMyAdmin @@ -3835,6 +4035,57 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et # - Move new instance in place G_EXEC mv "phpMyAdmin-$version-english" /var/www/phpmyadmin + # Enable required PHP modules: https://docs.phpmyadmin.net/en/latest/require.html#php + G_EXEC phpenmod ctype curl gd json mbstring xml zip + + # Install and enable webserver config + # - Apache + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + + dps_index=$software_id Download_Install 'apache.phpmyadmin.conf' /etc/apache2/sites-available/dietpi-phpmyadmin.conf + a2ensite dietpi-phpmyadmin + + # - Lighttpd + elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + + dps_index=$software_id Download_Install 'lighttpd.phpmyadmin.conf' /etc/lighttpd/conf-available/98-dietpi-phpmyadmin.conf + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod dietpi-phpmyadmin + + # - Nginx + elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + + dps_index=$software_id Download_Install 'nginx.phpmyadmin.conf' /etc/apache2/sites-dietpi/dietpi-phpmyadmin.conf + + fi + + # Copy default config in place and adjust, if not already existent + if [[ ! -f '/var/www/phpmyadmin/config.inc.php' ]]; then + + cp -a /var/www/phpmyadmin/config.sample.inc.php /var/www/phpmyadmin/config.inc.php + GCI_PASSWORD=1 G_CONFIG_INJECT "\\\$cfg\\['blowfish_secret'][[:blank:]]*=" "\$cfg['blowfish_secret'] = '$(openssl rand -base64 32)';" /var/www/phpmyadmin/config.inc.php + + fi + + # Create MariaDB database and user + if [[ -d '/mnt/dietpi_userdata/mysql/phpmyadmin' ]]; then + + G_DIETPI-NOTIFY 2 'phpMyAdmin MariaDB database found, will NOT overwrite.' + + else + + /boot/dietpi/func/create_mysql_db phpmyadmin phpmyadmin "$GLOBAL_PW" + mysql phpmyadmin < /var/www/phpmyadmin/sql/create_tables.sql + # Since "root" user cannot be used for login (unix_socket authentication), grant full admin privileges to "phpmyadmin" + mysql -e 'grant all privileges on *.* to phpmyadmin@localhost with grant option' + + fi + + # Pre-create TempDir: https://docs.phpmyadmin.net/en/latest/config.html#cfg_TempDir + [[ -d '/var/www/phpmyadmin/tmp' ]] || G_EXEC mkdir /var/www/phpmyadmin/tmp + G_EXEC chown www-data:root /var/www/phpmyadmin/tmp + G_EXEC chmod 700 /var/www/phpmyadmin/tmp + fi software_id=125 # Synapse @@ -4133,6 +4384,12 @@ _EOF_ fi + # Preserve old database name + [[ -d '/mnt/dietpi_userdata/mysql/phpbb3' ]] || /boot/dietpi/func/create_mysql_db phpbb phpbb "$GLOBAL_PW" + + # Permissions: The web-based installer writes setup and database access information to this file. Upload, cache and store directories are shipped with 777 modes already. + G_EXEC chown www-data /var/www/phpbb/config.php + fi software_id=58 # OpenBazaar @@ -4167,7 +4424,69 @@ _EOF_ G_EXEC_NOEXIT=1 G_EXEC rm -R .cache src bin fi - fi + # Init OB 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 + G_EXEC mkdir -p /mnt/dietpi_userdata/openbazaar + + G_EXEC_OUTPUT=1 G_EXEC openbazaar-go init -d /mnt/dietpi_userdata/openbazaar + + # Add current IP as gateway to allow external client connection + G_CONFIG_INJECT '"Gateway": "' " \"Gateway\": \"/ip4/$(G_GET_NET -4 ip)/tcp/4002\"," /mnt/dietpi_userdata/openbazaar/config + + # Client connection credentials + G_DIETPI-NOTIFY 2 "Please enter username and password for your ${aSOFTWARE_NAME[$software_id]} client connection:" + G_EXEC_OUTPUT=1 G_EXEC openbazaar-go setapicreds -d /mnt/dietpi_userdata/openbazaar + + # Client IP needs to be added to allowed IP list + local ob_client_ip= + local invalid_entry= + while : + do + if G_WHIP_INPUTBOX "${invalid_entry}Please enter the IP address of your ${aSOFTWARE_NAME[$software_id]} client machine +This is required, since the ${aSOFTWARE_NAME[$software_id]} server node by default does not allow any remote connection." && [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9.]+$ ]]; then + + ob_client_ip=$G_WHIP_RETURNED_VALUE + break + + else + + invalid_entry='[FAILED] Please enter a valid IP address\n\n' + + fi + done + G_CONFIG_INJECT '"AllowedIPs":' " \"AllowedIPs\": [\"$ob_client_ip\"]," /mnt/dietpi_userdata/openbazaar/config + + else + + G_DIETPI-NOTIFY 2 "Existing ${aSOFTWARE_NAME[$software_id]} config found. Skipping pre-configuration..." + + fi + + # User + Create_User -d /mnt/dietpi_userdata/openbazaar openbazaar + + # Service + cat << '_EOF_' > /etc/systemd/system/openbazaar.service +[Unit] +Description=OpenBazaar (DietPi) +Documentation=https://docs.openbazaar.org/ +Wants=network-online.target +After=network-online.target + +[Service] +User=openbazaar +WorkingDirectory=/mnt/dietpi_userdata/openbazaar +ExecStart=/usr/local/bin/openbazaar-go start -d /mnt/dietpi_userdata/openbazaar -f -l notice + +[Install] +WantedBy=multi-user.target +_EOF_ + # Permissions + G_EXEC chown -R openbazaar:openbazaar /mnt/dietpi_userdata/openbazaar + + fi software_id=133 # YaCy if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -4180,6 +4499,22 @@ _EOF_ Download_Install "https://download.yacy.net/$file" /etc + # Service + cat << '_EOF_' > /etc/systemd/system/yacy.service +[Unit] +Description=YaCy (DietPi) +Documentation=https://wiki.yacy.net/index.php/En:Start +Wants=network-online.target +After=network-online.target + +[Service] +Type=forking +ExecStart=/etc/yacy/startYACY.sh +ExecStop=/etc/yacy/stopYACY.sh + +[Install] +WantedBy=multi-user.target +_EOF_ fi software_id=186 # IPFS Node @@ -4210,6 +4545,48 @@ _EOF_ # Install G_EXEC_OUTPUT=1 G_EXEC go-ipfs/install.sh + # Data and config directory + [[ -d '/mnt/dietpi_userdata/ipfs' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/ipfs + + # User + Create_User -d /mnt/dietpi_userdata/ipfs ipfs + + # Service + cat << '_EOF_' > /etc/systemd/system/ipfs.service +[Unit] +Description=IPFS (DietPi) +Documentation=https://docs.ipfs.io/reference/go/api/ +Wants=network-online.target +After=network-online.target + +[Service] +User=ipfs +Environment=IPFS_PATH=/mnt/dietpi_userdata/ipfs +ExecStart=/usr/local/bin/ipfs daemon + +[Install] +WantedBy=multi-user.target +_EOF_ + # Config: Preserve existing on reinstall + if [[ ! -f '/mnt/dietpi_userdata/ipfs/config' ]]; then + + IPFS_PATH='/mnt/dietpi_userdata/ipfs' G_EXEC_OUTPUT=1 G_EXEC ipfs init + IPFS_PATH='/mnt/dietpi_userdata/ipfs' G_EXEC ipfs config --json Addresses.Gateway '"/ip4/0.0.0.0/tcp/8087"' + IPFS_PATH='/mnt/dietpi_userdata/ipfs' G_EXEC ipfs config --json Addresses.API '"/ip4/0.0.0.0/tcp/5003"' + IPFS_PATH='/mnt/dietpi_userdata/ipfs' G_EXEC ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' + + fi + + # Permissions + G_EXEC chown -R ipfs:ipfs /mnt/dietpi_userdata/ipfs + + # CLI alias + echo "alias ipfs='sudo -u ipfs IPFS_PATH=/mnt/dietpi_userdata/ipfs ipfs'" > /etc/bashrc.d/dietpi-ipfs.sh + + # Raise packet receive buffer: https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size + G_EXEC eval "echo 'net.core.rmem_max=2500000' > /etc/sysctl.d/dietpi-ipfs.conf" + G_EXEC sysctl -w net.core.rmem_max=2500000 + fi software_id=2 # Folding@Home @@ -4233,6 +4610,38 @@ _EOF_ Download_Install 'https://download.foldingathome.org/releases/public/release/fahclient/debian-stable-64bit/v7.6/latest.deb' fi + # Remove obsolete config + data directories and SysV service + config + [[ -d '/var/lib/fahclient' ]] && rm -R /var/lib/fahclient + [[ -d '/etc/fahclient' ]] && rm -R /etc/fahclient + [[ -f '/etc/default/fahclient' ]] && rm /etc/default/fahclient + Remove_SysV FAHClient + + # Prepare our new config + data directory if not yet present + if [[ ! -f '/mnt/dietpi_userdata/fahclient/config.xml' ]]; then + + G_EXEC mkdir -p /mnt/dietpi_userdata/fahclient + dps_index=$software_id Download_Install 'config.xml' /mnt/dietpi_userdata/fahclient/config.xml + + fi + + # Service + cat << _EOF_ > /etc/systemd/system/fahclient.service +[Unit] +Description=Folding@Home (DietPi) +Wants=network-online.target +After=network-online.target + +[Service] +User=fahclient +WorkingDirectory=/mnt/dietpi_userdata/fahclient +ExecStart=$(command -v FAHClient) + +[Install] +WantedBy=multi-user.target +_EOF_ + # Permissions + G_EXEC chown -R fahclient /mnt/dietpi_userdata/fahclient + fi software_id=47 # ownCloud @@ -4266,8806 +4675,7922 @@ _EOF_ [[ $DEPS_LIST ]] && { G_DIETPI-NOTIFY 2 'Installing required PHP modules'; G_AGI $DEPS_LIST; DEPS_LIST=''; } - fi - - software_id=114 # Nextcloud - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - DEPS_LIST="$PHP_NAME-intl" # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation + G_DIETPI-NOTIFY 2 'Enabling required PHP modules.' # https://doc.owncloud.org/server/administration_manual/installation/manual_installation.html#php-extensions + G_EXEC phpenmod ctype curl dom gd iconv intl json mbstring pdo_mysql posix simplexml xmlreader xmlwriter zip fileinfo opcache apcu redis exif - if [[ -f '/var/www/nextcloud/occ' ]]; then + G_DIETPI-NOTIFY 2 'Enabling APCu memory cache for PHP command line usage (CLI) as well, including ownCloud occ command and cron jobs.' + echo -e '; ownCloud PHP settings\n; priority=98\napc.enable_cli=1' > $FP_PHP_BASE_DIR/mods-available/dietpi-owncloud.ini + G_EXEC phpenmod dietpi-owncloud - G_DIETPI-NOTIFY 2 'Existing Nextcloud installation found, will NOT overwrite...' + # Get version string + 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 - else + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - local datadir=$(sed -n '/^[[:blank:]]*SOFTWARE_NEXTCLOUD_DATADIR=/{s/^[^=]*=//p;q}' /boot/dietpi.txt | sed 's|/$||') - [[ $datadir ]] || datadir='/mnt/dietpi_userdata/nextcloud_data' - if [[ -f $datadir/dietpi-nextcloud-installation-backup/occ ]]; then + G_DIETPI-NOTIFY 2 'Apache webserver found, enabling ownCloud specific configuration.' # https://doc.owncloud.org/server/administration_manual/installation/manual_installation.html#configure-apache-web-server + a2enmod rewrite headers env dir mime 1> /dev/null + local owncloud_conf='/etc/apache2/sites-available/dietpi-owncloud.conf' + if [[ -f $owncloud_conf ]]; then - G_DIETPI-NOTIFY 2 'Nextcloud installation backup found, starting recovery...' - G_EXEC cp -a "$datadir"/dietpi-nextcloud-installation-backup/. /var/www/nextcloud/ - # Correct config.php data directory entry, in case it changed due to server migration: - G_CONFIG_INJECT "'datadirectory'" "'datadirectory' => '$datadir'," /var/www/nextcloud/config/config.php "'dbtype'" + owncloud_conf+='.dietpi-new' + G_WHIP_MSG "Existing ownCloud Apache configuration found, will preserve the old one and save the new one for review and comparison to: $owncloud_conf" - else + fi + dps_index=$software_id Download_Install 'apache.owncloud.conf' $owncloud_conf + a2ensite dietpi-owncloud 1> /dev/null + # Cal/CardDAV redirects to ownCloud DAV endpoint + if [[ ! -f '/etc/apache2/conf-available/dietpi-dav_redirect.conf' ]]; then - Download_Install 'https://download.nextcloud.com/server/releases/latest.tar.bz2' /var/www + echo '# Redirect Cal/CardDAV requests to ownCloud endpoint: +Redirect 301 /.well-known/carddav /owncloud/remote.php/dav +Redirect 301 /.well-known/caldav /owncloud/remote.php/dav' > /etc/apache2/conf-available/dietpi-dav_redirect.conf + a2enconf dietpi-dav_redirect fi - fi + elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then - [[ $DEPS_LIST ]] && { G_DIETPI-NOTIFY 2 'Installing required PHP modules'; G_AGI $DEPS_LIST; DEPS_LIST=''; } + G_DIETPI-NOTIFY 2 'Lighttpd webserver found, enabling ownCloud specific configuration.' - fi + # Enable required modules + G_CONFIG_INJECT '"mod_access",' ' "mod_access",' /etc/lighttpd/lighttpd.conf '"mod_.+",' + G_CONFIG_INJECT '"mod_setenv",' ' "mod_setenv",' /etc/lighttpd/lighttpd.conf '"mod_.+",' - software_id=168 # Nextcloud Talk - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Move ownCloud configuration file in place and activate it + owncloud_conf='/etc/lighttpd/conf-available/99-dietpi-owncloud.conf' + if [[ -f $owncloud_conf ]]; then - Banner_Installing + owncloud_conf+='.dietpi-new' + G_WHIP_MSG "Existing ownCloud Lighttpd configuration found, will preserve the old one and save the new one for review and comparison to: $owncloud_conf" - # Install Coturn server only, install Nextcloud Talk app after Nextcloud has been fully configured - G_AGI coturn + fi + dps_index=$software_id Download_Install 'lighttpd.owncloud.conf' $owncloud_conf + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod rewrite dietpi-owncloud - fi + # Cal/CardDAV redirects to ownCloud DAV endpoint + if [[ ! -f '/etc/lighttpd/conf-enabled/99-dietpi-dav_redirect.conf' ]]; then - software_id=32 # ympd - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + echo '# Redirect Cal/CardDAV requests to ownCloud endpoint: +url.redirect += ( + "^/.well-known/caldav" => "/owncloud/remote.php/dav", + "^/.well-known/carddav" => "/owncloud/remote.php/dav" +)' > /etc/lighttpd/conf-available/99-dietpi-dav_redirect.conf + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod dietpi-dav_redirect - Banner_Installing + fi - Download_Install 'https://dietpi.com/downloads/binaries/all/ympd_1.2.3.7z' + elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - local binary_name='ympd_' - # ARMv6 - if (( $G_HW_ARCH == 1 )); then + G_DIETPI-NOTIFY 2 'Nginx webserver found, enabling ownCloud specific configuration.' # https://doc.owncloud.org/server/administration_manual/installation/nginx_configuration.html + local owncloud_conf='/etc/nginx/sites-dietpi/dietpi-owncloud.conf' + if [[ -f $owncloud_conf ]]; then - binary_name+='armv6' + owncloud_conf+='.dietpi-new' + G_WHIP_MSG "Existing ownCloud Nginx configuration found, will preserve the old one and save the new one for review and comparison to: $owncloud_conf" - # ARMv7 - elif (( $G_HW_ARCH == 2 )); then + fi + dps_index=$software_id Download_Install 'nginx.owncloud.conf' $owncloud_conf - binary_name+='armv7' + # Uncomment HSTS header, if chosen via dietpi-letsencrypt and HTTPS connection test succeeds (incl. self-singed cert => exit code 5) + if [[ -f '/boot/dietpi/.dietpi-letsencrypt' && $(mawk 'NR==4' /boot/dietpi/.dietpi-letsencrypt) == 1 ]]; then - # ARMv8 - elif (( $G_HW_ARCH == 3 )); then + wget -q --spider --timeout=10 --tries=2 https://localhost &> /dev/null + [[ $? == [05] ]] && sed -i 's/#add_header Strict-Transport-Security/add_header Strict-Transport-Security/g' $owncloud_conf - binary_name+='armv8' + fi - # x86_64 - elif (( $G_HW_ARCH == 10 )); then - - binary_name+='amd64' + # Disable pretty URLs (front controller) for ownCloud versions lower than 10: + (( $oc_version_major < 10 )) && sed -i 's/^[[:blank:]]*fastcgi_param front_controller_active true;/\t\t#fastcgi_param front_controller_active true;/g' $owncloud_conf - fi + # Cal/CardDAV redirects to ownCloud DAV endpoint + if [[ ! -f '/etc/nginx/sites-dietpi/dietpi-dav_redirect.conf' ]]; then - # We have no Buster binaries yet, so always use Stretch binaries - binary_name+='_stretch' + # shellcheck disable=SC2016 + echo '# Redirect Cal/CardDAV requests to ownCloud endpoint: +location = /.well-known/carddav { return 301 /owncloud/remote.php/dav/; } +location = /.well-known/caldav { return 301 /owncloud/remote.php/dav/; }' > /etc/nginx/sites-dietpi/dietpi-dav_redirect.conf - G_EXEC mv $binary_name /usr/bin/ympd - G_EXEC chmod +x /usr/bin/ympd - G_EXEC_NOEXIT=1 G_EXEC rm ympd_* + fi - fi + fi - software_id=148 # myMPD - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Start MariaDB and Redis (required for reinstalls) for database creation and occ command + G_EXEC systemctl restart mariadb + G_EXEC systemctl restart redis-server - Banner_Installing + # Initially add occ command shortcut, will be done by Dietpi-Globals automatically, if occ file exist: + occ(){ sudo -u www-data php /var/www/owncloud/occ "$@"; } - # Install dependencies: https://github.com/jcorporation/myMPD/blob/master/build.sh#L615-L616 - DEPS_LIST='make gcc cmake perl libc6-dev libssl-dev libid3tag0-dev libflac-dev liblua5.3-dev pkg-config libpcre3-dev' + # Adjusting config file: + local config_php='/var/www/owncloud/config/config.php' - # Download source - Download_Install 'https://github.com/jcorporation/myMPD/archive/master.tar.gz' + local datadir=$(sed -n '/^[[:blank:]]*SOFTWARE_OWNCLOUD_DATADIR=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + [[ $datadir ]] || datadir='/mnt/dietpi_userdata/owncloud_data' + G_EXEC mkdir -p "$datadir" + G_EXEC chown -R www-data:www-data /var/www/owncloud "$datadir" - # Build and install myMPD - G_EXEC cd myMPD-master - G_EXEC ./build.sh releaseinstall + if [[ -d '/mnt/dietpi_userdata/mysql/owncloud' ]]; then - # Cleanup - G_EXEC cd /tmp/$G_PROGRAM_NAME - G_EXEC_NOEXIT=1 G_EXEC rm -R myMPD-master + G_DIETPI-NOTIFY 2 'ownCloud database found, will NOT overwrite.' + if [[ ! -f $config_php ]]; then - # User: Switch to primary group "dietpi" to allow media access and create media files as "dietpi" group: https://github.com/MichaIng/DietPi/issues/3382 - G_EXEC usermod -g dietpi mympd - getent group mympd > /dev/null && G_EXEC_NOEXIT=1 G_EXEC groupdel mympd + G_WHIP_MSG '[WARNING] Existing ownCloud database was found, but no related install directory\n +A remaining MariaDB "owncloud" database from an earlier installed instance was found. But the related install directory "/var/www/owncloud/config/config.php" does not exist. +Since running a fresh install with an existing database can produce data corruption, if the versions do not exactly match, you either need to remove the database or find and place the related install directory.\n +We cannot predict your aim and do not want to mess or break your data, so please do this manually.\n +To remove the existing database (including e.g. contacts, calendar, file tags etc.): + # mysqladmin drop owncloud +Otherwise to copy an existing instance in place: + # rm -R /var/www/owncloud + # mkdir /var/www/owncloud + # cp -a /path/to/existing/owncloud/. /var/www/owncloud/ +The install script will now exit. After applying one of the the above, rerun dietpi-software, e.g.: + # dietpi-software install 47' - # Config: Create on fresh install - # - On reinstall /var/lib/mympd exists, so use its existence as reinstall flag - if [[ ! -d '/var/lib/mympd' ]] - then - export MYMPD_HTTP_PORT=1333 - export MYMPD_SSL=false - export MYMPD_MPD_HOST='/run/mpd/socket' - export MYMPD_LOGLEVEL=4 - G_EXEC mympd -c - G_EXEC mkdir -pm 0700 /var/lib/mympd/state - echo '/mnt/dietpi_userdata/Music' > /var/lib/mympd/state/playlist_directory - echo '/mnt/dietpi_userdata/Music' > /var/lib/mympd/state/music_directory - G_EXEC chmod 0600 /var/lib/mympd/state/* - G_EXEC chown -R mympd:dietpi /var/lib/mympd/state - fi + [[ -f '/var/www/owncloud/occ' ]] && G_EXEC rm /var/www/owncloud/occ + /boot/dietpi/dietpi-services start + exit 1 - # myMPD pre-v8.0.0 migration: Remove obsolete file - [[ -f '/etc/mympd.conf' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /etc/mympd.conf - [[ -f '/etc/mympd.conf.dist' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /etc/mympd.conf.dist - command -v mympd-config > /dev/null && G_EXEC rm "$(command -v mympd-config)" + fi - fi + elif [[ -f $datadir/dietpi-owncloud-database-backup.sql ]]; then - software_id=121 # Roon Bridge - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + G_DIETPI-NOTIFY 2 'ownCloud database backup found, starting recovery...' + local dbuser=$(grep -m1 "^[[:blank:]]*'dbuser'" $config_php | mawk -F\' '{print $4}') + local dbpass=$(grep -m1 "^[[:blank:]]*'dbpassword'" $config_php | mawk -F\' '{print $4}') + /boot/dietpi/func/create_mysql_db owncloud "$dbuser" "$dbpass" + mysql owncloud < "$datadir/dietpi-owncloud-database-backup.sql" + ### Seems to be not needed anymore and can cause double entries: https://help.nextcloud.com/t/howto-change-move-data-directory-after-installation/17170/3?u=michaing + # Adjust database data directory entry, in case it changed due to server migration: + #G_EXEC mysql -e "update owncloud.oc_storages set id='local::$datadir/' where id rlike 'local::'" - Banner_Installing + elif ! grep -q "'installed' => true," $config_php 2>/dev/null; then - # ARMv7 - local url='https://download.roonlabs.com/builds/RoonBridge_linuxarmv7hf.tar.bz2' + local username=$(sed -n '/^[[:blank:]]*SOFTWARE_OWNCLOUD_NEXTCLOUD_USERNAME=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + [[ $username ]] || username='admin' - # ARMv8 - if (( $G_HW_ARCH == 3 )) - then - url='https://download.roonlabs.com/builds/RoonBridge_linuxarmv8.tar.bz2' + # For MariaDB, temporary database admin user needs to be created, as 'root' uses unix_socket login, which cannot be accessed by sudo -u www-data. + # - Create random temporary alphanumeric 30 characters password + local oc_password=$(tr -dc '[:alnum:]' < /dev/random | head -c30) + # - Failsafe: Use non-blocking entropy source, if /dev/random fails + (( ${#oc_password} == 30 )) || oc_password=$(tr -dc '[:alnum:]' < /dev/urandom | head -c30) + G_EXEC mysql -e "grant all privileges on *.* to tmp_root@localhost identified by '$oc_password' with grant option" - # x86_64 - elif (( $G_HW_ARCH == 10 )) - then - url='https://download.roonlabs.com/builds/RoonBridge_linuxx64.tar.bz2' - fi + G_EXEC_DESC='ownCloud occ install' + # - Replace password strings internally to avoid printing it to console + G_EXEC_PRE_FUNC(){ acommand[10]=$oc_password acommand[14]=$GLOBAL_PW; } + # - Checking output for stack trace to handle internal errors that do not lead to php error exit code + G_EXEC_POST_FUNC(){ grep -qi 'Stack trace' $fp_log && exit_code=255; } + G_EXEC occ maintenance:install --no-interaction --database 'mysql' --database-name 'owncloud' --database-user 'tmp_root' --database-pass "${oc_password//?/X}" --admin-user "$username" --admin-pass "${GLOBAL_PW//?/X}" --data-dir "$datadir" + G_EXEC mysql -e 'drop user tmp_root@localhost' + unset -v oc_password - Download_Install "$url" + # Remove obsolete default data dir + [[ $(readlink -f "$datadir") != $(readlink -f /var/www/owncloud/data) ]] && G_EXEC rm -R /var/www/owncloud/data - # Clear dir on reinstall - [[ -d '/etc/roonbridge' ]] && G_EXEC rm -R /etc/roonbridge - G_EXEC mv RoonBridge /etc/roonbridge + fi - fi + # Enable ownCloud to use 4-byte database + G_CONFIG_INJECT "'mysql.utf8mb4'" "'mysql.utf8mb4' => true," $config_php "'dbpassword'" - software_id=119 # CAVA - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Add local IP and hostname to trusted domains. + # If "1 => '" does not exist, the config.php is not copied e.g. from older instance, so we add entries. + if ! grep -q "1 => '" $config_php; then - Banner_Installing + sed -i "/0 => 'localhost'/a 1 => '$(G_GET_NET ip)'," $config_php + sed -i "/1 => '/a 2 => '$( 0 )); then - # ARMv8 - elif (( $G_HW_ARCH == 3 )); then + GCI_PRESERVE=1 G_CONFIG_INJECT "'htaccess.RewriteBase'" "'htaccess.RewriteBase' => '/owncloud'," $config_php "'overwrite.cli.url'" + occ maintenance:update:htaccess - url='https://dietpi.com/downloads/binaries/all/cava_0.6.1-1_arm64.deb' - # Using older binary for Odroid C2 due to: https://github.com/MichaIng/DietPi/issues/1340#issuecomment-393225267 - (( $G_HW_MODEL == 12 )) && url='https://dietpi.com/downloads/binaries/all/cava_0.4.2_arm64.deb' + fi - # x86_64 - elif (( $G_HW_ARCH == 10 )); then + # APCu Memcache + GCI_PRESERVE=1 G_CONFIG_INJECT "'memcache.local'" "'memcache.local' => '\\\\OC\\\\Memcache\\\\APCu'," $config_php "'version'" - url='https://dietpi.com/downloads/binaries/all/cava_0.6.1-1_amd64.deb' + # Redis for transactional file locking: + G_DIETPI-NOTIFY 2 'Enabling Redis for transactional file locking.' # https://doc.owncloud.org/server/administration_manual/configuration/server/caching_configuration.html#configuring-transactional-file-locking + local redis_conf='/etc/redis/redis.conf' + # - Enable Redis socket and grant www-data access to it + GCI_PRESERVE=1 G_CONFIG_INJECT 'unixsocket[[:blank:]]' 'unixsocket /run/redis/redis-server.sock' $redis_conf + G_CONFIG_INJECT 'unixsocketperm[[:blank:]]' 'unixsocketperm 770' $redis_conf + G_EXEC usermod -aG redis www-data + G_EXEC systemctl restart redis-server + # - Enable ownCloud to use Redis socket for transactional file locking: + G_CONFIG_INJECT "'filelocking.enabled'" "'filelocking.enabled' => true," $config_php "'memcache.local'" + local redis_sock=$(grep -m1 '^[[:blank:]]*unixsocket[[:blank:]]' $redis_conf | mawk '{print $2}') # Re-estimate in case of existing custom path + GCI_PRESERVE=1 GCI_NEWLINE=1 G_CONFIG_INJECT "'memcache.locking'" "'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis',\n'redis' => array ('host' => '$redis_sock', 'port' => 0,)," $config_php "'filelocking.enabled'" - fi + # Enable ownCloud background cron job: + # - v10.3 comes with new occ system:cron command: https://doc.owncloud.org/server/10.3/admin_manual/release_notes.html#changes-to-background-job-execution + local occ_command='occ system:cron' + (( $oc_version_major < 10 || ( $oc_version_major == 10 && $oc_version_minor < 3 ) )) && occ_command='cron.php' + 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 - G_THREAD_START curl -sSfL 'https://dietpi.com/downloads/binaries/all/cava.psf' -o /root/cava.psf # Font for nice bars + # Enable maintenance mode to allow handling by dietpi-services: + grep -q "^[[:blank:]]*'maintenance' => true," $config_php || occ maintenance:mode --on - DEPS_LIST='libpulse0 libfftw3-3 libncursesw5' Download_Install "$url" + # 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 fi - software_id=118 # Mopidy + software_id=114 # Nextcloud if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing + DEPS_LIST="$PHP_NAME-intl" # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation - # Install our config file only, if not yet existent, to preserve manual user config. - # - This needs to be done prior to APT install, since this would otherwise install a default config file as well. - [[ -f '/etc/mopidy/mopidy.conf' ]] || dps_index=$software_id Download_Install 'mopidy.conf' /etc/mopidy/mopidy.conf + if [[ -f '/var/www/nextcloud/occ' ]]; then - # Official repo does not support ARMv8 + Stretch, using distro repo instead: https://github.com/mopidy/apt/tree/master/dists/stretch/main - if (( $G_HW_ARCH != 3 || $G_DISTRO > 4 )) - then - # APT key - local url='https://apt.mopidy.com/mopidy.gpg' - G_CHECK_URL "$url" - G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-mopidy.gpg --yes" + G_DIETPI-NOTIFY 2 'Existing Nextcloud installation found, will NOT overwrite...' - # APT list - G_EXEC curl -sSfL "https://apt.mopidy.com/${G_DISTRO_NAME/bullseye/buster}.list" -o /etc/apt/sources.list.d/mopidy.list - G_AGUP - fi + else - # Stretch: Mopidy v2, pip2 and Mopidy-Local-Images - if (( $G_DISTRO < 5 )) - then - G_AGI mopidy gstreamer1.0-alsa python-pip python-dev - G_EXEC_OUTPUT=1 G_EXEC pip2 install -U pip setuptools wheel - G_EXEC_OUTPUT=1 G_EXEC pip2 install -U Mopidy-MusicBox-Webclient Mopidy-Local-Images + local datadir=$(sed -n '/^[[:blank:]]*SOFTWARE_NEXTCLOUD_DATADIR=/{s/^[^=]*=//p;q}' /boot/dietpi.txt | sed 's|/$||') + [[ $datadir ]] || datadir='/mnt/dietpi_userdata/nextcloud_data' + if [[ -f $datadir/dietpi-nextcloud-installation-backup/occ ]]; then - # Buster+: Mopidy v3, pip3 (ID=130) and mopidy-local: https://mopidy.com/ext/local/ - else - G_AGI mopidy gstreamer1.0-alsa mopidy-local - G_EXEC_OUTPUT=1 G_EXEC pip3 install -U Mopidy-MusicBox-Webclient - fi + G_DIETPI-NOTIFY 2 'Nextcloud installation backup found, starting recovery...' + G_EXEC cp -a "$datadir"/dietpi-nextcloud-installation-backup/. /var/www/nextcloud/ + # Correct config.php data directory entry, in case it changed due to server migration: + G_CONFIG_INJECT "'datadirectory'" "'datadirectory' => '$datadir'," /var/www/nextcloud/config/config.php "'dbtype'" - # 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\]' - G_CONFIG_INJECT 'cache_dir[[:blank:]]*=' 'cache_dir = /mnt/dietpi_userdata/mopidy/cache' /etc/mopidy/mopidy.conf '\[core\]' + else + + Download_Install 'https://download.nextcloud.com/server/releases/latest.tar.bz2' /var/www + + fi - # Move existing home+data to dietpi_userdata, if not yet existent - if [[ -d '/var/lib/mopidy' && ! -d '/mnt/dietpi_userdata/mopidy' ]] - then - G_EXEC mv /var/lib/mopidy /mnt/dietpi_userdata/mopidy - # Workaround error about moving data dir into itself - G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/.hidden_data - # Non-hidden files/folders are data - G_EXEC mv /mnt/dietpi_userdata/mopidy/* /mnt/dietpi_userdata/mopidy/.hidden_data - G_EXEC mv /mnt/dietpi_userdata/mopidy/.hidden_data /mnt/dietpi_userdata/mopidy/data - else - G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/data - [[ -d '/var/lib/mopidy' ]] && G_EXEC rm -R /var/lib/mopidy fi - # Move existing cache to dietpi_userdata, if not yet existent - if [[ -d '/var/cache/mopidy' && ! -d '/mnt/dietpi_userdata/mopidy/cache' ]] - then - G_EXEC mv /var/cache/mopidy /mnt/dietpi_userdata/mopidy/cache - else - G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/cache - [[ -d '/var/cache/mopidy' ]] && G_EXEC rm -R /var/cache/mopidy - fi - - # Permissions - G_EXEC chown -R mopidy:root /mnt/dietpi_userdata/mopidy - - # User - G_EXEC usermod -g dietpi -aG audio -d /mnt/dietpi_userdata/mopidy mopidy + [[ $DEPS_LIST ]] && { G_DIETPI-NOTIFY 2 'Installing required PHP modules'; G_AGI $DEPS_LIST; DEPS_LIST=''; } - # Do not pre-create obsolete cache dir - G_EXEC mkdir -p /etc/systemd/system/mopidy.service.d - echo -e '[Service]\nExecStartPre=' > /etc/systemd/system/mopidy.service.d/dietpi.conf + G_DIETPI-NOTIFY 2 'Enabling required PHP modules.' # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation + G_EXEC phpenmod ctype curl dom gd iconv intl json mbstring pdo_mysql posix simplexml xmlreader xmlwriter zip fileinfo opcache apcu redis exif - Download_Test_Media + 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 + G_EXEC phpenmod dietpi-nextcloud - fi + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - software_id=31 # Kodi - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + G_DIETPI-NOTIFY 2 'Apache webserver found, enabling Nextcloud specific configuration.' # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#apache-web-server-configuration + a2enmod rewrite headers env dir mime 1> /dev/null + local nextcloud_conf='/etc/apache2/sites-available/dietpi-nextcloud.conf' + if [[ -f $nextcloud_conf ]]; then - Banner_Installing + nextcloud_conf+='.dietpi-new' + G_WHIP_MSG "Existing Nextcloud Apache configuration found, will preserve the old one and save the new one for review and comparison to: $nextcloud_conf" - # CEC + NFS support - local apackages=() # Fixed package dependencies since Bullseye - if (( $G_DISTRO < 5 )) - then - apackages=('libcec4' 'libnfs8') + fi + dps_index=$software_id Download_Install 'apache.nextcloud.conf' $nextcloud_conf + a2ensite dietpi-nextcloud 1> /dev/null + # Cal/CardDAV redirects to Nextcloud DAV endpoint + if [[ ! -f '/etc/apache2/conf-available/dietpi-dav_redirect.conf' ]]; then - elif (( $G_DISTRO == 5 )) - then - apackages=('libcec4' 'libnfs12') - fi + echo '# Redirect Cal/CardDAV requests to Nextcloud endpoint: +Redirect 301 /.well-known/carddav /nextcloud/remote.php/dav +Redirect 301 /.well-known/caldav /nextcloud/remote.php/dav' > /etc/apache2/conf-available/dietpi-dav_redirect.conf + a2enconf dietpi-dav_redirect - # Odroids - if [[ $G_HW_MODEL == 1[0-9] ]]; then + fi - # Odroid C1/C2/N2/C4 - [[ $G_HW_MODEL == 1[0256] ]] && apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* aml-libs-odroid(,|$)' && apackages+=('aml-libs-odroid') + elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then - # Odroid C1 - if (( $G_HW_MODEL == 10 )) - then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali400-odroid(,|$)' && apackages+=('mali400-odroid') + G_DIETPI-NOTIFY 2 'Lighttpd webserver found, enabling Nextcloud specific configuration.' - # Odroid XU4 - elif (( $G_HW_MODEL == 11 )) - then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malit628-odroid(,|$)' && apackages+=('malit628-odroid') - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* firmware-samsung(,|$)' && apackages+=('firmware-samsung') + # Enable required modules + G_CONFIG_INJECT '"mod_access",' ' "mod_access",' /etc/lighttpd/lighttpd.conf '"mod_.+",' + G_CONFIG_INJECT '"mod_setenv",' ' "mod_setenv",' /etc/lighttpd/lighttpd.conf '"mod_.+",' - # Odroid C2 - elif (( $G_HW_MODEL == 12 )) - then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali450-odroid(,|$)' && apackages+=('mali450-odroid') + # Move Nextcloud configuration file in place and activate it + nextcloud_conf='/etc/lighttpd/conf-available/99-dietpi-nextcloud.conf' + if [[ -f $nextcloud_conf ]]; then - # Odroid N2 - elif (( $G_HW_MODEL == 15 )) - then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malig52-fbdev-opencl-odroid(,|$)' && apackages+=('malig52-fbdev-opencl-odroid') + nextcloud_conf+='.dietpi-new' + G_WHIP_MSG "Existing Nextcloud Lighttpd configuration found, will preserve the old one and save the new one for review and comparison to: $nextcloud_conf" - # Odroid C4 - elif (( $G_HW_MODEL == 16 )) - then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malig31-fbdev-opencl-odroid(,|$)' && apackages+=('malig31-fbdev-opencl-odroid') fi + dps_index=$software_id Download_Install 'lighttpd.nextcloud.conf' $nextcloud_conf + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod rewrite dietpi-nextcloud - # Odroid N2/C4 - if [[ $G_HW_MODEL == 1[56] ]] - then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* kodi-aml-fbdev-odroid(,|$)' && apackages+=('kodi-aml-fbdev-odroid') || apackages=('kodi') - echo 'media_clock -firmware -decoder_common -stream_input -amvdec_avs -amvdec_h264 -amvdec_h264_4k2k -amvdec_mh264 -amvdec_h264mvc -amvdec_h265 -amvdec_mjpeg -amvdec_mmjpeg -amvdec_mpeg12 -amvdec_mpeg4 -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 + # Cal/CardDAV redirects to Nextcloud DAV endpoint + if [[ ! -f '/etc/lighttpd/conf-enabled/99-dietpi-dav_redirect.conf' ]]; then + + echo '# Redirect Cal/CardDAV requests to Nextcloud endpoint: +url.redirect += ( + "^/.well-known/caldav" => "/nextcloud/remote.php/dav", + "^/.well-known/carddav" => "/nextcloud/remote.php/dav" +)' > /etc/lighttpd/conf-available/99-dietpi-dav_redirect.conf + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod dietpi-dav_redirect - # 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 -qE '^P(ackage|rovides):.* kodi-odroid(,|$)' && apackages+=('kodi-odroid') || apackages=('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-fkms-v3d - Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/kodi_$G_HW_ARCH_NAME.deb" + elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - # Everything else - else - apackages+=('kodi') + G_DIETPI-NOTIFY 2 'Nginx webserver found, enabling Nextcloud specific configuration.' # https://docs.nextcloud.com/server/stable/admin_manual/installation/nginx.html + local nextcloud_conf='/etc/nginx/sites-dietpi/dietpi-nextcloud.conf' + if [[ -f $nextcloud_conf ]]; then - # 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') + nextcloud_conf+='.dietpi-new' + G_WHIP_MSG "Existing Nextcloud Nginx configuration found, will preserve the old one and save the new one for review and comparison to: $nextcloud_conf" - # 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 + fi + dps_index=$software_id Download_Install 'nginx.nextcloud.conf' $nextcloud_conf - # Else legacy (non-GL) driver required - else - /boot/dietpi/func/dietpi-set_hardware rpi-opengl disable - fi + # Uncomment HSTS header, if chosen via dietpi-letsencrypt and HTTPS connection test succeeds (incl. self-singed cert => exit code 5) + if [[ -f '/boot/dietpi/.dietpi-letsencrypt' && $(mawk 'NR==4' /boot/dietpi/.dietpi-letsencrypt) == 1 ]]; then - # 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 + wget -q --spider --timeout=10 --tries=2 https://localhost &> /dev/null + [[ $? == [05] ]] && sed -i 's/#add_header Strict-Transport-Security/add_header Strict-Transport-Security/g' $nextcloud_conf - # 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 - fi - G_AGI "${apackages[@]}" + # Disable pretty URLs (front controller), if Nextcloud version is lower than 13 + if (( $(sed -n '/OC_VersionString/{s/^[^0-9]*//;s/\..*$//p;q}' /var/www/nextcloud/version.php) < 13 )); then - # 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 + sed -i 's/^[[:blank:]]*fastcgi_param front_controller_active true;/\t\t#fastcgi_param front_controller_active true;/g' $nextcloud_conf - # Copy udev rules, probably not needed for root, but we'll do it anyway - dps_index=$software_id Download_Install '99-dietpi-kodi.rules' /etc/udev/rules.d/99-dietpi-kodi.rules + fi - # Run Kodi as root - [[ -f '/etc/default/kodi' ]] && G_CONFIG_INJECT 'USER=' 'USER=root' /etc/default/kodi + # Cal/CardDAV redirects to Nextcloud DAV endpoint + if [[ ! -f '/etc/nginx/sites-dietpi/dietpi-dav_redirect.conf' ]]; then - # Remove Kodi user (Whilst waving) - getent passwd kodi > /dev/null && G_EXEC userdel kodi + # shellcheck disable=SC2016 + echo '# Redirect Cal/CardDAV requests to Nextcloud endpoint: +location = /.well-known/carddav { return 301 /nextcloud/remote.php/dav/; } +location = /.well-known/caldav { return 301 /nextcloud/remote.php/dav/; }' > /etc/nginx/sites-dietpi/dietpi-dav_redirect.conf - G_THREAD_WAIT + fi - # Desktop shortcut - Create_Desktop_Shortcut kodi + fi - fi + # Start MariaDB and Redis (required for reinstalls) for database creation and ncc command + G_EXEC systemctl restart mariadb + G_EXEC systemctl restart redis-server - software_id=39 # ReadyMedia - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Initially add occ command shortcut, will be done by Dietpi-Globals automatically, if occ file exist: + ncc(){ sudo -u www-data php /var/www/nextcloud/occ "$@"; } - Banner_Installing - G_AGI minidlna + # Adjusting config file: + local config_php='/var/www/nextcloud/config/config.php' - fi + local datadir=$(sed -n '/^[[:blank:]]*SOFTWARE_NEXTCLOUD_DATADIR=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + [[ $datadir ]] || datadir='/mnt/dietpi_userdata/nextcloud_data' + G_EXEC mkdir -p "$datadir" + G_EXEC chown -R www-data:www-data /var/www/nextcloud "$datadir" - software_id=108 # Amiberry - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + if [[ -d '/mnt/dietpi_userdata/mysql/nextcloud' ]]; then - Banner_Installing + G_DIETPI-NOTIFY 2 'Nextcloud database found, will NOT overwrite.' + if [[ ! -f $config_php ]]; then - # Libraries - # - wget: Used for WHDLoad database update: https://github.com/midwan/amiberry/commit/d6c103e3310bcf75c2d72a15849fbdf5eb7432b5 - DEPS_LIST='libxml2 libfreetype6 libflac8 libmpeg2-4 libmpg123-0 wget' # libpng16-16 pulled by libfreetype6 + G_WHIP_MSG '[WARNING] Existing Nextcloud database was found, but no related install directory\n +A remaining MariaDB "nextcloud" database from an earlier installed instance was found. But the related install directory "/var/www/nextcloud/config/config.php" does not exist. +Since running a fresh install with an existing database can produce data corruption, if the versions do not exactly match, you either need to remove the database or find and place the related install directory.\n +We cannot predict your aim and do not want to mess or break your data, so please do this manually.\n +To remove the existing database (including e.g. contacts, calendar, file tags etc.): + # mysqladmin drop nextcloud +Otherwise to copy an existing instance in place: + # rm -R /var/www/nextcloud + # mkdir /var/www/nextcloud + # cp -a /path/to/existing/nextcloud/. /var/www/nextcloud/ +The install script will now exit. After applying one of the the above, rerun dietpi-software, e.g.: + # dietpi-software install 114' - # Platform and GPU drivers - # - RPi - if (( $G_HW_MODEL < 10 )); then + [[ -f '/var/www/nextcloud/occ' ]] && G_EXEC rm /var/www/nextcloud/occ + /boot/dietpi/dietpi-services start + exit 1 - local platform='rpi1' # Include ID -1 + 0 - (( $G_HW_MODEL > 1 )) && platform="rpi$G_HW_MODEL" - /boot/dietpi/func/dietpi-set_hardware rpi-opengl vc4-fkms-v3d - DEPS_LIST+=' libraspberrypi0' + fi - # - Odroid XU4: https://dietpi.com/meveric/pool/main/s/setup-odroid/ - elif (( $G_HW_MODEL == 11 )); then + elif [[ -f $datadir/dietpi-nextcloud-database-backup.sql ]]; then - local platform='xu4' - DEPS_LIST+=' malit628-odroid' + G_DIETPI-NOTIFY 2 'Nextcloud database backup found, starting recovery...' + local dbuser=$(grep -m1 "^[[:blank:]]*'dbuser'" $config_php | mawk -F\' '{print $4}') + local dbpass=$(grep -m1 "^[[:blank:]]*'dbpassword'" $config_php | mawk -F\' '{print $4}') + /boot/dietpi/func/create_mysql_db nextcloud "$dbuser" "$dbpass" + mysql nextcloud < "$datadir/dietpi-nextcloud-database-backup.sql" + ### Seems to be not needed anymore and can cause double entries: https://help.nextcloud.com/t/howto-change-move-data-directory-after-installation/17170/3?u=michaing + # Adjust database data directory entry, in case it changed due to server migration: + #G_EXEC mysql -e "update nextcloud.oc_storages set id='local::$datadir/' where id rlike 'local::'" - # - ASUS Tinker Board - elif (( $G_HW_MODEL == 52 )); then - - local platform='RK3288' - DEPS_LIST+=' libegl1 libgles2 libgl1-mesa-dri' + elif ! grep -q "'installed' => true," $config_php 2>/dev/null; then - fi + local username=$(sed -n '/^[[:blank:]]*SOFTWARE_OWNCLOUD_NEXTCLOUD_USERNAME=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + [[ $username ]] || username='admin' - # Download Amiberry - Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/amiberry_$platform.tar.bz2" + # For MariaDB, temporary database admin user needs to be created, as 'root' uses unix_socket login, which cannot be accessed by sudo -u www-data. + # - Create random temporary alphanumeric 30 characters password + local nc_password=$(tr -dc '[:alnum:]' < /dev/random | head -c30) + # - Failsafe: Use non-blocking entropy source, if /dev/random fails + (( ${#nc_password} == 30 )) || nc_password=$(tr -dc '[:alnum:]' < /dev/urandom | head -c30) + G_EXEC mysql -e "grant all privileges on *.* to tmp_root@localhost identified by '$nc_password' with grant option" - # Reinstall: Install new amiberry.conf as amiberry.conf_new, to preserve user settings and remove obsolete config file: https://github.com/midwan/amiberry/releases/tag/v2.25 - [[ -f '/mnt/dietpi_userdata/amiberry/conf/amiberry.conf' ]] && G_EXEC mv amiberry/conf/amiberry.conf /mnt/dietpi_userdata/amiberry/conf/amiberry.conf_new - [[ -f '/mnt/dietpi_userdata/amiberry/conf/adfdir.conf' ]] && G_EXEC rm /mnt/dietpi_userdata/amiberry/conf/adfdir.conf + G_EXEC_DESC='Nextcloud ncc install' + # - Replace password strings internally to avoid printing it to console + G_EXEC_PRE_FUNC(){ acommand[10]=$nc_password acommand[14]=$GLOBAL_PW; } + # - Checking output for stack trace to handle internal errors that do not lead to php error exit code + # - Workaround Nextcloud 14.0.3 throwing an error, when data dir path contains a symlink: https://github.com/nextcloud/server/issues/12247 + G_EXEC_POST_FUNC(){ - # Move/Merge new instance in place - G_EXEC cp -a amiberry /mnt/dietpi_userdata/ + if (( $exit_code )); then - # Cleanup - G_EXEC_NOHALT=1 G_EXEC rm -R amiberry + grep -q 'Following symlinks is not allowed' $fp_log && { cp -a /var/www/nextcloud/core/skeleton/. "$datadir/$username/files/"; exit_code=0; } - # Service - cat << '_EOF_' > /etc/systemd/system/amiberry.service -[Unit] -Description=Amiberry Amiga Emulator (DietPi) -Documentation=https://github.com/midwan/amiberry/wiki + else -[Service] -WorkingDirectory=/mnt/dietpi_userdata/amiberry -Environment=LD_LIBRARY_PATH=/mnt/dietpi_userdata/amiberry/lib -ExecStartPre=/bin/chvt 3 -ExecStart=/mnt/dietpi_userdata/amiberry/amiberry -ExecStopPost=/bin/chvt 1 + grep -qi 'Stack trace' $fp_log && exit_code=255 -[Install] -WantedBy=local-fs.target -_EOF_ - # Permissions: Enable access for kickstart uploads via file servers - G_EXEC chgrp dietpi /mnt/dietpi_userdata/amiberry/kickstarts - G_EXEC chmod 0775 /mnt/dietpi_userdata/amiberry/kickstarts + fi - fi + } + G_EXEC ncc maintenance:install --no-interaction --database 'mysql' --database-name 'nextcloud' --database-user 'tmp_root' --database-pass "${nc_password//?/X}" --admin-user "$username" --admin-pass "${GLOBAL_PW//?/X}" --data-dir "$datadir" + G_EXEC mysql -e 'drop user tmp_root@localhost' + unset -v nc_password - software_id=112 # DXX-Rebirth - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Remove obsolete default data dir + [[ $(readlink -f "$datadir") != $(readlink -f /var/www/nextcloud/data) ]] && G_EXEC rm -R /var/www/nextcloud/data - Banner_Installing + fi - DEPS_LIST='libsdl-mixer1.2 libsdl1.2debian libphysfs1' - Download_Install 'https://dietpi.com/downloads/binaries/rpi/dxx-rebirth.7z' /mnt/dietpi_userdata + # Enable Nextcloud to use 4-byte database + G_CONFIG_INJECT "'mysql.utf8mb4'" "'mysql.utf8mb4' => true," $config_php "'dbpassword'" - fi + # Disable trusted_domains. + grep -q "1 => '*'" $config_php || sed -i "/0 => 'localhost'/a 1 => '*'," $config_php - software_id=111 # UrBackup Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Set CLI URL to Nextcloud sub directory: + G_EXEC sed -i "s|'http://localhost'|'http://localhost/nextcloud'|" $config_php - Banner_Installing + # Set pretty URLs (without /index.php/) on Apache: + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - # Grab latest version - local url='https://hndl.urbackup.org/Server/latest' - G_CHECK_URL "$url" + GCI_PRESERVE=1 G_CONFIG_INJECT "'htaccess.RewriteBase'" "'htaccess.RewriteBase' => '/nextcloud'," $config_php "'overwrite.cli.url'" + ncc maintenance:update:htaccess - # Latest known version - local latest='2.4.13' + fi - # 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) + # APCu Memcache + GCI_PRESERVE=1 G_CONFIG_INJECT "'memcache.local'" "'memcache.local' => '\\\\OC\\\\Memcache\\\\APCu'," $config_php "'version'" - # ARMv8 - if (( $G_HW_ARCH == 3 )); then + # Redis for transactional file locking: + G_DIETPI-NOTIFY 2 'Enabling Redis for transactional file locking.' # https://docs.nextcloud.com/server/stable/admin_manual/configuration_files/files_locking_transactional.html + local redis_conf="/etc/redis/redis.conf" + # - Enable Redis socket and grant www-data access to it + GCI_PRESERVE=1 G_CONFIG_INJECT 'unixsocket[[:blank:]]' 'unixsocket /run/redis/redis-server.sock' $redis_conf + G_CONFIG_INJECT 'unixsocketperm[[:blank:]]' 'unixsocketperm 770' $redis_conf + G_EXEC usermod -aG redis www-data + G_EXEC systemctl restart redis-server + # - Enable Nextcloud to use Redis socket: + G_CONFIG_INJECT "'filelocking.enabled'" "'filelocking.enabled' => true," $config_php "'memcache.local'" + local redis_sock=$(grep -m1 '^[[:blank:]]*unixsocket[[:blank:]]' $redis_conf | mawk '{print $2}') # Re-estimate in case of existing custom path + GCI_PRESERVE=1 GCI_NEWLINE=1 G_CONFIG_INJECT "'memcache.locking'" "'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis',\n'redis' => array ('host' => '$redis_sock', 'port' => 0,)," $config_php "'filelocking.enabled'" - 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) + # Tweak Argon2 hashing + # - Use all available CPU threads + GCI_PRESERVE=1 G_CONFIG_INJECT "'hashingThreads'" "'hashingThreads' => ${G_HW_CPU_CORES}," $config_php "'version'" + # - ToDo: Configure the other settings after getting some clarifications: https://github.com/nextcloud/server/pull/19023#issuecomment-660071524 + #GCI_PRESERVE=1 G_CONFIG_INJECT "'hashingMemoryCost'" "'hashingMemoryCost' => 65536," $config_php "'hashingThreads'" + #GCI_PRESERVE=1 G_CONFIG_INJECT "'hashingTimeCost'" "'hashingTimeCost' => 4," $config_php "'hashingMemoryCost'" - # x86_64 - elif (( $G_HW_ARCH == 10 )); then + # Enable Nextcloud background cron job: https://docs.nextcloud.com/server/17/admin_manual/configuration_server/background_jobs_configuration.html#cron + crontab -u www-data -l 2> /dev/null | grep -q '/var/www/nextcloud/cron.php' || ( crontab -u www-data -l 2> /dev/null ; echo '*/5 * * * * php /var/www/nextcloud/cron.php' ) | crontab -u www-data - + ncc background:cron - 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) + # Convert filecache table to bigint, which is not done automatically by Nextcloud since v15 + ncc db:convert-filecache-bigint -n - fi + # Add missing database columns and indices, which is not done automatically by Nextcloud + ncc db:add-missing-columns + ncc db:add-missing-indices + ncc db:add-missing-primary-keys - [[ $file ]] && url="$url/$file" || url=$fallback_url - unset -v file fallback_url + # Enable maintenance mode to allow handling by dietpi-services: + grep -q "^[[:blank:]]*'maintenance' => true," $config_php || ncc maintenance:mode --on - debconf-set-selections <<< 'urbackup-server urbackup/backuppath string /mnt/dietpi_userdata/urbackup' - Download_Install "$url" + # 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 fi - software_id=51 # OpenTyrian + software_id=168 # Nextcloud Talk if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - DEPS_LIST='libsdl1.2debian libsdl-net1.2' - Download_Install 'https://dietpi.com/downloads/binaries/rpi/opentyrian_armhf.zip' / + # Install Coturn server only, install Nextcloud Talk app after Nextcloud has been fully configured + G_AGI coturn - # Move to /usr/games - G_EXEC cp -a /usr/local/games/opentyrian /usr/games/ - G_EXEC rm -R /usr/local/games/opentyrian - G_EXEC chmod +x /usr/games/opentyrian/opentyrian + G_DIETPI-NOTIFY 2 'Configuring TURN server:' + # Buster: systemd unit + if [[ -f '/lib/systemd/system/coturn.service' ]]; then - fi + Remove_SysV coturn 1 - software_id=59 # RPi Cam Control - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Disable Coturn logging by default, this can be overridden via /etc/turnserver.conf + 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 - Banner_Installing + # Stretch: sysvinit service + else - DEPS_LIST='gpac motion' - Download_Install 'https://github.com/silvanmelchior/RPi_Cam_Web_Interface/archive/master.tar.gz' + # Enable init.d service + G_CONFIG_INJECT 'TURNSERVER_ENABLED=' 'TURNSERVER_ENABLED=1' /etc/default/coturn + # Disable coturn logging by default, this can be overridden via /etc/turnserver.conf + G_CONFIG_INJECT 'DAEMON_ARGS=' "DAEMON_ARGS='-c /etc/turnserver.conf -o -l stdout --no-stdout-log --simple-log'" /etc/default/coturn - G_EXEC cd RPi_Cam_Web_Interface-master + fi - # Remove files which are not to be installed - [[ -f 'www/status_mjpeg.txt' ]] && G_EXEC rm www/status_mjpeg.txt + # Ask user for server domain and desired TURN server port + local invalid_text= + local domain=$(hostname -f) + while : + do + G_WHIP_DEFAULT_ITEM=$domain + if G_WHIP_INPUTBOX "${invalid_text}Please enter your servers external domain to allow Nextcloud Talk access your TURN server:" && [[ $G_WHIP_RETURNED_VALUE ]]; then - # Config /etc/motion/ - G_EXEC mkdir -p /etc/motion - G_EXEC cp etc/motion/motion.conf.1 /etc/motion/motion.conf + domain=${G_WHIP_RETURNED_VALUE#http*://} + break - # Config /etc/raspimjpeg - G_EXEC cp etc/raspimjpeg/raspimjpeg.1 /etc/raspimjpeg + else - # Setup /var/www/rpicam - G_EXEC mkdir -p /var/www/rpicam - G_EXEC cp -dR www/. /var/www/rpicam/ - [[ -e '/var/www/rpicam/FIFO' ]] || G_EXEC mknod /var/www/rpicam/FIFO p - [[ -e '/var/www/rpicam/FIFO1' ]] || G_EXEC mknod /var/www/rpicam/FIFO1 p + invalid_text='[ERROR] No valid entry found. Please retry...\n\n' - # Allow shutdown and reboot via web interface - G_EXEC cp etc/sudoers.d/RPI_Cam_Web_Interface /etc/sudoers.d/dietpi-rpi_cam_control + fi + done + invalid_text= + local port=3478 + while : + do + G_WHIP_DEFAULT_ITEM=$port + if G_WHIP_INPUTBOX "${invalid_text}Please enter the network port, that should be used for your TURN server:\n +NB: This port needs to be forwarded by your router and/or opened in your firewall settings. Default value is: 3478" && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 0; then - # Symlink cam preview and status - G_EXEC ln -sf /run/shm/mjpeg/cam.jpg /var/www/rpicam/cam.jpg - G_EXEC ln -sf /run/shm/mjpeg/status_mjpeg.txt /var/www/rpicam/status_mjpeg.txt + port=$G_WHIP_RETURNED_VALUE + break - # Setup Raspimjpeg binary - # - Use Stretch binary on Stretch - (( $G_DISTRO < 5 )) && G_EXEC mv bin/raspimjpeg{-stretch,} - G_EXEC cp {,/usr/local/}bin/raspimjpeg - G_EXEC chmod +x /usr/local/bin/raspimjpeg + else - # Cleanup / remove extracted source - G_EXEC cd /tmp/$G_PROGRAM_NAME - G_EXEC_NOFAIL=1 G_EXEC rm -R RPi_Cam_Web_Interface-master + invalid_text='[ERROR] No valid entry found, value needs to be a sequence of integers. Please retry...\n\n' - fi + fi + done - software_id=45 # Deluge - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Adjust coTURN settings + # - If /etc/turnserver.conf is not present, use default or create empty file + if [[ ! -f '/etc/turnserver.conf' ]]; then - Banner_Installing + # shellcheck disable=SC2015 + [[ -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 - # Packages - G_AGI deluged deluge-web deluge-console + fi + # - 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 + G_CONFIG_INJECT 'fingerprint' 'fingerprint' /etc/turnserver.conf + G_CONFIG_INJECT 'use-auth-secret' 'use-auth-secret' /etc/turnserver.conf + if (( $version < 4508 )); then - # Remove SysV service leftovers, installed by Debian APT package - Remove_SysV deluged 1 - [[ -d '/var/lib/deluged' ]] && G_EXEC rm -R /var/lib/deluged - [[ -d '/var/log/deluged' ]] && G_EXEC rm -R /var/log/deluged + G_CONFIG_INJECT 'lt-cred-mech' 'lt-cred-mech' /etc/turnserver.conf - # User - Create_User -g dietpi -G debian-deluged -d /mnt/dietpi_userdata/deluge debian-deluged + else - # Config - if [[ ! -f '/mnt/dietpi_userdata/deluge/.config/deluge/core.conf' ]] - then - [[ -d '/mnt/dietpi_userdata/deluge/.config/deluge' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/deluge/.config/deluge + sed -i 's/^[[:blank:]]*lt-cred-mech/#lt-cred-mech/' /etc/turnserver.conf - # Default configs - dps_index=$software_id Download_Install 'deluge.conf' /mnt/dietpi_userdata/deluge/.config/deluge/core.conf - dps_index=$software_id Download_Install 'deluge_web.conf' /mnt/dietpi_userdata/deluge/.config/deluge/web.conf + fi + G_CONFIG_INJECT 'realm=' "realm=$domain" /etc/turnserver.conf + GCI_PRESERVE=1 G_CONFIG_INJECT 'total-quota=' 'total-quota=100' /etc/turnserver.conf + GCI_PRESERVE=1 G_CONFIG_INJECT 'bps-capacity=' 'bps-capacity=0' /etc/turnserver.conf + G_CONFIG_INJECT 'stale-nonce' 'stale-nonce' /etc/turnserver.conf + if (( $version < 4510 )); then - # Apply optimised settings - # - Cache size in 16 KiB units - G_CONFIG_INJECT '"cache_size":' " \"cache_size\": $(( $(Optimise_BitTorrent 0) * 1024 / 16 ))," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf - G_CONFIG_INJECT '"max_active_limit":' " \"max_active_limit\": $(Optimise_BitTorrent 1)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf - G_CONFIG_INJECT '"max_active_downloading":' " \"max_active_downloading\": $(Optimise_BitTorrent 1)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf - G_CONFIG_INJECT '"max_connections_global":' " \"max_connections_global\": $(Optimise_BitTorrent 2)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf - G_CONFIG_INJECT '"max_upload_slots_global":' " \"max_upload_slots_global\": $(Optimise_BitTorrent 3)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf + G_CONFIG_INJECT 'no-loopback-peers' 'no-loopback-peers' /etc/turnserver.conf - # Web UI access - local salt=$(tr -dc '0-9a-f' < /dev/random | head -c40) - GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_salt":' " \"pwd_salt\": \"$salt\"," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf - GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_sha1":' " \"pwd_sha1\": \"$(echo -n "$salt$GLOBAL_PW" | sha1sum | mawk '{print $1}')\"," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf + else - # Remote access - local localpass=$(tr -dc '0-9a-f' < /dev/random | head -c40) - > /mnt/dietpi_userdata/deluge/.config/deluge/auth - G_EXEC chmod 0600 /mnt/dietpi_userdata/deluge/.config/deluge/auth - echo -e "root:$GLOBAL_PW:10\nlocalclient:$localpass:10" > /mnt/dietpi_userdata/deluge/.config/deluge/auth - fi + sed -i 's/^[[:blank:]]*allow-loopback-peers/#allow-loopback-peers/' /etc/turnserver.conf + sed -i '/^[[:blank:]]*no-loopback-peers/d' /etc/turnserver.conf - # Permissions - G_EXEC chown -R debian-deluged:root /mnt/dietpi_userdata/deluge + fi + G_CONFIG_INJECT 'no-multicast-peers' 'no-multicast-peers' /etc/turnserver.conf - # Service: https://github.com/deluge-torrent/deluge/blob/develop/packaging/systemd/deluged.service - cat << _EOF_ > /etc/systemd/system/deluged.service -[Unit] -Description=Deluge Daemon (DietPi) -Documentation=man:deluged + # Install Nextcloud Talk app + G_EXEC systemctl start mariadb + G_EXEC systemctl start redis-server + G_EXEC ncc maintenance:mode --off + if [[ ! -d '/var/www/nextcloud/apps/spreed' ]]; then -[Service] -User=debian-deluged -UMask=002 -ExecStart=$(command -v deluged) -d + # Succeed if app is already installed and on "Cannot declare class" bug: https://github.com/MichaIng/DietPi/issues/3499#issuecomment-622955490 + G_EXEC_POST_FUNC(){ [[ $exit_code != 0 && $(<$fp_log) =~ (' already installed'$|' Cannot declare class ') ]] && exit_code=0; } + G_EXEC ncc app:install spreed -[Install] -WantedBy=multi-user.target -_EOF_ - # https://github.com/deluge-torrent/deluge/blob/develop/packaging/systemd/deluge-web.service - # - Bullseye: deluge-web v2 requires the "-d" flag to stay in foreground, but v1 does not understand it yet - local flag= - (( $G_DISTRO < 6 )) || flag=' -d' - cat << _EOF_ > /etc/systemd/system/deluge-web.service -[Unit] -Description=Deluge Web UI (DietPi) -Documentation=man:deluge-web + fi + ncc app:enable spreed -[Service] -User=debian-deluged -UMask=027 -ExecStart=$(command -v deluge-web)$flag + # 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) + GCI_PASSWORD=1 GCI_PRESERVE=1 G_CONFIG_INJECT 'static-auth-secret=' "static-auth-secret=$secret" /etc/turnserver.conf + # - Scrape existing secret, in case user manually chose/edited it + secret=$(sed -n '/^[[:blank:]]*static-auth-secret=/{s/^[^=]*=//p;q}' /etc/turnserver.conf) + ncc config:app:set spreed turn_servers --value="[{\"server\":\"$domain:$port\",\"secret\":\"$secret\",\"protocols\":\"udp,tcp\"}]" | sed 's/"secret":".*","protocols"/"secret":"","protocols"/' + unset -v secret domain port invalid_text version -[Install] -WantedBy=multi-user.target -_EOF_ fi - software_id=115 # Webmin + software_id=32 # ympd if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # APT key - local url='https://webmin.com/jcameron-key.asc' - G_CHECK_URL "$url" - G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-webmin.gpg --yes" + Download_Install 'https://dietpi.com/downloads/binaries/all/ympd_1.2.3.7z' - # APT list - G_EXEC eval "echo 'deb https://download.webmin.com/download/repository/ sarge contrib' > /etc/apt/sources.list.d/webmin.list" - G_AGUP + local binary_name='ympd_' + # ARMv6 + if (( $G_HW_ARCH == 1 )); then - # APT package - G_AGI webmin + binary_name+='armv6' - fi + # ARMv7 + elif (( $G_HW_ARCH == 2 )); then - software_id=195 # youtube-dl - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + binary_name+='armv7' - Banner_Installing + # ARMv8 + elif (( $G_HW_ARCH == 3 )); then - DEPS_LIST='python3' + binary_name+='armv8' - # youtube-dl supports Python 2 and Python 3, but its shebang calls Python 2, else fails: https://github.com/ytdl-org/youtube-dl/issues/27649 - # We hence install the binary with Python 2 suffix and create a shell wrapper to call it with Python 3. - Download_Install 'https://yt-dl.org/downloads/latest/youtube-dl' /usr/local/bin/youtube-dl-py2 - echo -e '#!/bin/dash\nexec python3 /usr/local/bin/youtube-dl-py2 "$@"' > /usr/local/bin/youtube-dl - G_EXEC chmod +x /usr/local/bin/youtube-dl{,-py2} + # x86_64 + elif (( $G_HW_ARCH == 10 )); then - fi + binary_name+='amd64' - software_id=129 # O!MPD - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + fi - Banner_Installing + # We have no Buster binaries yet, so always use Stretch binaries + binary_name+='_stretch' - Download_Install 'https://github.com/ArturSierzant/OMPD/archive/master.tar.gz' /var/www - # Replace existing installs but preserve local config override - if [[ -d '/var/www/ompd' ]]; then + G_EXEC mv $binary_name /usr/bin/ympd + G_EXEC chmod +x /usr/bin/ympd + G_EXEC_NOEXIT=1 G_EXEC rm ympd_* - [[ -f '/var/www/ompd/include/config.local.inc.php' ]] && G_EXEC mv /var/www/ompd/include/config.local.inc.php /var/www/OMPD-master/include/ - G_EXEC rm -R /var/www/ompd + # User + Create_User -g dietpi ympd - fi - G_EXEC mv /var/www/OMPD-master /var/www/ompd + # Service + cat << '_EOF_' > /etc/systemd/system/ympd.service +[Unit] +Description=ympd (DietPi) +After=mpd.service + +[Service] +ExecStart=/usr/bin/ympd --user ympd --webport 1337 + +[Install] +WantedBy=multi-user.target +_EOF_ fi - software_id=135 # IceCast + DarkIce + software_id=148 # myMPD if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_AGI darkice icecast2 - fi + # Install dependencies: https://github.com/jcorporation/myMPD/blob/master/build.sh#L615-L616 + DEPS_LIST='make gcc cmake perl libc6-dev libssl-dev libid3tag0-dev libflac-dev liblua5.3-dev pkg-config libpcre3-dev' - software_id=63 # LinuxDash - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Download source + Download_Install 'https://github.com/jcorporation/myMPD/archive/master.tar.gz' - Banner_Installing + # Build and install myMPD + G_EXEC cd myMPD-master + G_EXEC ./build.sh releaseinstall - Download_Install 'https://github.com/afaqurk/linux-dash/archive/master.tar.gz' - G_EXEC mkdir -p /var/www/linuxdash - G_EXEC cp -a linux-dash-master/* /var/www/linuxdash/ - G_EXEC_NOHALT=1 G_EXEC rm -R linux-dash-master + # Cleanup + G_EXEC cd /tmp/$G_PROGRAM_NAME + G_EXEC_NOEXIT=1 G_EXEC rm -R myMPD-master + + # User: Switch to primary group "dietpi" to allow media access and create media files as "dietpi" group: https://github.com/MichaIng/DietPi/issues/3382 + G_EXEC usermod -g dietpi mympd + getent group mympd > /dev/null && G_EXEC_NOEXIT=1 G_EXEC groupdel mympd + + # Config: Create on fresh install + # - On reinstall /var/lib/mympd exists, so use its existence as reinstall flag + if [[ ! -d '/var/lib/mympd' ]] + then + export MYMPD_HTTP_PORT=1333 + export MYMPD_SSL=false + export MYMPD_MPD_HOST='/run/mpd/socket' + export MYMPD_LOGLEVEL=4 + G_EXEC mympd -c + G_EXEC mkdir -pm 0700 /var/lib/mympd/state + echo '/mnt/dietpi_userdata/Music' > /var/lib/mympd/state/playlist_directory + echo '/mnt/dietpi_userdata/Music' > /var/lib/mympd/state/music_directory + G_EXEC chmod 0600 /var/lib/mympd/state/* + G_EXEC chown -R mympd:dietpi /var/lib/mympd/state + fi + + # myMPD pre-v8.0.0 migration: Remove obsolete file + [[ -f '/etc/mympd.conf' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /etc/mympd.conf + [[ -f '/etc/mympd.conf.dist' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /etc/mympd.conf.dist + command -v mympd-config > /dev/null && G_EXEC rm "$(command -v mympd-config)" fi - software_id=184 # Tor Relay + software_id=121 # Roon Bridge if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_AGI tor - - local nickname= - G_WHIP_BUTTON_CANCEL_TEXT='Skip' - G_WHIP_INPUTBOX 'Pick a nickname for your relay.\n\nNB: This is optional, select "Skip" to leave it empty.' && nickname=$G_WHIP_RETURNED_VALUE - local email= - G_WHIP_BUTTON_CANCEL_TEXT='Skip' - G_WHIP_INPUTBOX 'Pick a contact email for your relay.\n\nNB: This is optional but encouraged, and it will be published depending on your relay.' && email=$G_WHIP_RETURNED_VALUE + # ARMv7 + local url='https://download.roonlabs.com/builds/RoonBridge_linuxarmv7hf.tar.bz2' - local orport=443 - local invalid_text= - while : - do - G_WHIP_DEFAULT_ITEM=$orport - if G_WHIP_INPUTBOX "${invalid_text}Please enter the ORPort that people will use to connect to your Tor relay: -\nNB: This port needs to be forwarded by your router and/or opened in your firewall settings. Default value is: 443, which should be changed when running a webserver. -\nDo not use 9001, as this port is commonly associated with Tor and censors might scan for it." && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 1 - then - orport=$G_WHIP_RETURNED_VALUE - break - else - invalid_text='[ERROR] No valid entry found, value needs to be a sequence of integers. Please retry...\n\n' - fi - done + # ARMv8 + if (( $G_HW_ARCH == 3 )) + then + url='https://download.roonlabs.com/builds/RoonBridge_linuxarmv8.tar.bz2' - local ipv6= - if grep -q '^[[:blank:]]*CONFIG_ENABLE_IPV6=1' /boot/dietpi.txt + # x86_64 + elif (( $G_HW_ARCH == 10 )) then - for i in $(hostname -I) - do - [[ $i == *.* ]] && continue - G_WHIP_DEFAULT_ITEM=$i - break - done - G_WHIP_BUTTON_CANCEL_TEXT='Skip' - G_WHIP_INPUTBOX "Please enter the private IPv6 address of this device. Skip this if you only want to use IPv4, or if this device doesn't have an IPv6 address." && ipv6=$G_WHIP_RETURNED_VALUE + url='https://download.roonlabs.com/builds/RoonBridge_linuxx64.tar.bz2' fi - local choice_required= - while : - do - G_WHIP_MENU_ARRAY=( - 'Bridge' ': Use this machine as an obfs4 bridge. This is the safest to run from home.' - 'Guard/Middle' ': Use this machine as a beginning or middle relay. Some info will be made public.' - 'Exit' ': Use this machine as an exit relay. This is most at risk for legal complaints.' - ) + Download_Install "$url" - G_WHIP_MENU "${choice_required}Please choose which type of relay this should be set up as:" || { choice_required='[ERROR] A choice is required to finish the Tor install.\n\n'; continue; } + # Clear dir on reinstall + [[ -d '/etc/roonbridge' ]] && G_EXEC rm -R /etc/roonbridge + G_EXEC mv RoonBridge /etc/roonbridge - if [[ $G_WHIP_RETURNED_VALUE == 'Exit' ]] - then - G_WHIP_BUTTON_OK_TEXT='YES' - G_WHIP_BUTTON_CANCEL_TEXT='NO' - G_WHIP_YESNO 'WARNING: DO NOT RUN AN EXIT RELAY FROM HOME. -\nAlso, it is highly recommended that you setup exit relays on dedicated servers. -\nBefore running an exit relay, check with your hosting provider to make sure they allow it. -\nAlso, set a reverse DNS (PTR) record (tor-exit is a good name), and preferably edit your WHOIS record to show that this is a Tor exit node. -\nWould you still like to continue?' || continue - fi + # User: !!! root required for remote updates + #Create_User -g dietpi -G audio -d /mnt/dietpi_userdata/roon roon - break - done + dps_index=$software_id Download_Install 'roonbridge.service' /etc/systemd/system/roonbridge.service - if [[ $G_WHIP_RETURNED_VALUE == 'Bridge' ]] - then - G_AGI obfs4proxy - local obfs4port=80 - invalid_text= - while : - do - G_WHIP_DEFAULT_ITEM=$obfs4port - if G_WHIP_INPUTBOX "${invalid_text}Please enter the obfs4 port that people will use to connect to your bridge: -\nNB: This port needs to be forwarded by your router and/or opened in your firewall settings. Default value is: 80. Do not use default value if running a webserver. -\nDo not use 9001, as this port is commonly associated with Tor and censors might scan for it." && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 1; then - obfs4port=$G_WHIP_RETURNED_VALUE - break - else - invalid_text='[ERROR] No valid entry found, value needs to be a sequence of integers. Please retry...\n\n' - fi - done - - # Grant capability to bind to privileged ports below 1024 - (( $obfs4port < 1024 )) && G_EXEC setcap cap_net_bind_service=+ep "$(command -v obfs4proxy)" - - cat << _EOF_ > /etc/tor/torrc -BridgeRelay 1 -ORPort $orport -ServerTransportPlugin obfs4 exec $(command -v obfs4proxy) -ServerTransportListenAddr obfs4 0.0.0.0:$obfs4port -ExtORPort auto -_EOF_ - G_EXEC mkdir -p /etc/systemd/system/tor@.service.d - G_EXEC eval "echo -e '[Service]\nNoNewPrivileges=no' > /etc/systemd/system/tor@.service.d/dietpi-relay.conf" - - elif [[ $G_WHIP_RETURNED_VALUE == 'Guard/Middle' ]] - then - cat << _EOF_ > /etc/tor/torrc -ORPort $orport -ExitRelay 0 -SocksPort 0 -ControlSocket 0 -_EOF_ - elif [[ $G_WHIP_RETURNED_VALUE == 'Exit' ]] - then - G_AGI unbound - aSOFTWARE_INSTALL_STATE[182]=1 - - cat << _EOF_ > /etc/tor/torrc -ORPort $orport -ExitRelay 1 -SocksPort 0 -ControlSocket 0 - -ExitPolicy accept *:20-21 -ExitPolicy accept *:43 -ExitPolicy accept *:53 -ExitPolicy accept *:79 -ExitPolicy accept *:80-81 -ExitPolicy accept *:88 -ExitPolicy accept *:110 -ExitPolicy accept *:143 -ExitPolicy accept *:220 -ExitPolicy accept *:389 -ExitPolicy accept *:443 -ExitPolicy accept *:464 -ExitPolicy accept *:531 -ExitPolicy accept *:543-544 -ExitPolicy accept *:554 -ExitPolicy accept *:636 -ExitPolicy accept *:706 -ExitPolicy accept *:749 -ExitPolicy accept *:873 -ExitPolicy accept *:902-904 -ExitPolicy accept *:981 -ExitPolicy accept *:989-990 -ExitPolicy accept *:991 -ExitPolicy accept *:992 -ExitPolicy accept *:993 -ExitPolicy accept *:995 -ExitPolicy accept *:1194 -ExitPolicy accept *:1220 -ExitPolicy accept *:1293 -ExitPolicy accept *:1500 -ExitPolicy accept *:1533 -ExitPolicy accept *:1677 -ExitPolicy accept *:1723 -ExitPolicy accept *:1755 -ExitPolicy accept *:1863 -ExitPolicy accept *:2082 -ExitPolicy accept *:2083 -ExitPolicy accept *:2086-2087 -ExitPolicy accept *:2095-2096 -ExitPolicy accept *:2102-2104 -ExitPolicy accept *:3690 -ExitPolicy accept *:4321 -ExitPolicy accept *:4643 -ExitPolicy accept *:5050 -ExitPolicy accept *:5190 -ExitPolicy accept *:5222-5223 -ExitPolicy accept *:5228 -ExitPolicy accept *:8008 -ExitPolicy accept *:8074 -ExitPolicy accept *:8082 -ExitPolicy accept *:8087-8088 -ExitPolicy accept *:8232-8233 -ExitPolicy accept *:8332-8333 -ExitPolicy accept *:8443 -ExitPolicy accept *:8888 -ExitPolicy accept *:9418 -ExitPolicy accept *:10000 -ExitPolicy accept *:11371 -ExitPolicy accept *:19294 -ExitPolicy accept *:19638 -ExitPolicy accept *:50002 -ExitPolicy accept *:64738 -ExitPolicy reject *:* -_EOF_ - [[ $ipv6 ]] && echo 'IPv6Exit 1' >> /etc/tor/torrc - # Apply Unbound as local DNS resolver for privacy reasons - command -v resolvconf > /dev/null && G_EXEC sed -i 's/dns-nameservers.*$/dns-nameservers 127.0.0.1/' /etc/network/interfaces - G_EXEC eval "echo 'nameserver 127.0.0.1' > /etc/resolv.conf" # Unbound is running and configured in the very next config step, so it is safe to switch the DNS nameserver right now. - fi - - echo 'ControlPort 9051' >> /etc/tor/torrc - echo 'CookieAuthentication 1' >> /etc/tor/torrc - [[ $nickname ]] && echo "Nickname $nickname" >> /etc/tor/torrc - [[ $email ]] && echo "ContactInfo $email" >> /etc/tor/torrc - [[ $ipv6 ]] && echo "ORPort [$ipv6]:$orport" >> /etc/tor/torrc - - fi - - software_id=182 # Unbound - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then - Banner_Installing - - G_DIETPI-NOTIFY 2 'Pre-configuring Unbound to avoid port binding conflicts' - - # Download/update list of root hints - Download_Install 'https://www.internic.net/domain/named.root' /var/lib/unbound/root.hints - - # Create monthly cron job to keep root hints updated - echo -e '#!/bin/dash\n# Update Unbound root hints\ncurl -sSfL https://www.internic.net/domain/named.root -o /var/lib/unbound/root.hints' > /etc/cron.monthly/dietpi-unbound - G_EXEC chmod +x /etc/cron.monthly/dietpi-unbound - - # Download base configuration if it does not exist yet - [[ -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 - 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 - fi - - # Stretch: Remove incompatible setting - (( $G_DISTRO < 5 )) && sed -i '/log-replies/d' /etc/unbound/unbound.conf.d/dietpi.conf - - # Since IP binding might be used, start after network interfaces have been configured, not when they just start to be configured - G_EXEC mkdir -p /etc/systemd/system/unbound.service.d - G_EXEC eval "echo -e '[Unit]\nWants=network-online.target\nAfter=network-online.target' > /etc/systemd/system/unbound.service.d/dietpi.conf" - - # Pi-hole + AdGuard Home part 1 - if (( ${aSOFTWARE_INSTALL_STATE[93]} > 0 || ${aSOFTWARE_INSTALL_STATE[126]} > 0 )) && grep -q '^[[:blank:]]*port:[[:blank:]][[:blank:]]*53$' /etc/unbound/unbound.conf.d/dietpi.conf - then - G_DIETPI-NOTIFY 2 'Configuring Unbound to work for your selected AdBlocker' - grep '^[[:blank:]]*nameserver[[:blank:]]' /etc/resolv.conf | grep -qvE '[[:blank:]]127.0.0.1(:53)?$' || echo 'nameserver 9.9.9.9' >> /etc/resolv.conf # Failsafe - G_CONFIG_INJECT 'port:[[:blank:]]' ' port: 5335' /etc/unbound/unbound.conf.d/dietpi.conf - G_CONFIG_INJECT 'interface:[[:blank:]]' ' interface: 127.0.0.1' /etc/unbound/unbound.conf.d/dietpi.conf - fi - - [[ -f '/lib/systemd/system/unbound.service' ]] && G_EXEC systemctl restart unbound - G_AGI unbound - G_EXEC systemctl enable --now unbound # Failsafe - - # Pi-hole part 2 - if (( ${aSOFTWARE_INSTALL_STATE[93]} == 2 )) - then - G_DIETPI-NOTIFY 2 'Configuring Pi-hole to use Unbound' - if [[ -f '/etc/dnsmasq.d/01-pihole.conf' ]] - then - G_EXEC sed -i '/^[[:blank:]]*server=/d' /etc/dnsmasq.d/01-pihole.conf - G_CONFIG_INJECT 'server=' 'server=127.0.0.1#5335' /etc/dnsmasq.d/01-pihole.conf - systemctl -q is-active pihole-FTL && G_EXEC systemctl restart pihole-FTL - fi - if [[ -f '/etc/pihole/setupVars.conf' ]] - then - G_CONFIG_INJECT 'PIHOLE_DNS_1=' 'PIHOLE_DNS_1=127.0.0.1#5335' /etc/pihole/setupVars.conf - G_EXEC sed -i '/^[[:blank:]]*PIHOLE_DNS_2=/d' /etc/pihole/setupVars.conf - fi - fi - - # AdGuard Home part 2 - if (( ${aSOFTWARE_INSTALL_STATE[126]} == 2 )) - then - G_DIETPI-NOTIFY 2 'Configuring AdGuard Home to use Unbound' - if [[ ! -f '/mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf' ]] - then - echo '127.0.0.1:5335' > /mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf - G_CONFIG_INJECT 'upstream_dns_file:[[:blank:]]' ' upstream_dns_file: /mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf' /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml - systemctl -q is-active adguardhome && G_EXEC systemctl restart adguardhome - fi - fi - - # Plex Media Server: Fix secure remote access: https://dietpi.com/phpbb/viewtopic.php?t=8896 - (( ${aSOFTWARE_INSTALL_STATE[42]} > 0 )) && echo -e 'server:\n\tprivate-domain: "plex.direct"' > /etc/unbound/unbound.conf.d/dietpi-plex.conf - fi - - software_id=93 # Pi-hole - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then - Banner_Installing - - local url='https://raw.githubusercontent.com/pi-hole/pi-hole/master/automated%20install/basic-install.sh' - G_CHECK_URL "$url" - - # Check free available memory. Increase swap size to prevent gravity running out of memory. - if (( $(free -m | mawk '/^Mem:/{print $7;exit}') < 512 && $(free -m | mawk '/^Swap:/{print $2;exit}') < 512 )) - then - G_DIETPI-NOTIFY 2 'Increasing swap size to 512 MiB for running gravity.sh, please wait...\n' - /boot/dietpi/func/dietpi-set_swapfile 512 - fi - - # Dependencies: https://github.com/pi-hole/pi-hole/blob/development/automated%20install/basic-install.sh#L250 - G_AGI $PHP_NAME-xml $PHP_NAME-sqlite3 $PHP_NAME-intl - - # Unbound: Switch port to 5335 if it was installed before, else it got just configured within its install step above - if (( ${aSOFTWARE_INSTALL_STATE[182]} == 2 )) && grep -q '^[[:blank:]]*port:[[:blank:]][[:blank:]]*53$' /etc/unbound/unbound.conf.d/dietpi.conf - then - G_DIETPI-NOTIFY 2 'Configuring Unbound to work for Pi-hole' - grep '^[[:blank:]]*nameserver[[:blank:]]' /etc/resolv.conf | grep -qvE '[[:blank:]]127.0.0.1(:53)?$' || echo 'nameserver 9.9.9.9' >> /etc/resolv.conf # Failsafe - G_CONFIG_INJECT 'port:[[:blank:]]' ' port: 5335' /etc/unbound/unbound.conf.d/dietpi.conf - G_CONFIG_INJECT 'interface:[[:blank:]]' ' interface: 127.0.0.1' /etc/unbound/unbound.conf.d/dietpi.conf - G_EXEC systemctl restart unbound - fi - - # Install - G_EXEC curl -sSfL "$url" -o install.sh - G_EXEC chmod +x install.sh - # - Skip web server install, since we allow to choose and install it prior to Pi-hole - # - Skip supported OS check. We do not support Debian testing suite but we are testing it already now. - export PIHOLE_SKIP_OS_CHECK=true - G_EXEC_NOEXIT=1 G_EXEC_OUTPUT=1 G_EXEC ./install.sh --disable-install-webserver || aSOFTWARE_INSTALL_STATE[$software_id]=0 - G_EXEC_NOHALT=1 G_EXEC rm install.sh - fi - - software_id=126 # AdGuard Home - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # ARMv6 - local url='https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv6.tar.gz' - - # ARMv7 - if (( $G_HW_ARCH == 2 )); then - - url='https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv7.tar.gz' - - # ARMv8 - elif (( $G_HW_ARCH == 3 )); then - - url='https://static.adguard.com/adguardhome/release/AdGuardHome_linux_arm64.tar.gz' - - # x86_64 - elif (( $G_HW_ARCH == 10 )); then - - url='https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz' - - fi - - # Deps: apache2-utils is required for htpasswd command to create bcrypt password hashes - DEPS_LIST='apache2-utils' - Download_Install "$url" - - # Install to userdata until it is possible to split binary and data/config without breaking the updater: https://github.com/AdguardTeam/AdGuardHome/issues/3286 - [[ -d '/mnt/dietpi_userdata/adguardhome' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/adguardhome - G_EXEC cp -a AdGuardHome/. /mnt/dietpi_userdata/adguardhome/ - G_EXEC rm -R AdGuardHome - - [[ -d '/opt/adguardhome' ]] && G_EXEC rm -R /opt/adguardhome # v7.3 beta - - # Unbound: Switch port to 5335 if it was installed before, else it got just configured within its install step above - if (( ${aSOFTWARE_INSTALL_STATE[182]} == 2 )) && grep -q '^[[:blank:]]*port:[[:blank:]][[:blank:]]*53$' /etc/unbound/unbound.conf.d/dietpi.conf - then - G_DIETPI-NOTIFY 2 'Configuring Unbound to work for AdGuard Home' - grep '^[[:blank:]]*nameserver[[:blank:]]' /etc/resolv.conf | grep -qvE '[[:blank:]]127.0.0.1(:53)?$' || echo 'nameserver 9.9.9.9' >> /etc/resolv.conf # Failsafe - G_CONFIG_INJECT 'port:[[:blank:]]' ' port: 5335' /etc/unbound/unbound.conf.d/dietpi.conf - G_CONFIG_INJECT 'interface:[[:blank:]]' ' interface: 127.0.0.1' /etc/unbound/unbound.conf.d/dietpi.conf - G_EXEC systemctl restart unbound - fi - - fi - - software_id=33 # Airsonic - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - 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 - - fi - - software_id=68 # Remot3.it - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # ARMv6/7 - local arch='armhf' - - # ARMv8 - if (( $G_HW_ARCH == 3 )); then - - arch='arm64' - - # x86_64 - elif (( $G_HW_ARCH == 10 )); then - - arch='amd64' - - fi - - local fallback_url="https://github.com/remoteit/installer/releases/download/v2.6.39/connectd_2.6.39_$arch.deb" - Download_Install "$(curl -sSfL 'https://api.github.com/repos/remoteit/installer/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/connectd_[^\"\/]*_$arch\.deb\"/{print \$4}")" - - fi - - software_id=69 # Python 3 RPi.GPIO - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - G_AGI python3-rpi.gpio - - fi - - software_id=70 # WiringPi - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # RPi - if (( $G_HW_MODEL < 10 )) - then - Download_Install 'https://github.com/WiringPi/WiringPi/archive/master.tar.gz' - - # Odroids - else - Download_Install 'https://github.com/hardkernel/wiringPi/archive/master.tar.gz' - G_EXEC mv {w,W}iringPi-master - fi - - G_EXEC cd WiringPi-master - G_EXEC_OUTPUT=1 G_EXEC ./build - G_EXEC strip --remove-section=.comment --remove-section=.note /usr/local/bin/gpio - G_EXEC cd /tmp/$G_PROGRAM_NAME - - # Move source dir to disk, as it contains additional examples to compile - [[ -d '/root/wiringPi' ]] && G_EXEC_NOEXIT=1 G_EXEC rm -R /root/wiringPi # Pre-v7.2 - [[ -d '/mnt/dietpi_userdata/WiringPi' ]] && G_EXEC rm -R /mnt/dietpi_userdata/WiringPi - G_EXEC mv WiringPi-master /mnt/dietpi_userdata/WiringPi - - fi - - software_id=72 # I2C - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - /boot/dietpi/func/dietpi-set_hardware i2c enable - - fi - - software_id=100 # PiJuice - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # On Bullseye currently the package is not available yet. So pull and install manually, if this is the case: https://github.com/MichaIng/DietPi/issues/4643 - if apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* pijuice-base(,|$)' - then - G_AGI pijuice-base - else - Download_Install 'http://archive.raspberrypi.org/debian/pool/main/p/pijuice-base/pijuice-base_1.7_all.deb' - fi - - 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 - G_EXEC chmod +x /var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func1.sh - - cat << '_EOF_' > /var/lib/pijuice/pijuice_config.JSON -{ - "system_events": { - "low_battery_voltage": { - "function": "SYS_FUNC_HALT", - "enabled": true - }, - "low_charge": { - "function": "NO_FUNC", - "enabled": true - }, - "button_power_off": { - "function": "USER_FUNC1", - "enabled": true - }, - "forced_power_off": { - "function": "USER_FUNC2", - "enabled": false - }, - "no_power": { - "function": "SYS_FUNC_HALT_POW_OFF", - "enabled": true - }, - "forced_sys_power_off": { - "function": "USER_FUNC3", - "enabled": false - }, - "watchdog_reset": { - "function": "USER_EVENT", - "enabled": true - } - }, - "user_functions": { - "USER_FUNC1": "/var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func1.sh", - "USER_FUNC2": "/var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func2.sh", - "USER_FUNC3": "/var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func3.sh", - "USER_FUNC4": "", - "USER_FUNC5": "", - "USER_FUNC6": "", - "USER_FUNC7": "", - "USER_FUNC8": "" - }, - "system_task": { - "watchdog": { - "enabled": true, - "period": "60" - }, - "min_bat_voltage": { - "threshold": "1", - "enabled": true - }, - "min_charge": { - "threshold": "1", - "enabled": true - }, - "enabled": true, - "wakeup_on_charge": { - "enabled": true, - "trigger_level": "1" - } - } -} -_EOF_ - fi - - software_id=171 # frp - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Architecture - # - ARMv6/7 - local arch='arm' - # - ARMv8 - if (( $G_HW_ARCH == 3 )) - then - arch='arm64' - - # - x86_64 - elif (( $G_HW_ARCH == 10 )) - then - arch='amd64' - 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}')" - - G_EXEC cd frp_* - - local choice_required= - while : - do - G_WHIP_MENU_ARRAY=( - 'Server' ': Use this machine as a server, with a public IP' - 'Client' ': Use this machine as a client, without a public IP' - 'Both' ': Run the reverse proxy only on this machine' - ) - - G_WHIP_MENU "${choice_required}Please choose how you are going to run frp." && break - choice_required='[ERROR] A choice is required to finish the frp install.\n\n' - done - local mode=$G_WHIP_RETURNED_VALUE - - G_EXEC mkdir -p /etc/frp - Create_User frp -d /etc/frp - - local token= - if [[ $mode == 'Server' || $mode == 'Both' ]] - then - G_EXEC mv frps /usr/local/bin/frps - cat << '_EOF_' > /etc/systemd/system/frps.service -[Unit] -Description=frp server (DietPi) -Wants=network-online.target -After=network-online.target - -[Service] -User=frp -AmbientCapabilities=CAP_NET_BIND_SERVICE -ExecStart=/usr/local/bin/frps -c /etc/frp/frps.ini -Restart=on-failure -RestartSec=5s - -[Install] -WantedBy=multi-user.target -_EOF_ - token=$(openssl rand -hex 15) - # Pre-create config file to turn on dashboard - [[ -f '/etc/frp/frps.ini' ]] || cat << _EOF_ > /etc/frp/frps.ini -[common] -bind_port = 7000 - -dashboard_port = 7500 -dashboard_user = admin -dashboard_pwd = $GLOBAL_PW - -authentication_method = token -token = $token -_EOF_ - G_EXEC chown root:frp /etc/frp/frps.ini - G_EXEC chmod 0640 /etc/frp/frps.ini - fi - - if [[ $mode == 'Client' || $mode == 'Both' ]] - then - G_EXEC mv frpc /usr/local/bin/frpc - cat << '_EOF_' > /etc/systemd/system/frpc.service -[Unit] -Description=frp client (DietPi) -Wants=network-online.target -After=network-online.target frps.service - -[Service] -User=frp -ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.ini -ExecReload=/usr/local/bin/frpc reload -c /etc/frp/frpc.ini -Restart=on-failure -RestartSec=5s - -[Install] -WantedBy=multi-user.target -_EOF_ - local server_addr= - local server_port=7000 - if [[ $G_WHIP_RETURNED_VALUE == 'Both' ]] - then - server_addr=127.0.0.1 - else - local invalid_entry= - while : - do - if G_WHIP_INPUTBOX "${invalid_entry}Please enter the IP address of your frp server, including port (default 7000)" && [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9.:]+$ ]] - then - server_addr=${G_WHIP_RETURNED_VALUE#*:} - [[ $G_WHIP_RETURNED_VALUE =~ : ]] && server_port=${G_WHIP_RETURNED_VALUE%:*} - break - else - invalid_entry='[FAILED] Please enter a valid IP address\n\n' - fi - done - - while : - do - if G_WHIP_INPUTBOX "${invalid_entry}Please enter the authentication token of your frp server" && [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9.]+$ ]] - then - token=$G_WHIP_RETURNED_VALUE - break - else - invalid_entry='[FAILED] Please enter a token\n\n' - fi - done - fi - - # Pre-create config file to turn on admin UI - [[ -f '/etc/frp/frpc.ini' ]] || cat << _EOF_ > /etc/frp/frpc.ini -[common] -server_addr = $server_addr -server_port = $server_port - -admin_addr = 0.0.0.0 -admin_port = 7400 -admin_user = admin -admin_pwd = $GLOBAL_PW - -token=$token -_EOF_ - G_EXEC chown root:frp /etc/frp/frpc.ini - G_EXEC chmod 0660 /etc/frp/frpc.ini - fi - - # Cleanup - G_EXEC cd /tmp/$G_PROGRAM_NAME - G_EXEC_NOEXIT=1 G_EXEC rm -R frp_* - - fi - - software_id=122 # Node-RED - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - 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 - - # User - Create_User -G gpio,i2c -d /mnt/dietpi_userdata/node-red nodered - # - Allow sudo calls - echo 'nodered ALL=NOPASSWD: ALL' > /etc/sudoers.d/nodered - - # Permissions - G_EXEC chown -R nodered:nodered /mnt/dietpi_userdata/node-red - - # Service - cat << '_EOF_' > /etc/systemd/system/node-red.service -[Unit] -Description=Node-RED (DietPi) - -[Service] -User=nodered -ExecStart=/mnt/dietpi_userdata/node-red/node_modules/.bin/node-red -u /mnt/dietpi_userdata/node-red - -[Install] -WantedBy=multi-user.target -_EOF_ - # Pre-reqs - G_AGI python3 - - # Install as local instance for "nodered" user - G_EXEC cd /mnt/dietpi_userdata/node-red - G_EXEC_OUTPUT=1 G_EXEC sudo -u nodered npm i --no-audit node-red - G_EXEC cd /tmp/$G_PROGRAM_NAME - - # CLI alias - echo "alias node-red-admin='sudo -u nodered /mnt/dietpi_userdata/node-red/node_modules/.bin/node-red-admin'" > /etc/bashrc.d/dietpi-node-red.sh - - fi - - software_id=123 # Mosquitto - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Use official APT repository where available: https://repo.mosquitto.org/debian/pool/main/m/mosquitto/ - if [[ $G_HW_ARCH != 3 ]]; then - - # 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" - - # 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" - G_AGUP - - fi - - G_AGI mosquitto - - Remove_SysV mosquitto - - # Password file - if [[ ! -f '/etc/mosquitto/passwd' ]] - then - G_EXEC umask 0037 - > /etc/mosquitto/passwd # Pre-create file, required for pre-v1.6.10 (ARMv8 up to Buster): https://github.com/MichaIng/DietPi/issues/4424 - G_EXEC_PRE_FUNC(){ acommand[4]=$GLOBAL_PW; } - G_EXEC mosquitto_passwd -b /etc/mosquitto/passwd mosquitto "${GLOBAL_PW//?/X}" - G_EXEC chown root:mosquitto /etc/mosquitto/passwd - G_EXEC umask 0022 - fi - - # Config: /etc/mosquitto/conf.d exists, but doubled settings do not override each other and lead to a startup failure instead, which breaks the purpose we want to use it for. - # - Disable PID file, not required for systemd handling - G_EXEC sed -i '/^[[:blank:]]*pid_file[[:blank:]]/d' /etc/mosquitto/mosquitto.conf - [[ -d '/run/mosquitto' ]] && G_EXEC rm -R /run/mosquitto - # - Log to default STDERR > systemd-journald - G_EXEC sed -i '/^[[:blank:]]*log_dest[[:blank:]]/d' /etc/mosquitto/mosquitto.conf - [[ -d '/var/log/mosquitto' ]] && G_EXEC rm -R /var/log/mosquitto - # - Add default password file for authenticated requests: https://github.com/MichaIng/DietPi/issues/4133 - GCI_PRESERVE=1 G_CONFIG_INJECT 'password_file[[:blank:]]' 'password_file /etc/mosquitto/passwd' /etc/mosquitto/mosquitto.conf - # - Add default listener at port 1883 not bound to loopback IP: https://github.com/MichaIng/DietPi/issues/4133 - GCI_PRESERVE=1 G_CONFIG_INJECT 'listener[[:blank:]]' 'listener 1883' /etc/mosquitto/mosquitto.conf - - # Add/override default systemd unit: https://github.com/eclipse/mosquitto/tree/master/service/systemd - cat << '_EOF_' > /etc/systemd/system/mosquitto.service -[Unit] -Description=Mosquitto MQTT Broker (DietPi) -Documentation=man:mosquitto.conf(5) man:mosquitto(8) -Wants=network-online.target -After=network-online.target - -[Service] -Type=notify -NotifyAccess=main -User=mosquitto -ExecStart=/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf -ExecReload=/bin/kill -HUP $MAINPID - -[Install] -WantedBy=multi-user.target -_EOF_ - fi - - software_id=131 # Blynk Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Stretch and ARMv6: Install Java 8 build - local fallback_url='https://github.com/Peterkn2001/blynk-server/releases/download/v0.41.16/server-0.41.16.jar' java= - (( $G_DISTRO < 5 || $G_HW_ARCH == 1 )) && fallback_url='https://github.com/Peterkn2001/blynk-server/releases/download/v0.41.16/server-0.41.16-java8.jar' java='-java8' - - # RPi: Install build deps for the "onoff" Node module - (( $G_HW_MODEL > 9 )) || DEPS_LIST='python3 make g++' - - Download_Install "$(curl -sSfL 'https://api.github.com/repos/Peterkn2001/blynk-server/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/server-[0-9.]*$java\.jar\"/{print \$4}")" /mnt/dietpi_userdata/blynk/blynkserver.jar - - # RPi: Install "onoff" for GPIO access - (( $G_HW_MODEL > 9 )) || G_EXEC_OUTPUT=1 G_EXEC npm i -g --unsafe-perm --no-audit onoff - - # Install Blynk JS library - G_EXEC_OUTPUT=1 G_EXEC npm i -g --unsafe-perm --no-audit blynk-library - - # Preserve existing config - if [[ ! -f '/mnt/dietpi_userdata/blynk/server.properties' ]] - then - G_EXEC curl -sSfL 'https://raw.githubusercontent.com/Peterkn2001/blynk-server/master/server/core/src/main/resources/server.properties' -o /mnt/dietpi_userdata/blynk/server.properties - G_EXEC chmod 0600 /mnt/dietpi_userdata/blynk/server.properties - G_CONFIG_INJECT 'logs.folder=' 'logs.folder=/var/log/blynk' /mnt/dietpi_userdata/blynk/server.properties - G_CONFIG_INJECT 'data.folder=' 'data.folder=/mnt/dietpi_userdata/blynk/data' /mnt/dietpi_userdata/blynk/server.properties - G_CONFIG_INJECT 'http.port=' 'http.port=8442' /mnt/dietpi_userdata/blynk/server.properties - GCI_PASSWORD=1 G_CONFIG_INJECT 'admin.pass=' "admin.pass=$GLOBAL_PW" /mnt/dietpi_userdata/blynk/server.properties - fi - - # Example local TCP connection script - if [[ ! -f '/mnt/dietpi_userdata/blynk/client-tcp-local.js' ]] - then - G_EXEC curl -sSfL 'https://raw.githubusercontent.com/vshymanskyy/blynk-library-js/master/examples/nodejs/client-tcp-local.js' -o /mnt/dietpi_userdata/blynk/client-tcp-local.js - G_EXEC sed -i "s|require('blynk-library')|require('/usr/local/lib/node_modules/blynk-library')|" /mnt/dietpi_userdata/blynk/client-tcp-local.js - G_EXEC chmod +x /mnt/dietpi_userdata/blynk/client-tcp-local.js - fi - - # User - Create_User -d /mnt/dietpi_userdata/blynk blynk - - # Service - cat << _EOF_ > /etc/systemd/system/blynkserver.service -[Unit] -Description=Blynk Server (DietPi) -Wants=network-online.target -After=network-online.target - -[Service] -SyslogIdentifier=Blynk -User=blynk -WorkingDirectory=/mnt/dietpi_userdata/blynk -ExecStart=$(command -v java) -jar /mnt/dietpi_userdata/blynk/blynkserver.jar - -# Hardening -PrivateTmp=true - -[Install] -WantedBy=multi-user.target -_EOF_ - # Permissions - G_EXEC chown -R blynk:blynk /mnt/dietpi_userdata/blynk - - # Assure that the default log directory exists, when it is set in the config file: https://github.com/MichaIng/DietPi/issues/4721 - if grep -q '^logs.folder=/var/log/blynk$' /mnt/dietpi_userdata/blynk/server.properties - then - G_EXEC mkdir -p /var/log/blynk - G_EXEC chown -R blynk:blynk /var/log/blynk - fi - - fi - - software_id=124 # NAA Daemon - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Base URL - local url='https://www.signalyst.eu/bins/naa/linux' - - # Arch - # - ARMv6/7 - local arch='armhf' - - # - ARMv8 - if (( $G_HW_ARCH == 3 )); then - - arch='arm64' - - # - x86_64 - elif (( $G_HW_ARCH == 10 )); then - - arch='amd64' - - fi - - # Get latest version: No Bullseye packages available yet - local distro=$G_DISTRO_NAME - (( $G_DISTRO > 5 )) && distro='buster' - local package=$(curl -sSfL "$url/$distro/" | sed -n "/href=\"networkaudiod_[^\"]*_$arch.deb\"/{s/^[^\"]*\"//;s/\".*$//p}" | tail -1) - - # Check final URL before applying debconf settings - G_CHECK_URL "$url/$distro/$package" - - # Skip license - debconf-set-selections <<< 'networkaudiod networkaudiod/license note false' - - # Install - no_check_url=1 Download_Install "$url/$distro/$package" - - unset url arch distro package - - fi - - software_id=71 # WebIOPi - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing # https://github.com/Freenove/WebIOPi - - # Check for reinstall - local reinstall=0 - [[ -f '/etc/webiopi/config' ]] && reinstall=1 - - DEPS_LIST='python3-dev python3-setuptools patch' - Download_Install 'https://github.com/Freenove/WebIOPi/archive/master.tar.gz' - - G_EXEC cd WebIOPi-master/WebIOPi-* - - # Apply patch - G_EXEC_OUTPUT=1 G_EXEC patch -p1 -i webiopi-pi2bplus.patch - - # Install for Python 3 only - G_EXEC sed -i '/SEARCH="python python3"/c\SEARCH="python3"' setup.sh - - # Skip Weaved install prompt - G_EXEC sed -i '/read response/c\response="n"' setup.sh - - # Run setup script, skipping APT installs - G_EXEC_OUTPUT=1 G_EXEC ./setup.sh skip-apt - - G_EXEC cd /tmp/$G_PROGRAM_NAME - - # Cleanup - G_EXEC_NOHALT=1 G_EXEC rm -R WebIOPi-master - - # On fresh installs, change port to 8002 to avoid conflict with IceCast - (( $reinstall )) || G_EXEC sed -i 's/^port = 8000$/port = 8002/' /etc/webiopi/config - - # Service - Remove_SysV webiopi 1 - cat << _EOF_ > /etc/systemd/system/webiopi.service -[Unit] -Description=WebIOPi (DietPi) -Wants=network-online.target -After=network-online.target - -[Service] -SyslogIdentifier=WebIOPi -ExecStart=$(which python3) -m webiopi -c /etc/webiopi/config - -# Hardening -PrivateTmp=true -ProtectHome=true - -[Install] -WantedBy=multi-user.target -_EOF_ - fi - - software_id=98 # HAProxy - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - local version='2.4.3' # 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" - - # Compile - G_EXEC cd haproxy-$version - G_EXEC_OUTPUT=1 G_EXEC make -j "$G_HW_CPU_CORES" TARGET=linux-glibc CPU=generic USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 ADDLIB='-Wl,--no-as-needed -lgcc_s -Wl,--as-needed' DEBUG_CFLAGS='-g0 -O3' LDFLAGS='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed' - # Strip binary size - G_EXEC strip --remove-section=.comment --remove-section=.note haproxy - # Install - G_EXEC_OUTPUT=1 G_EXEC make install - # - systemd unit - G_EXEC cd admin/systemd - G_EXEC_OUTPUT=1 G_EXEC make - G_EXEC mv {,/etc/systemd/system/}haproxy.service - # - Error pages - G_EXEC cd /tmp/$G_PROGRAM_NAME - G_EXEC mkdir -p /etc/haproxy/errors - G_EXEC mv haproxy-$version/examples/errorfiles/*.http /etc/haproxy/errors/ - # Clean up - G_EXEC_NOHALT=1 G_EXEC rm -R haproxy-$version - - fi - - software_id=35 # Logitech Media Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing # https://wiki.slimdevices.com/index.php/DebianPackage#installing_7.9.2 - - # Grab architecture - local arch='arm' - (( $G_HW_ARCH == 10 )) && arch='amd64' - - # Grab latest package URL: Force HTTPS! - local fallback_url="https://downloads.slimdevices.com/LogitechMediaServer_v8.2.0/logitechmediaserver_8.2.0_$arch.deb" - Download_Install "$(curl -sSfL "https://www.mysqueezebox.com/update/?version=8.2&geturl=1&os=deb$arch" | sed 's|^http://|https://|')" - - # Remove bundled SysVinit service - systemctl -q is-enabled logitechmediaserver 2> /dev/null || systemctl -q is-active logitechmediaserver && G_EXEC systemctl disable --now logitechmediaserver - killall -qwr squeezeboxserver* # Provided service may not wait for exit, kill: https://github.com/MichaIng/DietPi/issues/1613#issuecomment-372787574 - Remove_SysV logitechmediaserver 1 - - # Grant user access to DietPi media files - G_EXEC usermod -aG dietpi squeezeboxserver - - # systemd service - cat << _EOF_ > /etc/systemd/system/logitechmediaserver.service -[Unit] -Description=Logitech Media Server (DietPi) - -[Service] -User=squeezeboxserver -ExecStart=$(command -v squeezeboxserver) --prefsdir /var/lib/squeezeboxserver/prefs --logdir /var/log/squeezeboxserver/ --cachedir /var/lib/squeezeboxserver/cache --charset=utf8 --logfile /var/log/squeezeboxserver/error.log -Restart=on-failure -RestartSec=5 - -[Install] -WantedBy=multi-user.target -_EOF_ - # Grab our test media for user - Download_Test_Media - - fi - - software_id=55 # Wordpress - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - Download_Install 'https://wordpress.org/latest.tar.gz' /var/www - - fi - - software_id=38 # FreshRSS - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Install required PHP modules: https://github.com/FreshRSS/FreshRSS#example-of-full-installation-on-linux-debianubuntu - DEPS_LIST="$PHP_NAME-curl $PHP_NAME-gmp $PHP_NAME-intl $PHP_NAME-json $PHP_NAME-mbstring $PHP_NAME-xml $PHP_NAME-zip" - - if [[ -d '/opt/FreshRSS' ]] - then - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/FreshRSS\" already exists. Download and install steps will be skipped. - - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. - - if you need to reinstall (e.g. broken instance), please manually backup your config files+data, remove the install dir \"/opt/FreshRSS\" and rerun \"dietpi-software (re)install $software_id\"." - else - Download_Install 'https://github.com/FreshRSS/FreshRSS/archive/master.tar.gz' /opt - G_EXEC mv /opt/FreshRSS-master /opt/FreshRSS - fi - - fi - - software_id=28 # TigerVNC Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - # netbase is required until Bullseye to solve: "Use of uninitialized value $proto in socket at /usr/bin/tigervncserver" - # - It is a recommendation and no dependency of perl, but expected by some packages depending on perl only: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=939055 - # tigervnc-common is required as it is a recommendation only until Bullseye. - local apackages=() - (( $G_DISTRO > 5 )) || apackages=('tigervnc-common' 'netbase') - # https://github.com/MichaIng/DietPi/issues/1558#issuecomment-701547904 - (( ${aSOFTWARE_INSTALL_STATE[23]} > 0 )) && apackages+=('dbus-user-session') - G_AGI tigervnc-standalone-server tigervnc-scraping-server "${apackages[@]}" - - fi - - software_id=120 # RealVNC Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - G_AGI realvnc-vnc-server - - fi - - software_id=73 # Fail2Ban - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Create jail.conf (backend = systemd) first, to prevent APT failure due to missing /var/log/auth.log: https://github.com/MichaIng/DietPi/issues/475#issuecomment-310873879 - G_EXEC mkdir -p /etc/fail2ban/fail2ban.d - [[ -f '/etc/fail2ban/jail.conf' ]] || cat << '_EOF_' > /etc/fail2ban/jail.conf -[DEFAULT] -enabled = true -ignoreip = 127.0.0.1/8 -ignorecommand = -backend = systemd -mode = normal -filter = %(__name__)s[mode=%(mode)s] -findtime = 600 -maxretry = 3 -bantime = 600 -banaction = route -action = %(banaction)s[blocktype=blackhole] - -[dropbear] - -[sshd] -# Mode: normal (default), ddos, extra or aggressive (combines all) -# See "filter.d/sshd.conf" for details. -#mode = normal -_EOF_ - # Log to systemd by default - local logtarget='SYSOUT' - (( $G_DISTRO < 5 )) && logtarget='SYSLOG' - echo -e "[Definition]\nlogtarget = $logtarget" > /etc/fail2ban/fail2ban.d/97_dietpi.conf - unset -v logtarget - - G_AGI python3-systemd fail2ban - - Remove_SysV fail2ban 1 - - # Failsafe - G_EXEC systemctl unmask fail2ban - G_EXEC systemctl enable --now fail2ban - - fi - - software_id=74 # InfluxDB - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # 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" - - # 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" - G_AGUP - - # APT package - G_AGI influxdb - - fi - - software_id=77 # Grafana - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # ARMv6: Install package manually since repo is not compatible: https://grafana.com/grafana/download?platform=arm - if (( $G_HW_ARCH == 1 )); then - - Download_Install 'https://dl.grafana.com/oss/release/grafana-rpi_8.1.2_armhf.deb' - - # Else use official APT repo: https://grafana.com/docs/grafana/latest/installation/debian/#install-from-apt-repository - else - - # 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" - - # APT list - G_EXEC eval "echo 'deb https://packages.grafana.com/oss/deb/ stable main' > /etc/apt/sources.list.d/grafana.list" - G_AGUP - - # APT package - G_AGI grafana - - fi - - fi - - software_id=64 # phpSysInfo - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Download - Download_Install 'https://github.com/phpsysinfo/phpsysinfo/archive/main.tar.gz' - - # Clean reinstall, but preserve previous config - if [[ -d '/var/www/phpsysinfo' ]] - then - G_EXEC mv /var/www/phpsysinfo/phpsysinfo.ini phpsysinfo-main/phpsysinfo.ini - G_EXEC rm -R /var/www/phpsysinfo - fi - G_EXEC mv phpsysinfo-main /var/www/phpsysinfo - - fi - - software_id=80 # Ubooquity - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - G_EXEC curl -sSfL https://vaemendis.net/ubooquity/service/download.php -o Ubooquity.zip - G_EXEC unzip -o Ubooquity.zip - G_EXEC_NOEXIT=1 G_EXEC rm Ubooquity.zip - G_EXEC mkdir -p /mnt/dietpi_userdata/ubooquity - G_EXEC mv {,/mnt/dietpi_userdata/ubooquity/}Ubooquity.jar - - fi - - software_id=179 # Komga - 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' - 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 - - fi - - software_id=56 # Single File PHP Gallery - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Install required PHP modules: https://sye.dk/sfpg/ - DEPS_LIST="$PHP_NAME-gd" - Download_Install 'https://sye.dk/sfpg/Single_File_PHP_Gallery_4.8.0.zip' /var/www/gallery - - # Enable required PHP modules - G_EXEC phpenmod gd - - # Thumbnails and metadata cache: Remove on reinstalls - [[ -d '/var/www/gallery/_sfpg_data' ]] && G_EXEC rm -R /var/www/gallery/_sfpg_data - G_EXEC mkdir /var/www/gallery/_sfpg_data - G_EXEC chown www-data /var/www/gallery/_sfpg_data - - # Apply a random security phrase - local phrase=$(tr -dc '[:alnum:]' < /dev/random | head -c30) - GCI_PASSWORD=1 G_CONFIG_INJECT "define\('SECURITY_PHRASE'" "define('SECURITY_PHRASE', '$phrase');" /var/www/gallery/index.php - unset -v phrase - - # Create test galleries - [[ -d '/var/www/gallery/DietPi' ]] || G_EXEC mkdir /var/www/gallery/DietPi - [[ -f '/var/www/gallery/DietPi/logo_256.png' ]] || G_THREAD_START curl -sSfL 'https://dietpi.com/images/dietpi-logo_256x256.png' -o /var/www/gallery/DietPi/logo_256.png - [[ -d '/var/www/gallery/Tr-Zero' ]] || G_EXEC mkdir /var/www/gallery/Tr-Zero - [[ -f '/var/www/gallery/Tr-Zero/SS_0.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/SS_0.jpg' -o /var/www/gallery/Tr-Zero/SS_0.jpg - [[ -f '/var/www/gallery/Tr-Zero/SS_1.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/SS_44.jpg' -o /var/www/gallery/Tr-Zero/SS_1.jpg - [[ -f '/var/www/gallery/Tr-Zero/SS_2.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/3.png' -o /var/www/gallery/Tr-Zero/SS_2.jpg - G_THREAD_WAIT - - fi - - software_id=40 # Ampache - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing # https://github.com/ampache/ampache/wiki/Installation - - # Required PHP modules: https://github.com/ampache/ampache/wiki/Installation#prerequisites - DEPS_LIST="$PHP_NAME-curl $PHP_NAME-intl $PHP_NAME-json $PHP_NAME-xml" - - # 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' - 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 - else - local fallback_url='https://github.com/ampache/ampache/releases/download/4.4.3/ampache-4.4.3_all.zip' - Download_Install "$(curl -sSfL 'https://api.github.com/repos/ampache/ampache/releases' | mawk -F\" '/"browser_download_url": ".*\/ampache-4[0-9\.]*_all.zip"/{print $4}' | head -1)" ampache - fi - - # Reinstall: Preserve existing config files - [[ -f '/var/www/ampache/config/ampache.cfg.php' ]] && G_EXEC mv /var/www/ampache/config/ampache.cfg.php ampache/config/ - [[ -f '/var/www/ampache/config/registration_agreement.php' ]] && G_EXEC mv /var/www/ampache/config/registration_agreement.php ampache/config/ - [[ -f '/var/www/ampache/channel/.htaccess' ]] && G_EXEC mv /var/www/ampache/channel/.htaccess ampache/channel/ - [[ -f '/var/www/ampache/rest/.htaccess' ]] && G_EXEC mv /var/www/ampache/rest/.htaccess ampache/rest/ - [[ -f '/var/www/ampache/play/.htaccess' ]] && G_EXEC mv /var/www/ampache/play/.htaccess ampache/play/ - [[ -d '/var/www/ampache' ]] && G_EXEC rm -R /var/www/ampache - - G_EXEC mv {,/var/www/}ampache - - fi - - software_id=97 # OpenVPN Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - G_AGI openvpn iptables - Remove_SysV openvpn - - fi - - software_id=117 # PiVPN - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - G_EXEC curl -sSfL 'https://raw.githubusercontent.com/pivpn/pivpn/master/auto_install/install.sh' -o install.bash - G_EXEC chmod +x install.bash - G_DIETPI-NOTIFY 2 'Preventing reboot from within PiVPN installer' - G_EXEC sed -i '/shutdown[[:space:]]/d' install.bash - G_DIETPI-NOTIFY 2 'Preventing install of unattended-upgrades' - G_EXEC sed -i 's/^[[:blank:]]*UNATTUPG=[[:digit:]]/UNATTUPG=0/' install.bash - - # APT deps - G_AGI dnsutils net-tools bsdmainutils iptables-persistent # https://github.com/pivpn/pivpn/blob/master/auto_install/install.sh#L37 - - G_EXEC_OUTPUT=1 G_EXEC_NOEXIT=1 G_EXEC ./install.bash || aSOFTWARE_INSTALL_STATE[$software_id]=0 - G_EXEC_NOHALT=1 G_EXEC rm install.bash - - fi - - software_id=172 # WireGuard - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Packages available on Buster backports and Bullseye: For Stretch and Raspbian Buster add Bullseye repo - if (( $G_DISTRO < 5 || ( $G_HW_MODEL < 10 && ${G_RASPBIAN:-1} && $G_DISTRO == 5 ) )); then - - # Raspbian or Debian? - local url='http://raspbian.raspberrypi.org/raspbian/' - (( $G_HW_MODEL > 9 )) || (( ! $G_RASPBIAN )) && url='https://deb.debian.org/debian/' - - echo "deb $url bullseye main" > /etc/apt/sources.list.d/dietpi-wireguard.list - - # Disable repo via priority "-1", to prevent any accidental package upgrades: https://github.com/MichaIng/DietPi/issues/2568 - # Enable but set WireGuard package priorities low enough to install only if not available in main repo(s) - echo -e 'Package: *\nPin: release n=bullseye\nPin-Priority: -1\n -Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin-Priority: 100' > /etc/apt/preferences.d/dietpi-wireguard - - G_AGUP - - fi - - # If the kernel module is shipped with the kernel (e.g. Armbian 5.X) - if [[ $WIREGUARD_BUILTIN == 1 ]]; then - - # Purge DKMS as it is not required and might mess with available kernel module - dpkg-query -s wireguard-dkms &> /dev/null && G_AGP wireguard-dkms - # Install user space tools only - G_AGI wireguard-tools iptables qrencode - - # Else, kernel headers and matching kernel image is required for wireguard-dkms to build the WireGuard kernel module - else - - local apackages=() - # x86_64 - if (( $G_HW_ARCH == 10 )); then - - apackages=('linux-image-amd64' 'linux-headers-amd64') - - # RPi - elif (( $G_HW_MODEL < 10 )); then - - # Install bootloader package as well to assure we have a correctly booting system with intended kernel - apackages=('raspberrypi-kernel' 'raspberrypi-kernel-headers' 'raspberrypi-bootloader') - - # Odroid XU4 - elif (( $G_HW_MODEL == 11 )); then - - apackages=('linux-image-4.14-armhf-odroid-xu4' 'linux-headers-4.14-armhf-odroid-xu4') - - # Odroid C2 - elif (( $G_HW_MODEL == 12 )); then - - apackages=('linux-image-arm64-odroid-c2' 'linux-headers-arm64-odroid-c2') - - # Odroid N2 - elif (( $G_HW_MODEL == 15 )); then - - apackages=('linux-image-arm64-odroid-n2' 'linux-headers-arm64-odroid-n2') - - # Odroid C4 - elif (( $G_HW_MODEL == 16 )); then - - apackages=('linux-image-arm64-odroid-c4' 'linux-headers-arm64-odroid-c4') - - fi - - # Odroids need to purge before we install, else, does not update to latest version... - (( $G_HW_MODEL > 9 && $G_HW_MODEL < 20 )) && G_AGP "${apackages[@]}" - - # Since G_AGUG does not upgrade packages with changed dependencies, in case of kernel image meta packages, those need to be installed+upgraded via G_AGI. - G_AGI "${apackages[@]}" # apt-get install overrides hold state - unset -v apackages - - # Workaround for missing /lib/modules//build symlink: https://github.com/MichaIng/DietPi/issues/3577 - # - Known as issue currently on Odroid C2/N2, check for new build system if linux-/ holds current headers instead of linux-source-/: https://dietpi.com/meveric/pool/c2/l/ - for i in /lib/modules/* - do - [[ -d $i/build ]] && continue - [[ -d /usr/src/linux-headers-${i##*/} ]] && ln -sfv "/usr/src/linux-headers-${i##*/}" "$i/build" - done - - # If existing install, reconfigure to rebuild WireGuard kernel module against current kernel + headers - dpkg-query -s wireguard-dkms &> /dev/null && G_EXEC dpkg-reconfigure -f noninteractive wireguard-dkms - - # iptables required to forward incoming VPN traffic to local LAN/internet interface - # qrencode required to print client config QR code to console - G_AGI wireguard-dkms wireguard-tools iptables qrencode - - fi - - fi - - software_id=92 # Certbot - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - - G_AGI certbot python3-certbot-apache - - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - - G_AGI certbot python3-certbot-nginx - - else - - G_AGI certbot - - fi - - fi - - software_id=60 # WiFi Hotspot - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - local packages=('hostapd' 'isc-dhcp-server' 'iptables' 'libnl-3-200') - - # RTL8188C* device and special Realtek hostapd package available - lsusb | grep -qi 'RTL8188C' && apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* hostapd-realtek(,|$)' && packages[0]='hostapd-realtek' - - G_AGI "${packages[@]}" - - # Enable WiFi modules - /boot/dietpi/func/dietpi-set_hardware wifimodules enable - - # Unmask hostapd service: https://github.com/MichaIng/DietPi/issues/2962 - G_EXEC systemctl unmask hostapd - - fi - - software_id=61 # Tor Hotspot - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - G_AGI tor - - fi - - software_id=189 # VSCodium - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # APT key - G_EXEC eval "curl -sSfL 'https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-vscodium.gpg --yes" - - # APT list - G_EXEC eval "echo 'deb https://paulcarroty.gitlab.io/vscodium-deb-rpm-repo/debs vscodium main' > /etc/apt/sources.list.d/dietpi-vscodium.list" - G_AGUP - - # APT package - # - gnome-keyring is the backend daemon for the Secrets API used to store credentials, required e.g. for the GitHub PR and issues extension. - G_AGI codium gnome-keyring - - # Desktop shortcut - Create_Desktop_Shortcut codium - - fi - - software_id=37 # Shairport Sync - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/shairport-sync_$G_HW_ARCH_NAME.deb" - - fi - - software_id=48 # Pydio - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Install required PHP modules - DEPS_LIST="$PHP_NAME-apcu $PHP_NAME-gd $PHP_NAME-intl $PHP_NAME-mbstring $PHP_NAME-opcache $PHP_NAME-xml" - - # Skip install, if already present - if [[ -d /var/www/pydio ]]; then - - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/var/www/pydio\" already exists. Download and install steps will be skipped. - - Please manually backup your config files+data, remove the install dir and rerun \"dietpi-software (re)install $software_id\" if you need to reinstall. - - If you want to update the ${aSOFTWARE_NAME[$software_id]} instance, please use the internal updater from WebUI." - # shellcheck disable=SC2086 - G_AGI $DEPS_LIST - DEPS_LIST= - - else - - Download_Install 'https://download.pydio.com/pub/core/ci/pydio-latest.tar.gz' /var/www - mv /var/www/pydio-latest /var/www/pydio - - fi - - fi - - software_id=36 # Squeezelite - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/squeezelite_$G_HW_ARCH_NAME.deb" - - fi - - software_id=66 # RPi-Monitor - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - Download_Install 'https://raw.githubusercontent.com/XavierBerger/RPi-Monitor-deb/develop/packages/rpimonitor_2.13-beta6_all.deb' - - # Update APT package status - G_EXEC /usr/share/rpimonitor/scripts/updatePackagesStatus.pl - - # USB drive stats implementation by Rich - if [[ ! -f '/etc/rpimonitor/template/usb_hdd.conf' ]] && findmnt -S /dev/sda1 > /dev/null - then - G_EXEC sed -i '\|include=/etc/rpimonitor/template/sdcard.conf|a\include=/etc/rpimonitor/template/usb_hdd.conf' /etc/rpimonitor/data.conf - cat << '_EOF_' > /etc/rpimonitor/template/usb_hdd.conf -######################################################################## -# Extract USB HDD (sda1) information -# Page: 1 -# Information Status Statistics -# - USBHDD1 total - yes - yes -# - USBHDD1 used - yes - yes -######################################################################## -static.10.name=usbhdd_total -static.10.source=df -t ext4 -static.10.regexp=sda1\s+(\d+) -static.10.postprocess=$1/1024 - -dynamic.14.name=usbhdd_used -dynamic.14.source=df -t ext4 -dynamic.14.regexp=sda1\s+\d+\s+(\d+) -dynamic.14.postprocess=$1/1024 -dynamic.14.rrd=GAUGE - -web.status.1.content.9.name=USB HDD -web.status.1.content.9.icon=usb_hdd.png -web.status.1.content.9.line.1="/sda1 Used: "+KMG(data.usbhdd_used,'M')+" ("+Percent(data.udbhdd_used,data.usbhdd_total,'M')+") Free: "+KMG(data.usbhdd_total-data.usbhdd_used,'M')+ " Total: "+ KMG(data.usbhdd_total,'M') +"" -web.status.1.content.9.line.2=ProgressBar(data.usbhdd_used,data.usbhdd_total) - -web.statistics.1.content.9.name=USB HDD -web.statistics.1.content.9.graph.1=usbhdd_total -web.statistics.1.content.9.graph.2=usbhdd_used -web.statistics.1.content.9.ds_graph_options.usbhdd_total.label=USB HDD total space (MB) -web.statistics.1.content.9.ds_graph_options.usbhdd_total.color="#FF7777" -web.statistics.1.content.9.ds_graph_options.usbhdd_used.label=USB HDD used space (MB) -web.statistics.1.content.9.ds_graph_options.usbhdd_used.lines={ fill: true } -web.statistics.1.content.9.ds_graph_options.usbhdd_used.color="#7777FF" -_EOF_ - fi - - fi - - software_id=65 # Netdata - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # No package available on Stretch - if (( $G_DISTRO < 5 )); then - - # For ARMv6 RPi use our self-compiled package - if (( $G_HW_ARCH == 1 )); then - - DEPS_LIST='zlib1g-dev' - Download_Install 'https://dietpi.com/downloads/binaries/all/netdata_1.11.1-1_armv6l.deb' - - # Else use the packages from Debian Stretch backports snapshot, that were removed recently, hosted now on dietpi.com - else - - 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* - - fi - - else - - G_AGI netdata - - fi - - fi - - software_id=57 # Baïkal - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # APT deps: https://github.com/sabre-io/Baikal/wiki/Baïkal-dependencies - DEPS_LIST="$PHP_NAME-xml $PHP_NAME-mbstring $PHP_NAME-mysql" - - local fallback_url='https://github.com/sabre-io/Baikal/releases/download/0.8.0/baikal-0.8.0.zip' - Download_Install "$(curl -sSfL 'https://api.github.com/repos/sabre-io/Baikal/releases/latest' | mawk -F\" '/"browser_download_url": .*\/baikal-[^"\/]*\.zip"/{print $4}')" - - # Reinstall: https://sabre.io/baikal/upgrade/ - if [[ -d '/var/www/baikal' ]]; then - - [[ -d '/var/www/baikal/Specific' ]] && G_EXEC cp -a /var/www/baikal/Specific/. baikal/Specific/ - [[ -d '/var/www/baikal/config' ]] && G_EXEC cp -a /var/www/baikal/config/. baikal/config/ - G_EXEC rm -R /var/www/baikal + # Move log files to /var/log (dietpi-ramlog) + G_EXEC mkdir -p /var/log/roon /mnt/dietpi_userdata/roon/{RoonBridge,RAATServer} + # - Clear symlink locations + G_EXEC rm -Rf /mnt/dietpi_userdata/roon/{RoonBridge,RAATServer}/Logs + G_EXEC ln -s /var/log/roon /mnt/dietpi_userdata/roon/RoonBridge/Logs + G_EXEC ln -s /var/log/roon /mnt/dietpi_userdata/roon/RAATServer/Logs - fi - G_EXEC mv baikal /var/www/baikal + # Permissions + #chown -R roon:dietpi /mnt/dietpi_userdata/roon /var/log/roon fi - software_id=43 # Mumble Server + software_id=119 # CAVA if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_AGI mumble-server - - fi - - software_id=41 # Emby Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Installing + # ARMv6 + local url='https://dietpi.com/downloads/binaries/all/cava_0.6.1-1_armv6.deb' # ARMv7 - local arch='armhf' + if (( $G_HW_ARCH == 2 )); then + + url='https://dietpi.com/downloads/binaries/all/cava_0.6.1-1_armv7.deb' # ARMv8 - if (( $G_HW_ARCH == 3 )); then + elif (( $G_HW_ARCH == 3 )); then - arch='arm64' + url='https://dietpi.com/downloads/binaries/all/cava_0.6.1-1_arm64.deb' + # Using older binary for Odroid C2 due to: https://github.com/MichaIng/DietPi/issues/1340#issuecomment-393225267 + (( $G_HW_MODEL == 12 )) && url='https://dietpi.com/downloads/binaries/all/cava_0.4.2_arm64.deb' # x86_64 elif (( $G_HW_ARCH == 10 )); then - arch='amd64' + url='https://dietpi.com/downloads/binaries/all/cava_0.6.1-1_amd64.deb' 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" - 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}")" - - fi - - software_id=42 # Plex Media Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + G_THREAD_START curl -sSfL 'https://dietpi.com/downloads/binaries/all/cava.psf' -o /root/cava.psf # Font for nice bars - Banner_Installing + DEPS_LIST='libpulse0 libfftw3-3 libncursesw5' Download_Install "$url" - # 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" + # CAVA conf, preserve existing + [[ -f '/root/.config/cava/config' ]] || dps_index=$software_id Download_Install 'cava.conf' /root/.config/cava/config - # APT list - G_EXEC eval "echo 'deb https://downloads.plex.tv/repo/deb/ public main' > /etc/apt/sources.list.d/plexmediaserver.list" - G_AGUP + # Lower MPD buffer size to reduce latency of spectrum + G_EXEC sed -i '/audio_buffer_size /c\audio_buffer_size "384"' /etc/mpd.conf - # APT package - G_AGI plexmediaserver + # FIFO stream for mpd + grep -q '/tmp/mpd.fifo' /etc/mpd.conf || cat << '_EOF_' >> /etc/mpd.conf +# CAVA FIFO stream +audio_output { + type "fifo" + enabled "yes" + name "CAVA" + path "/tmp/mpd.fifo" + format "44100:16:2" +} +_EOF_ fi - software_id=52 # Cuberite + software_id=118 # Mopidy if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # ARMv6/7/8: https://github.com/cuberite/cuberite/issues/5221 - local url='https://download.cuberite.org/linux-armhf-raspbian/Cuberite.tar.gz' - - # x86_64 - (( $G_HW_ARCH == 10 )) && url='https://download.cuberite.org/linux-x86_64/Cuberite.tar.gz' - - Download_Install "$url" /mnt/dietpi_userdata/cuberite - - # User - Create_User -d /mnt/dietpi_userdata/cuberite cuberite - - # Service: Needs to be Type=forking, else it shuts down automatically after startup has finished :/ ... - cat << '_EOF_' > /etc/systemd/system/cuberite.service -[Unit] -Description=Cuberite Server (DietPi) - -[Service] -Type=forking -User=cuberite -WorkingDirectory=/mnt/dietpi_userdata/cuberite -ExecStart=/mnt/dietpi_userdata/cuberite/Cuberite -d + # Install our config file only, if not yet existent, to preserve manual user config. + # - This needs to be done prior to APT install, since this would otherwise install a default config file as well. + [[ -f '/etc/mopidy/mopidy.conf' ]] || dps_index=$software_id Download_Install 'mopidy.conf' /etc/mopidy/mopidy.conf -[Install] -WantedBy=multi-user.target -_EOF_ - # Web UI settings: Do not overwrite existing! - [[ -f '/mnt/dietpi_userdata/cuberite/webadmin.ini' ]] || cat << _EOF_ > /mnt/dietpi_userdata/cuberite/webadmin.ini -[User:admin] -Password=$GLOBAL_PW + # Official repo does not support ARMv8 + Stretch, using distro repo instead: https://github.com/mopidy/apt/tree/master/dists/stretch/main + if (( $G_HW_ARCH != 3 || $G_DISTRO > 4 )) + then + # APT key + local url='https://apt.mopidy.com/mopidy.gpg' + G_CHECK_URL "$url" + G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-mopidy.gpg --yes" -[WebAdmin] -Ports=1339 -Enabled=1 -_EOF_ - # Permissions - G_EXEC chmod 0600 /mnt/dietpi_userdata/cuberite/webadmin.ini - G_EXEC chown -R cuberite:cuberite /mnt/dietpi_userdata/cuberite - G_EXEC chmod +x /mnt/dietpi_userdata/cuberite/Cuberite + # APT list + G_EXEC curl -sSfL "https://apt.mopidy.com/${G_DISTRO_NAME/bullseye/buster}.list" -o /etc/apt/sources.list.d/mopidy.list + G_AGUP + fi - fi + # Stretch: Mopidy v2, pip2 and Mopidy-Local-Images + if (( $G_DISTRO < 5 )) + then + G_AGI mopidy gstreamer1.0-alsa python-pip python-dev + G_EXEC_OUTPUT=1 G_EXEC pip2 install -U pip setuptools wheel + G_EXEC_OUTPUT=1 G_EXEC pip2 install -U Mopidy-MusicBox-Webclient Mopidy-Local-Images - software_id=53 # MineOS - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then - Banner_Installing # https://minecraft.codeemo.com/mineoswiki/index.php?title=MineOS-node_(apt-get) + # Buster+: Mopidy v3, pip3 (ID=130) and mopidy-local: https://mopidy.com/ext/local/ + else + G_AGI mopidy gstreamer1.0-alsa mopidy-local + G_EXEC_OUTPUT=1 G_EXEC pip3 install -U Mopidy-MusicBox-Webclient + fi - local url='https://github.com/hexparrot/mineos-node.git' - G_CHECK_URL "$url" + # 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\]' + G_CONFIG_INJECT 'cache_dir[[:blank:]]*=' 'cache_dir = /mnt/dietpi_userdata/mopidy/cache' /etc/mopidy/mopidy.conf '\[core\]' - # APT deps - G_AGI python rdiff-backup rsync screen + # Move existing home+data to dietpi_userdata, if not yet existent + if [[ -d '/var/lib/mopidy' && ! -d '/mnt/dietpi_userdata/mopidy' ]] + then + G_EXEC mv /var/lib/mopidy /mnt/dietpi_userdata/mopidy + # Workaround error about moving data dir into itself + G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/.hidden_data + # Non-hidden files/folders are data + G_EXEC mv /mnt/dietpi_userdata/mopidy/* /mnt/dietpi_userdata/mopidy/.hidden_data + G_EXEC mv /mnt/dietpi_userdata/mopidy/.hidden_data /mnt/dietpi_userdata/mopidy/data + else + G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/data + [[ -d '/var/lib/mopidy' ]] && G_EXEC rm -R /var/lib/mopidy + fi - # Download/Update MineOS - G_EXEC mkdir -p /mnt/dietpi_userdata/mineos - G_EXEC cd /mnt/dietpi_userdata/mineos - if [[ -d 'minecraft' ]] + # Move existing cache to dietpi_userdata, if not yet existent + if [[ -d '/var/cache/mopidy' && ! -d '/mnt/dietpi_userdata/mopidy/cache' ]] then - # https://minecraft.codeemo.com/mineoswiki/index.php?title=Updating_the_Webui - G_EXEC cd minecraft - if [[ -x 'update_webui.sh' ]] - then - G_EXEC_OUTPUT=1 G_EXEC ./update_webui.sh - else - G_EXEC_OUTPUT=1 G_EXEC git fetch - G_EXEC_OUTPUT=1 G_EXEC git merge origin/master - fi + G_EXEC mv /var/cache/mopidy /mnt/dietpi_userdata/mopidy/cache else - G_EXEC_OUTPUT=1 G_EXEC git clone "$url" minecraft - G_EXEC cd minecraft + G_EXEC mkdir -p /mnt/dietpi_userdata/mopidy/cache + [[ -d '/var/cache/mopidy' ]] && G_EXEC rm -R /var/cache/mopidy fi - # File modes - G_EXEC git config core.filemode false - G_EXEC chmod +x mineos_console.js webui.js update_webui.sh reset_webui.sh generate-sslcert.sh + # Permissions + G_EXEC chown -R mopidy:root /mnt/dietpi_userdata/mopidy - # Install Node 11, as MineOS is currently not compatible with newer Node versions: https://github.com/hexparrot/mineos-node/issues/374 - G_EXEC_OUTPUT=1 G_EXEC npm i -g --unsafe-perm --no-audit n - G_EXEC_OUTPUT=1 G_EXEC n 11 + # User + G_EXEC usermod -g dietpi -aG audio -d /mnt/dietpi_userdata/mopidy mopidy + + # Do not pre-create obsolete cache dir + G_EXEC mkdir -p /etc/systemd/system/mopidy.service.d + echo -e '[Service]\nExecStartPre=' > /etc/systemd/system/mopidy.service.d/dietpi.conf + + Download_Test_Media - # Install MineOS - G_EXEC_OUTPUT=1 G_EXEC npm i --unsafe-perm --no-audit - G_EXEC cd /tmp/$G_PROGRAM_NAME fi - software_id=49 # Gogs + software_id=31 # Kodi if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # ARMv6: No pre-compiled binaries available, thus we use our own: https://github.com/gogs/gogs/releases - local url='https://dietpi.com/downloads/binaries/all/gogs_armv6.zip' - - # Else install latest binaries from GitHub - if (( $G_HW_MODEL != 1 )) + # CEC + NFS support + local apackages=() # Fixed package dependencies since Bullseye + if (( $G_DISTRO < 5 )) then - # ARMv7 - local arch='armv7' - - # ARMv8 - if (( $G_HW_ARCH == 3 )) - then - arch='armv8' - - # x86_64 - elif (( $G_HW_ARCH == 10 )) - then - arch='amd64' - fi + apackages=('libcec4' 'libnfs8') - local fallback_url="https://github.com/gogs/gogs/releases/download/v0.12.3/gogs_0.12.3_linux_$arch.tar.gz" - url=$(curl -sSfL 'https://api.github.com/repos/gogs/gogs/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/gogs_[^\"\/]*_linux_$arch.tar.gz\"/{print \$4}") + elif (( $G_DISTRO == 5 )) + then + apackages=('libcec4' 'libnfs12') fi - Download_Install "$url" - - # Remove old install dir, but preserve existing configs - 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 + # Odroids + if [[ $G_HW_MODEL == 1[0-9] ]]; then - fi + # Odroid C1/C2/N2/C4 + [[ $G_HW_MODEL == 1[0256] ]] && apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* aml-libs-odroid(,|$)' && apackages+=('aml-libs-odroid') - G_EXEC mv gogs /etc/gogs + # Odroid C1 + if (( $G_HW_MODEL == 10 )) + then + apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali400-odroid(,|$)' && apackages+=('mali400-odroid') - fi + # Odroid XU4 + elif (( $G_HW_MODEL == 11 )) + then + apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malit628-odroid(,|$)' && apackages+=('malit628-odroid') + apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* firmware-samsung(,|$)' && apackages+=('firmware-samsung') - software_id=46 # qBittorrent - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Odroid C2 + elif (( $G_HW_MODEL == 12 )) + then + apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali450-odroid(,|$)' && apackages+=('mali450-odroid') - Banner_Installing - G_AGI qbittorrent-nox + # Odroid N2 + elif (( $G_HW_MODEL == 15 )) + then + apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malig52-fbdev-opencl-odroid(,|$)' && apackages+=('malig52-fbdev-opencl-odroid') - # User - Create_User -g dietpi -d /home/qbittorrent qbittorrent + # Odroid C4 + elif (( $G_HW_MODEL == 16 )) + then + apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malig31-fbdev-opencl-odroid(,|$)' && apackages+=('malig31-fbdev-opencl-odroid') + fi - # Config: Create only on fresh install - if [[ ! -f '/home/qbittorrent/.config/qBittorrent/qBittorrent.conf' ]]; then + # Odroid N2/C4 + if [[ $G_HW_MODEL == 1[56] ]] + then + apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* kodi-aml-fbdev-odroid(,|$)' && apackages+=('kodi-aml-fbdev-odroid') || apackages=('kodi') + echo 'media_clock +firmware +decoder_common +stream_input +amvdec_avs +amvdec_h264 +amvdec_h264_4k2k +amvdec_mh264 +amvdec_h264mvc +amvdec_h265 +amvdec_mjpeg +amvdec_mmjpeg +amvdec_mpeg12 +amvdec_mpeg4 +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_EXEC mkdir -p /home/qbittorrent/.config/qBittorrent /var/log/qbittorrent - G_EXEC chown -R qbittorrent:root /var/log/qbittorrent - cat << _EOF_ > /home/qbittorrent/.config/qBittorrent/qBittorrent.conf -[General] -ported_to_new_savepath_system=true + # 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 -qE '^P(ackage|rovides):.* kodi-odroid(,|$)' && apackages+=('kodi-odroid') || apackages=('kodi') + fi -[Application] -FileLogger\Enabled=true -FileLogger\Path=/var/log/qbittorrent + # 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-fkms-v3d + Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/kodi_$G_HW_ARCH_NAME.deb" -[AutoRun] -enabled=false + # Everything else + else + apackages+=('kodi') -[LegalNotice] -Accepted=true + # 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') -[Preferences] -Advanced\AnonymousMode=false -Advanced\IncludeOverhead=false -Bittorrent\DHT=true -Bittorrent\DHTPort=6881 -Bittorrent\Encryption=1 -Bittorrent\LSD=true -Bittorrent\MaxConnecs=$(Optimise_BitTorrent 2) -Bittorrent\MaxConnecsPerTorrent=$(Optimise_BitTorrent 2) -Bittorrent\MaxUploads=$(Optimise_BitTorrent 3) -Bittorrent\MaxUploadsPerTorrent=$(Optimise_BitTorrent 3) -Bittorrent\PeX=true -Bittorrent\sameDHTPortAsBT=true -Bittorrent\uTP=true -Bittorrent\uTP_rate_limited=false -Connection\GlobalDLLimit=-1 -Connection\GlobalDLLimitAlt=10 -Connection\GlobalUPLimit=-1 -Connection\GlobalUPLimitAlt=10 -Connection\PortRangeMin=6881 -Connection\Proxy\Authentication=false -Connection\ProxyPeerConnections=false -Connection\ResolvePeerCountries=false -Connection\UPnP=true -Downloads\DiskWriteCacheSize=$(Optimise_BitTorrent 0) -Downloads\DiskWriteCacheTTL=60 -Downloads\PreAllocation=false -Downloads\SavePath=/mnt/dietpi_userdata/downloads -Downloads\TempPath=/mnt/dietpi_userdata/downloads -Downloads\TempPathEnabled=false -Downloads\UseIncompleteExtension=false -DynDNS\Enabled=false -General\Locale=en -IPFilter\Enabled=false -MailNotification\enabled=false -Queueing\IgnoreSlowTorrents=false -Queueing\MaxActiveDownloads=$(Optimise_BitTorrent 1) -Queueing\MaxActiveTorrents=$(Optimise_BitTorrent 1) -Queueing\MaxActiveUploads=1 -Queueing\QueueingEnabled=false -Scheduler\Enabled=false -WebUI\CSRFProtection=true -WebUI\ClickjackingProtection=true -WebUI\Enabled=true -WebUI\HTTPS\Enabled=false -WebUI\HostHeaderValidation=false -WebUI\LocalHostAuth=true -WebUI\Password_ha1=@ByteArray($(echo -n "$GLOBAL_PW" | md5sum | mawk '{print $1}')) -WebUI\Port=1340 -WebUI\SecureCookie=true -WebUI\UseUPnP=true -WebUI\Username=qbittorrent -_EOF_ + # 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 fi - # Since v4.2.0, the PBKDF2 needs to be used: https://github.com/MichaIng/DietPi/issues/4711 - (( $G_DISTRO < 6 )) || G_EXEC sed -i '/^WebUI\\Password_ha1/c\WebUI\\Password_PBKDF2="@ByteArray(tpgNK76AcpP14rjOZP9vwg==:rQNtOB0P4HfNj20pJtxiTBi9miduS6L1Xqqazc4Y6Gpm3Rn02jMXnPPT3KH2JMDKhFQjAaTGVJz0dz5JVw2QUQ==)"' /home/qbittorrent/.config/qBittorrent/qBittorrent.conf + G_AGI "${apackages[@]}" - # Service - cat << _EOF_ > /etc/systemd/system/qbittorrent.service -[Unit] -Description=qBittorrent (DietPi) -Documentation=man:qbittorrent-nox(1) -Wants=network-online.target -After=network-online.target + # 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 -[Service] -User=qbittorrent -UMask=002 -ExecStart=$(command -v qbittorrent-nox) + # Copy udev rules, probably not needed for root, but we'll do it anyway + dps_index=$software_id Download_Install '99-dietpi-kodi.rules' /etc/udev/rules.d/99-dietpi-kodi.rules -[Install] -WantedBy=multi-user.target -_EOF_ - # Permissions - G_EXEC chown -R qbittorrent:root /home/qbittorrent + # 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 + Create_Desktop_Shortcut kodi fi - software_id=107 # rTorrent + software_id=39 # ReadyMedia if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - DEPS_LIST='rtorrent mediainfo' - # On Buster, no "screen" is required to run rTorrent as daemon: https://github.com/rakshasa/rtorrent/wiki/Daemon_Mode - (( $G_DISTRO < 5 )) && DEPS_LIST+=' screen' - - # Install ruTorrent: Web UI for rTorrent - # - Grab current version - local version=$(curl -sSfL 'https://api.github.com/repos/Novik/ruTorrent/releases/latest' | mawk -F\" '/"tag_name": /{print $4}') - [[ $version ]] || { version='v3.10'; G_DIETPI-NOTIFY 1 "Automatic latest ruTorrent 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/Novik/ruTorrent/archive/$version.tar.gz" - - # - Reinstall - if [[ -d '/var/www/rutorrent' ]]; then + G_AGI minidlna - # Make new config files examples, if they exist in the old install already - [[ -f '/var/www/rutorrent/conf/config.php' ]] && G_EXEC mv "ruTorrent-${version#v}/conf/config.php"{,.example} - [[ -f '/var/www/rutorrent/conf/access.ini' ]] && G_EXEC mv "ruTorrent-${version#v}/conf/access.ini"{,.example} - [[ -f '/var/www/rutorrent/conf/plugins.ini' ]] && G_EXEC mv "ruTorrent-${version#v}/conf/plugins.ini"{,.example} + # User: Make "dietpi" the primary group to enable cross-access to media files + Create_User -g dietpi -G minidlna -d /var/lib/minidlna minidlna - # Merge new install into old to preserve e.g. 3rd party plugins - G_EXEC cp -a "ruTorrent-${version#v}/". /var/www/rutorrent/ - G_EXEC rm -R "ruTorrent-${version#v}" + # 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 - # - Fresh install - else + # Service + cat << _EOF_ > /etc/systemd/system/minidlna.service +[Unit] +Description=ReadyMedia (DietPi) +Wants=network-online.target +After=network-online.target - G_EXEC mv "ruTorrent-${version#v}" /var/www/rutorrent +[Service] +User=minidlna +ExecStart=$(command -v minidlnad) -S -R -f /etc/minidlna.conf -P /dev/null - fi +[Install] +WantedBy=multi-user.target +_EOF_ + # Bullseye: Debian patched forced file logging inside, overriding "-S": https://github.com/MichaIng/DietPi/issues/4745 + (( $G_DISTRO < 6 )) || G_CONFIG_INJECT 'LogsDirectory=' 'LogsDirectory=minidlna' /etc/systemd/system/minidlna.service '^User=' - # Install DarkBetter theme manually: https://github.com/MichaIng/DietPi/issues/3271 - if [[ -d '/var/www/rutorrent/plugins/theme/themes/DarkBetter' ]]; then + # Config + G_BACKUP_FP /etc/minidlna.conf + dps_index=$software_id Download_Install 'minidlna.conf' /etc/minidlna.conf - Download_Install 'https://github.com/chocolatkey/DarkBetter/archive/master.tar.gz' - G_EXEC rm -R /var/www/rutorrent/plugins/theme/themes/DarkBetter - G_EXEC mv DarkBetter-master /var/www/rutorrent/plugins/theme/themes/DarkBetter + # Cache + G_EXEC mkdir -p /mnt/dietpi_userdata/.MiniDLNA_Cache + G_EXEC chown -R minidlna:root /mnt/dietpi_userdata/.MiniDLNA_Cache - fi + Download_Test_Media fi - software_id=132 # Aria2 + software_id=108 # Amiberry if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_AGI aria2 - - # Web UI: Settings are stored client-wise, web UI files are never written by webserver. Thus root:root 022 permissions existing dir removal on reinstall can be done. - Download_Install 'https://github.com/ziahamza/webui-aria2/archive/master.tar.gz' - [[ -d '/var/www/aria2' ]] && G_EXEC rm -R /var/www/aria2 - G_EXEC mv webui-aria2-master /var/www/aria2 + # Libraries + # - wget: Used for WHDLoad database update: https://github.com/midwan/amiberry/commit/d6c103e3310bcf75c2d72a15849fbdf5eb7432b5 + DEPS_LIST='libxml2 libfreetype6 libflac8 libmpeg2-4 libmpg123-0 wget' # libpng16-16 pulled by libfreetype6 - fi + # Platform and GPU drivers + # - RPi + if (( $G_HW_MODEL < 10 )); then - software_id=116 # Medusa - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + local platform='rpi1' # Include ID -1 + 0 + (( $G_HW_MODEL > 1 )) && platform="rpi$G_HW_MODEL" + /boot/dietpi/func/dietpi-set_hardware rpi-opengl vc4-fkms-v3d + DEPS_LIST+=' libraspberrypi0' - Banner_Installing + # - Odroid XU4: https://dietpi.com/meveric/pool/main/s/setup-odroid/ + elif (( $G_HW_MODEL == 11 )); then - DEPS_LIST='mediainfo python3' + local platform='xu4' + DEPS_LIST+=' malit628-odroid' - if [[ -d '/mnt/dietpi_userdata/medusa' ]]; then + # - ASUS Tinker Board + elif (( $G_HW_MODEL == 52 )); then - # shellcheck disable=SC2086 - G_AGI $DEPS_LIST - DEPS_LIST= - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/mnt/dietpi_userdata/medusa\" already exists. Download and install steps will be skipped. - - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from WebUI. - - If you need to reinstall (e.g. broken instance), please manually backup your config files+data, remove the install dir and rerun \"dietpi-software (re)install $software_id\"." + local platform='RK3288' + DEPS_LIST+=' libegl1 libgles2 libgl1-mesa-dri' - else + fi - Download_Install 'https://github.com/pymedusa/Medusa/archive/master.tar.gz' /mnt/dietpi_userdata - G_EXEC mv /mnt/dietpi_userdata/{Medusa-master,medusa} + # Download Amiberry + Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/amiberry_$platform.tar.bz2" - fi + # Reinstall: Install new amiberry.conf as amiberry.conf_new, to preserve user settings and remove obsolete config file: https://github.com/midwan/amiberry/releases/tag/v2.25 + [[ -f '/mnt/dietpi_userdata/amiberry/conf/amiberry.conf' ]] && G_EXEC mv amiberry/conf/amiberry.conf /mnt/dietpi_userdata/amiberry/conf/amiberry.conf_new + [[ -f '/mnt/dietpi_userdata/amiberry/conf/adfdir.conf' ]] && G_EXEC rm /mnt/dietpi_userdata/amiberry/conf/adfdir.conf - fi + # Move/Merge new instance in place + G_EXEC cp -a amiberry /mnt/dietpi_userdata/ - software_id=50 # Syncthing - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Cleanup + G_EXEC_NOHALT=1 G_EXEC rm -R amiberry - Banner_Installing + # Service + cat << '_EOF_' > /etc/systemd/system/amiberry.service +[Unit] +Description=Amiberry Amiga Emulator (DietPi) +Documentation=https://github.com/midwan/amiberry/wiki - if [[ -d '/opt/syncthing' ]]; then +[Service] +WorkingDirectory=/mnt/dietpi_userdata/amiberry +Environment=LD_LIBRARY_PATH=/mnt/dietpi_userdata/amiberry/lib +ExecStartPre=/bin/chvt 3 +ExecStart=/mnt/dietpi_userdata/amiberry/amiberry +ExecStopPost=/bin/chvt 1 - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/syncthing\" already exists. Download and install steps will be skipped. - - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. - - if you need to reinstall (e.g. broken instance), please manually backup your config files+data, remove the install dir \"/opt/syncthing\" and rerun \"dietpi-software (re)install $software_id\"." +[Install] +WantedBy=local-fs.target +_EOF_ + # Permissions: Enable access for kickstart uploads via file servers + G_EXEC chgrp dietpi /mnt/dietpi_userdata/amiberry/kickstarts + G_EXEC chmod 0775 /mnt/dietpi_userdata/amiberry/kickstarts - else + fi - # ARMv6/7 - local arch='arm' + software_id=112 # DXX-Rebirth + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # ARMv8 - if (( $G_HW_ARCH == 3 )); then + Banner_Installing - arch+='64' + DEPS_LIST='libsdl-mixer1.2 libsdl1.2debian libphysfs1' + Download_Install 'https://dietpi.com/downloads/binaries/rpi/dxx-rebirth.7z' /mnt/dietpi_userdata - # x86_64 - elif (( $G_HW_ARCH == 10 )); then + # Symlink savegames to root + # - Remove existing symlinks + G_EXEC rm -Rf /root/.d{1,2}x-rebirth - arch='amd64' + G_EXEC ln -sf /mnt/dietpi_userdata/dxx-rebirth/descent_1_profiles /root/.d1x-rebirth + G_EXEC ln -sf /mnt/dietpi_userdata/dxx-rebirth/descent_2_profiles /root/.d2x-rebirth - fi + # +exe + G_EXEC chmod -R +x /mnt/dietpi_userdata/dxx-rebirth/* - local fallback_url="https://github.com/syncthing/syncthing/releases/download/v1.18.1/syncthing-linux-$arch-v1.18.1.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 + # Desktop menu entry + G_EXEC mkdir -p /usr/share/applications + G_EXEC ln -sf /mnt/dietpi_userdata/dxx-rebirth/dxx-rebirth.desktop /usr/share/applications/dxx-rebirth.desktop - fi + # Desktop shortcut + Create_Desktop_Shortcut dxx-rebirth fi - software_id=113 # Chromium + software_id=111 # UrBackup Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # Apply preference index - INDEX_BROWSER_TARGET=-2 INDEX_BROWSER_CURRENT=-2 + # Grab latest version + local url='https://hndl.urbackup.org/Server/latest' + G_CHECK_URL "$url" - if (( $G_HW_MODEL > 9 )) - then - G_AGI chromium + # Latest known version + local latest='2.4.13' - # RPi: Use RPi repo package - 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[@]}" - fi + # 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) - # Allow root, start maximized and disable sandbox under root (blank screen without) - local export_options="export CHROMIUM_FLAGS=\"\$CHROMIUM_FLAGS \ ---test-type \ ---no-sandbox \ ---temp-profile \ ---user-data-dir \ ---disable-smooth-scrolling \ ---disable-low-res-tiling \ ---enable-low-end-device-mode \ ---num-raster-threads=$G_HW_CPU_CORES \ ---profiler-timing=0 \ ---disable-composited-antialiasing" + # ARMv8 + if (( $G_HW_ARCH == 3 )); then - # RPi: Leave OpenGL choice to user, as it also depends on RPi model - if (( $G_HW_MODEL < 10 )) - 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) - # x86_64: OpenGL - elif [[ $G_HW_ARCH == 1 ]] - then - : + # 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) - # GLES - else - export_options+=' --use-gl=egl' fi - export_options+='"' + [[ $file ]] && url="$url/$file" || url=$fallback_url + unset -v file fallback_url - G_EXEC mkdir -p /etc/chromium.d - echo "$export_options" > /etc/chromium.d/custom_flags + debconf-set-selections <<< 'urbackup-server urbackup/backuppath string /mnt/dietpi_userdata/urbackup' + Download_Install "$url" - # Chromium 60+ - G_EXEC cp /etc/chromium.d/custom_flags /root/.chromium-browser.init + # As we have /tmp mounted to RAM, change tmp location + [[ -d '/mnt/dietpi_userdata/urbackup/tmp' ]] || 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 - # Desktop shortcut: chromium-browser.desktop on RPi - if (( $G_HW_MODEL > 9 )) - then - Create_Desktop_Shortcut chromium - else - Create_Desktop_Shortcut chromium-browser - fi + # https://github.com/MichaIng/DietPi/issues/545#issuecomment-252419739 + #sqlite3 /usr/local/var/urbackup/backup_server_settings.db "UPDATE settings SET value = '/mnt/dietpi_userdata/urbackup/' WHERE key = 'backupfolder'" - # 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 + fi -# 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" + software_id=51 # OpenTyrian + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then -# Resolution to use for kiosk mode, should ideally match current system resolution -RES_X=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_RES_X=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) -RES_Y=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_RES_Y=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + Banner_Installing -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' + DEPS_LIST='libsdl1.2debian libsdl-net1.2' + Download_Install 'https://dietpi.com/downloads/binaries/rpi/opentyrian_armhf.zip' / -# Add URL for first run: -URL=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_AUTOSTART_URL=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) -CHROMIUM_OPTS+=" --homepage $URL" + # Move to /usr/games + G_EXEC cp -a /usr/local/games/opentyrian /usr/games/ + G_EXEC rm -R /usr/local/games/opentyrian + G_EXEC chmod +x /usr/games/opentyrian/opentyrian -# Find absolute filepath location of Chromium binary. -FP_CHROMIUM=$(command -v chromium) -if [[ ! $FP_CHROMIUM ]]; then + # Desktop menu entry + G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/apps/opentyrian.desktop" -o /usr/share/applications/opentyrian.desktop - # Assume RPi - FP_CHROMIUM="$(command -v chromium-browser)" + # Copy the DietPi run file for OpenTyrian + dps_index=$software_id Download_Install 'run' /usr/games/opentyrian/run + G_EXEC chmod +x /usr/games/opentyrian/run -fi + # Desktop shortcut + Create_Desktop_Shortcut opentyrian -xinit $FP_CHROMIUM $CHROMIUM_OPTS -_EOF_ - G_EXEC chmod +x /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh + G_THREAD_WAIT fi - software_id=136 # MotionEye + software_id=59 # RPi Cam Control if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # Motion + dependencies - G_AGI motion v4l-utils curl python-pip python-dev gcc libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev + DEPS_LIST='gpac motion' + Download_Install 'https://github.com/silvanmelchior/RPi_Cam_Web_Interface/archive/master.tar.gz' - # MotionEye - G_EXEC_OUTPUT=1 G_EXEC pip2 install -U pip setuptools wheel - G_EXEC_OUTPUT=1 G_EXEC pip2 install -U motioneye + G_EXEC cd RPi_Cam_Web_Interface-master - # RPi: Enable camera module - (( $G_HW_MODEL < 10 )) && /boot/dietpi/func/dietpi-set_hardware rpi-camera enable + # Remove files which are not to be installed + [[ -f 'www/status_mjpeg.txt' ]] && G_EXEC rm www/status_mjpeg.txt - # Config - if [[ ! -f '/etc/motioneye/motioneye.conf' ]] - then - [[ -d '/etc/motioneye' ]] || G_EXEC mkdir -p /etc/motioneye - G_EXEC cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf + # Config /etc/motion/ + G_EXEC mkdir -p /etc/motion + G_EXEC cp etc/motion/motion.conf.1 /etc/motion/motion.conf - # Data - [[ -d '/mnt/dietpi_userdata/motioneye' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/motioneye - G_EXEC sed -i '/^media_path/c\media_path /mnt/dietpi_userdata/motioneye' /etc/motioneye/motioneye.conf - fi + # Config /etc/raspimjpeg + G_EXEC cp etc/raspimjpeg/raspimjpeg.1 /etc/raspimjpeg - # Service - G_EXEC cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service + # Setup /var/www/rpicam + G_EXEC mkdir -p /var/www/rpicam + G_EXEC cp -dR www/. /var/www/rpicam/ + [[ -e '/var/www/rpicam/FIFO' ]] || G_EXEC mknod /var/www/rpicam/FIFO p + [[ -e '/var/www/rpicam/FIFO1' ]] || G_EXEC mknod /var/www/rpicam/FIFO1 p - fi + # Allow shutdown and reboot via web interface + G_EXEC cp etc/sudoers.d/RPI_Cam_Web_Interface /etc/sudoers.d/dietpi-rpi_cam_control - software_id=137 # mjpg-streamer - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then - Banner_Installing + # Symlink cam preview and status + G_EXEC ln -sf /run/shm/mjpeg/cam.jpg /var/www/rpicam/cam.jpg + G_EXEC ln -sf /run/shm/mjpeg/status_mjpeg.txt /var/www/rpicam/status_mjpeg.txt - # Build dependencies - DEPS_LIST='make cmake gcc libc6-dev libjpeg-dev' - # - On RPi, add RPi Camera support by default - (( $G_HW_MODEL > 9 )) || DEPS_LIST+=' libraspberrypi-dev' + # Setup Raspimjpeg binary + # - Use Stretch binary on Stretch + (( $G_DISTRO < 5 )) && G_EXEC mv bin/raspimjpeg{-stretch,} + G_EXEC cp {,/usr/local/}bin/raspimjpeg + G_EXEC chmod +x /usr/local/bin/raspimjpeg - # Download sources - Download_Install 'https://github.com/jacksonliam/mjpg-streamer/archive/master.tar.gz' + # Cleanup / remove extracted source + G_EXEC cd /tmp/$G_PROGRAM_NAME + G_EXEC_NOFAIL=1 G_EXEC rm -R RPi_Cam_Web_Interface-master - # Compile - G_EXEC cd mjpg-streamer-master/mjpg-streamer-experimental - G_EXEC_OUTPUT=1 G_EXEC make CFLAGS='-g0 -O3' -j "$(nproc)" - G_EXEC strip --remove-section=.comment --remove-section=.note _build/mjpg_streamer + # raspimjpeg conf + G_EXEC ln -sf /etc/raspimjpeg /var/www/rpicam/raspimjpeg - # Move all plugin libraries into the executable's directory to avoid the need for LD_LIBRARY_PATH - G_EXEC mv _build/plugins/*/*.so _build/ + # Motion conf + G_EXEC chown motion:www-data /etc/motion/motion.conf + G_EXEC chmod 664 /etc/motion/motion.conf + G_EXEC usermod -aG video www-data - # Remove all left build files - G_EXEC rm -R _build/{{,C,c}[Mm]ake*,plugins} + # raspimjpeg/php schedule startup and control script + dps_index=$software_id Download_Install 'raspimjpeg.sh' /var/lib/dietpi/dietpi-software/installed/raspimjpeg.sh + G_EXEC chmod +x /var/lib/dietpi/dietpi-software/installed/raspimjpeg.sh + cat << '_EOF_' > /etc/systemd/system/raspimjpeg.service +[Unit] +Description=Raspimjpeg (DietPi) - # Install to system, in case remove previous installs - [[ -d '/opt/mjpg-streamer' ]] && G_EXEC rm -R /opt/mjpg-streamer - G_EXEC mv _build /opt/mjpg-streamer +[Service] +RemainAfterExit=yes +ExecStart=/var/lib/dietpi/dietpi-software/installed/raspimjpeg.sh start +ExecStop=/var/lib/dietpi/dietpi-software/installed/raspimjpeg.sh stop + +[Install] +WantedBy=multi-user.target +_EOF_ + # Replace configs with /var/www to /var/www/rpicam, once + if ! grep -q '/rpicam' /etc/raspimjpeg; then + + G_EXEC sed -i 's#/var/www#/var/www/rpicam#g' /etc/raspimjpeg + G_EXEC sed -i 's#/var/www#/var/www/rpicam#g' /etc/motion/motion.conf + + fi + + # Setup data directory + G_EXEC mkdir -p /mnt/dietpi_userdata/rpicam + G_EXEC rm -Rf /var/www/rpicam/media + G_EXEC ln -s /mnt/dietpi_userdata/rpicam /var/www/rpicam/media + + # Enable RPi camera + /boot/dietpi/func/dietpi-set_hardware rpi-camera enable + + # Permissions + G_EXEC chown -R www-data:www-data /var/www/rpicam /mnt/dietpi_userdata/rpicam - # Cleanup - G_EXEC cd /tmp/$G_PROGRAM_NAME - G_EXEC rm -R mjpg-streamer-master fi - software_id=138 # VirtualHere + software_id=45 # Deluge if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - local url='https://virtualhere.com/sites/default/files/usbserver/vhusbd' + # Packages + G_AGI deluged deluge-web deluge-console - # ARMv6/7 - if [[ $G_HW_ARCH == [12] ]]; then + # Remove SysV service leftovers, installed by Debian APT package + Remove_SysV deluged 1 + [[ -d '/var/lib/deluged' ]] && G_EXEC rm -R /var/lib/deluged + [[ -d '/var/log/deluged' ]] && G_EXEC rm -R /var/log/deluged - url+='arm' + # User + Create_User -g dietpi -G debian-deluged -d /mnt/dietpi_userdata/deluge debian-deluged - # ARMv8 - elif (( $G_HW_ARCH == 3 )); then + # Config + if [[ ! -f '/mnt/dietpi_userdata/deluge/.config/deluge/core.conf' ]] + then + [[ -d '/mnt/dietpi_userdata/deluge/.config/deluge' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/deluge/.config/deluge - url+='arm64' + # Default configs + dps_index=$software_id Download_Install 'deluge.conf' /mnt/dietpi_userdata/deluge/.config/deluge/core.conf + dps_index=$software_id Download_Install 'deluge_web.conf' /mnt/dietpi_userdata/deluge/.config/deluge/web.conf - # x86_64 - elif (( $G_HW_ARCH == 10 )); then + # Apply optimised settings + # - Cache size in 16 KiB units + G_CONFIG_INJECT '"cache_size":' " \"cache_size\": $(( $(Optimise_BitTorrent 0) * 1024 / 16 ))," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf + G_CONFIG_INJECT '"max_active_limit":' " \"max_active_limit\": $(Optimise_BitTorrent 1)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf + G_CONFIG_INJECT '"max_active_downloading":' " \"max_active_downloading\": $(Optimise_BitTorrent 1)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf + G_CONFIG_INJECT '"max_connections_global":' " \"max_connections_global\": $(Optimise_BitTorrent 2)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf + G_CONFIG_INJECT '"max_upload_slots_global":' " \"max_upload_slots_global\": $(Optimise_BitTorrent 3)," /mnt/dietpi_userdata/deluge/.config/deluge/core.conf - url+='x86_64' + # Web UI access + local salt=$(tr -dc '0-9a-f' < /dev/random | head -c40) + GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_salt":' " \"pwd_salt\": \"$salt\"," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf + GCI_PASSWORD=1 G_CONFIG_INJECT '"pwd_sha1":' " \"pwd_sha1\": \"$(echo -n "$salt$GLOBAL_PW" | sha1sum | mawk '{print $1}')\"," /mnt/dietpi_userdata/deluge/.config/deluge/web.conf + # Remote access + local localpass=$(tr -dc '0-9a-f' < /dev/random | head -c40) + > /mnt/dietpi_userdata/deluge/.config/deluge/auth + G_EXEC chmod 0600 /mnt/dietpi_userdata/deluge/.config/deluge/auth + echo -e "root:$GLOBAL_PW:10\nlocalclient:$localpass:10" > /mnt/dietpi_userdata/deluge/.config/deluge/auth fi - G_EXEC mkdir -p /etc/vhusbd - G_EXEC curl -sSfL "$url" -o /etc/vhusbd/vhusbd - G_EXEC chmod +x /etc/vhusbd/vhusbd + # Permissions + G_EXEC chown -R debian-deluged:root /mnt/dietpi_userdata/deluge + + # Service: https://github.com/deluge-torrent/deluge/blob/develop/packaging/systemd/deluged.service + cat << _EOF_ > /etc/systemd/system/deluged.service +[Unit] +Description=Deluge Daemon (DietPi) +Documentation=man:deluged + +[Service] +User=debian-deluged +UMask=002 +ExecStart=$(command -v deluged) -d + +[Install] +WantedBy=multi-user.target +_EOF_ + # https://github.com/deluge-torrent/deluge/blob/develop/packaging/systemd/deluge-web.service + # - Bullseye: deluge-web v2 requires the "-d" flag to stay in foreground, but v1 does not understand it yet + local flag= + (( $G_DISTRO < 6 )) || flag=' -d' + cat << _EOF_ > /etc/systemd/system/deluge-web.service +[Unit] +Description=Deluge Web UI (DietPi) +Documentation=man:deluge-web + +[Service] +User=debian-deluged +UMask=027 +ExecStart=$(command -v deluge-web)$flag +[Install] +WantedBy=multi-user.target +_EOF_ fi - software_id=139 # SABnzbd + software_id=115 # Webmin if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Installing # https://sabnzbd.org/wiki/installation/install-off-modules - - # 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' - - # Download - Download_Install "https://github.com/sabnzbd/sabnzbd/archive/$version.tar.gz" + Banner_Installing - # Reinstall: Remove old install dir - if [[ -d '/etc/sabnzbd' ]]; then + # APT key + local url='https://webmin.com/jcameron-key.asc' + G_CHECK_URL "$url" + G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-webmin.gpg --yes" - # 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 + # APT list + G_EXEC eval "echo 'deb https://download.webmin.com/download/repository/ sarge contrib' > /etc/apt/sources.list.d/webmin.list" + G_AGUP - fi + # APT package + G_AGI webmin - # Install - G_EXEC mv sabnzbd-$version /etc/sabnzbd + # Service + Remove_SysV webmin + cat << '_EOF_' > /etc/systemd/system/webmin.service +[Unit] +Description=Webmin (DietPi) +Documentation=https://doxfer.webmin.com/Webmin/Main_Page - # Python deps - G_EXEC cd /etc/sabnzbd - G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur requirements.txt - G_EXEC cd /tmp/$G_PROGRAM_NAME +[Service] +Type=forking +GuessMainPID=no +SyslogIdentifier=Webmin +ExecStart=/etc/webmin/start +ExecStop=/etc/webmin/stop +ExecReload=/etc/webmin/reload +[Install] +WantedBy=multi-user.target +_EOF_ fi - software_id=177 # Firefox Sync Server + software_id=195 # youtube-dl if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # Dependencies: https://github.com/mozilla-services/syncserver#quickstart - DEPS_LIST='python-virtualenv python-dev libmariadb-dev' - # - Additional module compiling required on ARM - (( $G_HW_ARCH < 10 )) && DEPS_LIST+=' libffi-dev libssl-dev' - - # Download & Install - local commit='c116417d653432db9470098236fb117adb349c36' # https://github.com/MichaIng/DietPi/issues/3774#issuecomment-703230290 - Download_Install "https://github.com/mozilla-services/syncserver/archive/$commit.tar.gz" - [[ -d '/opt/firefox-sync' ]] && G_EXEC rm -R /opt/firefox-sync - G_EXEC mv syncserver-$commit /opt/firefox-sync + DEPS_LIST='python3' - # Build - G_EXEC cd /opt/firefox-sync - G_EXEC_OUTPUT=1 G_EXEC make build - G_EXEC cd /tmp/$G_PROGRAM_NAME + # youtube-dl supports Python 2 and Python 3, but its shebang calls Python 2, else fails: https://github.com/ytdl-org/youtube-dl/issues/27649 + # We hence install the binary with Python 2 suffix and create a shell wrapper to call it with Python 3. + Download_Install 'https://yt-dl.org/downloads/latest/youtube-dl' /usr/local/bin/youtube-dl-py2 + echo -e '#!/bin/dash\nexec python3 /usr/local/bin/youtube-dl-py2 "$@"' > /usr/local/bin/youtube-dl + G_EXEC chmod +x /usr/local/bin/youtube-dl{,-py2} fi - software_id=183 # vaultwarden + software_id=129 # O!MPD if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # Dependencies: https://github.com/dani-garcia/vaultwarden/wiki/Building-binary#dependencies - DEPS_LIST='pkg-config libssl-dev' - - # 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"; } - Download_Install "https://github.com/dani-garcia/vaultwarden/archive/$version.tar.gz" + Download_Install 'https://github.com/ArturSierzant/OMPD/archive/master.tar.gz' /var/www + # Replace existing installs but preserve local config override + if [[ -d '/var/www/ompd' ]]; then - # Replace old instance on reinstall using new project name - [[ -d '/opt/vaultwarden' ]] && G_EXEC rm -R /opt/vaultwarden - G_EXEC mv "vaultwarden-$version" /opt/vaultwarden + [[ -f '/var/www/ompd/include/config.local.inc.php' ]] && G_EXEC mv /var/www/ompd/include/config.local.inc.php /var/www/OMPD-master/include/ + G_EXEC rm -R /var/www/ompd - # Assure 3 GiB overall memory on single-core and 4 GiB on multi-core systems (-200 MiB to avoid tiny swap space) - local ram_min=3 - (( $(nproc) > 1 )) && ram_min=4 - if (( $RAM_TOTAL < $ram_min * 1024 - 200 )) - then - G_DIETPI-NOTIFY 2 "Vaultwarden build requires at least $ram_min GiB memory. We will now increase your swap size to satisfy this requirement." - /boot/dietpi/func/dietpi-set_swapfile $(( $ram_min * 1024 - $RAM_TOTAL )) fi + G_EXEC mv /var/www/OMPD-master /var/www/ompd - # Temporarily assure 2 GiB /tmp size for temporary Rust install - (( $(findmnt -bno SIZE /tmp) < 2147483648 )) && G_EXEC mount -o remount,size=2G /tmp - - # Clean APT cache (which includes temporarily downloaded archives) when moved to RAM - [[ -d '/tmp/apt' ]] && G_EXEC apt-get clean + # Preserve config file, create local override if non-existent + # Database will be migrated automatically, so only create new on fresh install, using local override config as flag + if [[ ! -f '/var/www/ompd/include/config.local.inc.php' ]]; then - # Override $HOME to allow temporary Rust install to RAMdisk and DietPi-Software working directory, so all leftovers are automatically removed on script exit and/or reboot - export HOME="/tmp/$G_PROGRAM_NAME" + G_EXEC systemctl start mariadb + # - Create database user only, database will be created automatically + mysql -e "grant all privileges on ompd.* to ompd@localhost identified by '$GLOBAL_PW'" + systemctl stop mariadb - # Install Rust via https://rustup.rs/ - G_EXEC curl -sSfL https://sh.rustup.rs -o rustup-init.sh - G_EXEC chmod +x rustup-init.sh - G_EXEC ./rustup-init.sh -y --default-toolchain none - G_EXEC_NOHALT=1 G_EXEC rm rustup-init.sh - G_EXEC . .cargo/env + cat << _EOF_ > /var/www/ompd/include/config.local.inc.php + +_EOF_ + fi - # Build - G_EXEC cd /opt/vaultwarden - G_EXEC_OUTPUT=1 G_EXEC cargo build --features sqlite --release - G_EXEC cd /tmp/$G_PROGRAM_NAME + # Webserver configs + # - Lighttpd + if (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then - # Uninstall rust after compiling - G_EXEC rustup self uninstall -y + dps_index=$software_id Download_Install 'lighttpd.ompd.conf' /etc/lighttpd/conf-available/99-dietpi-ompd.conf + [[ -f '/etc/lighttpd/conf-enabled/99-dietpi-ompd.conf' ]] || G_EXEC lighty-enable-mod dietpi-ompd - # Restore $HOME - HOME='/root' + fi - # Install web vault - local fallback_url='https://github.com/dani-garcia/bw_web_builds/releases/download/v2.21.1/bw_web_v2.21.1.tar.gz' - Download_Install "$(curl -sSfL 'https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest' | mawk -F\" '/"browser_download_url": .*\/bw_web_[^"\/]*\.tar\.gz"/{print $4}')" /mnt/dietpi_userdata/vaultwarden + # Permissions: http://ompd.pl/configuration + G_EXEC chown -R www-data:www-data /var/www/ompd/{tmp,stream,cache} fi - software_id=193 # K3s + software_id=135 # IceCast + DarkIce if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # APT deps - G_AGI apparmor iptables - - # Fetch config file if it exists - if [[ -f '/boot/dietpi-k3s.yaml' && ! -f '/etc/rancher/k3s/config.yaml' ]] - then - G_EXEC mkdir -p '/etc/rancher/k3s' - G_EXEC cp '/boot/dietpi-k3s.yaml' '/etc/rancher/k3s/config.yaml' - fi - - # Install - G_EXEC curl -sSfL 'https://get.k3s.io/' -o install.sh - 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_NOHALT=1 G_EXEC rm install.sh - - # Do not enter into a server restart loop on failure - [[ -d '/etc/systemd/system/k3s.service.d' ]] || G_EXEC mkdir /etc/systemd/system/k3s.service.d - echo -e '[Service]\nRestart=on-success' > /etc/systemd/system/k3s.service.d/dietpi.conf - - # Enable cgroups used by Docker and alike - if [[ -f '/boot/boot.cmd' ]] && grep -q 'docker_optimizations' /boot/boot.cmd - then - # Armbian - [[ -f '/boot/armbianEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/armbianEnv.txt - # Radxa Zero - [[ -f '/boot/uEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/uEnv.txt - fi - - fi + G_AGI darkice icecast2 - software_id=141 # Spotify Connect Web - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # IceCast: Set passwords, if not yet done (default found) + sed -i "/hackme/c\ $GLOBAL_PW" /etc/icecast2/icecast.xml + sed -i "/hackme/c\ $GLOBAL_PW" /etc/icecast2/icecast.xml + sed -i "/hackme/c\ $GLOBAL_PW" /etc/icecast2/icecast.xml + # - Remove default service config + [[ -f '/etc/default/icecast2' ]] && G_EXEC rm /etc/default/icecast2 - Banner_Installing + # DarkIce + [[ -f '/etc/darkice.cfg' ]] || > /etc/darkice.cfg + G_EXEC chmod 0600 /etc/darkice.cfg + local input_device_index=$(arecord -l | mawk -F'[ :]' '/card/{print $2;exit}') + cat << _EOF_ > /etc/darkice.cfg +[general] +duration = 0 +bufferSecs = 3 +reconnect = yes - # Download and merge into existing directory - Download_Install 'https://github.com/Fornoth/spotify-connect-web/releases/download/0.0.4-alpha/spotify-connect-web_0.0.4-alpha.tar.gz' /mnt/dietpi_userdata +[input] +device = hw:$input_device_index,0 +sampleRate = 44100 +bitsPerSample = 16 +channel = 1 - # Service - cat << '_EOF_' > /etc/systemd/system/spotify-connect-web.service +[icecast2-0] +bitrateMode = vbr +format = vorbis +quality = 0.8 +server = localhost +port = 8000 +password = $GLOBAL_PW +mountPoint = DietPi +name = DietPi +description = DarkIce on DietPi +url = http://localhost +genre = none +public = no +#localDumpFile = /mnt/dietpi_userdata/darkice_recording.ogg +_EOF_ + Remove_SysV darkice 1 + cat << _EOF_ > /etc/systemd/system/darkice.service [Unit] -Description=Spotify Connect Web (DietPi) -Wants=network-online.target -After=network-online.target sound.target +Description=DarkIce (DietPi) +Requires=icecast2.service +After=icecast2.service [Service] -WorkingDirectory=/mnt/dietpi_userdata/spotify-connect-web -ExecStart=/mnt/dietpi_userdata/spotify-connect-web/spotify-connect-web +ExecStart=$(command -v darkice) [Install] WantedBy=multi-user.target _EOF_ fi - software_id=143 # Koel + software_id=63 # LinuxDash if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # APT dependencies: https://docs.koel.dev/#server > https://laravel.com/docs/master/deployment#server-requirements - # - PHP composer install fails if no PHP SQLite and cURL modules are installed and enabled, even when MariaDB is used later. - 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' - 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 - if [[ -d '/mnt/dietpi_userdata/koel' ]]; then - - [[ -f '/mnt/dietpi_userdata/koel/.env' ]] && G_EXEC mv /mnt/dietpi_userdata/koel/.env koel/ - G_EXEC rm -R /mnt/dietpi_userdata/koel - - fi - G_EXEC mv koel /mnt/dietpi_userdata/koel - - # Download and install composer - G_EXEC curl -sSfL https://getcomposer.org/composer-stable.phar -o /usr/local/bin/composer - G_EXEC chmod +x /usr/local/bin/composer - - # Enable required PHP modules - G_EXEC phpenmod bcmath ctype fileinfo json mbstring tokenizer xml pdo_sqlite curl sqlite3 - - # Install Koel - G_EXEC cd /mnt/dietpi_userdata/koel - G_EXEC_OUTPUT=1 G_EXEC composer install -n - G_EXEC cd /tmp/$G_PROGRAM_NAME + Download_Install 'https://github.com/afaqurk/linux-dash/archive/master.tar.gz' + G_EXEC mkdir -p /var/www/linuxdash + G_EXEC cp -a linux-dash-master/* /var/www/linuxdash/ + G_EXEC_NOHALT=1 G_EXEC rm -R linux-dash-master fi - software_id=144 # Sonarr + software_id=184 # Tor Relay if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - 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 + Banner_Installing + G_AGI tor - # 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" + local nickname= + G_WHIP_BUTTON_CANCEL_TEXT='Skip' + G_WHIP_INPUTBOX 'Pick a nickname for your relay.\n\nNB: This is optional, select "Skip" to leave it empty.' && nickname=$G_WHIP_RETURNED_VALUE - # Update package lists - G_AGUP + local email= + G_WHIP_BUTTON_CANCEL_TEXT='Skip' + G_WHIP_INPUTBOX 'Pick a contact email for your relay.\n\nNB: This is optional but encouraged, and it will be published depending on your relay.' && email=$G_WHIP_RETURNED_VALUE - # Pre-configure DEB package - G_EXEC eval "debconf-set-selections <<< 'sonarr sonarr/owning_group string dietpi'" - G_EXEC eval "debconf-set-selections <<< 'sonarr sonarr/config_directory string /mnt/dietpi_userdata/sonarr'" + local orport=443 + local invalid_text= + while : + do + G_WHIP_DEFAULT_ITEM=$orport + if G_WHIP_INPUTBOX "${invalid_text}Please enter the ORPort that people will use to connect to your Tor relay: +\nNB: This port needs to be forwarded by your router and/or opened in your firewall settings. Default value is: 443, which should be changed when running a webserver. +\nDo not use 9001, as this port is commonly associated with Tor and censors might scan for it." && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 1 + then + orport=$G_WHIP_RETURNED_VALUE + break + else + invalid_text='[ERROR] No valid entry found, value needs to be a sequence of integers. Please retry...\n\n' + fi + done - # Install Sonarr and mediainfo - G_AGI sonarr mediainfo + local ipv6= + if grep -q '^[[:blank:]]*CONFIG_ENABLE_IPV6=1' /boot/dietpi.txt + then + for i in $(hostname -I) + do + [[ $i == *.* ]] && continue + G_WHIP_DEFAULT_ITEM=$i + break + done + G_WHIP_BUTTON_CANCEL_TEXT='Skip' + G_WHIP_INPUTBOX "Please enter the private IPv6 address of this device. Skip this if you only want to use IPv4, or if this device doesn't have an IPv6 address." && ipv6=$G_WHIP_RETURNED_VALUE + fi - # 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' - [[ -f '/mnt/dietpi_userdata/sonarr/nzbdrone.pid' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /mnt/dietpi_userdata/sonarr/nzbdrone.pid - [[ -f '/mnt/dietpi_userdata/sonarr/nzbdrone.db.bak' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /mnt/dietpi_userdata/sonarr/nzbdrone.db.bak + local choice_required= + while : + do + G_WHIP_MENU_ARRAY=( + 'Bridge' ': Use this machine as an obfs4 bridge. This is the safest to run from home.' + 'Guard/Middle' ': Use this machine as a beginning or middle relay. Some info will be made public.' + 'Exit' ': Use this machine as an exit relay. This is most at risk for legal complaints.' + ) - fi + G_WHIP_MENU "${choice_required}Please choose which type of relay this should be set up as:" || { choice_required='[ERROR] A choice is required to finish the Tor install.\n\n'; continue; } - software_id=145 # Radarr - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then + if [[ $G_WHIP_RETURNED_VALUE == 'Exit' ]] + then + G_WHIP_BUTTON_OK_TEXT='YES' + G_WHIP_BUTTON_CANCEL_TEXT='NO' + G_WHIP_YESNO 'WARNING: DO NOT RUN AN EXIT RELAY FROM HOME. +\nAlso, it is highly recommended that you setup exit relays on dedicated servers. +\nBefore running an exit relay, check with your hosting provider to make sure they allow it. +\nAlso, set a reverse DNS (PTR) record (tor-exit is a good name), and preferably edit your WHOIS record to show that this is a Tor exit node. +\nWould you still like to continue?' || continue + fi - Banner_Installing + break + done - # APT dependencies - DEPS_LIST='mediainfo' - # - .NET: https://packages.microsoft.com/debian/ - if (( $G_HW_ARCH != 1 )) + if [[ $G_WHIP_RETURNED_VALUE == 'Bridge' ]] then - if (( $G_DISTRO < 5 )) - then - DEPS_LIST+=' libicu57' + G_AGI obfs4proxy + local obfs4port=80 + invalid_text= + while : + do + G_WHIP_DEFAULT_ITEM=$obfs4port + if G_WHIP_INPUTBOX "${invalid_text}Please enter the obfs4 port that people will use to connect to your bridge: +\nNB: This port needs to be forwarded by your router and/or opened in your firewall settings. Default value is: 80. Do not use default value if running a webserver. +\nDo not use 9001, as this port is commonly associated with Tor and censors might scan for it." && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 1; then + obfs4port=$G_WHIP_RETURNED_VALUE + break + else + invalid_text='[ERROR] No valid entry found, value needs to be a sequence of integers. Please retry...\n\n' + fi + done - elif (( $G_DISTRO == 5 )) - then - DEPS_LIST+=' libicu63' - else - DEPS_LIST+=' libicu67' - fi - fi + # Grant capability to bind to privileged ports below 1024 + (( $obfs4port < 1024 )) && G_EXEC setcap cap_net_bind_service=+ep "$(command -v obfs4proxy)" - # Reinstall: Skip download and install, advice to use internal updater from web UI - if [[ -d '/opt/radarr' ]] + cat << _EOF_ > /etc/tor/torrc +BridgeRelay 1 +ORPort $orport +ServerTransportPlugin obfs4 exec $(command -v obfs4proxy) +ServerTransportListenAddr obfs4 0.0.0.0:$obfs4port +ExtORPort auto +_EOF_ + G_EXEC mkdir -p /etc/systemd/system/tor@.service.d + G_EXEC eval "echo -e '[Service]\nNoNewPrivileges=no' > /etc/systemd/system/tor@.service.d/dietpi-relay.conf" + + elif [[ $G_WHIP_RETURNED_VALUE == 'Guard/Middle' ]] then - # shellcheck disable=SC2086 - G_AGI $DEPS_LIST - DEPS_LIST= - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/radarr\" already exists. Download and install steps will be skipped. - - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. - - If you need to reinstall (e.g. broken instance), please manually remove the install dir \"/opt/radarr\" and rerun \"dietpi-software reinstall $software_id\"." + cat << _EOF_ > /etc/tor/torrc +ORPort $orport +ExitRelay 0 +SocksPort 0 +ControlSocket 0 +_EOF_ + elif [[ $G_WHIP_RETURNED_VALUE == 'Exit' ]] + then + G_AGI unbound + aSOFTWARE_INSTALL_STATE[182]=1 - else - # ARMv6 - local url=$(curl -sSfL 'https://api.github.com/repos/Radarr/Radarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux\.tar\.gz"/{print $4}') - local version='3.2.2.5080' - local fallback_url="https://github.com/Radarr/Radarr/releases/download/v$version/Radarr.master.$version.linux.tar.gz" + cat << _EOF_ > /etc/tor/torrc +ORPort $orport +ExitRelay 1 +SocksPort 0 +ControlSocket 0 + +ExitPolicy accept *:20-21 +ExitPolicy accept *:43 +ExitPolicy accept *:53 +ExitPolicy accept *:79 +ExitPolicy accept *:80-81 +ExitPolicy accept *:88 +ExitPolicy accept *:110 +ExitPolicy accept *:143 +ExitPolicy accept *:220 +ExitPolicy accept *:389 +ExitPolicy accept *:443 +ExitPolicy accept *:464 +ExitPolicy accept *:531 +ExitPolicy accept *:543-544 +ExitPolicy accept *:554 +ExitPolicy accept *:636 +ExitPolicy accept *:706 +ExitPolicy accept *:749 +ExitPolicy accept *:873 +ExitPolicy accept *:902-904 +ExitPolicy accept *:981 +ExitPolicy accept *:989-990 +ExitPolicy accept *:991 +ExitPolicy accept *:992 +ExitPolicy accept *:993 +ExitPolicy accept *:995 +ExitPolicy accept *:1194 +ExitPolicy accept *:1220 +ExitPolicy accept *:1293 +ExitPolicy accept *:1500 +ExitPolicy accept *:1533 +ExitPolicy accept *:1677 +ExitPolicy accept *:1723 +ExitPolicy accept *:1755 +ExitPolicy accept *:1863 +ExitPolicy accept *:2082 +ExitPolicy accept *:2083 +ExitPolicy accept *:2086-2087 +ExitPolicy accept *:2095-2096 +ExitPolicy accept *:2102-2104 +ExitPolicy accept *:3690 +ExitPolicy accept *:4321 +ExitPolicy accept *:4643 +ExitPolicy accept *:5050 +ExitPolicy accept *:5190 +ExitPolicy accept *:5222-5223 +ExitPolicy accept *:5228 +ExitPolicy accept *:8008 +ExitPolicy accept *:8074 +ExitPolicy accept *:8082 +ExitPolicy accept *:8087-8088 +ExitPolicy accept *:8232-8233 +ExitPolicy accept *:8332-8333 +ExitPolicy accept *:8443 +ExitPolicy accept *:8888 +ExitPolicy accept *:9418 +ExitPolicy accept *:10000 +ExitPolicy accept *:11371 +ExitPolicy accept *:19294 +ExitPolicy accept *:19638 +ExitPolicy accept *:50002 +ExitPolicy accept *:64738 +ExitPolicy reject *:* +_EOF_ + [[ $ipv6 ]] && echo 'IPv6Exit 1' >> /etc/tor/torrc + # Apply Unbound as local DNS resolver for privacy reasons + command -v resolvconf > /dev/null && G_EXEC sed -i 's/dns-nameservers.*$/dns-nameservers 127.0.0.1/' /etc/network/interfaces + G_EXEC eval "echo 'nameserver 127.0.0.1' > /etc/resolv.conf" # Unbound is running and configured in the very next config step, so it is safe to switch the DNS nameserver right now. + fi - # ARMv7 - if (( $G_HW_ARCH == 2 )) - then - url=$(curl -sSfL 'https://api.github.com/repos/Radarr/Radarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-arm\.tar\.gz"/{print $4}') - fallback_url="https://github.com/Radarr/Radarr/releases/download/v$version/Radarr.master.$version.linux-core-arm.tar.gz" + echo 'ControlPort 9051' >> /etc/tor/torrc + echo 'CookieAuthentication 1' >> /etc/tor/torrc + [[ $nickname ]] && echo "Nickname $nickname" >> /etc/tor/torrc + [[ $email ]] && echo "ContactInfo $email" >> /etc/tor/torrc + [[ $ipv6 ]] && echo "ORPort [$ipv6]:$orport" >> /etc/tor/torrc - # ARMv8 - elif (( $G_HW_ARCH == 3 )) - then - url=$(curl -sSfL 'https://api.github.com/repos/Radarr/Radarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-arm64\.tar\.gz"/{print $4}') - fallback_url="https://github.com/Radarr/Radarr/releases/download/v$version/Radarr.master.$version.linux-core-arm64.tar.gz" + fi - # x86_64 - elif (( $G_HW_ARCH == 10 )) - then - url=$(curl -sSfL 'https://api.github.com/repos/Radarr/Radarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-x64\.tar\.gz"/{print $4}') - fallback_url="https://github.com/Radarr/Radarr/releases/download/v$version/Radarr.master.$version.linux-core-x64.tar.gz" - fi + software_id=182 # Unbound + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then + Banner_Installing - Download_Install "$url" - G_EXEC mv Radarr /opt/radarr - fi + G_DIETPI-NOTIFY 2 'Pre-configuring Unbound to avoid port binding conflicts' - # Radarr v2: Remove old PID file and database backups from DietPi-Arr_to_RAM - [[ -f '/mnt/dietpi_userdata/radarr/nzbdrone.pid' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /mnt/dietpi_userdata/radarr/nzbdrone.pid - [[ -f '/mnt/dietpi_userdata/radarr/nzbdrone.db.bak' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /mnt/dietpi_userdata/radarr/nzbdrone.db.bak - fi + # Download/update list of root hints + Download_Install 'https://www.internic.net/domain/named.root' /var/lib/unbound/root.hints - software_id=106 # Lidarr - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Create monthly cron job to keep root hints updated + echo -e '#!/bin/dash\n# Update Unbound root hints\ncurl -sSfL https://www.internic.net/domain/named.root -o /var/lib/unbound/root.hints' > /etc/cron.monthly/dietpi-unbound + G_EXEC chmod +x /etc/cron.monthly/dietpi-unbound - Banner_Installing + # Download base configuration if it does not exist yet + [[ -f '/etc/unbound/unbound.conf.d/dietpi.conf' ]] || dps_index=$software_id Download_Install 'unbound.conf' /etc/unbound/unbound.conf.d/dietpi.conf - # APT dependencies - DEPS_LIST='mediainfo' - # - .NET: https://packages.microsoft.com/debian/ - if (( $G_HW_ARCH != 1 )) + # Toggle IPv6 preference based on dietpi.txt settings + if grep -q 'CONFIG_ENABLE_IPV6=0' /boot/dietpi.txt then - if (( $G_DISTRO < 5 )) - then - DEPS_LIST+=' libicu57' + G_CONFIG_INJECT 'do-ip6:[[:blank:]]' ' do-ip6: no' /etc/unbound/unbound.conf.d/dietpi.conf - elif (( $G_DISTRO == 5 )) - then - DEPS_LIST+=' libicu63' - else - DEPS_LIST+=' libicu67' - fi + 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 fi - # Pre-v7.5 ARMv6: Migrate old install dir - [[ -d '/opt/Lidarr' && ! -d '/opt/lidarr' ]] && G_EXEC mv /opt/{L,l}idarr + # Stretch: Remove incompatible setting + (( $G_DISTRO < 5 )) && sed -i '/log-replies/d' /etc/unbound/unbound.conf.d/dietpi.conf - # Reinstall: Skip download and install, advice to use internal updater from web UI - if [[ -d '/opt/lidarr' ]] + # Since IP binding might be used, start after network interfaces have been configured, not when they just start to be configured + G_EXEC mkdir -p /etc/systemd/system/unbound.service.d + G_EXEC eval "echo -e '[Unit]\nWants=network-online.target\nAfter=network-online.target' > /etc/systemd/system/unbound.service.d/dietpi.conf" + + # Pi-hole + AdGuard Home part 1 + if (( ${aSOFTWARE_INSTALL_STATE[93]} > 0 || ${aSOFTWARE_INSTALL_STATE[126]} > 0 )) && grep -q '^[[:blank:]]*port:[[:blank:]][[:blank:]]*53$' /etc/unbound/unbound.conf.d/dietpi.conf then - # shellcheck disable=SC2086 - G_AGI $DEPS_LIST - DEPS_LIST= - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/lidarr\" already exists. Download and install steps will be skipped. - - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. - - If you need to reinstall (e.g. broken instance), please manually remove the install dir \"/opt/lidarr\" and rerun \"dietpi-software reinstall $software_id\"." + G_DIETPI-NOTIFY 2 'Configuring Unbound to work for your selected AdBlocker' + grep '^[[:blank:]]*nameserver[[:blank:]]' /etc/resolv.conf | grep -qvE '[[:blank:]]127.0.0.1(:53)?$' || echo 'nameserver 9.9.9.9' >> /etc/resolv.conf # Failsafe + G_CONFIG_INJECT 'port:[[:blank:]]' ' port: 5335' /etc/unbound/unbound.conf.d/dietpi.conf + G_CONFIG_INJECT 'interface:[[:blank:]]' ' interface: 127.0.0.1' /etc/unbound/unbound.conf.d/dietpi.conf + fi - else - # ARMv6 - local url=$(curl -sSfL 'https://api.github.com/repos/Lidarr/Lidarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux\.tar\.gz"/{print $4}') - local version='0.8.1.2135' - local fallback_url="https://github.com/Lidarr/Lidarr/releases/download/v$version/Lidarr.master.$version.linux.tar.gz" + [[ -f '/lib/systemd/system/unbound.service' ]] && G_EXEC systemctl restart unbound + G_AGI unbound + G_EXEC systemctl enable --now unbound # Failsafe - # ARMv7 - if (( $G_HW_ARCH == 2 )) + # Pi-hole part 2 + if (( ${aSOFTWARE_INSTALL_STATE[93]} == 2 )) + then + G_DIETPI-NOTIFY 2 'Configuring Pi-hole to use Unbound' + if [[ -f '/etc/dnsmasq.d/01-pihole.conf' ]] then - url=$(curl -sSfL 'https://api.github.com/repos/Lidarr/Lidarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-arm\.tar\.gz"/{print $4}') - fallback_url="https://github.com/Lidarr/Lidarr/releases/download/v$version/Lidarr.master.$version.linux-core-arm.tar.gz" - - # ARMv8 - elif (( $G_HW_ARCH == 3 )) + G_EXEC sed -i '/^[[:blank:]]*server=/d' /etc/dnsmasq.d/01-pihole.conf + G_CONFIG_INJECT 'server=' 'server=127.0.0.1#5335' /etc/dnsmasq.d/01-pihole.conf + systemctl -q is-active pihole-FTL && G_EXEC systemctl restart pihole-FTL + fi + if [[ -f '/etc/pihole/setupVars.conf' ]] then - url=$(curl -sSfL 'https://api.github.com/repos/Lidarr/Lidarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-arm64\.tar\.gz"/{print $4}') - fallback_url="https://github.com/Lidarr/Lidarr/releases/download/v$version/Lidarr.master.$version.linux-core-arm64.tar.gz" + G_CONFIG_INJECT 'PIHOLE_DNS_1=' 'PIHOLE_DNS_1=127.0.0.1#5335' /etc/pihole/setupVars.conf + G_EXEC sed -i '/^[[:blank:]]*PIHOLE_DNS_2=/d' /etc/pihole/setupVars.conf + fi + fi - # x86_64 - elif (( $G_HW_ARCH == 10 )) + # AdGuard Home part 2 + if (( ${aSOFTWARE_INSTALL_STATE[126]} == 2 )) + then + G_DIETPI-NOTIFY 2 'Configuring AdGuard Home to use Unbound' + if [[ ! -f '/mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf' ]] then - url=$(curl -sSfL 'https://api.github.com/repos/Lidarr/Lidarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-x64\.tar\.gz"/{print $4}') - fallback_url="https://github.com/Lidarr/Lidarr/releases/download/v$version/Lidarr.master.$version.linux-core-x64.tar.gz" + echo '127.0.0.1:5335' > /mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf + G_CONFIG_INJECT 'upstream_dns_file:[[:blank:]]' ' upstream_dns_file: /mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf' /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml + systemctl -q is-active adguardhome && G_EXEC systemctl restart adguardhome fi - - Download_Install "$url" - G_EXEC mv Lidarr /opt/lidarr fi - # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/lidarr + # Plex Media Server: Fix secure remote access: https://dietpi.com/phpbb/viewtopic.php?t=8896 + (( ${aSOFTWARE_INSTALL_STATE[42]} > 0 )) && echo -e 'server:\n\tprivate-domain: "plex.direct"' > /etc/unbound/unbound.conf.d/dietpi-plex.conf + fi - # User - Create_User -g dietpi -d /mnt/dietpi_userdata/lidarr lidarr + software_id=93 # Pi-hole + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then + Banner_Installing - # Service: https://github.com/lidarr/Lidarr/wiki/Autostart-on-Linux#systemd - cat << _EOF_ > /etc/systemd/system/lidarr.service -[Unit] -Description=Lidarr Daemon (DietPi) -Wants=network-online.target -After=network-online.target + local url='https://raw.githubusercontent.com/pi-hole/pi-hole/master/automated%20install/basic-install.sh' + G_CHECK_URL "$url" -[Service] -SyslogIdentifier=Lidarr -User=lidarr -UMask=002 -ExecStart=/opt/lidarr/Lidarr -nobrowser -data=/mnt/dietpi_userdata/lidarr -TimeoutStopSec=20 -KillMode=process -Restart=on-failure + # Check free available memory. Increase swap size to prevent gravity running out of memory. + if (( $(free -m | mawk '/^Mem:/{print $7;exit}') < 512 && $(free -m | mawk '/^Swap:/{print $2;exit}') < 512 )) + then + G_DIETPI-NOTIFY 2 'Increasing swap size to 512 MiB for running gravity.sh, please wait...\n' + /boot/dietpi/func/dietpi-set_swapfile 512 + fi -# Hardening -ProtectSystem=strict -ProtectHome=true -PrivateDevices=true -ProtectKernelTunables=true -ProtectControlGroups=true -ReadWritePaths=-/opt/lidarr -/mnt -/media -/var/log/lidarr -/tmp + # Dependencies: https://github.com/pi-hole/pi-hole/blob/development/automated%20install/basic-install.sh#L250 + G_AGI $PHP_NAME-xml $PHP_NAME-sqlite3 $PHP_NAME-intl -[Install] -WantedBy=multi-user.target -_EOF_ - # - ARMv6 devices use Mono - (( $G_HW_ARCH == 1 )) && G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v mono) /opt/lidarr/Lidarr.exe -nobrowser -data=/mnt/dietpi_userdata/lidarr" /etc/systemd/system/lidarr.service + # Unbound: Switch port to 5335 if it was installed before, else it got just configured within its install step above + if (( ${aSOFTWARE_INSTALL_STATE[182]} == 2 )) && grep -q '^[[:blank:]]*port:[[:blank:]][[:blank:]]*53$' /etc/unbound/unbound.conf.d/dietpi.conf + then + G_DIETPI-NOTIFY 2 'Configuring Unbound to work for Pi-hole' + grep '^[[:blank:]]*nameserver[[:blank:]]' /etc/resolv.conf | grep -qvE '[[:blank:]]127.0.0.1(:53)?$' || echo 'nameserver 9.9.9.9' >> /etc/resolv.conf # Failsafe + G_CONFIG_INJECT 'port:[[:blank:]]' ' port: 5335' /etc/unbound/unbound.conf.d/dietpi.conf + G_CONFIG_INJECT 'interface:[[:blank:]]' ' interface: 127.0.0.1' /etc/unbound/unbound.conf.d/dietpi.conf + G_EXEC systemctl restart unbound + fi - # Logs to RAM - G_EXEC rm -Rf /mnt/dietpi_userdata/lidarr/logs* - G_EXEC mkdir -p /var/log/lidarr - G_EXEC ln -s /var/log/lidarr /mnt/dietpi_userdata/lidarr/logs - G_EXEC ln -s /var/log/lidarr/logs.db /mnt/dietpi_userdata/lidarr/logs.db - G_EXEC ln -s /var/log/lidarr/logs.db-shm /mnt/dietpi_userdata/lidarr/logs.db-shm - G_EXEC ln -s /var/log/lidarr/logs.db-wal /mnt/dietpi_userdata/lidarr/logs.db-wal + # Install + G_EXEC curl -sSfL "$url" -o install.sh + G_EXEC chmod +x install.sh + # - Skip web server install, since we allow to choose and install it prior to Pi-hole + # - Skip supported OS check. We do not support Debian testing suite but we are testing it already now. + export PIHOLE_SKIP_OS_CHECK=true + G_EXEC_NOEXIT=1 G_EXEC_OUTPUT=1 G_EXEC ./install.sh --disable-install-webserver || aSOFTWARE_INSTALL_STATE[$software_id]=0 + G_EXEC_NOHALT=1 G_EXEC rm install.sh - # Permissions - G_EXEC chown -R lidarr:dietpi /mnt/dietpi_userdata/lidarr /opt/lidarr /var/log/lidarr + # Apply most resource friendly and officially recommended NULL blocking: https://docs.pi-hole.net/ftldns/blockingmode/ + G_CONFIG_INJECT 'BLOCKINGMODE=' 'BLOCKINGMODE=NULL' /etc/pihole/pihole-FTL.conf - fi + # Disable pihole.log query logging: https://github.com/pi-hole/FTL/issues/614#issuecomment-510564476 + G_EXEC pihole -l off - software_id=180 # Bazarr - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Unbound: Configure Pi-hole to use it + if (( ${aSOFTWARE_INSTALL_STATE[182]} > 0 )) + then + G_DIETPI-NOTIFY 2 'Configuring Pi-hole to use Unbound' + G_EXEC sed -i '/^[[:blank:]]*server=/d' /etc/dnsmasq.d/01-pihole.conf + G_CONFIG_INJECT 'server=' 'server=127.0.0.1#5335' /etc/dnsmasq.d/01-pihole.conf + systemctl -q is-active pihole-FTL && G_EXEC systemctl restart pihole-FTL + G_CONFIG_INJECT 'PIHOLE_DNS_1=' 'PIHOLE_DNS_1=127.0.0.1#5335' /etc/pihole/setupVars.conf + G_EXEC sed -i '/^[[:blank:]]*PIHOLE_DNS_2=/d' /etc/pihole/setupVars.conf + fi - Banner_Installing # https://wiki.bazarr.media/Getting-Started/Installation/Linux/linux/ + # Enable required PHP modules: https://github.com/pi-hole/pi-hole/blob/development/automated%20install/basic-install.sh#L250 + G_EXEC phpenmod xml sqlite3 intl - if [[ -d '/opt/bazarr' ]]; then + # Webserver configs + # - Lighttpd + if (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/bazarr\" already exists. Download and install steps will be skipped. - - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. - - If you need to reinstall (e.g. broken instance), please manually remove the install dir \"/opt/bazarr\" and rerun \"dietpi-software reinstall $software_id\"." + # Enable required modules + G_CONFIG_INJECT '"mod_setenv",' ' "mod_setenv",' /etc/lighttpd/lighttpd.conf '"mod_.+",' - else + # Add and enable Pi-hole config + dps_index=$software_id Download_Install 'lighttpd.pihole.conf' /etc/lighttpd/conf-available/99-dietpi-pihole.conf + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod dietpi-pihole - Download_Install 'https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip' /opt/bazarr + # Optional config to block public access to admin panel + dps_index=$software_id Download_Install 'lighttpd.block_public_admin.conf' /etc/lighttpd/conf-available/99-dietpi-pihole-block_public_admin.conf + local enable_cmd='lighty-enable-mod dietpi-pihole-block_public_admin' + local disable_cmd='lighty-disable-mod dietpi-pihole-block_public_admin' - fi + # - Apache + elif (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + + # Enable required modules + G_EXEC a2enmod headers + + # Add and enable Pi-hole config + dps_index=$software_id Download_Install 'apache.pihole.conf' /etc/apache2/sites-available/dietpi-pihole.conf + G_EXEC a2ensite dietpi-pihole - # ARM: Install known required Python modules via APT to avoid time-consuming compiling and large build dependencies (on x86 pre-compiled wheels are available) - (( $G_HW_ARCH == 10 )) || G_AGI python3-{lxml,numpy} + # Optional config to block public access to admin panel + dps_index=$software_id Download_Install 'apache.block_public_admin.conf' /etc/apache2/sites-available/dietpi-pihole-block_public_admin.conf + local enable_cmd='a2ensite dietpi-pihole-block_public_admin' + local disable_cmd='a2dissite dietpi-pihole-block_public_admin' - G_EXEC cd /opt/bazarr - G_EXEC_OUTPUT=1 G_EXEC pip3 install -r requirements.txt - G_EXEC cd /tmp/$G_PROGRAM_NAME + # - Nginx + elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - fi + # Add Pi-hole config + dps_index=$software_id Download_Install 'nginx.pihole.conf' /etc/nginx/sites-dietpi/dietpi-pihole.conf - software_id=146 # Tautulli - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Optional config to block public access to admin panel + dps_index=$software_id Download_Install 'nginx.block_public_admin.conf' /etc/nginx/sites-dietpi/dietpi-pihole-block_public_admin.off + local enable_cmd='mv /etc/nginx/sites-dietpi/dietpi-pihole-block_public_admin.{off,on}' + local disable_cmd='mv /etc/nginx/sites-dietpi/dietpi-pihole-block_public_admin.{on,off}' - Banner_Installing + fi - if [[ -d '/opt/tautulli' ]]; then + # Ask user if they want to block public access to the admin panel + G_WHIP_BUTTON_OK_TEXT='YES' + G_WHIP_BUTTON_CANCEL_TEXT='NO' + G_WHIP_YESNO "In order to increase security, it is recommended to block public access to the Pi-hole admin panel, so that only connections from within your LAN or via VPN are possible. +\nPractically this means to deny access from all IPs that do not match the reserved loopback and LAN ranges: + - 127.* + - 192.168.* + - 10.* + - 172.16.* - 172.31.* + - ::1 + - fe80:* - febf:* + - fc00:* - fdff:* +\nYou can always enable/disable this later using the commands: + - $enable_cmd + - $disable_cmd +\nDo you want to block public access to the admin panel now?" && eval "$enable_cmd" - G_AGI python3-pkg-resources - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/tautulli\" already exists. Download and install steps will be skipped. - - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from WebUI. - - if you need to reinstall (e.g. broken instance), please manually backup your config files+data, remove the install dir \"/opt/tautulli\" and rerun \"dietpi-software reinstall $software_id\"." + # Create symlinks to align Pi-hole admin and 404 page relative to webroot + [[ -e '/var/www/admin' && ! -L '/var/www/admin' ]] && G_EXEC mv /var/www/admin{,.bak} + G_EXEC ln -sf /var/www/{html/admin,admin} + [[ -e '/var/www/pihole' && ! -L '/var/www/pihole' ]] && G_EXEC mv /var/www/pihole{,.bak} + G_EXEC ln -sf /var/www/{html/pihole,pihole} - else + # Pi-hole v5: Add webserver user to pihole group to allow gravity.db access from web UI: https://github.com/MichaIng/DietPi/issues/3391 + G_EXEC usermod -aG pihole www-data - local url='https://github.com/Tautulli/Tautulli.git' - G_CHECK_URL "$url" - G_THREAD_START git clone --depth 1 "$url" - G_AGI python3-pkg-resources - G_THREAD_WAIT - G_EXEC mv Tautulli /opt/tautulli + # Set web interface PW: https://github.com/MichaIng/DietPi/issues/662 + pihole -a -p "$GLOBAL_PW" - fi + # Reduce long-term database TTL: https://github.com/MichaIng/DietPi-Docs/issues/476 + G_DIETPI-NOTIFY 2 'The DNS query database logging duration is reduced to 2 days. If you require long-term query logs, read our docs about how to change the log duration: +- https://dietpi.com/docs/software/dns_servers/#pi-hole' + G_CONFIG_INJECT 'MAXDBDAYS=' 'MAXDBDAYS=2' /etc/pihole/pihole-FTL.conf fi - software_id=147 # Jackett + software_id=126 # AdGuard Home if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # Grab latest version download link - - # - 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' + # ARMv6 + local url='https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv6.tar.gz' - # - ARMv7 + # ARMv7 if (( $G_HW_ARCH == 2 )); then - url=${url/Mono/LinuxARM32} - fallback_url=${fallback_url/Mono/LinuxARM32} + url='https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv7.tar.gz' - # - ARMv8 + # ARMv8 elif (( $G_HW_ARCH == 3 )); then - url=${url/Mono/LinuxARM64} - fallback_url=${fallback_url/Mono/LinuxARM64} + url='https://static.adguard.com/adguardhome/release/AdGuardHome_linux_arm64.tar.gz' - # - x86_64 + # x86_64 elif (( $G_HW_ARCH == 10 )); then - url=${url/Mono/LinuxAMDx64} - fallback_url=${fallback_url/Mono/LinuxAMDx64} + url='https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz' fi - # .NET dependencies: https://packages.microsoft.com/debian/ - if (( $G_HW_ARCH != 1 )) + # Deps: apache2-utils is required for htpasswd command to create bcrypt password hashes + DEPS_LIST='apache2-utils' + Download_Install "$url" + + # Install to userdata until it is possible to split binary and data/config without breaking the updater: https://github.com/AdguardTeam/AdGuardHome/issues/3286 + [[ -d '/mnt/dietpi_userdata/adguardhome' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/adguardhome + G_EXEC cp -a AdGuardHome/. /mnt/dietpi_userdata/adguardhome/ + G_EXEC rm -R AdGuardHome + + [[ -d '/opt/adguardhome' ]] && G_EXEC rm -R /opt/adguardhome # v7.3 beta + + # Unbound: Switch port to 5335 if it was installed before, else it got just configured within its install step above + if (( ${aSOFTWARE_INSTALL_STATE[182]} == 2 )) && grep -q '^[[:blank:]]*port:[[:blank:]][[:blank:]]*53$' /etc/unbound/unbound.conf.d/dietpi.conf then - DEPS_LIST='liblttng-ust0' - if (( $G_DISTRO < 5 )) - then - DEPS_LIST+=' libicu57' + G_DIETPI-NOTIFY 2 'Configuring Unbound to work for AdGuard Home' + grep '^[[:blank:]]*nameserver[[:blank:]]' /etc/resolv.conf | grep -qvE '[[:blank:]]127.0.0.1(:53)?$' || echo 'nameserver 9.9.9.9' >> /etc/resolv.conf # Failsafe + G_CONFIG_INJECT 'port:[[:blank:]]' ' port: 5335' /etc/unbound/unbound.conf.d/dietpi.conf + G_CONFIG_INJECT 'interface:[[:blank:]]' ' interface: 127.0.0.1' /etc/unbound/unbound.conf.d/dietpi.conf + G_EXEC systemctl restart unbound + fi - elif (( $G_DISTRO == 5 )) - then - DEPS_LIST+=' libicu63' - else - DEPS_LIST+=' libicu67' - fi + # User + Create_User -d /mnt/dietpi_userdata/adguardhome adguardhome + + # Config + if [[ ! -f '/mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml' ]] + then + dps_index=$software_id Download_Install 'AdGuardHome.yaml' /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml + # shellcheck disable=SC2016 + G_CONFIG_INJECT 'password:[[:blank:]]' " password: $(htpasswd -bnBC 10 '' "$GLOBAL_PW" | tr -d ':\n' | sed 's/\$2y/\$2a/')" /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml fi - Download_Install "$url" /opt + # Unbound: Configure AdGuard Home to use it + if [[ ${aSOFTWARE_INSTALL_STATE[182]} -gt 0 && ! -f '/mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf' ]] + then + G_DIETPI-NOTIFY 2 'Configuring AdGuard Home to use Unbound' + echo '127.0.0.1:5335' > /mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf + G_CONFIG_INJECT 'upstream_dns_file:[[:blank:]]' ' upstream_dns_file: /mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf' /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml + systemctl -q is-active adguardhome && G_EXEC systemctl restart adguardhome + fi - # Move existing configs to unpacked install dir - [[ -d '/opt/jackett/Jackett' ]] && G_EXEC mv /opt/jackett/Jackett /opt/Jackett/ - [[ -d '/opt/jackett/.mono' ]] && G_EXEC mv /opt/jackett/.mono /opt/Jackett/ + # Permissions + G_EXEC chown -R adguardhome:adguardhome /mnt/dietpi_userdata/adguardhome + G_EXEC chmod 0755 /mnt/dietpi_userdata/adguardhome/AdGuardHome + G_EXEC chmod 0600 /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml - # Remove existing install dir - [[ -d '/opt/jackett' ]] && G_EXEC rm -R /opt/jackett + # Service + cat << '_EOF_' > /etc/systemd/system/adguardhome.service +[Unit] +Description=AdGuard Home (DietPi) +Wants=network-online.target +After=network-online.target - # Move unpacked install dir in place - G_EXEC mv /opt/Jackett /opt/jackett +# Restart attempt only 5 times +StartLimitIntervalSec=60 +StartLimitBurst=5 + +[Service] +User=adguardhome +AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW +ExecStart=/mnt/dietpi_userdata/adguardhome/AdGuardHome +ExecReload=/mnt/dietpi_userdata/adguardhome/AdGuardHome -s reload +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +_EOF_ + # AdGuard Home service needs to be started by systemd, as dietpi-services must not control it to prevent it from killing the systems own DNS server. + G_EXEC systemctl enable adguardhome + aSTART_SERVICES+=('adguardhome') fi - software_id=149 # NZBGet + software_id=33 # Airsonic if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_EXEC curl -sSfL 'https://nzbget.net/download/nzbget-latest-bin-linux.run' -o package.run - G_EXEC mkdir -p /mnt/dietpi_userdata/nzbget - G_EXEC_OUTPUT=1 G_EXEC dash package.run --destdir /mnt/dietpi_userdata/nzbget - G_EXEC_NOHALT=1 G_EXEC rm package.run + 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 # User - Create_User -g dietpi -d /mnt/dietpi_userdata/nzbget nzbget - - # Permissions - G_EXEC chown -R nzbget:root /mnt/dietpi_userdata/nzbget - G_EXEC chmod 0600 /mnt/dietpi_userdata/nzbget/nzbget.conf - - # Config - G_BACKUP_FP /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'MainDir=' 'MainDir=/mnt/dietpi_userdata/downloads' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'DestDir=' 'DestDir=/mnt/dietpi_userdata/downloads/complete' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'LogFile=' 'LogFile=/var/log/nzbget.log' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'ControlUsername=' 'ControlUsername=admin' /mnt/dietpi_userdata/nzbget/nzbget.conf - GCI_PASSWORD=1 G_CONFIG_INJECT 'ControlPassword=' "ControlPassword=$GLOBAL_PW" /mnt/dietpi_userdata/nzbget/nzbget.conf - - # Umask: https://github.com/MichaIng/DietPi/issues/1999 - G_CONFIG_INJECT 'UMask=' 'UMask=0002' /mnt/dietpi_userdata/nzbget/nzbget.conf + Create_User -g dietpi -G audio -d /mnt/dietpi_userdata/airsonic airsonic - # Optimisations - G_CONFIG_INJECT 'Server1.Cipher=' 'Server1.Cipher=RC4-MD5' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'CrcCheck=' 'CrcCheck=no' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'ParScan=' 'ParScan=limited' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'ParThreads=' "ParThreads=$G_HW_CPU_CORES" /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'DebugTarget=' 'DebugTarget=none' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'CrashTrace=' 'CrashTrace=no' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'DetailTarget=' 'DetailTarget=none' /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'ParBuffer=' "ParBuffer=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'ArticleCache=' "ArticleCache=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf - G_CONFIG_INJECT 'WriteBuffer=' "WriteBuffer=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf + # Optimise memory limit + local memory_limit=$(( $RAM_PHYS / 5 )) + (( $memory_limit < 200 )) && memory_limit=200 # Service - cat << '_EOF_' > /etc/systemd/system/nzbget.service + cat << _EOF_ > /etc/systemd/system/airsonic.service [Unit] -Description=NZBGet (DietPi) +Description=Airsonic Media Server (DietPi) +Wants=network-online.target +After=network-online.target remote-fs.target [Service] -Type=forking -User=nzbget -WorkingDirectory=/mnt/dietpi_userdata/nzbget -ExecStart=/mnt/dietpi_userdata/nzbget/nzbget -D +SyslogIdentifier=Airsonic +User=airsonic +WorkingDirectory=/mnt/dietpi_userdata/airsonic +ExecStart=$(command -v java) -Xmx${memory_limit}m -Dairsonic.home=/mnt/dietpi_userdata/airsonic -Dserver.context-path=/airsonic -Dserver.port=8080 -jar /mnt/dietpi_userdata/airsonic/airsonic.war [Install] 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 + + # Permissions + G_EXEC chmod +x /mnt/dietpi_userdata/airsonic/airsonic.war + G_EXEC chown airsonic:root /mnt/dietpi_userdata/airsonic + + # Grab our test media for user + Download_Test_Media + fi - software_id=155 # HTPC Manager + software_id=68 # Remot3.it if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - local url='https://github.com/HTPC-Manager/HTPC-Manager.git' - G_CHECK_URL "$url" - - # Python build dependencies for ARM - (( $G_HW_ARCH < 10 )) && G_AGI libffi-dev libssl-dev zlib1g-dev libjpeg-dev + # ARMv6/7 + local arch='armhf' - if [[ -d '/mnt/dietpi_userdata/htpc-manager/.git' ]]; then + # ARMv8 + if (( $G_HW_ARCH == 3 )); then - G_EXEC cd /mnt/dietpi_userdata/htpc-manager - G_EXEC_OUTPUT=1 G_EXEC git remote set-url origin "$url" - G_EXEC_OUTPUT=1 G_EXEC git fetch origin - G_EXEC_OUTPUT=1 G_EXEC git reset --hard origin - G_EXEC_OUTPUT=1 G_EXEC git clean -dxfe '/userdata' + arch='arm64' - else + # x86_64 + elif (( $G_HW_ARCH == 10 )); then - G_EXEC_OUTPUT=1 G_EXEC git clone --depth 1 "$url" - G_EXEC mkdir -p /mnt/dietpi_userdata/htpc-manager - G_EXEC cp -a HTPC-Manager/. /mnt/dietpi_userdata/htpc-manager/ - G_EXEC_NOHALT=1 G_EXEC rm -R HTPC-Manager - G_EXEC cd /mnt/dietpi_userdata/htpc-manager - G_EXEC_OUTPUT=1 G_EXEC git reset --hard origin - G_EXEC_OUTPUT=1 G_EXEC git clean -dxfe '/userdata' + arch='amd64' fi - # Python deps - G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur requirements.txt + local fallback_url="https://github.com/remoteit/installer/releases/download/v2.6.39/connectd_2.6.39_$arch.deb" + Download_Install "$(curl -sSfL 'https://api.github.com/repos/remoteit/installer/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/connectd_[^\"\/]*_$arch\.deb\"/{print \$4}")" fi - software_id=153 # OctoPrint - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then + software_id=69 # Python 3 RPi.GPIO + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + Banner_Installing + G_AGI python3-rpi.gpio - # Stretch: Install Python 2 development tools since OctoPrint does not support Python 3.5 - local pip='pip3' - if (( $G_DISTRO < 5 )) + fi + + software_id=70 # WiringPi + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + + # RPi + if (( $G_HW_MODEL < 10 )) then - G_AGI python-{pip,dev} - G_EXEC_OUTPUT=1 G_EXEC pip2 install -U pip setuptools wheel - pip='pip2' + Download_Install 'https://github.com/WiringPi/WiringPi/archive/master.tar.gz' + + # Odroids + else + Download_Install 'https://github.com/hardkernel/wiringPi/archive/master.tar.gz' + G_EXEC mv {w,W}iringPi-master fi - # Pre-create user and its home directory to allow user-level Python instance - Create_User -G dialout,tty,video -d /mnt/dietpi_userdata/octoprint octoprint - [[ -d '/mnt/dietpi_userdata/octoprint' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/octoprint - G_EXEC chown -R octoprint:octoprint /mnt/dietpi_userdata/octoprint + G_EXEC cd WiringPi-master + G_EXEC_OUTPUT=1 G_EXEC ./build + G_EXEC strip --remove-section=.comment --remove-section=.note /usr/local/bin/gpio + G_EXEC cd /tmp/$G_PROGRAM_NAME - # Clear pip cache in case it got somehow created - [[ -d '/mnt/dietpi_userdata/octoprint/.cache' ]] && G_EXEC rm -R /mnt/dietpi_userdata/octoprint/.cache + # Move source dir to disk, as it contains additional examples to compile + [[ -d '/root/wiringPi' ]] && G_EXEC_NOEXIT=1 G_EXEC rm -R /root/wiringPi # Pre-v7.2 + [[ -d '/mnt/dietpi_userdata/WiringPi' ]] && G_EXEC rm -R /mnt/dietpi_userdata/WiringPi + G_EXEC mv WiringPi-master /mnt/dietpi_userdata/WiringPi - # Install OctoPrint - G_EXEC_OUTPUT=1 G_EXEC sudo -u octoprint $pip install -U --no-cache-dir --user octoprint - unset -v pip fi - software_id=187 # CUPS + software_id=72 # I2C if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Installing - # Download base configuration if it does not exist yet - [[ -f '/etc/cups/cupsd.conf' ]] || dps_index=$software_id Download_Install 'cupsd.conf' /etc/cups/cupsd.conf + Banner_Installing + /boot/dietpi/func/dietpi-set_hardware i2c enable - G_AGI cups fi - software_id=154 # Roon Server + software_id=100 # PiJuice if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Installing # https://help.roonlabs.com/portal/en/kb/articles/linux-install#Downloads - - # .NET dependency: https://packages.microsoft.com/debian/ - if (( $G_DISTRO < 5 )) - then - DEPS_LIST='libicu57' + Banner_Installing - elif (( $G_DISTRO == 5 )) + # On Bullseye currently the package is not available yet. So pull and install manually, if this is the case: https://github.com/MichaIng/DietPi/issues/4643 + if apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* pijuice-base(,|$)' then - DEPS_LIST='libicu63' + G_AGI pijuice-base else - DEPS_LIST='libicu67' + Download_Install 'http://archive.raspberrypi.org/debian/pool/main/p/pijuice-base/pijuice-base_1.7_all.deb' fi - # Skip download and install, if already existent, manual removal or internal updater can be used: - if [[ -d '/opt/roonserver' ]] + 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 + G_EXEC chmod +x /var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func1.sh + + cat << '_EOF_' > /var/lib/pijuice/pijuice_config.JSON +{ + "system_events": { + "low_battery_voltage": { + "function": "SYS_FUNC_HALT", + "enabled": true + }, + "low_charge": { + "function": "NO_FUNC", + "enabled": true + }, + "button_power_off": { + "function": "USER_FUNC1", + "enabled": true + }, + "forced_power_off": { + "function": "USER_FUNC2", + "enabled": false + }, + "no_power": { + "function": "SYS_FUNC_HALT_POW_OFF", + "enabled": true + }, + "forced_sys_power_off": { + "function": "USER_FUNC3", + "enabled": false + }, + "watchdog_reset": { + "function": "USER_EVENT", + "enabled": true + } + }, + "user_functions": { + "USER_FUNC1": "/var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func1.sh", + "USER_FUNC2": "/var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func2.sh", + "USER_FUNC3": "/var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func3.sh", + "USER_FUNC4": "", + "USER_FUNC5": "", + "USER_FUNC6": "", + "USER_FUNC7": "", + "USER_FUNC8": "" + }, + "system_task": { + "watchdog": { + "enabled": true, + "period": "60" + }, + "min_bat_voltage": { + "threshold": "1", + "enabled": true + }, + "min_charge": { + "threshold": "1", + "enabled": true + }, + "enabled": true, + "wakeup_on_charge": { + "enabled": true, + "trigger_level": "1" + } + } +} +_EOF_ + fi + + software_id=171 # frp + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + + # Architecture + # - ARMv6/7 + local arch='arm' + # - ARMv8 + if (( $G_HW_ARCH == 3 )) then - G_AGI $DEPS_LIST - DEPS_LIST= - G_DIETPI-NOTIFY 2 "Existing install found\n -The ${aSOFTWARE_NAME[$software_id]} target install directory /opt/roonserver already exists. This will not be overwritten.\n -If the existing instance is broken or obsolete, please manually backup config files and data, then remove this directory and rerun \"dietpi-software\".\n -If you want to update ${aSOFTWARE_NAME[$software_id]}, please use its internal updater." + arch='arm64' - else - Download_Install 'https://download.roonlabs.com/builds/RoonServer_linuxx64.tar.bz2' - G_EXEC mv RoonServer /opt/roonserver + # - x86_64 + elif (( $G_HW_ARCH == 10 )) + then + arch='amd64' fi - # Data dir - [[ -d '/mnt/dietpi_userdata/roonserver' ]] || G_EXEC mkdir /mnt/dietpi_userdata/roonserver + # 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}')" - # Service - cat << '_EOF_' > /etc/systemd/system/roonserver.service + G_EXEC cd frp_* + + local choice_required= + while : + do + G_WHIP_MENU_ARRAY=( + 'Server' ': Use this machine as a server, with a public IP' + 'Client' ': Use this machine as a client, without a public IP' + 'Both' ': Run the reverse proxy only on this machine' + ) + + G_WHIP_MENU "${choice_required}Please choose how you are going to run frp." && break + choice_required='[ERROR] A choice is required to finish the frp install.\n\n' + done + local mode=$G_WHIP_RETURNED_VALUE + + G_EXEC mkdir -p /etc/frp + Create_User frp -d /etc/frp + + local token= + if [[ $mode == 'Server' || $mode == 'Both' ]] + then + G_EXEC mv frps /usr/local/bin/frps + cat << '_EOF_' > /etc/systemd/system/frps.service [Unit] -Description=Roon Server (DietPi) +Description=frp server (DietPi) Wants=network-online.target After=network-online.target [Service] -SyslogIdentifier=roonserver -Environment=ROON_DATAROOT=/mnt/dietpi_userdata/roonserver -#Environment=ROON_ID_DIR=/mnt/dietpi_userdata/roonserver -Group=dietpi -ExecStart=/opt/roonserver/start.sh +User=frp +AmbientCapabilities=CAP_NET_BIND_SERVICE +ExecStart=/usr/local/bin/frps -c /etc/frp/frps.ini +Restart=on-failure +RestartSec=5s [Install] WantedBy=multi-user.target _EOF_ - Download_Test_Media + token=$(openssl rand -hex 15) + # Pre-create config file to turn on dashboard + [[ -f '/etc/frp/frps.ini' ]] || cat << _EOF_ > /etc/frp/frps.ini +[common] +bind_port = 7000 - fi +dashboard_port = 7500 +dashboard_user = admin +dashboard_pwd = $GLOBAL_PW - software_id=156 # Steam - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then +authentication_method = token +token = $token +_EOF_ + G_EXEC chown root:frp /etc/frp/frps.ini + G_EXEC chmod 0640 /etc/frp/frps.ini + fi + + if [[ $mode == 'Client' || $mode == 'Both' ]] + then + G_EXEC mv frpc /usr/local/bin/frpc + cat << '_EOF_' > /etc/systemd/system/frpc.service +[Unit] +Description=frp client (DietPi) +Wants=network-online.target +After=network-online.target frps.service + +[Service] +User=frp +ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.ini +ExecReload=/usr/local/bin/frpc reload -c /etc/frp/frpc.ini +Restart=on-failure +RestartSec=5s - Banner_Installing +[Install] +WantedBy=multi-user.target +_EOF_ + local server_addr= + local server_port=7000 + if [[ $G_WHIP_RETURNED_VALUE == 'Both' ]] + then + server_addr=127.0.0.1 + else + local invalid_entry= + while : + do + if G_WHIP_INPUTBOX "${invalid_entry}Please enter the IP address of your frp server, including port (default 7000)" && [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9.:]+$ ]] + then + server_addr=${G_WHIP_RETURNED_VALUE#*:} + [[ $G_WHIP_RETURNED_VALUE =~ : ]] && server_port=${G_WHIP_RETURNED_VALUE%:*} + break + else + invalid_entry='[FAILED] Please enter a valid IP address\n\n' + fi + done - # Allow non-interactive install - G_EXEC eval "debconf-set-selections <<< 'steam steam/question select I AGREE'" + while : + do + if G_WHIP_INPUTBOX "${invalid_entry}Please enter the authentication token of your frp server" && [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9.]+$ ]] + then + token=$G_WHIP_RETURNED_VALUE + break + else + invalid_entry='[FAILED] Please enter a token\n\n' + fi + done + fi - # x86_64: Install Debian i386 package - if [[ $G_HW_ARCH == 10 ]] - then - # Add i386 arch: https://packages.debian.org/bullseye/steam - [[ $(dpkg --print-foreign-architectures) == *'i386'* ]] || { G_EXEC dpkg --add-architecture i386; G_AGUP; } - # Add Nvidia i386 driver libs, if Nvidia driver is detected - local nvidia - [[ -e '/sys/module/nvidia/version' ]] && nvidia='nvidia-driver-libs:i386' - G_AGI steam $nvidia + # Pre-create config file to turn on admin UI + [[ -f '/etc/frp/frpc.ini' ]] || cat << _EOF_ > /etc/frp/frpc.ini +[common] +server_addr = $server_addr +server_port = $server_port - # ARM: Install repacked Debian i386 package for armhf - elif [[ $G_HW_ARCH == 2 ]] - then - Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/steam_$G_HW_ARCH_NAME.deb" +admin_addr = 0.0.0.0 +admin_port = 7400 +admin_user = admin +admin_pwd = $GLOBAL_PW + +token=$token +_EOF_ + G_EXEC chown root:frp /etc/frp/frpc.ini + G_EXEC chmod 0660 /etc/frp/frpc.ini fi + # Cleanup + G_EXEC cd /tmp/$G_PROGRAM_NAME + G_EXEC_NOEXIT=1 G_EXEC rm -R frp_* + fi - software_id=158 # MinIO + software_id=122 # Node-RED if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Installing - - # ARMv6/7 - local url='https://dl.minio.io/server/minio/release/linux-arm/minio' + Banner_Installing # Pre-configure user and data directory to allow a local service user install - # ARMv8 - if (( $G_HW_ARCH == 3 )); then + # Data dir + G_EXEC mkdir -p /mnt/dietpi_userdata/node-red - url='https://dl.minio.io/server/minio/release/linux-arm64/minio' + # User + Create_User -G gpio,i2c -d /mnt/dietpi_userdata/node-red nodered + # - Allow sudo calls + echo 'nodered ALL=NOPASSWD: ALL' > /etc/sudoers.d/nodered - # x86_64 - elif (( $G_HW_ARCH == 10 )); then + # Permissions + G_EXEC chown -R nodered:nodered /mnt/dietpi_userdata/node-red - url='https://dl.minio.io/server/minio/release/linux-amd64/minio' + # Service + cat << '_EOF_' > /etc/systemd/system/node-red.service +[Unit] +Description=Node-RED (DietPi) - fi - G_EXEC curl -sSfLo /usr/local/bin/minio "$url" - G_EXEC chmod +x /usr/local/bin/minio +[Service] +User=nodered +ExecStart=/mnt/dietpi_userdata/node-red/node_modules/.bin/node-red -u /mnt/dietpi_userdata/node-red - # Service - G_EXEC curl -sSfLo /etc/systemd/system/minio.service 'https://github.com/minio/minio-service/raw/master/linux-systemd/minio.service' +[Install] +WantedBy=multi-user.target +_EOF_ + # Pre-reqs + G_AGI python3 - # User - Create_User -d /mnt/dietpi_userdata/minio-data minio-user + # Install as local instance for "nodered" user + G_EXEC cd /mnt/dietpi_userdata/node-red + G_EXEC_OUTPUT=1 G_EXEC sudo -u nodered npm i --no-audit node-red + G_EXEC cd /tmp/$G_PROGRAM_NAME - # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/minio-data - G_EXEC chown -R minio-user:minio-user /mnt/dietpi_userdata/minio-data + # CLI alias + echo "alias node-red-admin='sudo -u nodered /mnt/dietpi_userdata/node-red/node_modules/.bin/node-red-admin'" > /etc/bashrc.d/dietpi-node-red.sh fi - software_id=162 # Docker + software_id=123 # Mosquitto if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # Detect distro - local distro='debian' - (( $G_HW_MODEL < 10 )) && (( $G_RASPBIAN )) && distro='raspbian' + # Use official APT repository where available: https://repo.mosquitto.org/debian/pool/main/m/mosquitto/ + if [[ $G_HW_ARCH != 3 ]]; then - # APT key - G_EXEC eval "curl -sSfL 'https://download.docker.com/linux/$distro/gpg' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-docker.gpg --yes" + # 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" - # APT list - G_EXEC eval "echo 'deb https://download.docker.com/linux/$distro/ ${G_DISTRO_NAME/bookworm/bullseye} stable' > /etc/apt/sources.list.d/docker.list" - G_AGUP + # 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" + G_AGUP - # APT package - G_AGI docker-ce + fi - # 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 - G_EXEC eval "echo -e '[Service]\nType=simple' > /lib/systemd/system/docker.service.d/dietpi-simple.conf" + G_AGI mosquitto - # Config: https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file - # - Move Docker containers to dietpi_userdata - # - Log to systemd-journald (journalctl) by default with reduced log level: https://github.com/MichaIng/DietPi/issues/2388 - # + containerd: https://github.com/docker/docker.github.io/issues/9091 - [[ -d '/mnt/dietpi_userdata/docker-data' ]] || G_EXEC mkdir /mnt/dietpi_userdata/docker-data - if [[ -f '/etc/docker/daemon.json' ]] - then - GCI_PRESERVE=1 G_CONFIG_INJECT '"data-root":' ' "data-root": "/mnt/dietpi_userdata/docker-data",' /etc/docker/daemon.json '^\{([[:space:]]|$)' - GCI_PRESERVE=1 G_CONFIG_INJECT '"log-driver":' ' "log-driver": "journald",' /etc/docker/daemon.json '^\{([[:space:]]|$)' - GCI_PRESERVE=1 G_CONFIG_INJECT '"log-level":' ' "log-level": "warn",' /etc/docker/daemon.json '^\{([[:space:]]|$)' - GCI_PRESERVE=1 G_CONFIG_INJECT '"debug":' ' "debug": false,' /etc/docker/daemon.json '^\{([[:space:]]|$)' - else - [[ -d '/etc/docker' ]] || G_EXEC mkdir /etc/docker - echo '{ - "data-root": "/mnt/dietpi_userdata/docker-data", - "log-driver": "journald", - "log-level": "warn", - "debug": false -}' > /etc/docker/daemon.json - fi - G_CONFIG_INJECT '\[debug\]' '[debug]' /etc/containerd/config.toml - GCI_PRESERVE=1 G_CONFIG_INJECT 'level[[:blank:]]*=' ' level = "warn"' /etc/containerd/config.toml '^\[debug\]' + Remove_SysV mosquitto - # Enable cgroups used by Docker and alike - if [[ -f '/boot/boot.cmd' ]] && grep -q 'docker_optimizations' /boot/boot.cmd + # Password file + if [[ ! -f '/etc/mosquitto/passwd' ]] then - # Armbian - [[ -f '/boot/armbianEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/armbianEnv.txt - # Radxa Zero - [[ -f '/boot/uEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/uEnv.txt + G_EXEC umask 0037 + > /etc/mosquitto/passwd # Pre-create file, required for pre-v1.6.10 (ARMv8 up to Buster): https://github.com/MichaIng/DietPi/issues/4424 + G_EXEC_PRE_FUNC(){ acommand[4]=$GLOBAL_PW; } + G_EXEC mosquitto_passwd -b /etc/mosquitto/passwd mosquitto "${GLOBAL_PW//?/X}" + G_EXEC chown root:mosquitto /etc/mosquitto/passwd + G_EXEC umask 0022 fi - fi - - software_id=134 # Docker Compose - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing + # Config: /etc/mosquitto/conf.d exists, but doubled settings do not override each other and lead to a startup failure instead, which breaks the purpose we want to use it for. + # - Disable PID file, not required for systemd handling + G_EXEC sed -i '/^[[:blank:]]*pid_file[[:blank:]]/d' /etc/mosquitto/mosquitto.conf + [[ -d '/run/mosquitto' ]] && G_EXEC rm -R /run/mosquitto + # - Log to default STDERR > systemd-journald + G_EXEC sed -i '/^[[:blank:]]*log_dest[[:blank:]]/d' /etc/mosquitto/mosquitto.conf + [[ -d '/var/log/mosquitto' ]] && G_EXEC rm -R /var/log/mosquitto + # - Add default password file for authenticated requests: https://github.com/MichaIng/DietPi/issues/4133 + GCI_PRESERVE=1 G_CONFIG_INJECT 'password_file[[:blank:]]' 'password_file /etc/mosquitto/passwd' /etc/mosquitto/mosquitto.conf + # - Add default listener at port 1883 not bound to loopback IP: https://github.com/MichaIng/DietPi/issues/4133 + GCI_PRESERVE=1 G_CONFIG_INJECT 'listener[[:blank:]]' 'listener 1883' /etc/mosquitto/mosquitto.conf - # Python build dependencies for aarch64 - # - libffi-dev additionally required on Stretch: https://dietpi.com/phpbb/viewtopic.php?p=34293#p34293 - local apackages=('make' 'gcc') - (( $G_DISTRO < 5 )) && apackages+=('libffi-dev') - (( $G_HW_ARCH == 3 )) && G_AGI "${apackages[@]}" - unset -v apackages + # Add/override default systemd unit: https://github.com/eclipse/mosquitto/tree/master/service/systemd + cat << '_EOF_' > /etc/systemd/system/mosquitto.service +[Unit] +Description=Mosquitto MQTT Broker (DietPi) +Documentation=man:mosquitto.conf(5) man:mosquitto(8) +Wants=network-online.target +After=network-online.target - G_EXEC_OUTPUT=1 G_EXEC pip3 install docker-compose +[Service] +Type=notify +NotifyAccess=main +User=mosquitto +ExecStart=/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf +ExecReload=/bin/kill -HUP $MAINPID +[Install] +WantedBy=multi-user.target +_EOF_ fi - software_id=161 # FuguHub + software_id=131 # Blynk Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # ARM - local url='https://fuguhub.com/releases/raspberrypi/install.sh' - - # x86_64 - (( $G_HW_ARCH == 10 )) && url='https://fuguhub.com/install/FuguHub.linux.install' - - Download_Install "$url" FuguHubInstall.sh + # Stretch and ARMv6: Install Java 8 build + local fallback_url='https://github.com/Peterkn2001/blynk-server/releases/download/v0.41.16/server-0.41.16.jar' java= + (( $G_DISTRO < 5 || $G_HW_ARCH == 1 )) && fallback_url='https://github.com/Peterkn2001/blynk-server/releases/download/v0.41.16/server-0.41.16-java8.jar' java='-java8' - G_EXEC chmod +x FuguHubInstall.sh - G_EXEC_OUTPUT=1 G_EXEC ./FuguHubInstall.sh - G_EXEC_NOHALT=1 G_EXEC rm FuguHubInstall.sh + # RPi: Install build deps for the "onoff" Node module + (( $G_HW_MODEL > 9 )) || DEPS_LIST='python3 make g++' - G_EXEC curl -sSfL 'https://fuguhub.com/box.zip' -o /home/bd/applications/box.zip + Download_Install "$(curl -sSfL 'https://api.github.com/repos/Peterkn2001/blynk-server/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/server-[0-9.]*$java\.jar\"/{print \$4}")" /mnt/dietpi_userdata/blynk/blynkserver.jar - fi + # RPi: Install "onoff" for GPIO access + (( $G_HW_MODEL > 9 )) || G_EXEC_OUTPUT=1 G_EXEC npm i -g --unsafe-perm --no-audit onoff - software_id=164 # Nukkit - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Install Blynk JS library + G_EXEC_OUTPUT=1 G_EXEC npm i -g --unsafe-perm --no-audit blynk-library - Banner_Installing + # Preserve existing config + if [[ ! -f '/mnt/dietpi_userdata/blynk/server.properties' ]] + then + G_EXEC curl -sSfL 'https://raw.githubusercontent.com/Peterkn2001/blynk-server/master/server/core/src/main/resources/server.properties' -o /mnt/dietpi_userdata/blynk/server.properties + G_EXEC chmod 0600 /mnt/dietpi_userdata/blynk/server.properties + G_CONFIG_INJECT 'logs.folder=' 'logs.folder=/var/log/blynk' /mnt/dietpi_userdata/blynk/server.properties + G_CONFIG_INJECT 'data.folder=' 'data.folder=/mnt/dietpi_userdata/blynk/data' /mnt/dietpi_userdata/blynk/server.properties + G_CONFIG_INJECT 'http.port=' 'http.port=8442' /mnt/dietpi_userdata/blynk/server.properties + GCI_PASSWORD=1 G_CONFIG_INJECT 'admin.pass=' "admin.pass=$GLOBAL_PW" /mnt/dietpi_userdata/blynk/server.properties + fi - Download_Install 'https://ci.nukkitx.com/job/NukkitX/job/Nukkit/job/master/lastStableBuild/artifact/target/nukkit-1.0-SNAPSHOT.jar' /usr/local/bin/nukkit/nukkit.jar + # Example local TCP connection script + if [[ ! -f '/mnt/dietpi_userdata/blynk/client-tcp-local.js' ]] + then + G_EXEC curl -sSfL 'https://raw.githubusercontent.com/vshymanskyy/blynk-library-js/master/examples/nodejs/client-tcp-local.js' -o /mnt/dietpi_userdata/blynk/client-tcp-local.js + G_EXEC sed -i "s|require('blynk-library')|require('/usr/local/lib/node_modules/blynk-library')|" /mnt/dietpi_userdata/blynk/client-tcp-local.js + G_EXEC chmod +x /mnt/dietpi_userdata/blynk/client-tcp-local.js + fi - # Config - [[ -f '/usr/local/bin/nukkit/nukkit.yml ' ]] || G_EXEC curl -sSfL 'https://github.com/Nukkit/Languages/raw/master/eng/nukkit.yml' -o /usr/local/bin/nukkit/nukkit.yml + # User + Create_User -d /mnt/dietpi_userdata/blynk blynk # Service - cat << '_EOF_' > /etc/systemd/system/nukkit.service + cat << _EOF_ > /etc/systemd/system/blynkserver.service [Unit] -Description=nukkit (DietPi) +Description=Blynk Server (DietPi) +Wants=network-online.target +After=network-online.target [Service] -SyslogIdentifier=Nukkit -WorkingDirectory=/usr/local/bin/nukkit -ExecStart=/bin/bash -c 'java -jar /usr/local/bin/nukkit/nukkit.jar' +SyslogIdentifier=Blynk +User=blynk +WorkingDirectory=/mnt/dietpi_userdata/blynk +ExecStart=$(command -v java) -jar /mnt/dietpi_userdata/blynk/blynkserver.jar + +# Hardening +PrivateTmp=true [Install] WantedBy=multi-user.target _EOF_ + # Permissions + G_EXEC chown -R blynk:blynk /mnt/dietpi_userdata/blynk + + # Assure that the default log directory exists, when it is set in the config file: https://github.com/MichaIng/DietPi/issues/4721 + if grep -q '^logs.folder=/var/log/blynk$' /mnt/dietpi_userdata/blynk/server.properties + then + G_EXEC mkdir -p /var/log/blynk + G_EXEC chown -R blynk:blynk /var/log/blynk + fi + fi - software_id=165 # Gitea + software_id=124 # NAA Daemon if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # Binary + data dir - [[ -d '/mnt/dietpi_userdata/gitea/gitea-repositories' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/gitea/gitea-repositories + # Base URL + local url='https://www.signalyst.eu/bins/naa/linux' - # 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' + # Arch + # - ARMv6/7 + local arch='armhf' - # ARMv8 + # - ARMv8 if (( $G_HW_ARCH == 3 )); then arch='arm64' - # x86_64 + # - x86_64 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" - 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 + # Get latest version: No Bullseye packages available yet + local distro=$G_DISTRO_NAME + (( $G_DISTRO > 5 )) && distro='buster' + local package=$(curl -sSfL "$url/$distro/" | sed -n "/href=\"networkaudiod_[^\"]*_$arch.deb\"/{s/^[^\"]*\"//;s/\".*$//p}" | tail -1) - fi + # Check final URL before applying debconf settings + G_CHECK_URL "$url/$distro/$package" - software_id=159 # Allo web UI: 160 for quick reinstall - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 || ${aSOFTWARE_INSTALL_STATE[160]} == 1 )); then + # Skip license + debconf-set-selections <<< 'networkaudiod networkaudiod/license note false' - Banner_Installing - # Always perform a clean reinstall - [[ -d '/var/www/allo' ]] && G_EXEC rm -R /var/www/allo - Download_Install 'https://dietpi.com/downloads/binaries/all/allo_web_interface_v13.3.7z' /var/www + # Install + no_check_url=1 Download_Install "$url/$distro/$package" + + unset url arch distro package fi - software_id=163 # GMediaRender + software_id=71 # WebIOPi if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Installing - - # APT dependencies: https://github.com/hzeller/gmrender-resurrect/blob/master/INSTALL.md - (( $G_DISTRO < 5 )) && DEPS_LIST='libupnp6' || DEPS_LIST='libupnp13' - DEPS_LIST+=' gstreamer1.0-alsa gstreamer1.0-libav gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly' + Banner_Installing # https://github.com/Freenove/WebIOPi - Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/gmediarender_$G_HW_ARCH_NAME.7z" /usr/local/bin - G_EXEC chmod +x /usr/local/bin/gmediarender + # Check for reinstall + local reinstall=0 + [[ -f '/etc/webiopi/config' ]] && reinstall=1 - # Create dummy icons for now. ToDo: Add real icons, GMediaRender or DietPi ones, or disable via build options? - G_EXEC mkdir -p /usr/local/share/gmediarender - > /usr/local/share/gmediarender/grender-64x64.png - > /usr/local/share/gmediarender/grender-128x128.png + DEPS_LIST='python3-dev python3-setuptools patch' + Download_Install 'https://github.com/Freenove/WebIOPi/archive/master.tar.gz' - fi + G_EXEC cd WebIOPi-master/WebIOPi-* - software_id=166 # Audiophonics PI-SPC - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Apply patch + G_EXEC_OUTPUT=1 G_EXEC patch -p1 -i webiopi-pi2bplus.patch - Banner_Installing # https://github.com/audiophonics/Raspberry-pwr-management + # Install for Python 3 only + G_EXEC sed -i '/SEARCH="python python3"/c\SEARCH="python3"' setup.sh - [[ -d '/var/lib/dietpi/dietpi-software/installed/pi-spc' ]] || G_EXEC mkdir -p /var/lib/dietpi/dietpi-software/installed/pi-spc - cat << '_EOF_' > /var/lib/dietpi/dietpi-software/installed/pi-spc/sds.sh -#!/bin/dash + # Skip Weaved install prompt + G_EXEC sed -i '/read response/c\response="n"' setup.sh -echo 'Audiophonics PI-SPC: Shutdown script starting... -Asserting pins: -Shutdown : GPIO17=in, Low -Boot OK : GPIO22=out, High -Soft Shutdown : GPIO04=out, Low' + # Run setup script, skipping APT installs + G_EXEC_OUTPUT=1 G_EXEC ./setup.sh skip-apt -gpio -g mode 04 out -gpio -g write 04 0 -gpio -g mode 17 in -gpio -g write 17 0 -gpio -g mode 22 out -gpio -g write 22 1 + G_EXEC cd /tmp/$G_PROGRAM_NAME -until [ $(gpio -g read 17) = 1 ] -do - sleep 0.25 -done + # Cleanup + G_EXEC_NOHALT=1 G_EXEC rm -R WebIOPi-master -echo 'Audiophonics PI-SPC: Shutting down system as requested...' -poweroff -exit 0 -_EOF_ - G_EXEC chmod +x /var/lib/dietpi/dietpi-software/installed/pi-spc/sds.sh + # On fresh installs, change port to 8002 to avoid conflict with IceCast + (( $reinstall )) || G_EXEC sed -i 's/^port = 8000$/port = 8002/' /etc/webiopi/config - cat << '_EOF_' > /etc/systemd/system/pi-spc.service + # Service + Remove_SysV webiopi 1 + cat << _EOF_ > /etc/systemd/system/webiopi.service [Unit] -Description=Audiophonics PI-SPC (DietPi) +Description=WebIOPi (DietPi) +Wants=network-online.target +After=network-online.target [Service] -StandardOutput=tty -ExecStart=/var/lib/dietpi/dietpi-software/installed/pi-spc/sds.sh +SyslogIdentifier=WebIOPi +ExecStart=$(which python3) -m webiopi -c /etc/webiopi/config + +# Hardening +PrivateTmp=true +ProtectHome=true [Install] WantedBy=multi-user.target _EOF_ - - # Alternative: Use native GPIO shutdown and poweroff device tree overlays - - # systemd-logind < dbus is required for the gpio-shutdown device tree overlay to trigger the shutdown. - #G_AGI dbus - #G_EXEC systemctl unmask systemd-logind - #G_EXEC systemctl start systemd-logind - - #G_CONFIG_INJECT 'dtoverlay=gpio-shutdown' 'dtoverlay=gpio-shutdown,gpio_pin=17,active_low=0,gpio_pull=down' /boot/config.txt - #G_CONFIG_INJECT 'dtoverlay=gpio-poweroff' 'dtoverlay=gpio-poweroff,gpiopin=22,active_low' /boot/config.txt - fi - software_id=167 # Raspotify - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing # https://dtcooper.github.io/raspotify/#hard-installation - - # 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" - - # APT list - G_EXEC eval "echo 'deb https://dtcooper.github.io/raspotify/ raspotify main' > /etc/apt/sources.list.d/raspotify.list" - G_AGUP - - # APT package - G_AGI raspotify - - fi - - software_id=169 # Google AIY + software_id=98 # HAProxy if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_EXEC_OUTPUT=1 G_EXEC git clone -b voicekit 'https://github.com/google/aiyprojects-raspbian.git' /mnt/dietpi_userdata/voice-recognizer-raspi - G_EXEC cd /mnt/dietpi_userdata/voice-recognizer-raspi - - G_EXEC_OUTPUT=1 G_EXEC pip3 install -U pip virtualenv - G_EXEC_OUTPUT=1 G_EXEC virtualenv --system-site-packages -p python3 env - G_EXEC_OUTPUT=1 G_EXEC env/bin/pip install -Ur requirements.txt - - #??? ARMv7 only - (( $G_HW_ARCH == 2 )) && G_EXEC_OUTPUT=1 G_EXEC env/bin/pip install google-assistant-library==0.0.3 - - # Services - G_EXEC sed -i 's|/home/pi|/mnt/dietpi_userdata|g' systemd/voice-recognizer.service - G_CONFIG_INJECT 'User=' 'User=dietpi' systemd/voice-recognizer.service '\[Service\]' - - G_EXEC cp systemd/voice-recognizer.service /etc/systemd/system/ - G_EXEC cp systemd/alsa-init.service /etc/systemd/system/ - #G_EXEC cp systemd/ntpdate.service /etc/systemd/system/ - - source env/bin/activate - - # Enable default app for service start - G_EXEC cp src/assistant_library_with_button_demo.py src/main.py + local version='2.4.3' # 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" + # Compile + G_EXEC cd haproxy-$version + G_EXEC_OUTPUT=1 G_EXEC make -j "$G_HW_CPU_CORES" TARGET=linux-glibc CPU=generic USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 ADDLIB='-Wl,--no-as-needed -lgcc_s -Wl,--as-needed' DEBUG_CFLAGS='-g0 -O3' LDFLAGS='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed' + # Strip binary size + G_EXEC strip --remove-section=.comment --remove-section=.note haproxy + # Install + G_EXEC_OUTPUT=1 G_EXEC make install + # - systemd unit + G_EXEC cd admin/systemd + G_EXEC_OUTPUT=1 G_EXEC make + G_EXEC mv {,/etc/systemd/system/}haproxy.service + # - Error pages G_EXEC cd /tmp/$G_PROGRAM_NAME + G_EXEC mkdir -p /etc/haproxy/errors + G_EXEC mv haproxy-$version/examples/errorfiles/*.http /etc/haproxy/errors/ + # Clean up + G_EXEC_NOHALT=1 G_EXEC rm -R haproxy-$version - fi - - software_id=176 # Mycroft AI - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Git clone to DietPi userdata - G_EXEC cd /mnt/dietpi_userdata - if [[ ! -d 'mycroft-core/.git' ]]; then - - [[ -d 'mycroft-core' ]] && G_EXEC rm -R mycroft-core - G_THREAD_START git clone -b master --depth 1 https://github.com/MycroftAI/mycroft-core.git - - fi - - # APT deps - DEPS_LIST='vorbis-tools' - - # Pre-create global config to reflect correct data dir and audio settings within install - # - Overwrite existing config, user should use /mnt/dietpi_userdata/mycroft-data/.mycroft/mycroft.conf instead to override. - dps_index=$software_id Download_Install 'mycroft.conf' /etc/mycroft/mycroft.conf + # Jail directory + G_EXEC mkdir -p /var/lib/haproxy - # Pre-create user and directories with correct permissions - Create_User -G audio -d /mnt/dietpi_userdata/mycroft-data mycroft - G_EXEC mkdir -p /mnt/dietpi_userdata/mycroft-data/skills /var/log/mycroft - G_EXEC chown -R mycroft:mycroft /etc/mycroft /mnt/dietpi_userdata/mycroft-{core,data} /var/log/mycroft - # - Force skills to be placed directly into data dir - G_EXEC rm -Rf /opt/mycroft # symlink - G_EXEC ln -s /mnt/dietpi_userdata/mycroft-data /opt/mycroft - # - Grant mycroft user sudo permissions which is required for dev_setup.sh and some other Mycroft scripts - G_EXEC eval "echo 'mycroft ALL=NOPASSWD: ALL' > /etc/sudoers.d/mycroft" + # Config + [[ -f '/etc/haproxy/haproxy.cfg' ]] || cat << '_EOF_' > /etc/haproxy/haproxy.cfg +global - # Assure 2 GiB overall memory (-100 MiB to avoid tiny swap space) is available - if (( $RAM_TOTAL < 1948 )); then + maxconn 64 + # Jail directory + chroot /var/lib/haproxy + stats socket /run/haproxy.sock mode 660 level admin + stats timeout 30s + user root + group root + daemon - G_DIETPI-NOTIFY 2 '\e[33m[WARNING] Insufficient overall memory size: Mycroft AI requires at least 2 GiB memory on first start. We will now attempt to increase your swap size to satisfy this requirement.' - /boot/dietpi/func/dietpi-set_swapfile 1 + # Default SSL material locations + ca-base /etc/ssl/certs + crt-base /etc/ssl/private - fi + # Default ciphers to use on SSL-enabled listening sockets. + # For more information, see ciphers(1SSL). + ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL - # Run installer as user mycroft - G_EXEC cd /mnt/dietpi_userdata/mycroft-core - # -sm: Skip mimic build which is time intense and can be manually done any time later. - # - Remove PulseAudio from dependencies, we use ALSA - G_EXEC sed -Ei 's/[^[:blank:]"'\'']*pulseaudio[^[:blank:]"'\'']*//g' ./dev_setup.sh - G_EXEC_OUTPUT=1 G_EXEC sudo -u mycroft ./dev_setup.sh -sm - G_EXEC cd /tmp/$G_PROGRAM_NAME +defaults - fi + log global + mode http + option httplog + option dontlognull + timeout connect 5000 + timeout client 50000 + timeout server 50000 + errorfile 400 /etc/haproxy/errors/400.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 408 /etc/haproxy/errors/408.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http + errorfile 504 /etc/haproxy/errors/504.http - software_id=86 # Roon Extension Manager - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then +frontend localnodes - Banner_Installing + bind *:80 + mode http + default_backend nodes - # Restart Docker service to be able to deploy the container - G_DIETPI-NOTIFY 2 'Docker will be restarted to be able to deploy the container.' - G_EXEC systemctl daemon-reload - G_EXEC systemctl restart docker +backend nodes - # Unset SUDO_USER variable to avoid download, install and run as sudo-calling user, which fails due to /tmp/$G_PROGRAM_NAME write permissions: https://github.com/MichaIng/DietPi/issues/4462 - unset -v SUDO_USER + mode http + balance roundrobin + option forwardfor + http-request set-header X-Forwarded-Port %[dst_port] + http-request add-header X-Forwarded-Proto https if { ssl_fc } + option httpchk HEAD / HTTP/1.1\r\nHost:localhost + server web01 127.0.0.1:9000 check + server web02 127.0.0.1:9001 check + server web03 127.0.0.1:9002 check - G_EXEC curl -sSfLO 'https://raw.githubusercontent.com/TheAppgineer/roon-extension-manager/v1.x/rem-setup.sh' - G_EXEC chmod +x rem-setup.sh - G_EXEC_OUTPUT=1 G_EXEC ./rem-setup.sh - G_EXEC_NOHALT=1 G_EXEC rm rem-setup.sh +# Admin web page + listen stats + bind *:1338 + stats enable + stats uri / + stats hide-version + stats auth admin:dietpi +_EOF_ fi - software_id=178 # Jellyfin + software_id=35 # Logitech Media Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Installing - - # APT key - local url='https://repo.jellyfin.org/jellyfin_team.gpg.key' - G_CHECK_URL "$url" - G_EXEC eval "curl -sSfL '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-jellyfin.gpg --yes" + Banner_Installing # https://wiki.slimdevices.com/index.php/DebianPackage#installing_7.9.2 - # APT list - G_EXEC eval "echo 'deb https://repo.jellyfin.org/debian/ $G_DISTRO_NAME main' > /etc/apt/sources.list.d/dietpi-jellyfin.list" - G_AGUP + # Grab architecture + local arch='arm' + (( $G_HW_ARCH == 10 )) && arch='amd64' - # APT meta package: Server, web component and FFmpeg implementation - G_AGI jellyfin + # Grab latest package URL: Force HTTPS! + local fallback_url="https://downloads.slimdevices.com/LogitechMediaServer_v8.2.0/logitechmediaserver_8.2.0_$arch.deb" + Download_Install "$(curl -sSfL "https://www.mysqueezebox.com/update/?version=8.2&geturl=1&os=deb$arch" | sed 's|^http://|https://|')" - fi + # Remove bundled SysVinit service + systemctl -q is-enabled logitechmediaserver 2> /dev/null || systemctl -q is-active logitechmediaserver && G_EXEC systemctl disable --now logitechmediaserver + killall -qwr squeezeboxserver* # Provided service may not wait for exit, kill: https://github.com/MichaIng/DietPi/issues/1613#issuecomment-372787574 + Remove_SysV logitechmediaserver 1 - software_id=62 # Box86 - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then - Banner_Installing + # Grant user access to DietPi media files + G_EXEC usermod -aG dietpi squeezeboxserver - # APT deps - DEPS_LIST='cmake python3-minimal' + # systemd service + cat << _EOF_ > /etc/systemd/system/logitechmediaserver.service +[Unit] +Description=Logitech Media Server (DietPi) - # 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"; } - Download_Install "https://github.com/ptitSeb/box86/archive/$version.tar.gz" +[Service] +User=squeezeboxserver +ExecStart=$(command -v squeezeboxserver) --prefsdir /var/lib/squeezeboxserver/prefs --logdir /var/log/squeezeboxserver/ --cachedir /var/lib/squeezeboxserver/cache --charset=utf8 --logfile /var/log/squeezeboxserver/error.log +Restart=on-failure +RestartSec=5 - # Build - G_EXEC mkdir box86-${version#v}/build - G_EXEC cd box86-${version#v}/build - # - RPi 2 - if [[ $G_HW_MODEL == 2 ]] - then - G_EXEC cmake .. -DRPI2=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo - # - RPi 3 - elif [[ $G_HW_MODEL == 3 ]] - then - G_EXEC cmake .. -DRPI3=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo - # - RPi 4 - elif [[ $G_HW_MODEL == 4 ]] - then - G_EXEC cmake .. -DRPI4=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo - # - Odroids - elif (( $G_HW_MODEL < 20 )) - then - G_EXEC cmake .. -DODROID=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo - # - Others - else - G_EXEC cmake .. -DARM_DYNAREC=ON -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo - fi - G_EXEC_OUTPUT=1 G_EXEC make CFLAGS='-g0 -O3' "-j$(nproc)" - G_EXEC strip --remove-section=.comment --remove-section=.note box86 - G_EXEC make install +[Install] +WantedBy=multi-user.target +_EOF_ + # Grab our test media for user + Download_Test_Media - # Reload binfmt to have i386 binaries executed via box86 automatically from now on - G_EXEC systemctl restart systemd-binfmt fi - software_id=197 # Box64 - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then + software_id=55 # Wordpress + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + Banner_Installing - # APT deps - DEPS_LIST='cmake python3-minimal' + Download_Install 'https://wordpress.org/latest.tar.gz' /var/www - # 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"; } - Download_Install "https://github.com/ptitSeb/box64/archive/$version.tar.gz" + # Permissions + G_EXEC chown -R www-data:www-data /var/www/wordpress - # Build - G_EXEC mkdir box64-${version#v}/build - G_EXEC cd box64-${version#v}/build - # - RPi 4 - if [[ $G_HW_MODEL == 4 ]] - then - G_EXEC cmake .. -DRPI4ARM64=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo - # - RK3399 - elif [[ $G_HW_CPUID == 3 ]] - then - G_EXEC cmake .. -DRK3399=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo - # - Others - else - G_EXEC cmake .. -DARM_DYNAREC=ON -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo - fi - G_EXEC_OUTPUT=1 G_EXEC make CFLAGS='-g0 -O3' "-j$(nproc)" - G_EXEC strip --remove-section=.comment --remove-section=.note box64 - G_EXEC make install + # Create MariaDB database + /boot/dietpi/func/create_mysql_db wordpress wordpress "$GLOBAL_PW" - # Reload binfmt to have x86_64 binaries executed via box64 automatically from now on - G_EXEC systemctl restart systemd-binfmt fi - software_id=27 # TasmoAdmin + software_id=38 # FreshRSS if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # Install required PHP modules - DEPS_LIST="$PHP_NAME-curl $PHP_NAME-zip" # https://github.com/reloxx13/TasmoAdmin#linux - - # Skip install, if already present - if [[ -d '/var/www/tasmoadmin' ]]; then - - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/var/www/tasmoadmin\" already exists. Download and install steps will be skipped. - - Please manually backup your config files+data, remove the install dir and rerun \"dietpi-software (re)install $software_id\" if you need to reinstall. - - If you want to update the ${aSOFTWARE_NAME[$software_id]} instance, please use the internal updater from WebUI." - # shellcheck disable=SC2086 - G_AGI $DEPS_LIST - DEPS_LIST= + # Install required PHP modules: https://github.com/FreshRSS/FreshRSS#example-of-full-installation-on-linux-debianubuntu + DEPS_LIST="$PHP_NAME-curl $PHP_NAME-gmp $PHP_NAME-intl $PHP_NAME-json $PHP_NAME-mbstring $PHP_NAME-xml $PHP_NAME-zip" + if [[ -d '/opt/FreshRSS' ]] + then + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/FreshRSS\" already exists. Download and install steps will be skipped. + - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. + - if you need to reinstall (e.g. broken instance), please manually backup your config files+data, remove the install dir \"/opt/FreshRSS\" and rerun \"dietpi-software (re)install $software_id\"." else - - Download_Install 'https://github.com/reloxx13/TasmoAdmin/archive/master.tar.gz' - mv TasmoAdmin-master/tasmoadmin /var/www/ - rm -R TasmoAdmin-master - chown -R www-data:www-data /var/www/tasmoadmin - + Download_Install 'https://github.com/FreshRSS/FreshRSS/archive/master.tar.gz' /opt + G_EXEC mv /opt/FreshRSS-master /opt/FreshRSS fi - # Configure the webserver - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - - G_DIETPI-NOTIFY 2 'Apache webserver found, enabling TasmoAdmin specific configuration.' - a2enmod setenvif rewrite authz_core authn_core authn_file 1> /dev/null - local tasmoadmin_conf='/etc/apache2/sites-available/dietpi-tasmoadmin.conf' - if [[ -f $tasmoadmin_conf ]]; then - - tasmoadmin_conf+='.dietpi-new' - G_WHIP_MSG "Existing TasmoAdmin Apache configuration found, will preserve the old one and save the new one for review and comparison to: $tasmoadmin_conf" - - fi - dps_index=$software_id Download_Install 'apache.tasmoadmin.conf' $tasmoadmin_conf - a2ensite dietpi-tasmoadmin 1> /dev/null - - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then - - G_DIETPI-NOTIFY 2 'Lighttpd webserver found, enabling TasmoAdmin specific configuration.' - local tasmoadmin_conf='/etc/lighttpd/conf-available/99-dietpi-tasmoadmin.conf' - if [[ -f $tasmoadmin_conf ]]; then - - tasmoadmin_conf+='.dietpi-new' - G_WHIP_MSG "Existing TasmoAdmin Lighttpd configuration found, will preserve the old one and save the new one for review and comparison to: $tasmoadmin_conf" - - fi - dps_index=$software_id Download_Install 'lighttpd.tasmoadmin.conf' $tasmoadmin_conf - # Enable required modules + our config - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod rewrite dietpi-tasmoadmin - - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + # Enable required PHP modules: https://github.com/FreshRSS/FreshRSS#requirements + G_EXEC phpenmod curl gmp intl json pdo_mysql ctype dom mbstring xml zip - G_DIETPI-NOTIFY 2 'Nginx webserver found, enabling TasmoAdmin specific configuration.' - local tasmoadmin_conf='/etc/nginx/sites-dietpi/dietpi-tasmoadmin.conf' - if [[ -f $tasmoadmin_conf ]]; then + # Apache configuration + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - owncloud_conf+='.dietpi-new' - G_WHIP_MSG "Existing TasmoAdmin Nginx configuration found, will preserve the old one and save the new one for review and comparison to: $tasmoadmin_conf" + # Required modules + G_EXEC a2enmod headers expires rewrite - fi - dps_index=$software_id Download_Install 'nginx.tasmoadmin.conf' $tasmoadmin_conf + # Better compatibility with mobile clients + echo 'AllowEncodedSlashes On' > /etc/apache2/conf-available/dietpi-freshrss.conf + G_EXEC a2enconf dietpi-freshrss fi - fi + # Create MariaDB database and user + if [[ -d '/mnt/dietpi_userdata/mysql/freshrss' ]]; then - software_id=157 # Home Assistant - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + G_DIETPI-NOTIFY 2 'FreshRSS MariaDB database found, will NOT overwrite.' + G_EXEC systemctl restart mariadb - Banner_Installing + else - 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.7' + /boot/dietpi/func/create_mysql_db freshrss freshrss "$GLOBAL_PW" - G_DIETPI-NOTIFY 2 "Home Assistant user: $ha_user" - G_DIETPI-NOTIFY 2 "Home Assistant home: $ha_home" - G_DIETPI-NOTIFY 2 "pyenv activation: \"$ha_pyenv_activation\"" - G_DIETPI-NOTIFY 2 "pyenv Python version: $ha_python_version" + fi - # User - Create_User -G dialout,gpio,i2c -d $ha_home $ha_user + # Set permissions for webserver access + G_EXEC chgrp -R www-data /opt/FreshRSS + G_EXEC chmod -R g+r+w /opt/FreshRSS - # Start with fresh instance, to allow clean pyenv and Python updates and fix broken instances. All userdata and configs are preserved in: /mnt/dietpi_userdata/homeassistant - [[ -d $ha_home/.pyenv ]] && G_EXEC rm -R $ha_home/.pyenv - [[ -d '/srv/homeassistant' ]] && G_EXEC rm -R /srv/homeassistant # pre-v6-27 + # CLI install: https://github.com/FreshRSS/FreshRSS/blob/master/cli/README.md#commands + G_EXEC cd /opt/FreshRSS + sudo -u www-data php ./cli/prepare.php + sudo -u www-data php ./cli/do-install.php --default_user dietpi --auth_type form --environment production --title FreshRSS --db-type mysql --db-host localhost --db-user freshrss --db-password "$GLOBAL_PW" --db-base freshrss --db-prefix freshrss + sudo -u www-data php ./cli/create-user.php --user dietpi --password "$GLOBAL_PW" --api_password "$GLOBAL_PW" + G_EXEC cd /tmp/$G_PROGRAM_NAME - # Build dependencies - # - MariaDB support: G_AGI libmariadb-dev - # - Read custom build dependencies - local custom_apt_deps=$(sed -n '/^[[:blank:]]*SOFTWARE_HOMEASSISTANT_APT_DEPS=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - # - All: gcc, libc6-dev, make, libssl-dev, zlib1g-dev for Python built and libbz2-dev, libreadline-dev, libsqlite3-dev to suppress warnings - # - All: libffi-dev for cffi on ARMv6/7 and for python-slugify==4.0.1 on ARMv8/x86_64 - DEPS_LIST="gcc libc6-dev make libssl-dev zlib1g-dev libffi-dev libbz2-dev libreadline-dev libsqlite3-dev $custom_apt_deps" - # - ARMv6/7: libjpeg-dev for Pillow, g++ for greenlet and libopenjp2-7 + libtiff5 + libxcb1 for runtime - [[ $G_HW_ARCH == [12] ]] && DEPS_LIST+=' libjpeg-dev g++ libopenjp2-7 libtiff5 libxcb1' + # Link web interface to webroot + G_EXEC rm -Rf /var/www/freshrss + G_EXEC ln -s /opt/FreshRSS/p /var/www/freshrss - # Install pyenv to $ha_home - G_EXEC mkdir -p $ha_home - Download_Install 'https://github.com/pyenv/pyenv/archive/master.tar.gz' - G_EXEC mv pyenv-master $ha_home/.pyenv - G_EXEC chown -R $ha_user:$ha_user $ha_home + # Create cron job for feed update every 30 minutes, if it does not yet exist + crontab -u www-data -l 2>/dev/null | grep -q '/opt/FreshRSS/app/actualize_script.php' || ( crontab -u www-data -l 2>/dev/null ; echo '*/30 * * * * php /opt/FreshRSS/app/actualize_script.php' ) | crontab -u www-data - - # Generate script to activate pyenv: This must be sourced from the originating shell, hence it does not require execute permissions. - echo "#!/bin/dash -if [ \$(whoami) != '$ha_user' ]; then - echo '[FAILED] This pyenv must be activated as user \"$ha_user\". Aborting...' - kill -INT \$\$ -fi -cd $ha_home -export PYENV_ROOT='$ha_home/.pyenv' -export PATH=\"\$PYENV_ROOT/bin:\$PATH\" -eval \"\$(pyenv init --path)\" -eval \"\$(pyenv init -)\"" > $ha_home/pyenv-activate.sh + fi - # ARMv6/7: Create pip config to pull wheels from piwheels.org - if [[ $G_HW_ARCH == [12] ]] - then - G_EXEC mkdir $ha_home/.pip - G_EXEC eval "echo -e '[global]\nextra-index-url=https://www.piwheels.org/simple/' > $ha_home/.pip/pip.conf" - fi + software_id=28 # TigerVNC Server + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - G_EXEC_DESC='Installing Python with Home Assistant module into pyenv' - # - Read custom Python modules - local custom_pip_deps=$(sed -n '/^[[:blank:]]*SOFTWARE_HOMEASSISTANT_PIP_DEPS=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - # - MariaDB support: pip3 install mysqlclient|PyMySQL - G_EXEC_OUTPUT=1 G_EXEC sudo -u $ha_user dash -c " -$ha_pyenv_activation -pyenv install $ha_python_version -pyenv local $ha_python_version -pip3 install -U pip wheel -[ -z '$custom_pip_deps' ] || pip3 install $custom_pip_deps -exec pip3 install homeassistant" + Banner_Installing + # netbase is required until Bullseye to solve: "Use of uninitialized value $proto in socket at /usr/bin/tigervncserver" + # - It is a recommendation and no dependency of perl, but expected by some packages depending on perl only: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=939055 + # tigervnc-common is required as it is a recommendation only until Bullseye. + local apackages=() + (( $G_DISTRO > 5 )) || apackages=('tigervnc-common' 'netbase') + # https://github.com/MichaIng/DietPi/issues/1558#issuecomment-701547904 + (( ${aSOFTWARE_INSTALL_STATE[23]} > 0 )) && apackages+=('dbus-user-session') + G_AGI tigervnc-standalone-server tigervnc-scraping-server "${apackages[@]}" - # Generate script to launch HA using pyenv - echo "#!/bin/dash -$ha_pyenv_activation -exec hass -c '/mnt/dietpi_userdata/homeassistant'" > $ha_home/homeassistant-start.sh - G_EXEC chmod +x $ha_home/homeassistant-start.sh + fi - # Generate script to update HA within pyenv - echo "#!/bin/dash -exec sudo -u $ha_user dash -c '$ha_pyenv_activation; exec pip3 install -U homeassistant'" > $ha_home/homeassistant-update.sh - G_EXEC chmod +x $ha_home/homeassistant-update.sh + software_id=120 # RealVNC Server + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - cat << '_EOF_' > /etc/systemd/system/home-assistant.service + Banner_Installing + G_AGI realvnc-vnc-server + + fi + + # TigerVNC/RealVNC Server - Shared setup + if (( ${aSOFTWARE_INSTALL_STATE[28]} == 1 || ${aSOFTWARE_INSTALL_STATE[120]} == 1 )); then + + # Service + cat << '_EOF_' > /etc/systemd/system/vncserver.service [Unit] -Description=Home Assistant (DietPi) +Description=VNC Server (DietPi) +Before=xrdp.service xrdp-sesman.service Wants=network-online.target -After=network-online.target mariadb.service +After=network-online.target [Service] -SyslogIdentifier=homeassistant -User=homeassistant -ExecStart=/home/homeassistant/homeassistant-start.sh +RemainAfterExit=yes +PAMName=login +User=root +Environment=HOME=/root +ExecStart=/usr/local/bin/vncserver start +ExecStop=/usr/local/bin/vncserver stop [Install] WantedBy=multi-user.target _EOF_ - # Link config and data to DietPi userdata - if [[ ! -d '/mnt/dietpi_userdata/homeassistant' ]] - then - if [[ -d '/home/homeassistant/.homeassistant' ]] - then - G_EXEC mv /home/homeassistant/.homeassistant /mnt/dietpi_userdata/homeassistant - else - G_EXEC mkdir -p /mnt/dietpi_userdata/homeassistant - fi - fi - G_EXEC rm -Rf /home/homeassistant/.homeassistant - G_EXEC ln -s /mnt/dietpi_userdata/homeassistant /home/homeassistant/.homeassistant - G_EXEC chown -R homeassistant:homeassistant /mnt/dietpi_userdata/homeassistant - - fi - - software_id=181 # PaperMC - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + G_EXEC systemctl daemon-reload + G_EXEC systemctl enable vncserver + aSTART_SERVICES+=('vncserver') - Banner_Installing + # RealVNC: Assure that its services are disabled when ours is enabled + (( ${aSOFTWARE_INSTALL_STATE[120]} == 1 )) && G_EXEC systemctl disable vncserver-virtuald vncserver-x11-serviced - # Make sure user agrees to the EULA - if [[ -f '/mnt/dietpi_userdata/papermc/eula.txt' ]] || G_WHIP_BUTTON_OK_TEXT='Yes' G_WHIP_BUTTON_CANCEL_TEXT='Abort' G_WHIP_YESNO 'Do you agree to the Minecraft EULA found at:\n\nhttps://account.mojang.com/documents/minecraft_eula' - then - # Collect latest version of PaperMC - local url='https://papermc.io/api/v2/projects/paper' - local version=$(curl -sSfL "$url"); version=${version%\"*} version=${version##*\"} - local build=$(curl -sSfL "$url/versions/$version"); build=${build%]*} build=${build##*[,[]} - #local file=$(curl -sSfL "$url/versions/$version/builds/$build"); file=${file##*\"name\":\"} file=${file%%\"*} - # Download and install PaperMC - Download_Install "$url/versions/$version/builds/$build/downloads/paper-$version-$build.jar" /opt/papermc/paperclip.jar - G_EXEC mkdir -p /mnt/dietpi_userdata/papermc - G_EXEC eval 'echo "eula=true" > /mnt/dietpi_userdata/papermc/eula.txt' + cat << '_EOF_' > /usr/local/bin/vncserver +#!/bin/dash - # User - Create_User -d /mnt/dietpi_userdata/papermc papermc +if [ -f '/usr/bin/vncserver-virtual' ] +then + echo '[ OK ] RealVNC detected' + FP_BINARY='/usr/bin/vncserver-virtual -Authentication VncAuth' + FP_SHARED='exec /usr/bin/vncserver-x11 -service -Authentication VncAuth' - # Bedrock compatibility - G_WHIP_BUTTON_OK_TEXT='Yes' - G_WHIP_BUTTON_CANCEL_TEXT='Skip' - if G_WHIP_YESNO 'Would you like to install the Geyser and Floodgate plugins for compatibility with Bedrock Edition?\n\nNote that this may be buggy.' - then - Download_Install 'https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/master/lastStableBuild/artifact/bootstrap/spigot/target/Geyser-Spigot.jar' /mnt/dietpi_userdata/papermc/plugins/Geyser-Spigot.jar - Download_Install 'https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/master/lastStableBuild/artifact/spigot/target/floodgate-spigot.jar' /mnt/dietpi_userdata/papermc/plugins/floodgate-bukkit.jar - fi +elif [ -f '/usr/bin/tigervncserver' ] +then + echo '[ OK ] TigerVNC detected' + FP_BINARY='/usr/bin/tigervncserver' + [ -f '/usr/bin/X0tigervnc' ] && FP_SHARED='/usr/bin/X0tigervnc' || FP_SHARED='/usr/bin/x0tigervncserver' + FP_SHARED="$FP_SHARED -display :0 -rfbauth $HOME/.vnc/passwd" +else + echo '[FAILED] No supported VNC server installed' + exit 1 +fi - # Minecraft rcon client for remote administration and server maintenance scripts - DEPS_LIST='gcc libc6-dev' - Download_Install 'https://github.com/Tiiffi/mcrcon/archive/master.tar.gz' - G_EXEC gcc -g0 -O3 mcrcon-master/mcrcon.c -o /usr/local/bin/mcrcon - G_EXEC rm -R mcrcon-master - G_EXEC strip --remove-section=.comment --remove-section=.note /usr/local/bin/mcrcon +case "$1" in - # Link logs to RAM - G_EXEC mkdir -p /var/log/papermc - G_EXEC rm -Rf /mnt/dietpi_userdata/papermc/logs - G_EXEC ln -s /var/log/papermc /mnt/dietpi_userdata/papermc/logs + start) + # Shared desktop mode + if grep -q '^[[:blank:]]*SOFTWARE_VNCSERVER_SHARE_DESKTOP=1' /boot/dietpi.txt + then + echo '[ INFO ] Waiting for X server...' + while : + do + until pgrep '^X' > /dev/null 2>&1; do sleep 1; done + echo '[ INFO ] Connecting to shared desktop' + $FP_SHARED + sleep 2 + pgrep '^X' > /dev/null 2>&1 && exit 1 + echo '[ INFO ] X server stopped, waiting for next session...' + done - # Permissions - G_EXEC chown -R papermc:papermc /{mnt/dietpi_userdata,var/log}/papermc + # Virtual desktop mode + else + DISPLAY=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_DISPLAY_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + WIDTH=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_WIDTH=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + HEIGHT=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_HEIGHT=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + DEPTH=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_DEPTH=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + echo "[ INFO ] Starting virtual desktop at display :${DISPLAY:-1} in ${WIDTH:-1280}x${HEIGHT:-720}x${DEPTH:-16}" + export SHELL='/bin/bash' + exec $FP_BINARY ":${DISPLAY:-1}" -geometry "${WIDTH:-1280}x${HEIGHT:-720}" -depth "${DEPTH:-16}" + fi + ;; - # Assure 1.5 GiB overall memory (-100 MiB to avoid tiny swap space) is available. - local heap_size='512' - if (( $RAM_TOTAL < 1436 )) - then - G_DIETPI-NOTIFY 2 'Stable PaperMC operation requires at least 1.5 GiB system memory. We will now increase your swap size to satisfy this requirement.' - /boot/dietpi/func/dietpi-set_swapfile $(( 1536 - $RAM_PHYS )) + stop) + # Shared desktop mode + if grep -q '^[[:blank:]]*SOFTWARE_VNCSERVER_SHARE_DESKTOP=1' /boot/dietpi.txt + then + echo '[ INFO ] Disconnecting from shared desktop' + killall -qw vncserver-x11-core x0tigervncserver X0tigervnc - # On 2 GiB+ physical RAM devices, apply 1 GiB heap size by default - elif (( $RAM_PHYS > 1848 )) - then - heap_size='1024' - fi + # Virtual desktop mode + else + DISPLAY=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_DISPLAY_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + echo "[ INFO ] Stopping virtual desktop at display :${DISPLAY:-1}" + $FP_BINARY -kill ":${DISPLAY:-1}" + fi + ;; - # Service - cat << _EOF_ > /etc/systemd/system/papermc.service -[Unit] -Description=PaperMC (DietPi) -Documentation=https://paper.readthedocs.io/ + *) + echo "[FAILED] Invalid command ($1), please use \"start\" or \"stop\"" + exit 1 + ;; -[Service] -SyslogIdentifier=PaperMC -User=papermc -WorkingDirectory=/mnt/dietpi_userdata/papermc -ExecStart=$(command -v java) -Xmx${heap_size}m -jar /opt/papermc/paperclip.jar --nogui --noconsole +esac -[Install] -WantedBy=multi-user.target +exit 0 _EOF_ - # Config - if [[ -f '/mnt/dietpi_userdata/papermc/plugins/Geyser-Spigot.jar' && -f '/mnt/dietpi_userdata/papermc/plugins/floodgate-bukkit.jar' ]] + G_EXEC chmod +x /usr/local/bin/vncserver + + # TigerVNC: Permit remote connections which implies TLSVnc authentications being enabled additionally + # shellcheck disable=SC2016 + [[ -f '/etc/vnc.conf' ]] && GCI_PRESERVE=1 G_CONFIG_INJECT '\$localhost[[:blank:]]*=' '$localhost = "no";' /etc/vnc.conf # Stretch/Buster + # shellcheck disable=SC2016 + [[ -f '/etc/tigervnc/vncserver-config-defaults' ]] && GCI_PRESERVE=1 G_CONFIG_INJECT '\$localhost[[:blank:]]*=' '$localhost = "no";' /etc/tigervnc/vncserver-config-defaults # Bullseye + + # TigerVNC: Set control + read-only passwords + if [[ ${aSOFTWARE_INSTALL_STATE[28]} == 1 && ! -f '/root/.vnc/passwd' ]] then - Create_Config /mnt/dietpi_userdata/papermc/plugins/Geyser-Spigot/config.yml papermc 1800 1 && - G_CONFIG_INJECT 'auth-type:[[:blank:]]' 'auth-type: floodgate' /mnt/dietpi_userdata/papermc/plugins/Geyser-Spigot/config.yml - else - Create_Config /mnt/dietpi_userdata/papermc/permissions.yml papermc 1800 1 + [[ -d '/root/.vnc' ]] || G_EXEC mkdir /root/.vnc + tigervncpasswd -f <<< "$GLOBAL_PW +$GLOBAL_PW" > /root/.vnc/passwd + G_EXEC chmod 600 /root/.vnc/passwd fi - G_CONFIG_INJECT 'enable-rcon=' 'enable-rcon=true' /mnt/dietpi_userdata/papermc/server.properties - GCI_PASSWORD=1 G_CONFIG_INJECT 'rcon.password=' "rcon.password=$GLOBAL_PW" /mnt/dietpi_userdata/papermc/server.properties - else - aSOFTWARE_INSTALL_STATE[$software_id]=0 - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install aborted due to outstanding EULA agreement" + # 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' ]] + then + vncpasswd -virtual <<< "$GLOBAL_PW +$GLOBAL_PW" + vncpasswd -virtual <<< "$GLOBAL_PW +$GLOBAL_PW" + vncpasswd -service <<< "$GLOBAL_PW +$GLOBAL_PW" fi - fi - software_id=140 # Domoticz + software_id=73 # Fail2Ban if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # APT deps - DEPS_LIST='libusb-0.1 libcurl3-gnutls' + # Create jail.conf (backend = systemd) first, to prevent APT failure due to missing /var/log/auth.log: https://github.com/MichaIng/DietPi/issues/475#issuecomment-310873879 + G_EXEC mkdir -p /etc/fail2ban/fail2ban.d + [[ -f '/etc/fail2ban/jail.conf' ]] || cat << '_EOF_' > /etc/fail2ban/jail.conf +[DEFAULT] +enabled = true +ignoreip = 127.0.0.1/8 +ignorecommand = +backend = systemd +mode = normal +filter = %(__name__)s[mode=%(mode)s] +findtime = 600 +maxretry = 3 +bantime = 600 +banaction = route +action = %(banaction)s[blocktype=blackhole] - # Reinstall: Clean old install dir - [[ -d '/opt/domoticz' ]] && G_EXEC rm -R /opt/domoticz - Download_Install "https://releases.domoticz.com/releases/release/domoticz_linux_${G_HW_ARCH_NAME/armv6l/armv7l}.tgz" /opt/domoticz +[dropbear] + +[sshd] +# Mode: normal (default), ddos, extra or aggressive (combines all) +# See "filter.d/sshd.conf" for details. +#mode = normal +_EOF_ + # Log to systemd by default + local logtarget='SYSOUT' + (( $G_DISTRO < 5 )) && logtarget='SYSLOG' + echo -e "[Definition]\nlogtarget = $logtarget" > /etc/fail2ban/fail2ban.d/97_dietpi.conf + unset -v logtarget + + G_AGI python3-systemd fail2ban + + Remove_SysV fail2ban 1 + + # Failsafe + G_EXEC systemctl unmask fail2ban + G_EXEC systemctl enable --now fail2ban fi - software_id=191 # Snapcast Server + software_id=74 # InfluxDB if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - local arch='armhf' - (( $G_HW_ARCH == 10 )) && arch='amd64' + # 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" - 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}")" + # 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" + G_AGUP - # Disable JSON RPC by default, if setting was never touched yet - sed -i '/^\[tcp\]/,/^\[/s/^#enabled = true$/enabled = false/' /etc/snapserver.conf + # APT package + G_AGI influxdb + + # Move DB/datadir to userdata location + [[ -d '/mnt/dietpi_userdata/influxdb' ]] || G_EXEC mv /var/lib/influxdb /mnt/dietpi_userdata/ + G_EXEC rm -Rf /var/lib/influxdb + G_EXEC ln -sf /mnt/dietpi_userdata/influxdb /var/lib/influxdb + + # Permissions + G_EXEC chown -R influxdb:influxdb /mnt/dietpi_userdata/influxdb fi - software_id=192 # Snapcast Client + software_id=77 # Grafana if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - local arch='armhf' - (( $G_HW_ARCH == 10 )) && arch='amd64' + # ARMv6: Install package manually since repo is not compatible: https://grafana.com/grafana/download?platform=arm + if (( $G_HW_ARCH == 1 )); then - 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}")" + Download_Install 'https://dl.grafana.com/oss/release/grafana-rpi_8.1.2_armhf.deb' - # Client IP needs to be added to allowed IP list - local snapcast_server_ip - local invalid_entry= - while : - do - if G_WHIP_INPUTBOX "${invalid_entry}Please enter the IPv4 address of your Snapcast server machine" && [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9.]+$ ]] - then - snapcast_server_ip=$G_WHIP_RETURNED_VALUE - break - else - invalid_entry='[ERROR] Please enter a valid IP address. Please retry...\n\n' - fi - done + # Else use official APT repo: https://grafana.com/docs/grafana/latest/installation/debian/#install-from-apt-repository + else - local snapcast_server_port=1704 - invalid_entry= - while : - do - G_WHIP_DEFAULT_ITEM=$snapcast_server_port - if G_WHIP_INPUTBOX "${invalid_text}Please enter the network port of your Snapcast server machine\n - default: 1704" && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 1 - then - snapcast_server_port=$G_WHIP_RETURNED_VALUE - break - else - invalid_text='[ERROR] Please enter a valid port number. Please retry...\n\n' - fi - done + # 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_CONFIG_INJECT 'SNAPCLIENT_OPTS[[:blank:]=]' "SNAPCLIENT_OPTS=\"-h $snapcast_server_ip -p $snapcast_server_port\"" /etc/default/snapclient + # APT list + G_EXEC eval "echo 'deb https://packages.grafana.com/oss/deb/ stable main' > /etc/apt/sources.list.d/grafana.list" + G_AGUP - fi + # APT package + G_AGI grafana - software_id=198 # File Browser - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + fi - Banner_Installing + Remove_SysV grafana-server - # ARMv6 - local arch='armv6' + # Link DB/plugins to userdata location + if [[ -d '/mnt/dietpi_userdata/grafana' ]]; then - # ARMv7 - if (( $G_HW_ARCH == 2 )); then - arch='armv7' + G_DIETPI-NOTIFY 2 "Existing database/plugin directory /mnt/dietpi_userdata/grafana found. Will not overwrite..." - # ARMv8 - elif (( $G_HW_ARCH == 3 )); then - arch='arm64' + elif [[ -d '/var/lib/grafana' ]]; then - # x86_64 - elif (( $G_HW_ARCH == 10 )); then - arch='amd64' + G_EXEC mv /var/lib/grafana /mnt/dietpi_userdata/ + + else + + G_EXEC mkdir -p /mnt/dietpi_userdata/grafana + G_EXEC chown -R grafana:grafana /mnt/dietpi_userdata/grafana fi + G_EXEC rm -Rf /var/lib/grafana + G_EXEC ln -s /mnt/dietpi_userdata/grafana /var/lib/grafana - local fallback_url="https://github.com/filebrowser/filebrowser/releases/download/v2.17.1/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/ + # 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 + 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 - # Reinstall - [[ -d '/opt/filebrowser' ]] && G_EXEC rm -R /opt/filebrowser + fi - # Install - G_EXEC mv filebrowser /opt/ + software_id=64 # phpSysInfo + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # User - [[ -d '/mnt/dietpi_userdata/filebrowser' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/filebrowser - Create_User -g dietpi -d /mnt/dietpi_userdata/filebrowser filebrowser + Banner_Installing - # Config if not exist - if [[ ! -f '/mnt/dietpi_userdata/filebrowser/filebrowser.db' ]] + # Download + Download_Install 'https://github.com/phpsysinfo/phpsysinfo/archive/main.tar.gz' + + # Clean reinstall, but preserve previous config + if [[ -d '/var/www/phpsysinfo' ]] then - G_EXEC cd /mnt/dietpi_userdata/filebrowser - G_EXEC /opt/filebrowser/filebrowser config init - G_EXEC /opt/filebrowser/filebrowser config set -a 0.0.0.0 -p 8084 -r /mnt - G_EXEC_DESC="Setting up File Browser login user 'dietpi'" G_EXEC /opt/filebrowser/filebrowser users add dietpi "$GLOBAL_PW" --perm.admin + G_EXEC mv /var/www/phpsysinfo/phpsysinfo.ini phpsysinfo-main/phpsysinfo.ini + G_EXEC rm -R /var/www/phpsysinfo fi + G_EXEC mv phpsysinfo-main /var/www/phpsysinfo - # Permissions - G_EXEC chown -R filebrowser:root /mnt/dietpi_userdata/filebrowser /opt/filebrowser - - # Service - cat << '_EOF_' > /etc/systemd/system/filebrowser.service -[Unit] -Description=File Browser (DietPi) -Documentation=https://filebrowser.org/ -Wants=network-online.target -After=network-online.target - -[Service] -User=filebrowser -UMask=002 -ExecStart=/opt/filebrowser/filebrowser -d /mnt/dietpi_userdata/filebrowser/filebrowser.db + [[ -f '/var/www/phpsysinfo/phpsysinfo.ini' ]] || dps_index=$software_id Download_Install 'phpsysinfo.ini' /var/www/phpsysinfo/phpsysinfo.ini -[Install] -WantedBy=multi-user.target -_EOF_ fi - software_id=199 # Spotifyd + software_id=80 # Ubooquity if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - # ARMv6 - local fallback_url='https://github.com/Spotifyd/spotifyd/releases/download/v0.3.2/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" - 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" - file='spotifyd-linux-full' - ;; - esac - - # Reinstall: Remove old install dir - [[ -d '/opt/spotifyd' ]] && G_EXEC rm -R /opt/spotifyd + G_EXEC curl -sSfL https://vaemendis.net/ubooquity/service/download.php -o Ubooquity.zip + G_EXEC unzip -o Ubooquity.zip + G_EXEC_NOEXIT=1 G_EXEC rm Ubooquity.zip + G_EXEC mkdir -p /mnt/dietpi_userdata/ubooquity + G_EXEC mv {,/mnt/dietpi_userdata/ubooquity/}Ubooquity.jar - # x86_64 only deps: Both ARM binaries are not compiled against these. dbus would be required for MPRIS support, but let's keep it slim for now. - (( $G_HW_ARCH == 10 )) && DEPS_LIST='libdbus-1-3 libpulse0' + # User + Create_User -G dietpi -d /mnt/dietpi_userdata/ubooquity ubooquity - Download_Install "$(curl -sSfL 'https://api.github.com/repos/Spotifyd/spotifyd/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/$file\.tar\.gz\"/{print \$4}")" /opt/spotifyd + # Data + G_EXEC mkdir -p /mnt/dietpi_userdata/{ebooks,comics} - # User - Create_User -g audio -d /mnt/dietpi_userdata/spotifyd spotifyd + # Logs + G_EXEC rm -Rf /mnt/dietpi_userdata/ubooquity/logs /var/log/ubooquity + G_EXEC mkdir -p /var/log/ubooquity + G_EXEC ln -s /var/log/ubooquity /mnt/dietpi_userdata/ubooquity/logs - # Config: Do not touch on reinstall - if [[ ! -f '/mnt/dietpi_userdata/spotifyd/spotifyd.conf' ]] - then - G_EXEC mkdir -p /mnt/dietpi_userdata/spotifyd/cache - dps_index=$software_id Download_Install 'spotifyd.conf' /mnt/dietpi_userdata/spotifyd/spotifyd.conf - G_EXEC chmod 0600 /mnt/dietpi_userdata/spotifyd/spotifyd.conf - fi + # Optimise memory limit + local memory_limit=$(( $RAM_PHYS / 5 )) + (( $memory_limit < 200 )) && memory_limit=200 # Service - cat << '_EOF_' > /etc/systemd/system/spotifyd.service + G_DIETPI-NOTIFY 2 "Generating systemd service to start ${aSOFTWARE_NAME[$software_id]} on boot" + cat << _EOF_ > /etc/systemd/system/ubooquity.service [Unit] -Description=Spotifyd (DietPi) +Description=Ubooquity (DietPi) Wants=network-online.target -After=network-online.target sound.target +After=network-online.target [Service] -User=spotifyd -WorkingDirectory=/mnt/dietpi_userdata/spotifyd -ExecStart=/opt/spotifyd/spotifyd --no-daemon --config-path=/mnt/dietpi_userdata/spotifyd/spotifyd.conf +SyslogIdentifier=Ubooquity +User=ubooquity +WorkingDirectory=/mnt/dietpi_userdata/ubooquity +ExecStart=$(command -v java) -Xmx${memory_limit}m -jar /mnt/dietpi_userdata/ubooquity/Ubooquity.jar --headless --remoteadmin --adminport 2038 --libraryport 2039 [Install] WantedBy=multi-user.target _EOF_ # Permissions - G_EXEC chown -R spotifyd:root /mnt/dietpi_userdata/spotifyd - G_EXEC chmod +x /opt/spotifyd/spotifyd + G_EXEC chmod +x /mnt/dietpi_userdata/ubooquity/Ubooquity.jar + G_EXEC chown -R ubooquity /{mnt/dietpi_userdata,var/log}/ubooquity + G_EXEC chown ubooquity:dietpi /mnt/dietpi_userdata/{ebooks,comics} + G_EXEC chmod 775 /mnt/dietpi_userdata/{ebooks,comics} fi - } - - 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 + software_id=179 # Komga + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # Check currently installed SSH servers via "dpkg --get-selections" to be failsafe - local dpkg_out=$(dpkg --get-selections) + Banner_Installing + local fallback_url='https://github.com/gotson/komga/releases/download/v0.120.1/komga-0.120.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 - 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 + # User + Create_User -G dietpi -d /mnt/dietpi_userdata/komga komga - # Dropbear - elif (( $INDEX_SSHSERVER_TARGET == -1 )); then + # Data + G_EXEC mkdir -p /mnt/dietpi_userdata/{ebooks,comics} - aSOFTWARE_INSTALL_STATE[104]=1 + # Config + [[ -f '/mnt/dietpi_userdata/komga/application.yml' ]] || cat << _EOF_ > /mnt/dietpi_userdata/komga/application.yml +komga: + libraries-scan-startup: true # Scan libraries at startup + libraries-scan-cron: "* 2 * * * *" # Scan libraries periodically every hour at :02 + file-hashing: false # Compute a filehash for your files. This is required for the trash bin functionality to work, but can consume lots of resources on large libraries or slow hardware + database: + file: /mnt/dietpi_userdata/komga/database.sqlite + remember-me: + key: $(openssl rand -hex 32) +logging: + file: + name: "" # Disable file logging, use: "journalctl -u komga" + level: + root: WARN # TRACE DEBUG INFO WARN ERROR +server: + port: 2037 +_EOF_ + # Optimise memory limit + local memory_limit=$(( $RAM_PHYS / 5 )) + (( $memory_limit < 200 )) && memory_limit=200 - # OpenSSH - elif (( $INDEX_SSHSERVER_TARGET == -2 )); then + # Service + cat << _EOF_ > /etc/systemd/system/komga.service +[Unit] +Description=Komga (DietPi) +Wants=network-online.target +After=network-online.target - aSOFTWARE_INSTALL_STATE[105]=1 +[Service] +SyslogIdentifier=Komga +User=komga +WorkingDirectory=/mnt/dietpi_userdata/komga +ExecStart=$(command -v java) -Xmx${memory_limit}m -jar komga.jar - fi +[Install] +WantedBy=multi-user.target +_EOF_ + # Permissions + G_EXEC chmod +x /mnt/dietpi_userdata/komga/komga.jar + G_EXEC chown -R komga /mnt/dietpi_userdata/komga + G_EXEC chown komga:dietpi /mnt/dietpi_userdata/{ebooks,comics} + G_EXEC chmod 775 /mnt/dietpi_userdata/{ebooks,comics} 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 + software_id=56 # Single File PHP Gallery + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # ProFTPD - elif (( $INDEX_FILESERVER_TARGET == -1 )); then + Banner_Installing - aSOFTWARE_INSTALL_STATE[94]=1 - (( ${aSOFTWARE_INSTALL_STATE[96]} == 2 )) && aSOFTWARE_INSTALL_STATE[96]=-1 UNINSTALL_REQUIRED=1 + # Install required PHP modules: https://sye.dk/sfpg/ + DEPS_LIST="$PHP_NAME-gd" + Download_Install 'https://sye.dk/sfpg/Single_File_PHP_Gallery_4.8.0.zip' /var/www/gallery - # Samba - elif (( $INDEX_FILESERVER_TARGET == -2 )); then + # Enable required PHP modules + G_EXEC phpenmod gd - aSOFTWARE_INSTALL_STATE[96]=1 - (( ${aSOFTWARE_INSTALL_STATE[94]} == 2 )) && aSOFTWARE_INSTALL_STATE[94]=-1 UNINSTALL_REQUIRED=1 + # Thumbnails and metadata cache: Remove on reinstalls + [[ -d '/var/www/gallery/_sfpg_data' ]] && G_EXEC rm -R /var/www/gallery/_sfpg_data + G_EXEC mkdir /var/www/gallery/_sfpg_data + G_EXEC chown www-data /var/www/gallery/_sfpg_data - fi + # Apply a random security phrase + local phrase=$(tr -dc '[:alnum:]' < /dev/random | head -c30) + GCI_PASSWORD=1 G_CONFIG_INJECT "define\('SECURITY_PHRASE'" "define('SECURITY_PHRASE', '$phrase');" /var/www/gallery/index.php + unset -v phrase - # Update current file server index - INDEX_FILESERVER_CURRENT=$INDEX_FILESERVER_TARGET + # Create test galleries + [[ -d '/var/www/gallery/DietPi' ]] || G_EXEC mkdir /var/www/gallery/DietPi + [[ -f '/var/www/gallery/DietPi/logo_256.png' ]] || G_THREAD_START curl -sSfL 'https://dietpi.com/images/dietpi-logo_256x256.png' -o /var/www/gallery/DietPi/logo_256.png + [[ -d '/var/www/gallery/Tr-Zero' ]] || G_EXEC mkdir /var/www/gallery/Tr-Zero + [[ -f '/var/www/gallery/Tr-Zero/SS_0.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/SS_0.jpg' -o /var/www/gallery/Tr-Zero/SS_0.jpg + [[ -f '/var/www/gallery/Tr-Zero/SS_1.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/SS_44.jpg' -o /var/www/gallery/Tr-Zero/SS_1.jpg + [[ -f '/var/www/gallery/Tr-Zero/SS_2.jpg' ]] || G_THREAD_START curl -sSfL 'https://media.indiedb.com/images/games/1/25/24673/3.png' -o /var/www/gallery/Tr-Zero/SS_2.jpg + G_THREAD_WAIT 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 + software_id=40 # Ampache + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 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 + Banner_Installing # https://github.com/ampache/ampache/wiki/Installation - # Logrotate + Rsyslog - logs to disk - elif (( $INDEX_LOGGING_TARGET == -3 )); then + # Required PHP modules: https://github.com/ampache/ampache/wiki/Installation#prerequisites + DEPS_LIST="$PHP_NAME-curl $PHP_NAME-intl $PHP_NAME-json $PHP_NAME-xml" - aSOFTWARE_INSTALL_STATE[101]=1 - aSOFTWARE_INSTALL_STATE[102]=1 - (( ${aSOFTWARE_INSTALL_STATE[103]} == 2 )) && aSOFTWARE_INSTALL_STATE[103]=-1 UNINSTALL_REQUIRED=1 + # 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' + 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 + else + local fallback_url='https://github.com/ampache/ampache/releases/download/4.4.3/ampache-4.4.3_all.zip' + Download_Install "$(curl -sSfL 'https://api.github.com/repos/ampache/ampache/releases' | mawk -F\" '/"browser_download_url": ".*\/ampache-4[0-9\.]*_all.zip"/{print $4}' | head -1)" ampache fi - # Update current logging index - INDEX_LOGGING_CURRENT=$INDEX_LOGGING_TARGET - - fi - - } - - # Configure marked software titles - Configure_Software(){ - - local software_id - - software_id=26 # GNUstep - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Reinstall: Preserve existing config files + [[ -f '/var/www/ampache/config/ampache.cfg.php' ]] && G_EXEC mv /var/www/ampache/config/ampache.cfg.php ampache/config/ + [[ -f '/var/www/ampache/config/registration_agreement.php' ]] && G_EXEC mv /var/www/ampache/config/registration_agreement.php ampache/config/ + [[ -f '/var/www/ampache/channel/.htaccess' ]] && G_EXEC mv /var/www/ampache/channel/.htaccess ampache/channel/ + [[ -f '/var/www/ampache/rest/.htaccess' ]] && G_EXEC mv /var/www/ampache/rest/.htaccess ampache/rest/ + [[ -f '/var/www/ampache/play/.htaccess' ]] && G_EXEC mv /var/www/ampache/play/.htaccess ampache/play/ + [[ -d '/var/www/ampache' ]] && G_EXEC rm -R /var/www/ampache - Banner_Configuration - Create_Desktop_Shared_Items + G_EXEC mv {,/var/www/}ampache - fi + Download_Test_Media - software_id=25 # Xfce - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Enable required PHP modules: https://github.com/ampache/ampache/wiki/Installation#prerequisites + G_EXEC phpenmod curl intl json xml - Banner_Configuration - Create_Desktop_Shared_Items + # Import our pre-made Ampache database, if not existent already + if [[ ! -d '/mnt/dietpi_userdata/mysql/ampache' ]]; then - # Composition manager: Xfce has one integrated with xfwm4, which is blocked by xcompmgr, breaking settings and leading to ugly results: https://github.com/MichaIng/DietPi/issues/3665 - [[ -f '/etc/xdg/autostart/xcompmgr.desktop' ]] && G_EXEC rm /etc/xdg/autostart/xcompmgr.desktop + /boot/dietpi/func/create_mysql_db ampache ampache "$GLOBAL_PW" + Download_Install 'https://dietpi.com/downloads/mysql_databases/ampache_mysql_3.8.2-v6.0.zip' + G_EXEC mysql ampache < ampache.sql + G_EXEC_NOHALT=1 G_EXEC rm ampache.sql + # Also update password here for rare but possible case that database was lost but config file still exists + [[ -f '/var/www/ampache/config/ampache.cfg.php' ]] && G_CONFIG_INJECT 'database_password[[:blank:]]+=' "database_password = \"$GLOBAL_PW\"" /var/www/ampache/config/ampache.cfg.php - fi + fi - software_id=83 # Apache - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Create new config, if not existent already + if [[ ! -f '/var/www/ampache/config/ampache.cfg.php' ]]; then - Banner_Configuration + G_EXEC mv /var/www/ampache/config/ampache.cfg.php{.dist,} + G_CONFIG_INJECT 'web_path[[:blank:]]+=' 'web_path = "/ampache"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'database_hostname[[:blank:]]+=' 'database_hostname = /run/mysqld/mysqld.sock' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'database_name[[:blank:]]+=' 'database_name = ampache' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'database_username[[:blank:]]+=' 'database_username = ampache' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'database_password[[:blank:]]+=' "database_password = \"$GLOBAL_PW\"" /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'waveform[[:blank:]]+=' 'waveform = "true"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'tmp_dir_path[[:blank:]]+=' 'tmp_dir_path = "/tmp"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'generate_video_preview[[:blank:]]+=' 'generate_video_preview = "true"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'channel[[:blank:]]+=' 'channel = "true"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_m4a[[:blank:]]+=' 'transcode_m4a = "required"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_flac[[:blank:]]+=' 'transcode_flac = "required"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_mpc[[:blank:]]+=' 'transcode_mpc = "required"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_ogg[[:blank:]]+=' 'transcode_ogg = "allowed"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_wav[[:blank:]]+=' 'transcode_wav = "required"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_avi[[:blank:]]+=' 'transcode_avi = "allowed"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_mkv[[:blank:]]+=' 'transcode_mkv = "allowed"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_mpg[[:blank:]]+=' 'transcode_mpg = "allowed"' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'encode_target[[:blank:]]+=' 'encode_target = mp3' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'encode_video_target[[:blank:]]+=' 'encode_video_target = webm' /var/www/ampache/config/ampache.cfg.php + G_CONFIG_INJECT 'transcode_cmd[[:blank:]]+=' 'transcode_cmd = "ffmpeg"' /var/www/ampache/config/ampache.cfg.php - # 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 - -_EOF_ - # Webroot - [[ -f '/var/www/html/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 + fi - # Change error log level - G_EXEC sed -i '/LogLevel[[:blank:]]/c\ LogLevel error' /etc/apache2/sites-available/* + # Permissions: Ampache can automatically migrate old configs to the new config file + G_EXEC chown www-data /var/www/ampache/config/ampache.cfg.php fi - software_id=85 # Nginx + software_id=97 # OpenVPN Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - - # Custom configs, included by sites-enabled/default within server directive, while nginx/(conf.d|sites-enabled) is included by nginx.conf outside server directive - G_EXEC mkdir -p /etc/nginx/sites-dietpi - - G_BACKUP_FP /etc/nginx/nginx.conf - dps_index=$software_id Download_Install 'nginx.conf' /etc/nginx/nginx.conf - # Adjust socket name to PHP version - G_EXEC sed -i "s#/run/php/php.*-fpm.sock#/run/php/$PHP_NAME-fpm.sock#g" /etc/nginx/nginx.conf + Banner_Installing + G_AGI openvpn iptables + Remove_SysV openvpn - # CPU core count - G_EXEC sed -i "/worker_processes/c\worker_processes $G_HW_CPU_CORES;" /etc/nginx/nginx.conf + # Create initial server and client configs, if not yet present + # - Wildcard config file detection via for loop + local i + for i in /etc/openvpn/*.conf + do - # Default site - dps_index=$software_id Download_Install 'nginx.default' /etc/nginx/sites-available/default + # Inform user, if config exist, that config generation is skipped + if [[ -f $i ]]; then - # Webroot - [[ -f '/var/www/html/index.nginx-debian.html' ]] && G_EXEC mv /var/www/html/index.nginx-debian.html /var/www/ - [[ -d '/var/www/html' ]] && G_EXEC rmdir --ignore-fail-on-non-empty /var/www/html + G_DIETPI-NOTIFY 2 "Existing OpenVPN configuration found: $i + - Config generation will be skipped. + - If you need a fresh key/cert/config set, please remove $i + and run: dietpi-software reinstall 97" + break - fi + fi - software_id=89 # PHP - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Pre-v6.26 cleanup + [[ -f '/etc/openvpn/dh2048.pem' ]] && rm /etc/openvpn/dh2048.pem + dpkg-query -s easy-rsa &> /dev/null && G_AGP easy-rsa - Banner_Configuration + # Download latest easy-rsa from GitHub + G_DIETPI-NOTIFY 2 'Downloading latest easy-rsa for certificate and key generation...' + local fallback_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz' + Download_Install "$(curl -sSfL 'https://api.github.com/repos/OpenVPN/easy-rsa/releases/latest' | mawk -F\" '/"browser_download_url": .*\/EasyRSA-[^"\/]*\.tgz"/{print $4}')" + [[ -d '/etc/openvpn/easy-rsa' ]] && rm -R /etc/openvpn/easy-rsa + G_EXEC mv EasyRSA-* /etc/openvpn/easy-rsa - # PHP-FPM - if (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + # Cert and key generation via easy-rsa + G_DIETPI-NOTIFY 2 'Generating unique OpenVPN certificates and keys. Please wait...\n' + G_EXEC cd /etc/openvpn/easy-rsa + cat << '_EOF_' > vars +set_var EASYRSA_REQ_COUNTRY "UK" +set_var EASYRSA_REQ_PROVINCE "DietPi" +set_var EASYRSA_REQ_CITY "DietPi" +set_var EASYRSA_REQ_ORG "DietPi" +set_var EASYRSA_REQ_EMAIL "noreply@dietpi.com" +set_var EASYRSA_REQ_OU "DietPi" +set_var EASYRSA_BATCH "1" +_EOF_ + ./easyrsa init-pki + ./easyrsa build-ca nopass + ./easyrsa gen-dh + ./easyrsa build-server-full DietPi_OpenVPN_Server nopass + ./easyrsa build-client-full DietPi_OpenVPN_Client nopass - # Base - sed -i '/cgi.fix_pathinfo=/c\cgi.fix_pathinfo=1' "$FP_PHP_BASE_DIR"/fpm/php.ini + # Server config + cp -a pki/{ca.crt,dh.pem,issued/DietPi_OpenVPN_Server.crt,private/DietPi_OpenVPN_Server.key} /etc/openvpn/ + G_EXEC cd /etc/openvpn + cat << '_EOF_' > server.conf +port 1194 +proto udp +dev tun - # 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 +ca ca.crt +cert DietPi_OpenVPN_Server.crt +key DietPi_OpenVPN_Server.key +dh dh.pem - # 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 +server 10.8.0.0 255.255.255.0 - fi +client-to-client +keepalive 10 60 +comp-lzo +max-clients 10 - # 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 +user nobody +group nogroup - # Set UTF-8 - G_CONFIG_INJECT 'default_charset[[:blank:]]*=' 'default_charset="UTF-8"' $target_php_ini +persist-key +persist-tun +verb 3 - # 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 +# Web Forwarding (uncomment to enable) +#push "redirect-gateway" +#push "dhcp-option DNS 10.8.0.1" +_EOF_ - # File uploads: https://github.com/MichaIng/DietPi/issues/546 - # - This is especially relevant for cloud software like ownCloud/Nextcloud. - # - Generally we want to hold tmp upload files in RAM to reduce disk (especially SD card) writes for performance and disk wear reasons. - # - By default only max 2 MiB file uploads are allowed, hold in /tmp tmpfs, which is safe but not usable for usual cloud usage. - # - 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 - # - Nginx: https://github.com/MichaIng/DietPi/issues/546 => https://github.com/MichaIng/DietPi/blob/dev/.conf/dps_85/nginx.conf + # Client config + cat << '_EOF_' > DietPi_OpenVPN_Client.ovpn +client +proto udp +dev tun - # Cache settings - local target_php_cachesize=$(( $RAM_PHYS / 30 )) - (( $target_php_cachesize < 10 )) && target_php_cachesize=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 - # 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 - # - 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 +# IP/domain name of DietPi system, running OpenVPN server +remote mywebsite.com 1194 - # Enable all available PHP modules - local amodules=() - mapfile -t amodules < <(find "$FP_PHP_BASE_DIR/mods-available" -type f -name '*.ini' -printf '%f\n') - G_EXEC phpenmod "${amodules[@]%.ini}" - unset -v amodules +resolv-retry infinite +nobind - # 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 +user nobody +group nogroup - # PHP info page - echo '' > /var/www/phpinfo.php - # OPcache info page - G_THREAD_START curl -sSfL https://raw.githubusercontent.com/amnuts/opcache-gui/master/index.php -o /var/www/opcache.php - # APCu info page - G_THREAD_START curl -sSfL https://raw.githubusercontent.com/krakjoe/apcu/master/apc.php -o /var/www/apc.php +persist-key +persist-tun - G_THREAD_WAIT +remote-cert-tls server +comp-lzo +verb 3 +_EOF_ + # - Add CA cert, client cert and key + echo -e " +\n$( +\n$( +\n$(" >> DietPi_OpenVPN_Client.ovpn - fi + # - Copy to userdata + G_EXEC cp DietPi_OpenVPN_Client.ovpn /mnt/dietpi_userdata/ + # - and /boot partition + G_EXEC cp DietPi_OpenVPN_Client.ovpn /boot/ - fi + G_EXEC cd /tmp/$G_PROGRAM_NAME + break # Always break loop which is only for single wildcard file detection - software_id=90 # phpMyAdmin - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + done - Banner_Configuration + # Enable IP forwarding + echo -e 'net.ipv4.ip_forward=1\nnet.ipv6.conf.all.forwarding=1\nnet.ipv6.conf.default.forwarding=1' > /etc/sysctl.d/dietpi-openvpn.conf + sysctl net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 net.ipv6.conf.default.forwarding=1 - # Enable required PHP modules: https://docs.phpmyadmin.net/en/latest/require.html#php - G_EXEC phpenmod ctype curl gd json mbstring xml zip + # Web Forwarding (Setup IPtables, must also be run during boot) + #iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o "$(G_GET_NET iface)" -j MASQUERADE - # Install and enable webserver config - # - Apache - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + aSTART_SERVICES+=('openvpn') - dps_index=$software_id Download_Install 'apache.phpmyadmin.conf' /etc/apache2/sites-available/dietpi-phpmyadmin.conf - a2ensite dietpi-phpmyadmin + fi - # - Lighttpd - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + software_id=117 # PiVPN + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - dps_index=$software_id Download_Install 'lighttpd.phpmyadmin.conf' /etc/lighttpd/conf-available/98-dietpi-phpmyadmin.conf - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod dietpi-phpmyadmin + Banner_Installing - # - Nginx - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + G_EXEC curl -sSfL 'https://raw.githubusercontent.com/pivpn/pivpn/master/auto_install/install.sh' -o install.bash + G_EXEC chmod +x install.bash + G_DIETPI-NOTIFY 2 'Preventing reboot from within PiVPN installer' + G_EXEC sed -i '/shutdown[[:space:]]/d' install.bash + G_DIETPI-NOTIFY 2 'Preventing install of unattended-upgrades' + G_EXEC sed -i 's/^[[:blank:]]*UNATTUPG=[[:digit:]]/UNATTUPG=0/' install.bash - dps_index=$software_id Download_Install 'nginx.phpmyadmin.conf' /etc/apache2/sites-dietpi/dietpi-phpmyadmin.conf + # APT deps + G_AGI dnsutils net-tools bsdmainutils iptables-persistent # https://github.com/pivpn/pivpn/blob/master/auto_install/install.sh#L37 - fi + G_EXEC_OUTPUT=1 G_EXEC_NOEXIT=1 G_EXEC ./install.bash || aSOFTWARE_INSTALL_STATE[$software_id]=0 + G_EXEC_NOHALT=1 G_EXEC rm install.bash - # Copy default config in place and adjust, if not already existent - if [[ ! -f '/var/www/phpmyadmin/config.inc.php' ]]; then + fi - cp -a /var/www/phpmyadmin/config.sample.inc.php /var/www/phpmyadmin/config.inc.php - GCI_PASSWORD=1 G_CONFIG_INJECT "\\\$cfg\\['blowfish_secret'][[:blank:]]*=" "\$cfg['blowfish_secret'] = '$(openssl rand -base64 32)';" /var/www/phpmyadmin/config.inc.php + software_id=172 # WireGuard + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - fi + Banner_Installing - # Create MariaDB database and user - if [[ -d '/mnt/dietpi_userdata/mysql/phpmyadmin' ]]; then + # Packages available on Buster backports and Bullseye: For Stretch and Raspbian Buster add Bullseye repo + if (( $G_DISTRO < 5 || ( $G_HW_MODEL < 10 && ${G_RASPBIAN:-1} && $G_DISTRO == 5 ) )); then - G_DIETPI-NOTIFY 2 'phpMyAdmin MariaDB database found, will NOT overwrite.' + # Raspbian or Debian? + local url='http://raspbian.raspberrypi.org/raspbian/' + (( $G_HW_MODEL > 9 )) || (( ! $G_RASPBIAN )) && url='https://deb.debian.org/debian/' - else + echo "deb $url bullseye main" > /etc/apt/sources.list.d/dietpi-wireguard.list - /boot/dietpi/func/create_mysql_db phpmyadmin phpmyadmin "$GLOBAL_PW" - mysql phpmyadmin < /var/www/phpmyadmin/sql/create_tables.sql - # Since "root" user cannot be used for login (unix_socket authentication), grant full admin privileges to "phpmyadmin" - mysql -e 'grant all privileges on *.* to phpmyadmin@localhost with grant option' + # Disable repo via priority "-1", to prevent any accidental package upgrades: https://github.com/MichaIng/DietPi/issues/2568 + # Enable but set WireGuard package priorities low enough to install only if not available in main repo(s) + echo -e 'Package: *\nPin: release n=bullseye\nPin-Priority: -1\n +Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin-Priority: 100' > /etc/apt/preferences.d/dietpi-wireguard + + G_AGUP fi - # Pre-create TempDir: https://docs.phpmyadmin.net/en/latest/config.html#cfg_TempDir - mkdir /var/www/phpmyadmin/tmp - chown www-data:www-data /var/www/phpmyadmin/tmp - chmod 700 /var/www/phpmyadmin/tmp + # If the kernel module is shipped with the kernel (e.g. Armbian 5.X) + if [[ $WIREGUARD_BUILTIN == 1 ]]; then - fi + # Purge DKMS as it is not required and might mess with available kernel module + dpkg-query -s wireguard-dkms &> /dev/null && G_AGP wireguard-dkms + # Install user space tools only + G_AGI wireguard-tools iptables qrencode - software_id=91 # Redis - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Else, kernel headers and matching kernel image is required for wireguard-dkms to build the WireGuard kernel module + else - Banner_Configuration + local apackages=() + # x86_64 + if (( $G_HW_ARCH == 10 )); then - # Enable redis php module, if installed - phpenmod redis 2> /dev/null + apackages=('linux-image-amd64' 'linux-headers-amd64') - # Disable file logging and enable syslog instead, which resolves reported startup issues in cases as well: https://github.com/MichaIng/DietPi/issues/3291 - G_CONFIG_INJECT 'loglevel[[:blank:]]' 'loglevel warning' /etc/redis/redis.conf - G_CONFIG_INJECT 'logfile[[:blank:]]' 'logfile ""' /etc/redis/redis.conf - G_CONFIG_INJECT 'syslog-enabled[[:blank:]]' 'syslog-enabled yes' /etc/redis/redis.conf - (( $G_DISTRO < 5 )) || G_CONFIG_INJECT 'always-show-logo[[:blank:]]' 'always-show-logo no' /etc/redis/redis.conf + # RPi + elif (( $G_HW_MODEL < 10 )); then - fi + # Install bootloader package as well to assure we have a correctly booting system with intended kernel + apackages=('raspberrypi-kernel' 'raspberrypi-kernel-headers' 'raspberrypi-bootloader') - software_id=58 # OpenBazaar - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Odroid XU4 + elif (( $G_HW_MODEL == 11 )); then - Banner_Configuration + apackages=('linux-image-4.14-armhf-odroid-xu4' 'linux-headers-4.14-armhf-odroid-xu4') - # Init OB 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 + # Odroid C2 + elif (( $G_HW_MODEL == 12 )); then - # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/openbazaar + apackages=('linux-image-arm64-odroid-c2' 'linux-headers-arm64-odroid-c2') - G_EXEC_OUTPUT=1 G_EXEC openbazaar-go init -d /mnt/dietpi_userdata/openbazaar + # Odroid N2 + elif (( $G_HW_MODEL == 15 )); then - # Add current IP as gateway to allow external client connection - G_CONFIG_INJECT '"Gateway": "' " \"Gateway\": \"/ip4/$(G_GET_NET -4 ip)/tcp/4002\"," /mnt/dietpi_userdata/openbazaar/config + apackages=('linux-image-arm64-odroid-n2' 'linux-headers-arm64-odroid-n2') - # Client connection credentials - G_DIETPI-NOTIFY 2 "Please enter username and password for your ${aSOFTWARE_NAME[$software_id]} client connection:" - G_EXEC_OUTPUT=1 G_EXEC openbazaar-go setapicreds -d /mnt/dietpi_userdata/openbazaar + # Odroid C4 + elif (( $G_HW_MODEL == 16 )); then - # Client IP needs to be added to allowed IP list - local ob_client_ip= - local invalid_entry= - while : - do - if G_WHIP_INPUTBOX "${invalid_entry}Please enter the IP address of your ${aSOFTWARE_NAME[$software_id]} client machine -This is required, since the ${aSOFTWARE_NAME[$software_id]} server node by default does not allow any remote connection." && [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9.]+$ ]]; then + apackages=('linux-image-arm64-odroid-c4' 'linux-headers-arm64-odroid-c4') - ob_client_ip=$G_WHIP_RETURNED_VALUE - break + fi - else + # Odroids need to purge before we install, else, does not update to latest version... + (( $G_HW_MODEL > 9 && $G_HW_MODEL < 20 )) && G_AGP "${apackages[@]}" - invalid_entry='[FAILED] Please enter a valid IP address\n\n' + # Since G_AGUG does not upgrade packages with changed dependencies, in case of kernel image meta packages, those need to be installed+upgraded via G_AGI. + G_AGI "${apackages[@]}" # apt-get install overrides hold state + unset -v apackages - fi + # Workaround for missing /lib/modules//build symlink: https://github.com/MichaIng/DietPi/issues/3577 + # - Known as issue currently on Odroid C2/N2, check for new build system if linux-/ holds current headers instead of linux-source-/: https://dietpi.com/meveric/pool/c2/l/ + for i in /lib/modules/* + do + [[ -d $i/build ]] && continue + [[ -d /usr/src/linux-headers-${i##*/} ]] && ln -sfv "/usr/src/linux-headers-${i##*/}" "$i/build" done - G_CONFIG_INJECT '"AllowedIPs":' " \"AllowedIPs\": [\"$ob_client_ip\"]," /mnt/dietpi_userdata/openbazaar/config - else + # If existing install, reconfigure to rebuild WireGuard kernel module against current kernel + headers + dpkg-query -s wireguard-dkms &> /dev/null && G_EXEC dpkg-reconfigure -f noninteractive wireguard-dkms - G_DIETPI-NOTIFY 2 "Existing ${aSOFTWARE_NAME[$software_id]} config found. Skipping pre-configuration..." + # iptables required to forward incoming VPN traffic to local LAN/internet interface + # qrencode required to print client config QR code to console + G_AGI wireguard-dkms wireguard-tools iptables qrencode fi - # User - Create_User -d /mnt/dietpi_userdata/openbazaar openbazaar + # Try to enable module, if it fails, a reboot is required + local module_active=0 + modprobe wireguard 2> /dev/null && module_active=1 - # Service - cat << '_EOF_' > /etc/systemd/system/openbazaar.service -[Unit] -Description=OpenBazaar (DietPi) -Documentation=https://docs.openbazaar.org/ -Wants=network-online.target -After=network-online.target + # Server/Client choice + local choice_required= + while : + do + G_WHIP_MENU_ARRAY=( -[Service] -User=openbazaar -WorkingDirectory=/mnt/dietpi_userdata/openbazaar -ExecStart=/usr/local/bin/openbazaar-go start -d /mnt/dietpi_userdata/openbazaar -f -l notice + 'Server' ': Use this machine as VPN server and allow clients to connect to it.' + 'Client' ': Use this machine as VPN client to connect to another VPN server or service provider.' -[Install] -WantedBy=multi-user.target -_EOF_ - # Permissions - G_EXEC chown -R openbazaar:openbazaar /mnt/dietpi_userdata/openbazaar + ) - fi + G_WHIP_MENU "${choice_required}Please choose, if this machine should be set up as VPN server or client:" && break + choice_required='[ERROR] A choice is required to finish the WireGuard install.\n\n' + done - software_id=133 # YaCy - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Server choice + if [[ $G_WHIP_RETURNED_VALUE == 'Server' ]]; then - Banner_Configuration + # Public IP/domain and desired WireGuard server port + local invalid_text= + local domain=$(hostname -f) + while : + do + G_WHIP_DEFAULT_ITEM=$domain + if G_WHIP_INPUTBOX "${invalid_text}Please enter your servers public IP/domain for WireGuard client access:" && [[ $G_WHIP_RETURNED_VALUE ]]; then - # Service - cat << '_EOF_' > /etc/systemd/system/yacy.service -[Unit] -Description=YaCy (DietPi) -Documentation=https://wiki.yacy.net/index.php/En:Start -Wants=network-online.target -After=network-online.target + domain=${G_WHIP_RETURNED_VALUE#http*://} + break -[Service] -Type=forking -ExecStart=/etc/yacy/startYACY.sh -ExecStop=/etc/yacy/stopYACY.sh + else -[Install] -WantedBy=multi-user.target -_EOF_ + invalid_text='[ERROR] No valid entry found. Please retry...\n\n' - fi + fi + done + invalid_text= + local port=51820 + while : + do + G_WHIP_DEFAULT_ITEM=$port + if G_WHIP_INPUTBOX "${invalid_text}Please enter the network port that will be used to access your WireGuard server:\n +NB: This port needs to be forwarded by your router and/or opened in your firewall settings. Default value is: 51820" && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 0; then - software_id=2 # Folding@Home - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + port=$G_WHIP_RETURNED_VALUE + break - Banner_Configuration + else - # Remove obsolete config + data directories and SysV service + config - [[ -d '/var/lib/fahclient' ]] && rm -R /var/lib/fahclient - [[ -d '/etc/fahclient' ]] && rm -R /etc/fahclient - [[ -f '/etc/default/fahclient' ]] && rm /etc/default/fahclient - Remove_SysV FAHClient + invalid_text='[ERROR] No valid entry found, value needs to be a sequence of integers. Please retry...\n\n' - # Prepare our new config + data directory if not yet present - if [[ ! -f '/mnt/dietpi_userdata/fahclient/config.xml' ]]; then + fi + done - G_EXEC mkdir -p /mnt/dietpi_userdata/fahclient - dps_index=$software_id Download_Install 'config.xml' /mnt/dietpi_userdata/fahclient/config.xml + # Create everything inside WireGuard config dir + G_EXEC cd /etc/wireguard - fi + # For security reasons set umask to 077 + umask 077 - # Service - cat << _EOF_ > /etc/systemd/system/fahclient.service -[Unit] -Description=Folding@Home (DietPi) -Wants=network-online.target -After=network-online.target + # Create server and client keys + [[ -f 'server_private.key' ]] || wg genkey > server_private.key + [[ -f 'server_public.key' ]] || wg pubkey < server_private.key > server_public.key + [[ -f 'client_private.key' ]] || wg genkey > client_private.key + [[ -f 'client_public.key' ]] || wg pubkey < client_private.key > client_public.key + + # Server config + [[ -f 'wg0.conf' ]] || cat << _EOF_ > wg0.conf +[Interface] +Address = 10.9.0.1/24 +PrivateKey = $( wg0-client.conf +[Interface] +Address = 10.9.0.2/24 +PrivateKey = $( $FP_PHP_BASE_DIR/mods-available/dietpi-owncloud.ini - G_EXEC phpenmod dietpi-owncloud +# Kill switch: Uncomment the following, if the client should stop any network traffic, when disconnected from the VPN server +# NB: This requires "iptables" to be installed, thus will not work on most mobile phones. +#PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark \$(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT && ip6tables -I OUTPUT ! -o %i -m mark ! --mark \$(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT +#PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark \$(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT && ip6tables -D OUTPUT ! -o %i -m mark ! --mark \$(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT - # Get version string - 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 +[Peer] +PublicKey = $( 0 )); then +# Uncomment the following, if you're behind a NAT and want the connection to be kept alive. +#PersistentKeepalive = 25 +_EOF_ + # Set umask back to default 022 + umask 022 - G_DIETPI-NOTIFY 2 'Apache webserver found, enabling ownCloud specific configuration.' # https://doc.owncloud.org/server/administration_manual/installation/manual_installation.html#configure-apache-web-server - a2enmod rewrite headers env dir mime 1> /dev/null - local owncloud_conf='/etc/apache2/sites-available/dietpi-owncloud.conf' - if [[ -f $owncloud_conf ]]; then + # Navigate back to DietPi-Software working dir + G_EXEC cd /tmp/$G_PROGRAM_NAME - owncloud_conf+='.dietpi-new' - G_WHIP_MSG "Existing ownCloud Apache configuration found, will preserve the old one and save the new one for review and comparison to: $owncloud_conf" + # Use wg-quick@.service to start VPN on boot + G_EXEC systemctl enable wg-quick@wg0 + # - Start now if module is active already + (( $module_active )) && G_EXEC systemctl start wg-quick@wg0 - fi - dps_index=$software_id Download_Install 'apache.owncloud.conf' $owncloud_conf - a2ensite dietpi-owncloud 1> /dev/null - # Cal/CardDAV redirects to ownCloud DAV endpoint - if [[ ! -f '/etc/apache2/conf-available/dietpi-dav_redirect.conf' ]]; then + # Client choice + elif [[ $G_WHIP_RETURNED_VALUE == 'Client' ]]; then - echo '# Redirect Cal/CardDAV requests to ownCloud endpoint: -Redirect 301 /.well-known/carddav /owncloud/remote.php/dav -Redirect 301 /.well-known/caldav /owncloud/remote.php/dav' > /etc/apache2/conf-available/dietpi-dav_redirect.conf - a2enconf dietpi-dav_redirect + G_AGI resolvconf # Use by wg-quick to apply DNS in client setup + G_WHIP_MSG '[ INFO ] WireGuard client setup has been chosen\n +Please follow the instructions of your VPN provider to configure WireGuard.\n +If no WireGuard (auto)start is included, but you require it, please do the following: +1. Check for the created config file/interface name: + ls -Al /etc/wireguard/ + It has a ".conf" file ending, lets assume "wg0-client.conf". +2. To start the VPN interface, run: + systemctl start wg-quick@wg0-client +3. To autostart the VPN interface on boot, run: + systemctl enable wg-quick@wg0-client +4. To disable autostart again, run: + systemctl disable wg-quick@wg0-client' - fi + fi - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + (( $module_active )) || G_WHIP_MSG '[ INFO ] WireGuard install finished\n\nNB: WireGuard has been successfully installed, but a reboot is required, before it can be started.' - G_DIETPI-NOTIFY 2 'Lighttpd webserver found, enabling ownCloud specific configuration.' + unset -v module_active choice_required domain port invalid_text server_ip - # Enable required modules - G_CONFIG_INJECT '"mod_access",' ' "mod_access",' /etc/lighttpd/lighttpd.conf '"mod_.+",' - G_CONFIG_INJECT '"mod_setenv",' ' "mod_setenv",' /etc/lighttpd/lighttpd.conf '"mod_.+",' + fi - # Move ownCloud configuration file in place and activate it - owncloud_conf='/etc/lighttpd/conf-available/99-dietpi-owncloud.conf' - if [[ -f $owncloud_conf ]]; then + software_id=92 # Certbot + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - owncloud_conf+='.dietpi-new' - G_WHIP_MSG "Existing ownCloud Lighttpd configuration found, will preserve the old one and save the new one for review and comparison to: $owncloud_conf" + Banner_Installing - fi - dps_index=$software_id Download_Install 'lighttpd.owncloud.conf' $owncloud_conf - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod rewrite dietpi-owncloud + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - # Cal/CardDAV redirects to ownCloud DAV endpoint - if [[ ! -f '/etc/lighttpd/conf-enabled/99-dietpi-dav_redirect.conf' ]]; then + G_AGI certbot python3-certbot-apache - echo '# Redirect Cal/CardDAV requests to ownCloud endpoint: -url.redirect += ( - "^/.well-known/caldav" => "/owncloud/remote.php/dav", - "^/.well-known/carddav" => "/owncloud/remote.php/dav" -)' > /etc/lighttpd/conf-available/99-dietpi-dav_redirect.conf - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod dietpi-dav_redirect + elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - fi + G_AGI certbot python3-certbot-nginx - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + else - G_DIETPI-NOTIFY 2 'Nginx webserver found, enabling ownCloud specific configuration.' # https://doc.owncloud.org/server/administration_manual/installation/nginx_configuration.html - local owncloud_conf='/etc/nginx/sites-dietpi/dietpi-owncloud.conf' - if [[ -f $owncloud_conf ]]; then + G_AGI certbot - owncloud_conf+='.dietpi-new' - G_WHIP_MSG "Existing ownCloud Nginx configuration found, will preserve the old one and save the new one for review and comparison to: $owncloud_conf" + fi - fi - dps_index=$software_id Download_Install 'nginx.owncloud.conf' $owncloud_conf + fi - # Uncomment HSTS header, if chosen via dietpi-letsencrypt and HTTPS connection test succeeds (incl. self-singed cert => exit code 5) - if [[ -f '/boot/dietpi/.dietpi-letsencrypt' && $(mawk 'NR==4' /boot/dietpi/.dietpi-letsencrypt) == 1 ]]; then + software_id=60 # WiFi Hotspot + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - wget -q --spider --timeout=10 --tries=2 https://localhost &> /dev/null - [[ $? == [05] ]] && sed -i 's/#add_header Strict-Transport-Security/add_header Strict-Transport-Security/g' $owncloud_conf + Banner_Installing - fi + local packages=('hostapd' 'isc-dhcp-server' 'iptables' 'libnl-3-200') - # Disable pretty URLs (front controller) for ownCloud versions lower than 10: - (( $oc_version_major < 10 )) && sed -i 's/^[[:blank:]]*fastcgi_param front_controller_active true;/\t\t#fastcgi_param front_controller_active true;/g' $owncloud_conf + # RTL8188C* device and special Realtek hostapd package available + lsusb | grep -qi 'RTL8188C' && apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* hostapd-realtek(,|$)' && packages[0]='hostapd-realtek' - # Cal/CardDAV redirects to ownCloud DAV endpoint - if [[ ! -f '/etc/nginx/sites-dietpi/dietpi-dav_redirect.conf' ]]; then + G_AGI "${packages[@]}" - # shellcheck disable=SC2016 - echo '# Redirect Cal/CardDAV requests to ownCloud endpoint: -location = /.well-known/carddav { return 301 /owncloud/remote.php/dav/; } -location = /.well-known/caldav { return 301 /owncloud/remote.php/dav/; }' > /etc/nginx/sites-dietpi/dietpi-dav_redirect.conf + # Enable WiFi modules + /boot/dietpi/func/dietpi-set_hardware wifimodules enable - fi + # Unmask hostapd service: https://github.com/MichaIng/DietPi/issues/2962 + G_EXEC systemctl unmask hostapd - fi + local eth_iface=$(G_GET_NET -t eth iface) + local wifi_iface=$(G_GET_NET -t wlan iface) - # Start MariaDB and Redis (required for reinstalls) for database creation and occ command - G_EXEC systemctl restart mariadb - G_EXEC systemctl restart redis-server + # DHCPD Config + G_BACKUP_FP /etc/dhcp/dhcpd.conf + cat << '_EOF_' > /etc/dhcp/dhcpd.conf +ddns-update-style none; +default-lease-time 600; +max-lease-time 7200; +authoritative; +log-facility local7; - # Initially add occ command shortcut, will be done by Dietpi-Globals automatically, if occ file exist: - occ(){ sudo -u www-data php /var/www/owncloud/occ "$@"; } +subnet 192.168.42.0 netmask 255.255.255.0 { + range 192.168.42.10 192.168.42.50; + option broadcast-address 192.168.42.255; + option routers 192.168.42.1; + option domain-name "local"; + option domain-name-servers 8.8.8.8, 8.8.4.4; +} +_EOF_ + # Assign detected WLAN interface + echo "INTERFACESv4=\"$wifi_iface\"" > /etc/default/isc-dhcp-server - # Adjusting config file: - local config_php='/var/www/owncloud/config/config.php' + # Remove all entries below wlan, so we can recreate them + G_EXEC sed -i '/allow-hotplug wlan/q0' /etc/network/interfaces - local datadir=$(sed -n '/^[[:blank:]]*SOFTWARE_OWNCLOUD_DATADIR=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - [[ $datadir ]] || datadir='/mnt/dietpi_userdata/owncloud_data' - G_EXEC mkdir -p "$datadir" - G_EXEC chown -R www-data:www-data /var/www/owncloud "$datadir" + # Enable up wlan + G_CONFIG_INJECT 'allow-hotplug wlan' "allow-hotplug $wifi_iface" /etc/network/interfaces - if [[ -d '/mnt/dietpi_userdata/mysql/owncloud' ]]; then + # Add WiFi settings to network interfaces config + cat << _EOF_ >> /etc/network/interfaces +iface $wifi_iface inet static +address 192.168.42.1 +netmask 255.255.255.0 +#gateway 192.168.0.1 +wireless-power off +#dns-nameservers 8.8.8.8 8.8.4.4 - G_DIETPI-NOTIFY 2 'ownCloud database found, will NOT overwrite.' - if [[ ! -f $config_php ]]; then +# IP tables +up iptables-restore < /etc/iptables.ipv4.nat +_EOF_ + # Assign static IP for wlan now + G_EXEC ip a add 192.168.42.1 dev "$wifi_iface" - G_WHIP_MSG '[WARNING] Existing ownCloud database was found, but no related install directory\n -A remaining MariaDB "owncloud" database from an earlier installed instance was found. But the related install directory "/var/www/owncloud/config/config.php" does not exist. -Since running a fresh install with an existing database can produce data corruption, if the versions do not exactly match, you either need to remove the database or find and place the related install directory.\n -We cannot predict your aim and do not want to mess or break your data, so please do this manually.\n -To remove the existing database (including e.g. contacts, calendar, file tags etc.): - # mysqladmin drop owncloud -Otherwise to copy an existing instance in place: - # rm -R /var/www/owncloud - # mkdir /var/www/owncloud - # cp -a /path/to/existing/owncloud/. /var/www/owncloud/ -The install script will now exit. After applying one of the the above, rerun dietpi-software, e.g.: - # dietpi-software install 47' + # Create access point config + G_BACKUP_FP /etc/hostapd/hostapd.conf + cat << _EOF_ > /etc/hostapd/hostapd.conf +interface=$wifi_iface +driver=nl80211 +ssid=$(sed -n '/^[[:blank:]]*SOFTWARE_WIFI_HOTSPOT_SSID=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) +hw_mode=g +channel=$(sed -n '/^[[:blank:]]*SOFTWARE_WIFI_HOTSPOT_CHANNEL=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) +macaddr_acl=0 +auth_algs=1 +ignore_broadcast_ssid=0 +wpa=2 +wpa_passphrase=$(sed -n '/^[[:blank:]]*SOFTWARE_WIFI_HOTSPOT_KEY=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) +wpa_key_mgmt=WPA-PSK +wpa_pairwise=TKIP +rsn_pairwise=CCMP +_EOF_ + # Use "rtl871xdrv" driver when special package has been installed + dpkg-query -s hostapd-realtek &> /dev/null && G_CONFIG_INJECT 'driver=' 'driver=rtl871xdrv' /etc/hostapd/hostapd.conf - [[ -f '/var/www/owncloud/occ' ]] && G_EXEC rm /var/www/owncloud/occ - /boot/dietpi/dietpi-services start - exit 1 + # Enable access point config + echo 'DAEMON_CONF="/etc/hostapd/hostapd.conf"' > /etc/default/hostapd - fi + # Enable IP forwarding + echo -e 'net.ipv4.ip_forward=1\nnet.ipv6.conf.all.forwarding=1\nnet.ipv6.conf.default.forwarding=1' > /etc/sysctl.d/dietpi-wifihotspot.conf + sysctl net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 net.ipv6.conf.default.forwarding=1 - elif [[ -f $datadir/dietpi-owncloud-database-backup.sql ]]; then + # Apply IP tables + iptables -t nat -A POSTROUTING -o "$eth_iface" -j MASQUERADE + iptables -A FORWARD -i "$eth_iface" -o "$wifi_iface" -m state --state RELATED,ESTABLISHED -j ACCEPT + iptables -A FORWARD -i "$wifi_iface" -o "$eth_iface" -j ACCEPT - G_DIETPI-NOTIFY 2 'ownCloud database backup found, starting recovery...' - local dbuser=$(grep -m1 "^[[:blank:]]*'dbuser'" $config_php | mawk -F\' '{print $4}') - local dbpass=$(grep -m1 "^[[:blank:]]*'dbpassword'" $config_php | mawk -F\' '{print $4}') - /boot/dietpi/func/create_mysql_db owncloud "$dbuser" "$dbpass" - mysql owncloud < "$datadir/dietpi-owncloud-database-backup.sql" - ### Seems to be not needed anymore and can cause double entries: https://help.nextcloud.com/t/howto-change-move-data-directory-after-installation/17170/3?u=michaing - # Adjust database data directory entry, in case it changed due to server migration: - #G_EXEC mysql -e "update owncloud.oc_storages set id='local::$datadir/' where id rlike 'local::'" + # Save IP tables, applied during ifup in /etc/network/interfaces + iptables-save > /etc/iptables.ipv4.nat - elif ! grep -q "'installed' => true," $config_php 2>/dev/null; then + # RPi3/4 onboard WiFi: Enable N support + [[ $G_HW_MODEL == [34] ]] && G_CONFIG_INJECT 'ieee80211n=' 'ieee80211n=1' /etc/hostapd/hostapd.conf - local username=$(sed -n '/^[[:blank:]]*SOFTWARE_OWNCLOUD_NEXTCLOUD_USERNAME=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - [[ $username ]] || username='admin' + fi - # For MariaDB, temporary database admin user needs to be created, as 'root' uses unix_socket login, which cannot be accessed by sudo -u www-data. - # - Create random temporary alphanumeric 30 characters password - local oc_password=$(tr -dc '[:alnum:]' < /dev/random | head -c30) - # - Failsafe: Use non-blocking entropy source, if /dev/random fails - (( ${#oc_password} == 30 )) || oc_password=$(tr -dc '[:alnum:]' < /dev/urandom | head -c30) - G_EXEC mysql -e "grant all privileges on *.* to tmp_root@localhost identified by '$oc_password' with grant option" + software_id=61 # Tor Hotspot + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - G_EXEC_DESC='ownCloud occ install' - # - Replace password strings internally to avoid printing it to console - G_EXEC_PRE_FUNC(){ acommand[10]=$oc_password acommand[14]=$GLOBAL_PW; } - # - Checking output for stack trace to handle internal errors that do not lead to php error exit code - G_EXEC_POST_FUNC(){ grep -qi 'Stack trace' $fp_log && exit_code=255; } - G_EXEC occ maintenance:install --no-interaction --database 'mysql' --database-name 'owncloud' --database-user 'tmp_root' --database-pass "${oc_password//?/X}" --admin-user "$username" --admin-pass "${GLOBAL_PW//?/X}" --data-dir "$datadir" - G_EXEC mysql -e 'drop user tmp_root@localhost' - unset -v oc_password + Banner_Installing - # Remove obsolete default data dir - [[ $(readlink -f "$datadir") != $(readlink -f /var/www/owncloud/data) ]] && G_EXEC rm -R /var/www/owncloud/data + G_AGI tor - fi + Remove_SysV tor 1 - # Enable ownCloud to use 4-byte database - G_CONFIG_INJECT "'mysql.utf8mb4'" "'mysql.utf8mb4' => true," $config_php "'dbpassword'" + # Tor config + cat << '_EOF_' > /etc/tor/torrc +Log notice stdout +VirtualAddrNetwork 10.192.0.0/10 +AutomapHostsSuffixes .onion,.exit +AutomapHostsOnResolve 1 +TransPort 192.168.42.1:9040 +DNSPort 192.168.42.1:53 +_EOF_ + # Flush IP tables + iptables -F + iptables -t nat -F - # Add local IP and hostname to trusted domains. - # If "1 => '" does not exist, the config.php is not copied e.g. from older instance, so we add entries. - if ! grep -q "1 => '" $config_php; then + # Generate tor prerouting tables + local wifi_iface=$(G_GET_NET -t wlan iface) + iptables -t nat -A PREROUTING -i "$wifi_iface" -p tcp --dport 22 -j REDIRECT --to-ports 22 + iptables -t nat -A PREROUTING -i "$wifi_iface" -p udp --dport 53 -j REDIRECT --to-ports 53 + iptables -t nat -A PREROUTING -i "$wifi_iface" -p tcp --syn -j REDIRECT --to-ports 9040 - sed -i "/0 => 'localhost'/a 1 => '$(G_GET_NET ip)'," $config_php - sed -i "/1 => '/a 2 => '$( /etc/iptables.ipv4.nat - fi + # User: Test tor is functional + #https://check.torproject.org - # Set CLI URL to ownCloud sub directory: - G_EXEC sed -i "s|'http://localhost'|'http://localhost/owncloud'|" $config_php + fi - # Set pretty URLs (without /index.php/) on Apache: - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + software_id=189 # VSCodium + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - GCI_PRESERVE=1 G_CONFIG_INJECT "'htaccess.RewriteBase'" "'htaccess.RewriteBase' => '/owncloud'," $config_php "'overwrite.cli.url'" - occ maintenance:update:htaccess + Banner_Installing - fi + # APT key + G_EXEC eval "curl -sSfL 'https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-vscodium.gpg --yes" - # APCu Memcache - GCI_PRESERVE=1 G_CONFIG_INJECT "'memcache.local'" "'memcache.local' => '\\\\OC\\\\Memcache\\\\APCu'," $config_php "'version'" + # APT list + G_EXEC eval "echo 'deb https://paulcarroty.gitlab.io/vscodium-deb-rpm-repo/debs vscodium main' > /etc/apt/sources.list.d/dietpi-vscodium.list" + G_AGUP - # Redis for transactional file locking: - G_DIETPI-NOTIFY 2 'Enabling Redis for transactional file locking.' # https://doc.owncloud.org/server/administration_manual/configuration/server/caching_configuration.html#configuring-transactional-file-locking - local redis_conf='/etc/redis/redis.conf' - # - Enable Redis socket and grant www-data access to it - GCI_PRESERVE=1 G_CONFIG_INJECT 'unixsocket[[:blank:]]' 'unixsocket /run/redis/redis-server.sock' $redis_conf - G_CONFIG_INJECT 'unixsocketperm[[:blank:]]' 'unixsocketperm 770' $redis_conf - G_EXEC usermod -aG redis www-data - G_EXEC systemctl restart redis-server - # - Enable ownCloud to use Redis socket for transactional file locking: - G_CONFIG_INJECT "'filelocking.enabled'" "'filelocking.enabled' => true," $config_php "'memcache.local'" - local redis_sock=$(grep -m1 '^[[:blank:]]*unixsocket[[:blank:]]' $redis_conf | mawk '{print $2}') # Re-estimate in case of existing custom path - GCI_PRESERVE=1 GCI_NEWLINE=1 G_CONFIG_INJECT "'memcache.locking'" "'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis',\n'redis' => array ('host' => '$redis_sock', 'port' => 0,)," $config_php "'filelocking.enabled'" + # APT package + # - gnome-keyring is the backend daemon for the Secrets API used to store credentials, required e.g. for the GitHub PR and issues extension. + G_AGI codium gnome-keyring - # Enable ownCloud background cron job: - # - v10.3 comes with new occ system:cron command: https://doc.owncloud.org/server/10.3/admin_manual/release_notes.html#changes-to-background-job-execution - local occ_command='occ system:cron' - (( $oc_version_major < 10 || ( $oc_version_major == 10 && $oc_version_minor < 3 ) )) && occ_command='cron.php' - 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 + # Desktop shortcut + Create_Desktop_Shortcut codium - # Enable maintenance mode to allow handling by dietpi-services: - grep -q "^[[:blank:]]*'maintenance' => true," $config_php || occ maintenance:mode --on + fi - # 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 + software_id=37 # Shairport Sync + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/shairport-sync_$G_HW_ARCH_NAME.deb" fi - software_id=114 # Nextcloud + software_id=48 # Pydio if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - G_DIETPI-NOTIFY 2 'Enabling required PHP modules.' # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation - G_EXEC phpenmod ctype curl dom gd iconv intl json mbstring pdo_mysql posix simplexml xmlreader xmlwriter zip fileinfo opcache apcu redis exif + # Install required PHP modules + DEPS_LIST="$PHP_NAME-apcu $PHP_NAME-gd $PHP_NAME-intl $PHP_NAME-mbstring $PHP_NAME-opcache $PHP_NAME-xml" - 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 - G_EXEC phpenmod dietpi-nextcloud + # Skip install, if already present + if [[ -d /var/www/pydio ]]; then - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/var/www/pydio\" already exists. Download and install steps will be skipped. + - Please manually backup your config files+data, remove the install dir and rerun \"dietpi-software (re)install $software_id\" if you need to reinstall. + - If you want to update the ${aSOFTWARE_NAME[$software_id]} instance, please use the internal updater from WebUI." + # shellcheck disable=SC2086 + G_AGI $DEPS_LIST + DEPS_LIST= - G_DIETPI-NOTIFY 2 'Apache webserver found, enabling Nextcloud specific configuration.' # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#apache-web-server-configuration - a2enmod rewrite headers env dir mime 1> /dev/null - local nextcloud_conf='/etc/apache2/sites-available/dietpi-nextcloud.conf' - if [[ -f $nextcloud_conf ]]; then + else - nextcloud_conf+='.dietpi-new' - G_WHIP_MSG "Existing Nextcloud Apache configuration found, will preserve the old one and save the new one for review and comparison to: $nextcloud_conf" + Download_Install 'https://download.pydio.com/pub/core/ci/pydio-latest.tar.gz' /var/www + mv /var/www/pydio-latest /var/www/pydio - fi - dps_index=$software_id Download_Install 'apache.nextcloud.conf' $nextcloud_conf - a2ensite dietpi-nextcloud 1> /dev/null - # Cal/CardDAV redirects to Nextcloud DAV endpoint - if [[ ! -f '/etc/apache2/conf-available/dietpi-dav_redirect.conf' ]]; then + fi - echo '# Redirect Cal/CardDAV requests to Nextcloud endpoint: -Redirect 301 /.well-known/carddav /nextcloud/remote.php/dav -Redirect 301 /.well-known/caldav /nextcloud/remote.php/dav' > /etc/apache2/conf-available/dietpi-dav_redirect.conf - a2enconf dietpi-dav_redirect + # PHP configuration + G_EXEC phpenmod apcu gd intl pdo_mysql dom mbstring xml - fi + # Webserver config + # - Apache2 + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + # Enable Apache2 rewrite engine + a2enmod rewrite - G_DIETPI-NOTIFY 2 'Lighttpd webserver found, enabling Nextcloud specific configuration.' + # Move Pydio Apache2 config in place + dps_index=$software_id Download_Install 'apache.pydio.conf' /etc/apache2/sites-available/dietpi-pydio.conf + a2ensite dietpi-pydio - # Enable required modules + # - Lighttpd + elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + + # Enable Lighttpd setenv, access and rewrite modules G_CONFIG_INJECT '"mod_access",' ' "mod_access",' /etc/lighttpd/lighttpd.conf '"mod_.+",' G_CONFIG_INJECT '"mod_setenv",' ' "mod_setenv",' /etc/lighttpd/lighttpd.conf '"mod_.+",' - # Move Nextcloud configuration file in place and activate it - nextcloud_conf='/etc/lighttpd/conf-available/99-dietpi-nextcloud.conf' - if [[ -f $nextcloud_conf ]]; then + # Move Pydio Lighttpd config in place + dps_index=$software_id Download_Install 'lighttpd.pydio.conf' /etc/lighttpd/conf-available/99-dietpi-pydio.conf + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod rewrite dietpi-pydio - nextcloud_conf+='.dietpi-new' - G_WHIP_MSG "Existing Nextcloud Lighttpd configuration found, will preserve the old one and save the new one for review and comparison to: $nextcloud_conf" + # - Nginx + elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - fi - dps_index=$software_id Download_Install 'lighttpd.nextcloud.conf' $nextcloud_conf - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod rewrite dietpi-nextcloud + # Move Pydio Nginx config in place + dps_index=$software_id Download_Install 'nginx.pydio.conf' /etc/nginx/sites-dietpi/dietpi-pydio.conf - # Cal/CardDAV redirects to Nextcloud DAV endpoint - if [[ ! -f '/etc/lighttpd/conf-enabled/99-dietpi-dav_redirect.conf' ]]; then + fi - echo '# Redirect Cal/CardDAV requests to Nextcloud endpoint: -url.redirect += ( - "^/.well-known/caldav" => "/nextcloud/remote.php/dav", - "^/.well-known/carddav" => "/nextcloud/remote.php/dav" -)' > /etc/lighttpd/conf-available/99-dietpi-dav_redirect.conf - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod dietpi-dav_redirect + # Create MySQL DB + /boot/dietpi/func/create_mysql_db pydio pydio "$GLOBAL_PW" - fi + # Setup Data directory + # - Skip if already existent + local target_data_dir=/mnt/dietpi_userdata/pydio_data + if [[ -d $target_data_dir ]]; then - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + G_DIETPI-NOTIFY 2 "Existing $target_data_dir found, will migrate..." + [[ -e '/var/www/pydio/data' ]] && rm -R /var/www/pydio/data - G_DIETPI-NOTIFY 2 'Nginx webserver found, enabling Nextcloud specific configuration.' # https://docs.nextcloud.com/server/stable/admin_manual/installation/nginx.html - local nextcloud_conf='/etc/nginx/sites-dietpi/dietpi-nextcloud.conf' - if [[ -f $nextcloud_conf ]]; then + else - nextcloud_conf+='.dietpi-new' - G_WHIP_MSG "Existing Nextcloud Nginx configuration found, will preserve the old one and save the new one for review and comparison to: $nextcloud_conf" + # - Move data structure + [[ -e $target_data_dir ]] && rm -R $target_data_dir + mv /var/www/pydio/data $target_data_dir - fi - dps_index=$software_id Download_Install 'nginx.nextcloud.conf' $nextcloud_conf + fi - # Uncomment HSTS header, if chosen via dietpi-letsencrypt and HTTPS connection test succeeds (incl. self-singed cert => exit code 5) - if [[ -f '/boot/dietpi/.dietpi-letsencrypt' && $(mawk 'NR==4' /boot/dietpi/.dietpi-letsencrypt) == 1 ]]; then + # Create symlink + ln -sf $target_data_dir /var/www/pydio/data + chown -R www-data:www-data $target_data_dir + + fi + + software_id=36 # Squeezelite + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/squeezelite_$G_HW_ARCH_NAME.deb" - wget -q --spider --timeout=10 --tries=2 https://localhost &> /dev/null - [[ $? == [05] ]] && sed -i 's/#add_header Strict-Transport-Security/add_header Strict-Transport-Security/g' $nextcloud_conf + fi - fi + software_id=66 # RPi-Monitor + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # Disable pretty URLs (front controller), if Nextcloud version is lower than 13 - if (( $(sed -n '/OC_VersionString/{s/^[^0-9]*//;s/\..*$//p;q}' /var/www/nextcloud/version.php) < 13 )); then + Banner_Installing - sed -i 's/^[[:blank:]]*fastcgi_param front_controller_active true;/\t\t#fastcgi_param front_controller_active true;/g' $nextcloud_conf + Download_Install 'https://raw.githubusercontent.com/XavierBerger/RPi-Monitor-deb/develop/packages/rpimonitor_2.13-beta6_all.deb' - fi + # Update APT package status + G_EXEC /usr/share/rpimonitor/scripts/updatePackagesStatus.pl - # Cal/CardDAV redirects to Nextcloud DAV endpoint - if [[ ! -f '/etc/nginx/sites-dietpi/dietpi-dav_redirect.conf' ]]; then + # USB drive stats implementation by Rich + if [[ ! -f '/etc/rpimonitor/template/usb_hdd.conf' ]] && findmnt -S /dev/sda1 > /dev/null + then + G_EXEC sed -i '\|include=/etc/rpimonitor/template/sdcard.conf|a\include=/etc/rpimonitor/template/usb_hdd.conf' /etc/rpimonitor/data.conf + cat << '_EOF_' > /etc/rpimonitor/template/usb_hdd.conf +######################################################################## +# Extract USB HDD (sda1) information +# Page: 1 +# Information Status Statistics +# - USBHDD1 total - yes - yes +# - USBHDD1 used - yes - yes +######################################################################## +static.10.name=usbhdd_total +static.10.source=df -t ext4 +static.10.regexp=sda1\s+(\d+) +static.10.postprocess=$1/1024 - # shellcheck disable=SC2016 - echo '# Redirect Cal/CardDAV requests to Nextcloud endpoint: -location = /.well-known/carddav { return 301 /nextcloud/remote.php/dav/; } -location = /.well-known/caldav { return 301 /nextcloud/remote.php/dav/; }' > /etc/nginx/sites-dietpi/dietpi-dav_redirect.conf +dynamic.14.name=usbhdd_used +dynamic.14.source=df -t ext4 +dynamic.14.regexp=sda1\s+\d+\s+(\d+) +dynamic.14.postprocess=$1/1024 +dynamic.14.rrd=GAUGE - fi +web.status.1.content.9.name=USB HDD +web.status.1.content.9.icon=usb_hdd.png +web.status.1.content.9.line.1="/sda1 Used: "+KMG(data.usbhdd_used,'M')+" ("+Percent(data.udbhdd_used,data.usbhdd_total,'M')+") Free: "+KMG(data.usbhdd_total-data.usbhdd_used,'M')+ " Total: "+ KMG(data.usbhdd_total,'M') +"" +web.status.1.content.9.line.2=ProgressBar(data.usbhdd_used,data.usbhdd_total) +web.statistics.1.content.9.name=USB HDD +web.statistics.1.content.9.graph.1=usbhdd_total +web.statistics.1.content.9.graph.2=usbhdd_used +web.statistics.1.content.9.ds_graph_options.usbhdd_total.label=USB HDD total space (MB) +web.statistics.1.content.9.ds_graph_options.usbhdd_total.color="#FF7777" +web.statistics.1.content.9.ds_graph_options.usbhdd_used.label=USB HDD used space (MB) +web.statistics.1.content.9.ds_graph_options.usbhdd_used.lines={ fill: true } +web.statistics.1.content.9.ds_graph_options.usbhdd_used.color="#7777FF" +_EOF_ fi - # Start MariaDB and Redis (required for reinstalls) for database creation and ncc command - G_EXEC systemctl restart mariadb - G_EXEC systemctl restart redis-server + fi - # Initially add occ command shortcut, will be done by Dietpi-Globals automatically, if occ file exist: - ncc(){ sudo -u www-data php /var/www/nextcloud/occ "$@"; } + software_id=65 # Netdata + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # Adjusting config file: - local config_php='/var/www/nextcloud/config/config.php' + Banner_Installing - local datadir=$(sed -n '/^[[:blank:]]*SOFTWARE_NEXTCLOUD_DATADIR=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - [[ $datadir ]] || datadir='/mnt/dietpi_userdata/nextcloud_data' - G_EXEC mkdir -p "$datadir" - G_EXEC chown -R www-data:www-data /var/www/nextcloud "$datadir" + # No package available on Stretch + if (( $G_DISTRO < 5 )); then - if [[ -d '/mnt/dietpi_userdata/mysql/nextcloud' ]]; then + # For ARMv6 RPi use our self-compiled package + if (( $G_HW_ARCH == 1 )); then - G_DIETPI-NOTIFY 2 'Nextcloud database found, will NOT overwrite.' - if [[ ! -f $config_php ]]; then + DEPS_LIST='zlib1g-dev' + Download_Install 'https://dietpi.com/downloads/binaries/all/netdata_1.11.1-1_armv6l.deb' - G_WHIP_MSG '[WARNING] Existing Nextcloud database was found, but no related install directory\n -A remaining MariaDB "nextcloud" database from an earlier installed instance was found. But the related install directory "/var/www/nextcloud/config/config.php" does not exist. -Since running a fresh install with an existing database can produce data corruption, if the versions do not exactly match, you either need to remove the database or find and place the related install directory.\n -We cannot predict your aim and do not want to mess or break your data, so please do this manually.\n -To remove the existing database (including e.g. contacts, calendar, file tags etc.): - # mysqladmin drop nextcloud -Otherwise to copy an existing instance in place: - # rm -R /var/www/nextcloud - # mkdir /var/www/nextcloud - # cp -a /path/to/existing/nextcloud/. /var/www/nextcloud/ -The install script will now exit. After applying one of the the above, rerun dietpi-software, e.g.: - # dietpi-software install 114' + # Else use the packages from Debian Stretch backports snapshot, that were removed recently, hosted now on dietpi.com + else - [[ -f '/var/www/nextcloud/occ' ]] && G_EXEC rm /var/www/nextcloud/occ - /boot/dietpi/dietpi-services start - exit 1 + 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* fi - elif [[ -f $datadir/dietpi-nextcloud-database-backup.sql ]]; then + else - G_DIETPI-NOTIFY 2 'Nextcloud database backup found, starting recovery...' - local dbuser=$(grep -m1 "^[[:blank:]]*'dbuser'" $config_php | mawk -F\' '{print $4}') - local dbpass=$(grep -m1 "^[[:blank:]]*'dbpassword'" $config_php | mawk -F\' '{print $4}') - /boot/dietpi/func/create_mysql_db nextcloud "$dbuser" "$dbpass" - mysql nextcloud < "$datadir/dietpi-nextcloud-database-backup.sql" - ### Seems to be not needed anymore and can cause double entries: https://help.nextcloud.com/t/howto-change-move-data-directory-after-installation/17170/3?u=michaing - # Adjust database data directory entry, in case it changed due to server migration: - #G_EXEC mysql -e "update nextcloud.oc_storages set id='local::$datadir/' where id rlike 'local::'" + G_AGI netdata - elif ! grep -q "'installed' => true," $config_php 2>/dev/null; then + fi - local username=$(sed -n '/^[[:blank:]]*SOFTWARE_OWNCLOUD_NEXTCLOUD_USERNAME=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - [[ $username ]] || username='admin' + # Only required for our self-compiled package, leave defaults for Debian APT package otherwise + if (( $G_HW_ARCH == 1 && $G_DISTRO < 5 )); then - # For MariaDB, temporary database admin user needs to be created, as 'root' uses unix_socket login, which cannot be accessed by sudo -u www-data. - # - Create random temporary alphanumeric 30 characters password - local nc_password=$(tr -dc '[:alnum:]' < /dev/random | head -c30) - # - Failsafe: Use non-blocking entropy source, if /dev/random fails - (( ${#nc_password} == 30 )) || nc_password=$(tr -dc '[:alnum:]' < /dev/urandom | head -c30) - G_EXEC mysql -e "grant all privileges on *.* to tmp_root@localhost identified by '$nc_password' with grant option" + # Service + dps_index=$software_id Download_Install 'netdata.service' /etc/systemd/system/netdata.service - G_EXEC_DESC='Nextcloud ncc install' - # - Replace password strings internally to avoid printing it to console - G_EXEC_PRE_FUNC(){ acommand[10]=$nc_password acommand[14]=$GLOBAL_PW; } - # - Checking output for stack trace to handle internal errors that do not lead to php error exit code - # - Workaround Nextcloud 14.0.3 throwing an error, when data dir path contains a symlink: https://github.com/nextcloud/server/issues/12247 - G_EXEC_POST_FUNC(){ + # Dir (failsafe) + mkdir -p /var/lib/netdata - if (( $exit_code )); then + # User + Create_User -d /var/lib/netdata netdata - grep -q 'Following symlinks is not allowed' $fp_log && { cp -a /var/www/nextcloud/core/skeleton/. "$datadir/$username/files/"; exit_code=0; } + # 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 + # - apps.plugin requires root privileges to read disk I/O + 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 - else + fi - grep -qi 'Stack trace' $fp_log && exit_code=255 + fi - fi + software_id=57 # Baïkal + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - } - G_EXEC ncc maintenance:install --no-interaction --database 'mysql' --database-name 'nextcloud' --database-user 'tmp_root' --database-pass "${nc_password//?/X}" --admin-user "$username" --admin-pass "${GLOBAL_PW//?/X}" --data-dir "$datadir" - G_EXEC mysql -e 'drop user tmp_root@localhost' - unset -v nc_password + Banner_Installing - # Remove obsolete default data dir - [[ $(readlink -f "$datadir") != $(readlink -f /var/www/nextcloud/data) ]] && G_EXEC rm -R /var/www/nextcloud/data + # APT deps: https://github.com/sabre-io/Baikal/wiki/Baïkal-dependencies + DEPS_LIST="$PHP_NAME-xml $PHP_NAME-mbstring $PHP_NAME-mysql" - fi + local fallback_url='https://github.com/sabre-io/Baikal/releases/download/0.8.0/baikal-0.8.0.zip' + Download_Install "$(curl -sSfL 'https://api.github.com/repos/sabre-io/Baikal/releases/latest' | mawk -F\" '/"browser_download_url": .*\/baikal-[^"\/]*\.zip"/{print $4}')" - # Enable Nextcloud to use 4-byte database - G_CONFIG_INJECT "'mysql.utf8mb4'" "'mysql.utf8mb4' => true," $config_php "'dbpassword'" + # Reinstall: https://sabre.io/baikal/upgrade/ + if [[ -d '/var/www/baikal' ]]; then - # Disable trusted_domains. - grep -q "1 => '*'" $config_php || sed -i "/0 => 'localhost'/a 1 => '*'," $config_php + [[ -d '/var/www/baikal/Specific' ]] && G_EXEC cp -a /var/www/baikal/Specific/. baikal/Specific/ + [[ -d '/var/www/baikal/config' ]] && G_EXEC cp -a /var/www/baikal/config/. baikal/config/ + G_EXEC rm -R /var/www/baikal - # Set CLI URL to Nextcloud sub directory: - G_EXEC sed -i "s|'http://localhost'|'http://localhost/nextcloud'|" $config_php + fi + G_EXEC mv baikal /var/www/baikal - # Set pretty URLs (without /index.php/) on Apache: + # Enable required PHP modules: https://github.com/sabre-io/Baikal/wiki/Baïkal-dependencies + G_EXEC phpenmod xml mbstring pdo_mysql + + # Database + /boot/dietpi/func/create_mysql_db baikal baikal "$GLOBAL_PW" + + # Web server configs: http://sabre.io/baikal/install/ + https://github.com/bambocher/docker-baikal/blob/master/lighttpd.conf + # - Apache if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - GCI_PRESERVE=1 G_CONFIG_INJECT "'htaccess.RewriteBase'" "'htaccess.RewriteBase' => '/nextcloud'," $config_php "'overwrite.cli.url'" - ncc maintenance:update:htaccess + dps_index=$software_id Download_Install 'apache.baikal.conf' /etc/apache2/sites-available/dietpi-baikal.conf + a2ensite dietpi-baikal + echo '# Redirect Cal/CardDAV requests to Baïkal endpoint: +Redirect 301 /.well-known/carddav /baikal/html/dav.php +Redirect 301 /.well-known/caldav /baikal/html/dav.php' > /etc/apache2/conf-available/dietpi-dav_redirect.conf + a2enconf dietpi-dav_redirect + + # - Lighttpd + elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + + dps_index=$software_id Download_Install 'lighttpd.baikal.conf' /etc/lighttpd/conf-available/99-dietpi-baikal.conf + echo '# Redirect Cal/CardDAV requests to Baïkal endpoint: +url.redirect += ( + "^/.well-known/caldav" => "/baikal/html/dav.php", + "^/.well-known/carddav" => "/baikal/html/dav.php" +)' > /etc/lighttpd/conf-available/99-dietpi-dav_redirect.conf + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod dietpi-baikal dietpi-dav_redirect + + # - Nginx + elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + + dps_index=$software_id Download_Install 'nginx.baikal.conf' /etc/nginx/sites-dietpi/dietpi-baikal.conf + # shellcheck disable=SC2016 + echo '# Redirect Cal/CardDAV requests to Baïkal endpoint: +location = /.well-known/carddav { return 301 /baikal/html/dav.php; } +location = /.well-known/caldav { return 301 /baikal/html/dav.php; }' > /etc/nginx/sites-dietpi/dietpi-dav_redirect.conf fi - # APCu Memcache - GCI_PRESERVE=1 G_CONFIG_INJECT "'memcache.local'" "'memcache.local' => '\\\\OC\\\\Memcache\\\\APCu'," $config_php "'version'" + # Permissions + G_EXEC chown -R www-data:root /var/www/baikal/{Specific,config} + G_EXEC find /var/www/baikal/{Specific,config} \( -name '.ht*' -o -name '.git*' \) -exec chown root {} + - # Redis for transactional file locking: - G_DIETPI-NOTIFY 2 'Enabling Redis for transactional file locking.' # https://docs.nextcloud.com/server/stable/admin_manual/configuration_files/files_locking_transactional.html - local redis_conf="/etc/redis/redis.conf" - # - Enable Redis socket and grant www-data access to it - GCI_PRESERVE=1 G_CONFIG_INJECT 'unixsocket[[:blank:]]' 'unixsocket /run/redis/redis-server.sock' $redis_conf - G_CONFIG_INJECT 'unixsocketperm[[:blank:]]' 'unixsocketperm 770' $redis_conf - G_EXEC usermod -aG redis www-data - G_EXEC systemctl restart redis-server - # - Enable Nextcloud to use Redis socket: - G_CONFIG_INJECT "'filelocking.enabled'" "'filelocking.enabled' => true," $config_php "'memcache.local'" - local redis_sock=$(grep -m1 '^[[:blank:]]*unixsocket[[:blank:]]' $redis_conf | mawk '{print $2}') # Re-estimate in case of existing custom path - GCI_PRESERVE=1 GCI_NEWLINE=1 G_CONFIG_INJECT "'memcache.locking'" "'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis',\n'redis' => array ('host' => '$redis_sock', 'port' => 0,)," $config_php "'filelocking.enabled'" + fi - # Tweak Argon2 hashing - # - Use all available CPU threads - GCI_PRESERVE=1 G_CONFIG_INJECT "'hashingThreads'" "'hashingThreads' => ${G_HW_CPU_CORES}," $config_php "'version'" - # - ToDo: Configure the other settings after getting some clarifications: https://github.com/nextcloud/server/pull/19023#issuecomment-660071524 - #GCI_PRESERVE=1 G_CONFIG_INJECT "'hashingMemoryCost'" "'hashingMemoryCost' => 65536," $config_php "'hashingThreads'" - #GCI_PRESERVE=1 G_CONFIG_INJECT "'hashingTimeCost'" "'hashingTimeCost' => 4," $config_php "'hashingMemoryCost'" + software_id=43 # Mumble Server + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # Enable Nextcloud background cron job: https://docs.nextcloud.com/server/17/admin_manual/configuration_server/background_jobs_configuration.html#cron - crontab -u www-data -l 2> /dev/null | grep -q '/var/www/nextcloud/cron.php' || ( crontab -u www-data -l 2> /dev/null ; echo '*/5 * * * * php /var/www/nextcloud/cron.php' ) | crontab -u www-data - - ncc background:cron + Banner_Installing - # Convert filecache table to bigint, which is not done automatically by Nextcloud since v15 - ncc db:convert-filecache-bigint -n + G_AGI mumble-server - # Add missing database columns and indices, which is not done automatically by Nextcloud - ncc db:add-missing-columns - ncc db:add-missing-indices - ncc db:add-missing-primary-keys + # Cap total connections + local max_users=$(( $G_HW_CPU_CORES * 8 )) + G_EXEC sed -i "/users=/c\users=$max_users" /etc/mumble-server.ini + + # Name the root channel + G_EXEC sed -i '/registerName=/c\registerName=DietPi Mumble Server' /etc/mumble-server.ini - # Enable maintenance mode to allow handling by dietpi-services: - grep -q "^[[:blank:]]*'maintenance' => true," $config_php || ncc maintenance:mode --on + # Disable DB logging + G_EXEC sed -i '/logdays=/c\logdays=-1' /etc/mumble-server.ini - # 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 + # Set Superuser passwd: https://dietpi.com/phpbb/viewtopic.php?p=8084#p8084 + murmurd -ini /etc/mumble-server.ini -supw "$GLOBAL_PW" fi - software_id=168 # Nextcloud Talk + software_id=41 # Emby Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - G_DIETPI-NOTIFY 2 'Configuring TURN server:' - # Buster: systemd unit - if [[ -f '/lib/systemd/system/coturn.service' ]]; then + # ARMv7 + local arch='armhf' - Remove_SysV coturn 1 + # ARMv8 + if (( $G_HW_ARCH == 3 )); then - # Disable Coturn logging by default, this can be overridden via /etc/turnserver.conf - 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 + arch='arm64' - # Stretch: sysvinit service - else + # x86_64 + elif (( $G_HW_ARCH == 10 )); then - # Enable init.d service - G_CONFIG_INJECT 'TURNSERVER_ENABLED=' 'TURNSERVER_ENABLED=1' /etc/default/coturn - # Disable coturn logging by default, this can be overridden via /etc/turnserver.conf - G_CONFIG_INJECT 'DAEMON_ARGS=' "DAEMON_ARGS='-c /etc/turnserver.conf -o -l stdout --no-stdout-log --simple-log'" /etc/default/coturn + arch='amd64' fi - # Ask user for server domain and desired TURN server port - local invalid_text= - local domain=$(hostname -f) - while : - do - G_WHIP_DEFAULT_ITEM=$domain - if G_WHIP_INPUTBOX "${invalid_text}Please enter your servers external domain to allow Nextcloud Talk access your TURN server:" && [[ $G_WHIP_RETURNED_VALUE ]]; then - - domain=${G_WHIP_RETURNED_VALUE#http*://} - break + local fallback_url="https://github.com/MediaBrowser/Emby.Releases/releases/download/4.6.4.0/emby-server-deb_4.6.4.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}")" - else + # 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 - invalid_text='[ERROR] No valid entry found. Please retry...\n\n' + Download_Test_Media - fi - done - invalid_text= - local port=3478 - while : - do - G_WHIP_DEFAULT_ITEM=$port - if G_WHIP_INPUTBOX "${invalid_text}Please enter the network port, that should be used for your TURN server:\n -NB: This port needs to be forwarded by your router and/or opened in your firewall settings. Default value is: 3478" && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 0; then + fi - port=$G_WHIP_RETURNED_VALUE - break + software_id=42 # Plex Media Server + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - else + Banner_Installing - invalid_text='[ERROR] No valid entry found, value needs to be a sequence of integers. Please retry...\n\n' + # 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" - fi - done + # APT list + G_EXEC eval "echo 'deb https://downloads.plex.tv/repo/deb/ public main' > /etc/apt/sources.list.d/plexmediaserver.list" + G_AGUP - # Adjust coTURN settings - # - If /etc/turnserver.conf is not present, use default or create empty file - if [[ ! -f '/etc/turnserver.conf' ]]; then + # APT package + G_AGI plexmediaserver - # shellcheck disable=SC2015 - [[ -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 + # 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 + # - Unset explicit group in service file (applied by DEB package) as this may override supplementary group permissions + G_EXEC mkdir -p /etc/systemd/system/plexmediaserver.service.d + echo -e '[Service]\nGroup=' > /etc/systemd/system/plexmediaserver.service.d/dietpi-group.conf - fi - # - 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 - G_CONFIG_INJECT 'fingerprint' 'fingerprint' /etc/turnserver.conf - G_CONFIG_INJECT 'use-auth-secret' 'use-auth-secret' /etc/turnserver.conf - if (( $version < 4508 )); then + # Unbound: Fix secure remote access: https://dietpi.com/phpbb/viewtopic.php?t=8896 + (( ${aSOFTWARE_INSTALL_STATE[182]} == 2 )) && echo -e 'server:\n\tprivate-domain: "plex.direct"' > /etc/unbound/unbound.conf.d/dietpi-plex.conf - G_CONFIG_INJECT 'lt-cred-mech' 'lt-cred-mech' /etc/turnserver.conf + Download_Test_Media - else + fi - sed -i 's/^[[:blank:]]*lt-cred-mech/#lt-cred-mech/' /etc/turnserver.conf + software_id=52 # Cuberite + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - fi - G_CONFIG_INJECT 'realm=' "realm=$domain" /etc/turnserver.conf - GCI_PRESERVE=1 G_CONFIG_INJECT 'total-quota=' 'total-quota=100' /etc/turnserver.conf - GCI_PRESERVE=1 G_CONFIG_INJECT 'bps-capacity=' 'bps-capacity=0' /etc/turnserver.conf - G_CONFIG_INJECT 'stale-nonce' 'stale-nonce' /etc/turnserver.conf - if (( $version < 4510 )); then + Banner_Installing - G_CONFIG_INJECT 'no-loopback-peers' 'no-loopback-peers' /etc/turnserver.conf + # ARMv6/7/8: https://github.com/cuberite/cuberite/issues/5221 + local url='https://download.cuberite.org/linux-armhf-raspbian/Cuberite.tar.gz' - else + # x86_64 + (( $G_HW_ARCH == 10 )) && url='https://download.cuberite.org/linux-x86_64/Cuberite.tar.gz' - sed -i 's/^[[:blank:]]*allow-loopback-peers/#allow-loopback-peers/' /etc/turnserver.conf - sed -i '/^[[:blank:]]*no-loopback-peers/d' /etc/turnserver.conf + Download_Install "$url" /mnt/dietpi_userdata/cuberite - fi - G_CONFIG_INJECT 'no-multicast-peers' 'no-multicast-peers' /etc/turnserver.conf + # User + Create_User -d /mnt/dietpi_userdata/cuberite cuberite - # Install Nextcloud Talk app - G_EXEC systemctl start mariadb - G_EXEC systemctl start redis-server - G_EXEC ncc maintenance:mode --off - if [[ ! -d '/var/www/nextcloud/apps/spreed' ]]; then + # Service: Needs to be Type=forking, else it shuts down automatically after startup has finished :/ ... + cat << '_EOF_' > /etc/systemd/system/cuberite.service +[Unit] +Description=Cuberite Server (DietPi) - # Succeed if app is already installed and on "Cannot declare class" bug: https://github.com/MichaIng/DietPi/issues/3499#issuecomment-622955490 - G_EXEC_POST_FUNC(){ [[ $exit_code != 0 && $(<$fp_log) =~ (' already installed'$|' Cannot declare class ') ]] && exit_code=0; } - G_EXEC ncc app:install spreed +[Service] +Type=forking +User=cuberite +WorkingDirectory=/mnt/dietpi_userdata/cuberite +ExecStart=/mnt/dietpi_userdata/cuberite/Cuberite -d - fi - ncc app:enable spreed +[Install] +WantedBy=multi-user.target +_EOF_ + # Web UI settings: Do not overwrite existing! + [[ -f '/mnt/dietpi_userdata/cuberite/webadmin.ini' ]] || cat << _EOF_ > /mnt/dietpi_userdata/cuberite/webadmin.ini +[User:admin] +Password=$GLOBAL_PW - # 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) - GCI_PASSWORD=1 GCI_PRESERVE=1 G_CONFIG_INJECT 'static-auth-secret=' "static-auth-secret=$secret" /etc/turnserver.conf - # - Scrape existing secret, in case user manually chose/edited it - secret=$(sed -n '/^[[:blank:]]*static-auth-secret=/{s/^[^=]*=//p;q}' /etc/turnserver.conf) - ncc config:app:set spreed turn_servers --value="[{\"server\":\"$domain:$port\",\"secret\":\"$secret\",\"protocols\":\"udp,tcp\"}]" | sed 's/"secret":".*","protocols"/"secret":"","protocols"/' - unset secret domain port invalid_text version +[WebAdmin] +Ports=1339 +Enabled=1 +_EOF_ + # Permissions + G_EXEC chmod 0600 /mnt/dietpi_userdata/cuberite/webadmin.ini + G_EXEC chown -R cuberite:cuberite /mnt/dietpi_userdata/cuberite + G_EXEC chmod +x /mnt/dietpi_userdata/cuberite/Cuberite fi - software_id=44 # Transmission - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + software_id=53 # MineOS + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then + Banner_Installing # https://minecraft.codeemo.com/mineoswiki/index.php?title=MineOS-node_(apt-get) - Banner_Configuration + local url='https://github.com/hexparrot/mineos-node.git' + G_CHECK_URL "$url" - # Remove obsolete service and environment files - Remove_SysV transmission-daemon 1 - [[ -f '/etc/init/transmission-daemon.conf' ]] && rm -v /etc/init/transmission-daemon.conf + # APT deps + G_AGI python rdiff-backup rsync screen - # 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 + # Download/Update MineOS + G_EXEC mkdir -p /mnt/dietpi_userdata/mineos + G_EXEC cd /mnt/dietpi_userdata/mineos + if [[ -d 'minecraft' ]] + then + # https://minecraft.codeemo.com/mineoswiki/index.php?title=Updating_the_Webui + G_EXEC cd minecraft + if [[ -x 'update_webui.sh' ]] + then + G_EXEC_OUTPUT=1 G_EXEC ./update_webui.sh + else + G_EXEC_OUTPUT=1 G_EXEC git fetch + G_EXEC_OUTPUT=1 G_EXEC git merge origin/master + fi + else + G_EXEC_OUTPUT=1 G_EXEC git clone "$url" minecraft + G_EXEC cd minecraft + fi - # Apply optimised settings - G_CONFIG_INJECT '"cache-size-mb"' ' "cache-size-mb": '"$(Optimise_BitTorrent 0)"',' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"download-queue-size"' ' "download-queue-size": '"$(Optimise_BitTorrent 1)"',' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"peer-limit-global"' ' "peer-limit-global": '"$(Optimise_BitTorrent 2)"',' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"upload-slots-per-torrent"' ' "upload-slots-per-torrent": '"$(Optimise_BitTorrent 3)"',' /etc/transmission-daemon/settings.json '^\{$' + # File modes + G_EXEC git config core.filemode false + G_EXEC chmod +x mineos_console.js webui.js update_webui.sh reset_webui.sh generate-sslcert.sh - G_CONFIG_INJECT '"port-forwarding-enabled"' ' "port-forwarding-enabled": true,' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"encryption"' ' "encryption": 2,' /etc/transmission-daemon/settings.json '^\{$' + # Install Node 11, as MineOS is currently not compatible with newer Node versions: https://github.com/hexparrot/mineos-node/issues/374 + G_EXEC_OUTPUT=1 G_EXEC npm i -g --unsafe-perm --no-audit n + G_EXEC_OUTPUT=1 G_EXEC n 11 - G_CONFIG_INJECT '"idle-seeding-limit"' ' "idle-seeding-limit": 1,' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"idle-seeding-limit-enabled"' ' "idle-seeding-limit-enabled": true,' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"ratio-limit"' ' "ratio-limit": 1.1,' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"ratio-limit-enabled"' ' "ratio-limit-enabled": true,' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"trash-original-torrent-files"' ' "trash-original-torrent-files": true,' /etc/transmission-daemon/settings.json '^\{$' + # Install MineOS + G_EXEC_OUTPUT=1 G_EXEC npm i --unsafe-perm --no-audit + G_EXEC cd /tmp/$G_PROGRAM_NAME - G_CONFIG_INJECT '"download-dir"' ' "download-dir": "/mnt/dietpi_userdata/downloads",' /etc/transmission-daemon/settings.json '^\{$' - # - Double quotes need to be escaped in .json files: https://github.com/MichaIng/DietPi/issues/2484#issuecomment-481374924 - # - ToDo: Hash password directly. Which hash method is used? - GCI_PASSWORD=1 G_CONFIG_INJECT '"rpc-password"' ' "rpc-password": "'"${GLOBAL_PW//\"/\\\"}"'",' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"rpc-username"' ' "rpc-username": "root",' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"rpc-whitelist-enabled"' ' "rpc-whitelist-enabled": false,' /etc/transmission-daemon/settings.json '^\{$' - G_CONFIG_INJECT '"message-level"' ' "message-level": 0,' /etc/transmission-daemon/settings.json '^\{$' + # Config: Preserve existing + [[ -f '/etc/mineos.conf' ]] || G_EXEC cp /mnt/dietpi_userdata/mineos/minecraft/mineos.conf /etc/mineos.conf - # To allow access for download managers and media software, files need to be created with 77X/66X permissions. - G_CONFIG_INJECT '"umask"' ' "umask": 7,' /etc/transmission-daemon/settings.json '^\{$' + # Create symlinks for console and userdata dir + G_EXEC ln -sf /mnt/dietpi_userdata/mineos/minecraft/mineos_console.js /usr/local/bin/mineos + G_EXEC rm -Rf /var/games/minecraft + G_EXEC mkdir -p /var/games /mnt/dietpi_userdata/mineos/serverdata + G_EXEC ln -s /mnt/dietpi_userdata/mineos/serverdata /var/games/minecraft + + # Setup SSL cert + G_EXEC cd /mnt/dietpi_userdata/mineos/minecraft + G_EXEC_OUTPUT=1 G_EXEC ./generate-sslcert.sh + G_EXEC cd /tmp/$G_PROGRAM_NAME + + # Service + cat << _EOF_ > /etc/systemd/system/mineos.service +[Unit] +Description=MineOS (DietPi) +Wants=network-online.target +After=network-online.target +[Service] +WorkingDirectory=/mnt/dietpi_userdata/mineos/minecraft +Environment="SHELL=/bin/bash" "HOME=/root" +SyslogIdentifier=MineOS +ExecStart=$(command -v node) webui.js +KillMode=process + +[Install] +WantedBy=multi-user.target +_EOF_ fi - software_id=54 # phpBB + software_id=49 # Gogs if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - - # Preserve old database name - [[ -d '/mnt/dietpi_userdata/mysql/phpbb3' ]] || /boot/dietpi/func/create_mysql_db phpbb phpbb "$GLOBAL_PW" + Banner_Installing - # Permissions: The web-based installer writes setup and database access information to this file. Upload, cache and store directories are shipped with 777 modes already. - G_EXEC chown www-data /var/www/phpbb/config.php + # ARMv6: No pre-compiled binaries available, thus we use our own: https://github.com/gogs/gogs/releases + local url='https://dietpi.com/downloads/binaries/all/gogs_armv6.zip' - fi + # Else install latest binaries from GitHub + if (( $G_HW_MODEL != 1 )) + then + # ARMv7 + local arch='armv7' - software_id=94 # ProFTPD - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # ARMv8 + if (( $G_HW_ARCH == 3 )) + then + arch='armv8' - Banner_Configuration + # x86_64 + elif (( $G_HW_ARCH == 10 )) + then + arch='amd64' + fi - # Config - G_BACKUP_FP /etc/proftpd/proftpd.conf - dps_index=$software_id Download_Install 'conf' /etc/proftpd/proftpd.conf + local fallback_url="https://github.com/gogs/gogs/releases/download/v0.12.3/gogs_0.12.3_linux_$arch.tar.gz" + url=$(curl -sSfL 'https://api.github.com/repos/gogs/gogs/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/gogs_[^\"\/]*_linux_$arch.tar.gz\"/{print \$4}") + fi - # Do not allow root access via FTP - G_EXEC sed -i 's/^[[:blank:]]*root/#root/' /etc/ftpusers + Download_Install "$url" - # Bullseye: Fix ident lookup: https://github.com/MichaIng/DietPi/issues/4666 - (( $G_DISTRO < 6 )) || G_EXEC sed -i '/IdentLookups/c\\nIdentLookups off\n' /etc/proftpd/proftpd.conf + # Remove old install dir, but preserve existing configs + if [[ -d '/etc/gogs' ]]; then - fi + [[ -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 - software_id=96 # Samba Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + fi - Banner_Configuration + G_EXEC mv gogs /etc/gogs - echo -e "$GLOBAL_PW\n$GLOBAL_PW" | smbpasswd -s -a dietpi + # User + Create_User -d /etc/gogs gogs - local fp_conf='/etc/samba/smb.conf' - G_BACKUP_FP $fp_conf - dps_index=$software_id Download_Install 'conf' $fp_conf + # Directories + permissions + G_EXEC mkdir -p /mnt/dietpi_userdata/gogs-repo /var/log/gogs + G_EXEC chown -R gogs:gogs /etc/gogs /mnt/dietpi_userdata/gogs-repo /var/log/gogs - G_CONFIG_INJECT 'max connections =' "max connections = $(( $G_HW_CPU_CORES * 2 ))" $fp_conf + # Database + if [[ ! -d '/var/lib/mysql/gogs' ]]; then - fi + 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'" - software_id=95 # vsftpd - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + fi - Banner_Configuration + # Service: https://github.com/gogs/gogs/blob/main/scripts/systemd/gogs.service + cat << '_EOF_' > /etc/systemd/system/gogs.service +[Unit] +Description=Gogs (DietPi) +Wants=network-online.target +After=network-online.target mariadb.service - # Config - G_BACKUP_FP /etc/vsftpd.conf - dps_index=$software_id Download_Install 'conf' /etc/vsftpd.conf +[Service] +User=gogs +WorkingDirectory=/etc/gogs +ExecStart=/etc/gogs/gogs web - # Do not allow root access via FTP - sed -i 's/^[[:blank:]]*root/#root/' /etc/ftpusers +# Hardening +ProtectSystem=full +PrivateDevices=yes +PrivateTmp=yes +NoNewPrivileges=true +ReadWritePaths=-/etc/gogs +[Install] +WantedBy=multi-user.target +_EOF_ fi - software_id=109 # NFS Server + software_id=46 # qBittorrent if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - G_EXEC mkdir -p /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 + Banner_Installing + G_AGI qbittorrent-nox - fi + # User + Create_User -g dietpi -d /home/qbittorrent qbittorrent - software_id=32 # ympd - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Config: Create only on fresh install + if [[ ! -f '/home/qbittorrent/.config/qBittorrent/qBittorrent.conf' ]]; then - Banner_Configuration + G_EXEC mkdir -p /home/qbittorrent/.config/qBittorrent /var/log/qbittorrent + G_EXEC chown -R qbittorrent:root /var/log/qbittorrent + cat << _EOF_ > /home/qbittorrent/.config/qBittorrent/qBittorrent.conf +[General] +ported_to_new_savepath_system=true - # User - Create_User -g dietpi ympd +[Application] +FileLogger\Enabled=true +FileLogger\Path=/var/log/qbittorrent + +[AutoRun] +enabled=false + +[LegalNotice] +Accepted=true + +[Preferences] +Advanced\AnonymousMode=false +Advanced\IncludeOverhead=false +Bittorrent\DHT=true +Bittorrent\DHTPort=6881 +Bittorrent\Encryption=1 +Bittorrent\LSD=true +Bittorrent\MaxConnecs=$(Optimise_BitTorrent 2) +Bittorrent\MaxConnecsPerTorrent=$(Optimise_BitTorrent 2) +Bittorrent\MaxUploads=$(Optimise_BitTorrent 3) +Bittorrent\MaxUploadsPerTorrent=$(Optimise_BitTorrent 3) +Bittorrent\PeX=true +Bittorrent\sameDHTPortAsBT=true +Bittorrent\uTP=true +Bittorrent\uTP_rate_limited=false +Connection\GlobalDLLimit=-1 +Connection\GlobalDLLimitAlt=10 +Connection\GlobalUPLimit=-1 +Connection\GlobalUPLimitAlt=10 +Connection\PortRangeMin=6881 +Connection\Proxy\Authentication=false +Connection\ProxyPeerConnections=false +Connection\ResolvePeerCountries=false +Connection\UPnP=true +Downloads\DiskWriteCacheSize=$(Optimise_BitTorrent 0) +Downloads\DiskWriteCacheTTL=60 +Downloads\PreAllocation=false +Downloads\SavePath=/mnt/dietpi_userdata/downloads +Downloads\TempPath=/mnt/dietpi_userdata/downloads +Downloads\TempPathEnabled=false +Downloads\UseIncompleteExtension=false +DynDNS\Enabled=false +General\Locale=en +IPFilter\Enabled=false +MailNotification\enabled=false +Queueing\IgnoreSlowTorrents=false +Queueing\MaxActiveDownloads=$(Optimise_BitTorrent 1) +Queueing\MaxActiveTorrents=$(Optimise_BitTorrent 1) +Queueing\MaxActiveUploads=1 +Queueing\QueueingEnabled=false +Scheduler\Enabled=false +WebUI\CSRFProtection=true +WebUI\ClickjackingProtection=true +WebUI\Enabled=true +WebUI\HTTPS\Enabled=false +WebUI\HostHeaderValidation=false +WebUI\LocalHostAuth=true +WebUI\Password_ha1=@ByteArray($(echo -n "$GLOBAL_PW" | md5sum | mawk '{print $1}')) +WebUI\Port=1340 +WebUI\SecureCookie=true +WebUI\UseUPnP=true +WebUI\Username=qbittorrent +_EOF_ + fi + + # Since v4.2.0, the PBKDF2 needs to be used: https://github.com/MichaIng/DietPi/issues/4711 + (( $G_DISTRO < 6 )) || G_EXEC sed -i '/^WebUI\\Password_ha1/c\WebUI\\Password_PBKDF2="@ByteArray(tpgNK76AcpP14rjOZP9vwg==:rQNtOB0P4HfNj20pJtxiTBi9miduS6L1Xqqazc4Y6Gpm3Rn02jMXnPPT3KH2JMDKhFQjAaTGVJz0dz5JVw2QUQ==)"' /home/qbittorrent/.config/qBittorrent/qBittorrent.conf # Service - cat << '_EOF_' > /etc/systemd/system/ympd.service + cat << _EOF_ > /etc/systemd/system/qbittorrent.service [Unit] -Description=ympd (DietPi) -After=mpd.service +Description=qBittorrent (DietPi) +Documentation=man:qbittorrent-nox(1) +Wants=network-online.target +After=network-online.target [Service] -ExecStart=/usr/bin/ympd --user ympd --webport 1337 +User=qbittorrent +UMask=002 +ExecStart=$(command -v qbittorrent-nox) [Install] WantedBy=multi-user.target _EOF_ + # Permissions + G_EXEC chown -R qbittorrent:root /home/qbittorrent + fi - software_id=121 # Roon Bridge + software_id=107 # rTorrent if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # User: !!! root required for remote updates - #Create_User -g dietpi -G audio -d /mnt/dietpi_userdata/roon roon + DEPS_LIST='rtorrent mediainfo' + # On Buster, no "screen" is required to run rTorrent as daemon: https://github.com/rakshasa/rtorrent/wiki/Daemon_Mode + (( $G_DISTRO < 5 )) && DEPS_LIST+=' screen' - dps_index=$software_id Download_Install 'roonbridge.service' /etc/systemd/system/roonbridge.service + # Install ruTorrent: Web UI for rTorrent + # - Grab current version + local version=$(curl -sSfL 'https://api.github.com/repos/Novik/ruTorrent/releases/latest' | mawk -F\" '/"tag_name": /{print $4}') + [[ $version ]] || { version='v3.10'; G_DIETPI-NOTIFY 1 "Automatic latest ruTorrent 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/Novik/ruTorrent/archive/$version.tar.gz" - # Move log files to /var/log (dietpi-ramlog) - G_EXEC mkdir -p /var/log/roon /mnt/dietpi_userdata/roon/{RoonBridge,RAATServer} - # - Clear symlink locations - G_EXEC rm -Rf /mnt/dietpi_userdata/roon/{RoonBridge,RAATServer}/Logs - G_EXEC ln -s /var/log/roon /mnt/dietpi_userdata/roon/RoonBridge/Logs - G_EXEC ln -s /var/log/roon /mnt/dietpi_userdata/roon/RAATServer/Logs + # - Reinstall + if [[ -d '/var/www/rutorrent' ]]; then - # Permissions - #chown -R roon:dietpi /mnt/dietpi_userdata/roon /var/log/roon + # Make new config files examples, if they exist in the old install already + [[ -f '/var/www/rutorrent/conf/config.php' ]] && G_EXEC mv "ruTorrent-${version#v}/conf/config.php"{,.example} + [[ -f '/var/www/rutorrent/conf/access.ini' ]] && G_EXEC mv "ruTorrent-${version#v}/conf/access.ini"{,.example} + [[ -f '/var/www/rutorrent/conf/plugins.ini' ]] && G_EXEC mv "ruTorrent-${version#v}/conf/plugins.ini"{,.example} - fi + # Merge new install into old to preserve e.g. 3rd party plugins + G_EXEC cp -a "ruTorrent-${version#v}/". /var/www/rutorrent/ + G_EXEC rm -R "ruTorrent-${version#v}" + + # - Fresh install + else + + G_EXEC mv "ruTorrent-${version#v}" /var/www/rutorrent + + fi + + # Install DarkBetter theme manually: https://github.com/MichaIng/DietPi/issues/3271 + if [[ -d '/var/www/rutorrent/plugins/theme/themes/DarkBetter' ]]; then + + Download_Install 'https://github.com/chocolatkey/DarkBetter/archive/master.tar.gz' + G_EXEC rm -R /var/www/rutorrent/plugins/theme/themes/DarkBetter + G_EXEC mv DarkBetter-master /var/www/rutorrent/plugins/theme/themes/DarkBetter + + fi + + # ruTorrent: Enable HTTP authentication and RPC + # - Apache2 + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + + # Enable SCGI module + G_EXEC a2enmod auth_basic authn_file authz_user proxy_scgi + + # Enable HTTP authentication and rTorrent access via SCGI + [[ -f '/etc/.rutorrent-htaccess' ]] || htpasswd -cb /etc/.rutorrent-htaccess root "$GLOBAL_PW" + cat << '_EOF_' > /etc/apache2/sites-available/dietpi-rutorrent.conf + + AllowOverride All + AuthType Basic + AuthName "ruTorrent login" + AuthBasicProvider file + AuthUserFile "/etc/.rutorrent-htaccess" + Require valid-user + + + AuthType Basic + AuthName "rTorrent login" + AuthBasicProvider file + AuthUserFile "/etc/.rutorrent-htaccess" + Require valid-user + +ProxyPass "/RPC2" "scgi:///mnt/dietpi_userdata/downloads/.session/rpc.socket" +_EOF_ + G_EXEC a2ensite dietpi-rutorrent - software_id=119 # CAVA - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # - Lighttpd + elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then - Banner_Configuration + [[ -f '/etc/.rutorrent-htaccess' ]] || echo "root:rtorrent:$(echo -n "root:rtorrent:$GLOBAL_PW" | md5sum | mawk '{print $1}')" > /etc/.rutorrent-htaccess - # CAVA conf, preserve existing - [[ -f '/root/.config/cava/config' ]] || dps_index=$software_id Download_Install 'cava.conf' /root/.config/cava/config + # Pre-v7.2: Remove obsolete entries from /etc/lighttpd/lighttpd.conf + grep -q '^#RUTORRENT_DIETPI' /etc/lighttpd/lighttpd.conf && G_EXEC sed -i '/#RUTORRENT_DIETPI/,/#RUTORRENT_DIETPI/d' /etc/lighttpd/lighttpd.conf - # Lower MPD buffer size to reduce latency of spectrum - G_EXEC sed -i '/audio_buffer_size /c\audio_buffer_size "384"' /etc/mpd.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 +auth.backend = "htdigest" +auth.backend.htdigest.userfile = "/etc/.rutorrent-htaccess" +auth.require = ( "/rutorrent" => + ( + "method" => "digest", + "realm" => "rtorrent", + "require" => "valid-user" + ), + "/RPC2" => + ( + "method" => "digest", + "realm" => "rtorrent", + "require" => "valid-user" + ) +) +scgi.server = ( "/RPC2" => + ( "rtorrent" => + ( + "socket" => "/mnt/dietpi_userdata/downloads/.session/rpc.socket", + "check-local" => "disable" + ) + ) +) +$HTTP["url"] =~ "^/rutorrent/(conf|share)($|/)" { + url.access-deny = ("") +} +_EOF_ + [[ -f '/etc/lighttpd/conf-enabled/98-dietpi-rtorrent.conf' ]] || G_EXEC lighty-enable-mod dietpi-rtorrent - # FIFO stream for mpd - grep -q '/tmp/mpd.fifo' /etc/mpd.conf || cat << '_EOF_' >> /etc/mpd.conf + # - Nginx + elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then -# CAVA FIFO stream -audio_output { - type "fifo" - enabled "yes" - name "CAVA" - path "/tmp/mpd.fifo" - format "44100:16:2" + # "openssl passwd -5" (sha256, even "-6" sha512) can be used from Buster on. + [[ -f '/etc/.rutorrent-htaccess' ]] || echo "root:$(openssl passwd -apr1 "$GLOBAL_PW")" > /etc/.rutorrent-htaccess + cat << '_EOF_' > /etc/nginx/sites-dietpi/dietpi-rutorrent.conf +location ^~ /rutorrent { + auth_basic "ruTorrent login"; + auth_basic_user_file /etc/.rutorrent-htaccess; + location ~ ^/rutorrent/(?:conf|share)(?:/|$) { return 404; } +} +location ^~ /RPC2 { + auth_basic "rTorrent login"; + auth_basic_user_file /etc/.rutorrent-htaccess; + include scgi_params; + scgi_pass unix:/mnt/dietpi_userdata/downloads/.session/rpc.socket; } _EOF_ - fi + fi - software_id=39 # ReadyMedia - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + G_EXEC chmod 0400 /etc/.rutorrent-htaccess + G_EXEC chown www-data:www-data /etc/.rutorrent-htaccess - Banner_Configuration + # ruTorrent config + # shellcheck disable=SC2016 + G_CONFIG_INJECT '\$scgi_port[[:blank:]]' ' $scgi_port = 0;' /var/www/rutorrent/conf/config.php + # shellcheck disable=SC2016 + G_CONFIG_INJECT '\$scgi_host[[:blank:]]' ' $scgi_host = "unix:///mnt/dietpi_userdata/downloads/.session/rpc.socket";' /var/www/rutorrent/conf/config.php + G_CONFIG_INJECT '"curl"[[:blank:]]' ' "curl" => "/usr/bin/curl",' /var/www/rutorrent/conf/config.php - # User: Make "dietpi" the primary group to enable cross-access to media files - Create_User -g dietpi -G minidlna -d /var/lib/minidlna minidlna + # Session dir + G_EXEC mkdir -p /mnt/dietpi_userdata/downloads/.session - # 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 + Create_User -g dietpi -d /mnt/dietpi_userdata/rtorrent rtorrent # Service - cat << _EOF_ > /etc/systemd/system/minidlna.service + cat << _EOF_ > /etc/systemd/system/rtorrent.service [Unit] -Description=ReadyMedia (DietPi) +Description=rTorrent (DietPi) Wants=network-online.target After=network-online.target [Service] -User=minidlna -ExecStart=$(command -v minidlnad) -S -R -f /etc/minidlna.conf -P /dev/null +Type=forking +User=rtorrent +ExecStart=$(command -v screen) -fa -dmS rtorrent $(command -v rtorrent) +ExecStop=$(command -v screen) -S rtorrent -X quit +KillMode=none [Install] WantedBy=multi-user.target _EOF_ - # Bullseye: Debian patched forced file logging inside, overriding "-S": https://github.com/MichaIng/DietPi/issues/4745 - (( $G_DISTRO < 6 )) || G_CONFIG_INJECT 'LogsDirectory=' 'LogsDirectory=minidlna' /etc/systemd/system/minidlna.service '^User=' - - # Config - G_BACKUP_FP /etc/minidlna.conf - dps_index=$software_id Download_Install 'minidlna.conf' /etc/minidlna.conf - - # Cache - G_EXEC mkdir -p /mnt/dietpi_userdata/.MiniDLNA_Cache - G_EXEC chown -R minidlna:root /mnt/dietpi_userdata/.MiniDLNA_Cache - - Download_Test_Media - - fi - - software_id=112 # DXX-Rebirth - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Symlink savegames to root - # - Remove existing symlinks - G_EXEC rm -Rf /root/.d{1,2}x-rebirth - - G_EXEC ln -sf /mnt/dietpi_userdata/dxx-rebirth/descent_1_profiles /root/.d1x-rebirth - G_EXEC ln -sf /mnt/dietpi_userdata/dxx-rebirth/descent_2_profiles /root/.d2x-rebirth - - # +exe - G_EXEC chmod -R +x /mnt/dietpi_userdata/dxx-rebirth/* - - # Desktop menu entry - G_EXEC mkdir -p /usr/share/applications - G_EXEC ln -sf /mnt/dietpi_userdata/dxx-rebirth/dxx-rebirth.desktop /usr/share/applications/dxx-rebirth.desktop + # Since Buster we use new daemon mode + if (( $G_DISTRO > 4 )); then - # Desktop shortcut - Create_Desktop_Shortcut dxx-rebirth + G_EXEC sed -Ei '/^(Type|KillMode|ExecStop)=/d' /etc/systemd/system/rtorrent.service + G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v rtorrent)" /etc/systemd/system/rtorrent.service - fi + fi - software_id=51 # OpenTyrian - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # rTorrent config: Do not overwrite if existent + # - Example: https://github.com/rakshasa/rtorrent/blob/master/doc/rtorrent.rc + # - 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 + 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 + else + cat << _EOF_ > /mnt/dietpi_userdata/rtorrent/.rtorrent.rc +### Miscellaneous settings +#system.daemon.set = true +# Default download dir +directory.default.set = /mnt/dietpi_userdata/downloads +# Session dir +session.path.set = /mnt/dietpi_userdata/downloads/.session +# Save session every 5 minutes +schedule2 = session_save, 240, 300, ((session.save)) +# Close torrents on low diskspace, check every minute +schedule2 = monitor_diskspace, 15, 60, ((close_low_diskspace, 1000M)) +system.umask.set = 002 +# Max memory mapping size, not max physical RAM usage! +pieces.memory.max.set = ${RAM_PHYS}M +pieces.hash.on_completion.set = no - Banner_Configuration +### Connection settings +# Incoming connection ports +network.port_open.set = no +network.port_random.set = no +#network.port_range.set = 33101-33199 +# 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 - # Desktop menu entry - G_THREAD_START curl -sSfL "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.conf/desktop/apps/opentyrian.desktop" -o /usr/share/applications/opentyrian.desktop +### Network limits +network.http.max_open.set = $(Optimise_BitTorrent 2) +network.max_open_files.set = $(( $(Optimise_BitTorrent 2) * 2 )) +network.max_open_sockets.set = $(Optimise_BitTorrent 2) +# Global max download/upload rate in KiB, "0" for unlimited +throttle.global_down.max_rate.set_kb = 0 +throttle.global_up.max_rate.set_kb = 0 - # Copy the DietPi run file for OpenTyrian - dps_index=$software_id Download_Install 'run' /usr/games/opentyrian/run - G_EXEC chmod +x /usr/games/opentyrian/run +### Peer settings +# Max downloads/uploads accross all torrents +throttle.max_downloads.global.set = $(Optimise_BitTorrent 2) +throttle.max_uploads.global.set = $(Optimise_BitTorrent 2) +# Max downloads/uploads per torrent +throttle.max_downloads.set = $(( $(Optimise_BitTorrent 2) / 2 )) +throttle.max_uploads.set = $(( $(Optimise_BitTorrent 2) / 2 )) +# Min/Max connected peers +throttle.min_peers.normal.set = $(( $(Optimise_BitTorrent 2) - 1)) +throttle.max_peers.normal.set = $(Optimise_BitTorrent 2) +throttle.min_peers.seed.set = -1 +throttle.max_peers.seed.set = -1 +trackers.numwant.set = $(Optimise_BitTorrent 2) +# Public tracker support +trackers.use_udp.set = yes +dht.mode.set = on +#dht.port.set = 6881 +protocol.pex.set = yes +protocol.encryption.set = allow_incoming,try_outgoing,enable_retry +_EOF_ + fi - # Desktop shortcut - Create_Desktop_Shortcut opentyrian + # Since Buster use new daemon mode + (( $G_DISTRO > 4 )) && G_CONFIG_INJECT 'system.daemon.set[[:blank:]=]' 'system.daemon.set = true' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc - G_THREAD_WAIT + # Permissions + G_EXEC chown -R rtorrent:dietpi /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 root:root /var/www/rutorrent/share/.htaccess fi - software_id=59 # RPi Cam Control + software_id=132 # Aria2 if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # raspimjpeg conf - G_EXEC ln -sf /etc/raspimjpeg /var/www/rpicam/raspimjpeg + G_AGI aria2 - # Motion conf - G_EXEC chown motion:www-data /etc/motion/motion.conf - G_EXEC chmod 664 /etc/motion/motion.conf - G_EXEC usermod -aG video www-data + # Web UI: Settings are stored client-wise, web UI files are never written by webserver. Thus root:root 022 permissions existing dir removal on reinstall can be done. + Download_Install 'https://github.com/ziahamza/webui-aria2/archive/master.tar.gz' + [[ -d '/var/www/aria2' ]] && G_EXEC rm -R /var/www/aria2 + G_EXEC mv webui-aria2-master /var/www/aria2 - # raspimjpeg/php schedule startup and control script - dps_index=$software_id Download_Install 'raspimjpeg.sh' /var/lib/dietpi/dietpi-software/installed/raspimjpeg.sh - G_EXEC chmod +x /var/lib/dietpi/dietpi-software/installed/raspimjpeg.sh - cat << '_EOF_' > /etc/systemd/system/raspimjpeg.service -[Unit] -Description=Raspimjpeg (DietPi) + # User + Create_User -g dietpi -d /mnt/dietpi_userdata/aria2 aria2 -[Service] -RemainAfterExit=yes -ExecStart=/var/lib/dietpi/dietpi-software/installed/raspimjpeg.sh start -ExecStop=/var/lib/dietpi/dietpi-software/installed/raspimjpeg.sh stop + # Config + G_EXEC mkdir -p /mnt/dietpi_userdata/aria2 + [[ -f '/mnt/dietpi_userdata/aria2/aria2.conf' ]] || cat << _EOF_ > /mnt/dietpi_userdata/aria2/aria2.conf +# DietPi default aria2c options served as aria2.conf file via --conf-path +# https://aria2.github.io/manual/en/html/aria2c.html#options -[Install] -WantedBy=multi-user.target -_EOF_ - # Replace configs with /var/www to /var/www/rpicam, once - if ! grep -q '/rpicam' /etc/raspimjpeg; then +# Logging +log=/var/log/aria2.log +log-level=warn - G_EXEC sed -i 's#/var/www#/var/www/rpicam#g' /etc/raspimjpeg - G_EXEC sed -i 's#/var/www#/var/www/rpicam#g' /etc/motion/motion.conf +# Session +always-resume=true +continue=true +input-file=/mnt/dietpi_userdata/downloads/aria2.session +save-session=/mnt/dietpi_userdata/downloads/aria2.session +save-session-interval=60 - fi +# Connection +listen-port=6881-6999 +ftp-pasv=true +check-certificate=false +# - Count +max-concurrent-downloads=$(Optimise_BitTorrent 1) +split=$(Optimise_BitTorrent 1) +max-connection-per-server=$(Optimise_BitTorrent 1) +bt-max-peers=$(Optimise_BitTorrent 2) +# - Bandwidth +max-overall-upload-limit=0 +max-upload-limit=0 +max-overall-download-limit=0 +max-download-limit=0 +# - Retries +max-file-not-found=3 +max-tries=5 +retry-wait=60 - # Setup data directory - G_EXEC mkdir -p /mnt/dietpi_userdata/rpicam - G_EXEC rm -Rf /var/www/rpicam/media - G_EXEC ln -s /mnt/dietpi_userdata/rpicam /var/www/rpicam/media +# RPC +enable-rpc=true +rpc-listen-all=true +rpc-listen-port=6800 +rpc-secret=$GLOBAL_PW +rpc-allow-origin-all=true +pause=false - # Enable RPi camera - /boot/dietpi/func/dietpi-set_hardware rpi-camera enable +# Store +dir=/mnt/dietpi_userdata/downloads +allow-overwrite=false +auto-file-renaming=false +file-allocation=none +check-integrity=true - # Permissions - G_EXEC chown -R www-data:www-data /var/www/rpicam /mnt/dietpi_userdata/rpicam +# Seeding +seed-ratio=0.1 +seed-time=0 +_EOF_ - fi + # Pre-create log file + local fp_log=$(sed -n '/^[[:blank:]]*log=/{s/^[^=]*=//p;q}' /mnt/dietpi_userdata/aria2/aria2.conf) + [[ ${fp_log//\"} && ! -f $fp_log ]] && >> "$fp_log" - software_id=115 # Webmin - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Pre-create input file + local fp_input=$(sed -n '/^[[:blank:]]*input-file=/{s/^[^=]*=//p;q}' /mnt/dietpi_userdata/aria2/aria2.conf) + [[ ${fp_input//\"} && ! -f $fp_input ]] && >> "$fp_input" - Banner_Configuration + # Permissions + G_EXEC chown -R aria2:root /mnt/dietpi_userdata/aria2 "$fp_input" + G_EXEC chown aria2:dietpi "$fp_log" + G_EXEC chmod 600 /mnt/dietpi_userdata/aria2/aria2.conf + unset -v fp_log fp_input # Service - Remove_SysV webmin - cat << '_EOF_' > /etc/systemd/system/webmin.service + cat << _EOF_ > /etc/systemd/system/aria2.service [Unit] -Description=Webmin (DietPi) -Documentation=https://doxfer.webmin.com/Webmin/Main_Page +Description=Aria2 (DietPi) [Service] -Type=forking -GuessMainPID=no -SyslogIdentifier=Webmin -ExecStart=/etc/webmin/start -ExecStop=/etc/webmin/stop -ExecReload=/etc/webmin/reload +User=aria2 +UMask=002 +ExecStart=$(command -v aria2c) --conf-path=/mnt/dietpi_userdata/aria2/aria2.conf [Install] WantedBy=multi-user.target _EOF_ fi - software_id=93 # Pi-hole + software_id=116 # Medusa if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # Apply most resource friendly and officially recommended NULL blocking: https://docs.pi-hole.net/ftldns/blockingmode/ - G_CONFIG_INJECT 'BLOCKINGMODE=' 'BLOCKINGMODE=NULL' /etc/pihole/pihole-FTL.conf + DEPS_LIST='mediainfo python3' - # Disable pihole.log query logging: https://github.com/pi-hole/FTL/issues/614#issuecomment-510564476 - G_EXEC pihole -l off + if [[ -d '/mnt/dietpi_userdata/medusa' ]]; then - # Unbound: Configure Pi-hole to use it - if (( ${aSOFTWARE_INSTALL_STATE[182]} > 0 )) - then - G_DIETPI-NOTIFY 2 'Configuring Pi-hole to use Unbound' - G_EXEC sed -i '/^[[:blank:]]*server=/d' /etc/dnsmasq.d/01-pihole.conf - G_CONFIG_INJECT 'server=' 'server=127.0.0.1#5335' /etc/dnsmasq.d/01-pihole.conf - systemctl -q is-active pihole-FTL && G_EXEC systemctl restart pihole-FTL - G_CONFIG_INJECT 'PIHOLE_DNS_1=' 'PIHOLE_DNS_1=127.0.0.1#5335' /etc/pihole/setupVars.conf - G_EXEC sed -i '/^[[:blank:]]*PIHOLE_DNS_2=/d' /etc/pihole/setupVars.conf - fi + # shellcheck disable=SC2086 + G_AGI $DEPS_LIST + DEPS_LIST= + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/mnt/dietpi_userdata/medusa\" already exists. Download and install steps will be skipped. + - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from WebUI. + - If you need to reinstall (e.g. broken instance), please manually backup your config files+data, remove the install dir and rerun \"dietpi-software (re)install $software_id\"." - # Enable required PHP modules: https://github.com/pi-hole/pi-hole/blob/development/automated%20install/basic-install.sh#L250 - G_EXEC phpenmod xml sqlite3 intl + else - # Webserver configs - # - Lighttpd - if (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + Download_Install 'https://github.com/pymedusa/Medusa/archive/master.tar.gz' /mnt/dietpi_userdata + G_EXEC mv /mnt/dietpi_userdata/{Medusa-master,medusa} - # Enable required modules - G_CONFIG_INJECT '"mod_setenv",' ' "mod_setenv",' /etc/lighttpd/lighttpd.conf '"mod_.+",' + fi - # Add and enable Pi-hole config - dps_index=$software_id Download_Install 'lighttpd.pihole.conf' /etc/lighttpd/conf-available/99-dietpi-pihole.conf - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod dietpi-pihole + # User + Create_User -g dietpi -d /mnt/dietpi_userdata/medusa medusa - # Optional config to block public access to admin panel - dps_index=$software_id Download_Install 'lighttpd.block_public_admin.conf' /etc/lighttpd/conf-available/99-dietpi-pihole-block_public_admin.conf - local enable_cmd='lighty-enable-mod dietpi-pihole-block_public_admin' - local disable_cmd='lighty-disable-mod dietpi-pihole-block_public_admin' + # Service: https://github.com/pymedusa/Medusa/blob/master/runscripts/init.systemd + G_EXEC cp /mnt/dietpi_userdata/medusa/runscripts/init.systemd /etc/systemd/system/medusa.service + # - Prevent unlimited restarts on failure: Permit up to three restarts in 10 minutes + G_CONFIG_INJECT 'StartLimitIntervalSec=' 'StartLimitIntervalSec=600' /etc/systemd/system/medusa.service '\[Unit\]' + G_CONFIG_INJECT 'StartLimitBurst=' 'StartLimitBurst=3' /etc/systemd/system/medusa.service 'StartLimitIntervalSec=' + # - Remove "Group=medusa" which does not exist, instead fallback to primary group "dietpi" + G_EXEC sed -i '/^[[:blank:]]*Group=/d' /etc/systemd/system/medusa.service + # - Launch from our install and data directory + G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v python3) /mnt/dietpi_userdata/medusa/start.py -q --nolaunch --datadir=/mnt/dietpi_userdata/medusa" /etc/systemd/system/medusa.service - # - Apache - elif (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + # Permissions + G_EXEC chown -R medusa:dietpi /mnt/dietpi_userdata/medusa - # Enable required modules - G_EXEC a2enmod headers + fi - # Add and enable Pi-hole config - dps_index=$software_id Download_Install 'apache.pihole.conf' /etc/apache2/sites-available/dietpi-pihole.conf - G_EXEC a2ensite dietpi-pihole + software_id=50 # Syncthing + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # Optional config to block public access to admin panel - dps_index=$software_id Download_Install 'apache.block_public_admin.conf' /etc/apache2/sites-available/dietpi-pihole-block_public_admin.conf - local enable_cmd='a2ensite dietpi-pihole-block_public_admin' - local disable_cmd='a2dissite dietpi-pihole-block_public_admin' + Banner_Installing - # - Nginx - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + if [[ -d '/opt/syncthing' ]]; then - # Add Pi-hole config - dps_index=$software_id Download_Install 'nginx.pihole.conf' /etc/nginx/sites-dietpi/dietpi-pihole.conf + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/syncthing\" already exists. Download and install steps will be skipped. + - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. + - if you need to reinstall (e.g. broken instance), please manually backup your config files+data, remove the install dir \"/opt/syncthing\" and rerun \"dietpi-software (re)install $software_id\"." - # Optional config to block public access to admin panel - dps_index=$software_id Download_Install 'nginx.block_public_admin.conf' /etc/nginx/sites-dietpi/dietpi-pihole-block_public_admin.off - local enable_cmd='mv /etc/nginx/sites-dietpi/dietpi-pihole-block_public_admin.{off,on}' - local disable_cmd='mv /etc/nginx/sites-dietpi/dietpi-pihole-block_public_admin.{on,off}' + else - fi + # ARMv6/7 + local arch='arm' - # Ask user if they want to block public access to the admin panel - G_WHIP_BUTTON_OK_TEXT='YES' - G_WHIP_BUTTON_CANCEL_TEXT='NO' - G_WHIP_YESNO "In order to increase security, it is recommended to block public access to the Pi-hole admin panel, so that only connections from within your LAN or via VPN are possible. -\nPractically this means to deny access from all IPs that do not match the reserved loopback and LAN ranges: - - 127.* - - 192.168.* - - 10.* - - 172.16.* - 172.31.* - - ::1 - - fe80:* - febf:* - - fc00:* - fdff:* -\nYou can always enable/disable this later using the commands: - - $enable_cmd - - $disable_cmd -\nDo you want to block public access to the admin panel now?" && eval "$enable_cmd" + # ARMv8 + if (( $G_HW_ARCH == 3 )); then - # Create symlinks to align Pi-hole admin and 404 page relative to webroot - [[ -e '/var/www/admin' && ! -L '/var/www/admin' ]] && G_EXEC mv /var/www/admin{,.bak} - G_EXEC ln -sf /var/www/{html/admin,admin} - [[ -e '/var/www/pihole' && ! -L '/var/www/pihole' ]] && G_EXEC mv /var/www/pihole{,.bak} - G_EXEC ln -sf /var/www/{html/pihole,pihole} + arch+='64' - # Pi-hole v5: Add webserver user to pihole group to allow gravity.db access from web UI: https://github.com/MichaIng/DietPi/issues/3391 - G_EXEC usermod -aG pihole www-data + # x86_64 + elif (( $G_HW_ARCH == 10 )); then - # Set web interface PW: https://github.com/MichaIng/DietPi/issues/662 - pihole -a -p "$GLOBAL_PW" + arch='amd64' - # Reduce long-term database TTL: https://github.com/MichaIng/DietPi-Docs/issues/476 - G_DIETPI-NOTIFY 2 'The DNS query database logging duration is reduced to 2 days. If you require long-term query logs, read our docs about how to change the log duration: -- https://dietpi.com/docs/software/dns_servers/#pi-hole' - G_CONFIG_INJECT 'MAXDBDAYS=' 'MAXDBDAYS=2' /etc/pihole/pihole-FTL.conf + fi - fi + local fallback_url="https://github.com/syncthing/syncthing/releases/download/v1.18.1/syncthing-linux-$arch-v1.18.1.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 - software_id=126 # AdGuard Home - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + fi - Banner_Configuration + # Permissions + G_EXEC chown -R dietpi:dietpi /opt/syncthing # to permit self-updates - # User - Create_User -d /mnt/dietpi_userdata/adguardhome adguardhome + # Pre-create and edit default config only on fresh installs + if [[ ! -f '/mnt/dietpi_userdata/syncthing/config.xml' ]]; then - # Config - if [[ ! -f '/mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml' ]] - then - dps_index=$software_id Download_Install 'AdGuardHome.yaml' /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml - # shellcheck disable=SC2016 - G_CONFIG_INJECT 'password:[[:blank:]]' " password: $(htpasswd -bnBC 10 '' "$GLOBAL_PW" | tr -d ':\n' | sed 's/\$2y/\$2a/')" /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml - fi + # Failsafe: Assure that "dietpi" has permission to create the /mnt/dietpi_userdata/syncthing directory + G_EXEC chown dietpi /mnt/dietpi_userdata - # Unbound: Configure AdGuard Home to use it - if [[ ${aSOFTWARE_INSTALL_STATE[182]} -gt 0 && ! -f '/mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf' ]] - then - G_DIETPI-NOTIFY 2 'Configuring AdGuard Home to use Unbound' - echo '127.0.0.1:5335' > /mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf - G_CONFIG_INJECT 'upstream_dns_file:[[:blank:]]' ' upstream_dns_file: /mnt/dietpi_userdata/adguardhome/dietpi-unbound.conf' /mnt/dietpi_userdata/adguardhome/AdGuardHome.yaml - systemctl -q is-active adguardhome && G_EXEC systemctl restart adguardhome - fi + # Run Syncthing to pre-create config dir and exit + G_EXEC_OUTPUT=1 G_EXEC sudo -u dietpi /opt/syncthing/syncthing -generate=/mnt/dietpi_userdata/syncthing + + # Allow remote access: https://docs.syncthing.net/users/faq.html#how-do-i-access-the-web-gui-from-another-computer + G_EXEC sed -i '\|:8384|c\
0.0.0.0:8384
' /mnt/dietpi_userdata/syncthing/config.xml + + # Set default data directory + G_EXEC mkdir -p /mnt/dietpi_userdata/syncthing_data + G_EXEC chown -R dietpi:dietpi /mnt/dietpi_userdata/syncthing_data + sed -i '\| /etc/systemd/system/adguardhome.service + # Service: https://github.com/syncthing/syncthing/blob/master/etc/linux-systemd/system/syncthing%40.service + cat << '_EOF_' > /etc/systemd/system/syncthing.service [Unit] -Description=AdGuard Home (DietPi) +Description=Syncthing (DietPi) Wants=network-online.target After=network-online.target - -# Restart attempt only 5 times StartLimitIntervalSec=60 -StartLimitBurst=5 +StartLimitBurst=4 [Service] -User=adguardhome -AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW -ExecStart=/mnt/dietpi_userdata/adguardhome/AdGuardHome -ExecReload=/mnt/dietpi_userdata/adguardhome/AdGuardHome -s reload +User=dietpi +ExecStart=/opt/syncthing/syncthing -no-browser -no-restart -logflags=0 -home=/mnt/dietpi_userdata/syncthing Restart=on-failure -RestartSec=5 +RestartSec=1 +SuccessExitStatus=3 4 +RestartForceExitStatus=3 4 + +# Hardening +ProtectSystem=full +PrivateTmp=true +SystemCallArchitectures=native +MemoryDenyWriteExecute=true +NoNewPrivileges=true [Install] WantedBy=multi-user.target _EOF_ - # AdGuard Home service needs to be started by systemd, as dietpi-services must not control it to prevent it from killing the systems own DNS server. - G_EXEC systemctl enable adguardhome - aSTART_SERVICES+=('adguardhome') + # Increase fs watcher limit: https://docs.syncthing.net/users/faq.html#how-do-i-increase-the-inotify-limit-to-get-my-filesystem-watcher-to-work + G_EXEC eval "echo 'fs.inotify.max_user_watches=204800' > /etc/sysctl.d/dietpi-syncthing.conf" fi - software_id=33 # Airsonic + software_id=113 # Chromium if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # User - Create_User -g dietpi -G audio -d /mnt/dietpi_userdata/airsonic airsonic + # Apply preference index + INDEX_BROWSER_TARGET=-2 INDEX_BROWSER_CURRENT=-2 - # Optimise memory limit - local memory_limit=$(( $RAM_PHYS / 5 )) - (( $memory_limit < 200 )) && memory_limit=200 + if (( $G_HW_MODEL > 9 )) + then + G_AGI chromium - # Service - cat << _EOF_ > /etc/systemd/system/airsonic.service -[Unit] -Description=Airsonic Media Server (DietPi) -Wants=network-online.target -After=network-online.target remote-fs.target + # RPi: Use RPi repo package + 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[@]}" + fi -[Service] -SyslogIdentifier=Airsonic -User=airsonic -WorkingDirectory=/mnt/dietpi_userdata/airsonic -ExecStart=$(command -v java) -Xmx${memory_limit}m -Dairsonic.home=/mnt/dietpi_userdata/airsonic -Dserver.context-path=/airsonic -Dserver.port=8080 -jar /mnt/dietpi_userdata/airsonic/airsonic.war + # Allow root, start maximized and disable sandbox under root (blank screen without) + local export_options="export CHROMIUM_FLAGS=\"\$CHROMIUM_FLAGS \ +--test-type \ +--no-sandbox \ +--temp-profile \ +--user-data-dir \ +--disable-smooth-scrolling \ +--disable-low-res-tiling \ +--enable-low-end-device-mode \ +--num-raster-threads=$G_HW_CPU_CORES \ +--profiler-timing=0 \ +--disable-composited-antialiasing" -[Install] -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 + # RPi: Leave OpenGL choice to user, as it also depends on RPi model + if (( $G_HW_MODEL < 10 )) + then + : - # Permissions - G_EXEC chmod +x /mnt/dietpi_userdata/airsonic/airsonic.war - G_EXEC chown airsonic:root /mnt/dietpi_userdata/airsonic + # x86_64: OpenGL + elif [[ $G_HW_ARCH == 1 ]] + then + : - # Grab our test media for user - Download_Test_Media + # GLES + else + export_options+=' --use-gl=egl' + fi - fi + export_options+='"' - software_id=98 # HAProxy - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + G_EXEC mkdir -p /etc/chromium.d + echo "$export_options" > /etc/chromium.d/custom_flags - Banner_Configuration + # Chromium 60+ + G_EXEC cp /etc/chromium.d/custom_flags /root/.chromium-browser.init - # Jail directory - G_EXEC mkdir -p /var/lib/haproxy + # Desktop shortcut: chromium-browser.desktop on RPi + if (( $G_HW_MODEL > 9 )) + then + Create_Desktop_Shortcut chromium + else + Create_Desktop_Shortcut chromium-browser + fi - # Config - [[ -f '/etc/haproxy/haproxy.cfg' ]] || cat << '_EOF_' > /etc/haproxy/haproxy.cfg -global + # 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 - maxconn 64 - # Jail directory - chroot /var/lib/haproxy - stats socket /run/haproxy.sock mode 660 level admin - stats timeout 30s - user root - group root - daemon +# 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" - # Default SSL material locations - ca-base /etc/ssl/certs - crt-base /etc/ssl/private +# Resolution to use for kiosk mode, should ideally match current system resolution +RES_X=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_RES_X=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) +RES_Y=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_RES_Y=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - # Default ciphers to use on SSL-enabled listening sockets. - # For more information, see ciphers(1SSL). - ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL +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' -defaults +# Add URL for first run: +URL=$(sed -n '/^[[:blank:]]*SOFTWARE_CHROMIUM_AUTOSTART_URL=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) +CHROMIUM_OPTS+=" --homepage $URL" - log global - mode http - option httplog - option dontlognull - timeout connect 5000 - timeout client 50000 - timeout server 50000 - errorfile 400 /etc/haproxy/errors/400.http - errorfile 403 /etc/haproxy/errors/403.http - errorfile 408 /etc/haproxy/errors/408.http - errorfile 500 /etc/haproxy/errors/500.http - errorfile 502 /etc/haproxy/errors/502.http - errorfile 503 /etc/haproxy/errors/503.http - errorfile 504 /etc/haproxy/errors/504.http +# Find absolute filepath location of Chromium binary. +FP_CHROMIUM=$(command -v chromium) +if [[ ! $FP_CHROMIUM ]]; then -frontend localnodes + # Assume RPi + FP_CHROMIUM="$(command -v chromium-browser)" - bind *:80 - mode http - default_backend nodes +fi -backend nodes +xinit $FP_CHROMIUM $CHROMIUM_OPTS +_EOF_ + G_EXEC chmod +x /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh - mode http - balance roundrobin - option forwardfor - http-request set-header X-Forwarded-Port %[dst_port] - http-request add-header X-Forwarded-Proto https if { ssl_fc } - option httpchk HEAD / HTTP/1.1\r\nHost:localhost - server web01 127.0.0.1:9000 check - server web02 127.0.0.1:9001 check - server web03 127.0.0.1:9002 check + fi -# Admin web page + software_id=136 # MotionEye + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + + # Motion + dependencies + G_AGI motion v4l-utils curl python-pip python-dev gcc libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev + + # MotionEye + G_EXEC_OUTPUT=1 G_EXEC pip2 install -U pip setuptools wheel + G_EXEC_OUTPUT=1 G_EXEC pip2 install -U motioneye + + # RPi: Enable camera module + (( $G_HW_MODEL < 10 )) && /boot/dietpi/func/dietpi-set_hardware rpi-camera enable + + # Config + if [[ ! -f '/etc/motioneye/motioneye.conf' ]] + then + [[ -d '/etc/motioneye' ]] || G_EXEC mkdir -p /etc/motioneye + G_EXEC cp /usr/local/share/motioneye/extra/motioneye.conf.sample /etc/motioneye/motioneye.conf + + # Data + [[ -d '/mnt/dietpi_userdata/motioneye' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/motioneye + G_EXEC sed -i '/^media_path/c\media_path /mnt/dietpi_userdata/motioneye' /etc/motioneye/motioneye.conf + fi + + # Service + G_EXEC cp /usr/local/share/motioneye/extra/motioneye.systemd-unit-local /etc/systemd/system/motioneye.service - listen stats - bind *:1338 - stats enable - stats uri / - stats hide-version - stats auth admin:dietpi -_EOF_ fi - software_id=55 # Wordpress - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + software_id=137 # mjpg-streamer + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then + Banner_Installing - Banner_Configuration + # Build dependencies + DEPS_LIST='make cmake gcc libc6-dev libjpeg-dev' + # - On RPi, add RPi Camera support by default + (( $G_HW_MODEL > 9 )) || DEPS_LIST+=' libraspberrypi-dev' - # Permissions - G_EXEC chown -R www-data:www-data /var/www/wordpress + # Download sources + Download_Install 'https://github.com/jacksonliam/mjpg-streamer/archive/master.tar.gz' - # Create MariaDB database - /boot/dietpi/func/create_mysql_db wordpress wordpress "$GLOBAL_PW" + # Compile + G_EXEC cd mjpg-streamer-master/mjpg-streamer-experimental + G_EXEC_OUTPUT=1 G_EXEC make CFLAGS='-g0 -O3' -j "$(nproc)" + G_EXEC strip --remove-section=.comment --remove-section=.note _build/mjpg_streamer - fi + # Move all plugin libraries into the executable's directory to avoid the need for LD_LIBRARY_PATH + G_EXEC mv _build/plugins/*/*.so _build/ - software_id=38 # FreshRSS - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Remove all left build files + G_EXEC rm -R _build/{{,C,c}[Mm]ake*,plugins} - Banner_Configuration + # Install to system, in case remove previous installs + [[ -d '/opt/mjpg-streamer' ]] && G_EXEC rm -R /opt/mjpg-streamer + G_EXEC mv _build /opt/mjpg-streamer - # Enable required PHP modules: https://github.com/FreshRSS/FreshRSS#requirements - G_EXEC phpenmod curl gmp intl json pdo_mysql ctype dom mbstring xml zip + # Cleanup + G_EXEC cd /tmp/$G_PROGRAM_NAME + G_EXEC rm -R mjpg-streamer-master - # Apache configuration - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + # User + Create_User -g video -d /opt/mjpg-streamer mjpg-streamer - # Required modules - G_EXEC a2enmod headers expires rewrite + # Service + # - On RPi, if the RPi camera module is enabled already, use it by default. + local input='input_uvc.so -d /dev/video0' + [[ $G_HW_MODEL -gt 9 || -f '/etc/modprobe.d/dietpi-disable_rpi_camera.conf' ]] || input='input_raspicam.so' + cat << _EOF_ > /etc/systemd/system/mjpg-streamer.service +[Unit] +Description=mjpg-streamer (DietPi) +Documentation=https://github.com/jacksonliam/mjpg-streamer/tree/master/mjpg-streamer-experimental +Wants=network-online.target +After=network-online.target - # Better compatibility with mobile clients - echo 'AllowEncodedSlashes On' > /etc/apache2/conf-available/dietpi-freshrss.conf - G_EXEC a2enconf dietpi-freshrss +[Service] +User=mjpg-streamer +WorkingDirectory=/opt/mjpg-streamer +ExecStart=/opt/mjpg-streamer/mjpg_streamer -i '$input' -o 'output_http.so -p 8082 -n' - fi +# Hardening +ProtectSystem=strict +PrivateTmp=true +ProtectHome=true +ProtectKernelTunables=true +ProtectControlGroups=true - # Create MariaDB database and user - if [[ -d '/mnt/dietpi_userdata/mysql/freshrss' ]]; then +[Install] +WantedBy=multi-user.target +_EOF_ + # OctoPrint: Configure it to use mjpg-streamer, if installed + if [[ ${aSOFTWARE_INSTALL_STATE[153]} == 2 && -f '/mnt/dietpi_userdata/octoprint/.octoprint/config.yaml' ]] + then + G_DIETPI-NOTIFY 2 'Configuring OctoPrint to use mjpg-streamer for webcam support' + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.stream "http://$(G_GET_NET ip):8082/?action=stream" + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.snapshot 'http://127.0.0.1:8082/?action=snapshot' + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.ffmpeg "$(command -v ffmpeg)" + fi + fi - G_DIETPI-NOTIFY 2 'FreshRSS MariaDB database found, will NOT overwrite.' - G_EXEC systemctl restart mariadb + software_id=138 # VirtualHere + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - else + Banner_Installing - /boot/dietpi/func/create_mysql_db freshrss freshrss "$GLOBAL_PW" + local url='https://virtualhere.com/sites/default/files/usbserver/vhusbd' - fi + # ARMv6/7 + if [[ $G_HW_ARCH == [12] ]]; then - # Set permissions for webserver access - G_EXEC chgrp -R www-data /opt/FreshRSS - G_EXEC chmod -R g+r+w /opt/FreshRSS + url+='arm' - # CLI install: https://github.com/FreshRSS/FreshRSS/blob/master/cli/README.md#commands - G_EXEC cd /opt/FreshRSS - sudo -u www-data php ./cli/prepare.php - sudo -u www-data php ./cli/do-install.php --default_user dietpi --auth_type form --environment production --title FreshRSS --db-type mysql --db-host localhost --db-user freshrss --db-password "$GLOBAL_PW" --db-base freshrss --db-prefix freshrss - sudo -u www-data php ./cli/create-user.php --user dietpi --password "$GLOBAL_PW" --api_password "$GLOBAL_PW" - G_EXEC cd /tmp/$G_PROGRAM_NAME + # ARMv8 + elif (( $G_HW_ARCH == 3 )); then - # Link web interface to webroot - G_EXEC rm -Rf /var/www/freshrss - G_EXEC ln -s /opt/FreshRSS/p /var/www/freshrss + url+='arm64' - # Create cron job for feed update every 30 minutes, if it does not yet exist - crontab -u www-data -l 2>/dev/null | grep -q '/opt/FreshRSS/app/actualize_script.php' || ( crontab -u www-data -l 2>/dev/null ; echo '*/30 * * * * php /opt/FreshRSS/app/actualize_script.php' ) | crontab -u www-data - + # x86_64 + elif (( $G_HW_ARCH == 10 )); then - fi + url+='x86_64' - # TigerVNC/RealVNC Server - Shared setup - if (( ${aSOFTWARE_INSTALL_STATE[28]} == 1 || ${aSOFTWARE_INSTALL_STATE[120]} == 1 )); then + fi - (( ${aSOFTWARE_INSTALL_STATE[28]} == 1 )) && software_id=28 || software_id=120 - Banner_Configuration + G_EXEC mkdir -p /etc/vhusbd + G_EXEC curl -sSfL "$url" -o /etc/vhusbd/vhusbd + G_EXEC chmod +x /etc/vhusbd/vhusbd # Service - cat << '_EOF_' > /etc/systemd/system/vncserver.service + cat << '_EOF_' > /etc/systemd/system/virtualhere.service [Unit] -Description=VNC Server (DietPi) -Before=xrdp.service xrdp-sesman.service -Wants=network-online.target -After=network-online.target +Description=VirtualHere (DietPi) [Service] -RemainAfterExit=yes -PAMName=login -User=root -Environment=HOME=/root -ExecStart=/usr/local/bin/vncserver start -ExecStop=/usr/local/bin/vncserver stop +ExecStart=/etc/vhusbd/vhusbd -r /var/log/virtualhere.log [Install] WantedBy=multi-user.target _EOF_ - G_EXEC systemctl daemon-reload - G_EXEC systemctl enable vncserver - aSTART_SERVICES+=('vncserver') + # Config + echo "ServerName='DietPi'" > /etc/vhusbd/config.ini - # RealVNC: Assure that its services are disabled when ours is enabled - (( ${aSOFTWARE_INSTALL_STATE[120]} == 1 )) && G_EXEC systemctl disable vncserver-virtuald vncserver-x11-serviced + fi - cat << '_EOF_' > /usr/local/bin/vncserver -#!/bin/dash + software_id=139 # SABnzbd + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then -if [ -f '/usr/bin/vncserver-virtual' ] -then - echo '[ OK ] RealVNC detected' - FP_BINARY='/usr/bin/vncserver-virtual -Authentication VncAuth' - FP_SHARED='exec /usr/bin/vncserver-x11 -service -Authentication VncAuth' + Banner_Installing # https://sabnzbd.org/wiki/installation/install-off-modules -elif [ -f '/usr/bin/tigervncserver' ] -then - echo '[ OK ] TigerVNC detected' - FP_BINARY='/usr/bin/tigervncserver' - [ -f '/usr/bin/X0tigervnc' ] && FP_SHARED='/usr/bin/X0tigervnc' || FP_SHARED='/usr/bin/x0tigervncserver' - FP_SHARED="$FP_SHARED -display :0 -rfbauth $HOME/.vnc/passwd" -else - echo '[FAILED] No supported VNC server installed' - exit 1 -fi + # APT deps + DEPS_LIST='par2 p7zip-full' + # - Pre-compiling required on ARM + (( $G_HW_ARCH > 9 )) || DEPS_LIST+=' libffi-dev libssl-dev' -case "$1" in + # 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' - start) - # Shared desktop mode - if grep -q '^[[:blank:]]*SOFTWARE_VNCSERVER_SHARE_DESKTOP=1' /boot/dietpi.txt - then - echo '[ INFO ] Waiting for X server...' - while : - do - until pgrep '^X' > /dev/null 2>&1; do sleep 1; done - echo '[ INFO ] Connecting to shared desktop' - $FP_SHARED - sleep 2 - pgrep '^X' > /dev/null 2>&1 && exit 1 - echo '[ INFO ] X server stopped, waiting for next session...' - done + # Download + Download_Install "https://github.com/sabnzbd/sabnzbd/archive/$version.tar.gz" - # Virtual desktop mode - else - DISPLAY=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_DISPLAY_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - WIDTH=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_WIDTH=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - HEIGHT=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_HEIGHT=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - DEPTH=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_DEPTH=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - echo "[ INFO ] Starting virtual desktop at display :${DISPLAY:-1} in ${WIDTH:-1280}x${HEIGHT:-720}x${DEPTH:-16}" - export SHELL='/bin/bash' - exec $FP_BINARY ":${DISPLAY:-1}" -geometry "${WIDTH:-1280}x${HEIGHT:-720}" -depth "${DEPTH:-16}" - fi - ;; + # Reinstall: Remove old install dir + if [[ -d '/etc/sabnzbd' ]]; then - stop) - # Shared desktop mode - if grep -q '^[[:blank:]]*SOFTWARE_VNCSERVER_SHARE_DESKTOP=1' /boot/dietpi.txt - then - echo '[ INFO ] Disconnecting from shared desktop' - killall -qw vncserver-x11-core x0tigervncserver X0tigervnc + # 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 - # Virtual desktop mode - else - DISPLAY=$(sed -n '/^[[:blank:]]*SOFTWARE_VNCSERVER_DISPLAY_INDEX=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - echo "[ INFO ] Stopping virtual desktop at display :${DISPLAY:-1}" - $FP_BINARY -kill ":${DISPLAY:-1}" - fi - ;; + fi - *) - echo "[FAILED] Invalid command ($1), please use \"start\" or \"stop\"" - exit 1 - ;; + # Install + G_EXEC mv sabnzbd-$version /etc/sabnzbd -esac + # Python deps + G_EXEC cd /etc/sabnzbd + G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur requirements.txt + G_EXEC cd /tmp/$G_PROGRAM_NAME -exit 0 + # User + Create_User -g dietpi -d /etc/sabnzbd sabnzbd + + # 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 + cat << _EOF_ > /etc/systemd/system/sabnzbd.service +[Unit] +Description=SABnzbd (DietPi) +Documentation=https://sabnzbd.org/wiki/ +Wants=network-online.target +After=network-online.target + +[Service] +User=sabnzbd +ExecStart=$(command -v python3) -OO /etc/sabnzbd/SABnzbd.py -b 0 -f /etc/sabnzbd/sabnzbd.ini +Restart=on-failure + +[Install] +WantedBy=multi-user.target _EOF_ - G_EXEC chmod +x /usr/local/bin/vncserver + # Log dir and permissions + G_EXEC mkdir -p /var/log/sabnzbd + G_EXEC chown -R sabnzbd:root /{etc,var/log}/sabnzbd - # TigerVNC: Permit remote connections which implies TLSVnc authentications being enabled additionally - # shellcheck disable=SC2016 - [[ -f '/etc/vnc.conf' ]] && GCI_PRESERVE=1 G_CONFIG_INJECT '\$localhost[[:blank:]]*=' '$localhost = "no";' /etc/vnc.conf # Stretch/Buster - # shellcheck disable=SC2016 - [[ -f '/etc/tigervnc/vncserver-config-defaults' ]] && GCI_PRESERVE=1 G_CONFIG_INJECT '\$localhost[[:blank:]]*=' '$localhost = "no";' /etc/tigervnc/vncserver-config-defaults # Bullseye + # 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 + 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 - # TigerVNC: Set control + read-only passwords - if [[ ${aSOFTWARE_INSTALL_STATE[28]} == 1 && ! -f '/root/.vnc/passwd' ]] - then - [[ -d '/root/.vnc' ]] || G_EXEC mkdir /root/.vnc - tigervncpasswd -f <<< "$GLOBAL_PW -$GLOBAL_PW" > /root/.vnc/passwd - G_EXEC chmod 600 /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' ]] - then - vncpasswd -virtual <<< "$GLOBAL_PW -$GLOBAL_PW" - vncpasswd -virtual <<< "$GLOBAL_PW -$GLOBAL_PW" - vncpasswd -service <<< "$GLOBAL_PW -$GLOBAL_PW" - 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 cd /tmp/$G_PROGRAM_NAME + fi - software_id=74 # InfluxDB + software_id=177 # Firefox Sync Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # Move DB/datadir to userdata location - [[ -d '/mnt/dietpi_userdata/influxdb' ]] || mv /var/lib/influxdb /mnt/dietpi_userdata/ - rm -Rf /var/lib/influxdb - ln -sf /mnt/dietpi_userdata/influxdb /var/lib/influxdb + # Dependencies: https://github.com/mozilla-services/syncserver#quickstart + DEPS_LIST='python-virtualenv python-dev libmariadb-dev' + # - Additional module compiling required on ARM + (( $G_HW_ARCH < 10 )) && DEPS_LIST+=' libffi-dev libssl-dev' - # Permissions - chown -R influxdb:influxdb /mnt/dietpi_userdata/influxdb + # Download & Install + local commit='c116417d653432db9470098236fb117adb349c36' # https://github.com/MichaIng/DietPi/issues/3774#issuecomment-703230290 + Download_Install "https://github.com/mozilla-services/syncserver/archive/$commit.tar.gz" + [[ -d '/opt/firefox-sync' ]] && G_EXEC rm -R /opt/firefox-sync + G_EXEC mv syncserver-$commit /opt/firefox-sync - fi + # Build + G_EXEC cd /opt/firefox-sync + G_EXEC_OUTPUT=1 G_EXEC make build + G_EXEC cd /tmp/$G_PROGRAM_NAME - software_id=186 # IPFS Node - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # User + Create_User -d /mnt/dietpi_userdata/firefox-sync ffsync + + # Create database and config directory + G_EXEC mkdir -p /mnt/dietpi_userdata/firefox-sync - Banner_Configuration + # Create database if it doesn't exist + [[ -f '/mnt/dietpi_userdata/firefox-sync/FF-Sync-DB.db' ]] || G_EXEC sqlite3 /mnt/dietpi_userdata/firefox-sync/FF-Sync-DB.db 'create table aTable(field1 int); drop table aTable;' - # Data and config directory - [[ -d '/mnt/dietpi_userdata/ipfs' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/ipfs + # Copy and modify default config file if it doesn't exist + local ffsync_conf='/mnt/dietpi_userdata/firefox-sync/syncserver.ini' + if [[ ! -f $ffsync_conf ]]; then - # User - Create_User -d /mnt/dietpi_userdata/ipfs ipfs + G_EXEC cp -a /opt/firefox-sync/syncserver.ini $ffsync_conf + local ffsync_ip=$(G_GET_NET ip) + G_CONFIG_INJECT 'host =' "host = $ffsync_ip" $ffsync_conf + G_CONFIG_INJECT 'port =' 'port = 5002' $ffsync_conf # Avoid port conflict with Shairport Sync + G_CONFIG_INJECT 'public_url =' "public_url = http://$ffsync_ip:5002/" $ffsync_conf + G_CONFIG_INJECT 'sqluri = sqlite:' 'sqluri = sqlite:////mnt/dietpi_userdata/firefox-sync/FF-Sync-DB.db' $ffsync_conf + + fi # Service - cat << '_EOF_' > /etc/systemd/system/ipfs.service + cat << _EOF_ > /etc/systemd/system/firefox-sync.service [Unit] -Description=IPFS (DietPi) -Documentation=https://docs.ipfs.io/reference/go/api/ +Description=Firefox Sync Server (DietPi) +Documentation=https://github.com/mozilla-services/syncserver Wants=network-online.target After=network-online.target [Service] -User=ipfs -Environment=IPFS_PATH=/mnt/dietpi_userdata/ipfs -ExecStart=/usr/local/bin/ipfs daemon +SyslogIdentifier=Firefox Sync Server +User=ffsync +WorkingDirectory=/mnt/dietpi_userdata/firefox-sync +ExecStart=/opt/firefox-sync/local/bin/gunicorn --paste $ffsync_conf + +# Hardening +ProtectSystem=strict +ProtectHome=true +PrivateTmp=true +PrivateDevices=true +ProtectKernelTunables=true +ProtectControlGroups=true +ReadWritePaths=-/mnt/dietpi_userdata/firefox-sync [Install] WantedBy=multi-user.target _EOF_ - # Config: Preserve existing on reinstall - if [[ ! -f '/mnt/dietpi_userdata/ipfs/config' ]]; then + # Permissions + G_EXEC chown -R ffsync:ffsync /mnt/dietpi_userdata/firefox-sync - IPFS_PATH='/mnt/dietpi_userdata/ipfs' G_EXEC_OUTPUT=1 G_EXEC ipfs init - IPFS_PATH='/mnt/dietpi_userdata/ipfs' G_EXEC ipfs config --json Addresses.Gateway '"/ip4/0.0.0.0/tcp/8087"' - IPFS_PATH='/mnt/dietpi_userdata/ipfs' G_EXEC ipfs config --json Addresses.API '"/ip4/0.0.0.0/tcp/5003"' - IPFS_PATH='/mnt/dietpi_userdata/ipfs' G_EXEC ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' + fi + + software_id=183 # vaultwarden + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + + # Dependencies: https://github.com/dani-garcia/vaultwarden/wiki/Building-binary#dependencies + DEPS_LIST='pkg-config libssl-dev' + + # 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"; } + Download_Install "https://github.com/dani-garcia/vaultwarden/archive/$version.tar.gz" + + # Replace old instance on reinstall using new project name + [[ -d '/opt/vaultwarden' ]] && G_EXEC rm -R /opt/vaultwarden + G_EXEC mv "vaultwarden-$version" /opt/vaultwarden + # Assure 3 GiB overall memory on single-core and 4 GiB on multi-core systems (-200 MiB to avoid tiny swap space) + local ram_min=3 + (( $(nproc) > 1 )) && ram_min=4 + if (( $RAM_TOTAL < $ram_min * 1024 - 200 )) + then + G_DIETPI-NOTIFY 2 "Vaultwarden build requires at least $ram_min GiB memory. We will now increase your swap size to satisfy this requirement." + /boot/dietpi/func/dietpi-set_swapfile $(( $ram_min * 1024 - $RAM_TOTAL )) fi - # Permissions - G_EXEC chown -R ipfs:ipfs /mnt/dietpi_userdata/ipfs + # Temporarily assure 2 GiB /tmp size for temporary Rust install + (( $(findmnt -bno SIZE /tmp) < 2147483648 )) && G_EXEC mount -o remount,size=2G /tmp - # CLI alias - echo "alias ipfs='sudo -u ipfs IPFS_PATH=/mnt/dietpi_userdata/ipfs ipfs'" > /etc/bashrc.d/dietpi-ipfs.sh + # Clean APT cache (which includes temporarily downloaded archives) when moved to RAM + [[ -d '/tmp/apt' ]] && G_EXEC apt-get clean - # Raise packet receive buffer: https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size - G_EXEC eval "echo 'net.core.rmem_max=2500000' > /etc/sysctl.d/dietpi-ipfs.conf" - G_EXEC sysctl -w net.core.rmem_max=2500000 + # Override $HOME to allow temporary Rust install to RAMdisk and DietPi-Software working directory, so all leftovers are automatically removed on script exit and/or reboot + export HOME="/tmp/$G_PROGRAM_NAME" - fi + # Install Rust via https://rustup.rs/ + G_EXEC curl -sSfL https://sh.rustup.rs -o rustup-init.sh + G_EXEC chmod +x rustup-init.sh + G_EXEC ./rustup-init.sh -y --default-toolchain none + G_EXEC_NOHALT=1 G_EXEC rm rustup-init.sh + G_EXEC . .cargo/env - software_id=77 # Grafana - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Build + G_EXEC cd /opt/vaultwarden + G_EXEC_OUTPUT=1 G_EXEC cargo build --features sqlite --release + G_EXEC cd /tmp/$G_PROGRAM_NAME - Banner_Configuration + # Uninstall rust after compiling + G_EXEC rustup self uninstall -y - Remove_SysV grafana-server + # Restore $HOME + HOME='/root' - # Link DB/plugins to userdata location - if [[ -d '/mnt/dietpi_userdata/grafana' ]]; then + # Install web vault + local fallback_url='https://github.com/dani-garcia/bw_web_builds/releases/download/v2.21.1/bw_web_v2.21.1.tar.gz' + Download_Install "$(curl -sSfL 'https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest' | mawk -F\" '/"browser_download_url": .*\/bw_web_[^"\/]*\.tar\.gz"/{print $4}')" /mnt/dietpi_userdata/vaultwarden - G_DIETPI-NOTIFY 2 "Existing database/plugin directory /mnt/dietpi_userdata/grafana found. Will not overwrite..." + # User + Create_User -d /mnt/dietpi_userdata/vaultwarden vaultwarden - elif [[ -d '/var/lib/grafana' ]]; then + [[ ! -d '/mnt/dietpi_userdata/vaultwarden' ]] && G_EXEC mkdir -p /mnt/dietpi_userdata/vaultwarden - G_EXEC mv /var/lib/grafana /mnt/dietpi_userdata/ + # Config: Preserve old + if [[ ! -f '/mnt/dietpi_userdata/vaultwarden/vaultwarden.env' ]] + then + G_EXEC cp /opt/vaultwarden/.env.template /mnt/dietpi_userdata/vaultwarden/vaultwarden.env + G_CONFIG_INJECT 'DATA_FOLDER=' 'DATA_FOLDER=/mnt/dietpi_userdata/vaultwarden' /mnt/dietpi_userdata/vaultwarden/vaultwarden.env + # Create TLS certificate for web vault: Currently only RSA is supported. Add SAN with local IP and hostname, required for the client to accept the connection. + G_EXEC_OUTPUT=1 G_EXEC openssl req -reqexts SAN -subj '/CN=DietPi Vaultwarden' -config <(cat /etc/ssl/openssl.cnf <(echo -ne "[SAN]\nsubjectAltName=DNS:$( /etc/systemd/system/vaultwarden.service +[Unit] +Description=vaultwarden Server (Rust Edition) +Documentation=https://github.com/dani-garcia/vaultwarden +Wants=network-online.target +After=network-online.target + +# Restart attempt only 5 times +StartLimitIntervalSec=500 +StartLimitBurst=5 + +[Service] +# Server sometimes fails to start on startup, this should fix it +Restart=on-failure +RestartSec=5s +# The user vaultwarden is run under. the working directory (see below) should allow write and read access to this user +User=vaultwarden +# The location of the .env file for configuration +EnvironmentFile=/mnt/dietpi_userdata/vaultwarden/vaultwarden.env +# The location of the compiled binary +ExecStart=/opt/vaultwarden/target/release/vaultwarden +# Set reasonable connection and process limits +LimitNOFILE=1048576 +LimitNPROC=64 +# Isolate vaultwarden from the rest of the system +PrivateTmp=true +PrivateDevices=true +ProtectHome=true +ProtectSystem=strict +# Only allow writes to the following directory and set it to the working directory (user and password data are stored here) +WorkingDirectory=/mnt/dietpi_userdata/vaultwarden +ReadWritePaths=-/mnt/dietpi_userdata/vaultwarden +# Allow vaultwarden to bind ports in the range of 0-1024 +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target +_EOF_ + fi + + software_id=193 # K3s + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + + # APT deps + G_AGI apparmor iptables + + # Fetch config file if it exists + if [[ -f '/boot/dietpi-k3s.yaml' && ! -f '/etc/rancher/k3s/config.yaml' ]] + then + G_EXEC mkdir -p '/etc/rancher/k3s' + G_EXEC cp '/boot/dietpi-k3s.yaml' '/etc/rancher/k3s/config.yaml' + fi + + # Install + G_EXEC curl -sSfL 'https://get.k3s.io/' -o install.sh + 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_NOHALT=1 G_EXEC rm install.sh + + # Do not enter into a server restart loop on failure + [[ -d '/etc/systemd/system/k3s.service.d' ]] || G_EXEC mkdir /etc/systemd/system/k3s.service.d + echo -e '[Service]\nRestart=on-success' > /etc/systemd/system/k3s.service.d/dietpi.conf + # Enable cgroups used by Docker and alike + if [[ -f '/boot/boot.cmd' ]] && grep -q 'docker_optimizations' /boot/boot.cmd + then + # Armbian + [[ -f '/boot/armbianEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/armbianEnv.txt + # Radxa Zero + [[ -f '/boot/uEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/uEnv.txt fi - G_EXEC rm -Rf /var/lib/grafana - 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 - 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 fi - software_id=80 # Ubooquity + software_id=141 # Spotify Connect Web if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - - # User - Create_User -G dietpi -d /mnt/dietpi_userdata/ubooquity ubooquity - - # Data - G_EXEC mkdir -p /mnt/dietpi_userdata/{ebooks,comics} - - # Logs - G_EXEC rm -Rf /mnt/dietpi_userdata/ubooquity/logs /var/log/ubooquity - G_EXEC mkdir -p /var/log/ubooquity - G_EXEC ln -s /var/log/ubooquity /mnt/dietpi_userdata/ubooquity/logs + Banner_Installing - # Optimise memory limit - local memory_limit=$(( $RAM_PHYS / 5 )) - (( $memory_limit < 200 )) && memory_limit=200 + # Download and merge into existing directory + Download_Install 'https://github.com/Fornoth/spotify-connect-web/releases/download/0.0.4-alpha/spotify-connect-web_0.0.4-alpha.tar.gz' /mnt/dietpi_userdata # Service - G_DIETPI-NOTIFY 2 "Generating systemd service to start ${aSOFTWARE_NAME[$software_id]} on boot" - cat << _EOF_ > /etc/systemd/system/ubooquity.service + cat << '_EOF_' > /etc/systemd/system/spotify-connect-web.service [Unit] -Description=Ubooquity (DietPi) +Description=Spotify Connect Web (DietPi) Wants=network-online.target -After=network-online.target +After=network-online.target sound.target [Service] -SyslogIdentifier=Ubooquity -User=ubooquity -WorkingDirectory=/mnt/dietpi_userdata/ubooquity -ExecStart=$(command -v java) -Xmx${memory_limit}m -jar /mnt/dietpi_userdata/ubooquity/Ubooquity.jar --headless --remoteadmin --adminport 2038 --libraryport 2039 +WorkingDirectory=/mnt/dietpi_userdata/spotify-connect-web +ExecStart=/mnt/dietpi_userdata/spotify-connect-web/spotify-connect-web [Install] WantedBy=multi-user.target _EOF_ - # Permissions - G_EXEC chmod +x /mnt/dietpi_userdata/ubooquity/Ubooquity.jar - G_EXEC chown -R ubooquity /{mnt/dietpi_userdata,var/log}/ubooquity - G_EXEC chown ubooquity:dietpi /mnt/dietpi_userdata/{ebooks,comics} - G_EXEC chmod 775 /mnt/dietpi_userdata/{ebooks,comics} - fi - software_id=179 # Komga + software_id=143 # Koel if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing + + # APT dependencies: https://docs.koel.dev/#server > https://laravel.com/docs/master/deployment#server-requirements + # - PHP composer install fails if no PHP SQLite and cURL modules are installed and enabled, even when MariaDB is used later. + 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' + 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 + if [[ -d '/mnt/dietpi_userdata/koel' ]]; then + + [[ -f '/mnt/dietpi_userdata/koel/.env' ]] && G_EXEC mv /mnt/dietpi_userdata/koel/.env koel/ + G_EXEC rm -R /mnt/dietpi_userdata/koel + + fi + G_EXEC mv koel /mnt/dietpi_userdata/koel + + # Download and install composer + G_EXEC curl -sSfL https://getcomposer.org/composer-stable.phar -o /usr/local/bin/composer + G_EXEC chmod +x /usr/local/bin/composer + + # Enable required PHP modules + G_EXEC phpenmod bcmath ctype fileinfo json mbstring tokenizer xml pdo_sqlite curl sqlite3 + + # Install Koel + G_EXEC cd /mnt/dietpi_userdata/koel + G_EXEC_OUTPUT=1 G_EXEC composer install -n + G_EXEC cd /tmp/$G_PROGRAM_NAME # User - Create_User -G dietpi -d /mnt/dietpi_userdata/komga komga + Create_User -g dietpi -d /mnt/dietpi_userdata/koel koel - # Data - G_EXEC mkdir -p /mnt/dietpi_userdata/{ebooks,comics} + # Permissions + G_EXEC cd /mnt/dietpi_userdata/koel + G_EXEC chmod 0600 .env + G_EXEC chown -R koel:dietpi . - # Config - [[ -f '/mnt/dietpi_userdata/komga/application.yml' ]] || cat << _EOF_ > /mnt/dietpi_userdata/komga/application.yml -komga: - libraries-scan-startup: true # Scan libraries at startup - libraries-scan-cron: "* 2 * * * *" # Scan libraries periodically every hour at :02 - file-hashing: false # Compute a filehash for your files. This is required for the trash bin functionality to work, but can consume lots of resources on large libraries or slow hardware - database: - file: /mnt/dietpi_userdata/komga/database.sqlite - remember-me: - key: $(openssl rand -hex 32) -logging: - file: - name: "" # Disable file logging, use: "journalctl -u komga" - level: - root: WARN # TRACE DEBUG INFO WARN ERROR -server: - port: 2037 -_EOF_ - # Optimise memory limit - local memory_limit=$(( $RAM_PHYS / 5 )) - (( $memory_limit < 200 )) && memory_limit=200 + # Create database and apply to config file, if it does not exist yet + if [[ ! -d '/mnt/dietpi_userdata/mysql/koel' ]]; then - # Service - cat << _EOF_ > /etc/systemd/system/komga.service + # Create random alphanumeric 30 characters password + local password=$(tr -dc '[:alnum:]' < /dev/random | head -c30) + /boot/dietpi/func/create_mysql_db koel koel "$password" + G_CONFIG_INJECT 'DB_CONNECTION=' 'DB_CONNECTION=mysql' .env + G_CONFIG_INJECT 'DB_HOST=' 'DB_HOST=localhost' .env + G_CONFIG_INJECT 'DB_DATABASE=' 'DB_DATABASE=koel' .env + G_CONFIG_INJECT 'DB_USERNAME=' 'DB_USERNAME=koel' .env + GCI_PASSWORD=1 G_CONFIG_INJECT 'DB_PASSWORD=' "DB_PASSWORD=$password" .env + unset -v password + G_CONFIG_INJECT 'MEDIA_PATH=' 'MEDIA_PATH=/mnt/dietpi_userdata/Music' .env + G_CONFIG_INJECT 'FFMPEG_PATH=' "FFMPEG_PATH=$(command -v ffmpeg)" .env + # Admin credentials cannot be pre-configured anymore: https://github.com/koel/koel/issues/1302 + #G_CONFIG_INJECT 'ADMIN_EMAIL=' 'ADMIN_EMAIL=dietpi@dietpi.com' .env + #G_CONFIG_INJECT 'ADMIN_NAME=' 'ADMIN_NAME=dietpi' .env + #GCI_PASSWORD=1 G_CONFIG_INJECT 'ADMIN_PASSWORD=' "ADMIN_PASSWORD=$GLOBAL_PW" .env + + # Else assure database server runs + else + + G_EXEC systemctl restart mariadb + + fi + + # Download test media + Download_Test_Media + + # Init + G_EXEC_OUTPUT=1 G_EXEC sudo -u koel $PHP_NAME artisan koel:init -n --no-assets + G_EXEC_OUTPUT=1 G_EXEC sudo -u koel $PHP_NAME artisan koel:sync + G_EXEC cd /tmp/$G_PROGRAM_NAME + + # Service: Run on port 8003 by default to avoid conflict with IceCast + cat << _EOF_ > /etc/systemd/system/koel.service [Unit] -Description=Komga (DietPi) +Description=Koel (DietPi) +Documentation=https://docs.koel.dev/ Wants=network-online.target After=network-online.target [Service] -SyslogIdentifier=Komga -User=komga -WorkingDirectory=/mnt/dietpi_userdata/komga -ExecStart=$(command -v java) -Xmx${memory_limit}m -jar komga.jar +SyslogIdentifier=Koel +User=koel +WorkingDirectory=/mnt/dietpi_userdata/koel +ExecStart=$(command -v $PHP_NAME) /mnt/dietpi_userdata/koel/artisan serve --host 0.0.0.0 --port 8003 [Install] WantedBy=multi-user.target _EOF_ - # Permissions - G_EXEC chmod +x /mnt/dietpi_userdata/komga/komga.jar - G_EXEC chown -R komga /mnt/dietpi_userdata/komga - G_EXEC chown komga:dietpi /mnt/dietpi_userdata/{ebooks,comics} - G_EXEC chmod 775 /mnt/dietpi_userdata/{ebooks,comics} - fi - software_id=64 # phpSysInfo + software_id=144 # Sonarr if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - [[ -f '/var/www/phpsysinfo/phpsysinfo.ini' ]] || dps_index=$software_id Download_Install 'phpsysinfo.ini' /var/www/phpsysinfo/phpsysinfo.ini + Banner_Installing # https://sonarr.tv/#downloads-v3-linux-debian - fi + # APT repo key + G_EXEC apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8 - software_id=40 # Ampache - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # 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" - Banner_Configuration - Download_Test_Media + # Update package lists + G_AGUP - # Enable required PHP modules: https://github.com/ampache/ampache/wiki/Installation#prerequisites - G_EXEC phpenmod curl intl json xml + # Pre-configure DEB package + G_EXEC eval "debconf-set-selections <<< 'sonarr sonarr/owning_group string dietpi'" + G_EXEC eval "debconf-set-selections <<< 'sonarr sonarr/config_directory string /mnt/dietpi_userdata/sonarr'" - # Import our pre-made Ampache database, if not existent already - if [[ ! -d '/mnt/dietpi_userdata/mysql/ampache' ]]; then + # Install Sonarr and mediainfo + G_AGI sonarr mediainfo - /boot/dietpi/func/create_mysql_db ampache ampache "$GLOBAL_PW" - Download_Install 'https://dietpi.com/downloads/mysql_databases/ampache_mysql_3.8.2-v6.0.zip' - G_EXEC mysql ampache < ampache.sql - G_EXEC_NOHALT=1 G_EXEC rm ampache.sql - # Also update password here for rare but possible case that database was lost but config file still exists - [[ -f '/var/www/ampache/config/ampache.cfg.php' ]] && G_CONFIG_INJECT 'database_password[[:blank:]]+=' "database_password = \"$GLOBAL_PW\"" /var/www/ampache/config/ampache.cfg.php + # 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' + [[ -f '/mnt/dietpi_userdata/sonarr/nzbdrone.pid' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /mnt/dietpi_userdata/sonarr/nzbdrone.pid + [[ -f '/mnt/dietpi_userdata/sonarr/nzbdrone.db.bak' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /mnt/dietpi_userdata/sonarr/nzbdrone.db.bak - fi + # Data dir + G_EXEC mkdir -p /mnt/dietpi_userdata/sonarr - # Create new config, if not existent already - if [[ ! -f '/var/www/ampache/config/ampache.cfg.php' ]]; then + # User + Create_User -g dietpi -d /mnt/dietpi_userdata/sonarr sonarr - G_EXEC mv /var/www/ampache/config/ampache.cfg.php{.dist,} - G_CONFIG_INJECT 'web_path[[:blank:]]+=' 'web_path = "/ampache"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'database_hostname[[:blank:]]+=' 'database_hostname = /run/mysqld/mysqld.sock' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'database_name[[:blank:]]+=' 'database_name = ampache' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'database_username[[:blank:]]+=' 'database_username = ampache' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'database_password[[:blank:]]+=' "database_password = \"$GLOBAL_PW\"" /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'waveform[[:blank:]]+=' 'waveform = "true"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'tmp_dir_path[[:blank:]]+=' 'tmp_dir_path = "/tmp"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'generate_video_preview[[:blank:]]+=' 'generate_video_preview = "true"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'channel[[:blank:]]+=' 'channel = "true"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_m4a[[:blank:]]+=' 'transcode_m4a = "required"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_flac[[:blank:]]+=' 'transcode_flac = "required"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_mpc[[:blank:]]+=' 'transcode_mpc = "required"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_ogg[[:blank:]]+=' 'transcode_ogg = "allowed"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_wav[[:blank:]]+=' 'transcode_wav = "required"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_avi[[:blank:]]+=' 'transcode_avi = "allowed"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_mkv[[:blank:]]+=' 'transcode_mkv = "allowed"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_mpg[[:blank:]]+=' 'transcode_mpg = "allowed"' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'encode_target[[:blank:]]+=' 'encode_target = mp3' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'encode_video_target[[:blank:]]+=' 'encode_video_target = webm' /var/www/ampache/config/ampache.cfg.php - G_CONFIG_INJECT 'transcode_cmd[[:blank:]]+=' 'transcode_cmd = "ffmpeg"' /var/www/ampache/config/ampache.cfg.php + # Service: https://github.com/Sonarr/Sonarr/blob/phantom-develop/distribution/debian/sonarr.service + cat << _EOF_ > /etc/systemd/system/sonarr.service +[Unit] +Description=Sonarr Daemon (DietPi) +Wants=network-online.target +After=network-online.target - fi +[Service] +SyslogIdentifier=Sonarr +User=sonarr +UMask=002 +ExecStart=$(command -v mono) /usr/lib/sonarr/bin/Sonarr.exe -nobrowser -data=/mnt/dietpi_userdata/sonarr +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +# Hardening +ProtectSystem=strict +ProtectHome=true +PrivateDevices=true +ProtectKernelTunables=true +ProtectControlGroups=true +ReadWritePaths=-/usr/lib/sonarr -/mnt -/media -/var/log/sonarr -/tmp + +[Install] +WantedBy=multi-user.target +_EOF_ + # Logs to RAM + G_EXEC rm -Rf /mnt/dietpi_userdata/sonarr/logs* + G_EXEC mkdir -p /var/log/sonarr + G_EXEC ln -s /var/log/sonarr /mnt/dietpi_userdata/sonarr/logs + G_EXEC ln -s /var/log/sonarr/logs.db /mnt/dietpi_userdata/sonarr/logs.db + G_EXEC ln -s /var/log/sonarr/logs.db-shm /mnt/dietpi_userdata/sonarr/logs.db-shm + G_EXEC ln -s /var/log/sonarr/logs.db-wal /mnt/dietpi_userdata/sonarr/logs.db-wal - # Permissions: Ampache can automatically migrate old configs to the new config file - G_EXEC chown www-data /var/www/ampache/config/ampache.cfg.php + # Permissions + G_EXEC chown -R sonarr:dietpi /mnt/dietpi_userdata/sonarr /usr/lib/sonarr /var/log/sonarr fi - software_id=97 # OpenVPN Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Create initial server and client configs, if not yet present - # - Wildcard config file detection via for loop - local i - for i in /etc/openvpn/*.conf - do + software_id=145 # Radarr + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then - # Inform user, if config exist, that config generation is skipped - if [[ -f $i ]]; then + Banner_Installing - G_DIETPI-NOTIFY 2 "Existing OpenVPN configuration found: $i - - Config generation will be skipped. - - If you need a fresh key/cert/config set, please remove $i - and run: dietpi-software reinstall 97" - break + # APT dependencies + DEPS_LIST='mediainfo' + # - .NET: https://packages.microsoft.com/debian/ + if (( $G_HW_ARCH != 1 )) + then + if (( $G_DISTRO < 5 )) + then + DEPS_LIST+=' libicu57' + elif (( $G_DISTRO == 5 )) + then + DEPS_LIST+=' libicu63' + else + DEPS_LIST+=' libicu67' fi + fi - # Pre-v6.26 cleanup - [[ -f '/etc/openvpn/dh2048.pem' ]] && rm /etc/openvpn/dh2048.pem - dpkg-query -s easy-rsa &> /dev/null && G_AGP easy-rsa + # Reinstall: Skip download and install, advice to use internal updater from web UI + if [[ -d '/opt/radarr' ]] + then + # shellcheck disable=SC2086 + G_AGI $DEPS_LIST + DEPS_LIST= + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/radarr\" already exists. Download and install steps will be skipped. + - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. + - If you need to reinstall (e.g. broken instance), please manually remove the install dir \"/opt/radarr\" and rerun \"dietpi-software reinstall $software_id\"." - # Download latest easy-rsa from GitHub - G_DIETPI-NOTIFY 2 'Downloading latest easy-rsa for certificate and key generation...' - local fallback_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz' - Download_Install "$(curl -sSfL 'https://api.github.com/repos/OpenVPN/easy-rsa/releases/latest' | mawk -F\" '/"browser_download_url": .*\/EasyRSA-[^"\/]*\.tgz"/{print $4}')" - [[ -d '/etc/openvpn/easy-rsa' ]] && rm -R /etc/openvpn/easy-rsa - G_EXEC mv EasyRSA-* /etc/openvpn/easy-rsa + else + # ARMv6 + local url=$(curl -sSfL 'https://api.github.com/repos/Radarr/Radarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux\.tar\.gz"/{print $4}') + local version='3.2.2.5080' + local fallback_url="https://github.com/Radarr/Radarr/releases/download/v$version/Radarr.master.$version.linux.tar.gz" - # Cert and key generation via easy-rsa - G_DIETPI-NOTIFY 2 'Generating unique OpenVPN certificates and keys. Please wait...\n' - G_EXEC cd /etc/openvpn/easy-rsa - cat << '_EOF_' > vars -set_var EASYRSA_REQ_COUNTRY "UK" -set_var EASYRSA_REQ_PROVINCE "DietPi" -set_var EASYRSA_REQ_CITY "DietPi" -set_var EASYRSA_REQ_ORG "DietPi" -set_var EASYRSA_REQ_EMAIL "noreply@dietpi.com" -set_var EASYRSA_REQ_OU "DietPi" -set_var EASYRSA_BATCH "1" -_EOF_ - ./easyrsa init-pki - ./easyrsa build-ca nopass - ./easyrsa gen-dh - ./easyrsa build-server-full DietPi_OpenVPN_Server nopass - ./easyrsa build-client-full DietPi_OpenVPN_Client nopass + # ARMv7 + if (( $G_HW_ARCH == 2 )) + then + url=$(curl -sSfL 'https://api.github.com/repos/Radarr/Radarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-arm\.tar\.gz"/{print $4}') + fallback_url="https://github.com/Radarr/Radarr/releases/download/v$version/Radarr.master.$version.linux-core-arm.tar.gz" - # Server config - cp -a pki/{ca.crt,dh.pem,issued/DietPi_OpenVPN_Server.crt,private/DietPi_OpenVPN_Server.key} /etc/openvpn/ - G_EXEC cd /etc/openvpn - cat << '_EOF_' > server.conf -port 1194 -proto udp -dev tun + # ARMv8 + elif (( $G_HW_ARCH == 3 )) + then + url=$(curl -sSfL 'https://api.github.com/repos/Radarr/Radarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-arm64\.tar\.gz"/{print $4}') + fallback_url="https://github.com/Radarr/Radarr/releases/download/v$version/Radarr.master.$version.linux-core-arm64.tar.gz" -ca ca.crt -cert DietPi_OpenVPN_Server.crt -key DietPi_OpenVPN_Server.key -dh dh.pem + # x86_64 + elif (( $G_HW_ARCH == 10 )) + then + url=$(curl -sSfL 'https://api.github.com/repos/Radarr/Radarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-x64\.tar\.gz"/{print $4}') + fallback_url="https://github.com/Radarr/Radarr/releases/download/v$version/Radarr.master.$version.linux-core-x64.tar.gz" + fi -server 10.8.0.0 255.255.255.0 + Download_Install "$url" + G_EXEC mv Radarr /opt/radarr + fi -client-to-client -keepalive 10 60 -comp-lzo -max-clients 10 + # Radarr v2: Remove old PID file and database backups from DietPi-Arr_to_RAM + [[ -f '/mnt/dietpi_userdata/radarr/nzbdrone.pid' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /mnt/dietpi_userdata/radarr/nzbdrone.pid + [[ -f '/mnt/dietpi_userdata/radarr/nzbdrone.db.bak' ]] && G_EXEC_NOEXIT=1 G_EXEC rm /mnt/dietpi_userdata/radarr/nzbdrone.db.bak -user nobody -group nogroup + # Data dir + G_EXEC mkdir -p /mnt/dietpi_userdata/radarr -persist-key -persist-tun -verb 3 + # User + Create_User -g dietpi -d /mnt/dietpi_userdata/radarr radarr -# Web Forwarding (uncomment to enable) -#push "redirect-gateway" -#push "dhcp-option DNS 10.8.0.1" -_EOF_ + # Service: https://github.com/Radarr/Radarr/wiki/Autostart-on-Linux#service-file + cat << '_EOF_' > /etc/systemd/system/radarr.service +[Unit] +Description=Radarr Daemon (DietPi) +Wants=network-online.target +After=network-online.target - # Client config - cat << '_EOF_' > DietPi_OpenVPN_Client.ovpn -client -proto udp -dev tun +[Service] +SyslogIdentifier=Radarr +User=radarr +UMask=002 +ExecStart=/opt/radarr/Radarr -nobrowser -data=/mnt/dietpi_userdata/radarr +TimeoutStopSec=20 +KillMode=process +Restart=on-failure -# IP/domain name of DietPi system, running OpenVPN server -remote mywebsite.com 1194 +# Hardening +ProtectSystem=strict +ProtectHome=true +PrivateDevices=true +ProtectKernelTunables=true +ProtectControlGroups=true +ReadWritePaths=-/opt/radarr -/mnt -/media -/var/log/radarr -/tmp -resolv-retry infinite -nobind +[Install] +WantedBy=multi-user.target +_EOF_ + # - ARMv6 devices use Mono + (( $G_HW_ARCH == 1 )) && G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v mono) /opt/radarr/Radarr.exe -nobrowser -data=/mnt/dietpi_userdata/radarr" /etc/systemd/system/radarr.service -user nobody -group nogroup + # Logs to RAM + G_EXEC rm -Rf /mnt/dietpi_userdata/radarr/logs* + G_EXEC mkdir -p /var/log/radarr + G_EXEC ln -s /var/log/radarr /mnt/dietpi_userdata/radarr/logs + G_EXEC ln -s /var/log/radarr/logs.db /mnt/dietpi_userdata/radarr/logs.db + G_EXEC ln -s /var/log/radarr/logs.db-shm /mnt/dietpi_userdata/radarr/logs.db-shm + G_EXEC ln -s /var/log/radarr/logs.db-wal /mnt/dietpi_userdata/radarr/logs.db-wal -persist-key -persist-tun + # Permissions + G_EXEC chown -R radarr:dietpi /mnt/dietpi_userdata/radarr /opt/radarr /var/log/radarr + fi -remote-cert-tls server -comp-lzo -verb 3 -_EOF_ - # - Add CA cert, client cert and key - echo -e " -\n$( -\n$( -\n$(" >> DietPi_OpenVPN_Client.ovpn + software_id=106 # Lidarr + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # - Copy to userdata - G_EXEC cp DietPi_OpenVPN_Client.ovpn /mnt/dietpi_userdata/ - # - and /boot partition - G_EXEC cp DietPi_OpenVPN_Client.ovpn /boot/ + Banner_Installing - G_EXEC cd /tmp/$G_PROGRAM_NAME - break # Always break loop which is only for single wildcard file detection + # APT dependencies + DEPS_LIST='mediainfo' + # - .NET: https://packages.microsoft.com/debian/ + if (( $G_HW_ARCH != 1 )) + then + if (( $G_DISTRO < 5 )) + then + DEPS_LIST+=' libicu57' - done + elif (( $G_DISTRO == 5 )) + then + DEPS_LIST+=' libicu63' + else + DEPS_LIST+=' libicu67' + fi + fi - # Enable IP forwarding - echo -e 'net.ipv4.ip_forward=1\nnet.ipv6.conf.all.forwarding=1\nnet.ipv6.conf.default.forwarding=1' > /etc/sysctl.d/dietpi-openvpn.conf - sysctl net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 net.ipv6.conf.default.forwarding=1 + # Pre-v7.5 ARMv6: Migrate old install dir + [[ -d '/opt/Lidarr' && ! -d '/opt/lidarr' ]] && G_EXEC mv /opt/{L,l}idarr - # Web Forwarding (Setup IPtables, must also be run during boot) - #iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o "$(G_GET_NET iface)" -j MASQUERADE + # Reinstall: Skip download and install, advice to use internal updater from web UI + if [[ -d '/opt/lidarr' ]] + then + # shellcheck disable=SC2086 + G_AGI $DEPS_LIST + DEPS_LIST= + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/lidarr\" already exists. Download and install steps will be skipped. + - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. + - If you need to reinstall (e.g. broken instance), please manually remove the install dir \"/opt/lidarr\" and rerun \"dietpi-software reinstall $software_id\"." - aSTART_SERVICES+=('openvpn') + else + # ARMv6 + local url=$(curl -sSfL 'https://api.github.com/repos/Lidarr/Lidarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux\.tar\.gz"/{print $4}') + local version='0.8.1.2135' + local fallback_url="https://github.com/Lidarr/Lidarr/releases/download/v$version/Lidarr.master.$version.linux.tar.gz" - fi + # ARMv7 + if (( $G_HW_ARCH == 2 )) + then + url=$(curl -sSfL 'https://api.github.com/repos/Lidarr/Lidarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-arm\.tar\.gz"/{print $4}') + fallback_url="https://github.com/Lidarr/Lidarr/releases/download/v$version/Lidarr.master.$version.linux-core-arm.tar.gz" - software_id=172 # WireGuard - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # ARMv8 + elif (( $G_HW_ARCH == 3 )) + then + url=$(curl -sSfL 'https://api.github.com/repos/Lidarr/Lidarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-arm64\.tar\.gz"/{print $4}') + fallback_url="https://github.com/Lidarr/Lidarr/releases/download/v$version/Lidarr.master.$version.linux-core-arm64.tar.gz" + + # x86_64 + elif (( $G_HW_ARCH == 10 )) + then + url=$(curl -sSfL 'https://api.github.com/repos/Lidarr/Lidarr/releases/latest' | mawk -F\" '/"browser_download_url": .*linux-core-x64\.tar\.gz"/{print $4}') + fallback_url="https://github.com/Lidarr/Lidarr/releases/download/v$version/Lidarr.master.$version.linux-core-x64.tar.gz" + fi - Banner_Configuration + Download_Install "$url" + G_EXEC mv Lidarr /opt/lidarr + fi - # Try to enable module, if it fails, a reboot is required - local module_active=0 - modprobe wireguard 2> /dev/null && module_active=1 + # Data dir + G_EXEC mkdir -p /mnt/dietpi_userdata/lidarr - # Server/Client choice - local choice_required= - while : - do - G_WHIP_MENU_ARRAY=( + # User + Create_User -g dietpi -d /mnt/dietpi_userdata/lidarr lidarr - 'Server' ': Use this machine as VPN server and allow clients to connect to it.' - 'Client' ': Use this machine as VPN client to connect to another VPN server or service provider.' + # Service: https://github.com/lidarr/Lidarr/wiki/Autostart-on-Linux#systemd + cat << _EOF_ > /etc/systemd/system/lidarr.service +[Unit] +Description=Lidarr Daemon (DietPi) +Wants=network-online.target +After=network-online.target - ) +[Service] +SyslogIdentifier=Lidarr +User=lidarr +UMask=002 +ExecStart=/opt/lidarr/Lidarr -nobrowser -data=/mnt/dietpi_userdata/lidarr +TimeoutStopSec=20 +KillMode=process +Restart=on-failure - G_WHIP_MENU "${choice_required}Please choose, if this machine should be set up as VPN server or client:" && break - choice_required='[ERROR] A choice is required to finish the WireGuard install.\n\n' - done +# Hardening +ProtectSystem=strict +ProtectHome=true +PrivateDevices=true +ProtectKernelTunables=true +ProtectControlGroups=true +ReadWritePaths=-/opt/lidarr -/mnt -/media -/var/log/lidarr -/tmp - # Server choice - if [[ $G_WHIP_RETURNED_VALUE == 'Server' ]]; then +[Install] +WantedBy=multi-user.target +_EOF_ + # - ARMv6 devices use Mono + (( $G_HW_ARCH == 1 )) && G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v mono) /opt/lidarr/Lidarr.exe -nobrowser -data=/mnt/dietpi_userdata/lidarr" /etc/systemd/system/lidarr.service - # Public IP/domain and desired WireGuard server port - local invalid_text= - local domain=$(hostname -f) - while : - do - G_WHIP_DEFAULT_ITEM=$domain - if G_WHIP_INPUTBOX "${invalid_text}Please enter your servers public IP/domain for WireGuard client access:" && [[ $G_WHIP_RETURNED_VALUE ]]; then + # Logs to RAM + G_EXEC rm -Rf /mnt/dietpi_userdata/lidarr/logs* + G_EXEC mkdir -p /var/log/lidarr + G_EXEC ln -s /var/log/lidarr /mnt/dietpi_userdata/lidarr/logs + G_EXEC ln -s /var/log/lidarr/logs.db /mnt/dietpi_userdata/lidarr/logs.db + G_EXEC ln -s /var/log/lidarr/logs.db-shm /mnt/dietpi_userdata/lidarr/logs.db-shm + G_EXEC ln -s /var/log/lidarr/logs.db-wal /mnt/dietpi_userdata/lidarr/logs.db-wal - domain=${G_WHIP_RETURNED_VALUE#http*://} - break + # Permissions + G_EXEC chown -R lidarr:dietpi /mnt/dietpi_userdata/lidarr /opt/lidarr /var/log/lidarr - else + fi - invalid_text='[ERROR] No valid entry found. Please retry...\n\n' + software_id=180 # Bazarr + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - fi - done - invalid_text= - local port=51820 - while : - do - G_WHIP_DEFAULT_ITEM=$port - if G_WHIP_INPUTBOX "${invalid_text}Please enter the network port that will be used to access your WireGuard server:\n -NB: This port needs to be forwarded by your router and/or opened in your firewall settings. Default value is: 51820" && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 0; then + Banner_Installing # https://wiki.bazarr.media/Getting-Started/Installation/Linux/linux/ - port=$G_WHIP_RETURNED_VALUE - break + if [[ -d '/opt/bazarr' ]]; then - else + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/opt/bazarr\" already exists. Download and install steps will be skipped. + - If you want to update ${aSOFTWARE_NAME[$software_id]}, please use the internal updater from web UI. + - If you need to reinstall (e.g. broken instance), please manually remove the install dir \"/opt/bazarr\" and rerun \"dietpi-software reinstall $software_id\"." - invalid_text='[ERROR] No valid entry found, value needs to be a sequence of integers. Please retry...\n\n' + else - fi - done + Download_Install 'https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip' /opt/bazarr - # Create everything inside WireGuard config dir - G_EXEC cd /etc/wireguard + fi - # For security reasons set umask to 077 - umask 077 + # ARM: Install known required Python modules via APT to avoid time-consuming compiling and large build dependencies (on x86 pre-compiled wheels are available) + (( $G_HW_ARCH == 10 )) || G_AGI python3-{lxml,numpy} - # Create server and client keys - [[ -f 'server_private.key' ]] || wg genkey > server_private.key - [[ -f 'server_public.key' ]] || wg pubkey < server_private.key > server_public.key - [[ -f 'client_private.key' ]] || wg genkey > client_private.key - [[ -f 'client_public.key' ]] || wg pubkey < client_private.key > client_public.key + G_EXEC cd /opt/bazarr + G_EXEC_OUTPUT=1 G_EXEC pip3 install -r requirements.txt + G_EXEC cd /tmp/$G_PROGRAM_NAME - # Server config - [[ -f 'wg0.conf' ]] || cat << _EOF_ > wg0.conf -[Interface] -Address = 10.9.0.1/24 -PrivateKey = $( /etc/systemd/system/bazarr.service +[Unit] +Description=Bazarr Daemon (DietPi) +Wants=network-online.target +After=network-online.target sonarr.service radarr.service -# Client 2 -#[Peer] -#PublicKey = XXXX -#AllowedIPs = 10.9.0.3/32 -_EOF_ +[Service] +SyslogIdentifier=Bazarr +User=bazarr +UMask=002 +ExecStart=$(command -v python3) /opt/bazarr/bazarr.py -c /mnt/dietpi_userdata/bazarr - # Server local network IP - local server_ip=$(G_GET_NET ip) +# Hardening +ProtectSystem=strict +ProtectHome=true +PrivateDevices=true +PrivateTmp=true +ProtectKernelTunables=true +ProtectControlGroups=true +ReadWritePaths=-/opt/bazarr -/mnt -/media -/var/log/bazarr -/tmp - # Server DNS nameserver - local server_dns=$(mawk '/nameserver/{print $2;exit}' /etc/resolv.conf) - # - Replace "127.0.0.1"/"localhost" loopback entries by server wg0 IP: https://github.com/MichaIng/DietPi/issues/2482 - server_dns=${server_dns//127.0.0.1/10.9.0.1} - server_dns=${server_dns//localhost/10.9.0.1} +[Install] +WantedBy=multi-user.target +_EOF_ + # Logs to RAM + G_EXEC rm -Rf /mnt/dietpi_userdata/bazarr/log + G_EXEC mkdir -p /var/log/bazarr + G_EXEC ln -s /var/log/bazarr /mnt/dietpi_userdata/bazarr/log - # Client config - [[ -f 'wg0-client.conf' ]] || cat << _EOF_ > wg0-client.conf -[Interface] -Address = 10.9.0.2/24 -PrivateKey = $( 0 )) && Create_Config /mnt/dietpi_userdata/bazarr/config/config.ini bazarr + then + # Sonarr + if (( ${aSOFTWARE_INSTALL_STATE[144]} > 0 )) && CREATE_CONFIG_CONTENT='ApiKey' Create_Config /mnt/dietpi_userdata/sonarr/config.xml sonarr + then + local port=$(sed -nE '/[0-9]+<\/Port>/{s/^.*([0-9]+)<\/Port>.*$/\1/p;q}' /mnt/dietpi_userdata/sonarr/config.xml) + local apikey=$(sed -nE '/.+<\/ApiKey>/{s/^.*(.+)<\/ApiKey>.*$/\1/p;q}' /mnt/dietpi_userdata/sonarr/config.xml) + G_EXEC sed -i '/\[sonarr\]/,/^$/s/^ip = .*$/ip = 127.0.0.1/' /mnt/dietpi_userdata/bazarr/config/config.ini + G_EXEC sed -i "/\[sonarr\]/,/^$/s/^port = .*$/port = $port/" /mnt/dietpi_userdata/bazarr/config/config.ini + G_EXEC sed -i '/\[sonarr\]/,/^$/s/^base_url = .*$/base_url = \//' /mnt/dietpi_userdata/bazarr/config/config.ini + G_EXEC sed -i "/\[sonarr\]/,/^$/s/^apikey = .*$/apikey = $apikey/" /mnt/dietpi_userdata/bazarr/config/config.ini + G_CONFIG_INJECT 'use_sonarr[[:blank:]]*=' 'use_sonarr = True' /mnt/dietpi_userdata/bazarr/config/config.ini '\[general\]' + fi + # Radarr + if (( ${aSOFTWARE_INSTALL_STATE[145]} > 0 )) && CREATE_CONFIG_CONTENT='ApiKey' Create_Config /mnt/dietpi_userdata/radarr/config.xml radarr + then + local port=$(sed -nE '/[0-9]+<\/Port>/{s/^.*([0-9]+)<\/Port>.*$/\1/p;q}' /mnt/dietpi_userdata/radarr/config.xml) + local apikey=$(sed -nE '/.+<\/ApiKey>/{s/^.*(.+)<\/ApiKey>.*$/\1/p;q}' /mnt/dietpi_userdata/radarr/config.xml) + G_EXEC sed -i '/\[radarr\]/,/^$/s/^ip = .*$/ip = 127.0.0.1/' /mnt/dietpi_userdata/bazarr/config/config.ini + G_EXEC sed -i "/\[radarr\]/,/^$/s/^port = .*$/port = $port/" /mnt/dietpi_userdata/bazarr/config/config.ini + G_EXEC sed -i '/\[radarr\]/,/^$/s/^base_url = .*$/base_url = \//' /mnt/dietpi_userdata/bazarr/config/config.ini + G_EXEC sed -i "/\[radarr\]/,/^$/s/^apikey = .*$/apikey = $apikey/" /mnt/dietpi_userdata/bazarr/config/config.ini + G_CONFIG_INJECT 'use_radarr[[:blank:]]*=' 'use_radarr = True' /mnt/dietpi_userdata/bazarr/config/config.ini '\[general\]' + fi + fi -# Kill switch: Uncomment the following, if the client should stop any network traffic, when disconnected from the VPN server -# NB: This requires "iptables" to be installed, thus will not work on most mobile phones. -#PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark \$(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT && ip6tables -I OUTPUT ! -o %i -m mark ! --mark \$(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT -#PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark \$(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT && ip6tables -D OUTPUT ! -o %i -m mark ! --mark \$(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT + fi -[Peer] -PublicKey = $( /etc/systemd/system/tautulli.service +[Unit] +Description=Tautulli - Stats for Plex Media Server usage (DietPi) +Wants=network-online.target +After=network-online.target + +[Service] +User=tautulli +ExecStart=$(command -v python3) /opt/tautulli/Tautulli.py -q --nolaunch --config /mnt/dietpi_userdata//tautulli/config.ini --datadir /mnt/dietpi_userdata/tautulli + +[Install] +WantedBy=multi-user.target +_EOF_ + # Permissions + G_EXEC chown -R tautulli:tautulli /{opt,mnt/dietpi_userdata}/tautulli fi - software_id=60 # WiFi Hotspot + software_id=147 # Jackett if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - local eth_iface=$(G_GET_NET -t eth iface) - local wifi_iface=$(G_GET_NET -t wlan iface) + # Grab latest version download link - # DHCPD Config - G_BACKUP_FP /etc/dhcp/dhcpd.conf - cat << '_EOF_' > /etc/dhcp/dhcpd.conf -ddns-update-style none; -default-lease-time 600; -max-lease-time 7200; -authoritative; -log-facility local7; + # - 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' -subnet 192.168.42.0 netmask 255.255.255.0 { - range 192.168.42.10 192.168.42.50; - option broadcast-address 192.168.42.255; - option routers 192.168.42.1; - option domain-name "local"; - option domain-name-servers 8.8.8.8, 8.8.4.4; -} -_EOF_ - # Assign detected WLAN interface - echo "INTERFACESv4=\"$wifi_iface\"" > /etc/default/isc-dhcp-server + # - ARMv7 + if (( $G_HW_ARCH == 2 )); then - # Remove all entries below wlan, so we can recreate them - G_EXEC sed -i '/allow-hotplug wlan/q0' /etc/network/interfaces + url=${url/Mono/LinuxARM32} + fallback_url=${fallback_url/Mono/LinuxARM32} - # Enable up wlan - G_CONFIG_INJECT 'allow-hotplug wlan' "allow-hotplug $wifi_iface" /etc/network/interfaces + # - ARMv8 + elif (( $G_HW_ARCH == 3 )); then - # Add WiFi settings to network interfaces config - cat << _EOF_ >> /etc/network/interfaces -iface $wifi_iface inet static -address 192.168.42.1 -netmask 255.255.255.0 -#gateway 192.168.0.1 -wireless-power off -#dns-nameservers 8.8.8.8 8.8.4.4 + url=${url/Mono/LinuxARM64} + fallback_url=${fallback_url/Mono/LinuxARM64} -# IP tables -up iptables-restore < /etc/iptables.ipv4.nat -_EOF_ - # Assign static IP for wlan now - G_EXEC ip a add 192.168.42.1 dev "$wifi_iface" + # - x86_64 + elif (( $G_HW_ARCH == 10 )); then - # Create access point config - G_BACKUP_FP /etc/hostapd/hostapd.conf - cat << _EOF_ > /etc/hostapd/hostapd.conf -interface=$wifi_iface -driver=nl80211 -ssid=$(sed -n '/^[[:blank:]]*SOFTWARE_WIFI_HOTSPOT_SSID=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) -hw_mode=g -channel=$(sed -n '/^[[:blank:]]*SOFTWARE_WIFI_HOTSPOT_CHANNEL=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) -macaddr_acl=0 -auth_algs=1 -ignore_broadcast_ssid=0 -wpa=2 -wpa_passphrase=$(sed -n '/^[[:blank:]]*SOFTWARE_WIFI_HOTSPOT_KEY=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) -wpa_key_mgmt=WPA-PSK -wpa_pairwise=TKIP -rsn_pairwise=CCMP -_EOF_ - # Use "rtl871xdrv" driver when special package has been installed - dpkg-query -s hostapd-realtek &> /dev/null && G_CONFIG_INJECT 'driver=' 'driver=rtl871xdrv' /etc/hostapd/hostapd.conf + url=${url/Mono/LinuxAMDx64} + fallback_url=${fallback_url/Mono/LinuxAMDx64} - # Enable access point config - echo 'DAEMON_CONF="/etc/hostapd/hostapd.conf"' > /etc/default/hostapd + fi - # Enable IP forwarding - echo -e 'net.ipv4.ip_forward=1\nnet.ipv6.conf.all.forwarding=1\nnet.ipv6.conf.default.forwarding=1' > /etc/sysctl.d/dietpi-wifihotspot.conf - sysctl net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 net.ipv6.conf.default.forwarding=1 + # .NET dependencies: https://packages.microsoft.com/debian/ + if (( $G_HW_ARCH != 1 )) + then + DEPS_LIST='liblttng-ust0' + if (( $G_DISTRO < 5 )) + then + DEPS_LIST+=' libicu57' - # Apply IP tables - iptables -t nat -A POSTROUTING -o "$eth_iface" -j MASQUERADE - iptables -A FORWARD -i "$eth_iface" -o "$wifi_iface" -m state --state RELATED,ESTABLISHED -j ACCEPT - iptables -A FORWARD -i "$wifi_iface" -o "$eth_iface" -j ACCEPT + elif (( $G_DISTRO == 5 )) + then + DEPS_LIST+=' libicu63' + else + DEPS_LIST+=' libicu67' + fi + fi - # Save IP tables, applied during ifup in /etc/network/interfaces - iptables-save > /etc/iptables.ipv4.nat + Download_Install "$url" /opt - # RPi3/4 onboard WiFi: Enable N support - [[ $G_HW_MODEL == [34] ]] && G_CONFIG_INJECT 'ieee80211n=' 'ieee80211n=1' /etc/hostapd/hostapd.conf + # Move existing configs to unpacked install dir + [[ -d '/opt/jackett/Jackett' ]] && G_EXEC mv /opt/jackett/Jackett /opt/Jackett/ + [[ -d '/opt/jackett/.mono' ]] && G_EXEC mv /opt/jackett/.mono /opt/Jackett/ - fi + # Remove existing install dir + [[ -d '/opt/jackett' ]] && G_EXEC rm -R /opt/jackett - software_id=61 # Tor Hotspot - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Move unpacked install dir in place + G_EXEC mv /opt/Jackett /opt/jackett - Banner_Configuration + # User + Create_User -d /opt/jackett jackett - Remove_SysV tor 1 + # Permissions + G_EXEC chown -R jackett:jackett /opt/jackett - # Tor config - cat << '_EOF_' > /etc/tor/torrc -Log notice stdout -VirtualAddrNetwork 10.192.0.0/10 -AutomapHostsSuffixes .onion,.exit -AutomapHostsOnResolve 1 -TransPort 192.168.42.1:9040 -DNSPort 192.168.42.1:53 -_EOF_ - # Flush IP tables - iptables -F - iptables -t nat -F + # Service: https://github.com/Jackett/Jackett/wiki/systemd-service + # - Wrap execution into shell to work around: https://github.com/Jackett/Jackett/issues/5208 + cat << '_EOF_' > /etc/systemd/system/jackett.service +[Unit] +Description=Jackett (DietPi) +Wants=network-online.target +After=network-online.target - # Generate tor prerouting tables - local wifi_iface=$(G_GET_NET -t wlan iface) - iptables -t nat -A PREROUTING -i "$wifi_iface" -p tcp --dport 22 -j REDIRECT --to-ports 22 - iptables -t nat -A PREROUTING -i "$wifi_iface" -p udp --dport 53 -j REDIRECT --to-ports 53 - iptables -t nat -A PREROUTING -i "$wifi_iface" -p tcp --syn -j REDIRECT --to-ports 9040 +[Service] +SyslogIdentifier=jackett +User=jackett +WorkingDirectory=/opt/jackett +Environment=XDG_CONFIG_HOME=/opt/jackett +ExecStart=/bin/dash -c '/opt/jackett/jackett --NoRestart; while pgrep -u jackett JackettUpdater > /dev/null; do sleep 1; done' +Restart=always +RestartSec=5 +TimeoutStopSec=30 - # Save IP tables - iptables-save > /etc/iptables.ipv4.nat +# Hardening +ProtectSystem=strict +ProtectHome=true +PrivateDevices=true +PrivateTmp=true +ProtectKernelTunables=true +ProtectControlGroups=true +ReadWritePaths=-/opt/jackett - # User: Test tor is functional - #https://check.torproject.org +[Install] +WantedBy=multi-user.target +_EOF_ + # - ARMv6 devices use Mono + (( $G_HW_ARCH == 1 )) && G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v mono) /opt/jackett/JackettConsole.exe --NoRestart" /etc/systemd/system/jackett.service fi - software_id=48 # Pydio + software_id=149 # NZBGet if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # PHP configuration - G_EXEC phpenmod apcu gd intl pdo_mysql dom mbstring xml + G_EXEC curl -sSfL 'https://nzbget.net/download/nzbget-latest-bin-linux.run' -o package.run + G_EXEC mkdir -p /mnt/dietpi_userdata/nzbget + G_EXEC_OUTPUT=1 G_EXEC dash package.run --destdir /mnt/dietpi_userdata/nzbget + G_EXEC_NOHALT=1 G_EXEC rm package.run - # Webserver config - # - Apache2 - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + # User + Create_User -g dietpi -d /mnt/dietpi_userdata/nzbget nzbget - # Enable Apache2 rewrite engine - a2enmod rewrite + # Permissions + G_EXEC chown -R nzbget:root /mnt/dietpi_userdata/nzbget + G_EXEC chmod 0600 /mnt/dietpi_userdata/nzbget/nzbget.conf - # Move Pydio Apache2 config in place - dps_index=$software_id Download_Install 'apache.pydio.conf' /etc/apache2/sites-available/dietpi-pydio.conf - a2ensite dietpi-pydio + # Config + G_BACKUP_FP /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'MainDir=' 'MainDir=/mnt/dietpi_userdata/downloads' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'DestDir=' 'DestDir=/mnt/dietpi_userdata/downloads/complete' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'LogFile=' 'LogFile=/var/log/nzbget.log' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ControlUsername=' 'ControlUsername=admin' /mnt/dietpi_userdata/nzbget/nzbget.conf + GCI_PASSWORD=1 G_CONFIG_INJECT 'ControlPassword=' "ControlPassword=$GLOBAL_PW" /mnt/dietpi_userdata/nzbget/nzbget.conf + + # Umask: https://github.com/MichaIng/DietPi/issues/1999 + G_CONFIG_INJECT 'UMask=' 'UMask=0002' /mnt/dietpi_userdata/nzbget/nzbget.conf + + # Optimisations + G_CONFIG_INJECT 'Server1.Cipher=' 'Server1.Cipher=RC4-MD5' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'CrcCheck=' 'CrcCheck=no' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ParScan=' 'ParScan=limited' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ParThreads=' "ParThreads=$G_HW_CPU_CORES" /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'DebugTarget=' 'DebugTarget=none' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'CrashTrace=' 'CrashTrace=no' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'DetailTarget=' 'DetailTarget=none' /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ParBuffer=' "ParBuffer=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'ArticleCache=' "ArticleCache=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf + G_CONFIG_INJECT 'WriteBuffer=' "WriteBuffer=$(Optimise_BitTorrent 0)" /mnt/dietpi_userdata/nzbget/nzbget.conf + + # Service + cat << '_EOF_' > /etc/systemd/system/nzbget.service +[Unit] +Description=NZBGet (DietPi) + +[Service] +Type=forking +User=nzbget +WorkingDirectory=/mnt/dietpi_userdata/nzbget +ExecStart=/mnt/dietpi_userdata/nzbget/nzbget -D + +[Install] +WantedBy=multi-user.target +_EOF_ + fi + + software_id=155 # HTPC Manager + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing - # - Lighttpd - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + local url='https://github.com/HTPC-Manager/HTPC-Manager.git' + G_CHECK_URL "$url" - # Enable Lighttpd setenv, access and rewrite modules - G_CONFIG_INJECT '"mod_access",' ' "mod_access",' /etc/lighttpd/lighttpd.conf '"mod_.+",' - G_CONFIG_INJECT '"mod_setenv",' ' "mod_setenv",' /etc/lighttpd/lighttpd.conf '"mod_.+",' + # Python build dependencies for ARM + (( $G_HW_ARCH < 10 )) && G_AGI libffi-dev libssl-dev zlib1g-dev libjpeg-dev - # Move Pydio Lighttpd config in place - dps_index=$software_id Download_Install 'lighttpd.pydio.conf' /etc/lighttpd/conf-available/99-dietpi-pydio.conf - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod rewrite dietpi-pydio + if [[ -d '/mnt/dietpi_userdata/htpc-manager/.git' ]]; then - # - Nginx - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + G_EXEC cd /mnt/dietpi_userdata/htpc-manager + G_EXEC_OUTPUT=1 G_EXEC git remote set-url origin "$url" + G_EXEC_OUTPUT=1 G_EXEC git fetch origin + G_EXEC_OUTPUT=1 G_EXEC git reset --hard origin + G_EXEC_OUTPUT=1 G_EXEC git clean -dxfe '/userdata' - # Move Pydio Nginx config in place - dps_index=$software_id Download_Install 'nginx.pydio.conf' /etc/nginx/sites-dietpi/dietpi-pydio.conf + else + + G_EXEC_OUTPUT=1 G_EXEC git clone --depth 1 "$url" + G_EXEC mkdir -p /mnt/dietpi_userdata/htpc-manager + G_EXEC cp -a HTPC-Manager/. /mnt/dietpi_userdata/htpc-manager/ + G_EXEC_NOHALT=1 G_EXEC rm -R HTPC-Manager + G_EXEC cd /mnt/dietpi_userdata/htpc-manager + G_EXEC_OUTPUT=1 G_EXEC git reset --hard origin + G_EXEC_OUTPUT=1 G_EXEC git clean -dxfe '/userdata' fi - # Create MySQL DB - /boot/dietpi/func/create_mysql_db pydio pydio "$GLOBAL_PW" + # Python deps + G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur requirements.txt - # Setup Data directory - # - Skip if already existent - local target_data_dir=/mnt/dietpi_userdata/pydio_data - if [[ -d $target_data_dir ]]; then + # Service + cat << _EOF_ > /etc/systemd/system/htpc-manager.service +[Unit] +Description=HTPC Manager (DietPi) +Wants=network-online.target +After=network-online.target - G_DIETPI-NOTIFY 2 "Existing $target_data_dir found, will migrate..." - [[ -e '/var/www/pydio/data' ]] && rm -R /var/www/pydio/data +[Service] +SyslogIdentifier=HTPC Manager +ExecStart=$(command -v python3) -OO /mnt/dietpi_userdata/htpc-manager/Htpc.py - else +[Install] +WantedBy=multi-user.target +_EOF_ + fi - # - Move data structure - [[ -e $target_data_dir ]] && rm -R $target_data_dir - mv /var/www/pydio/data $target_data_dir + software_id=153 # OctoPrint + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then + Banner_Installing + # Stretch: Install Python 2 development tools since OctoPrint does not support Python 3.5 + local pip='pip3' + if (( $G_DISTRO < 5 )) + then + G_AGI python-{pip,dev} + G_EXEC_OUTPUT=1 G_EXEC pip2 install -U pip setuptools wheel + pip='pip2' fi - # Create symlink - ln -sf $target_data_dir /var/www/pydio/data - chown -R www-data:www-data $target_data_dir - - fi + # Pre-create user and its home directory to allow user-level Python instance + Create_User -G dialout,tty,video -d /mnt/dietpi_userdata/octoprint octoprint + [[ -d '/mnt/dietpi_userdata/octoprint' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/octoprint + G_EXEC chown -R octoprint:octoprint /mnt/dietpi_userdata/octoprint - software_id=65 # Netdata - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Clear pip cache in case it got somehow created + [[ -d '/mnt/dietpi_userdata/octoprint/.cache' ]] && G_EXEC rm -R /mnt/dietpi_userdata/octoprint/.cache - Banner_Configuration + # Install OctoPrint + G_EXEC_OUTPUT=1 G_EXEC sudo -u octoprint $pip install -U --no-cache-dir --user octoprint + unset -v pip - # Only required for our self-compiled package, leave defaults for Debian APT package otherwise - if (( $G_HW_ARCH == 1 && $G_DISTRO < 5 )); then + # Service: https://github.com/OctoPrint/OctoPrint/blob/master/scripts/octoprint.service + cat << '_EOF_' > /etc/systemd/system/octoprint.service +[Unit] +Description=OctoPrint (DietPi) +Documentation=https://dietpi.com/docs/software/printing/#octoprint +Wants=network-online.target +After=network-online.target mjpg-streamer.service - # Service - dps_index=$software_id Download_Install 'netdata.service' /etc/systemd/system/netdata.service +[Service] +Environment="LC_ALL=C.UTF-8" "LANG=C.UTF-8" +User=octoprint +ExecStart=/mnt/dietpi_userdata/octoprint/.local/bin/octoprint serve - # Dir (failsafe) - mkdir -p /var/lib/netdata +[Install] +WantedBy=multi-user.target +_EOF_ + # CLI alias + echo "alias octoprint='sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint'" > /etc/bashrc.d/dietpi-octoprint.sh - # User - Create_User -d /var/lib/netdata netdata + # On fresh installs, change listening port to 5001 to avoid conflict with Shairport Sync. + [[ -f '/mnt/dietpi_userdata/octoprint/.octoprint/config.yaml' ]] || G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.port '5001' - # 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 - # - apps.plugin requires root privileges to read disk I/O - 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 + # Apply service and system commands: Allow execution via specific sudoers config + echo "octoprint ALL=NOPASSWD: $(command -v systemctl) restart octoprint, $(command -v reboot), $(command -v poweroff)" > /etc/sudoers.d/octoprint + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.serverRestartCommand 'sudo systemctl restart octoprint' + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.systemRestartCommand 'sudo reboot' + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.systemShutdownCommand 'sudo poweroff' + # mjpg-streamer: Configure OctoPrint to use it, if installed + if (( ${aSOFTWARE_INSTALL_STATE[137]} > 0 )) + then + G_DIETPI-NOTIFY 2 'Configuring OctoPrint to use mjpg-streamer for webcam support' + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.stream "http://$(G_GET_NET ip):8082/?action=stream" + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.snapshot 'http://127.0.0.1:8082/?action=snapshot' + G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.ffmpeg "$(command -v ffmpeg)" fi - fi - software_id=57 # Baïkal - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration + software_id=187 # CUPS + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then + Banner_Installing - # Enable required PHP modules: https://github.com/sabre-io/Baikal/wiki/Baïkal-dependencies - G_EXEC phpenmod xml mbstring pdo_mysql + # Download base configuration if it does not exist yet + [[ -f '/etc/cups/cupsd.conf' ]] || dps_index=$software_id Download_Install 'cupsd.conf' /etc/cups/cupsd.conf - # Database - /boot/dietpi/func/create_mysql_db baikal baikal "$GLOBAL_PW" + G_AGI cups - # Web server configs: http://sabre.io/baikal/install/ + https://github.com/bambocher/docker-baikal/blob/master/lighttpd.conf - # - Apache - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + G_EXEC chown root:lp /etc/cups/ /etc/cups/ppd/ /etc/cups/ssl/ + fi - dps_index=$software_id Download_Install 'apache.baikal.conf' /etc/apache2/sites-available/dietpi-baikal.conf - a2ensite dietpi-baikal - echo '# Redirect Cal/CardDAV requests to Baïkal endpoint: -Redirect 301 /.well-known/carddav /baikal/html/dav.php -Redirect 301 /.well-known/caldav /baikal/html/dav.php' > /etc/apache2/conf-available/dietpi-dav_redirect.conf - a2enconf dietpi-dav_redirect + software_id=154 # Roon Server + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # - Lighttpd - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + Banner_Installing # https://help.roonlabs.com/portal/en/kb/articles/linux-install#Downloads - dps_index=$software_id Download_Install 'lighttpd.baikal.conf' /etc/lighttpd/conf-available/99-dietpi-baikal.conf - echo '# Redirect Cal/CardDAV requests to Baïkal endpoint: -url.redirect += ( - "^/.well-known/caldav" => "/baikal/html/dav.php", - "^/.well-known/carddav" => "/baikal/html/dav.php" -)' > /etc/lighttpd/conf-available/99-dietpi-dav_redirect.conf - G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already - G_EXEC lighty-enable-mod dietpi-baikal dietpi-dav_redirect + # .NET dependency: https://packages.microsoft.com/debian/ + if (( $G_DISTRO < 5 )) + then + DEPS_LIST='libicu57' - # - Nginx - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + elif (( $G_DISTRO == 5 )) + then + DEPS_LIST='libicu63' + else + DEPS_LIST='libicu67' + fi - dps_index=$software_id Download_Install 'nginx.baikal.conf' /etc/nginx/sites-dietpi/dietpi-baikal.conf - # shellcheck disable=SC2016 - echo '# Redirect Cal/CardDAV requests to Baïkal endpoint: -location = /.well-known/carddav { return 301 /baikal/html/dav.php; } -location = /.well-known/caldav { return 301 /baikal/html/dav.php; }' > /etc/nginx/sites-dietpi/dietpi-dav_redirect.conf + # Skip download and install, if already existent, manual removal or internal updater can be used: + if [[ -d '/opt/roonserver' ]] + then + G_AGI $DEPS_LIST + DEPS_LIST= + G_DIETPI-NOTIFY 2 "Existing install found\n +The ${aSOFTWARE_NAME[$software_id]} target install directory /opt/roonserver already exists. This will not be overwritten.\n +If the existing instance is broken or obsolete, please manually backup config files and data, then remove this directory and rerun \"dietpi-software\".\n +If you want to update ${aSOFTWARE_NAME[$software_id]}, please use its internal updater." + else + Download_Install 'https://download.roonlabs.com/builds/RoonServer_linuxx64.tar.bz2' + G_EXEC mv RoonServer /opt/roonserver fi - # Permissions - G_EXEC chown -R www-data:root /var/www/baikal/{Specific,config} - G_EXEC find /var/www/baikal/{Specific,config} \( -name '.ht*' -o -name '.git*' \) -exec chown root {} + + # Data dir + [[ -d '/mnt/dietpi_userdata/roonserver' ]] || G_EXEC mkdir /mnt/dietpi_userdata/roonserver - fi + # Service + cat << '_EOF_' > /etc/systemd/system/roonserver.service +[Unit] +Description=Roon Server (DietPi) +Wants=network-online.target +After=network-online.target - software_id=43 # Mumble Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then +[Service] +SyslogIdentifier=roonserver +Environment=ROON_DATAROOT=/mnt/dietpi_userdata/roonserver +#Environment=ROON_ID_DIR=/mnt/dietpi_userdata/roonserver +Group=dietpi +ExecStart=/opt/roonserver/start.sh + +[Install] +WantedBy=multi-user.target +_EOF_ + Download_Test_Media - Banner_Configuration + fi - # Cap total connections - local max_users=$(( $G_HW_CPU_CORES * 8 )) - sed -i "/users=/c\users=$max_users" /etc/mumble-server.ini + software_id=156 # Steam + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # Name the root channel - sed -i '/registerName=/c\registerName=DietPi Mumble Server' /etc/mumble-server.ini + Banner_Installing - # Disable DB logging - sed -i '/logdays=/c\logdays=-1' /etc/mumble-server.ini + # Allow non-interactive install + G_EXEC eval "debconf-set-selections <<< 'steam steam/question select I AGREE'" - # Set Superuser passwd: https://dietpi.com/phpbb/viewtopic.php?p=8084#p8084 - murmurd -ini /etc/mumble-server.ini -supw "$GLOBAL_PW" + # x86_64: Install Debian i386 package + if [[ $G_HW_ARCH == 10 ]] + then + # Add i386 arch: https://packages.debian.org/bullseye/steam + [[ $(dpkg --print-foreign-architectures) == *'i386'* ]] || { G_EXEC dpkg --add-architecture i386; G_AGUP; } + # Add Nvidia i386 driver libs, if Nvidia driver is detected + local nvidia + [[ -e '/sys/module/nvidia/version' ]] && nvidia='nvidia-driver-libs:i386' + G_AGI steam $nvidia - fi + # ARM: Install repacked Debian i386 package for armhf + elif [[ $G_HW_ARCH == 2 ]] + then + Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/steam_$G_HW_ARCH_NAME.deb" + fi - software_id=41 # Emby Server - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Move data dir to dietpi_userdata + if [[ -d '/mnt/dietpi_userdata/steam' ]] + then + G_EXEC rm -Rf /root/.steam - Banner_Configuration + elif [[ -d '/root/.steam' ]] + then + G_EXEC mv /root/.steam /mnt/dietpi_userdata/steam - # 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 + else + G_EXEC mkdir -p /mnt/dietpi_userdata/steam + fi + G_EXEC ln -s /mnt/dietpi_userdata/steam /root/.steam - Download_Test_Media + # Desktop shortcut + Create_Desktop_Shortcut steam fi - software_id=42 # Plex Media Server + software_id=158 # MinIO if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - - # 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 - # - Unset explicit group in service file (applied by DEB package) as this may override supplementary group permissions - G_EXEC mkdir -p /etc/systemd/system/plexmediaserver.service.d - echo -e '[Service]\nGroup=' > /etc/systemd/system/plexmediaserver.service.d/dietpi-group.conf - - # Unbound: Fix secure remote access: https://dietpi.com/phpbb/viewtopic.php?t=8896 - (( ${aSOFTWARE_INSTALL_STATE[182]} == 2 )) && echo -e 'server:\n\tprivate-domain: "plex.direct"' > /etc/unbound/unbound.conf.d/dietpi-plex.conf + Banner_Installing - Download_Test_Media + # ARMv6/7 + local url='https://dl.minio.io/server/minio/release/linux-arm/minio' - fi + # ARMv8 + if (( $G_HW_ARCH == 3 )); then - software_id=53 # MineOS - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then - Banner_Configuration + url='https://dl.minio.io/server/minio/release/linux-arm64/minio' - # Config: Preserve existing - [[ -f '/etc/mineos.conf' ]] || G_EXEC cp /mnt/dietpi_userdata/mineos/minecraft/mineos.conf /etc/mineos.conf + # x86_64 + elif (( $G_HW_ARCH == 10 )); then - # Create symlinks for console and userdata dir - G_EXEC ln -sf /mnt/dietpi_userdata/mineos/minecraft/mineos_console.js /usr/local/bin/mineos - G_EXEC rm -Rf /var/games/minecraft - G_EXEC mkdir -p /var/games /mnt/dietpi_userdata/mineos/serverdata - G_EXEC ln -s /mnt/dietpi_userdata/mineos/serverdata /var/games/minecraft + url='https://dl.minio.io/server/minio/release/linux-amd64/minio' - # Setup SSL cert - G_EXEC cd /mnt/dietpi_userdata/mineos/minecraft - G_EXEC_OUTPUT=1 G_EXEC ./generate-sslcert.sh - G_EXEC cd /tmp/$G_PROGRAM_NAME + fi + G_EXEC curl -sSfLo /usr/local/bin/minio "$url" + G_EXEC chmod +x /usr/local/bin/minio # Service - cat << _EOF_ > /etc/systemd/system/mineos.service -[Unit] -Description=MineOS (DietPi) -Wants=network-online.target -After=network-online.target + G_EXEC curl -sSfLo /etc/systemd/system/minio.service 'https://github.com/minio/minio-service/raw/master/linux-systemd/minio.service' -[Service] -WorkingDirectory=/mnt/dietpi_userdata/mineos/minecraft -Environment="SHELL=/bin/bash" "HOME=/root" -SyslogIdentifier=MineOS -ExecStart=$(command -v node) webui.js -KillMode=process + # User + Create_User -d /mnt/dietpi_userdata/minio-data minio-user -[Install] -WantedBy=multi-user.target + # Data dir + G_EXEC mkdir -p /mnt/dietpi_userdata/minio-data + G_EXEC chown -R minio-user:minio-user /mnt/dietpi_userdata/minio-data + + # Config + [[ -f '/etc/default/minio' ]] || cat << '_EOF_' > /etc/default/minio +# Default file path +MINIO_VOLUMES="/mnt/dietpi_userdata/minio-data" +# Use if you want to run MinIO on a custom port. +#MINIO_OPTS="--address :9199" +# Access key of the server. +#MINIO_ACCESS_KEY=Server-Access-Key +# Secret key of the server. +#MINIO_SECRET_KEY=Server-Secret-Key _EOF_ fi - software_id=49 # Gogs + software_id=162 # Docker if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # User - Create_User -d /etc/gogs gogs + # Detect distro + local distro='debian' + (( $G_HW_MODEL < 10 )) && (( $G_RASPBIAN )) && distro='raspbian' - # Directories + permissions - G_EXEC mkdir -p /mnt/dietpi_userdata/gogs-repo /var/log/gogs - G_EXEC chown -R gogs:gogs /etc/gogs /mnt/dietpi_userdata/gogs-repo /var/log/gogs + # APT key + G_EXEC eval "curl -sSfL 'https://download.docker.com/linux/$distro/gpg' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-docker.gpg --yes" - # Database - if [[ ! -d '/var/lib/mysql/gogs' ]]; then + # APT list + G_EXEC eval "echo 'deb https://download.docker.com/linux/$distro/ ${G_DISTRO_NAME/bookworm/bullseye} stable' > /etc/apt/sources.list.d/docker.list" + G_AGUP - 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'" + # APT package + G_AGI docker-ce + + # 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 + G_EXEC eval "echo -e '[Service]\nType=simple' > /lib/systemd/system/docker.service.d/dietpi-simple.conf" + + # Config: https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file + # - Move Docker containers to dietpi_userdata + # - Log to systemd-journald (journalctl) by default with reduced log level: https://github.com/MichaIng/DietPi/issues/2388 + # + containerd: https://github.com/docker/docker.github.io/issues/9091 + [[ -d '/mnt/dietpi_userdata/docker-data' ]] || G_EXEC mkdir /mnt/dietpi_userdata/docker-data + if [[ -f '/etc/docker/daemon.json' ]] + then + GCI_PRESERVE=1 G_CONFIG_INJECT '"data-root":' ' "data-root": "/mnt/dietpi_userdata/docker-data",' /etc/docker/daemon.json '^\{([[:space:]]|$)' + GCI_PRESERVE=1 G_CONFIG_INJECT '"log-driver":' ' "log-driver": "journald",' /etc/docker/daemon.json '^\{([[:space:]]|$)' + GCI_PRESERVE=1 G_CONFIG_INJECT '"log-level":' ' "log-level": "warn",' /etc/docker/daemon.json '^\{([[:space:]]|$)' + GCI_PRESERVE=1 G_CONFIG_INJECT '"debug":' ' "debug": false,' /etc/docker/daemon.json '^\{([[:space:]]|$)' + else + [[ -d '/etc/docker' ]] || G_EXEC mkdir /etc/docker + echo '{ + "data-root": "/mnt/dietpi_userdata/docker-data", + "log-driver": "journald", + "log-level": "warn", + "debug": false +}' > /etc/docker/daemon.json + fi + G_CONFIG_INJECT '\[debug\]' '[debug]' /etc/containerd/config.toml + GCI_PRESERVE=1 G_CONFIG_INJECT 'level[[:blank:]]*=' ' level = "warn"' /etc/containerd/config.toml '^\[debug\]' + # Enable cgroups used by Docker and alike + if [[ -f '/boot/boot.cmd' ]] && grep -q 'docker_optimizations' /boot/boot.cmd + then + # Armbian + [[ -f '/boot/armbianEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/armbianEnv.txt + # Radxa Zero + [[ -f '/boot/uEnv.txt' ]] && G_CONFIG_INJECT 'docker_optimizations=' 'docker_optimizations=on' /boot/uEnv.txt fi - # Service: https://github.com/gogs/gogs/blob/main/scripts/systemd/gogs.service - cat << '_EOF_' > /etc/systemd/system/gogs.service -[Unit] -Description=Gogs (DietPi) -Wants=network-online.target -After=network-online.target mariadb.service + fi -[Service] -User=gogs -WorkingDirectory=/etc/gogs -ExecStart=/etc/gogs/gogs web + software_id=134 # Docker Compose + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then -# Hardening -ProtectSystem=full -PrivateDevices=yes -PrivateTmp=yes -NoNewPrivileges=true -ReadWritePaths=-/etc/gogs + Banner_Installing + + # Python build dependencies for aarch64 + # - libffi-dev additionally required on Stretch: https://dietpi.com/phpbb/viewtopic.php?p=34293#p34293 + local apackages=('make' 'gcc') + (( $G_DISTRO < 5 )) && apackages+=('libffi-dev') + (( $G_HW_ARCH == 3 )) && G_AGI "${apackages[@]}" + unset -v apackages + + G_EXEC_OUTPUT=1 G_EXEC pip3 install docker-compose -[Install] -WantedBy=multi-user.target -_EOF_ fi - software_id=107 # rTorrent + software_id=161 # FuguHub if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - - # ruTorrent: Enable HTTP authentication and RPC - # - Apache2 - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then + Banner_Installing - # Enable SCGI module - G_EXEC a2enmod auth_basic authn_file authz_user proxy_scgi + # ARM + local url='https://fuguhub.com/releases/raspberrypi/install.sh' - # Enable HTTP authentication and rTorrent access via SCGI - [[ -f '/etc/.rutorrent-htaccess' ]] || htpasswd -cb /etc/.rutorrent-htaccess root "$GLOBAL_PW" - cat << '_EOF_' > /etc/apache2/sites-available/dietpi-rutorrent.conf - - AllowOverride All - AuthType Basic - AuthName "ruTorrent login" - AuthBasicProvider file - AuthUserFile "/etc/.rutorrent-htaccess" - Require valid-user - - - AuthType Basic - AuthName "rTorrent login" - AuthBasicProvider file - AuthUserFile "/etc/.rutorrent-htaccess" - Require valid-user - -ProxyPass "/RPC2" "scgi:///mnt/dietpi_userdata/downloads/.session/rpc.socket" -_EOF_ - G_EXEC a2ensite dietpi-rutorrent + # x86_64 + (( $G_HW_ARCH == 10 )) && url='https://fuguhub.com/install/FuguHub.linux.install' - # - Lighttpd - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + Download_Install "$url" FuguHubInstall.sh - [[ -f '/etc/.rutorrent-htaccess' ]] || echo "root:rtorrent:$(echo -n "root:rtorrent:$GLOBAL_PW" | md5sum | mawk '{print $1}')" > /etc/.rutorrent-htaccess + G_EXEC chmod +x FuguHubInstall.sh + G_EXEC_OUTPUT=1 G_EXEC ./FuguHubInstall.sh + G_EXEC_NOHALT=1 G_EXEC rm FuguHubInstall.sh - # Pre-v7.2: Remove obsolete entries from /etc/lighttpd/lighttpd.conf - grep -q '^#RUTORRENT_DIETPI' /etc/lighttpd/lighttpd.conf && G_EXEC sed -i '/#RUTORRENT_DIETPI/,/#RUTORRENT_DIETPI/d' /etc/lighttpd/lighttpd.conf + G_EXEC curl -sSfL 'https://fuguhub.com/box.zip' -o /home/bd/applications/box.zip - 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 -auth.backend = "htdigest" -auth.backend.htdigest.userfile = "/etc/.rutorrent-htaccess" -auth.require = ( "/rutorrent" => - ( - "method" => "digest", - "realm" => "rtorrent", - "require" => "valid-user" - ), - "/RPC2" => - ( - "method" => "digest", - "realm" => "rtorrent", - "require" => "valid-user" - ) -) -scgi.server = ( "/RPC2" => - ( "rtorrent" => - ( - "socket" => "/mnt/dietpi_userdata/downloads/.session/rpc.socket", - "check-local" => "disable" - ) - ) -) -$HTTP["url"] =~ "^/rutorrent/(conf|share)($|/)" { - url.access-deny = ("") -} -_EOF_ - [[ -f '/etc/lighttpd/conf-enabled/98-dietpi-rtorrent.conf' ]] || G_EXEC lighty-enable-mod dietpi-rtorrent + # Setup Filestore DietPi appropriate + # IF already present just create symlink + if [[ ! -d '/mnt/dietpi_userdata/fuguhub-data' ]]; then - # - Nginx - elif (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + # Move installed filestore to dietpi userdata + G_EXEC mkdir -p /mnt/dietpi_userdata/fuguhub-data + G_EXEC mv /home/bd/disk/* /mnt/dietpi_userdata/fuguhub-data/ + # Set permissions + G_EXEC chown -R bd:bd /mnt/dietpi_userdata/fuguhub-data/ + #setfacl -R -m u:bd:rwx /mnt/dietpi_userdata/fuguhub-data/ - # "openssl passwd -5" (sha256, even "-6" sha512) can be used from Buster on. - [[ -f '/etc/.rutorrent-htaccess' ]] || echo "root:$(openssl passwd -apr1 "$GLOBAL_PW")" > /etc/.rutorrent-htaccess - cat << '_EOF_' > /etc/nginx/sites-dietpi/dietpi-rutorrent.conf -location ^~ /rutorrent { - auth_basic "ruTorrent login"; - auth_basic_user_file /etc/.rutorrent-htaccess; - location ~ ^/rutorrent/(?:conf|share)(?:/|$) { return 404; } -} -location ^~ /RPC2 { - auth_basic "rTorrent login"; - auth_basic_user_file /etc/.rutorrent-htaccess; - include scgi_params; - scgi_pass unix:/mnt/dietpi_userdata/downloads/.session/rpc.socket; -} -_EOF_ fi - G_EXEC chmod 0400 /etc/.rutorrent-htaccess - G_EXEC chown www-data:www-data /etc/.rutorrent-htaccess + # Removed 'actual' folder to make way for symlink + G_EXEC rm -Rf /home/bd/disk + # Create symlink + G_EXEC ln -s /mnt/dietpi_userdata/fuguhub-data /home/bd/disk - # ruTorrent config - # shellcheck disable=SC2016 - G_CONFIG_INJECT '\$scgi_port[[:blank:]]' ' $scgi_port = 0;' /var/www/rutorrent/conf/config.php - # shellcheck disable=SC2016 - G_CONFIG_INJECT '\$scgi_host[[:blank:]]' ' $scgi_host = "unix:///mnt/dietpi_userdata/downloads/.session/rpc.socket";' /var/www/rutorrent/conf/config.php - G_CONFIG_INJECT '"curl"[[:blank:]]' ' "curl" => "/usr/bin/curl",' /var/www/rutorrent/conf/config.php + fi - # Session dir - G_EXEC mkdir -p /mnt/dietpi_userdata/downloads/.session + software_id=164 # Nukkit + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # User - Create_User -g dietpi -d /mnt/dietpi_userdata/rtorrent rtorrent + Banner_Installing + + Download_Install 'https://ci.nukkitx.com/job/NukkitX/job/Nukkit/job/master/lastStableBuild/artifact/target/nukkit-1.0-SNAPSHOT.jar' /usr/local/bin/nukkit/nukkit.jar + + # Config + [[ -f '/usr/local/bin/nukkit/nukkit.yml ' ]] || G_EXEC curl -sSfL 'https://github.com/Nukkit/Languages/raw/master/eng/nukkit.yml' -o /usr/local/bin/nukkit/nukkit.yml # Service - cat << _EOF_ > /etc/systemd/system/rtorrent.service + cat << '_EOF_' > /etc/systemd/system/nukkit.service [Unit] -Description=rTorrent (DietPi) -Wants=network-online.target -After=network-online.target +Description=nukkit (DietPi) [Service] -Type=forking -User=rtorrent -ExecStart=$(command -v screen) -fa -dmS rtorrent $(command -v rtorrent) -ExecStop=$(command -v screen) -S rtorrent -X quit -KillMode=none +SyslogIdentifier=Nukkit +WorkingDirectory=/usr/local/bin/nukkit +ExecStart=/bin/bash -c 'java -jar /usr/local/bin/nukkit/nukkit.jar' [Install] WantedBy=multi-user.target _EOF_ - # Since Buster we use new daemon mode - if (( $G_DISTRO > 4 )); then + fi - G_EXEC sed -Ei '/^(Type|KillMode|ExecStop)=/d' /etc/systemd/system/rtorrent.service - G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v rtorrent)" /etc/systemd/system/rtorrent.service + software_id=165 # Gitea + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - fi + Banner_Installing - # rTorrent config: Do not overwrite if existent - # - Example: https://github.com/rakshasa/rtorrent/blob/master/doc/rtorrent.rc - # - 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 - 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 - else - cat << _EOF_ > /mnt/dietpi_userdata/rtorrent/.rtorrent.rc -### Miscellaneous settings -#system.daemon.set = true -# Default download dir -directory.default.set = /mnt/dietpi_userdata/downloads -# Session dir -session.path.set = /mnt/dietpi_userdata/downloads/.session -# Save session every 5 minutes -schedule2 = session_save, 240, 300, ((session.save)) -# Close torrents on low diskspace, check every minute -schedule2 = monitor_diskspace, 15, 60, ((close_low_diskspace, 1000M)) -system.umask.set = 002 -# Max memory mapping size, not max physical RAM usage! -pieces.memory.max.set = ${RAM_PHYS}M -pieces.hash.on_completion.set = no + # Binary + data dir + [[ -d '/mnt/dietpi_userdata/gitea/gitea-repositories' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/gitea/gitea-repositories -### Connection settings -# Incoming connection ports -network.port_open.set = no -network.port_random.set = no -#network.port_range.set = 33101-33199 -# 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 + # 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' -### Network limits -network.http.max_open.set = $(Optimise_BitTorrent 2) -network.max_open_files.set = $(( $(Optimise_BitTorrent 2) * 2 )) -network.max_open_sockets.set = $(Optimise_BitTorrent 2) -# Global max download/upload rate in KiB, "0" for unlimited -throttle.global_down.max_rate.set_kb = 0 -throttle.global_up.max_rate.set_kb = 0 + # ARMv8 + if (( $G_HW_ARCH == 3 )); then + + arch='arm64' + + # x86_64 + elif (( $G_HW_ARCH == 10 )); then + + arch='amd64' -### Peer settings -# Max downloads/uploads accross all torrents -throttle.max_downloads.global.set = $(Optimise_BitTorrent 2) -throttle.max_uploads.global.set = $(Optimise_BitTorrent 2) -# Max downloads/uploads per torrent -throttle.max_downloads.set = $(( $(Optimise_BitTorrent 2) / 2 )) -throttle.max_uploads.set = $(( $(Optimise_BitTorrent 2) / 2 )) -# Min/Max connected peers -throttle.min_peers.normal.set = $(( $(Optimise_BitTorrent 2) - 1)) -throttle.max_peers.normal.set = $(Optimise_BitTorrent 2) -throttle.min_peers.seed.set = -1 -throttle.max_peers.seed.set = -1 -trackers.numwant.set = $(Optimise_BitTorrent 2) -# Public tracker support -trackers.use_udp.set = yes -dht.mode.set = on -#dht.port.set = 6881 -protocol.pex.set = yes -protocol.encryption.set = allow_incoming,try_outgoing,enable_retry -_EOF_ fi - # Since Buster use new daemon mode - (( $G_DISTRO > 4 )) && G_CONFIG_INJECT 'system.daemon.set[[:blank:]=]' 'system.daemon.set = true' /mnt/dietpi_userdata/rtorrent/.rtorrent.rc + local fallback_url="https://github.com/go-gitea/gitea/releases/download/v1.15.0/gitea-1.15.0-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 -p /var/log/gitea # Permissions - G_EXEC chown -R rtorrent:dietpi /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 root:root /var/www/rutorrent/share/.htaccess + G_EXEC chown -R dietpi:dietpi /var/log/gitea /mnt/dietpi_userdata/gitea + G_EXEC chmod +x /mnt/dietpi_userdata/gitea/gitea - fi + # Database + /boot/dietpi/func/create_mysql_db gitea gitea "$GLOBAL_PW" - software_id=132 # Aria2 - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Service + cat << '_EOF_' > /etc/systemd/system/gitea.service +[Unit] +Description=Gitea (DietPi) - Banner_Configuration +[Service] +User=dietpi +WorkingDirectory=/mnt/dietpi_userdata/gitea/gitea-repositories +Environment=USER=dietpi HOME=/mnt/dietpi_userdata/gitea +ExecStart=/mnt/dietpi_userdata/gitea/gitea web - # User - Create_User -g dietpi -d /mnt/dietpi_userdata/aria2 aria2 +[Install] +WantedBy=multi-user.target +_EOF_ + fi - # Config - mkdir -p /mnt/dietpi_userdata/aria2 - [[ -f '/mnt/dietpi_userdata/aria2/aria2.conf' ]] || cat << _EOF_ > /mnt/dietpi_userdata/aria2/aria2.conf -# DietPi default aria2c options served as aria2.conf file via --conf-path -# https://aria2.github.io/manual/en/html/aria2c.html#options + software_id=159 # Allo web UI: 160 for quick reinstall + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 || ${aSOFTWARE_INSTALL_STATE[160]} == 1 )); then -# Logging -log=/var/log/aria2.log -log-level=warn + Banner_Installing -# Session -always-resume=true -continue=true -input-file=/mnt/dietpi_userdata/downloads/aria2.session -save-session=/mnt/dietpi_userdata/downloads/aria2.session -save-session-interval=60 + # Always perform a clean reinstall + [[ -d '/var/www/allo' ]] && G_EXEC rm -R /var/www/allo + Download_Install 'https://dietpi.com/downloads/binaries/all/allo_web_interface_v13.3.7z' /var/www -# Connection -listen-port=6881-6999 -ftp-pasv=true -check-certificate=false -# - Count -max-concurrent-downloads=$(Optimise_BitTorrent 1) -split=$(Optimise_BitTorrent 1) -max-connection-per-server=$(Optimise_BitTorrent 1) -bt-max-peers=$(Optimise_BitTorrent 2) -# - Bandwidth -max-overall-upload-limit=0 -max-upload-limit=0 -max-overall-download-limit=0 -max-download-limit=0 -# - Retries -max-file-not-found=3 -max-tries=5 -retry-wait=60 + # Create allo user for GUI + Create_User -G www-data -d /home/allo -s /bin/bash -p allo allo + # - Create home dir separately to avoid skeleton creation + [[ -d '/home/allo' ]] || G_EXEC mkdir -p /home/allo + G_EXEC chown -R allo:allo /home/allo + # - Grant sudo permissions + echo 'allo ALL=NOPASSWD: ALL' > /etc/sudoers.d/allo -# RPC -enable-rpc=true -rpc-listen-all=true -rpc-listen-port=6800 -rpc-secret=$GLOBAL_PW -rpc-allow-origin-all=true -pause=false + # Always Drop DB, and, recreate it, due to error issue with reinstall over the top. + G_EXEC systemctl restart mariadb + mysqladmin drop allo_db -f &> /dev/null + mysql -e 'drop user allo_db@localhost' &> /dev/null -# Store -dir=/mnt/dietpi_userdata/downloads -allow-overwrite=false -auto-file-renaming=false -file-allocation=none -check-integrity=true + /boot/dietpi/func/create_mysql_db allo_db allo_db dietpi + mysql allo_db < /var/www/allo_db.sql + G_EXEC rm /var/www/allo_db.sql -# Seeding -seed-ratio=0.1 -seed-time=0 + # Redirect to web interface by default: + rm -f /var/www/index\.* + cat << '_EOF_' > /var/www/index.php + _EOF_ + # Permissions + G_EXEC chown -R www-data:www-data /var/www/allo + G_EXEC chmod -R 0770 /var/www/allo + + fi + + software_id=163 # GMediaRender + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # Pre-create log file - local fp_log=$(sed -n '/^[[:blank:]]*log=/{s/^[^=]*=//p;q}' /mnt/dietpi_userdata/aria2/aria2.conf) - [[ ${fp_log//\"} && ! -f $fp_log ]] && >> "$fp_log" + Banner_Installing - # Pre-create input file - local fp_input=$(sed -n '/^[[:blank:]]*input-file=/{s/^[^=]*=//p;q}' /mnt/dietpi_userdata/aria2/aria2.conf) - [[ ${fp_input//\"} && ! -f $fp_input ]] && >> "$fp_input" + # APT dependencies: https://github.com/hzeller/gmrender-resurrect/blob/master/INSTALL.md + (( $G_DISTRO < 5 )) && DEPS_LIST='libupnp6' || DEPS_LIST='libupnp13' + DEPS_LIST+=' gstreamer1.0-alsa gstreamer1.0-libav gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly' - # Permissions - chown -R aria2:root /mnt/dietpi_userdata/aria2 "$fp_input" - chown aria2:dietpi "$fp_log" - chmod 600 /mnt/dietpi_userdata/aria2/aria2.conf - unset -v fp_log fp_input + Download_Install "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/gmediarender_$G_HW_ARCH_NAME.7z" /usr/local/bin + G_EXEC chmod +x /usr/local/bin/gmediarender + + # Create dummy icons for now. ToDo: Add real icons, GMediaRender or DietPi ones, or disable via build options? + G_EXEC mkdir -p /usr/local/share/gmediarender + > /usr/local/share/gmediarender/grender-64x64.png + > /usr/local/share/gmediarender/grender-128x128.png + + # User + Create_User -G audio,render gmrender # Service - cat << _EOF_ > /etc/systemd/system/aria2.service + cat << _EOF_ > /etc/systemd/system/gmrender.service [Unit] -Description=Aria2 (DietPi) +Description=GMediaRender (DietPi) +Documentation=https://github.com/hzeller/gmrender-resurrect/blob/master/INSTALL.md#commandline-options +Wants=network-online.target +After=network-online.target sound.target [Service] -User=aria2 -UMask=002 -ExecStart=$(command -v aria2c) --conf-path=/mnt/dietpi_userdata/aria2/aria2.conf +User=gmrender +ExecStartPre=+/bin/bash -c '. /boot/dietpi/func/dietpi-globals; systemctl set-environment ACTIVE_IP=\$(G_GET_NET ip)' +ExecStart=/usr/local/bin/gmediarender -u '$G_HW_UUID' -f '$( /var/lib/dietpi/dietpi-software/installed/pi-spc/sds.sh +#!/bin/dash - # Run Syncthing to pre-create config dir and exit - G_EXEC_OUTPUT=1 G_EXEC sudo -u dietpi /opt/syncthing/syncthing -generate=/mnt/dietpi_userdata/syncthing +echo 'Audiophonics PI-SPC: Shutdown script starting... +Asserting pins: +Shutdown : GPIO17=in, Low +Boot OK : GPIO22=out, High +Soft Shutdown : GPIO04=out, Low' - # Allow remote access: https://docs.syncthing.net/users/faq.html#how-do-i-access-the-web-gui-from-another-computer - G_EXEC sed -i '\|:8384|c\
0.0.0.0:8384
' /mnt/dietpi_userdata/syncthing/config.xml +gpio -g mode 04 out +gpio -g write 04 0 +gpio -g mode 17 in +gpio -g write 17 0 +gpio -g mode 22 out +gpio -g write 22 1 - # Set default data directory - G_EXEC mkdir -p /mnt/dietpi_userdata/syncthing_data - G_EXEC chown -R dietpi:dietpi /mnt/dietpi_userdata/syncthing_data - sed -i '\| /etc/systemd/system/syncthing.service + cat << '_EOF_' > /etc/systemd/system/pi-spc.service [Unit] -Description=Syncthing (DietPi) -Wants=network-online.target -After=network-online.target -StartLimitIntervalSec=60 -StartLimitBurst=4 +Description=Audiophonics PI-SPC (DietPi) [Service] -User=dietpi -ExecStart=/opt/syncthing/syncthing -no-browser -no-restart -logflags=0 -home=/mnt/dietpi_userdata/syncthing -Restart=on-failure -RestartSec=1 -SuccessExitStatus=3 4 -RestartForceExitStatus=3 4 - -# Hardening -ProtectSystem=full -PrivateTmp=true -SystemCallArchitectures=native -MemoryDenyWriteExecute=true -NoNewPrivileges=true +StandardOutput=tty +ExecStart=/var/lib/dietpi/dietpi-software/installed/pi-spc/sds.sh [Install] WantedBy=multi-user.target _EOF_ - # Increase fs watcher limit: https://docs.syncthing.net/users/faq.html#how-do-i-increase-the-inotify-limit-to-get-my-filesystem-watcher-to-work - G_EXEC eval "echo 'fs.inotify.max_user_watches=204800' > /etc/sysctl.d/dietpi-syncthing.conf" + + # Alternative: Use native GPIO shutdown and poweroff device tree overlays + + # systemd-logind < dbus is required for the gpio-shutdown device tree overlay to trigger the shutdown. + #G_AGI dbus + #G_EXEC systemctl unmask systemd-logind + #G_EXEC systemctl start systemd-logind + + #G_CONFIG_INJECT 'dtoverlay=gpio-shutdown' 'dtoverlay=gpio-shutdown,gpio_pin=17,active_low=0,gpio_pull=down' /boot/config.txt + #G_CONFIG_INJECT 'dtoverlay=gpio-poweroff' 'dtoverlay=gpio-poweroff,gpiopin=22,active_low' /boot/config.txt fi - software_id=111 # UrBackup Server + software_id=167 # Raspotify if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing # https://dtcooper.github.io/raspotify/#hard-installation - # As we have /tmp mounted to RAM, change tmp location - mkdir -p /mnt/dietpi_userdata/urbackup/tmp - chown -R urbackup:urbackup /mnt/dietpi_userdata/urbackup - G_CONFIG_INJECT 'DAEMON_TMPDIR=' "DAEMON_TMPDIR='/mnt/dietpi_userdata/urbackup/tmp'" /etc/default/urbackupsrv + # 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" - # https://github.com/MichaIng/DietPi/issues/545#issuecomment-252419739 - #sqlite3 /usr/local/var/urbackup/backup_server_settings.db "UPDATE settings SET value = '/mnt/dietpi_userdata/urbackup/' WHERE key = 'backupfolder'" + # APT list + G_EXEC eval "echo 'deb https://dtcooper.github.io/raspotify/ raspotify main' > /etc/apt/sources.list.d/raspotify.list" + G_AGUP + + # APT package + G_AGI raspotify fi - software_id=116 # Medusa + software_id=169 # Google AIY if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - - # User - Create_User -g dietpi -d /mnt/dietpi_userdata/medusa medusa + Banner_Installing - # Service: https://github.com/pymedusa/Medusa/blob/master/runscripts/init.systemd - G_EXEC cp /mnt/dietpi_userdata/medusa/runscripts/init.systemd /etc/systemd/system/medusa.service - # - Prevent unlimited restarts on failure: Permit up to three restarts in 10 minutes - G_CONFIG_INJECT 'StartLimitIntervalSec=' 'StartLimitIntervalSec=600' /etc/systemd/system/medusa.service '\[Unit\]' - G_CONFIG_INJECT 'StartLimitBurst=' 'StartLimitBurst=3' /etc/systemd/system/medusa.service 'StartLimitIntervalSec=' - # - Remove "Group=medusa" which does not exist, instead fallback to primary group "dietpi" - G_EXEC sed -i '/^[[:blank:]]*Group=/d' /etc/systemd/system/medusa.service - # - Launch from our install and data directory - G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v python3) /mnt/dietpi_userdata/medusa/start.py -q --nolaunch --datadir=/mnt/dietpi_userdata/medusa" /etc/systemd/system/medusa.service + G_EXEC_OUTPUT=1 G_EXEC git clone -b voicekit 'https://github.com/google/aiyprojects-raspbian.git' /mnt/dietpi_userdata/voice-recognizer-raspi + G_EXEC cd /mnt/dietpi_userdata/voice-recognizer-raspi - # Permissions - G_EXEC chown -R medusa:dietpi /mnt/dietpi_userdata/medusa + G_EXEC_OUTPUT=1 G_EXEC pip3 install -U pip virtualenv + G_EXEC_OUTPUT=1 G_EXEC virtualenv --system-site-packages -p python3 env + G_EXEC_OUTPUT=1 G_EXEC env/bin/pip install -Ur requirements.txt - fi + #??? ARMv7 only + (( $G_HW_ARCH == 2 )) && G_EXEC_OUTPUT=1 G_EXEC env/bin/pip install google-assistant-library==0.0.3 - software_id=129 # O!MPD - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Services + G_EXEC sed -i 's|/home/pi|/mnt/dietpi_userdata|g' systemd/voice-recognizer.service + G_CONFIG_INJECT 'User=' 'User=dietpi' systemd/voice-recognizer.service '\[Service\]' - Banner_Configuration + G_EXEC cp systemd/voice-recognizer.service /etc/systemd/system/ + G_EXEC cp systemd/alsa-init.service /etc/systemd/system/ + #G_EXEC cp systemd/ntpdate.service /etc/systemd/system/ - # Preserve config file, create local override if non-existent - # Database will be migrated automatically, so only create new on fresh install, using local override config as flag - if [[ ! -f '/var/www/ompd/include/config.local.inc.php' ]]; then + source env/bin/activate - G_EXEC systemctl start mariadb - # - Create database user only, database will be created automatically - mysql -e "grant all privileges on ompd.* to ompd@localhost identified by '$GLOBAL_PW'" - systemctl stop mariadb + # Enable default app for service start + G_EXEC cp src/assistant_library_with_button_demo.py src/main.py - cat << _EOF_ > /var/www/ompd/include/config.local.inc.php - -_EOF_ - fi + G_EXEC cd /tmp/$G_PROGRAM_NAME - # Webserver configs - # - Lighttpd - if (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then + # Symlink userdata location for assistant.json + G_EXEC ln -sf /mnt/dietpi_userdata/voice-recognizer-raspi/assistant.json /home/dietpi/assistant.json - dps_index=$software_id Download_Install 'lighttpd.ompd.conf' /etc/lighttpd/conf-available/99-dietpi-ompd.conf - [[ -f '/etc/lighttpd/conf-enabled/99-dietpi-ompd.conf' ]] || G_EXEC lighty-enable-mod dietpi-ompd + # Generate cache dir + [[ -d '/home/dietpi/.cache/voice-recognizer' ]] || G_EXEC mkdir -p /home/dietpi/.cache/voice-recognizer - fi + # Setup soundcard + /boot/dietpi/func/dietpi-set_hardware soundcard googlevoicehat-soundcard - # Permissions: http://ompd.pl/configuration - G_EXEC chown -R www-data:www-data /var/www/ompd/{tmp,stream,cache} + # Permissions + G_EXEC chown -R dietpi:dietpi /mnt/dietpi_userdata/voice-recognizer-raspi fi - software_id=135 # IceCast + DarkIce + software_id=176 # Mycroft AI if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - - # IceCast: Set passwords, if not yet done (default found) - sed -i "/hackme/c\ $GLOBAL_PW" /etc/icecast2/icecast.xml - sed -i "/hackme/c\ $GLOBAL_PW" /etc/icecast2/icecast.xml - sed -i "/hackme/c\ $GLOBAL_PW" /etc/icecast2/icecast.xml - # - Remove default service config - [[ -f '/etc/default/icecast2' ]] && G_EXEC rm /etc/default/icecast2 + Banner_Installing - # DarkIce - [[ -f '/etc/darkice.cfg' ]] || > /etc/darkice.cfg - G_EXEC chmod 0600 /etc/darkice.cfg - local input_device_index=$(arecord -l | mawk -F'[ :]' '/card/{print $2;exit}') - cat << _EOF_ > /etc/darkice.cfg -[general] -duration = 0 -bufferSecs = 3 -reconnect = yes + # Git clone to DietPi userdata + G_EXEC cd /mnt/dietpi_userdata + if [[ ! -d 'mycroft-core/.git' ]]; then -[input] -device = hw:$input_device_index,0 -sampleRate = 44100 -bitsPerSample = 16 -channel = 1 + [[ -d 'mycroft-core' ]] && G_EXEC rm -R mycroft-core + G_THREAD_START git clone -b master --depth 1 https://github.com/MycroftAI/mycroft-core.git -[icecast2-0] -bitrateMode = vbr -format = vorbis -quality = 0.8 -server = localhost -port = 8000 -password = $GLOBAL_PW -mountPoint = DietPi -name = DietPi -description = DarkIce on DietPi -url = http://localhost -genre = none -public = no -#localDumpFile = /mnt/dietpi_userdata/darkice_recording.ogg -_EOF_ - Remove_SysV darkice 1 - cat << _EOF_ > /etc/systemd/system/darkice.service -[Unit] -Description=DarkIce (DietPi) -Requires=icecast2.service -After=icecast2.service + fi -[Service] -ExecStart=$(command -v darkice) + # APT deps + DEPS_LIST='vorbis-tools' -[Install] -WantedBy=multi-user.target -_EOF_ - fi + # Pre-create global config to reflect correct data dir and audio settings within install + # - Overwrite existing config, user should use /mnt/dietpi_userdata/mycroft-data/.mycroft/mycroft.conf instead to override. + dps_index=$software_id Download_Install 'mycroft.conf' /etc/mycroft/mycroft.conf - software_id=137 # mjpg-streamer - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then - Banner_Configuration + # Pre-create user and directories with correct permissions + Create_User -G audio -d /mnt/dietpi_userdata/mycroft-data mycroft + G_EXEC mkdir -p /mnt/dietpi_userdata/mycroft-data/skills /var/log/mycroft + G_EXEC chown -R mycroft:mycroft /etc/mycroft /mnt/dietpi_userdata/mycroft-{core,data} /var/log/mycroft + # - Force skills to be placed directly into data dir + G_EXEC rm -Rf /opt/mycroft # symlink + G_EXEC ln -s /mnt/dietpi_userdata/mycroft-data /opt/mycroft + # - Grant mycroft user sudo permissions which is required for dev_setup.sh and some other Mycroft scripts + G_EXEC eval "echo 'mycroft ALL=NOPASSWD: ALL' > /etc/sudoers.d/mycroft" - # User - Create_User -g video -d /opt/mjpg-streamer mjpg-streamer + # Assure 2 GiB overall memory (-100 MiB to avoid tiny swap space) is available + if (( $RAM_TOTAL < 1948 )); then + + G_DIETPI-NOTIFY 2 '\e[33m[WARNING] Insufficient overall memory size: Mycroft AI requires at least 2 GiB memory on first start. We will now attempt to increase your swap size to satisfy this requirement.' + /boot/dietpi/func/dietpi-set_swapfile 1 + + fi + + # Run installer as user mycroft + G_EXEC cd /mnt/dietpi_userdata/mycroft-core + # -sm: Skip mimic build which is time intense and can be manually done any time later. + # - Remove PulseAudio from dependencies, we use ALSA + G_EXEC sed -Ei 's/[^[:blank:]"'\'']*pulseaudio[^[:blank:]"'\'']*//g' ./dev_setup.sh + G_EXEC_OUTPUT=1 G_EXEC sudo -u mycroft ./dev_setup.sh -sm + G_EXEC cd /tmp/$G_PROGRAM_NAME # Service - # - On RPi, if the RPi camera module is enabled already, use it by default. - local input='input_uvc.so -d /dev/video0' - [[ $G_HW_MODEL -gt 9 || -f '/etc/modprobe.d/dietpi-disable_rpi_camera.conf' ]] || input='input_raspicam.so' - cat << _EOF_ > /etc/systemd/system/mjpg-streamer.service + cat << '_EOF_' > /etc/systemd/system/mycroft.service [Unit] -Description=mjpg-streamer (DietPi) -Documentation=https://github.com/jacksonliam/mjpg-streamer/tree/master/mjpg-streamer-experimental -Wants=network-online.target -After=network-online.target +Description=Mycroft AI (DietPi) [Service] -User=mjpg-streamer -WorkingDirectory=/opt/mjpg-streamer -ExecStart=/opt/mjpg-streamer/mjpg_streamer -i '$input' -o 'output_http.so -p 8082 -n' - -# Hardening -ProtectSystem=strict -PrivateTmp=true -ProtectHome=true -ProtectKernelTunables=true -ProtectControlGroups=true +Type=forking +User=mycroft +SyslogIdentifier=Mycroft AI +WorkingDirectory=/mnt/dietpi_userdata/mycroft-data +ExecStart=/mnt/dietpi_userdata/mycroft-core/start-mycroft.sh all +ExecStop=/mnt/dietpi_userdata/mycroft-core/stop-mycroft.sh [Install] WantedBy=multi-user.target _EOF_ - # OctoPrint: Configure it to use mjpg-streamer, if installed - if [[ ${aSOFTWARE_INSTALL_STATE[153]} == 2 && -f '/mnt/dietpi_userdata/octoprint/.octoprint/config.yaml' ]] - then - G_DIETPI-NOTIFY 2 'Configuring OctoPrint to use mjpg-streamer for webcam support' - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.stream "http://$(G_GET_NET ip):8082/?action=stream" - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.snapshot 'http://127.0.0.1:8082/?action=snapshot' - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.ffmpeg "$(command -v ffmpeg)" - fi + # Add Mycroft binaries to $PATH + G_EXEC eval "echo -e '#!/bin/dash\nexport PATH=$PATH:/mnt/dietpi_userdata/mycroft-core/bin' > /etc/bashrc.d/mycroft.sh" + + # Enable ALSA automatic software conversion plugin + local soundcard=$(sed -n '/^[[:blank:]]*CONFIG_SOUNDCARD=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + soundcard=${soundcard%-eq} soundcard=${soundcard%-plug} + /boot/dietpi/func/dietpi-set_hardware soundcard "$soundcard-plug" + fi - software_id=138 # VirtualHere + software_id=86 # Roon Extension Manager if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # Service - cat << '_EOF_' > /etc/systemd/system/virtualhere.service -[Unit] -Description=VirtualHere (DietPi) + # Restart Docker service to be able to deploy the container + G_DIETPI-NOTIFY 2 'Docker will be restarted to be able to deploy the container.' + G_EXEC systemctl daemon-reload + G_EXEC systemctl restart docker -[Service] -ExecStart=/etc/vhusbd/vhusbd -r /var/log/virtualhere.log + # Unset SUDO_USER variable to avoid download, install and run as sudo-calling user, which fails due to /tmp/$G_PROGRAM_NAME write permissions: https://github.com/MichaIng/DietPi/issues/4462 + unset -v SUDO_USER -[Install] -WantedBy=multi-user.target -_EOF_ - # Config - echo "ServerName='DietPi'" > /etc/vhusbd/config.ini + G_EXEC curl -sSfLO 'https://raw.githubusercontent.com/TheAppgineer/roon-extension-manager/v1.x/rem-setup.sh' + G_EXEC chmod +x rem-setup.sh + G_EXEC_OUTPUT=1 G_EXEC ./rem-setup.sh + G_EXEC_NOHALT=1 G_EXEC rm rem-setup.sh fi - software_id=139 # SABnzbd + software_id=178 # Jellyfin if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # User - Create_User -g dietpi -d /etc/sabnzbd sabnzbd + # APT key + local url='https://repo.jellyfin.org/jellyfin_team.gpg.key' + G_CHECK_URL "$url" + G_EXEC eval "curl -sSfL '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-jellyfin.gpg --yes" - # 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 - cat << _EOF_ > /etc/systemd/system/sabnzbd.service -[Unit] -Description=SABnzbd (DietPi) -Documentation=https://sabnzbd.org/wiki/ -Wants=network-online.target -After=network-online.target + # APT list + G_EXEC eval "echo 'deb https://repo.jellyfin.org/debian/ $G_DISTRO_NAME main' > /etc/apt/sources.list.d/dietpi-jellyfin.list" + G_AGUP -[Service] -User=sabnzbd -ExecStart=$(command -v python3) -OO /etc/sabnzbd/SABnzbd.py -b 0 -f /etc/sabnzbd/sabnzbd.ini -Restart=on-failure + # APT meta package: Server, web component and FFmpeg implementation + G_AGI jellyfin -[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 + # Grant dietpi group permissions and assure video access + Create_User -G dietpi,video,render -d /mnt/dietpi_userdata/jellyfin jellyfin - # 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 + # Config: Only apply on fresh install, assumed when /mnt/dietpi_userdata/jellyfin does not yet exist + if [[ ! -d '/mnt/dietpi_userdata/jellyfin' ]]; then - Create_Config /etc/sabnzbd/sabnzbd.ini sabnzbd - sleep 1 # Additional wait, config being overwritten after below changes: https://dietpi.com/phpbb/viewtopic.php?p=7082#p7082 + # 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 + 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 + G_CONFIG_INJECT 'JELLYFIN_CACHE_DIR=' 'JELLYFIN_CACHE_DIR=/mnt/dietpi_userdata/jellyfin/cache' /etc/default/jellyfin - 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 + fi + + # Permissions + G_EXEC chown -R jellyfin: /mnt/dietpi_userdata/jellyfin + + Download_Test_Media + + fi + + software_id=62 # Box86 + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then + Banner_Installing + + # APT deps + DEPS_LIST='cmake python3-minimal' + + # 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"; } + Download_Install "https://github.com/ptitSeb/box86/archive/$version.tar.gz" + # Build + G_EXEC mkdir box86-${version#v}/build + G_EXEC cd box86-${version#v}/build + # - RPi 2 + if [[ $G_HW_MODEL == 2 ]] + then + G_EXEC cmake .. -DRPI2=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo + # - RPi 3 + elif [[ $G_HW_MODEL == 3 ]] + then + G_EXEC cmake .. -DRPI3=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo + # - RPi 4 + elif [[ $G_HW_MODEL == 4 ]] + then + G_EXEC cmake .. -DRPI4=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo + # - Odroids + elif (( $G_HW_MODEL < 20 )) + then + G_EXEC cmake .. -DODROID=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo + # - Others + else + G_EXEC cmake .. -DARM_DYNAREC=ON -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo fi + G_EXEC_OUTPUT=1 G_EXEC make CFLAGS='-g0 -O3' "-j$(nproc)" + G_EXEC strip --remove-section=.comment --remove-section=.note box86 + G_EXEC make install - # 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 cd /tmp/$G_PROGRAM_NAME + # Reload binfmt to have i386 binaries executed via box86 automatically from now on + G_EXEC systemctl restart systemd-binfmt + fi + + software_id=197 # Box64 + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) + then + Banner_Installing + + # APT deps + DEPS_LIST='cmake python3-minimal' + + # 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"; } + Download_Install "https://github.com/ptitSeb/box64/archive/$version.tar.gz" + + # Build + G_EXEC mkdir box64-${version#v}/build + G_EXEC cd box64-${version#v}/build + # - RPi 4 + if [[ $G_HW_MODEL == 4 ]] + then + G_EXEC cmake .. -DRPI4ARM64=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo + # - RK3399 + elif [[ $G_HW_CPUID == 3 ]] + then + G_EXEC cmake .. -DRK3399=1 -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo + # - Others + else + G_EXEC cmake .. -DARM_DYNAREC=ON -DNOGIT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo + fi + G_EXEC_OUTPUT=1 G_EXEC make CFLAGS='-g0 -O3' "-j$(nproc)" + G_EXEC strip --remove-section=.comment --remove-section=.note box64 + G_EXEC make install + # Reload binfmt to have x86_64 binaries executed via box64 automatically from now on + G_EXEC systemctl restart systemd-binfmt fi - software_id=177 # Firefox Sync Server + software_id=27 # TasmoAdmin if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # User - Create_User -d /mnt/dietpi_userdata/firefox-sync ffsync + # Install required PHP modules + DEPS_LIST="$PHP_NAME-curl $PHP_NAME-zip" # https://github.com/reloxx13/TasmoAdmin#linux - # Create database and config directory - G_EXEC mkdir -p /mnt/dietpi_userdata/firefox-sync + # Skip install, if already present + if [[ -d '/var/www/tasmoadmin' ]]; then - # Create database if it doesn't exist - [[ -f '/mnt/dietpi_userdata/firefox-sync/FF-Sync-DB.db' ]] || G_EXEC sqlite3 /mnt/dietpi_userdata/firefox-sync/FF-Sync-DB.db 'create table aTable(field1 int); drop table aTable;' + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install dir \"/var/www/tasmoadmin\" already exists. Download and install steps will be skipped. + - Please manually backup your config files+data, remove the install dir and rerun \"dietpi-software (re)install $software_id\" if you need to reinstall. + - If you want to update the ${aSOFTWARE_NAME[$software_id]} instance, please use the internal updater from WebUI." + # shellcheck disable=SC2086 + G_AGI $DEPS_LIST + DEPS_LIST= - # Copy and modify default config file if it doesn't exist - local ffsync_conf='/mnt/dietpi_userdata/firefox-sync/syncserver.ini' - if [[ ! -f $ffsync_conf ]]; then + else - G_EXEC cp -a /opt/firefox-sync/syncserver.ini $ffsync_conf - local ffsync_ip=$(G_GET_NET ip) - G_CONFIG_INJECT 'host =' "host = $ffsync_ip" $ffsync_conf - G_CONFIG_INJECT 'port =' 'port = 5002' $ffsync_conf # Avoid port conflict with Shairport Sync - G_CONFIG_INJECT 'public_url =' "public_url = http://$ffsync_ip:5002/" $ffsync_conf - G_CONFIG_INJECT 'sqluri = sqlite:' 'sqluri = sqlite:////mnt/dietpi_userdata/firefox-sync/FF-Sync-DB.db' $ffsync_conf + Download_Install 'https://github.com/reloxx13/TasmoAdmin/archive/master.tar.gz' + mv TasmoAdmin-master/tasmoadmin /var/www/ + rm -R TasmoAdmin-master + chown -R www-data:www-data /var/www/tasmoadmin fi - # Service - cat << _EOF_ > /etc/systemd/system/firefox-sync.service -[Unit] -Description=Firefox Sync Server (DietPi) -Documentation=https://github.com/mozilla-services/syncserver -Wants=network-online.target -After=network-online.target - -[Service] -SyslogIdentifier=Firefox Sync Server -User=ffsync -WorkingDirectory=/mnt/dietpi_userdata/firefox-sync -ExecStart=/opt/firefox-sync/local/bin/gunicorn --paste $ffsync_conf + # Configure the webserver + if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then -# Hardening -ProtectSystem=strict -ProtectHome=true -PrivateTmp=true -PrivateDevices=true -ProtectKernelTunables=true -ProtectControlGroups=true -ReadWritePaths=-/mnt/dietpi_userdata/firefox-sync + G_DIETPI-NOTIFY 2 'Apache webserver found, enabling TasmoAdmin specific configuration.' + a2enmod setenvif rewrite authz_core authn_core authn_file 1> /dev/null + local tasmoadmin_conf='/etc/apache2/sites-available/dietpi-tasmoadmin.conf' + if [[ -f $tasmoadmin_conf ]]; then -[Install] -WantedBy=multi-user.target -_EOF_ - # Permissions - G_EXEC chown -R ffsync:ffsync /mnt/dietpi_userdata/firefox-sync + tasmoadmin_conf+='.dietpi-new' + G_WHIP_MSG "Existing TasmoAdmin Apache configuration found, will preserve the old one and save the new one for review and comparison to: $tasmoadmin_conf" - fi + fi + dps_index=$software_id Download_Install 'apache.tasmoadmin.conf' $tasmoadmin_conf + a2ensite dietpi-tasmoadmin 1> /dev/null - software_id=183 # vaultwarden - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then - Banner_Configuration + G_DIETPI-NOTIFY 2 'Lighttpd webserver found, enabling TasmoAdmin specific configuration.' + local tasmoadmin_conf='/etc/lighttpd/conf-available/99-dietpi-tasmoadmin.conf' + if [[ -f $tasmoadmin_conf ]]; then - # User - Create_User -d /mnt/dietpi_userdata/vaultwarden vaultwarden + tasmoadmin_conf+='.dietpi-new' + G_WHIP_MSG "Existing TasmoAdmin Lighttpd configuration found, will preserve the old one and save the new one for review and comparison to: $tasmoadmin_conf" - [[ ! -d '/mnt/dietpi_userdata/vaultwarden' ]] && G_EXEC mkdir -p /mnt/dietpi_userdata/vaultwarden + fi + dps_index=$software_id Download_Install 'lighttpd.tasmoadmin.conf' $tasmoadmin_conf + # Enable required modules + our config + G_EXEC_POST_FUNC(){ [[ $exit_code == 2 ]] && exit_code=0; } # Do not fail if modules are enabled already + G_EXEC lighty-enable-mod rewrite dietpi-tasmoadmin - # Config: Preserve old - if [[ ! -f '/mnt/dietpi_userdata/vaultwarden/vaultwarden.env' ]] - then - G_EXEC cp /opt/vaultwarden/.env.template /mnt/dietpi_userdata/vaultwarden/vaultwarden.env - G_CONFIG_INJECT 'DATA_FOLDER=' 'DATA_FOLDER=/mnt/dietpi_userdata/vaultwarden' /mnt/dietpi_userdata/vaultwarden/vaultwarden.env - # Create TLS certificate for web vault: Currently only RSA is supported. Add SAN with local IP and hostname, required for the client to accept the connection. - G_EXEC_OUTPUT=1 G_EXEC openssl req -reqexts SAN -subj '/CN=DietPi Vaultwarden' -config <(cat /etc/ssl/openssl.cnf <(echo -ne "[SAN]\nsubjectAltName=DNS:$( 0 )); then - # Permissions - G_EXEC chown -R vaultwarden:vaultwarden /mnt/dietpi_userdata/vaultwarden - G_EXEC chmod +x /opt/vaultwarden/target/release/vaultwarden + G_DIETPI-NOTIFY 2 'Nginx webserver found, enabling TasmoAdmin specific configuration.' + local tasmoadmin_conf='/etc/nginx/sites-dietpi/dietpi-tasmoadmin.conf' + if [[ -f $tasmoadmin_conf ]]; then - # Service: https://github.com/dani-garcia/vaultwarden/wiki/Setup-as-a-systemd-service - cat << '_EOF_' > /etc/systemd/system/vaultwarden.service -[Unit] -Description=vaultwarden Server (Rust Edition) -Documentation=https://github.com/dani-garcia/vaultwarden -Wants=network-online.target -After=network-online.target + owncloud_conf+='.dietpi-new' + G_WHIP_MSG "Existing TasmoAdmin Nginx configuration found, will preserve the old one and save the new one for review and comparison to: $tasmoadmin_conf" -# Restart attempt only 5 times -StartLimitIntervalSec=500 -StartLimitBurst=5 + fi + dps_index=$software_id Download_Install 'nginx.tasmoadmin.conf' $tasmoadmin_conf -[Service] -# Server sometimes fails to start on startup, this should fix it -Restart=on-failure -RestartSec=5s -# The user vaultwarden is run under. the working directory (see below) should allow write and read access to this user -User=vaultwarden -# The location of the .env file for configuration -EnvironmentFile=/mnt/dietpi_userdata/vaultwarden/vaultwarden.env -# The location of the compiled binary -ExecStart=/opt/vaultwarden/target/release/vaultwarden -# Set reasonable connection and process limits -LimitNOFILE=1048576 -LimitNPROC=64 -# Isolate vaultwarden from the rest of the system -PrivateTmp=true -PrivateDevices=true -ProtectHome=true -ProtectSystem=strict -# Only allow writes to the following directory and set it to the working directory (user and password data are stored here) -WorkingDirectory=/mnt/dietpi_userdata/vaultwarden -ReadWritePaths=-/mnt/dietpi_userdata/vaultwarden -# Allow vaultwarden to bind ports in the range of 0-1024 -AmbientCapabilities=CAP_NET_BIND_SERVICE + fi -[Install] -WantedBy=multi-user.target -_EOF_ fi - software_id=143 # Koel + software_id=157 # Home Assistant if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # User - Create_User -g dietpi -d /mnt/dietpi_userdata/koel koel + 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.7' - # Permissions - G_EXEC cd /mnt/dietpi_userdata/koel - G_EXEC chmod 0600 .env - G_EXEC chown -R koel:dietpi . + G_DIETPI-NOTIFY 2 "Home Assistant user: $ha_user" + G_DIETPI-NOTIFY 2 "Home Assistant home: $ha_home" + G_DIETPI-NOTIFY 2 "pyenv activation: \"$ha_pyenv_activation\"" + G_DIETPI-NOTIFY 2 "pyenv Python version: $ha_python_version" - # Create database and apply to config file, if it does not exist yet - if [[ ! -d '/mnt/dietpi_userdata/mysql/koel' ]]; then + # User + Create_User -G dialout,gpio,i2c -d $ha_home $ha_user - # Create random alphanumeric 30 characters password - local password=$(tr -dc '[:alnum:]' < /dev/random | head -c30) - /boot/dietpi/func/create_mysql_db koel koel "$password" - G_CONFIG_INJECT 'DB_CONNECTION=' 'DB_CONNECTION=mysql' .env - G_CONFIG_INJECT 'DB_HOST=' 'DB_HOST=localhost' .env - G_CONFIG_INJECT 'DB_DATABASE=' 'DB_DATABASE=koel' .env - G_CONFIG_INJECT 'DB_USERNAME=' 'DB_USERNAME=koel' .env - GCI_PASSWORD=1 G_CONFIG_INJECT 'DB_PASSWORD=' "DB_PASSWORD=$password" .env - unset -v password - G_CONFIG_INJECT 'MEDIA_PATH=' 'MEDIA_PATH=/mnt/dietpi_userdata/Music' .env - G_CONFIG_INJECT 'FFMPEG_PATH=' "FFMPEG_PATH=$(command -v ffmpeg)" .env - # Admin credentials cannot be pre-configured anymore: https://github.com/koel/koel/issues/1302 - #G_CONFIG_INJECT 'ADMIN_EMAIL=' 'ADMIN_EMAIL=dietpi@dietpi.com' .env - #G_CONFIG_INJECT 'ADMIN_NAME=' 'ADMIN_NAME=dietpi' .env - #GCI_PASSWORD=1 G_CONFIG_INJECT 'ADMIN_PASSWORD=' "ADMIN_PASSWORD=$GLOBAL_PW" .env + # Start with fresh instance, to allow clean pyenv and Python updates and fix broken instances. All userdata and configs are preserved in: /mnt/dietpi_userdata/homeassistant + [[ -d $ha_home/.pyenv ]] && G_EXEC rm -R $ha_home/.pyenv + [[ -d '/srv/homeassistant' ]] && G_EXEC rm -R /srv/homeassistant # pre-v6-27 - # Else assure database server runs - else + # Build dependencies + # - MariaDB support: G_AGI libmariadb-dev + # - Read custom build dependencies + local custom_apt_deps=$(sed -n '/^[[:blank:]]*SOFTWARE_HOMEASSISTANT_APT_DEPS=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + # - All: gcc, libc6-dev, make, libssl-dev, zlib1g-dev for Python built and libbz2-dev, libreadline-dev, libsqlite3-dev to suppress warnings + # - All: libffi-dev for cffi on ARMv6/7 and for python-slugify==4.0.1 on ARMv8/x86_64 + DEPS_LIST="gcc libc6-dev make libssl-dev zlib1g-dev libffi-dev libbz2-dev libreadline-dev libsqlite3-dev $custom_apt_deps" + # - ARMv6/7: libjpeg-dev for Pillow, g++ for greenlet and libopenjp2-7 + libtiff5 + libxcb1 for runtime + [[ $G_HW_ARCH == [12] ]] && DEPS_LIST+=' libjpeg-dev g++ libopenjp2-7 libtiff5 libxcb1' - G_EXEC systemctl restart mariadb + # Install pyenv to $ha_home + G_EXEC mkdir -p $ha_home + Download_Install 'https://github.com/pyenv/pyenv/archive/master.tar.gz' + G_EXEC mv pyenv-master $ha_home/.pyenv + G_EXEC chown -R $ha_user:$ha_user $ha_home + + # Generate script to activate pyenv: This must be sourced from the originating shell, hence it does not require execute permissions. + echo "#!/bin/dash +if [ \$(whoami) != '$ha_user' ]; then + echo '[FAILED] This pyenv must be activated as user \"$ha_user\". Aborting...' + kill -INT \$\$ +fi +cd $ha_home +export PYENV_ROOT='$ha_home/.pyenv' +export PATH=\"\$PYENV_ROOT/bin:\$PATH\" +eval \"\$(pyenv init --path)\" +eval \"\$(pyenv init -)\"" > $ha_home/pyenv-activate.sh + # ARMv6/7: Create pip config to pull wheels from piwheels.org + if [[ $G_HW_ARCH == [12] ]] + then + G_EXEC mkdir $ha_home/.pip + G_EXEC eval "echo -e '[global]\nextra-index-url=https://www.piwheels.org/simple/' > $ha_home/.pip/pip.conf" fi - # Download test media - Download_Test_Media + G_EXEC_DESC='Installing Python with Home Assistant module into pyenv' + # - Read custom Python modules + local custom_pip_deps=$(sed -n '/^[[:blank:]]*SOFTWARE_HOMEASSISTANT_PIP_DEPS=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + # - MariaDB support: pip3 install mysqlclient|PyMySQL + G_EXEC_OUTPUT=1 G_EXEC sudo -u $ha_user dash -c " +$ha_pyenv_activation +pyenv install $ha_python_version +pyenv local $ha_python_version +pip3 install -U pip wheel +[ -z '$custom_pip_deps' ] || pip3 install $custom_pip_deps +exec pip3 install homeassistant" - # Init - G_EXEC_OUTPUT=1 G_EXEC sudo -u koel $PHP_NAME artisan koel:init -n --no-assets - G_EXEC_OUTPUT=1 G_EXEC sudo -u koel $PHP_NAME artisan koel:sync - G_EXEC cd /tmp/$G_PROGRAM_NAME + # Generate script to launch HA using pyenv + echo "#!/bin/dash +$ha_pyenv_activation +exec hass -c '/mnt/dietpi_userdata/homeassistant'" > $ha_home/homeassistant-start.sh + G_EXEC chmod +x $ha_home/homeassistant-start.sh - # Service: Run on port 8003 by default to avoid conflict with IceCast - cat << _EOF_ > /etc/systemd/system/koel.service + # Generate script to update HA within pyenv + echo "#!/bin/dash +exec sudo -u $ha_user dash -c '$ha_pyenv_activation; exec pip3 install -U homeassistant'" > $ha_home/homeassistant-update.sh + G_EXEC chmod +x $ha_home/homeassistant-update.sh + + cat << '_EOF_' > /etc/systemd/system/home-assistant.service [Unit] -Description=Koel (DietPi) -Documentation=https://docs.koel.dev/ +Description=Home Assistant (DietPi) Wants=network-online.target -After=network-online.target +After=network-online.target mariadb.service [Service] -SyslogIdentifier=Koel -User=koel -WorkingDirectory=/mnt/dietpi_userdata/koel -ExecStart=$(command -v $PHP_NAME) /mnt/dietpi_userdata/koel/artisan serve --host 0.0.0.0 --port 8003 +SyslogIdentifier=homeassistant +User=homeassistant +ExecStart=/home/homeassistant/homeassistant-start.sh [Install] WantedBy=multi-user.target _EOF_ + # Link config and data to DietPi userdata + if [[ ! -d '/mnt/dietpi_userdata/homeassistant' ]] + then + if [[ -d '/home/homeassistant/.homeassistant' ]] + then + G_EXEC mv /home/homeassistant/.homeassistant /mnt/dietpi_userdata/homeassistant + else + G_EXEC mkdir -p /mnt/dietpi_userdata/homeassistant + fi + fi + G_EXEC rm -Rf /home/homeassistant/.homeassistant + G_EXEC ln -s /mnt/dietpi_userdata/homeassistant /home/homeassistant/.homeassistant + G_EXEC chown -R homeassistant:homeassistant /mnt/dietpi_userdata/homeassistant + fi - software_id=144 # Sonarr + software_id=181 # PaperMC if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/sonarr + # Make sure user agrees to the EULA + if [[ -f '/mnt/dietpi_userdata/papermc/eula.txt' ]] || G_WHIP_BUTTON_OK_TEXT='Yes' G_WHIP_BUTTON_CANCEL_TEXT='Abort' G_WHIP_YESNO 'Do you agree to the Minecraft EULA found at:\n\nhttps://account.mojang.com/documents/minecraft_eula' + then + # Collect latest version of PaperMC + local url='https://papermc.io/api/v2/projects/paper' + local version=$(curl -sSfL "$url"); version=${version%\"*} version=${version##*\"} + local build=$(curl -sSfL "$url/versions/$version"); build=${build%]*} build=${build##*[,[]} + #local file=$(curl -sSfL "$url/versions/$version/builds/$build"); file=${file##*\"name\":\"} file=${file%%\"*} + # Download and install PaperMC + Download_Install "$url/versions/$version/builds/$build/downloads/paper-$version-$build.jar" /opt/papermc/paperclip.jar + G_EXEC mkdir -p /mnt/dietpi_userdata/papermc + G_EXEC eval 'echo "eula=true" > /mnt/dietpi_userdata/papermc/eula.txt' # User - Create_User -g dietpi -d /mnt/dietpi_userdata/sonarr sonarr - - # Service: https://github.com/Sonarr/Sonarr/blob/phantom-develop/distribution/debian/sonarr.service - cat << _EOF_ > /etc/systemd/system/sonarr.service -[Unit] -Description=Sonarr Daemon (DietPi) -Wants=network-online.target -After=network-online.target + Create_User -d /mnt/dietpi_userdata/papermc papermc -[Service] -SyslogIdentifier=Sonarr -User=sonarr -UMask=002 -ExecStart=$(command -v mono) /usr/lib/sonarr/bin/Sonarr.exe -nobrowser -data=/mnt/dietpi_userdata/sonarr -TimeoutStopSec=20 -KillMode=process -Restart=on-failure + # Bedrock compatibility + G_WHIP_BUTTON_OK_TEXT='Yes' + G_WHIP_BUTTON_CANCEL_TEXT='Skip' + if G_WHIP_YESNO 'Would you like to install the Geyser and Floodgate plugins for compatibility with Bedrock Edition?\n\nNote that this may be buggy.' + then + Download_Install 'https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/master/lastStableBuild/artifact/bootstrap/spigot/target/Geyser-Spigot.jar' /mnt/dietpi_userdata/papermc/plugins/Geyser-Spigot.jar + Download_Install 'https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/master/lastStableBuild/artifact/spigot/target/floodgate-spigot.jar' /mnt/dietpi_userdata/papermc/plugins/floodgate-bukkit.jar + fi -# Hardening -ProtectSystem=strict -ProtectHome=true -PrivateDevices=true -ProtectKernelTunables=true -ProtectControlGroups=true -ReadWritePaths=-/usr/lib/sonarr -/mnt -/media -/var/log/sonarr -/tmp + # Minecraft rcon client for remote administration and server maintenance scripts + DEPS_LIST='gcc libc6-dev' + Download_Install 'https://github.com/Tiiffi/mcrcon/archive/master.tar.gz' + G_EXEC gcc -g0 -O3 mcrcon-master/mcrcon.c -o /usr/local/bin/mcrcon + G_EXEC rm -R mcrcon-master + G_EXEC strip --remove-section=.comment --remove-section=.note /usr/local/bin/mcrcon -[Install] -WantedBy=multi-user.target -_EOF_ - # Logs to RAM - G_EXEC rm -Rf /mnt/dietpi_userdata/sonarr/logs* - G_EXEC mkdir -p /var/log/sonarr - G_EXEC ln -s /var/log/sonarr /mnt/dietpi_userdata/sonarr/logs - G_EXEC ln -s /var/log/sonarr/logs.db /mnt/dietpi_userdata/sonarr/logs.db - G_EXEC ln -s /var/log/sonarr/logs.db-shm /mnt/dietpi_userdata/sonarr/logs.db-shm - G_EXEC ln -s /var/log/sonarr/logs.db-wal /mnt/dietpi_userdata/sonarr/logs.db-wal + # Link logs to RAM + G_EXEC mkdir -p /var/log/papermc + G_EXEC rm -Rf /mnt/dietpi_userdata/papermc/logs + G_EXEC ln -s /var/log/papermc /mnt/dietpi_userdata/papermc/logs # Permissions - G_EXEC chown -R sonarr:dietpi /mnt/dietpi_userdata/sonarr /usr/lib/sonarr /var/log/sonarr - - fi - - software_id=145 # Radarr - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration + G_EXEC chown -R papermc:papermc /{mnt/dietpi_userdata,var/log}/papermc - # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/radarr + # Assure 1.5 GiB overall memory (-100 MiB to avoid tiny swap space) is available. + local heap_size='512' + if (( $RAM_TOTAL < 1436 )) + then + G_DIETPI-NOTIFY 2 'Stable PaperMC operation requires at least 1.5 GiB system memory. We will now increase your swap size to satisfy this requirement.' + /boot/dietpi/func/dietpi-set_swapfile $(( 1536 - $RAM_PHYS )) - # User - Create_User -g dietpi -d /mnt/dietpi_userdata/radarr radarr + # On 2 GiB+ physical RAM devices, apply 1 GiB heap size by default + elif (( $RAM_PHYS > 1848 )) + then + heap_size='1024' + fi - # Service: https://github.com/Radarr/Radarr/wiki/Autostart-on-Linux#service-file - cat << '_EOF_' > /etc/systemd/system/radarr.service + # Service + cat << _EOF_ > /etc/systemd/system/papermc.service [Unit] -Description=Radarr Daemon (DietPi) -Wants=network-online.target -After=network-online.target +Description=PaperMC (DietPi) +Documentation=https://paper.readthedocs.io/ [Service] -SyslogIdentifier=Radarr -User=radarr -UMask=002 -ExecStart=/opt/radarr/Radarr -nobrowser -data=/mnt/dietpi_userdata/radarr -TimeoutStopSec=20 -KillMode=process -Restart=on-failure - -# Hardening -ProtectSystem=strict -ProtectHome=true -PrivateDevices=true -ProtectKernelTunables=true -ProtectControlGroups=true -ReadWritePaths=-/opt/radarr -/mnt -/media -/var/log/radarr -/tmp +SyslogIdentifier=PaperMC +User=papermc +WorkingDirectory=/mnt/dietpi_userdata/papermc +ExecStart=$(command -v java) -Xmx${heap_size}m -jar /opt/papermc/paperclip.jar --nogui --noconsole [Install] WantedBy=multi-user.target _EOF_ - # - ARMv6 devices use Mono - (( $G_HW_ARCH == 1 )) && G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v mono) /opt/radarr/Radarr.exe -nobrowser -data=/mnt/dietpi_userdata/radarr" /etc/systemd/system/radarr.service - - # Logs to RAM - G_EXEC rm -Rf /mnt/dietpi_userdata/radarr/logs* - G_EXEC mkdir -p /var/log/radarr - G_EXEC ln -s /var/log/radarr /mnt/dietpi_userdata/radarr/logs - G_EXEC ln -s /var/log/radarr/logs.db /mnt/dietpi_userdata/radarr/logs.db - G_EXEC ln -s /var/log/radarr/logs.db-shm /mnt/dietpi_userdata/radarr/logs.db-shm - G_EXEC ln -s /var/log/radarr/logs.db-wal /mnt/dietpi_userdata/radarr/logs.db-wal + # Config + if [[ -f '/mnt/dietpi_userdata/papermc/plugins/Geyser-Spigot.jar' && -f '/mnt/dietpi_userdata/papermc/plugins/floodgate-bukkit.jar' ]] + then + Create_Config /mnt/dietpi_userdata/papermc/plugins/Geyser-Spigot/config.yml papermc 1800 1 && + G_CONFIG_INJECT 'auth-type:[[:blank:]]' 'auth-type: floodgate' /mnt/dietpi_userdata/papermc/plugins/Geyser-Spigot/config.yml + else + Create_Config /mnt/dietpi_userdata/papermc/permissions.yml papermc 1800 1 + fi + G_CONFIG_INJECT 'enable-rcon=' 'enable-rcon=true' /mnt/dietpi_userdata/papermc/server.properties + GCI_PASSWORD=1 G_CONFIG_INJECT 'rcon.password=' "rcon.password=$GLOBAL_PW" /mnt/dietpi_userdata/papermc/server.properties - # Permissions - G_EXEC chown -R radarr:dietpi /mnt/dietpi_userdata/radarr /opt/radarr /var/log/radarr + else + aSOFTWARE_INSTALL_STATE[$software_id]=0 + G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} install aborted due to outstanding EULA agreement" + fi fi - software_id=180 # Bazarr + software_id=140 # Domoticz if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - - # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/bazarr - - # User - Create_User -g dietpi -d /mnt/dietpi_userdata/bazarr bazarr - - # Service: https://github.com/morpheus65535/bazarr/wiki/Autostart-on-Linux-Windows-MacOS-FreeBSD#systemd-service-file-for-debian-ubuntu - cat << _EOF_ > /etc/systemd/system/bazarr.service -[Unit] -Description=Bazarr Daemon (DietPi) -Wants=network-online.target -After=network-online.target sonarr.service radarr.service - -[Service] -SyslogIdentifier=Bazarr -User=bazarr -UMask=002 -ExecStart=$(command -v python3) /opt/bazarr/bazarr.py -c /mnt/dietpi_userdata/bazarr + Banner_Installing -# Hardening -ProtectSystem=strict -ProtectHome=true -PrivateDevices=true -PrivateTmp=true -ProtectKernelTunables=true -ProtectControlGroups=true -ReadWritePaths=-/opt/bazarr -/mnt -/media -/var/log/bazarr -/tmp + # APT deps + DEPS_LIST='libusb-0.1 libcurl3-gnutls' -[Install] -WantedBy=multi-user.target -_EOF_ - # Logs to RAM - G_EXEC rm -Rf /mnt/dietpi_userdata/bazarr/log - G_EXEC mkdir -p /var/log/bazarr - G_EXEC ln -s /var/log/bazarr /mnt/dietpi_userdata/bazarr/log + # Reinstall: Clean old install dir + [[ -d '/opt/domoticz' ]] && G_EXEC rm -R /opt/domoticz + Download_Install "https://releases.domoticz.com/releases/release/domoticz_linux_${G_HW_ARCH_NAME/armv6l/armv7l}.tgz" /opt/domoticz - # Permissions - G_EXEC chown -R bazarr:dietpi /mnt/dietpi_userdata/bazarr /opt/bazarr /var/log/bazarr + # Data dir + G_EXEC mkdir -p /mnt/dietpi_userdata/domoticz - # On fresh install, pre-configure for Sonarr and Radarr when found - if (( ${aSOFTWARE_INSTALL_STATE[144]} + ${aSOFTWARE_INSTALL_STATE[145]} > 0 )) && Create_Config /mnt/dietpi_userdata/bazarr/config/config.ini bazarr - then - # Sonarr - if (( ${aSOFTWARE_INSTALL_STATE[144]} > 0 )) && CREATE_CONFIG_CONTENT='ApiKey' Create_Config /mnt/dietpi_userdata/sonarr/config.xml sonarr - then - local port=$(sed -nE '/[0-9]+<\/Port>/{s/^.*([0-9]+)<\/Port>.*$/\1/p;q}' /mnt/dietpi_userdata/sonarr/config.xml) - local apikey=$(sed -nE '/.+<\/ApiKey>/{s/^.*(.+)<\/ApiKey>.*$/\1/p;q}' /mnt/dietpi_userdata/sonarr/config.xml) - G_EXEC sed -i '/\[sonarr\]/,/^$/s/^ip = .*$/ip = 127.0.0.1/' /mnt/dietpi_userdata/bazarr/config/config.ini - G_EXEC sed -i "/\[sonarr\]/,/^$/s/^port = .*$/port = $port/" /mnt/dietpi_userdata/bazarr/config/config.ini - G_EXEC sed -i '/\[sonarr\]/,/^$/s/^base_url = .*$/base_url = \//' /mnt/dietpi_userdata/bazarr/config/config.ini - G_EXEC sed -i "/\[sonarr\]/,/^$/s/^apikey = .*$/apikey = $apikey/" /mnt/dietpi_userdata/bazarr/config/config.ini - G_CONFIG_INJECT 'use_sonarr[[:blank:]]*=' 'use_sonarr = True' /mnt/dietpi_userdata/bazarr/config/config.ini '\[general\]' - fi - # Radarr - if (( ${aSOFTWARE_INSTALL_STATE[145]} > 0 )) && CREATE_CONFIG_CONTENT='ApiKey' Create_Config /mnt/dietpi_userdata/radarr/config.xml radarr - then - local port=$(sed -nE '/[0-9]+<\/Port>/{s/^.*([0-9]+)<\/Port>.*$/\1/p;q}' /mnt/dietpi_userdata/radarr/config.xml) - local apikey=$(sed -nE '/.+<\/ApiKey>/{s/^.*(.+)<\/ApiKey>.*$/\1/p;q}' /mnt/dietpi_userdata/radarr/config.xml) - G_EXEC sed -i '/\[radarr\]/,/^$/s/^ip = .*$/ip = 127.0.0.1/' /mnt/dietpi_userdata/bazarr/config/config.ini - G_EXEC sed -i "/\[radarr\]/,/^$/s/^port = .*$/port = $port/" /mnt/dietpi_userdata/bazarr/config/config.ini - G_EXEC sed -i '/\[radarr\]/,/^$/s/^base_url = .*$/base_url = \//' /mnt/dietpi_userdata/bazarr/config/config.ini - G_EXEC sed -i "/\[radarr\]/,/^$/s/^apikey = .*$/apikey = $apikey/" /mnt/dietpi_userdata/bazarr/config/config.ini - G_CONFIG_INJECT 'use_radarr[[:blank:]]*=' 'use_radarr = True' /mnt/dietpi_userdata/bazarr/config/config.ini '\[general\]' - fi - fi - fi + # Config file + if [[ ! -f '/mnt/dietpi_userdata/domoticz/domoticz.conf' ]]; then - software_id=146 # Tautulli - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + G_EXEC cp /opt/domoticz/scripts/domoticz.conf /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'http_port=' 'http_port=8124' /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'ssl_port=' 'ssl_port=8424' /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'ssl_cert=' 'ssl_cert=/opt/domoticz/server_cert.pem' /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'ssl_key=' 'ssl_key=/opt/domoticz/server_cert.pem' /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'ssl_dhparam=' 'ssl_dhparam=/opt/domoticz/server_cert.pem' /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'loglevel=' 'loglevel=error' /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'syslog=' 'syslog=local7' /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'dbase_file=' "dbase_file=/mnt/dietpi_userdata/domoticz/domoticz.db" /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'app_path=' 'app_path=/opt/domoticz' /mnt/dietpi_userdata/domoticz/domoticz.conf + G_CONFIG_INJECT 'userdata_path=' "userdata_path=/mnt/dietpi_userdata/domoticz" /mnt/dietpi_userdata/domoticz/domoticz.conf - Banner_Configuration + fi # User - Create_User -d /mnt/dietpi_userdata/tautulli tautulli + Create_User -G dialout -d /mnt/dietpi_userdata/domoticz domoticz - # Directory - G_EXEC mkdir -p /mnt/dietpi_userdata/tautulli + # Permissions + G_EXEC chown -R domoticz:domoticz /opt/domoticz /mnt/dietpi_userdata/domoticz - # Service: https://github.com/Tautulli/Tautulli/blob/master/init-scripts/init.systemd - cat << _EOF_ > /etc/systemd/system/tautulli.service + # Copy scripts directory to data dir: https://dietpi.com/phpbb/viewtopic.php?t=8627 + G_EXEC cp -a /opt/domoticz/scripts /mnt/dietpi_userdata/domoticz/ + + # Service + cat << '_EOF_' > /etc/systemd/system/domoticz.service [Unit] -Description=Tautulli - Stats for Plex Media Server usage (DietPi) +Description=Domoticz (DietPi) Wants=network-online.target After=network-online.target [Service] -User=tautulli -ExecStart=$(command -v python3) /opt/tautulli/Tautulli.py -q --nolaunch --config /mnt/dietpi_userdata//tautulli/config.ini --datadir /mnt/dietpi_userdata/tautulli +User=domoticz +ExecStart=/opt/domoticz/domoticz -f /mnt/dietpi_userdata/domoticz/domoticz.conf [Install] WantedBy=multi-user.target _EOF_ - # Permissions - G_EXEC chown -R tautulli:tautulli /{opt,mnt/dietpi_userdata}/tautulli - fi - software_id=147 # Jackett + software_id=191 # Snapcast Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # User - Create_User -d /opt/jackett jackett + local arch='armhf' + (( $G_HW_ARCH == 10 )) && arch='amd64' - # Permissions - chown -R jackett:jackett /opt/jackett + 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}")" - # Service: https://github.com/Jackett/Jackett/wiki/systemd-service - # - Wrap execution into shell to work around: https://github.com/Jackett/Jackett/issues/5208 - cat << '_EOF_' > /etc/systemd/system/jackett.service -[Unit] -Description=Jackett (DietPi) -Wants=network-online.target -After=network-online.target + # Disable JSON RPC by default, if setting was never touched yet + sed -i '/^\[tcp\]/,/^\[/s/^#enabled = true$/enabled = false/' /etc/snapserver.conf -[Service] -SyslogIdentifier=jackett -User=jackett -WorkingDirectory=/opt/jackett -Environment=XDG_CONFIG_HOME=/opt/jackett -ExecStart=/bin/dash -c '/opt/jackett/jackett --NoRestart; while pgrep -u jackett JackettUpdater > /dev/null; do sleep 1; done' -Restart=always -RestartSec=5 -TimeoutStopSec=30 + fi -# Hardening -ProtectSystem=strict -ProtectHome=true -PrivateDevices=true -PrivateTmp=true -ProtectKernelTunables=true -ProtectControlGroups=true -ReadWritePaths=-/opt/jackett + software_id=192 # Snapcast Client + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then -[Install] -WantedBy=multi-user.target -_EOF_ - # - ARMv6 devices use Mono - (( $G_HW_ARCH == 1 )) && G_CONFIG_INJECT 'ExecStart=' "ExecStart=$(command -v mono) /opt/jackett/JackettConsole.exe --NoRestart" /etc/systemd/system/jackett.service + Banner_Installing - fi + local arch='armhf' + (( $G_HW_ARCH == 10 )) && arch='amd64' - software_id=155 # HTPC Manager - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + 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}")" - Banner_Configuration + # Client IP needs to be added to allowed IP list + local snapcast_server_ip + local invalid_entry= + while : + do + if G_WHIP_INPUTBOX "${invalid_entry}Please enter the IPv4 address of your Snapcast server machine" && [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9.]+$ ]] + then + snapcast_server_ip=$G_WHIP_RETURNED_VALUE + break + else + invalid_entry='[ERROR] Please enter a valid IP address. Please retry...\n\n' + fi + done - # Service - cat << _EOF_ > /etc/systemd/system/htpc-manager.service -[Unit] -Description=HTPC Manager (DietPi) -Wants=network-online.target -After=network-online.target + local snapcast_server_port=1704 + invalid_entry= + while : + do + G_WHIP_DEFAULT_ITEM=$snapcast_server_port + if G_WHIP_INPUTBOX "${invalid_text}Please enter the network port of your Snapcast server machine\n - default: 1704" && disable_error=1 G_CHECK_VALIDINT "$G_WHIP_RETURNED_VALUE" 1 + then + snapcast_server_port=$G_WHIP_RETURNED_VALUE + break + else + invalid_text='[ERROR] Please enter a valid port number. Please retry...\n\n' + fi + done -[Service] -SyslogIdentifier=HTPC Manager -ExecStart=$(command -v python3) -OO /mnt/dietpi_userdata/htpc-manager/Htpc.py + G_CONFIG_INJECT 'SNAPCLIENT_OPTS[[:blank:]=]' "SNAPCLIENT_OPTS=\"-h $snapcast_server_ip -p $snapcast_server_port\"" /etc/default/snapclient -[Install] -WantedBy=multi-user.target -_EOF_ fi - software_id=153 # OctoPrint - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )) - then - Banner_Configuration + software_id=198 # File Browser + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - # Service: https://github.com/OctoPrint/OctoPrint/blob/master/scripts/octoprint.service - cat << '_EOF_' > /etc/systemd/system/octoprint.service -[Unit] -Description=OctoPrint (DietPi) -Documentation=https://dietpi.com/docs/software/printing/#octoprint -Wants=network-online.target -After=network-online.target mjpg-streamer.service + Banner_Installing -[Service] -Environment="LC_ALL=C.UTF-8" "LANG=C.UTF-8" -User=octoprint -ExecStart=/mnt/dietpi_userdata/octoprint/.local/bin/octoprint serve + # ARMv6 + local arch='armv6' -[Install] -WantedBy=multi-user.target -_EOF_ - # CLI alias - echo "alias octoprint='sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint'" > /etc/bashrc.d/dietpi-octoprint.sh + # ARMv7 + if (( $G_HW_ARCH == 2 )); then + arch='armv7' - # On fresh installs, change listening port to 5001 to avoid conflict with Shairport Sync. - [[ -f '/mnt/dietpi_userdata/octoprint/.octoprint/config.yaml' ]] || G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.port '5001' + # ARMv8 + elif (( $G_HW_ARCH == 3 )); then + arch='arm64' - # Apply service and system commands: Allow execution via specific sudoers config - echo "octoprint ALL=NOPASSWD: $(command -v systemctl) restart octoprint, $(command -v reboot), $(command -v poweroff)" > /etc/sudoers.d/octoprint - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.serverRestartCommand 'sudo systemctl restart octoprint' - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.systemRestartCommand 'sudo reboot' - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set server.commands.systemShutdownCommand 'sudo poweroff' + # x86_64 + elif (( $G_HW_ARCH == 10 )); then + arch='amd64' - # mjpg-streamer: Configure OctoPrint to use it, if installed - if (( ${aSOFTWARE_INSTALL_STATE[137]} > 0 )) - then - G_DIETPI-NOTIFY 2 'Configuring OctoPrint to use mjpg-streamer for webcam support' - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.stream "http://$(G_GET_NET ip):8082/?action=stream" - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.snapshot 'http://127.0.0.1:8082/?action=snapshot' - G_EXEC sudo -u octoprint /mnt/dietpi_userdata/octoprint/.local/bin/octoprint config set webcam.ffmpeg "$(command -v ffmpeg)" fi - fi - software_id=187 # CUPS - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration - G_EXEC chown root:lp /etc/cups/ /etc/cups/ppd/ /etc/cups/ssl/ - fi + local fallback_url="https://github.com/filebrowser/filebrowser/releases/download/v2.17.1/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/ - software_id=156 # Steam - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + # Reinstall + [[ -d '/opt/filebrowser' ]] && G_EXEC rm -R /opt/filebrowser - Banner_Configuration + # Install + G_EXEC mv filebrowser /opt/ - # Move data dir to dietpi_userdata - if [[ -d '/mnt/dietpi_userdata/steam' ]] - then - G_EXEC rm -Rf /root/.steam + # User + [[ -d '/mnt/dietpi_userdata/filebrowser' ]] || G_EXEC mkdir -p /mnt/dietpi_userdata/filebrowser + Create_User -g dietpi -d /mnt/dietpi_userdata/filebrowser filebrowser - elif [[ -d '/root/.steam' ]] + # Config if not exist + if [[ ! -f '/mnt/dietpi_userdata/filebrowser/filebrowser.db' ]] then - G_EXEC mv /root/.steam /mnt/dietpi_userdata/steam - - else - G_EXEC mkdir -p /mnt/dietpi_userdata/steam + G_EXEC cd /mnt/dietpi_userdata/filebrowser + G_EXEC /opt/filebrowser/filebrowser config init + G_EXEC /opt/filebrowser/filebrowser config set -a 0.0.0.0 -p 8084 -r /mnt + G_EXEC_DESC="Setting up File Browser login user 'dietpi'" G_EXEC /opt/filebrowser/filebrowser users add dietpi "$GLOBAL_PW" --perm.admin fi - G_EXEC ln -s /mnt/dietpi_userdata/steam /root/.steam - # Desktop shortcut - Create_Desktop_Shortcut steam + # Permissions + G_EXEC chown -R filebrowser:root /mnt/dietpi_userdata/filebrowser /opt/filebrowser + + # Service + cat << '_EOF_' > /etc/systemd/system/filebrowser.service +[Unit] +Description=File Browser (DietPi) +Documentation=https://filebrowser.org/ +Wants=network-online.target +After=network-online.target + +[Service] +User=filebrowser +UMask=002 +ExecStart=/opt/filebrowser/filebrowser -d /mnt/dietpi_userdata/filebrowser/filebrowser.db +[Install] +WantedBy=multi-user.target +_EOF_ fi - software_id=140 # Domoticz: https://www.domoticz.com/wiki/Linux + software_id=199 # Spotifyd if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing - # Data dir - G_EXEC mkdir -p /mnt/dietpi_userdata/domoticz + # ARMv6 + local fallback_url='https://github.com/Spotifyd/spotifyd/releases/download/v0.3.2/spotifyd-linux-armv6-slim.tar.gz' + local file='spotifyd-linux-armv6-slim' - # Config file - if [[ ! -f '/mnt/dietpi_userdata/domoticz/domoticz.conf' ]]; then + 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" + 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" + file='spotifyd-linux-full' + ;; + esac - G_EXEC cp /opt/domoticz/scripts/domoticz.conf /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'http_port=' 'http_port=8124' /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'ssl_port=' 'ssl_port=8424' /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'ssl_cert=' 'ssl_cert=/opt/domoticz/server_cert.pem' /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'ssl_key=' 'ssl_key=/opt/domoticz/server_cert.pem' /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'ssl_dhparam=' 'ssl_dhparam=/opt/domoticz/server_cert.pem' /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'loglevel=' 'loglevel=error' /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'syslog=' 'syslog=local7' /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'dbase_file=' "dbase_file=/mnt/dietpi_userdata/domoticz/domoticz.db" /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'app_path=' 'app_path=/opt/domoticz' /mnt/dietpi_userdata/domoticz/domoticz.conf - G_CONFIG_INJECT 'userdata_path=' "userdata_path=/mnt/dietpi_userdata/domoticz" /mnt/dietpi_userdata/domoticz/domoticz.conf + # Reinstall: Remove old install dir + [[ -d '/opt/spotifyd' ]] && G_EXEC rm -R /opt/spotifyd - fi + # x86_64 only deps: Both ARM binaries are not compiled against these. dbus would be required for MPRIS support, but let's keep it slim for now. + (( $G_HW_ARCH == 10 )) && DEPS_LIST='libdbus-1-3 libpulse0' - # User - Create_User -G dialout -d /mnt/dietpi_userdata/domoticz domoticz + Download_Install "$(curl -sSfL 'https://api.github.com/repos/Spotifyd/spotifyd/releases/latest' | mawk -F\" "/\"browser_download_url\": .*\/$file\.tar\.gz\"/{print \$4}")" /opt/spotifyd - # Permissions - G_EXEC chown -R domoticz:domoticz /opt/domoticz /mnt/dietpi_userdata/domoticz + # User + Create_User -g audio -d /mnt/dietpi_userdata/spotifyd spotifyd - # Copy scripts directory to data dir: https://dietpi.com/phpbb/viewtopic.php?t=8627 - G_EXEC cp -a /opt/domoticz/scripts /mnt/dietpi_userdata/domoticz/ + # Config: Do not touch on reinstall + if [[ ! -f '/mnt/dietpi_userdata/spotifyd/spotifyd.conf' ]] + then + G_EXEC mkdir -p /mnt/dietpi_userdata/spotifyd/cache + dps_index=$software_id Download_Install 'spotifyd.conf' /mnt/dietpi_userdata/spotifyd/spotifyd.conf + G_EXEC chmod 0600 /mnt/dietpi_userdata/spotifyd/spotifyd.conf + fi # Service - cat << '_EOF_' > /etc/systemd/system/domoticz.service + cat << '_EOF_' > /etc/systemd/system/spotifyd.service [Unit] -Description=Domoticz (DietPi) +Description=Spotifyd (DietPi) Wants=network-online.target -After=network-online.target +After=network-online.target sound.target [Service] -User=domoticz -ExecStart=/opt/domoticz/domoticz -f /mnt/dietpi_userdata/domoticz/domoticz.conf +User=spotifyd +WorkingDirectory=/mnt/dietpi_userdata/spotifyd +ExecStart=/opt/spotifyd/spotifyd --no-daemon --config-path=/mnt/dietpi_userdata/spotifyd/spotifyd.conf [Install] WantedBy=multi-user.target _EOF_ + # Permissions + G_EXEC chown -R spotifyd:root /mnt/dietpi_userdata/spotifyd + G_EXEC chmod +x /opt/spotifyd/spotifyd fi - software_id=158 # MinIO - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Config - [[ -f '/etc/default/minio' ]] || cat << '_EOF_' > /etc/default/minio -# Default file path -MINIO_VOLUMES="/mnt/dietpi_userdata/minio-data" -# Use if you want to run MinIO on a custom port. -#MINIO_OPTS="--address :9199" -# Access key of the server. -#MINIO_ACCESS_KEY=Server-Access-Key -# Secret key of the server. -#MINIO_SECRET_KEY=Server-Secret-Key -_EOF_ - fi - software_id=185 # Portainer if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - Banner_Configuration + Banner_Installing # Restart Docker service to be able to deploy the container G_DIETPI-NOTIFY 2 'Docker will be restarted to be able to deploy the container.' @@ -13085,205 +12610,110 @@ _EOF_ fi - software_id=161 # FuguHub - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Setup Filestore DietPi appropriate - # IF already present just create symlink - if [[ ! -d '/mnt/dietpi_userdata/fuguhub-data' ]]; then - - # Move installed filestore to dietpi userdata - mkdir -p /mnt/dietpi_userdata/fuguhub-data - mv /home/bd/disk/* /mnt/dietpi_userdata/fuguhub-data/ - # Set permissions - chown -R bd:bd /mnt/dietpi_userdata/fuguhub-data/ - #setfacl -R -m u:bd:rwx /mnt/dietpi_userdata/fuguhub-data/ - - fi - - # Removed 'actual' folder to make way for symlink - rm -Rf /home/bd/disk - # Create symlink - ln -s /mnt/dietpi_userdata/fuguhub-data /home/bd/disk - - fi - - software_id=165 # Gitea - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration - - # Logs - mkdir -p /var/log/gitea - - # Permissions - chown -R dietpi:dietpi /var/log/gitea /mnt/dietpi_userdata/gitea - chmod +x /mnt/dietpi_userdata/gitea/gitea - - # Database - /boot/dietpi/func/create_mysql_db gitea gitea "$GLOBAL_PW" + } - # Service - cat << '_EOF_' > /etc/systemd/system/gitea.service -[Unit] -Description=Gitea (DietPi) + Apply_SSHServer_Choices(){ -[Service] -User=dietpi -WorkingDirectory=/mnt/dietpi_userdata/gitea/gitea-repositories -Environment=USER=dietpi HOME=/mnt/dietpi_userdata/gitea -ExecStart=/mnt/dietpi_userdata/gitea/gitea web + # 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 -[Install] -WantedBy=multi-user.target -_EOF_ + # No SSH server + if (( $INDEX_SSHSERVER_TARGET == 0 )); then - fi + # Check currently installed SSH servers via "dpkg --get-selections" to be failsafe + local dpkg_out=$(dpkg --get-selections) - software_id=159 # Allo web UI: 160 for quick reinstall/update - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 || ${aSOFTWARE_INSTALL_STATE[160]} == 1 )); then + 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 - Banner_Configuration + # Dropbear + elif (( $INDEX_SSHSERVER_TARGET == -1 )); then - # Create allo user for GUI - Create_User -G www-data -d /home/allo -s /bin/bash -p allo allo - # - Create home dir separately to avoid skeleton creation - [[ -d '/home/allo' ]] || G_EXEC mkdir -p /home/allo - G_EXEC chown -R allo:allo /home/allo - # - Grant sudo permissions - echo 'allo ALL=NOPASSWD: ALL' > /etc/sudoers.d/allo + aSOFTWARE_INSTALL_STATE[104]=1 - # Always Drop DB, and, recreate it, due to error issue with reinstall over the top. - G_EXEC systemctl restart mariadb - mysqladmin drop allo_db -f &> /dev/null - mysql -e 'drop user allo_db@localhost' &> /dev/null + # OpenSSH + elif (( $INDEX_SSHSERVER_TARGET == -2 )); then - /boot/dietpi/func/create_mysql_db allo_db allo_db dietpi - mysql allo_db < /var/www/allo_db.sql - G_EXEC rm /var/www/allo_db.sql + aSOFTWARE_INSTALL_STATE[105]=1 - # Redirect to web interface by default: - rm -f /var/www/index\.* - cat << '_EOF_' > /var/www/index.php - -_EOF_ - # Permissions - G_EXEC chown -R www-data:www-data /var/www/allo - G_EXEC chmod -R 0770 /var/www/allo + fi fi - software_id=163 # GMediaRender - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Configuration + } - # User - Create_User -G audio,render gmrender + Apply_FileServer_Choices(){ - # Service - cat << _EOF_ > /etc/systemd/system/gmrender.service -[Unit] -Description=GMediaRender (DietPi) -Documentation=https://github.com/hzeller/gmrender-resurrect/blob/master/INSTALL.md#commandline-options -Wants=network-online.target -After=network-online.target sound.target + # 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 -[Service] -User=gmrender -ExecStartPre=+/bin/bash -c '. /boot/dietpi/func/dietpi-globals; systemctl set-environment ACTIVE_IP=\$(G_GET_NET ip)' -ExecStart=/usr/local/bin/gmediarender -u '$G_HW_UUID' -f '$( /etc/systemd/system/mycroft.service -[Unit] -Description=Mycroft AI (DietPi) + Apply_Logging_Choices(){ -[Service] -Type=forking -User=mycroft -SyslogIdentifier=Mycroft AI -WorkingDirectory=/mnt/dietpi_userdata/mycroft-data -ExecStart=/mnt/dietpi_userdata/mycroft-core/start-mycroft.sh all -ExecStop=/mnt/dietpi_userdata/mycroft-core/stop-mycroft.sh + # 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 -[Install] -WantedBy=multi-user.target -_EOF_ - # Add Mycroft binaries to $PATH - G_EXEC eval "echo -e '#!/bin/dash\nexport PATH=$PATH:/mnt/dietpi_userdata/mycroft-core/bin' > /etc/bashrc.d/mycroft.sh" + # None + if (( $INDEX_LOGGING_TARGET == 0 )); then - # Enable ALSA automatic software conversion plugin - local soundcard=$(sed -n '/^[[:blank:]]*CONFIG_SOUNDCARD=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - soundcard=${soundcard%-eq} soundcard=${soundcard%-plug} - /boot/dietpi/func/dietpi-set_hardware soundcard "$soundcard-plug" + (( ${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 - fi + # RAMlog - clear every hour + elif (( $INDEX_LOGGING_TARGET == -1 )); then - software_id=178 # Jellyfin - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 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 - Banner_Configuration + # RAMlog - backup every hour to /root/logfile_storage, then clear + elif (( $INDEX_LOGGING_TARGET == -2 )); then - # Grant dietpi group permissions and assure video access - Create_User -G dietpi,video,render -d /mnt/dietpi_userdata/jellyfin jellyfin + 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 - # Config: Only apply on fresh install, assumed when /mnt/dietpi_userdata/jellyfin does not yet exist - if [[ ! -d '/mnt/dietpi_userdata/jellyfin' ]]; then + # Logrotate + Rsyslog - logs to disk + elif (( $INDEX_LOGGING_TARGET == -3 )); 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 - 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 - G_CONFIG_INJECT 'JELLYFIN_CACHE_DIR=' 'JELLYFIN_CACHE_DIR=/mnt/dietpi_userdata/jellyfin/cache' /etc/default/jellyfin + aSOFTWARE_INSTALL_STATE[101]=1 + aSOFTWARE_INSTALL_STATE[102]=1 + (( ${aSOFTWARE_INSTALL_STATE[103]} == 2 )) && aSOFTWARE_INSTALL_STATE[103]=-1 UNINSTALL_REQUIRED=1 fi - # Permissions - G_EXEC chown -R jellyfin: /mnt/dietpi_userdata/jellyfin - - Download_Test_Media + # Update current logging index + INDEX_LOGGING_CURRENT=$INDEX_LOGGING_TARGET fi @@ -13407,7 +12837,7 @@ _EOF_ Banner_Uninstalling apt-mark auto gnome-icon-theme tango-icon-theme upower policykit-1 2> /dev/null - G_AGP xfce4 + G_AGP xfce4 xfce4-* fi @@ -13898,7 +13328,7 @@ _EOF_ fi - software_id=132 + software_id=132 # Aria2 if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -14364,10 +13794,11 @@ _EOF_ fi software_id=187 # CUPS - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )) + then Banner_Uninstalling G_AGP cups - [[ -d '/etc/cups' ]] && rm -R /etc/cups + [[ -d '/etc/cups' ]] && G_EXEC rm -R /etc/cups fi software_id=121 # Roon Bridge @@ -15029,7 +14460,7 @@ _EOF_ fi - software_id=48 + software_id=48 # Pydio if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -16409,10 +15840,6 @@ _EOF_ # Uninstall software, if required by e.g. DietPi choice system (( $UNINSTALL_REQUIRED )) && Uninstall_Software - # Configure software, stop services of newly installed APT packages to reduce memory usage during config steps - /boot/dietpi/dietpi-services stop - Configure_Software - G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Finalising install' # Reload systemd units @@ -17973,7 +17400,6 @@ List of installed software and their online documentation URLs: # Banner Print #///////////////////////////////////////////////////////////////////////////////////// Banner_Installing(){ G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" "Installing ${aSOFTWARE_NAME[$software_id]}: ${aSOFTWARE_DESC[$software_id]}"; } - Banner_Configuration(){ G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" "Configuring ${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(){ From e906e71af930164892b2ad8eadbee2f933a651ac Mon Sep 17 00:00:00 2001 From: MichaIng Date: Fri, 5 Nov 2021 04:41:15 +0100 Subject: [PATCH 78/82] v7.8 + DietPi-Software | Further cleanup and coding enhancements --- dietpi/dietpi-software | 173 ++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 88 deletions(-) diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index d62d1b1a4c..ffd395075f 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -213,7 +213,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" fi # Available for (need to match highest value in dietpi-obtain_hw_model) - readonly MAX_G_HW_MODEL=73 + readonly MAX_G_HW_MODEL=74 readonly MAX_G_HW_ARCH=10 #readonly MAX_G_DISTRO=7 # - 2D array (well, bash style) @@ -1886,7 +1886,7 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" software_id=18 aSOFTWARE_NAME[$software_id]='Emacs' - aSOFTWARE_DESC[$software_id]='gnu emacs editor' + aSOFTWARE_DESC[$software_id]='GNU Emacs editor' aSOFTWARE_CATX[$software_id]=27 #------------------ software_id=19 @@ -2727,17 +2727,16 @@ _EOF_ elif (( $G_HW_MODEL == 10 )); then local apackages=() - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali400-odroid(,|$)' && apackages+=('mali400-odroid') - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* libump-odroid(,|$)' && apackages+=('libump-odroid') - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* xf86-video-mali-odroid(,|$)' && apackages+=('xf86-video-mali-odroid') + apt-cache dumpavail | grep -q '^Package: mali400-odroid$' && apackages+=('mali400-odroid') || apackages+=('libegl1' 'libgles2') + apt-cache dumpavail | grep -q '^Package: xf86-video-mali-odroid$' && apackages+=('libump-odroid' 'xf86-video-mali-odroid') G_AGI "${apackages[@]}" # Odroid XU4 elif (( $G_HW_MODEL == 11 )); then local apackages=() - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malit628-odroid(,|$)' && apackages+=('malit628-odroid') - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* xf86-video-armsoc-odroid(,|$)' && apackages+=('xf86-video-armsoc-odroid') + apt-cache dumpavail | grep -q '^Package: malit628-odroid$' && apackages+=('malit628-odroid') || apackages+=('libegl1' 'libgles2') + apt-cache dumpavail | grep -q '^Package: xf86-video-armsoc-odroid$' && apackages+=('xf86-video-armsoc-odroid') G_AGI "${apackages[@]}" # xf86-video-armsoc-odroid creates an xorg.conf @@ -2745,9 +2744,8 @@ _EOF_ elif (( $G_HW_MODEL == 12 )); then DEPS_LIST= - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali450-odroid(,|$)' && DEPS_LIST='mali450-odroid' - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* libump-odroid(,|$)' && DEPS_LIST+=' libump-odroid' - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* xf86-video-fbturbo-odroid(,|$)' && DEPS_LIST+=' xf86-video-fbturbo-odroid' + apt-cache dumpavail | grep -q '^Package: mali450-odroid$' && DEPS_LIST='mali450-odroid' || DEPS_LIST='libegl1 libgles2' + apt-cache dumpavail | grep -q '^Package: xf86-video-fbturbo-odroid$' && DEPS_LIST+=' libump-odroid xf86-video-fbturbo-odroid' G_BACKUP_FP /etc/X11/xorg.conf dps_index=$software_id Download_Install 'xorg_c2.conf' /etc/X11/xorg.conf @@ -2755,14 +2753,14 @@ _EOF_ elif (( $G_HW_MODEL == 15 )); then local apackages=('xserver-xorg-video-fbdev') - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malig52-fbdev-opencl-odroid(,|$)' && apackages+=('malig52-fbdev-opencl-odroid') + apt-cache dumpavail | grep -q '^Package: malig52-fbdev-opencl-odroid$' && apackages+=('malig52-fbdev-opencl-odroid') || apackages+=('libegl1' 'libgles2') G_AGI "${apackages[@]}" # Odroid C4 elif (( $G_HW_MODEL == 16 )); then local apackages=('xserver-xorg-video-fbdev') - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malig31-fbdev-opencl-odroid(,|$)' && apackages+=('malig31-fbdev-opencl-odroid') + apt-cache dumpavail | grep -q '^Packagerovides: malig31-fbdev-opencl-odroid$' && apackages+=('malig31-fbdev-opencl-odroid') || apackages+=('libegl1' 'libgles2') G_AGI "${apackages[@]}" fi @@ -2809,7 +2807,7 @@ _EOF_ fi - software_id=20 + software_id=20 # Vim if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing @@ -2817,7 +2815,7 @@ _EOF_ fi - software_id=21 + software_id=21 # Vim-Tiny if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing @@ -2833,7 +2831,7 @@ _EOF_ fi - software_id=18 + software_id=18 # Emacs if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing @@ -2944,14 +2942,11 @@ _EOF_ # On Stretch + Buster Dropbear packages have been split, install "dropbear-run" only, to have active service, but skip "dropbear-initramfs" # On Bullseye+ "dropbear-run" has become a transitional dummy package for "dropbear" which does not include "dropbear-initramfs" anymore. - if (( $G_DISTRO > 5 )); then - + if (( $G_DISTRO > 5 )) + then G_AGI dropbear - else - G_AGI dropbear-run - fi # Enable Dropbear daemon @@ -2985,7 +2980,7 @@ _EOF_ # Allow root login G_CONFIG_INJECT 'PermitRootLogin[[:blank:]]' 'PermitRootLogin yes' /etc/ssh/sshd_config - # Reload SSH server now so root users can login during setup. + # Reload SSH server now so root users can login during setup systemctl reload ssh # Failsafe: Enable OpenSSH service @@ -3361,24 +3356,6 @@ _EOF_ fi - software_id=67 # Firefox - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then - - Banner_Installing - - # Apply preference index - INDEX_BROWSER_TARGET=-1 INDEX_BROWSER_CURRENT=-1 - - G_AGI firefox-esr - - # Config - #G_CONFIG_INJECT 'pref\("extensions.update.enabled"' 'pref("extensions.update.enabled", false);' /etc/firefox-esr/firefox-esr.js - #G_CONFIG_INJECT 'pref\("datareporting.healthreport.uploadEnabled"' 'pref("datareporting.healthreport.uploadEnabled", false);' /etc/firefox-esr/firefox-esr.js - #G_CONFIG_INJECT 'pref\("browser.cache.disk.parent_directory"' 'pref("browser.cache.disk.parent_directory", "/tmp/firefox_cache");' /etc/firefox-esr/firefox-esr.js - #G_CONFIG_INJECT 'pref\("general.smoothScroll"' 'pref("general.smoothScroll", false);' /etc/firefox-esr/firefox-esr.js - - fi - software_id=173 # LXQt if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -3453,6 +3430,14 @@ _EOF_ fi + software_id=175 # Xfce Power Manager + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + G_AGI xfce4-power-manager + + fi + software_id=22 # QuiteRSS if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -3461,19 +3446,29 @@ _EOF_ fi - software_id=174 # GIMP + software_id=67 # Firefox if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_AGI gimp + + # Apply preference index + INDEX_BROWSER_TARGET=-1 INDEX_BROWSER_CURRENT=-1 + + G_AGI firefox-esr + + # Config + #G_CONFIG_INJECT 'pref\("extensions.update.enabled"' 'pref("extensions.update.enabled", false);' /etc/firefox-esr/firefox-esr.js + #G_CONFIG_INJECT 'pref\("datareporting.healthreport.uploadEnabled"' 'pref("datareporting.healthreport.uploadEnabled", false);' /etc/firefox-esr/firefox-esr.js + #G_CONFIG_INJECT 'pref\("browser.cache.disk.parent_directory"' 'pref("browser.cache.disk.parent_directory", "/tmp/firefox_cache");' /etc/firefox-esr/firefox-esr.js + #G_CONFIG_INJECT 'pref\("general.smoothScroll"' 'pref("general.smoothScroll", false);' /etc/firefox-esr/firefox-esr.js fi - software_id=175 # Xfce Power Manager + software_id=174 # GIMP if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_AGI xfce4-power-manager + G_AGI gimp fi @@ -3601,11 +3596,11 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_AGI vsftpd - # Config - G_BACKUP_FP /etc/vsftpd.conf - dps_index=$software_id Download_Install 'conf' /etc/vsftpd.conf + # Config: Preserve on reinstall + [[ -f '/etc/vsftpd.conf' ]] || dps_index=$software_id Download_Install 'conf' /etc/vsftpd.conf + + G_AGI vsftpd # Do not allow root access via FTP G_EXEC sed -i 's/^[[:blank:]]*root/#root/' /etc/ftpusers @@ -3679,7 +3674,7 @@ _EOF_ G_AGI "${apackages[@]}" # Custom configs, included by sites-enabled/default within server directive, while nginx/(conf.d|sites-enabled) is included by nginx.conf outside server directive - G_EXEC mkdir -p /etc/nginx/sites-dietpi + [[ -d '/etc/nginx/sites-dietpi' ]] || G_EXEC mkdir /etc/nginx/sites-dietpi G_BACKUP_FP /etc/nginx/nginx.conf dps_index=$software_id Download_Install 'nginx.conf' /etc/nginx/nginx.conf @@ -3852,7 +3847,7 @@ _EOF_ G_AGI "${apackages[@]}" # Enable redis php module, if installed - phpenmod redis 2> /dev/null + 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 G_CONFIG_INJECT 'loglevel[[:blank:]]' 'loglevel warning' /etc/redis/redis.conf @@ -3940,17 +3935,17 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et 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 + sed -i '/cgi.fix_pathinfo=/c\cgi.fix_pathinfo=1' "$FP_PHP_BASE_DIR/fpm/php.ini" # 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 + 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 + 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" fi @@ -4004,9 +3999,9 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et # PHP info page echo '' > /var/www/phpinfo.php # OPcache info page - G_THREAD_START curl -sSfL https://raw.githubusercontent.com/amnuts/opcache-gui/master/index.php -o /var/www/opcache.php + G_THREAD_START curl -sSfL 'https://raw.githubusercontent.com/amnuts/opcache-gui/master/index.php' -o /var/www/opcache.php # APCu info page - G_THREAD_START curl -sSfL https://raw.githubusercontent.com/krakjoe/apcu/master/apc.php -o /var/www/apc.php + G_THREAD_START curl -sSfL 'https://raw.githubusercontent.com/krakjoe/apcu/master/apc.php' -o /var/www/apc.php G_THREAD_WAIT @@ -4611,9 +4606,9 @@ _EOF_ fi # Remove obsolete config + data directories and SysV service + config - [[ -d '/var/lib/fahclient' ]] && rm -R /var/lib/fahclient - [[ -d '/etc/fahclient' ]] && rm -R /etc/fahclient - [[ -f '/etc/default/fahclient' ]] && rm /etc/default/fahclient + [[ -d '/var/lib/fahclient' ]] && G_EXEC rm -R /var/lib/fahclient + [[ -d '/etc/fahclient' ]] && G_EXEC rm -R /etc/fahclient + [[ -f '/etc/default/fahclient' ]] && G_EXEC rm /etc/default/fahclient Remove_SysV FAHClient # Prepare our new config + data directory if not yet present @@ -5445,21 +5440,15 @@ _EOF_ [[ -d '/etc/roonbridge' ]] && G_EXEC rm -R /etc/roonbridge G_EXEC mv RoonBridge /etc/roonbridge - # User: !!! root required for remote updates - #Create_User -g dietpi -G audio -d /mnt/dietpi_userdata/roon roon - dps_index=$software_id Download_Install 'roonbridge.service' /etc/systemd/system/roonbridge.service - # Move log files to /var/log (dietpi-ramlog) + # Log to /var/log/roon G_EXEC mkdir -p /var/log/roon /mnt/dietpi_userdata/roon/{RoonBridge,RAATServer} # - Clear symlink locations G_EXEC rm -Rf /mnt/dietpi_userdata/roon/{RoonBridge,RAATServer}/Logs G_EXEC ln -s /var/log/roon /mnt/dietpi_userdata/roon/RoonBridge/Logs G_EXEC ln -s /var/log/roon /mnt/dietpi_userdata/roon/RAATServer/Logs - # Permissions - #chown -R roon:dietpi /mnt/dietpi_userdata/roon /var/log/roon - fi software_id=119 # CAVA @@ -5609,39 +5598,39 @@ _EOF_ if [[ $G_HW_MODEL == 1[0-9] ]]; then # Odroid C1/C2/N2/C4 - [[ $G_HW_MODEL == 1[0256] ]] && apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* aml-libs-odroid(,|$)' && apackages+=('aml-libs-odroid') + [[ $G_HW_MODEL == 1[0256] ]] && apt-cache dumpavail | grep -q '^Package: aml-libs-odroid$' && apackages+=('aml-libs-odroid') # Odroid C1 if (( $G_HW_MODEL == 10 )) then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali400-odroid(,|$)' && apackages+=('mali400-odroid') + apt-cache dumpavail | grep -q '^Package: mali400-odroid$' && apackages+=('mali400-odroid') || apackages+=('libgles2') # Odroid XU4 elif (( $G_HW_MODEL == 11 )) then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malit628-odroid(,|$)' && apackages+=('malit628-odroid') - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* firmware-samsung(,|$)' && apackages+=('firmware-samsung') + apt-cache dumpavail | grep -q '^Package: malit628-odroid$' && apackages+=('malit628-odroid') || apackages+=('libgles2') + apt-cache dumpavail | grep -q '^Package: firmware-samsung$' && apackages+=('firmware-samsung') # Odroid C2 elif (( $G_HW_MODEL == 12 )) then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* mali450-odroid(,|$)' && apackages+=('mali450-odroid') + apt-cache dumpavail | grep -q '^Package: mali450-odroid$' && apackages+=('mali450-odroid') || apackages+=('libgles2') # Odroid N2 elif (( $G_HW_MODEL == 15 )) then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malig52-fbdev-opencl-odroid(,|$)' && apackages+=('malig52-fbdev-opencl-odroid') + apt-cache dumpavail | grep -q '^Package: malig52-fbdev-opencl-odroid$' && apackages+=('malig52-fbdev-opencl-odroid') || apackages+=('libgles2') # Odroid C4 elif (( $G_HW_MODEL == 16 )) then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* malig31-fbdev-opencl-odroid(,|$)' && apackages+=('malig31-fbdev-opencl-odroid') + apt-cache dumpavail | grep -q '^Package: malig31-fbdev-opencl-odroid$' && apackages+=('malig31-fbdev-opencl-odroid') || apackages+=('libgles2') fi # Odroid N2/C4 if [[ $G_HW_MODEL == 1[56] ]] then - apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* kodi-aml-fbdev-odroid(,|$)' && apackages+=('kodi-aml-fbdev-odroid') || apackages=('kodi') + apt-cache dumpavail | grep -q '^Package: kodi-aml-fbdev-odroid$' && apackages+=('kodi-aml-fbdev-odroid') || apackages=('kodi') echo 'media_clock firmware decoder_common @@ -5666,7 +5655,7 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-n2-kodi.conf 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 -qE '^P(ackage|rovides):.* kodi-odroid(,|$)' && apackages+=('kodi-odroid') || apackages=('kodi') + apt-cache dumpavail | grep -q '^Package: kodi-odroid$' && apackages+=('kodi-odroid') || apackages=('kodi') fi # RPi Raspbian Bullseye @@ -6116,7 +6105,7 @@ _EOF_ # APT key local url='https://webmin.com/jcameron-key.asc' G_CHECK_URL "$url" - G_EXEC eval "curl -sSLf '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-webmin.gpg --yes" + G_EXEC eval "curl -sSfL '$url' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-webmin.gpg --yes" # APT list G_EXEC eval "echo 'deb https://download.webmin.com/download/repository/ sarge contrib' > /etc/apt/sources.list.d/webmin.list" @@ -6150,13 +6139,14 @@ _EOF_ Banner_Installing - DEPS_LIST='python3' + DEPS_LIST='python3' Download_Install 'https://yt-dl.org/downloads/latest/youtube-dl' /usr/local/bin/youtube-dl + G_EXEC chmod +x /usr/local/bin/youtube-dl # youtube-dl supports Python 2 and Python 3, but its shebang calls Python 2, else fails: https://github.com/ytdl-org/youtube-dl/issues/27649 - # We hence install the binary with Python 2 suffix and create a shell wrapper to call it with Python 3. - Download_Install 'https://yt-dl.org/downloads/latest/youtube-dl' /usr/local/bin/youtube-dl-py2 - echo -e '#!/bin/dash\nexec python3 /usr/local/bin/youtube-dl-py2 "$@"' > /usr/local/bin/youtube-dl - G_EXEC chmod +x /usr/local/bin/youtube-dl{,-py2} + G_EXEC sed -i '1s/python$/python3/' /usr/local/bin/youtube-dl + + # Remove obsolete /usr/local/bin/youtube-dl-py2 we used previously + [[ -f '/usr/local/bin/youtube-dl-py2' ]] && G_EXEC rm /usr/local/bin/youtube-dl-py2 fi @@ -15333,7 +15323,7 @@ _EOF_ fi - software_id=18 + software_id=18 # Emacs if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -15341,12 +15331,19 @@ _EOF_ fi - software_id=20 - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )) || - (( ${aSOFTWARE_INSTALL_STATE[21]} == -1 )); then + software_id=20 # Vim + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + + Banner_Uninstalling + G_AGP vim + + fi + + software_id=21 # Vim-Tiny + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - G_AGP vim vim-tiny + G_AGP vim-tiny fi From 3f6f8e0839bf1d45704eaa100187bfea2f151d9b Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 6 Nov 2021 20:09:17 +0100 Subject: [PATCH 79/82] v7.8 + DietPi-Config | That RPi Zero 2 W currently runs with max 1.4V by default is a bug and current rpi-update firmware sets this to 1.35V to align with most other models. This means that for the high overclocking profile we apply over_voltage=2 to assure that 1.4V is kept. It is unlikely that this profile runs stable with only 1.35V. --- dietpi/dietpi-config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dietpi/dietpi-config b/dietpi/dietpi-config index 122d7d1099..835f0a5aa1 100644 --- a/dietpi/dietpi-config +++ b/dietpi/dietpi-config @@ -3423,7 +3423,7 @@ Additional benchmarks: G_WHIP_MENU_ARRAY=( 'energy saving' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | -2 overvolt' 'default' ': 1000 MHz ARM | 400 MHz core | 450 MHz SDRAM | 0 overvolt' - 'high' ': 1100 MHz ARM | 450 MHz core | 450 MHz SDRAM | 0 overvolt' + 'high' ': 1100 MHz ARM | 450 MHz core | 450 MHz SDRAM | 2 overvolt' ) G_WHIP_MENU "Hardware : $G_HW_MODEL_NAME\nCurrent: $arm_freq_value MHz ARM | $core_freq_value MHz core | $sdram_freq_value MHz SDRAM | $over_voltage_value overvolt" || return 0 @@ -3437,6 +3437,7 @@ Additional benchmarks: G_CONFIG_INJECT 'over_voltage=' 'over_voltage=-2' /boot/config.txt ;; 'high') + G_CONFIG_INJECT 'over_voltage=' 'over_voltage=2' /boot/config.txt G_CONFIG_INJECT 'arm_freq=' 'arm_freq=1100' /boot/config.txt G_CONFIG_INJECT 'core_freq=' 'core_freq=450' /boot/config.txt ;; From eda313ff6151223d13934057fda151d82fc488de Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 6 Nov 2021 23:04:54 +0100 Subject: [PATCH 80/82] v7.8 + DietPi-Pre-patches | If an APT key expired already, it shows "expired: " instead of "expires: ". To be failsafe, accept both: It is definitely the expired key when expiration date is in 2021. --- .update/pre-patches | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.update/pre-patches b/.update/pre-patches index e42841f95b..f9c326e875 100644 --- a/.update/pre-patches +++ b/.update/pre-patches @@ -29,7 +29,7 @@ then fi # v7.1: Update Ondrej's PHP APT repo key: https://github.com/MichaIng/DietPi/issues/4219 -if apt-key list '95BD4743' 2> /dev/null | grep -q 'expires: 2021-' +if apt-key list '95BD4743' 2> /dev/null | grep -q 'expire[sd]: 2021-' then G_DIETPI-NOTIFY 2 'Updating PHP APT repo key: https://github.com/MichaIng/DietPi/issues/4219' G_EXEC apt-key del '95BD4743' From 2cf4b3e8a186028bc46a8b6758f61b44f92e7373 Mon Sep 17 00:00:00 2001 From: ravenclaw900 <50060110+ravenclaw900@users.noreply.github.com> Date: Sat, 6 Nov 2021 17:36:58 -0500 Subject: [PATCH 81/82] v7.8 (#4918) + DietPi-Software | DietPi-Dashboard: Thanks to the great work of @ravenclaw900, we are proud to announce our own official DietPi web interface for monitoring and managing your DietPi system using your web browser. It is still in beta phase as we test and gradually implement more features. We would be happy if you would try it out via "dietpi-software install 200" and give us feedback: https://github.com/MichaIng/DietPi/issues/448 + DietPi-Services | When printing the status, instead of removing a hardcoded number of 11 characters from the start of the line, remove the first field and delimiter. The number of leading spaces has changed with Bullseye, so that the colon of "Active:" was shown unintentionally. --- .meta/dietpi-survey_report | 1 + CHANGELOG.txt | 3 ++ README.md | 1 + dietpi.txt | 6 +++ dietpi/dietpi-services | 49 +----------------------- dietpi/dietpi-software | 78 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 47 deletions(-) diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index cc1736a9b1..6b574e8c99 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -575,6 +575,7 @@ shopt -s extglob done unset -v 'aSOFTWARE_NAME7_8[34]' # Subsonic unset -v 'aSOFTWARE_NAME7_8[99]' # emonHub + aSOFTWARE_NAME7_8[200]='DietPi-Dashboard' # 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[@]}" diff --git a/CHANGELOG.txt b/CHANGELOG.txt index edd0e4bc99..6917f3db1f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,6 +5,9 @@ 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 - Raspberry Pi Zero 2 W | Initial support for this Raspberry Pi Zero/Zero W successor has been added, using hardware ID 3 for now (shared with RPi 3/3+), including overclocking profiles. Many thank to @CassTG for providing early hardware information and doing intensive overclocking tests: https://dietpi.com/phpbb/viewtopic.php?t=9599 +New software: +- DietPi-Dashboard | Thanks to the great work of @ravenclaw900, we are proud to announce our own official DietPi web interface for monitoring and managing your DietPi system using your web browser. It is still in beta phase as we test and gradually implement more features. We would be happy if you would try it out via "dietpi-software install 200" and give us feedback: https://github.com/MichaIng/DietPi/issues/448 + Removed software: - Subsonic | Since it is not developed anymore and due to shared library dependencies only compatible with Debian Stretch, we removed Subsonic from DietPi-Software. With Airsonic-Advanced, we'll provide a well maintained and Bullseye-compatible alternative. If you currently have Subsonic installed, it will remain. If you want to uninstall it, follow the instructions here: https://github.com/MichaIng/DietPi/pull/4895 - emonHub | Since we do not have a single reported installation, we removed emonHub from DietPi-Software. If you currently have emonHub installed, it will remain. If you want to keep using and updating it, have a look at the official repository: https://github.com/openenergymonitor/emonhub. If you want to uninstall it, follow the instructions here: https://github.com/MichaIng/DietPi/pull/4895 diff --git a/README.md b/README.md index b0577fb335..f85931b5a3 100644 --- a/README.md +++ b/README.md @@ -315,6 +315,7 @@ Links to hardware and software manufacturers, sources and build instructions use - [Blynk Server](https://github.com/Peterkn2001/blynk-server) - [File Browser](https://github.com/filebrowser/filebrowser) - [Spotifyd](https://github.com/Spotifyd/spotifyd) +- [DietPi-Dashboard](https://github.com/ravenclaw900/dietpi-dashboard) --- diff --git a/dietpi.txt b/dietpi.txt index 03eaab7c17..600288b84e 100644 --- a/dietpi.txt +++ b/dietpi.txt @@ -269,6 +269,12 @@ SOFTWARE_HOMEASSISTANT_PIP_DEPS= # https://rancher.com/docs/k3s/latest/en/installation/install-options/#configuration-file SOFTWARE_K3S_EXEC= +# DietPi-Dashboard +# Version to use +# - Stable = Use release version of DietPi-Dashboard. +# - Nightly = Use unstable version DietPi-Dashboard. Might have bugs, but will probably have more features. +SOFTWARE_DIETPI_DASHBOARD_VERSION=Stable + #------------------------------------------------------------------------------------------------------ ##### Dev settings ##### #------------------------------------------------------------------------------------------------------ diff --git a/dietpi/dietpi-services b/dietpi/dietpi-services index 311116c2a4..975e508de0 100644 --- a/dietpi/dietpi-services +++ b/dietpi/dietpi-services @@ -234,6 +234,7 @@ Available services: # DietPi aSERVICE_NAME+=('dietpi-vpn') # NordVPN install + client + aSERVICE_NAME+=('dietpi-dashboard') # Web Dashboard if [[ $INPUT_CMD == 'status' ]]; then aSERVICE_NAME+=('dietpi-ramlog') @@ -275,7 +276,6 @@ _EOF_ while read -r line do - # Include if [[ $line == '+ '* ]]; then @@ -284,9 +284,7 @@ _EOF_ # - 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" @@ -299,7 +297,6 @@ _EOF_ for i in "${!aSERVICE_NAME[@]}" do - [[ $line == "${aSERVICE_NAME[$i]}" ]] || continue # Show in menu, but mark as excluded @@ -315,7 +312,6 @@ _EOF_ fi break - done fi @@ -339,13 +335,11 @@ _EOF_ local i j for i in "${!aSERVICE_NAME[@]}" do - [[ ${aSERVICE_NAME[$i]} ]] || { unset -v "aSERVICE_NAME[$i]"; continue; } # Failsafe # Check for sysvinit services from systemd-sysv-generator dir: /run/systemd/generator.late/ for j in /{{etc,usr/local/lib,lib,usr/lib}/systemd/system,run/systemd/generator.late}/"${aSERVICE_NAME[$i]}.service" do - [[ -e $j ]] || continue # Check masked state, in case continue to catch real file @@ -353,12 +347,10 @@ _EOF_ aFP_SERVICE[$i]=$j break - done # Remove non-available services from array [[ ${aFP_SERVICE[$i]} ]] || unset -v "aSERVICE_NAME[$i]" - done } @@ -387,9 +379,7 @@ _EOF_ for i in "${!aSERVICE_NAME[@]}" do - services="$i $services" - done # - start/restart: Standard service order @@ -410,12 +400,10 @@ _EOF_ # Apply command for i in $services do - [[ ${aSERVICE_MODE[$i]} == 'masked' ]] && { G_DIETPI-NOTIFY 2 "skip : ${aSERVICE_NAME[$i]} (due to mask)"; continue; } G_DIETPI-NOTIFY -2 "${aSERVICE_NAME[$i]}" systemctl "$command" "${aSERVICE_NAME[$i]}" &> /dev/null Print_Status "$command" "${aSERVICE_NAME[$i]}" $? - done # Disable ownCloud and Nextcloud maintenance mode after all services being started or restarted @@ -449,12 +437,11 @@ _EOF_ local status_full space status for i in $services do - status_full=$(systemctl -l --no-pager status "${aSERVICE_NAME[$i]}") # Align status output space='\t' (( ${#aSERVICE_NAME[$i]} < 13 )) && space+='\t'; (( ${#aSERVICE_NAME[$i]} < 5 )) && space+='\t' - status="${aSERVICE_NAME[$i]}${space}$(mawk '/Active/{print substr($0,12);exit}' <<< "$status_full")" + status="${aSERVICE_NAME[$i]}${space}$(mawk '/Active:/{$1="";print;exit}' <<< "$status_full")"; status=${status# } if [[ $status == *'failed'* ]]; then G_DIETPI-NOTIFY 1 "$status_full" @@ -468,7 +455,6 @@ _EOF_ G_DIETPI-NOTIFY 0 "$status" fi - done # dietpi_controlled/systemd_controlled/mask/unmask/enable/disable @@ -504,12 +490,10 @@ _EOF_ # Apply command for i in $services do - # Skip masked services, if not to be unmasked [[ ${aSERVICE_MODE[$i]} == 'masked' && $systemctl_cmd != 'unmask' ]] && { G_DIETPI-NOTIFY 2 "skip : ${aSERVICE_NAME[$i]} (due to mask)"; continue; } systemctl $systemctl_cmd "${aSERVICE_NAME[$i]}" &> /dev/null Print_Status "$command" "${aSERVICE_NAME[$i]}" $? - done fi @@ -620,10 +604,8 @@ _EOF_ for i in "${!aSERVICE_NAME[@]}" do - aSERVICE_MODE[$i]=$(systemctl is-enabled "${aSERVICE_NAME[$i]}" 2> /dev/null) Load_Process_Tool "$i" - done } @@ -648,7 +630,6 @@ _EOF_ local service_restart_list_menu aservice_restart_list_systemd=() i for i in "${!aSERVICE_RESTART_REQUIRED[@]}" do - service_restart_list_menu+="\n - ${aSERVICE_NAME[$i]}: " [[ ${aCPU_AFFINITY[$i]} ]] && service_restart_list_menu+="Affinity=${aCPU_AFFINITY[$i]} | " [[ ${aCPU_POLICY[$i]} ]] && service_restart_list_menu+="CPU Scheduling Policy=${aCPU_POLICY[$i]} | " @@ -657,7 +638,6 @@ _EOF_ [[ ${aIO_CLASS[$i]} ]] && service_restart_list_menu+="I/O Scheduling Class=${aIO_CLASS[$i]} | " [[ ${aIO_PRIORITY[$i]} ]] && service_restart_list_menu+="I/O Scheduling Priority=${aIO_PRIORITY[$i]} | " aservice_restart_list_systemd+=("${aSERVICE_NAME[$i]}") - done if [[ ${aservice_restart_list_systemd[0]} ]] && G_WHIP_YESNO "[ INFO ] The following services require a restart, in order to apply your chosen settings:${service_restart_list_menu%[|:] } @@ -685,9 +665,7 @@ _EOF_ G_WHIP_MENU_ARRAY=('' '●─ Single Service Options ') for i in "${!aSERVICE_NAME[@]}" do - G_WHIP_MENU_ARRAY+=("${aSERVICE_NAME[$i]}" ": $(systemctl is-active "${aSERVICE_NAME[$i]}") | Affinity ${aCPU_AFFINITY[$i]:-0-$(( $G_HW_CPU_CORES - 1 ))}") - done G_WHIP_MENU_ARRAY+=( @@ -710,29 +688,23 @@ _EOF_ # Find first empty index for ((i=0;i<=${#aSERVICE_MODE[@]};i++)) do - [[ ${aSERVICE_NAME[$i]} ]] || { new_index=$i; break; } - done while G_WHIP_INPUTBOX "${not_found}Please add the name of the service to be added, without the \".service\" file ending:" do - if [[ $G_WHIP_RETURNED_VALUE ]]; then # Check for known services for i in "${aSERVICE_NAME[@]}" do - [[ $G_WHIP_RETURNED_VALUE == "$i" ]] || continue not_found="[FAILED] The service name you entered ($G_WHIP_RETURNED_VALUE) is already handled by DietPi-Services. Please retry or cancel.\n\n" continue 2 - done for i in /{{etc,usr/local/lib,lib,usr/lib}/systemd/system,run/systemd/generator.late}/"$G_WHIP_RETURNED_VALUE.service" do - [[ -f $i ]] || continue aSERVICE_NAME[$new_index]=$G_WHIP_RETURNED_VALUE @@ -741,13 +713,11 @@ _EOF_ Load_Process_Tool "$new_index" G_CONFIG_INJECT "+ ${aSERVICE_NAME[$new_index]}" "+ ${aSERVICE_NAME[$new_index]}" $FP_INCLUDE_EXCLUDE break 2 - done fi not_found="[FAILED] Could not find a service file that matches your input ($G_WHIP_RETURNED_VALUE). Please retry or cancel.\n\n" - done elif [[ $G_WHIP_RETURNED_VALUE == 'Restart' || $G_WHIP_RETURNED_VALUE == 'Stop' ]]; then @@ -763,11 +733,9 @@ _EOF_ MENU_SERVICE_INDEX=-1 for i in "${!aSERVICE_NAME[@]}" do - [[ ${aSERVICE_NAME[$i]} == "$G_WHIP_RETURNED_VALUE" ]] || continue MENU_SERVICE_INDEX=$i break - done (( $MENU_SERVICE_INDEX >= 0 )) && MENU_TARGETID=1 @@ -974,9 +942,7 @@ Please uncomment and edit only the lines that you need to change.\n\nTo undo cha G_WHIP_CHECKLIST_ARRAY=() for ((i=0; i<$G_HW_CPU_CORES; i++)) do - G_WHIP_CHECKLIST_ARRAY+=("$i" 'CPU ' 'on') - done if G_WHIP_CHECKLIST "Please select the desired CPU Affinity for: ${aSERVICE_NAME[$MENU_SERVICE_INDEX]}\n @@ -985,10 +951,8 @@ Please uncomment and edit only the lines that you need to change.\n\nTo undo cha local new_affinity= for i in $G_WHIP_RETURNED_VALUE do - # taskset requires comma-seperated CPU indices [[ $new_affinity ]] && new_affinity+=",$i" || new_affinity=$i - done # Update affinity array with new value, if at least 1 item was selected, otherwise reset @@ -1003,9 +967,7 @@ Please uncomment and edit only the lines that you need to change.\n\nTo undo cha G_WHIP_MENU_ARRAY=('Reset' ': Reset CPU Scheduling Policy to system defaults') for i in "${!aCPU_POLICY_TYPE[@]}" do - G_WHIP_MENU_ARRAY+=("${aCPU_POLICY_TYPE[$i]}" ": ${aCPU_POLICY_DESC[$i]}" ) - done G_WHIP_DEFAULT_ITEM=$cpu_policy @@ -1086,7 +1048,6 @@ Info:\n - Negative values have a higher priority (eg: -10).\n - Positive values G_WHIP_MENU_ARRAY=('Reset' ': Reset CPU Scheduling Priority to system defaults') for ((i=$scale_value_highest; i>=$scale_value_lowest; i--)) do - if (( $i == $scale_value_lowest )); then desc='(Lowest priority)' @@ -1122,7 +1083,6 @@ Info:\n - Negative values have a higher priority (eg: -10).\n - Positive values fi G_WHIP_MENU_ARRAY+=("$i" ": $desc") - done G_WHIP_DEFAULT_ITEM=$cpu_priority @@ -1140,9 +1100,7 @@ Info:\n - Negative values have a higher priority (eg: -10).\n - Positive values G_WHIP_MENU_ARRAY=('Reset' ': Reset I/O Scheduling Class to system defaults') for i in "${!aIO_CLASS_TYPE[@]}" do - G_WHIP_MENU_ARRAY+=("${aIO_CLASS_TYPE[$i]}" ": ${aIO_CLASS_DESC[$i]}" ) - done G_WHIP_DEFAULT_ITEM=$io_class @@ -1179,7 +1137,6 @@ NB: This only has an effect on drives handled by the CFQ scheduler.\nRead about fi G_WHIP_MENU_ARRAY+=("$i" ": $desc") - done G_WHIP_DEFAULT_ITEM=$io_priority @@ -1263,7 +1220,6 @@ NB: This only has an effect on drives handled by the CFQ scheduler."; then until (( $MENU_TARGETID < 0 )) do - if (( $MENU_TARGETID == 1 )); then Menu_Service @@ -1273,7 +1229,6 @@ NB: This only has an effect on drives handled by the CFQ scheduler."; then Menu_Main fi - done fi diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index ffd395075f..eabe110333 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -1199,6 +1199,14 @@ INDEX_BROWSER_TARGET=$INDEX_BROWSER_TARGET" 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 DietPi web dashboard' + aSOFTWARE_CATX[$software_id]=8 + aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/dietpi_tools/#dietpi-dashboard' + # Remote Access #-------------------------------------------------------------------------------- software_id=68 @@ -3503,6 +3511,62 @@ _EOF_ fi + software_id=200 # DietPi-Dashboard + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + + # Stable release or nightly? + local version=$(sed -n '/^[[:blank:]]*SOFTWARE_DIETPI_DASHBOARD_VERSION=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + [[ $version == 'Nightly' ]] || version='Stable' + + G_WHIP_MENU_ARRAY=( + 'Stable' ': Use a release version of DietPi-Dashboard.' + 'Nightly' ': Use an unstable version of DietPi-Dashboard.' + ) + + G_WHIP_BUTTON_CANCEL_TEXT=$version + G_WHIP_DEFAULT_ITEM=$version + G_WHIP_MENU "Please choose which version of DietPi-Dashboard should be installed." && version=$G_WHIP_RETURNED_VALUE + + 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 + + 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 + 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 + +# TLS for HTTPS +tls = false +cert = "/path/to/cert" +key = "/path/to/key" +_EOF_ + cat << '_EOF_' > /etc/systemd/system/dietpi-dashboard.service +[Unit] +Description=Web Dashboard (DietPi) +Wants=network-online.target +After=network-online.target + +[Service] +ExecStart=/opt/dietpi-dashboard/dietpi-dashboard + +[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. + G_EXEC systemctl enable dietpi-dashboard + aSTART_SERVICES+=('dietpi-dashboard') + + fi + software_id=44 # Transmission if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -13648,6 +13712,20 @@ _EOF_ fi + software_id=200 # DietPi-Dashboard + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + + Banner_Uninstalling + if [[ -f '/etc/systemd/system/dietpi-dashboard.service' ]] + then + G_EXEC systemctl disable --now dietpi-dashboard + G_EXEC rm /etc/systemd/system/dietpi-dashboard.service + fi + [[ -d '/etc/systemd/system/dietpi-dashboard.service.d' ]] && G_EXEC rm -R /etc/systemd/system/dietpi-dashboard.service.d + [[ -d '/opt/dietpi-dashboard' ]] && G_EXEC rm -R /opt/dietpi-dashboard + + fi + software_id=146 # Tautulli if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then From e5a6a2a2841ed4683e10e686b2ef816e2fd92548 Mon Sep 17 00:00:00 2001 From: MichaIng Date: Sat, 6 Nov 2021 23:38:54 +0100 Subject: [PATCH 82/82] v7.8 + RC up --- .update/version | 2 +- dietpi/func/dietpi-globals | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.update/version b/.update/version index f4a522152f..18f9319d96 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=-1 +G_REMOTE_VERSION_RC=0 # Minimum DietPi version to allow update G_MIN_VERSION_CORE=6 G_MIN_VERSION_SUB=0 diff --git a/dietpi/func/dietpi-globals b/dietpi/func/dietpi-globals index 4520e47775..217dcf79cb 100644 --- a/dietpi/func/dietpi-globals +++ b/dietpi/func/dietpi-globals @@ -57,7 +57,7 @@ # - 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=-1 + [[ $G_DIETPI_VERSION_RC ]] || G_DIETPI_VERSION_RC=0 [[ $G_GITBRANCH ]] || G_GITBRANCH='master' [[ $G_GITOWNER ]] || G_GITOWNER='MichaIng' # - Save current version and Git branch