diff --git a/.conf/desktop/icons/dietpi-icon.png b/.conf/desktop/icons/dietpi-icon.png index f972fb16a3..0105445058 100644 Binary files a/.conf/desktop/icons/dietpi-icon.png and b/.conf/desktop/icons/dietpi-icon.png differ diff --git a/.conf/desktop/icons/justboom.png b/.conf/desktop/icons/justboom.png index 506452f2bf..e091e552e6 100644 Binary files a/.conf/desktop/icons/justboom.png and b/.conf/desktop/icons/justboom.png differ diff --git a/.conf/desktop/icons/kodi-icon.png b/.conf/desktop/icons/kodi-icon.png index 5c5a7d72e4..ed25246b87 100644 Binary files a/.conf/desktop/icons/kodi-icon.png and b/.conf/desktop/icons/kodi-icon.png differ diff --git a/.conf/dps_114/apache.nextcloud.conf b/.conf/dps_114/apache.nextcloud.conf index 98f59abf55..149fb4abff 100644 --- a/.conf/dps_114/apache.nextcloud.conf +++ b/.conf/dps_114/apache.nextcloud.conf @@ -1,6 +1,7 @@ +# Location: /etc/apache2/sites-available/dietpi-nextcloud.conf # Based on: https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#apache-web-server-configuration -# Redirect OCM/OCS provider requests to Nextcloud endpoint: +# Redirect OCM/OCS provider requests to Nextcloud endpoint Redirect permanent /ocm-provider /nextcloud/ocm-provider Redirect permanent /ocs-provider /nextcloud/ocs-provider @@ -13,4 +14,7 @@ Redirect permanent /ocs-provider /nextcloud/ocs-provider Dav off + # https://github.com/MichaIng/DietPi/issues/3694 + Header unset Content-Security-Policy + Header always unset Content-Security-Policy diff --git a/.conf/dps_6/xorg_c2.conf b/.conf/dps_6/xorg_c2.conf index 997247df61..e3581ba69f 100644 --- a/.conf/dps_6/xorg_c2.conf +++ b/.conf/dps_6/xorg_c2.conf @@ -1,9 +1,8 @@ -# Provided by @Meveric's setup-odroid: http://fuzon.co.uk/meveric/pool/main/s/setup-odroid/ +# Provided by @Meveric's setup-odroid: https://dietpi.com/meveric/pool/main/s/setup-odroid/ Section "Device" Identifier "FBTURBO" Driver "fbturbo" Option "fbdev" "/dev/fb0" - Option "SwapbuffersWait" "true" Option "alpha_swap" "true" EndSection diff --git a/.conf/dps_85/nginx.conf b/.conf/dps_85/nginx.conf index b6cabc61f7..3d8bcb11b6 100644 --- a/.conf/dps_85/nginx.conf +++ b/.conf/dps_85/nginx.conf @@ -25,8 +25,8 @@ http { charset utf-8; - # + Nginx - To avoid 2MB upload error: https://github.com/MichaIng/DietPi/issues/546 - client_max_body_size 2000M; + # Avoid > 2 MiB upload error: https://github.com/MichaIng/DietPi/issues/546 + client_max_body_size 512M; # Upstream to abstract back-end connection(s) for PHP upstream php { diff --git a/.conf/dps_93/apache.pihole.conf b/.conf/dps_93/apache.pihole.conf index 2c1f8be219..ac71caa7a0 100644 --- a/.conf/dps_93/apache.pihole.conf +++ b/.conf/dps_93/apache.pihole.conf @@ -2,6 +2,12 @@ # Admin panel + # Assure Referrer-Policy is not set to "no-referrer" since + # HTTP_ORIGIN != null is required for CORS check: https://github.com/MichaIng/DietPi/issues/3675 + # In case it's set, replace by second strict policy "same-origin". + Header edit Referrer-Policy "no-referrer" "same-origin" + Header always edit Referrer-Policy "no-referrer" "same-origin" + # Create response header for Pi-hole debugger Header set X-Pi-hole "The Pi-hole Web interface is working!" Header set X-Frame-Options "DENY" diff --git a/.conf/dps_94/conf b/.conf/dps_94/conf index ec3027cc7e..f0247fda76 100644 --- a/.conf/dps_94/conf +++ b/.conf/dps_94/conf @@ -1,50 +1,53 @@ -# D I E T - P I -# File Location -# /etc/proftpd/proftpd.conf +# DietPi ProFTPD default config +# Location: /etc/proftpd/proftpd.conf +# Docs: http://www.proftpd.org/docs/directives/linked/configuration.html # Includes DSO modules Include /etc/proftpd/modules.conf -# Set off to disable IPv6 support which is problematic on IPv4 only boxes. -UseIPv6 on -# If set on you can experience a longer connection delay in many cases. -IdentLookups off +# Set "off" to disable IPv6 support which is problematic on IPv4 only boxes. +UseIPv6 on +# If set "on" you can experience a longer connection delay in many cases. +IdentLookups off +UseReverseDNS off -ServerName "DietPi FTP" -ServerType standalone -DeferWelcome off +ServerName "DietPi FTP" +ServerType standalone +DeferWelcome off -MultilineRFC2228 on -DefaultServer on -ShowSymlinks on +MultilineRFC2228 on +DefaultServer on +ShowSymlinks on -TimeoutNoTransfer 120 -TimeoutStalled 120 -TimeoutIdle 240 -DisplayLogin welcome.msg -DisplayChdir .message true -ListOptions "-l" +# Permit resuming downloads +AllowRetrieveRestart On +# Permit resuming uploads +AllowStoreRestart On +TimeoutNoTransfer 120 +TimeoutStalled 120 +TimeoutIdle 240 +DisplayLogin welcome.msg +DisplayChdir .message true +ListOptions "-l" -DenyFilter \*.*/ +DenyFilter \*.*/ -DefaultRoot /mnt/dietpi_userdata +DefaultRoot /mnt/dietpi_userdata -Port 21 +Port 21 +MaxInstances 8 -MaxInstances 8 +RootLogin off +User dietpi +Group dietpi +Umask 002 002 +AllowOverwrite on -RootLogin off -User dietpi -Group dietpi - -Umask 022 022 -AllowOverwrite on TransferLog /var/log/proftpd/xferlog -SystemLog /var/log/proftpd/proftpd.log - -# to stop logging wtmp /var/log/wtmp: No such file or directory -Gordon Williams change +SystemLog /var/log/proftpd/proftpd.log +# Stop /var/log/wtmp logging: No such file or directory -Gordon Williams change WtmpLog off - +# /var/log/lastlog logging #UseLastlog on @@ -60,11 +63,11 @@ DelayEngine on -ControlsEngine off -ControlsMaxClients 2 -ControlsLog /var/log/proftpd/controls.log -ControlsInterval 5 -ControlsSocket /var/run/proftpd/proftpd.sock +ControlsEngine off +ControlsMaxClients 2 +ControlsLog /var/log/proftpd/controls.log +ControlsInterval 5 +ControlsSocket /run/proftpd/proftpd.sock diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 2858916606..0000000000 --- a/.gitattributes +++ /dev/null @@ -1,37 +0,0 @@ -# Auto detect text files and perform LF normalization -* text eol=lf - -# Zip -*.7z binary -*.zip binary -*.tar binary -*.bz2 binary - -# Graphics -*.png binary -*.jpg binary -*.jpeg binary -*.gif binary -*.tif binary -*.tiff binary -*.ico binary -# SVG treated as an asset (binary) by default. If you want to treat it as text, -# comment-out the following line and uncomment the line after. -*.svg binary -#*.svg text -*.eps binary - -# Custom for Visual Studio -*.cs diff=csharp - -# Standard to msysgit -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 96374c4e7f..0000000000 --- a/.gitignore +++ /dev/null @@ -1,43 +0,0 @@ -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# ========================= -# Operating System Files -# ========================= - -# OSX -# ========================= - -.DS_Store -.AppleDouble -.LSOverride - -# Thumbnails -._* - -# Files that might appear on external disk -.Spotlight-V100 -.Trashes - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk diff --git a/.meta/dietpi-fan_control b/.meta/dietpi-fan_control index 1fe8baf5ac..de62808118 100644 --- a/.meta/dietpi-fan_control +++ b/.meta/dietpi-fan_control @@ -465,6 +465,6 @@ EG: To run the fan at 50%, enter\n \"60\"" && STATIC_SPEED=$G_WHIP_RETURNED_ fi #----------------------------------------------------------------------------------- - G_DIETPI-NOTIFY -1 0 "$G_PROGRAM_NAME |" && exit 0 + G_DIETPI-NOTIFY -1 0 "$G_PROGRAM_NAME" && exit 0 #----------------------------------------------------------------------------------- } diff --git a/.meta/dietpi-imager b/.meta/dietpi-imager index 19132ad590..e374025746 100755 --- a/.meta/dietpi-imager +++ b/.meta/dietpi-imager @@ -23,13 +23,13 @@ G_CHECK_ROOTFS_RW FP_ORIGIN=$PWD # Store origin dir G_INIT - cd "$FP_ORIGIN" # Process everything in origin dir instead of /tmp/$G_PROGRAM_NAME + cd "$FP_ORIGIN" || exit 1 # Process everything in origin dir instead of /tmp/$G_PROGRAM_NAME # Import DietPi-Globals --------------------------------------------------------------- FP_SOURCE_IMG= FP_SOURCE= FP_ROOT_DEV= - FP_MNT_TMP="/tmp/$G_PROGRAM_NAME_rootfs" + FP_MNT_TMP="/tmp/${G_PROGRAM_NAME}_rootfs" ROOT_PARTITION_INDEX=0 OUTPUT_IMG_NAME= OUTPUT_IMG_EXT='img' @@ -38,7 +38,7 @@ CLONEZILLA_REPO='https://sourceforge.net/projects/clonezilla/files/clonezilla_live_alternative' DIETPI_REPO="https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH" - Delete_Loopback(){ losetup $FP_SOURCE &> /dev/null && G_EXEC losetup -d $FP_SOURCE; } + Delete_Loopback(){ losetup "$FP_SOURCE" &> /dev/null && G_EXEC losetup -d "$FP_SOURCE"; } G_EXIT_CUSTOM(){ @@ -77,23 +77,24 @@ NB: Only compatible with x86_64 systems!' || exit 1 CLONING_TOOL=$G_WHIP_RETURNED_VALUE + local drives if [[ $CLONING_TOOL == 'dd' ]]; then # List block devices, excluding RAM disks - G_WHIP_MENU_ARRAY=$(lsblk -rnpo PKNAME,FSTYPE) + drives=$(lsblk -rnpo PKNAME,FSTYPE) else OUTPUT_IMG_EXT='iso' # List block devices, excluding RAM disks and loop devices - G_WHIP_MENU_ARRAY=$(lsblk -rnpo PKNAME,FSTYPE -e 1,7) + drives=$(lsblk -rnpo PKNAME,FSTYPE -e 1,7) fi # Detect drives with a partition table, containing a partition with ext4 file system, excluding the hosts root FS drive - local host_rootfs_dev=$(lsblk -rnpo PKNAME,MOUNTPOINT | mawk '$2=="/" {print $1;exit}') - G_WHIP_MENU_ARRAY=($(mawk -v root=$host_rootfs_dev '{if ( $1!=root && $2=="ext4" ) print $1,$2}' <<< "$G_WHIP_MENU_ARRAY" | sort -u)) + G_WHIP_MENU_ARRAY=($(mawk -v root="$(lsblk -npo PKNAME "$G_ROOTFS_DEV")" '{if ( $1!=root && $2=="ext4" ) print $1,$2}' <<< "$drives" | sort -u)) + unset -v drives - if [[ ! $G_WHIP_MENU_ARRAY ]]; then + if [[ ! ${G_WHIP_MENU_ARRAY[0]} ]]; then G_DIETPI-NOTIFY 1 'No drive with an ext4 partition found, aborting...' G_DIETPI-NOTIFY 2 'Hint: This is the list of available block devices' @@ -103,18 +104,18 @@ fi # Visually separate dev name and size and add model and serial - for ((i=1;i<${#G_WHIP_MENU_ARRAY[@]};i+=2)); do G_WHIP_MENU_ARRAY[$i]=": $(lsblk -drno SIZE,MODEL,SERIAL ${G_WHIP_MENU_ARRAY[$i-1]})"; done + for ((i=1;i<${#G_WHIP_MENU_ARRAY[@]};i+=2)); do G_WHIP_MENU_ARRAY[$i]=": $(lsblk -drno SIZE,MODEL,SERIAL "${G_WHIP_MENU_ARRAY[$i-1]}")"; done G_WHIP_MENU 'Please select the drive you wish to create the image from: \nNB: All mounted partitions of the selected drive will be unmounted.' || exit 1 FP_SOURCE=$G_WHIP_RETURNED_VALUE G_DIETPI-NOTIFY 2 'Unmounting all mounted file systems of the selected source drive...' local mountpoint - for i in $FP_SOURCE?* + for i in "$FP_SOURCE"?* do - mountpoint=$(findmnt -no TARGET $i) - [[ $mountpoint ]] && G_EXEC umount -R $mountpoint + mountpoint=$(findmnt -no TARGET "$i") + [[ $mountpoint ]] && G_EXEC umount -R "$mountpoint" done @@ -137,32 +138,32 @@ # Create loopback device from .img file G_EXEC modprobe loop FP_SOURCE=$(losetup -f) - G_EXEC losetup $FP_SOURCE "$FP_SOURCE_IMG" - G_EXEC partprobe $FP_SOURCE - G_EXEC partx -u $FP_SOURCE + G_EXEC losetup "$FP_SOURCE" "$FP_SOURCE_IMG" + G_EXEC partprobe "$FP_SOURCE" + G_EXEC partx -u "$FP_SOURCE" G_DIETPI-NOTIFY 0 "Mounted the image ($FP_SOURCE_IMG) as loopback device: $FP_SOURCE" fi # Detect partitions and list for selection - G_WHIP_MENU_ARRAY=($(lsblk -npo NAME,SIZE ${FP_SOURCE}?*)) + G_WHIP_MENU_ARRAY=($(lsblk -npo NAME,SIZE "$FP_SOURCE"?*)) # Visually separate dev name and size and add FS type - for ((i=1;i<${#G_WHIP_MENU_ARRAY[@]};i+=2)); do G_WHIP_MENU_ARRAY[$i]=": $(lsblk -drno SIZE,FSTYPE ${G_WHIP_MENU_ARRAY[$i-1]})"; done + for ((i=1;i<${#G_WHIP_MENU_ARRAY[@]};i+=2)); do G_WHIP_MENU_ARRAY[$i]=": $(lsblk -drno SIZE,FSTYPE "${G_WHIP_MENU_ARRAY[$i-1]}")"; done G_WHIP_MENU 'Please select the OS root partition:' || exit 1 FP_ROOT_DEV=$G_WHIP_RETURNED_VALUE ROOT_PARTITION_INDEX=${FP_ROOT_DEV: -1} - G_WHIP_DEFAULT_ITEM='DietPi_--' - G_WHIP_INPUTBOX 'Please enter the filename for the new image:\n - DietPi_--\n - EG: DietPi_RPi-ARMv6-Buster' || exit 1 + G_WHIP_DEFAULT_ITEM='DietPi_RPi-ARMv6-Buster' + G_WHIP_INPUTBOX 'Please enter the filename for the new image:\n - DietPi_--\n - E.g.: DietPi_RPi-ARMv6-Buster' || exit 1 OUTPUT_IMG_NAME=$G_WHIP_RETURNED_VALUE # Check for existing file, in case offer backup. Skip if source is image file and matches output file already. - if [[ $PWD/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT != $FP_SOURCE_IMG && -f $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT ]]; then + if [[ $PWD/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT != "$FP_SOURCE_IMG" && -f $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT ]]; then G_WHIP_BUTTON_OK_TEXT='Overwrite' G_WHIP_BUTTON_CANCEL_TEXT='Backup' G_WHIP_YESNO "[WARNING] $PWD/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT already exists\n -Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT.bak?" || mv $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT{,.bak} +Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT.bak?" || mv "$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT"{,.bak} fi @@ -170,9 +171,6 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O Main(){ - # Create final image + archive in current dir - #cd /root - Menu_Main # Install required packages: fdisk is an own package since Debian Buster: https://packages.debian.org/fdisk @@ -181,7 +179,7 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O G_AG_CHECK_INSTALL_PREREQ parted zerofree p7zip $fdisk # Auto detect partition table type, failsafe detection of MBR to debug possibly other/unknown wording/partition table types - if [[ $(parted -s $FP_SOURCE print) == *'Partition Table: msdos'* ]]; then + if [[ $(parted -s "$FP_SOURCE" print) == *'Partition Table: msdos'* ]]; then G_DIETPI-NOTIFY 2 'MBR partition table detected' GPT=0 @@ -190,25 +188,25 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O # - "GPT PMBR size mismatch (4458495 != 15523839)" # - "Error: The backup GPT table is corrupt, but the primary appears OK, so that will be used." # - gdisk will correct this - elif [[ $(parted -s $FP_SOURCE print) == *'Partition Table: gpt'* ]]; then + elif [[ $(parted -s "$FP_SOURCE" print) == *'Partition Table: gpt'* ]]; then G_DIETPI-NOTIFY 2 'GPT partition table detected, applying gdisk fix...' GPT=1 G_AG_CHECK_INSTALL_PREREQ gdisk - sgdisk -g $FP_SOURCE + sgdisk -g "$FP_SOURCE" else - G_DIETPI-NOTIFY 1 "Unknown partition table type ($(parted -s $FP_SOURCE print | mawk '/^Partition Table:/ {print $3;exit}')), aborting..." + G_DIETPI-NOTIFY 1 "Unknown partition table type ($(parted -s "$FP_SOURCE" print | mawk '/^Partition Table:/{print $3;exit}')), aborting..." exit 1 fi - G_EXEC_OUTPUT= 1 G_EXEC e2fsck -f $FP_ROOT_DEV + G_EXEC_OUTPUT=1 G_EXEC e2fsck -fp "$FP_ROOT_DEV" # Remount image for any required edits G_EXEC mkdir -p $FP_MNT_TMP - G_EXEC mount $FP_ROOT_DEV $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 if G_WHIP_YESNO "Do you want to review/edit contained files? @@ -222,16 +220,17 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O export G_DIETPI_LOGIN=1 G_EXEC cd $FP_MNT_TMP bash &> /dev/tty < /dev/tty - G_EXEC cd $FP_ORIGIN + G_EXEC cd "$FP_ORIGIN" (( $reallow_dietpi_login )) && unset -v G_DIETPI_LOGIN fi sync + sleep 1 # Give the system 1 second to avoid "mount is busy" G_EXEC umount $FP_MNT_TMP G_EXEC rmdir $FP_MNT_TMP - G_EXEC partprobe $FP_SOURCE # Failsafe - G_EXEC partx -u $FP_SOURCE # Failsafe - G_EXEC_OUTPUT= 1 G_EXEC e2fsck -f $FP_ROOT_DEV || exit 1 # Failsafe + G_EXEC partprobe "$FP_SOURCE" # Failsafe + G_EXEC partx -u "$FP_SOURCE" # Failsafe + G_EXEC_OUTPUT=1 G_EXEC e2fsck -fp "$FP_ROOT_DEV" # Shrink file system to minimum # - Run multiple times until no change is done any more @@ -241,15 +240,15 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O while : do - resize2fs -M $FP_ROOT_DEV 2>&1 | tee resize2fs_out + resize2fs -M "$FP_ROOT_DEV" 2>&1 | tee resize2fs_out if out=$(grep -im1 'nothing to do!' resize2fs_out); then - FS_SIZE=$(mawk '{print $5}' <<< $out) # blocks + FS_SIZE=$(mawk '{print $5}' <<< "$out") # blocks BLOCK_SIZE=${out%%k) *} BLOCK_SIZE=${BLOCK_SIZE##*\(} # KiB # Re-add 4 MiB to be failsafe, was required on Raspbian Buster for successful boot FS_SIZE=$(( $FS_SIZE + 4096/$BLOCK_SIZE )) # blocks rm resize2fs_out - resize2fs $FP_ROOT_DEV $FS_SIZE + resize2fs "$FP_ROOT_DEV" $FS_SIZE G_DIETPI-NOTIFY 0 "Reduced RootFS size to $(( $FS_SIZE * $BLOCK_SIZE / 1024 + 1 )) MiB" FS_SIZE=$(( $FS_SIZE * $BLOCK_SIZE * 2 )) # blocks => 512 byte sectors break @@ -263,35 +262,30 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O done - # Estimate minimum end sector - PART_START=$(sfdisk -qlo Device,Start $FP_SOURCE | grep "^$FP_ROOT_DEV" | mawk '{print $2}') # 512 byte sectors - PART_END_CURRENT=$(sfdisk -qlo Device,End $FP_SOURCE | grep "^$FP_ROOT_DEV" | mawk '{print $2}') - PART_END_TARGET=$(( $PART_START + $FS_SIZE )) - - # Only try to shrink partition when new end sector is less than current end sector - if (( $PART_END_CURRENT > $PART_END_TARGET )); then + # Only resize partition when new size would be less than current size + if (( $( $FS_SIZE )); then G_DIETPI-NOTIFY 2 "Shrinking root partition to: $(( $FS_SIZE / 2048 + 1 )) MiB" - G_EXEC_OUTPUT=1 G_EXEC parted $FP_SOURCE unit s resizepart $ROOT_PARTITION_INDEX $PART_END_TARGET - G_EXEC partprobe $FP_SOURCE - G_EXEC partx -u $FP_SOURCE + G_EXEC_OUTPUT=1 G_EXEC eval "sfdisk --no-reread --no-tell-kernel -fN$ROOT_PARTITION_INDEX '$FP_SOURCE' <<< ',$FS_SIZE'" + G_EXEC partprobe "$FP_SOURCE" + G_EXEC partx -u "$FP_SOURCE" fi G_DIETPI-NOTIFY 2 'Overriding root partition free space with zeros to purge removed data and allow further archive size reduction...' - G_EXEC_OUTPUT=1 G_EXEC zerofree -v $FP_ROOT_DEV + G_EXEC_OUTPUT=1 G_EXEC zerofree -v "$FP_ROOT_DEV" sync # GPT images: # - "GPT PMBR size mismatch (4458495 != 15523839)" # - "Error: The backup GPT table is corrupt, but the primary appears OK, so that will be used." # - gdisk will correct this - (( $GPT )) && G_EXEC_OUTPUT=1 G_EXEC sgdisk -g $FP_SOURCE + (( $GPT )) && G_EXEC_OUTPUT=1 G_EXEC sgdisk -g "$FP_SOURCE" # Finished: Derive final image size from last partition end + failsafe buffer - G_EXEC partprobe $FP_SOURCE - G_EXEC partx -u $FP_SOURCE - IMAGE_SIZE=$(( ( $(sfdisk -qlo End $FP_SOURCE | tail -1) + 1 ) * 512 )) # 512 byte sectors => Byte + G_EXEC partprobe "$FP_SOURCE" + G_EXEC partx -u "$FP_SOURCE" + IMAGE_SIZE=$(( ( $(sfdisk -qlo End "$FP_SOURCE" | tail -1) + 1 ) * 512 )) # 512 byte sectors => Byte IMAGE_SIZE=$(( $IMAGE_SIZE + ( 512 * 256 ) )) # 64 byte for secondary GPT + safety net # Image file source @@ -300,25 +294,25 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O # Clear loop Delete_Loopback - G_DIETPI-NOTIFY 2 "Truncating final image file to actually used size: $(( $IMAGE_SIZE / 1024 / 1024 + 1 )) MiB" + G_DIETPI-NOTIFY 2 "Truncating final image file to actually used size: $(( $IMAGE_SIZE / 1024**2 + 1 )) MiB" G_EXEC truncate --size=$IMAGE_SIZE "$FP_SOURCE_IMG" # Rename, if source image != output image already - [[ $PWD/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT != $FP_SOURCE_IMG ]] && mv "$FP_SOURCE_IMG" $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT + [[ $PWD/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT != "$FP_SOURCE_IMG" ]] && mv "$FP_SOURCE_IMG" "$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT" # Check if there is enough free disk space to store the 7z file - NEEDED_FREE_SPACE=$(( $IMAGE_SIZE / 100 * 15 / 1024 / 1024 )) + NEEDED_FREE_SPACE=$(( $IMAGE_SIZE * 15/100 / 1024**2 )) G_CHECK_FREESPACE . $(( $NEEDED_FREE_SPACE + 100 )) || exit 1 # Assure +100 MiB left partition space # Drive source, clone with dd elif [[ $CLONING_TOOL == 'dd' ]]; then # Check if there is enough free disk space to store the image and the 7z file - NEEDED_FREE_SPACE=$(( $IMAGE_SIZE / 100 * 115 / 1024 / 1024 )) + NEEDED_FREE_SPACE=$(( $IMAGE_SIZE * 115/100 / 1024**2 )) G_CHECK_FREESPACE . $(( $NEEDED_FREE_SPACE + 100 )) || exit 1 # Assure +100 MiB left partition space - G_DIETPI-NOTIFY 2 "Creating final image with actually used size: $(( $IMAGE_SIZE / 1024 / 1024 + 1 )) MiB" - G_EXEC dd if=$FP_SOURCE of=$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT bs=1M status=progress count=$(( $IMAGE_SIZE / 1024 / 1024 + 1 )) + G_DIETPI-NOTIFY 2 "Creating final image with actually used size: $(( $IMAGE_SIZE / 1024**2 + 1 )) MiB" + G_EXEC dd if="$FP_SOURCE" of="$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT" bs=1M status=progress count=$(( $IMAGE_SIZE / 1024**2 + 1 )) # Drive source, clone with Clonezilla else @@ -340,14 +334,14 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O CLONEZILLA_ZIP_SIZE=$(curl -sIL "$CLONEZILLA_ZIP_URL" | mawk '/^content-length:/{print $2}') # Check if there is enough free disk space to store Clonezilla, the final image and the 7z file - NEEDED_FREE_SPACE=$(( ( $CLONEZILLA_ZIP_SIZE + $IMAGE_SIZE / 100 * 23 ) * 2 / 1024 / 1024 )) + NEEDED_FREE_SPACE=$(( ( $CLONEZILLA_ZIP_SIZE + $IMAGE_SIZE * 23/100 ) * 2 / 1024**2 )) G_CHECK_FREESPACE . $(( $NEEDED_FREE_SPACE + 100 )) || exit 1 # Assure +100 MiB left partition space # Download Clonezilla Live - if [[ ! -f $CLONEZILLA_ZIP || $(stat -c %s "$CLONEZILLA_ZIP") != $CLONEZILLA_ZIP_SIZE ]]; then + if [[ ! -f $CLONEZILLA_ZIP || $(stat -c %s "$CLONEZILLA_ZIP") != "$CLONEZILLA_ZIP_SIZE" ]]; then G_DIETPI-NOTIFY 2 "Downloading Clonezilla Live v$CLONEZILLA_VERSION..." - G_EXEC wget "$CLONEZILLA_ZIP_URL" -O "$CLONEZILLA_ZIP" + G_EXEC curl -sSfL "$CLONEZILLA_ZIP_URL" -o "$CLONEZILLA_ZIP" fi @@ -360,21 +354,21 @@ Do you want to overwrite or backup the existing file to $PWD/$OUTPUT_IMG_NAME.$O mkdir -p tmpiso/home/partimag G_DIETPI-NOTIFY 2 'Cloning disk with Clonezilla...' - ocs-sr -or $PWD/tmpiso/home/partimag -nogui -fsck -q2 -c -j2 -z1p -i 4096 -senc -sc savedisk $OUTPUT_IMG_NAME ${FP_SOURCE##*/} || exit 1 + ocs-sr -or "$PWD/tmpiso/home/partimag" -nogui -fsck -q2 -c -j2 -z1p -i 4096 -senc -sc savedisk "$OUTPUT_IMG_NAME" "${FP_SOURCE##*/}" || exit 1 fi # For the sake of privacy, remove some non vital files that contain SNs and UUIDs - rm -f tmpiso/home/partimag/$OUTPUT_IMG_NAME/{Info*txt,*list,clonezilla-img} + rm -f "tmpiso/home/partimag/$OUTPUT_IMG_NAME/"{Info*txt,*list,clonezilla-img} # Check image G_DIETPI-NOTIFY 2 'Checking Clonezilla image...' - ocs-chkimg -or $PWD/tmpiso/home/partimag -nogui -b $OUTPUT_IMG_NAME || exit 1 + ocs-chkimg -or "$PWD/tmpiso/home/partimag" -nogui -b "$OUTPUT_IMG_NAME" || exit 1 # Prepare custom files used by the installer when booting in UEFI mode - G_EXEC wget "$DIETPI_REPO"/.meta/images/dietpi-background_768p.png -O tmpiso/boot/grub/dietpibg.png - G_EXEC wget "$DIETPI_REPO"/.meta/images/select_bkg_c.png -O tmpiso/boot/grub/select_bkg_c.png - cat << '_EOF_' > tmpiso/boot/grub/theme.txt + G_EXEC curl -sSfL "$DIETPI_REPO"/.meta/images/dietpi-background_768p.png -o tmpiso/boot/grub/dietpibg.png + G_EXEC curl -sSfL "$DIETPI_REPO"/.meta/images/select_bkg_c.png -o tmpiso/boot/grub/select_bkg_c.png + cat << _EOF_ > tmpiso/boot/grub/theme.txt title-text: "" desktop-image: "dietpibg.png" terminal-font: "Unifont Regular 16" @@ -394,12 +388,13 @@ _EOF_ sed '/menuentry /,/}/d' tmpiso/boot/grub/clonezilla.cfg | sed '/submenu /,/}/d' | grep -v '^[ ]*$' > tmpiso/boot/grub/grub.cfg sed -n -e '/menuentry .*800x600/,/}/p' -e '/menuentry .*KMS/,/}/p' -e '/menuentry .*Safe/,/}/p' \ -e '/menuentry .*Failsafe/,/}/p' tmpiso/boot/grub/clonezilla.cfg >> tmpiso/boot/grub/grub.cfg + # shellcheck disable=SC2016 sed -i -e 's|set timeout=.*|set timeout="-1"|' -e '/set pref=/ a set theme=$pref/theme.txt' \ - -e 's|"Clonezilla live |"Install DietPi |' -e 's|locales= |locales=en_GB.UTF-8 |' \ + -e 's|"Clonezilla live |"Install DietPi |' -e 's|locales= |locales=C.UTF-8 |' \ -e 's|keyboard-layouts= |keyboard-layouts=gb |' -e 's|ocs-live-general|ocs-live-restore|' \ -e 's|ocs_live_extra_param=""|ocs_live_extra_param="-icds -k1 -r -e2 -j2 -batch -p poweroff restoredisk ask_user ask_user"|' \ -e 's|ocs_live_batch="no"|ocs_live_batch="yes"|' tmpiso/boot/grub/grub.cfg - cat << '_EOF_' >> tmpiso/boot/grub/grub.cfg + cat << _EOF_ >> tmpiso/boot/grub/grub.cfg submenu "Clonezilla live" { set pref=/boot/grub configfile $pref/clonezilla.cfg @@ -414,8 +409,8 @@ _EOF_ sed -i 's|\(MENU TITLE\) .*|\1 Clonezilla live|' tmpiso/syslinux/clonezilla.cfg sed '/^label /,/MENU END/d' tmpiso/syslinux/clonezilla.cfg | grep -v '^[ ]*$' > tmpiso/syslinux/syslinux.cfg sed -i 's|^\(label Clonezilla live\)$|\1 800x600|' tmpiso/syslinux/clonezilla.cfg - sed -n -e '/^label .*800x600/,/append initrd/p' tmpiso/syslinux/clonezilla.cfg >> tmpiso/syslinux/syslinux.cfg - cat << '_EOF_' >> tmpiso/syslinux/syslinux.cfg + cat << _EOF_ >> tmpiso/syslinux/syslinux.cfg +$(sed -n -e '/^label .*800x600/,/append initrd/p' tmpiso/syslinux/clonezilla.cfg) TEXT HELP VGA mode 800x600. OK for most of VGA cards. ENDTEXT @@ -424,10 +419,10 @@ _EOF_ -e '/^label .*failsafe/,/ENDTEXT/p' tmpiso/syslinux/clonezilla.cfg >> tmpiso/syslinux/syslinux.cfg sed -i -e 's|^\(timeout\) .*|\1 0|' -e 's|\(MENU BACKGROUND\) .*|\1 dietpibg.png|' -e 's|MENU TITLE .*|MENU TABMSG|' \ -e '/menu title/d' -e '/^say /d' -e '/MENU MARGIN/ a MENU HSHIFT 80\n MENU COLOR BORDER 0 #00000000 #00000000 none' -e 's|Clonezilla live |Install DietPi |' \ - -e 's|locales= |locales=en_GB.UTF-8 |' -e 's|keyboard-layouts= |keyboard-layouts=gb |' -e 's|ocs-live-general|ocs-live-restore|' \ + -e 's|locales= |locales=C.UTF-8 |' -e 's|keyboard-layouts= |keyboard-layouts=gb |' -e 's|ocs-live-general|ocs-live-restore|' \ -e 's|ocs_live_extra_param=""|ocs_live_extra_param="-icds -k1 -r -e2 -j2 -batch -p poweroff restoredisk ask_user ask_user"|' \ -e 's|ocs_live_batch="no"|ocs_live_batch="yes"|' tmpiso/syslinux/syslinux.cfg - cat << '_EOF_' >> tmpiso/syslinux/syslinux.cfg + cat << _EOF_ >> tmpiso/syslinux/syslinux.cfg MENU BEGIN Clonezilla live INCLUDE clonezilla.cfg MENU END @@ -445,12 +440,12 @@ _EOF_ G_DIETPI-NOTIFY 2 "Generating $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT..." xorriso -as mkisofs -R -r -J -joliet-long -l -iso-level 3 \ -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -partition_offset 16 \ - -publisher 'DietPi - Lightweight justice for your SBC; https://dietpi.com;' -volid 'DIETPI_INSTALLER' \ + -publisher 'DietPi - Lightweight justice for your SBC; https://dietpi.com/;' -volid 'DIETPI_INSTALLER' \ -A "clonezilla-live-${CLONEZILLA_VERSION}-amd64" \ -b syslinux/isolinux.bin -c syslinux/boot.cat -no-emul-boot -boot-load-size 4 \ -boot-info-table -eltorito-alt-boot --efi-boot boot/grub/efi.img -isohybrid-gpt-basdat \ - -isohybrid-apm-hfsplus tmpiso > $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT || exit 1 - rm -rf tmpiso + -isohybrid-apm-hfsplus tmpiso > "$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT" || exit 1 + rm -Rf tmpiso fi # Generate hashes: MD5, SHA1, SHA256 @@ -458,9 +453,9 @@ _EOF_ cat << _EOF_ > hash.txt FILE: $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT DATE: $(date) -MD5: $(md5sum $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT | mawk '{print $1}') -SHA1: $(sha1sum $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT | mawk '{print $1}') -SHA256: $(sha256sum $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT | mawk '{print $1}') +MD5: $(md5sum "$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT" | mawk '{print $1}') +SHA1: $(sha1sum "$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT" | mawk '{print $1}') +SHA256: $(sha256sum "$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT" | mawk '{print $1}') _EOF_ # Download current README @@ -470,8 +465,8 @@ _EOF_ # NB: LZMA2 ultra compression requires much memory for usage and allocation, which is an issue on 32bit (ARM) devices. Use "-mmt" to limit used CPU threads to "" and lower memory usage and allocation. local limit_threads (( $(free -m | mawk '/Mem:/{print $2}') < 1750 && $(nproc) > 2 )) && limit_threads='-mmt2' - [[ -f $OUTPUT_IMG_NAME.7z ]] && rm $OUTPUT_IMG_NAME.7z - G_EXEC_DESC='Creating final 7zip archive' G_EXEC_OUTPUT=1 G_EXEC 7zr a -m0=lzma2 $limit_threads -mx=9 $OUTPUT_IMG_NAME.7z $OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT hash.txt README.md + [[ -f $OUTPUT_IMG_NAME.7z ]] && rm "$OUTPUT_IMG_NAME.7z" + G_EXEC_DESC='Creating final 7zip archive' G_EXEC_OUTPUT=1 G_EXEC 7zr a -m0=lzma2 $limit_threads -mx=9 "$OUTPUT_IMG_NAME.7z" "$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT" hash.txt README.md rm hash.txt README.md G_WHIP_MSG "[ OK ] DietPi-Imager has successfully finished.\n diff --git a/.meta/dietpi-survey_report b/.meta/dietpi-survey_report index 4910cfada1..30c991a935 100644 --- a/.meta/dietpi-survey_report +++ b/.meta/dietpi-survey_report @@ -47,6 +47,9 @@ aHW_NAME[51]='BananaPi Pro (Lemaker)' aHW_NAME[52]='ASUS Tinker Board' aHW_NAME[53]='BananaPi (sinovoip)' + aHW_NAME[54]='NanoPi K2' + aHW_NAME[55]='NanoPi R2S' + aHW_NAME[56]='NanoPi NEO3' aHW_NAME[57]='NanoPi NEO Plus2' aHW_NAME[58]='NanoPi M4V2' aHW_NAME[59]='ZeroPi' @@ -165,6 +168,7 @@ aAUTOSTART_NAME[11]='Chromium' aAUTOSTART_NAME[14]='Custom' aAUTOSTART_NAME[15]='JRiver' + # shellcheck disable=SC2034 aAUTOSTART_NAME[16]='Desktop LightDM login' # Convert software index to title array @@ -343,7 +347,7 @@ # v6.14 (earliest version that can currently upload) + v6.15 aSOFTWARE_NAME6_14=() aSOFTWARE_NAME6_15=() - for i in ${!aSOFTWARE_NAME[@]} + for i in "${!aSOFTWARE_NAME[@]}" do aSOFTWARE_NAME6_14[$i]=${aSOFTWARE_NAME[$i]} @@ -356,7 +360,7 @@ aSOFTWARE_NAME6_16=() aSOFTWARE_NAME6_17=() aSOFTWARE_NAME6_18=() - for i in ${!aSOFTWARE_NAME6_15[@]} + for i in "${!aSOFTWARE_NAME6_15[@]}" do aSOFTWARE_NAME6_16[$i]=${aSOFTWARE_NAME6_15[$i]} @@ -369,7 +373,7 @@ # v6.19 + v6.20 aSOFTWARE_NAME6_19=() aSOFTWARE_NAME6_20=() - for i in ${!aSOFTWARE_NAME6_18[@]} + for i in "${!aSOFTWARE_NAME6_18[@]}" do aSOFTWARE_NAME6_19[$i]=${aSOFTWARE_NAME6_18[$i]} @@ -385,7 +389,7 @@ aSOFTWARE_NAME6_21=() aSOFTWARE_NAME6_22=() aSOFTWARE_NAME6_23=() - for i in ${!aSOFTWARE_NAME6_20[@]} + for i in "${!aSOFTWARE_NAME6_20[@]}" do aSOFTWARE_NAME6_21[$i]=${aSOFTWARE_NAME6_20[$i]} @@ -400,7 +404,7 @@ # v6.24 + v6.25 aSOFTWARE_NAME6_24=() aSOFTWARE_NAME6_25=() - for i in ${!aSOFTWARE_NAME6_23[@]} + for i in "${!aSOFTWARE_NAME6_23[@]}" do aSOFTWARE_NAME6_24[$i]=${aSOFTWARE_NAME6_23[$i]} @@ -411,7 +415,7 @@ # v6.26 aSOFTWARE_NAME6_26=() - for i in ${!aSOFTWARE_NAME6_25[@]} + for i in "${!aSOFTWARE_NAME6_25[@]}" do aSOFTWARE_NAME6_26[$i]=${aSOFTWARE_NAME6_25[$i]} @@ -423,7 +427,7 @@ # v6.27 aSOFTWARE_NAME6_27=() - for i in ${!aSOFTWARE_NAME6_26[@]} + for i in "${!aSOFTWARE_NAME6_26[@]}" do aSOFTWARE_NAME6_27[$i]=${aSOFTWARE_NAME6_26[$i]} @@ -434,7 +438,7 @@ # v6.28 + v6.29 aSOFTWARE_NAME6_28=() aSOFTWARE_NAME6_29=() - for i in ${!aSOFTWARE_NAME6_27[@]} + for i in "${!aSOFTWARE_NAME6_27[@]}" do aSOFTWARE_NAME6_28[$i]=${aSOFTWARE_NAME6_27[$i]} @@ -446,7 +450,7 @@ # v6.30 + v6.31 aSOFTWARE_NAME6_30=() aSOFTWARE_NAME6_31=() - for i in ${!aSOFTWARE_NAME6_29[@]} + for i in "${!aSOFTWARE_NAME6_29[@]}" do aSOFTWARE_NAME6_30[$i]=${aSOFTWARE_NAME6_29[$i]} @@ -455,15 +459,27 @@ done aSOFTWARE_NAME6_31[177]='Firefox Sync Server' + # v6.32 + aSOFTWARE_NAME6_32=() + for i in "${!aSOFTWARE_NAME6_31[@]}" + do + + # shellcheck disable=SC2034 + aSOFTWARE_NAME6_32[$i]=${aSOFTWARE_NAME6_31[$i]} + + done + aSOFTWARE_NAME6_32[178]='Jellyfin' + aSOFTWARE_NAME6_32[179]='Komga' + Main(){ # Copy files to RAM to speed up sourcing #mkdir -p /tmp/dietpi-survey_report #cp /home/dietpi-survey/survey/*.txt /tmp/dietpi-survey_report/ # cp: Argument list too long - [[ -e '/tmp/dietpi-survey_report' ]] && rm -R /tmp/dietpi-survey_report - cp -R /home/dietpi-survey/survey /tmp/dietpi-survey_report + rm -Rf /tmp/dietpi-survey_report || exit 1 + cp -R /home/dietpi-survey/survey /tmp/dietpi-survey_report || exit 1 - cd /tmp/dietpi-survey_report + cd /tmp/dietpi-survey_report || exit 1 for file in *.txt do @@ -477,9 +493,9 @@ fi # Source survey files - [[ $(<$file) == '#!/bin/bash'* ]] || continue + [[ $(<"$file") == '#!/bin/bash'* ]] || continue - . $file + . "$file" # Add bench to array [[ $BENCH_HW_MODEL =~ ^[0-9]+$ ]] || continue @@ -559,20 +575,45 @@ done # Navigate to parent /tmp - cd /tmp + cd /tmp || exit 1 # Clean up reports dir - rm -R /tmp/dietpi-survey_report + rm -R /tmp/dietpi-survey_report || exit 1 # Optin count SURVEY_COUNT_OPTIN=$(( $SURVEY_COUNT_TOTAL - $SURVEY_COUNT_EMPTY )) + # Merge old and new hardware model names + for i in "${!aDEVICE_NAME[@]}" + do + + [[ $i == 'RPi B (ECN0001) (armv6l)' ]] && ((aDEVICE_NAME['RPi B (armv6l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'RPi (armv6l)' ]] && ((aDEVICE_NAME['RPi (Unknown) (armv6l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'RPi (armv7l)' ]] && ((aDEVICE_NAME['RPi (Unknown) (armv7l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Odroid XU3/XU4/HC1/HC2 (armv7l)' ]] && ((aDEVICE_NAME['Odroid XU3/XU4/MC1/HC1/HC2 (armv7l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Asus Tinker Board (armv7l)' ]] && ((aDEVICE_NAME['ASUS Tinker Board (armv7l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Pine A64 (aarch64)' ]] && ((aDEVICE_NAME['PINE A64 (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Pine H64 (aarch64)' ]] && ((aDEVICE_NAME['PINE H64 (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Rock64 (aarch64)' ]] && ((aDEVICE_NAME['ROCK64 (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'RockPro64 (aarch64)' ]] && ((aDEVICE_NAME['ROCKPro64 (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Pinebook A64 (aarch64)' ]] && ((aDEVICE_NAME['Pinebook (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Pinebook 1080p (aarch64)' ]] && ((aDEVICE_NAME['Pinebook (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'NanoPi Neo (armv7l)' ]] && ((aDEVICE_NAME['NanoPi NEO (armv7l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'NanoPi NEO 2 (aarch64)' ]] && ((aDEVICE_NAME['NanoPi NEO2 (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'NanoPi M3/T3/F3 (aarch64)' ]] && ((aDEVICE_NAME['NanoPi M3/T3/Fire3 (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'NanoPi M3/T3/F3 (armv7l)' ]] && ((aDEVICE_NAME['NanoPi M3/T3/Fire3 (armv7l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'BBB (armv7l)' ]] && ((aDEVICE_NAME['BeagleBone Black (armv7l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Unknown Device (armv7l)' ]] && ((aDEVICE_NAME['Generic Device (armv7l)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + [[ $i == 'Unknown Device (aarch64)' ]] && ((aDEVICE_NAME['Generic Device (aarch64)']+=aDEVICE_NAME["$i"])) && unset "aDEVICE_NAME[$i]" + + done + # Process all results, for later use in HTML printout # - NB: HW_MODEL array based local default_min_value=100000 # CPU - for i in ${!aBENCH_CPU_INDEX[@]} + for i in "${!aBENCH_CPU_INDEX[@]}" do aBENCH_RESULT_CPU_MIN[$i]=$default_min_value @@ -603,9 +644,9 @@ # Last item in current array. Work out averages (( $j == ${aBENCH_CPU_INDEX[$i]} - 1 )) || continue # - Devide CPU times by 100 and scale to revert decimal point removal - aBENCH_RESULT_CPU_MIN[$i]=$(bc -l <<< "scale=$BENCH_RESULTS_CPU_SCALE; ${aBENCH_RESULT_CPU_MIN[$i]} / 100") - aBENCH_RESULT_CPU_MAX[$i]=$(bc -l <<< "scale=$BENCH_RESULTS_CPU_SCALE; ${aBENCH_RESULT_CPU_MAX[$i]} / 100") - aBENCH_RESULT_CPU_AVG[$i]=$(bc -l <<< "scale=$BENCH_RESULTS_CPU_SCALE; ${aBENCH_RESULT_CPU_AVG[$i]} / ${aBENCH_CPU_INDEX[$i]} / 100") + aBENCH_RESULT_CPU_MIN[$i]=$(printf "%.${BENCH_RESULTS_CPU_SCALE}f" "${aBENCH_RESULT_CPU_MIN[$i]}e-2") + aBENCH_RESULT_CPU_MAX[$i]=$(printf "%.${BENCH_RESULTS_CPU_SCALE}f" "${aBENCH_RESULT_CPU_MAX[$i]}e-2") + aBENCH_RESULT_CPU_AVG[$i]=$(printf "%.${BENCH_RESULTS_CPU_SCALE}f" "$((${aBENCH_RESULT_CPU_AVG[$i]}*10/${aBENCH_CPU_INDEX[$i]}+1))e-3") aBENCH_RESULT_CPU_TEMP_START_AVG[$i]=$(( ${aBENCH_RESULT_CPU_TEMP_START_AVG[$i]} / ${aBENCH_CPU_INDEX[$i]} )) aBENCH_RESULT_CPU_TEMP_END_AVG[$i]=$(( ${aBENCH_RESULT_CPU_TEMP_END_AVG[$i]} / ${aBENCH_CPU_INDEX[$i]} )) @@ -614,7 +655,7 @@ done # RootFS - for i in ${!aBENCH_ROOTFS_INDEX[@]} + for i in "${!aBENCH_ROOTFS_INDEX[@]}" do aBENCH_RESULT_ROOTFS_WRITE_MIN[$i]=$default_min_value @@ -645,7 +686,7 @@ done # RAM - for i in ${!aBENCH_RAM_INDEX[@]} + for i in "${!aBENCH_RAM_INDEX[@]}" do aBENCH_RESULT_RAM_WRITE_MIN[$i]=$default_min_value @@ -676,7 +717,7 @@ done # LAN - for i in ${!aBENCH_LAN_INDEX[@]} + for i in "${!aBENCH_LAN_INDEX[@]}" do aBENCH_RESULT_NET_LAN_SPEED_MIN[$i]=$default_min_value @@ -699,7 +740,7 @@ done # CustomFS - for i in ${!aBENCH_CUSTOMFS_INDEX[@]} + for i in "${!aBENCH_CUSTOMFS_INDEX[@]}" do aBENCH_RESULT_CUSTOMFS_WRITE_MIN[$i]=$default_min_value @@ -731,28 +772,69 @@ # Create HTML file cat << _EOF_ > index.html - + + + + + + DietPi-Survey statistics + + + + + + + + + + + + + + + + + + + + + + + + + -

DietPi-Survey report page

- Uploads since: 2020-01-01 00:00:00 UTC
- Last update: $(TZ=UTC date "+%Y-%m-%d %T UTC")
+ +

DietPi-Survey statistics

+

Uploads since: 2020-01-01 00:00:00 UTC

+

Last update: $(TZ=UTC date '+%Y-%m-%d %T UTC')


@@ -760,159 +842,159 @@
Total system count$SURVEY_COUNT_TOTAL
Systems opted out DietPi-Survey$SURVEY_COUNT_EMPTY$(( $SURVEY_COUNT_EMPTY * 100 / $SURVEY_COUNT_TOTAL ))%
-

DietPi versions:

+

DietPi versions ¶

- $(for i in "${!aDIETPI_VERSION[@]}"; do echo ""; done | sort -nrk 1.17,1.20 -t ' ') + $(for i in "${!aDIETPI_VERSION[@]}"; do echo ""; done | sort -nrk 1.17,1.20 -t ' ')
DietPi v$i ${aDIETPI_VERSION[$i]}$(( ${aDIETPI_VERSION[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
DietPi v$i ${aDIETPI_VERSION[$i]}$(( ${aDIETPI_VERSION[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

Git branches:

+

Git branches ¶

- $(for i in "${!aGIT_BRANCH[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aGIT_BRANCH[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
$i ${aGIT_BRANCH[$i]}$(( ${aGIT_BRANCH[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
$i ${aGIT_BRANCH[$i]}$(( ${aGIT_BRANCH[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

Devices:

+

Devices ¶

- $(for i in "${!aDEVICE_NAME[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aDEVICE_NAME[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
$i ${aDEVICE_NAME[$i]}$(( ${aDEVICE_NAME[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
$i ${aDEVICE_NAME[$i]}$(( ${aDEVICE_NAME[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

CPU architectures:

+

CPU architectures ¶

- $(for i in "${!aCPU_ARCH[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aCPU_ARCH[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
$i ${aCPU_ARCH[$i]}$(( ${aCPU_ARCH[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
$i ${aCPU_ARCH[$i]}$(( ${aCPU_ARCH[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

CPU core counts:

+

CPU core counts ¶

- $(for i in ${!aCPU_COUNT[@]}; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aCPU_COUNT[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
$i Core(s) ${aCPU_COUNT[$i]}$(( ${aCPU_COUNT[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
$i Core(s) ${aCPU_COUNT[$i]}$(( ${aCPU_COUNT[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

Distro versions:

+

Distro versions ¶

- $(for i in "${!aDISTRO_VERSION[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aDISTRO_VERSION[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
$i ${aDISTRO_VERSION[$i]}$(( ${aDISTRO_VERSION[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
$i ${aDISTRO_VERSION[$i]}$(( ${aDISTRO_VERSION[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

RPi Debian (64-bit) vs Raspbian (32-bit):

+

RPi Debian 64-bit vs Raspbian 32-bit ¶

- +
Debian (64-bit) is used by${aRASPBIAN[0]} of $(( ${aRASPBIAN[0]} + ${aRASPBIAN[1]} )) RPi systems$(( ${aRASPBIAN[0]} * 100 / ( ${aRASPBIAN[0]} + ${aRASPBIAN[1]} ) ))%
Debian (64-bit) is used by${aRASPBIAN[0]} of $(( ${aRASPBIAN[0]} + ${aRASPBIAN[1]} )) RPi systems$(( ${aRASPBIAN[0]} * 100 / ( ${aRASPBIAN[0]} + ${aRASPBIAN[1]} ) ))%
-

Autostart options:

+

Autostart options ¶

- $(for i in "${!aAUTOSTART_OPTION[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aAUTOSTART_OPTION[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
$i ${aAUTOSTART_OPTION[$i]}$(( ${aAUTOSTART_OPTION[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
$i ${aAUTOSTART_OPTION[$i]}$(( ${aAUTOSTART_OPTION[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

DietPi-Automation:

+

DietPi-Automation ¶

- +
Used by${aAUTO_SETUP_AUTOMATED[1]} of $SURVEY_COUNT_OPTIN systems$(( ${aAUTO_SETUP_AUTOMATED[1]} * 100 / $SURVEY_COUNT_OPTIN ))%
Used by${aAUTO_SETUP_AUTOMATED[1]} of $SURVEY_COUNT_OPTIN systems$(( ${aAUTO_SETUP_AUTOMATED[1]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

Network interfaces:

+

Network interfaces ¶

- $(for i in "${!aNETWORK_INTERFACE[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aNETWORK_INTERFACE[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
$i ${aNETWORK_INTERFACE[$i]}$(( ${aNETWORK_INTERFACE[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
$i ${aNETWORK_INTERFACE[$i]}$(( ${aNETWORK_INTERFACE[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

Installed software titles:

+

Installed software titles ¶

- $(for i in "${!aSOFTWARE[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aSOFTWARE[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
$i ${aSOFTWARE[$i]}$(( ${aSOFTWARE[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
$i ${aSOFTWARE[$i]}$(( ${aSOFTWARE[$i]} * 100 / $SURVEY_COUNT_OPTIN ))%
-

DietPi-Benchmarks | CPU:

+

DietPi-Benchmarks | CPU ¶

- - + + + - - - - - - - - - - - + + + + + + + + + + + - $(for i in "${!aBENCH_CPU_INDEX[@]}"; do echo ""; done | sort -nk 2 -t ' ') + $(for i in "${!aBENCH_CPU_INDEX[@]}"; do echo ""; done | sort -nk 2 -t ' ')
- CPU time (seconds, lower is faster):CPU idle temp (°C):CPU full load temp (°C):CPU time (seconds, lower is faster)CPU idle temp [°C]CPU load temp [°C]
Device:Count:Average:Fastest:Slowest:Average:Lowest:Highest:Average:Lowest:Highest:DeviceCountAverageFastestSlowestAverageLowestHighestAverageLowestHighest
${aHW_NAME[$i]:=$i}${aBENCH_CPU_INDEX[$i]} ${aBENCH_RESULT_CPU_AVG[$i]}${aBENCH_RESULT_CPU_MIN[$i]}${aBENCH_RESULT_CPU_MAX[$i]}${aBENCH_RESULT_CPU_TEMP_START_AVG[$i]}${aBENCH_RESULT_CPU_TEMP_START_MIN[$i]}${aBENCH_RESULT_CPU_TEMP_START_MAX[$i]}${aBENCH_RESULT_CPU_TEMP_END_AVG[$i]}${aBENCH_RESULT_CPU_TEMP_END_MIN[$i]}${aBENCH_RESULT_CPU_TEMP_END_MAX[$i]}
${aHW_NAME[$i]:=$i}${aBENCH_CPU_INDEX[$i]} ${aBENCH_RESULT_CPU_AVG[$i]}${aBENCH_RESULT_CPU_MIN[$i]}${aBENCH_RESULT_CPU_MAX[$i]}${aBENCH_RESULT_CPU_TEMP_START_AVG[$i]}${aBENCH_RESULT_CPU_TEMP_START_MIN[$i]}${aBENCH_RESULT_CPU_TEMP_START_MAX[$i]}${aBENCH_RESULT_CPU_TEMP_END_AVG[$i]}${aBENCH_RESULT_CPU_TEMP_END_MIN[$i]}${aBENCH_RESULT_CPU_TEMP_END_MAX[$i]}
-

DietPi-Benchmarks | IO (RAM):

+

DietPi-Benchmarks | RAM I/O ¶

- + + - - - - - - - - + + + + + + + + - $(for i in "${!aBENCH_RAM_INDEX[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aBENCH_RAM_INDEX[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
- RAM write (MiB/s):RAM read (MiB/s):RAM write [MiB/s]RAM read [MiB/s]
Device:Count:Average:Fastest:Slowest:Average:Fastest:Slowest:DeviceCountAverageFastestSlowestAverageFastestSlowest
${aHW_NAME[$i]:=$i}${aBENCH_RAM_INDEX[$i]} ${aBENCH_RESULT_RAM_WRITE_AVG[$i]}${aBENCH_RESULT_RAM_WRITE_MAX[$i]}${aBENCH_RESULT_RAM_WRITE_MIN[$i]}${aBENCH_RESULT_RAM_READ_AVG[$i]}${aBENCH_RESULT_RAM_READ_MAX[$i]}${aBENCH_RESULT_RAM_READ_MIN[$i]}
${aHW_NAME[$i]:=$i}${aBENCH_RAM_INDEX[$i]} ${aBENCH_RESULT_RAM_WRITE_AVG[$i]}${aBENCH_RESULT_RAM_WRITE_MAX[$i]}${aBENCH_RESULT_RAM_WRITE_MIN[$i]}${aBENCH_RESULT_RAM_READ_AVG[$i]}${aBENCH_RESULT_RAM_READ_MAX[$i]}${aBENCH_RESULT_RAM_READ_MIN[$i]}
-

DietPi-Benchmarks | IO (RootFS):

+

DietPi-Benchmarks | RootFS I/O ¶

- + + - - - - - - - - + + + + + + + + - $(for i in "${!aBENCH_ROOTFS_INDEX[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aBENCH_ROOTFS_INDEX[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
- RootFS write (MiB/s):RootFS read (MiB/s):RootFS write [MiB/s]RootFS read [MiB/s]
Device:Count:Average:Fastest:Slowest:Average:Fastest:Slowest:DeviceCountAverageFastestSlowestAverageFastestSlowest
${aHW_NAME[$i]:=$i}${aBENCH_ROOTFS_INDEX[$i]} ${aBENCH_RESULT_ROOTFS_WRITE_AVG[$i]}${aBENCH_RESULT_ROOTFS_WRITE_MAX[$i]}${aBENCH_RESULT_ROOTFS_WRITE_MIN[$i]}${aBENCH_RESULT_ROOTFS_READ_AVG[$i]}${aBENCH_RESULT_ROOTFS_READ_MAX[$i]}${aBENCH_RESULT_ROOTFS_READ_MIN[$i]}
${aHW_NAME[$i]:=$i}${aBENCH_ROOTFS_INDEX[$i]} ${aBENCH_RESULT_ROOTFS_WRITE_AVG[$i]}${aBENCH_RESULT_ROOTFS_WRITE_MAX[$i]}${aBENCH_RESULT_ROOTFS_WRITE_MIN[$i]}${aBENCH_RESULT_ROOTFS_READ_AVG[$i]}${aBENCH_RESULT_ROOTFS_READ_MAX[$i]}${aBENCH_RESULT_ROOTFS_READ_MIN[$i]}
-

DietPi-Benchmarks | IO (Custom FS):

+

DietPi-Benchmarks | Custom FS I/O ¶

- + + - - - - - - - - + + + + + + + + - $(for i in "${!aBENCH_CUSTOMFS_INDEX[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aBENCH_CUSTOMFS_INDEX[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
- Custom FS write (MiB/s):Custom FS read (MiB/s):Custom FS write [MiB/s]Custom FS read [MiB/s]
Device:Count:Average:Fastest:Slowest:Average:Fastest:Slowest:DeviceCountAverageFastestSlowestAverageFastestSlowest
${aHW_NAME[$i]:=$i}${aBENCH_CUSTOMFS_INDEX[$i]} ${aBENCH_RESULT_CUSTOMFS_WRITE_AVG[$i]}${aBENCH_RESULT_CUSTOMFS_WRITE_MAX[$i]}${aBENCH_RESULT_CUSTOMFS_WRITE_MIN[$i]}${aBENCH_RESULT_CUSTOMFS_READ_AVG[$i]}${aBENCH_RESULT_CUSTOMFS_READ_MAX[$i]}${aBENCH_RESULT_CUSTOMFS_READ_MIN[$i]}
${aHW_NAME[$i]:=$i}${aBENCH_CUSTOMFS_INDEX[$i]} ${aBENCH_RESULT_CUSTOMFS_WRITE_AVG[$i]}${aBENCH_RESULT_CUSTOMFS_WRITE_MAX[$i]}${aBENCH_RESULT_CUSTOMFS_WRITE_MIN[$i]}${aBENCH_RESULT_CUSTOMFS_READ_AVG[$i]}${aBENCH_RESULT_CUSTOMFS_READ_MAX[$i]}${aBENCH_RESULT_CUSTOMFS_READ_MIN[$i]}
-

DietPi-Benchmarks | IO (Network LAN):

+

DietPi-Benchmarks | LAN I/O ¶

+ - - - - - + + + + + - $(for i in "${!aBENCH_LAN_INDEX[@]}"; do echo ""; done | sort -nrk 2 -t ' ') + $(for i in "${!aBENCH_LAN_INDEX[@]}"; do echo ""; done | sort -nrk 2 -t ' ')
- Transfer rate (MiB/s):Transfer rate [MiB/s]
Device:Count:Average:Fastest:Slowest:DeviceCountAverageFastestSlowest
${aHW_NAME[$i]:=$i}${aBENCH_LAN_INDEX[$i]} ${aBENCH_RESULT_NET_LAN_SPEED_AVG[$i]}${aBENCH_RESULT_NET_LAN_SPEED_MAX[$i]}${aBENCH_RESULT_NET_LAN_SPEED_MIN[$i]}
${aHW_NAME[$i]:=$i}${aBENCH_LAN_INDEX[$i]} ${aBENCH_RESULT_NET_LAN_SPEED_AVG[$i]}${aBENCH_RESULT_NET_LAN_SPEED_MAX[$i]}${aBENCH_RESULT_NET_LAN_SPEED_MIN[$i]}
diff --git a/.meta/images/76mm_rounder_sticker.png b/.meta/images/76mm_rounder_sticker.png index 81cb638325..3a9f1aa92b 100644 Binary files a/.meta/images/76mm_rounder_sticker.png and b/.meta/images/76mm_rounder_sticker.png differ diff --git a/.meta/images/dietpi-background_480p.png b/.meta/images/dietpi-background_480p.png index 2f4d8fe595..0500252ccb 100644 Binary files a/.meta/images/dietpi-background_480p.png and b/.meta/images/dietpi-background_480p.png differ diff --git a/.meta/images/dietpi-logo_inverted.png b/.meta/images/dietpi-logo_inverted.png index 18e1d13bed..e3dbf3cc93 100644 Binary files a/.meta/images/dietpi-logo_inverted.png and b/.meta/images/dietpi-logo_inverted.png differ diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000000..a7d05e6d4b --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1 @@ +disable=SC2004,SC2155,SC2188 diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 19024521f7..c2c38ec7b1 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,58 @@ +v6.32 +(XX/08/20) + +API Changes: +- DietPi-Set_swapfile | Running the script without input arguments does not print the current swap file location and size anymore but will apply the settings stored in dietpi.txt, refresh the current swap file or apply defaults as fallback. Currently active swap files can be reliably checked via /proc/swaps or htop. + +Changes / Improvements / Optimisations: +- NanoPi NEO3 | Initial support for this SBC has been added. +- NanoPi R2S | Initial support for this SBC has been added. +- NanoPi K2 | Initial support for this SBC has been added. +- DietPi-Set_swapfile | Added support for zram-based swap space. Use "zram" as swap location to have a zram device created (persistently via udev rule) at /dev/zram0 and used for compressed in-memory swap space. The auto-size option "1" will result in a zram size of 50% of physical RAM size, else the MiB value will be used, as long as its smaller than physical RAM size. Many thanks to @rickalm for pushing this topic with an initial implementation: https://github.com/MichaIng/DietPi/pull/3705 +- DietPi-Drive_Manager | For NTFS mounts, the "big_writes" mount option is now added by default, which reduces CPU load and by this may increase performance. Many thanks to @balexandrov for suggesting this enhancement: https://github.com/MichaIng/DietPi/issues/3330#issuecomment-654072107 +- DietPi-Config | Added selection of schedutil and userspace CPU frequency governors. Schedutil is a modern dynmic governor which sets frequency tightly related and according to metrics of the CPU scheduling driver itself. Userspace is a no-op governor, i.e. it does not touch CPU frequencies at all which allows setting manual/custom frequencies according to own metrics or via scripts. Read more about native Linux CPU frequency scaling: https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html#generic-scaling-governors +- DietPi-Config | RPi: Removed the option to switch the deprecated max_usb_current setting in config.txt. Max USB current is now enabled by default via firmware on all RPi models: https://github.com/raspberrypi/documentation/issues/1655 +- DietPi-LetsEncrypt | Lighttpd: Updated our default SSL cipher to match newer standards, still intermediate and compatible with Debian Stretch (Lighttpd v1.4.45). Additionally our config file names have been adjusted to use lighty-enable|disable-mod and priority prefixes to allow ordering own custom configs/vhosts more easily around them. Many thanks to @PanosssD for making us aware of this: https://github.com/MichaIng/DietPi/issues/3707 +- DietPi-Software | Komga: FOSS home server for comics and mangas, now available for install as ID 179. Many thanks to @himura95 for providing the implementation: https://github.com/MichaIng/DietPi/issues/3403 +- DietPi-Software | Jellyfin: A FOSS web interface media streaming server available for install. Many thanks to all who voted for it: https://feathub.com/MichaIng/DietPi/+63 +- DietPi-Software | Airsonic: It is now available on Debian Buster systems since Java 11 support has been added. Many thanks to @linxiaopi for pointing us at the required re-evaluation: https://github.com/MichaIng/DietPi/issues/3732 +- DietPi-Software | On the uninstall information prompt, the info has been added that uninstalling usually means that related userdata and configs are purged as well. Additionally "dietpi-software reinstall " is mentioned now as alternative to repair/update installed software. Many thanks to @kpine for doing this request: https://github.com/MichaIng/DietPi/issues/3550 +- DietPi-Software | Python pip: We migrated this software selection to a Python3/pip3 install only, due to Python2 EOL in 2020/01. Where possible, dependant software selections have been migrated to Python3 builds, where not possible, Python2/pip2 is installed separately for now. We hope that most affected software titles will do Python3 releases soon, otherwise we will remove them form our portfolio, at latest in spring 2021. The strongest reason for this is that next Debian Bullseye (summer 2021) will not ship Python2 packages anymore. +- DietPi-Software | SABnzbd: Migrated to a Python3-based install. +- DietPi-Software | OctoPrint: On Debian Buster and up, migrated to a Python3-based install. +- DietPi-Software | Wordpress: Plugins can now be installed and the internal updater used OOTB without the need to manually apply correct file permissions first. Many thanks to @Joulinar for implementing this: https://github.com/MichaIng/DietPi/pull/3720 +- DietPi-Software | ProFTPD: On fresh installs, reverse DNS lookups are disabled by default now by adding "UseReverseDNS off" to /etc/proftpd/proftpd.conf. This increases login speeds, in case dramatically, depending on reverse DNS server. Additionally file uploads can now be resumed by default via "AllowStoreRestart On" and members of the "dietpi" group have write access to uploaded files ("Umask 002") to increase OOTB compatibility with media and file sharing software. Many thanks to @bbsixzz for doing these suggestions: https://github.com/MichaIng/DietPi/issues/3727 +- DietPi-Software | HTPC Manager: Migrated to a Python3-compatibe fork by @gmiranda (https://github.com/gmiranda/HTPC-Manager), since the previous fork stopped development. Please help test, and when possible contribute to this project to keep it alive. We'll do minimal tests and assure the basic install and web interface works fine from Debian Stretch till Debian Bullseye. + +Bug Fixes: +- General | Resolved an issue where enabling or disabling IPv6 removed the expected symlink at /etc/sysctl.d/99-sysctl.conf with its actual target file. This happened when using dietpi-config network options and as well during firstrun setup when dietpi.txt choices are applied. The symlink is recreated, if missing, on all DietPi systems with next update. +- General | Resolved an external bug where the haveged entropy daemon failed to start on some ARM boards with the current version shipped with Debian Buster. On Buster ARMv7 and ARMv8 systems, a new package from Debian Bullseye is installed with this DietPi update, which contains the upstream fix: https://github.com/jirka-h/haveged/pull/7 +- DietPi-Benchmark | Resolved an issue where file system benchmarks failed. Many thanks to @dbambus for reporting this issue: https://github.com/MichaIng/DietPi/issues/3672 +- DietPi-Config | Resolved an issue where RPi onboard Bluetooth is attempted to be enabled on RPi models without onboard Bluetooth. On those models, now only the generic Bluetooth packages and services are installed and enabled. Many thanks to @TASSDevon for reporting this issue: https://github.com/MichaIng/DietPi/issues/3611 +- DietPi-Software | Node.js: Resolved an issue where the installer internet connection check fails due to new nodejs.org HTTPS redirection. For now we use our own fork. +- DietPi-Software | HTPC Manager: Resolved an issue where install failed due to missing build-essential dependency. +- DietPi-Software | HTPC Manager: Resolved an issue where the internal updater failed due to missing git meta files. +- DietPi-Software | EmonPi: Resolved a failing primary UART activation on install. +- DietPi-Software | PHP: Resolved an issue where on pre-v6.23 systems the PHP upgrade from v7.0/7.1 to v7.2/7.3 did not work as expected. Many thanks to @illusive-c for reporting this issue: https://github.com/MichaIng/DietPi/issues/3670 +- DietPi-Software | Xfce: Resolved an issue where the install and autostart of xcompmgr composition manager broke the xfwm4 internal one, leading to ineffective appearance settings and black borders around windows in certain cirumstances. Many thanks to @TamaTamaGoGo for reporting this issue: https://github.com/MichaIng/DietPi/issues/3665 +- DietPi-Software | Pi-hole: Resolved an issue with Apache webserver, where CORS check failed if the Referrer-Policy header has been set to "no-referrer". If this is the case, the Pi-hole Apache config now sets it to the second strict "same-origin", which does not break the Pi-hole admin panel. Many thanks to @Phil1988 for reporting this issue: https://github.com/MichaIng/DietPi/issues/3675 +- DietPi-Software | qBittorrent: Resolved an issue where setting the web UI port via config file or UI is overridden by the service file command option. Many thanks to @linxiaopi for reporting this issue: https://github.com/MichaIng/DietPi/issues/3660 +- DietPi-Software | Fail2Ban: Resolved an issue where sshd filter modes could not be set via jail config since the variable was not passed. Many thanks to @Darwolia for reporting this issue: https://github.com/MichaIng/DietPi/issues/3697 + +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 +- RPi | On TigerVNC virtual desktop, LXAppearance hangs on dbus-launch: https://github.com/MichaIng/DietPi/issues/1791 +- Odroid C2 | Some WiFi adapters do no work as hotspot: https://github.com/MichaIng/DietPi/issues/1955 +- DietPi-Software | Node-RED: Pre-installed modules cannot be updated via web UI: https://github.com/MichaIng/DietPi/issues/2073 +- DietPi-Software | Raspimjpeg: With Lighttpd, streaming mjpeg does not work: https://github.com/MichaIng/DietPi/issues/1747 +- DietPi-Software | MATE desktop: When logging in as root, desktop items and right-click context menu is missing: https://github.com/MichaIng/DietPi/issues/3160 +- DietPi-Software | Sonarr/Mono: With current Mono version 6, import to a file system without UNIX permissions support (exFAT, FAT32/vfat, CIFS mounts and NTFS without "permissions" option) fails, regardless of user/umask mount options: https://github.com/MichaIng/DietPi/issues/3179 +- DietPi-Software | Transmission: On Raspbian/Debian Stretch, RAM usage raises unlimited over time: https://github.com/MichaIng/DietPi/issues/2413 + +For all additional issues that may appear after release, please see the following link for active tickets: https://github.com/MichaIng/DietPi/issues + +----------------------------------------------------------------------------------------------------------- + v6.31 (05/07/20) @@ -38,18 +93,6 @@ Bug 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/3640 -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 -- RPi | On TigerVNC virtual desktop, LXAppearance hangs on dbus-launch: https://github.com/MichaIng/DietPi/issues/1791 -- Odroid C2 | Some WiFi adapters do no work as hotspot: https://github.com/MichaIng/DietPi/issues/1955 -- DietPi-Software | Node-RED: Pre-installed modules cannot be updated via web UI: https://github.com/MichaIng/DietPi/issues/2073 -- DietPi-Software | Raspimjpeg: With Lighttpd, streaming mjpeg does not work: https://github.com/MichaIng/DietPi/issues/1747 -- DietPi-Software | MATE desktop: When logging in as root, desktop items and right-click context menu is missing: https://github.com/MichaIng/DietPi/issues/3160 -- DietPi-Software | Sonarr/Mono: With current Mono version 6, import to a file system without UNIX permissions support (exFAT, FAT32/vfat, CIFS mounts and NTFS without "permissions" option) fails, regardless of user/umask mount options: https://github.com/MichaIng/DietPi/issues/3179 -- DietPi-Software | Transmission: On Raspbian/Debian Stretch, RAM usage raises unlimited over time: https://github.com/MichaIng/DietPi/issues/2413 - -For all additional issues that may appear after release, please see the following link for active tickets: https://github.com/MichaIng/DietPi/issues - ----------------------------------------------------------------------------------------------------------- v6.30 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index abc4811281..84ce773ccf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ Are you able to: - Provide feedback and/or test areas of DietPi, to improve the user experience? - Report bugs? -- Improve/add more features to the [DietPi website](https://dietpi.com)? +- Improve/add more features to the DietPi [website](https://github.com/MichaIng/DietPi-Website) or [documentation](https://github.com/MichaIng/DietPi-Docs)? - Compile software for our supported SBCs? - Contribute to DietPi with programming on GitHub? - Suggest new software that we can add to the `dietpi-software` install system? @@ -17,5 +17,5 @@ If so, let us know! We are always looking for talented people who believe in the DietPi project, and, wish to contribute in any way you can. - Send me an Email: micha@dietpi.com -- Join our forums: https://dietpi.com/phpbb +- Join our forums: https://dietpi.com/phpbb/ - GitHub: https://github.com/MichaIng/DietPi diff --git a/PREP_SYSTEM_FOR_DIETPI.sh b/PREP_SYSTEM_FOR_DIETPI.sh index f3561389cc..2975409dab 100644 --- a/PREP_SYSTEM_FOR_DIETPI.sh +++ b/PREP_SYSTEM_FOR_DIETPI.sh @@ -43,30 +43,45 @@ # Set $PATH variable to include all expected default binary locations, since we don't know the current system setup: https://github.com/MichaIng/DietPi/issues/3206 export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' - # Work inside /tmp as usually 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 - FP_PREP_SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")" - cd /tmp + # Make /tmp a tmpfs if it is not yet a dedicated mount + findmnt /tmp > /dev/null || mount -t tmpfs none /tmp - # APT: Prefer IPv4 by default to avoid hanging access attempts in some cases - # - NB: This needs to match the method in: /DietPi/dietpi/func/dietpi-set_hardware preferipv4 enable + # 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 + FP_PREP_SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")" + cd /tmp || exit 1 + + # APT pre-configuration + # - Remove unwanted APT configs + # RPi: Allow PDiffs since the "slow implementation" argument is outdated and PDiffs allow lower download size and less disk I/O + [[ -f '/etc/apt/apt.conf.d/50raspi' ]] && rm -v /etc/apt/apt.conf.d/50raspi + # Meveric: https://github.com/MichaIng/DietPi/issues/1285#issuecomment-355759321 + [[ -f '/etc/apt/sources.list.d/deb-multimedia.list' ]] && rm -v /etc/apt/sources.list.d/deb-multimedia.list + [[ -f '/etc/apt/preferences.d/deb-multimedia-pin-99' ]] && rm -v /etc/apt/preferences.d/deb-multimedia-pin-99 + [[ -f '/etc/apt/preferences.d/backports' ]] && rm -v /etc/apt/preferences.d/backports + # OMV: https://dietpi.com/phpbb/viewtopic.php?f=11&t=2772 + [[ -f '/etc/apt/sources.list.d/openmediavault.list' ]] && rm -v /etc/apt/sources.list.d/openmediavault.list + # Conflicting configs + rm -fv /etc/apt/apt.conf.d/*{recommends,armbian}* + # - Apply wanted APT configs: Overwritten by DietPi code archive + cat << _EOF_ > /etc/apt/apt.conf.d/97dietpi # https://raw.githubusercontent.com/MichaIng/DietPi/dev/rootfs/etc/apt/apt.conf.d/97dietpi +APT::Install-Recommends "false"; +APT::Install-Suggests "false"; +APT::AutoRemove::RecommendsImportant "false"; +APT::AutoRemove::SuggestsImportant "false"; +Acquire::Languages "none"; +Dir::Cache::srcpkgcache ""; +Acquire::GzipIndexes "true"; +Acquire::IndexTargets::deb::Packages::KeepCompressedAs "xz"; +Acquire::IndexTargets::deb::Translations::KeepCompressedAs "xz"; +Acquire::IndexTargets::deb-src::Sources::KeepCompressedAs "xz"; +_EOF_ + # - Forcing new DEB package config files (during PREP only) + echo 'DPkg::options:: "--force-confmiss,confnew";' > /etc/apt/apt.conf.d/98dietpi-forceconf + # - Prefer IPv4 by default to avoid hanging access attempts in some cases + # NB: This needs to match the method in: /DietPi/dietpi/func/dietpi-set_hardware preferipv4 enable echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99-dietpi-force-ipv4 - - # Allow PDiffs on RPi since the "slow implementation" argument is outdated and PDiffs allow lower download size and less disk I/O - [[ -f '/etc/apt/apt.conf.d/50raspi' ]] && rm /etc/apt/apt.conf.d/50raspi - - # Disable package state translation downloads - echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/98-dietpi-no_translations - - # Removing conflicting /etc/apt/sources.list.d entries - # - Meveric: https://github.com/MichaIng/DietPi/issues/1285#issuecomment-355759321 - [[ -f '/etc/apt/sources.list.d/deb-multimedia.list' ]] && rm /etc/apt/sources.list.d/deb-multimedia.list - [[ -f '/etc/apt/preferences.d/deb-multimedia-pin-99' ]] && rm /etc/apt/preferences.d/deb-multimedia-pin-99 - [[ -f '/etc/apt/preferences.d/backports' ]] && rm /etc/apt/preferences.d/backports - # - OMV: https://dietpi.com/phpbb/viewtopic.php?f=11&t=2772 - [[ -f '/etc/apt/sources.list.d/openmediavault.list' ]] && rm /etc/apt/sources.list.d/openmediavault.list - - # Fixing sources.list as Debian dropped Jessie support: https://github.com/MichaIng/DietPi/issues/2665 + # - Jessie: Fixing sources.list as Debian dropped Jessie support: https://github.com/MichaIng/DietPi/issues/2665 if grep -q 'jessie' /etc/os-release && ! grep -qi 'raspbian' /etc/os-release; then if [[ $(uname -m) == 'aarch64' ]]; then @@ -84,10 +99,10 @@ apt-get clean apt-get update - # Check for/Install APT packages required for this script to: + # Check for/Install DEB packages required for this script to: aAPT_PREREQS=( - 'wget' # Download DietPi-Globals... + 'curl' # Download DietPi-Globals... 'ca-certificates' # ...via HTTPS 'locales' # Set C.UTF-8 locale 'whiptail' # G_WHIP @@ -95,11 +110,10 @@ ) # - Pre-Buster: Support HTTPS sources for APT grep -qE '(jessie|stretch)' /etc/os-release && aAPT_PREREQS+=('apt-transport-https') - for i in "${aAPT_PREREQS[@]}" do - if ! dpkg-query -s $i &> /dev/null && ! apt-get -y --no-install-recommends install $i; then + if ! dpkg-query -s "$i" &> /dev/null && ! apt-get -y install "$i"; then echo -e "[FAILED] Unable to install $i, please try to install it manually:\n\t # apt install $i\n" exit 1 @@ -129,7 +143,6 @@ # - Remove existing settings that could break dpkg-reconfigure locales > /etc/environment [[ -f '/etc/default/locale' ]] && rm /etc/default/locale - # - NB: DEV, any changes here must be also rolled into function '/boot/dietpi/func/dietpi-set_software locale', for future script use echo 'C.UTF-8 UTF-8' > /etc/locale.gen # - dpkg-reconfigure includes: @@ -141,10 +154,8 @@ exit 1 fi - # - Export locale vars to assure the following whiptail being beautiful export LC_ALL='C.UTF-8' LANG='C.UTF-8' - # - Update /etc/default/locales with new values (not effective until next load of bash session, eg: logout/in) update-locale 'LC_ALL=C.UTF-8' @@ -161,7 +172,6 @@ 'dev' ': Unstable development branch' ) - if ! GITBRANCH=$(whiptail --title "$G_PROGRAM_NAME" --menu 'Please select the Git branch the installer should use:' --default-item 'master' --ok-button 'Ok' --cancel-button 'Exit' --backtitle "$G_PROGRAM_NAME" 12 80 3 "${aWHIP_BRANCH[@]}" 3>&1 1>&2 2>&3-); then echo -e '[ INFO ] No choice detected. Aborting...\n' @@ -171,7 +181,6 @@ unset aWHIP_BRANCH fi - echo "[ INFO ] Selected Git branch: $GITOWNER/$GITBRANCH" #------------------------------------------------------------------------------------------------ @@ -179,7 +188,7 @@ #------------------------------------------------------------------------------------------------ # NB: We have to manually handle errors, until DietPi-Globals are successfully loaded. # Download - if ! wget "https://raw.githubusercontent.com/$GITOWNER/DietPi/$GITBRANCH/dietpi/func/dietpi-globals" -O dietpi-globals; then + if ! curl -sSfL "https://raw.githubusercontent.com/$GITOWNER/DietPi/$GITBRANCH/dietpi/func/dietpi-globals" -o dietpi-globals; then echo -e '[FAILED] Unable to download dietpi-globals. Aborting...\n' exit 1 @@ -283,8 +292,8 @@ for i in /etc/systemd/system/dietpi-* do - [[ -f $i ]] && systemctl disable --now ${i##*/} - rm -Rfv $i + [[ -f $i ]] && systemctl disable --now "${i##*/}" + rm -Rfv "$i" done @@ -294,6 +303,7 @@ [[ -d '/DietPi' ]] && rm -R /DietPi rm -Rfv /{boot,mnt,etc,var/lib,var/tmp,run}/*dietpi* rm -fv /etc{,/cron.*,/{bashrc,profile,sysctl,network/if-up,udev/rules}.d}/{,.}*dietpi* + rm -fv /etc/apt/apt.conf.d/{99-dietpi-norecommends,98-dietpi-no_translations,99-dietpi-forceconf} # Pre-v6.32 [[ -f '/root/DietPi-Automation.log' ]] && rm -v /root/DietPi-Automation.log [[ -f '/boot/Automation_Format_My_Usb_Drive' ]] && rm -v /boot/Automation_Format_My_Usb_Drive @@ -417,6 +427,7 @@ '59' ': ZeroPi' '60' ': NanoPi NEO' '65' ': NanoPi NEO2' + '56' ': NanoPi NEO3' '57' ': NanoPi NEO Plus2' '64' ': NanoPi NEO Air' '63' ': NanoPi M1/T1' @@ -426,6 +437,8 @@ '62' ': NanoPi M3/T3/Fire3' '68' ': NanoPi M4/T4/NEO4' '58' ': NanoPi M4V2' + '55' ': NanoPi R2S' + '54' ': NanoPi K2' '72' ': ROCK Pi 4' '73' ': ROCK Pi S' '69' ': Firefly RK3399' @@ -458,7 +471,7 @@ for i in "${G_WHIP_MENU_ARRAY[@]}" do - [[ $HW_MODEL == $i ]] && break 2 + [[ $HW_MODEL == "$i" ]] && break 2 done @@ -570,7 +583,7 @@ for i in "${G_WHIP_MENU_ARRAY[@]}" do - [[ $DISTRO_TARGET == $i ]] && break 2 + [[ $DISTRO_TARGET == "$i" ]] && break 2 done @@ -685,7 +698,7 @@ Currently installed: $G_DISTRO_NAME (ID: $G_DISTRO)"; then G_DISTRO=$DISTRO_TARGET G_DISTRO_NAME=$DISTRO_TARGET_NAME G_HW_MODEL=$G_HW_MODEL G_RASPBIAN=$G_RASPBIAN G_EXEC /boot/dietpi/func/dietpi-set_software apt-mirror default # Meveric, update repo to use our EU mirror: https://github.com/MichaIng/DietPi/issues/1519#issuecomment-368234302 - sed -Ei 's@https?://oph\.mdrjr\.net@http://fuzon.co.uk@' /etc/apt/sources.list.d/meveric* &> /dev/null + sed -Ei 's|https?://oph\.mdrjr\.net|https://dietpi.com|' /etc/apt/sources.list.d/meveric*.list &> /dev/null # (Re)create DietPi runtime and logs dir, used by G_AGx G_EXEC mkdir -p /run/dietpi /var/tmp/dietpi/logs @@ -696,55 +709,33 @@ Currently installed: $G_DISTRO_NAME (ID: $G_DISTRO)"; then G_DIETPI-NOTIFY 2 'Marking all packages as auto-installed first, to allow effective autoremove afterwards' G_EXEC apt-mark auto $(dpkg --get-selections | mawk '{print $1}') - G_EXEC_DESC='Disable automatic recommends/suggests install and allow them to be autoremoved' - # Remove existing/conflicting files first - rm -fv /etc/apt/apt.conf.d/*recommends* - G_EXEC eval 'cat << _EOF_ > /etc/apt/apt.conf.d/99-dietpi-norecommends -APT::Install-Recommends "false"; -APT::Install-Suggests "false"; -APT::AutoRemove::RecommendsImportant "false"; -APT::AutoRemove::SuggestsImportant "false"; -_EOF_' - - G_DIETPI-NOTIFY 2 'Disable package state translation downloads' - echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/98-dietpi-no_translations - - G_EXEC_DESC='Preserve modified config files on APT update' - G_EXEC eval 'cat << _EOF_ > /etc/apt/apt.conf.d/99-dietpi-forceconf -Dpkg::options { - "--force-confdef"; - "--force-confold"; -} -_EOF_' - # DietPi list of minimal required packages, which must be installed: aPACKAGES_REQUIRED_INSTALL=( - 'apt-utils' # Allows "debconf" to pre-configure APT packages for non-interactive install + 'apt' # Debian package manager 'bash-completion' # Auto completes a wide list of bash commands and options via - 'bc' # Bash calculator, e.g. for floating point calculation - 'bzip2' # (.tar).bz2 wrapper + 'bzip2' # (.tar).bz2 archiver 'ca-certificates' # Adds known ca-certificates, necessary to practically access HTTPS sources 'console-setup' # DietPi-Config keyboard configuration + console fonts 'cron' # Background job scheduler 'curl' # Web address testing, downloading, uploading etc. - 'debconf' # APT package pre-configuration, e.g. "debconf-set-selections" for non-interactive install 'dirmngr' # GNU key management required for some APT installs via additional repos 'ethtool' # Force Ethernet link speed 'fake-hwclock' # Hardware clock emulation, to allow correct timestamps during boot before network time sync - 'gnupg' # apt-key add + 'gnupg' # apt-key add / gpg 'htop' # System monitor 'ifupdown' # Network interface configuration 'iputils-ping' # "ping" command 'isc-dhcp-client' # DHCP client 'kmod' # "modprobe", "lsmod", used by several DietPi scripts - 'locales' # Support locales, necessary for DietPi scripts, as we use C.UTF-8 as default + 'locales' # Support locales, used by dietpi-config > Language/Regional Options > Locale 'nano' # Simple text editor - 'p7zip' # .7z wrapper - 'parted' # partprobe + drive partitioning, required by DietPi-Drive_Manager + 'p7zip' # .7z archiver + 'parted' # partprobe + drive partitioning, used by DietPi-Drive_Manager 'procps' # "kill", "ps", "pgrep", "sysctl", used by several DietPi scripts 'psmisc' # "killall", used by several DietPi scripts - 'sudo' # Root permission wrapper for users within /etc/sudoers(.d/) + 'rfkill' # Block/unblock WiFi and Bluetooth adapters, only installed once to unblock everything, purged afterwards! + 'sudo' # Root permission wrapper for users permitted via /etc/sudoers(.d/) 'systemd-sysv' # Includes systemd and additional commands: "poweroff", "shutdown" etc. 'tzdata' # Time zone data for system clock, auto summer/winter time adjustment 'udev' # /dev/ and hotplug management daemon @@ -752,7 +743,7 @@ _EOF_' 'usbutils' # "lsusb", used by DietPi-Software + DietPi-Bugreport 'wget' # Download tool 'whiptail' # DietPi dialogs - #'xz-utils' # (.tar).xz wrapper + #'xz-utils' # (.tar).xz archiver ) @@ -773,7 +764,7 @@ _EOF_' fi # - systemd-timesyncd: Network time sync daemon # Available as dedicated package since Bullseye: https://packages.debian.org/systemd-timesyncd - # While the above needs to be checked against current distro to not break SSH or APT before distro upgrade, this one should be checked against target distro version. + # While the above needs to be checked against "current" distro to not break SSH or APT before distro upgrade, this one should be checked against "target" distro version. (( $DISTRO_TARGET > 5 )) && aPACKAGES_REQUIRED_INSTALL+=('systemd-timesyncd') # - fdisk: Partitioning tool used by DietPi-FS_partition_resize and DietPi-Imager @@ -805,6 +796,8 @@ _EOF_' aPACKAGES_REQUIRED_INSTALL+=('rng-tools') fi + # - Drive power management control + (( $G_HW_MODEL == 20 )) || aPACKAGES_REQUIRED_INSTALL+=('hdparm') # WiFi related if (( $WIFI_REQUIRED )); then @@ -812,14 +805,10 @@ _EOF_' aPACKAGES_REQUIRED_INSTALL+=('iw') # Tools to configure WiFi adapters aPACKAGES_REQUIRED_INSTALL+=('wireless-tools') # Same as "iw", deprecated but still required for non-nl80211 adapters aPACKAGES_REQUIRED_INSTALL+=('crda') # Set WiFi frequencies according to local regulations, based on WiFi country code - aPACKAGES_REQUIRED_INSTALL+=('rfkill') # Block/unblock wireless adapters, including WiFi and Bluetooth aPACKAGES_REQUIRED_INSTALL+=('wpasupplicant') # Support for WPA-protected WiFi network connection fi - # G_HW_MODEL specific - (( $G_HW_MODEL == 20 )) || aPACKAGES_REQUIRED_INSTALL+=('hdparm') # Drive power management adjustments - # Install gdisk if root file system is on a GPT partition, used by DietPi-FS_partition_resize [[ $(parted -s "$(lsblk -npo PKNAME "$(findmnt -no SOURCE /)")" print) == *'Partition Table: gpt'* ]] && aPACKAGES_REQUIRED_INSTALL+=('gdisk') @@ -844,7 +833,7 @@ _EOF_' if dpkg-query -s 'grub-efi-amd64' &> /dev/null || [[ -d '/boot/efi' ]]; then packages+=' grub-efi-amd64' - # On Buster+ enable secure boot compatibility: https://packages.debian.org/buster/grub-efi-amd64-signed + # On Buster+ enable secure boot compatibility: https://packages.debian.org/grub-efi-amd64-signed (( $DISTRO_TARGET > 4 )) && packages+=' grub-efi-amd64-signed shim-signed' # Grub BIOS @@ -898,7 +887,7 @@ _EOF_' elif (( $G_HW_MODEL == 16 )); then G_AGI linux-image-arm64-odroid-c4 meveric-keyring - G_EXEC_NOHALT=1 G_EXEC apt-mark manual u-boot # Workaround until C4 u-boot package has been added to repo + G_EXEC_NOHALT=1 G_EXEC apt-mark manual u-boot # Workaround until C4 u-boot package has been added to repo: https://dietpi.com/meveric/pool/c4/ # Odroid N2 elif (( $G_HW_MODEL == 15 )); then @@ -915,7 +904,7 @@ _EOF_' G_AGI linux-image-arm64-odroid-c2 meveric-keyring - # Odroid XU3/4/HC1/HC2 + # Odroid XU3/XU4/MC1/HC1/HC2 elif (( $G_HW_MODEL == 11 )); then G_AGI linux-image-4.14-armhf-odroid-xu4 meveric-keyring @@ -925,7 +914,7 @@ _EOF_' G_AGI rockpis-rk-u-boot-latest linux-4.4-rockpis-latest rockchip-overlay - # - Auto detect kernel package incl. ARMbian/others DTB + # - Generic kernel + device tree package auto detect else AUTO_DETECT_KERN_PKG=$(dpkg --get-selections | mawk '/^linux-(image|dtb)/{print $1}') @@ -986,7 +975,7 @@ _EOF_' G_DIETPI-NOTIFY 2 'Generating list of minimal packages, required for DietPi installation' - local packages=$(dpkg --get-selections ${aPACKAGES_REQUIRED_INSTALL[@]} 2> /dev/null | mawk '{print $1}') + local packages=$(dpkg --get-selections "${aPACKAGES_REQUIRED_INSTALL[@]}" 2> /dev/null | mawk '{print $1}') [[ $packages ]] && G_EXEC_DESC='Marking required packages as manually installed' G_EXEC apt-mark manual $packages # Purging additional packages, that (in some cases) do not get autoremoved: @@ -999,7 +988,7 @@ _EOF_' (( $G_DISTRO < 4 )) && G_EXEC_PRE_FUNC(){ acommand[2]='--force-yes'; } G_AGP dbus dhcpcd5 mountall initscripts '*office*' '*xfce*' '*qt5*' '*xserver*' '*xorg*' glib-networking libgtk-3-0 # Remove any autoremove prevention - rm -f /etc/apt/apt.conf.d/01autoremove* + rm -fv /etc/apt/apt.conf.d/*autoremove* G_AGA #------------------------------------------------------------------------------------------------ @@ -1009,7 +998,7 @@ _EOF_' G_DIETPI-NOTIFY 2 '-----------------------------------------------------------------------------------' #------------------------------------------------------------------------------------------------ - # - Jessie workaround: https://github.com/MichaIng/DietPi/issues/3462 + # Jessie workaround: https://github.com/MichaIng/DietPi/issues/3462 (( $G_DISTRO < 4 )) && G_EXEC_PRE_FUNC(){ acommand[2]='--force-yes'; } G_AGDUG @@ -1018,13 +1007,15 @@ _EOF_' G_DISTRO_NAME=$DISTRO_TARGET_NAME unset DISTRO_TARGET DISTRO_TARGET_NAME - G_DIETPI-NOTIFY 2 'Installing core DietPi pre-req APT packages' + G_DIETPI-NOTIFY 2 'Installing core DietPi pre-req DEB packages' - G_AGI ${aPACKAGES_REQUIRED_INSTALL[@]} + G_AGI "${aPACKAGES_REQUIRED_INSTALL[@]}" unset aPACKAGES_REQUIRED_INSTALL G_AGA + G_EXEC_DESC='Preserving modified DEB package config files from now on' G_EXEC rm -v /etc/apt/apt.conf.d/98dietpi-forceconf + #------------------------------------------------------------------------------------------------ echo G_DIETPI-NOTIFY 2 '-----------------------------------------------------------------------------------' @@ -1032,6 +1023,19 @@ _EOF_' G_DIETPI-NOTIFY 2 '-----------------------------------------------------------------------------------' #------------------------------------------------------------------------------------------------ + # https://github.com/jirka-h/haveged/pull/7 https://github.com/MichaIng/DietPi/issues/3689#issuecomment-678322767 + if [[ $G_DISTRO == 5 && $G_HW_ARCH == [23] && $G_HW_MODEL -gt 9 ]] && dpkg-query -s haveged &> /dev/null; then + + G_DIETPI-NOTIFY 2 'Upgrading haveged entropy daemon to fix an issue on ARM:' + G_DIETPI-NOTIFY 2 ' - https://github.com/jirka-h/haveged/pull/7' + G_EXEC curl -sSfLO "https://dietpi.com/downloads/binaries/buster/libhavege2_$G_HW_ARCH_NAME.deb" + G_EXEC curl -sSfLO "https://dietpi.com/downloads/binaries/buster/haveged_$G_HW_ARCH_NAME.deb" + G_AGI "./libhavege2_$G_HW_ARCH_NAME.deb" "./haveged_$G_HW_ARCH_NAME.deb" + G_EXEC_NOHALT=1 G_EXEC rm "./libhavege2_$G_HW_ARCH_NAME.deb" "./haveged_$G_HW_ARCH_NAME.deb" + G_AGA + + fi + G_DIETPI-NOTIFY 2 'Deleting list of known users and groups, not required by DietPi' getent passwd pi &> /dev/null && userdel -f pi @@ -1053,7 +1057,9 @@ _EOF_' G_DIETPI-NOTIFY 2 'Removing misc files/folders/services, not required by DietPi' + # shellcheck disable=SC2115 [[ -d '/home' ]] && rm -Rfv /home/{,.??,.[^.]}* || mkdir /home + # shellcheck disable=SC2115 [[ -d '/media' ]] && rm -Rfv /media/{,.??,.[^.]}* || mkdir /media [[ -d '/selinux' ]] && rm -Rv /selinux [[ -d '/var/cache/apparmor' ]] && rm -Rv /var/cache/apparmor @@ -1076,6 +1082,9 @@ _EOF_' 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 {} + + # - Fonts [[ -d '/usr/share/fonts' ]] && rm -vR /usr/share/fonts [[ -d '/usr/share/icons' ]] && rm -vR /usr/share/icons @@ -1097,7 +1106,7 @@ _EOF_' ) - for i in ${aservices[@]} + for i in "${aservices[@]}" do # Loop through known service locations @@ -1105,14 +1114,14 @@ _EOF_' do [[ -e $j ]] || continue - [[ -f $j ]] && systemctl disable --now ${j##*/} - # Remove if not attached to any APT package, else mask - if dpkg -S $j &> /dev/null; then + [[ -f $j ]] && systemctl disable --now "${j##*/}" + # Remove if not attached to any DEB package, else mask + if dpkg -S "$j" &> /dev/null; then - systemctl mask ${j##*/} + systemctl mask "${j##*/}" else - rm -vR $j + rm -Rv "$j" fi @@ -1120,7 +1129,7 @@ _EOF_' done - # - Remove obsolete sysvinit service entries + # - Remove obsolete SysV service entries aservices=( fake-hwclock @@ -1138,10 +1147,10 @@ _EOF_' ) - for i in ${aservices[@]} + for i in "${aservices[@]}" do - G_EXEC update-rc.d -f $i remove + G_EXEC update-rc.d -f "$i" remove done @@ -1216,7 +1225,7 @@ _EOF_ #----------------------------------------------------------------------------------- # Boot Logo - [[ -f '/boot/boot.bmp' ]] && G_EXEC wget https://github.com/$G_GITOWNER/DietPi/raw/$G_GITBRANCH/.meta/images/dietpi-logo_boot.bmp -O /boot/boot.bmp + [[ -f '/boot/boot.bmp' ]] && G_EXEC curl -sSfL "https://github.com/$G_GITOWNER/DietPi/raw/$G_GITBRANCH/.meta/images/dietpi-logo_boot.bmp" -o /boot/boot.bmp #----------------------------------------------------------------------------------- # Bash Profiles @@ -1241,11 +1250,11 @@ _EOF_ #----------------------------------------------------------------------------------- # UID bit for sudo: https://github.com/MichaIng/DietPi/issues/794 G_DIETPI-NOTIFY 2 'Setting sudo UID bit' - chmod 4755 $(command -v sudo) + chmod 4755 "$(command -v sudo)" #----------------------------------------------------------------------------------- # Dirs - G_DIETPI-NOTIFY 2 'Generating DietPi Directories' + G_DIETPI-NOTIFY 2 'Generating DietPi directories' mkdir -pv /var/lib/dietpi/{postboot.d,dietpi-software/installed} mkdir -pv /var/tmp/dietpi/logs/dietpi-ramlog_store mkdir -pv $G_FP_DIETPI_USERDATA /mnt/{samba,ftp_client,nfs_client} @@ -1263,9 +1272,9 @@ _EOF_ #----------------------------------------------------------------------------------- # Install vmtouch to lock DietPi scripts and config in file system cache - G_EXEC wget https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/vmtouch_$G_HW_ARCH_NAME.deb - G_EXEC dpkg --force-hold,confnew -i vmtouch_$G_HW_ARCH_NAME.deb - rm vmtouch_$G_HW_ARCH_NAME.deb + G_EXEC curl -sSfLO "https://dietpi.com/downloads/binaries/$G_DISTRO_NAME/vmtouch_$G_HW_ARCH_NAME.deb" + G_EXEC dpkg --force-hold,confnew -i "vmtouch_$G_HW_ARCH_NAME.deb" + rm -v "vmtouch_$G_HW_ARCH_NAME.deb" #----------------------------------------------------------------------------------- # Cron jobs @@ -1286,6 +1295,12 @@ _EOF_' #----------------------------------------------------------------------------------- # Network + G_DIETPI-NOTIFY 2 'Removing all rfkill soft blocks and the rfkill package' + rfkill unblock all + G_AGP rfkill + G_AGA + [[ -d '/var/lib/systemd/rfkill' ]] && rm -Rv /var/lib/systemd/rfkill + G_DIETPI-NOTIFY 2 'Configuring wlan/eth naming to be preferred for networked devices:' ln -sfv /dev/null /etc/systemd/network/99-default.link ln -sfv /dev/null /etc/udev/rules.d/80-net-setup-link.rules @@ -1364,8 +1379,8 @@ _EOF_' G_EXEC_DESC='Generating /etc/fstab' G_EXEC /boot/dietpi/dietpi-drive_manager 4 # Create and navigate to "/tmp/$G_PROGRAM_NAME" working directory, now assured to be tmpfs - mkdir -p /tmp/$G_PROGRAM_NAME - cd /tmp/$G_PROGRAM_NAME + G_EXEC mkdir -p /tmp/$G_PROGRAM_NAME + G_EXEC cd /tmp/$G_PROGRAM_NAME local info_use_drive_manager='Can be installed and setup by DietPi-Drive_Manager.\nSimply run "dietpi-drive_manager" and select "Add network drive".' echo -e "Samba client: $info_use_drive_manager" > /mnt/samba/readme.txt @@ -1437,7 +1452,6 @@ right_meter_modes=1 1 2 2 2 _EOF_' G_DIETPI-NOTIFY 2 'Configuring fake-hwclock:' - systemctl stop fake-hwclock # Allow times in the past G_CONFIG_INJECT 'FORCE=' 'FORCE=force' /etc/default/fake-hwclock systemctl restart fake-hwclock # Failsafe, apply now if date is way far back... @@ -1463,21 +1477,25 @@ _EOF_' fi G_DIETPI-NOTIFY 2 'Reducing getty count and resource usage:' - systemctl mask getty-static + systemctl mask --now getty-static # - logind features disabled by default. Usually not needed and all features besides auto getty creation are not available without libpam-systemd package. - # - It will be unmasked/enabled, automatically if libpam-systemd got installed during dietpi-software install, usually with desktops. - systemctl disable --now systemd-logind 2> /dev/null - systemctl mask systemd-logind + # - It will be unmasked, automatically if libpam-systemd got installed during dietpi-software install, usually with desktops. + systemctl mask --now systemd-logind + + #G_DIETPI-NOTIFY 2 'Configuring locales:' # Runs at start of script - G_DIETPI-NOTIFY 2 'Configuring regional settings (TZdata):' + G_DIETPI-NOTIFY 2 'Configuring time zone:' rm -fv /etc/{localtime,timezone} ln -sv /usr/share/zoneinfo/UTC /etc/localtime G_EXEC dpkg-reconfigure -f noninteractive tzdata - G_DIETPI-NOTIFY 2 'Configuring regional settings (Keyboard):' + G_DIETPI-NOTIFY 2 'Configuring keyboard:' dpkg-reconfigure -f noninteractive keyboard-configuration # Keyboard must be plugged in for this to work! - #G_DIETPI-NOTIFY 2 "Configuring regional settings (Locale):" # Runs at start of script + G_DIETPI-NOTIFY 2 'Configuring console:' # This can be wrong, e.g. when selecting a non-UTF-8 locale during Debian installer + G_CONFIG_INJECT 'CHARMAP=' 'CHARMAP="UTF-8"' /etc/default/console-setup + G_EXEC eval "debconf-set-selections <<< 'console-setup console-setup/charmap47 select UTF-8'" + G_EXEC setupcon --save # G_HW_ARCH specific G_DIETPI-NOTIFY 2 'Applying G_HW_ARCH specific tweaks:' @@ -1498,6 +1516,9 @@ _EOF_ # Apply usb-storage quirks to disable UAS for unsupported drives (Seagate ST5000LM000-2AN170): https://github.com/MichaIng/DietPi/issues/2905 echo 'options usb-storage quirks=0bc2:ab30:u' > /etc/modprobe.d/dietpi-usb-storage_quirks.conf + # Fix grub install device: https://github.com/MichaIng/DietPi/issues/3700 + dpkg-query -s grub-pc &> /dev/null && G_EXEC eval "debconf-set-selections <<< 'grub-pc grub-pc/install_devices multiselect /dev/sda'" + # Update initramfs with above changes if command -v update-tirfs &> /dev/null; then @@ -1523,10 +1544,10 @@ _EOF_ # Since Debian Bullseye, spindown_time is not applied if APM is not supported by the drive. force_spindown_time is required to override that. local spindown='spindown_time' (( $G_DISTRO > 5 )) && spindown='force_spindown_time' - G_EXEC eval 'cat << _EOF_ > /etc/hdparm.conf + G_EXEC eval "cat << _EOF_ > /etc/hdparm.conf apm = 127 $spindown = 120 -_EOF_' +_EOF_" unset spindown fi @@ -1540,14 +1561,14 @@ _EOF_' elif (( $G_HW_MODEL == 70 )); then # Install latest kernel/drivers - G_EXEC wget https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/dragon_fly_check/uImage -O /boot/uImage - G_EXEC wget https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/dragon_fly_check/3.10.38.bz2 + G_EXEC curl -sSfL https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/dragon_fly_check/uImage -o /boot/uImage + G_EXEC curl -sSfLO https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/dragon_fly_check/3.10.38.bz2 G_EXEC tar -xf 3.10.38.bz2 -C /lib/modules/ rm 3.10.38.bz2 # - USB audio update - G_EXEC wget https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/dsd-marantz/snd-usb-audio.ko -O /lib/modules/3.10.38/kernel/sound/usb/snd-usb-audio.ko + G_EXEC curl -sSfL https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/dsd-marantz/snd-usb-audio.ko -o /lib/modules/3.10.38/kernel/sound/usb/snd-usb-audio.ko # - Ethernet update - G_EXEC wget https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/sparky-eth/ethernet.ko -O /lib/modules/3.10.38/kernel/drivers/net/ethernet/acts/ethernet.ko + G_EXEC curl -sSfL https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/sparky-eth/ethernet.ko -o /lib/modules/3.10.38/kernel/drivers/net/ethernet/acts/ethernet.ko # Boot args cat << _EOF_ > /boot/uenv.txt @@ -1625,8 +1646,8 @@ _EOF_ # Update USBridgeSig Ethernet driver via postinst kernel script, until it has been merged into official RPi kernel: https://github.com/allocom/USBridgeSig/tree/master/ethernet cat << _EOF_ > /etc/kernel/postinst.d/dietpi-USBridgeSig #!/bin/bash -# Only apply to ARMv7+ kernel -[[ \$1 == *'-v7+' ]] || exit 0 +# Only apply to v7+ and v8+ kernel +[[ \$1 == *'-v'[78]'+' ]] || exit 0 echo "[ INFO ] Updating asix ax88179 driver for kernel \$1, as provided by allo.com:" echo '[ INFO ] - https://github.com/allocom/USBridgeSig/tree/master/ethernet' echo '[ INFO ] Downloading driver...' @@ -1639,17 +1660,17 @@ echo '[ INFO ] Cleaning up...' rm -v /tmp/ax88179_178a.ko || exit 0 _EOF_ chmod +x /etc/kernel/postinst.d/dietpi-USBridgeSig - # - Update for all installed ARMv7+ kernel versions now - for i in /lib/modules/*-v7+ + # - Update for all installed v7+ and v8+ kernel versions now + for i in /lib/modules/*-v[78]+ do [[ -d $i ]] || continue i=${i##*/} - /etc/kernel/postinst.d/dietpi-USBridgeSig $i + /etc/kernel/postinst.d/dietpi-USBridgeSig "$i" done - # - Pine A64 (and possibily others): Cursor fix for FB + # - PINE A64 (and possibily others): Cursor fix for FB elif (( $G_HW_MODEL == 40 )); then cat << _EOF_ > /etc/bashrc.d/dietpi-pine64-cursorfix.sh @@ -1666,7 +1687,7 @@ _EOF_ fi - # - ARMbian special + # - Armbian special if [[ -f '/boot/armbianEnv.txt' ]]; then # Reset default kernel log verbosity, reduced to "1" on most Armbian images @@ -1708,7 +1729,7 @@ _EOF_ # - Set Pi cmdline.txt back to normal [[ -f '/boot/cmdline.txt' ]] && sed -i 's/ rootdelay=10//g' /boot/cmdline.txt - G_DIETPI-NOTIFY 2 'Disabling generic BT by default' + G_DIETPI-NOTIFY 2 'Disabling Bluetooth by default' /boot/dietpi/func/dietpi-set_hardware bluetooth disable # - Set WiFi @@ -1824,7 +1845,7 @@ _EOF_ G_DIETPI-NOTIFY 2 'Clearing items below tmpfs mount points' G_EXEC mkdir -p /mnt/tmp_root - G_EXEC mount $(findmnt -no source /) /mnt/tmp_root + G_EXEC mount "$(findmnt -no SOURCE /)" /mnt/tmp_root rm -vRf /mnt/tmp_root/{dev,proc,run,sys,tmp,var/log}/{,.??,.[^.]}* G_EXEC umount /mnt/tmp_root G_EXEC rmdir /mnt/tmp_root @@ -1833,7 +1854,7 @@ _EOF_ rm -Rfv /{root,home/*}/.{bash_history,nano_history,wget-hsts,cache,local,config,gnupg,viminfo,dbus,gconf,nano,vim} # Remove PREP script - [[ -f $FP_PREP_SCRIPT ]] && rm -v $FP_PREP_SCRIPT + [[ -f $FP_PREP_SCRIPT ]] && rm -v "$FP_PREP_SCRIPT" sync @@ -1841,7 +1862,7 @@ _EOF_ kernel_apt_packages=$(dpkg -l | grep -E '[[:blank:]]linux-(image|dtb)-[0-9]') if [[ $kernel_apt_packages ]]; then - G_DIETPI-NOTIFY 2 'The following kernel APT packages have been found, please purge outdated ones:' + G_DIETPI-NOTIFY 2 'The following kernel DEB packages have been found, please purge outdated ones:' echo "$kernel_apt_packages" fi diff --git a/README.md b/README.md index f0dce87957..651b074cb9 100644 --- a/README.md +++ b/README.md @@ -7,42 +7,37 @@

optimised • simplified • for everyone

- find out moredownload image + WebsiteDocumentationView all supported platforms


- Optional "ready to run" optimised software choices with dietpi-software.
- Feature rich configuration tool for your device with dietpi-config. + Ready to run optimised software choices with dietpi-software +
Feature rich configuration tool for your device with dietpi-config.


-

- myVirtualserver
- DietPi's web hosting is powered by myVirtualserver. -

- A wide range of SBCs and VMs are supported. Click here for the full list. -

-

## Introduction -DietPi is an extremely lightweight Debian-based OS. With images starting at 400MB, that's 3x lighter than "Raspbian Lite". It is highly optimized for minimal CPU and RAM resource usage, ensuring your SBC always runs at its maximum potential. The programs use lightweight Whiptail menus. You'll spend less time staring at the command line, and more time enjoying DietPi. +DietPi is an extremely lightweight Debian-based OS. It is highly optimised for minimal CPU and RAM resource usage, ensuring your SBC always runs at its maximum potential. -Use `dietpi-software` to quickly and easily install popular software that's "Ready to run" and optimised for your system. Only the software you need is installed. Use `dietpi-services` to control which installed software has higher or lower priority levels (nice, affinity, policy scheduler). +The **dietpi programs** use lightweight whiptail menus. You'll spend more time enjoying DietPi and applications you need and less time staring at the command line. -`dietpi-update` automatically checks for updates and informs you when they are available. Update instantly, without having to write a new image. `dietpi-automation` Allows you to completely automate a DietPi installation with no user input, simply by configuring "dietpi.txt" before powering on. +Use `dietpi-software` to quick and easy install **Ready to Run** & **Optimised** applications for your system. DietPi will do all the necessary configurations, including starting the services. Few highlights: [Desktop Environments](https://dietpi.com/docs/user-optimised-software/#desktops), [Remote Desktop access](https://dietpi.com/docs/user-optimised-software/#remote-desktop-access), [Media systems and Media Players](https://dietpi.com/docs/user-optimised-software/#media-systems), [Torrents and Downloading](https://dietpi.com/docs/user-optimised-software/#bittorrent-download-tools), [Cloud and Backup](https://dietpi.com/docs/user-optimised-software/#cloud-backups), [Gaming](https://dietpi.com/docs/user-optimised-software/#emulation-gaming), [Social & Search](https://dietpi.com/docs/user-optimised-software/#social-search), [Camera and Surveillance](https://dietpi.com/docs/user-optimised-software/#camera-surveillance), [WiFi Hotspot](https://dietpi.com/docs/user-optimised-software/#wifi-hotspot), [System Stats & Management](https://dietpi.com/docs/user-optimised-software/#system-stats-management), [Home automation](https://dietpi.com/docs/user-optimised-software/#home-automation), [Hardware & Voice Projects](https://dietpi.com/docs/user-optimised-software/#hardware-projects), [Webserver Stacks](https://dietpi.com/docs/user-optimised-software/#webserver-stacks), [DNS server / PiHole](https://dietpi.com/docs/user-optimised-software/#dns-servers), [File Servers](https://dietpi.com/docs/user-optimised-software/#file-servers), [Cloud printing and Print 3D](https://dietpi.com/docs/user-optimised-software/#printing) and much more. + +Use `dietpi-services` to control which installed software has higher or lower priority levels (nice, affinity, policy scheduler). + +`dietpi-update` automatically checks for updates and informs you when they are available. Update instantly, without having to write a new image. **DietPi automation** allows you to completely automate a DietPi installation with no user input, simply by configuring `dietpi.txt` before powering on. ## The DietPi Project Team -### Lead +### Contributors #### Micha (MichaIng) -Project lead of DietPi (20/02/2019 and onwards), source code contributor, bug fixes, software improvements, DietPi forum administrator. +_Joined Q3 2017_ ---- - -### Active Contributors +Project lead (20/02/2019 and onwards), source code contributor, bug fixes, software improvements, DietPi forum administrator. #### Daniel Knight (Fourdee) @@ -66,20 +61,32 @@ _Joined Q4 2019_ DietPi forum moderator, support, testing, bug reports + investigation and valuable feedback. +#### StephanStS + +_Joined Q4 2019_ + +NanoPi image creator, tester and bug reports. + +#### Petru (fpetru) + +_Joined 2020-05-31_ + +DietPi documentation author, product manager, SEO and DietPi visibility recommendations. + --- ### Collaborations #### DietPi + Amiberry -_02/09/2016_ +_Since 2016-09-02_ Joint venture to bring you the ultimate Amiga experience on your SBC, running lightweight and optimised DietPi at its core: https://github.com/MichaIng/DietPi/issues/474 --- -### Previous/Inactive Contributors +### Hall of Fame #### K-Plan @@ -103,7 +110,7 @@ Contributions to the DietPi in general, including source code, testing, new devi _Joined 2015-10-10_ -Provided DietPi.com web hosting for 1 year until April 17th 2016. Additionally: forum moderator, testing, bug reporting. +Provided dietpi.com web hosting for 1 year until April 17th 2016. Additionally: forum moderator, testing, bug reporting. #### xenfomation @@ -119,12 +126,6 @@ Created the DietPi image for NanoPi M3/T3. --- -### Honourable Mentions/Thanks - -A personal thanks to **Pilovali** for helping DietPi during our early days with desperately needed web hosting. - ---- - ## Contributing Git coders, please use the active development branch: [dev](https://github.com/MichaIng/DietPi/tree/dev) @@ -135,7 +136,7 @@ Are you able to: - Provide feedback and/or test areas of DietPi, to improve the user experience? - Report bugs? -- Improve/add more features to the [DietPi website](https://dietpi.com)? +- Improve/add more features to the [DietPi website](https://dietpi.com/)? - Compile software for our supported SBCs? - Contribute to DietPi with programming on GitHub? - Suggest new software that we can add to the `dietpi-software` install system? @@ -144,7 +145,7 @@ If so, let us know! We are always looking for talented people who believe in the DietPi project, and, wish to contribute in any way you can. - Send me an Email: micha@dietpi.com -- Join our forums: https://dietpi.com/phpbb +- Join our forums: https://dietpi.com/phpbb/ - GitHub: https://github.com/MichaIng/DietPi ### FeatHub @@ -157,7 +158,7 @@ Vote for new suggestions, feature-, software- or image requests, or add your own DietPi Copyright (C) 2020 MichaIng - Email micha@dietpi.com -- Web https://dietpi.com +- Web https://dietpi.com/ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -202,7 +203,7 @@ Links to hardware and software manufacturers, sources and build instructions use - [Debian distribution](https://salsa.debian.org/) - [Raspberry](https://github.com/raspberrypi) [Pi](https://github.com/RPi-Distro) - [Hardkernel](https://github.com/hardkernel?tab=repositories) -- [Meverics Odroid repository](https://forum.odroid.com/viewtopic.php?f=52&t=5908) +- [Meveric's Odroid repository](https://forum.odroid.com/viewtopic.php?f=52&t=5908) - [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) @@ -270,3 +271,14 @@ Links to hardware and software manufacturers, sources and build instructions use - [TasmoAdmin](https://github.com/reloxx13/TasmoAdmin) - [Domoticz](https://github.com/domoticz/domoticz) - [Firefox Sync Server](https://github.com/mozilla-services/syncserver) +- [Jellyfin](https://github.com/jellyfin/jellyfin) +- [Komga](https://github.com/gotson/komga) + +--- + + +

+ myVirtualserver +
DietPi's web hosting is powered by myVirtualserver. +

+ diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..7a72c57424 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,13 @@ +## Security Policy + +### Coverage + +Please report security vulnerabilities shipped with our images or created by our scripts (in **/boot/dietpi/**), like insecure system configurations or insecure default software implementations. + +We are **not** responsible for a security vulnerability in any package or binary shipped with Debian, Raspbian, any 3rd party repository or within the software executables themselves. In such cases please report issues to the related repository bug tracker or upstream developers. You may still report those additionally to us, so that we may find a way to work around the issue for our implementation until a fix is available. + +### Reporting a Vulnerability + +If you have discovered a potential security issue within our images, scripts, configs or software implementations, please send all relevant information (such as references, commits, or code examples that would be useful in reproducing the issue) to , so that we may be able to investigate and fix it internally without having our users systems exposed. + +Only open an issue at https://github.com/MichaIng/DietPi/issues if you are sure that the contained information cannot be used to compromise any of our users systems. diff --git a/config.txt b/config.txt index a62ff5c17b..e9e5c0ae10 100644 --- a/config.txt +++ b/config.txt @@ -58,9 +58,6 @@ gpu_mem_256=16 gpu_mem_512=16 gpu_mem_1024=16 -#-------Max USB current--------- -max_usb_current=1 - #-------Boot splash screen------ disable_splash=1 diff --git a/dietpi.txt b/dietpi.txt index 71e0428c64..92ed49574f 100644 --- a/dietpi.txt +++ b/dietpi.txt @@ -45,9 +45,9 @@ AUTO_SETUP_NET_STATIC_DNS=9.9.9.9 AUTO_SETUP_NET_HOSTNAME=DietPi ##### Misc Options ##### -# Swapfile size to generate: 0=disable | 1=auto (2GB-RAM = size) | 2+=manual (MB) +# Swap space size to generate: 0 => disable | 1 => auto | 2 and up => size in MiB AUTO_SETUP_SWAPFILE_SIZE=1 -# Swapfile location +# Swap space location: "zram" => swap space on /dev/zram0 (auto-size = 50% of RAM size) | /path/to/file => swap file at location (auto-size = 2 GiB minus RAM size) AUTO_SETUP_SWAPFILE_LOCATION=/var/swap # Set to "1" to disable HDMI output (and GPU/VPU where supported) for supported devices: RPi, Odroid C1, Odroid C2 diff --git a/dietpi/boot b/dietpi/boot index 8e6a5c9c72..9947cdb3f3 100644 --- a/dietpi/boot +++ b/dietpi/boot @@ -32,11 +32,11 @@ while (( $loops_left )) do - G_DIETPI-NOTIFY 2 "$(date) | Waiting for valid network connection before continuing boot | Mode=$mode" + G_DIETPI-NOTIFY 2 "Waiting for valid network connection before continuing boot | Mode=$mode" if ip r l 0/0 &> /dev/null; then - G_DIETPI-NOTIFY 0 "$(date) | Valid network connection found" + G_DIETPI-NOTIFY 0 'Valid network connection found' return 0 fi @@ -46,7 +46,7 @@ done - G_DIETPI-NOTIFY 1 "$(date) | Waiting for valid network connection timed out" + G_DIETPI-NOTIFY 1 'Waiting for valid network connection timed out' return 1 } diff --git a/dietpi/dietpi-backup b/dietpi/dietpi-backup index 604f7ad5ad..ceeea2945b 100644 --- a/dietpi/dietpi-backup +++ b/dietpi/dietpi-backup @@ -65,7 +65,7 @@ RSYNC_LOGGING_OPTIONS="-v --log-file=$FP_LOG" # Date format for logs - Print_Date(){ date +"%d-%m-%Y %H:%M"; } + Print_Date(){ date +"%Y-%m-%d_%T"; } Create_Filter_Include_Exclude(){ @@ -121,13 +121,13 @@ _EOF_ Services_Stop - # Generate target dir. + # Generate target dir mkdir -p "$FP_TARGET" # Error: Unable to create target folder. if [[ ! -d $FP_TARGET ]]; then - G_WHIP_MSG "$RSYNC_MODE_TEXT Failed:\n\nUnable to create $FP_TARGET" + G_WHIP_MSG "$RSYNC_MODE_TEXT failed:\n\nUnable to create $FP_TARGET" # Error: Rsync is already running elif pgrep 'rsync' &> /dev/null; then @@ -137,7 +137,7 @@ _EOF_ else # Start Backup - echo -e "DietPi-Backup Log File. $(date +"%d-%m-%Y_%H%M")\n\n" > $FP_LOG + echo -e "DietPi-Backup Log File. $(Print_Date)\n\n" > $FP_LOG # Generate Exclude/Include lists Create_Filter_Include_Exclude @@ -145,12 +145,11 @@ _EOF_ while : do - # - system - RSYNC_MODE_TEXT='Backup' + # System mkdir -p "$FP_TARGET"/data - # - - Check for sufficient free space - # NB: working in KiB until end MiB conversion, as, don't like using long long int, and, KiB should offer a good end result. + # Check for sufficient free space + # - NB: working in KiB until end MiB conversion, as, don't like using long long int, and, KiB should offer a good end result. local old_backup_size=$(du -ks "$FP_TARGET"/data | mawk '{print $1}') # Actual disk space usage rsync --dry-run --stats $RSYNC_RUN_OPTIONS_BACKUP "$FP_SOURCE" "$FP_TARGET"/data/ > /tmp/dietpi-backup_result @@ -176,19 +175,19 @@ _EOF_ fi - G_DIETPI-NOTIFY 2 "$RSYNC_MODE_TEXT $FP_TARGET: in progress, please wait..." + G_DIETPI-NOTIFY 2 "$RSYNC_MODE_TEXT to $FP_TARGET in progress, please wait..." rsync $RSYNC_RUN_OPTIONS_BACKUP $RSYNC_LOGGING_OPTIONS "$FP_SOURCE" "$FP_TARGET"/data/ EXIT_CODE=$? G_DIETPI-NOTIFY -1 $EXIT_CODE "$G_PROGRAM_NAME: $RSYNC_MODE_TEXT" if (( $EXIT_CODE == 0 )); then - echo -e "$RSYNC_MODE_TEXT Completed : $(Print_Date)" >> "$FP_TARGET/$BACKUP_STATS_FILENAME" - G_WHIP_MSG "$RSYNC_MODE_TEXT Completed:\n - $FP_TARGET" + echo -e "$RSYNC_MODE_TEXT completed : $(Print_Date)" >> "$FP_TARGET/$BACKUP_STATS_FILENAME" + G_WHIP_MSG "$RSYNC_MODE_TEXT completed:\n - $FP_TARGET" else - G_WHIP_MSG "$RSYNC_MODE_TEXT Failed:\n - $FP_TARGET\n\nYou will given an option to view the logfile on the next screen. Please check it for information and/or errors." + G_WHIP_MSG "$RSYNC_MODE_TEXT failed:\n - $FP_TARGET\n\nYou will given an option to view the logfile on the next screen. Please check it for information and/or errors." fi @@ -228,9 +227,9 @@ _EOF_ if [[ ! -f $FP_TARGET/$BACKUP_STATS_FILENAME ]]; then G_DIETPI-NOTIFY 2 "No Backup was found in $FP_TARGET" - G_DIETPI-NOTIFY 1 "$RSYNC_MODE_TEXT Failed.\n" + G_DIETPI-NOTIFY 1 "$RSYNC_MODE_TEXT failed.\n" - G_WHIP_MSG "$RSYNC_MODE_TEXT Failed:\n\n$FP_TARGET/$BACKUP_STATS_FILENAME does not exist\n\nHave you created a backup?" + G_WHIP_MSG "$RSYNC_MODE_TEXT failed:\n\n$FP_TARGET/$BACKUP_STATS_FILENAME does not exist\n\nHave you created a backup?" # Error: Rsync is already running elif pgrep 'rsync' &> /dev/null; then @@ -243,20 +242,19 @@ _EOF_ # Generate Exclude/Include lists Create_Filter_Include_Exclude - G_DIETPI-NOTIFY 2 "$RSYNC_MODE_TEXT $FP_TARGET: in progress, please wait..." + G_DIETPI-NOTIFY 2 "$RSYNC_MODE_TEXT from $FP_TARGET in progress, please wait..." - RSYNC_MODE_TEXT='Restore' rsync $RSYNC_RUN_OPTIONS_RESTORE $RSYNC_LOGGING_OPTIONS "$FP_TARGET"/data/ "$FP_SOURCE" EXIT_CODE=$? G_DIETPI-NOTIFY -1 $EXIT_CODE "$G_PROGRAM_NAME: $RSYNC_MODE_TEXT" if (( $EXIT_CODE == 0 )); then - echo -e "$RSYNC_MODE_TEXT Completed : $(Print_Date)" >> "$FP_TARGET/$BACKUP_STATS_FILENAME" - G_WHIP_MSG "$RSYNC_MODE_TEXT Completed:\n - $FP_TARGET\n\nNB: A Reboot is highly recommended." + echo -e "$RSYNC_MODE_TEXT completed : $(Print_Date)" >> "$FP_TARGET/$BACKUP_STATS_FILENAME" + G_WHIP_MSG "$RSYNC_MODE_TEXT completed:\n - $FP_TARGET\n\nNB: A Reboot is highly recommended." else - G_WHIP_MSG "$RSYNC_MODE_TEXT Failed:\n - $FP_TARGET\n\nYou will given an option to view the logfile on the next screen. Please check it for information and/or errors." + G_WHIP_MSG "$RSYNC_MODE_TEXT failed:\n - $FP_TARGET\n\nYou will given an option to view the logfile on the next screen. Please check it for information and/or errors." fi @@ -301,12 +299,9 @@ _EOF_ for ((i=0; i<${#aSUPPORTED_FILESYSTEMS[@]}; i++)) do - if [[ $TARGET_FILESYSTEM_TYPE == ${aSUPPORTED_FILESYSTEMS[$i]} ]]; then - - TARGET_DIRECTORY_SUPPORTED=1 - break - - fi + [[ $TARGET_FILESYSTEM_TYPE == "${aSUPPORTED_FILESYSTEMS[$i]}" ]] || continue + TARGET_DIRECTORY_SUPPORTED=1 + break done @@ -356,7 +351,7 @@ _EOF_ if [[ -f $FP_TARGET'/'$BACKUP_STATS_FILENAME ]]; then G_WHIP_MENU_ARRAY+=('Delete' ": Remove backup ($FP_TARGET)") - backup_last_completed=$(grep 'Completed' "$FP_TARGET/$BACKUP_STATS_FILENAME" | tail -1) + backup_last_completed=$(grep 'ompleted' "$FP_TARGET/$BACKUP_STATS_FILENAME" | tail -1) fi G_WHIP_MENU_ARRAY+=('' '●─ Run ') @@ -456,7 +451,7 @@ _EOF_ for ((i=0; i<${#search_results_list[@]}; i++)) do - local last_backup_date=$(grep 'Completed' ${search_results_list[$i]} | tail -1 | sed 's/.*: //') # Date of last backup for this backup + local last_backup_date=$(grep 'ompleted' ${search_results_list[$i]} | tail -1 | sed 's/.*: //') # Date of last backup for this backup local backup_directory=$(echo -e ${search_results_list[$i]} | sed 's/\/'"$BACKUP_STATS_FILENAME"'//g') # Backup directory (minus the backup file), that we can use for target backup directory. G_WHIP_MENU_ARRAY+=("$backup_directory" ": $last_backup_date") @@ -545,7 +540,7 @@ _EOF_ Error_Rsync_Already_Running(){ G_DIETPI-NOTIFY 1 'Another Rsync process is already running.' - echo -e "$RSYNC_MODE_TEXT failed: $(date +"%d-%m-%Y_%H%M"). Rsync is already running." >> "$FP_TARGET/$BACKUP_STATS_FILENAME" + echo -e "$RSYNC_MODE_TEXT failed: $(Print_Date). Rsync is already running." >> "$FP_TARGET/$BACKUP_STATS_FILENAME" G_WHIP_MSG "$RSYNC_MODE_TEXT Error:\n\nA $RSYNC_MODE_TEXT could not be started as rsync is already running." } diff --git a/dietpi/dietpi-cloudshell b/dietpi/dietpi-cloudshell index 0c27463b91..29f4526db9 100644 --- a/dietpi/dietpi-cloudshell +++ b/dietpi/dietpi-cloudshell @@ -74,58 +74,32 @@ } - # BC does not allow for printing leading zeros. - BC_ADD_LEADING_ZERO(){ - - #$1 = string input - local return_value=$1 - - #BC - Add leading zero to start of .* string. - # +0 - if [[ ${return_value:0:1} == '.' ]]; then - - return_value="0$return_value" - - # -0 - elif [[ ${return_value:0:2} == '-.' ]]; then - - return_value="-0.${return_value#-.}" - - fi - - echo "$return_value" - - } - # Converts a byte int to string, in human readable byte format. BYTE_PRINT_CONVERSION(){ - local return_value=0 - local decimal_count=1 - # $1=byte value - # - KB - if (( $1 < 1048576 )); then + # bytes + if (( $1 < 1024 )); then - return_value="$(bc -l <<< "scale=$decimal_count; $1 / 1024") KB" + echo -n "$1 bytes" - # - MB - elif (( $1 < 1073741824 )); then + # KiB + elif (( $1 < 1048576 )); then - return_value="$(bc -l <<< "scale=$decimal_count; $1 / 1024 / 1024") MB" + printf '%.1f KiB' "$(($1*100/1024+1))e-2" - # - GB - else + # MiB + elif (( $1 < 1073741824 )); then - return_value="$(bc -l <<< "scale=$decimal_count; $1 / 1024 / 1024 / 1024") GB" + printf '%.1f MiB' "$(($1*100/1024**2+1))e-2" - fi + # GiB + elif (( $1 )); then - # BC - Add leading zero to start of .* string. - return_value=$(BC_ADD_LEADING_ZERO "$return_value") + printf '%.1f GiB' "$(($1*100/1024**3+1))e-2" - echo "$return_value" + fi } @@ -134,32 +108,29 @@ # - 1MB = 8Mbit | 1Mbit = 0.125MB BIT_PRINT_CONVERSION(){ - local return_value=0 - local decimal_count=1 - # $1=byte value - # - Kbit - if (( $1 < 1000000 )); then + # bit + if (( $1 < 1000 )); then - return_value="$(bc -l <<< "scale=$decimal_count; $1 * 8 / 1000") Kbit" + echo -n "$(($1*8)) bit" - # - MBit - elif (( $1 < 1000000000 )); then + # Kbit + elif (( $1 < 1000000 )); then - return_value="$(bc -l <<< "scale=$decimal_count; $1 * 8 / 1000 / 1000") Mbit" + printf '%.1f Kbit' "$(($1*800/1000+1))e-2" - # - GBit - else + # Mbit + elif (( $1 < 1000000000 )); then - return_value="$(bc -l <<< "scale=$decimal_count; $1 * 8 / 1000 / 1000 / 1000") Gbit" + printf '%.1f Mbit' "$(($1*800/1000**2+1))e-2" - fi + # Gbit + elif (( $1 )); then - # BC - Add leading zero to start of .* string. - return_value=$(BC_ADD_LEADING_ZERO "$return_value") + printf '%.1f Gbit' "$(($1*800/1000**3+1))e-2" - echo "$return_value" + fi } @@ -217,7 +188,7 @@ #$C_PERCENT_GRAPH = return text # Convert to int - local input_value=$(cut -d. -f1 <<< $1) + local input_value=${1%.*} # Cap input value if (( $input_value > 100 )); then @@ -375,8 +346,8 @@ CPU_TOTALPROCESSES=0 Obtain_CPU(){ - CPU_TOTALPROCESSES=$(( $(ps --ppid 2 -p 2 --deselect | wc -l) - 2 )) # - ps process and descriptions. - [[ -r '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor' ]] && CPU_GOV=$( 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_CONFIG_INJECT 'temp_limit=' "temp_limit=$G_WHIP_RETURNED_VALUE" /boot/config.txt REBOOT_REQUIRED=1 @@ -1925,8 +1900,7 @@ Current setting: $user_frequency_min_text" && G_CONFIG_INJECT 'CONFIG_CPU_MIN_FR 'ARM Idle Frequency') - MIN_VALUE=100 - MAX_VALUE=600 + MIN_VALUE=200 MAX_VALUE=600 G_WHIP_DEFAULT_ITEM=$arm_freq_min if G_WHIP_INPUTBOX "ARM frequency (MHz) used by CPU governors powersave and conservative/ondemand/interactive when on idle. - Recommended value: 300\n - Valid range: $MIN_VALUE - $MAX_VALUE\n - Setting a value outside of range will reset to RPi defaults."; then @@ -1948,8 +1922,7 @@ Current setting: $user_frequency_min_text" && G_CONFIG_INJECT 'CONFIG_CPU_MIN_FR 'ARM Initial Turbo') - MIN_VALUE=1 - MAX_VALUE=60 + MIN_VALUE=1 MAX_VALUE=60 G_WHIP_DEFAULT_ITEM=$initial_turbo if G_WHIP_INPUTBOX "Amount of seconds on boot, where the CPU runs at highest clock, before it starts to respect the CPU governor. This reduces boot time quite much since RPi boots with powersave governor until the chosen one is applied at later boot stage. - Recommended value: 20\n - Valid range: $MIN_VALUE - $MAX_VALUE\n - Setting a value outside of range will disable this feature."; then diff --git a/dietpi/dietpi-drive_manager b/dietpi/dietpi-drive_manager index b178922aeb..79dd775d3c 100644 --- a/dietpi/dietpi-drive_manager +++ b/dietpi/dietpi-drive_manager @@ -235,10 +235,10 @@ $swap_mounts (( ${aDRIVE_ISREADONLY_CURRENTLY[$index]} )) && options=',ro' # Additional FS-specific options - # - NFTS: Enable POSIX permissions + # - NTFS: Enable POSIX permissions and prevent splitting write buffers into 4k chunks: https://manpages.debian.org/ntfs-3g#OPTIONS if [[ ${aDRIVE_FSTYPE[$index]} == 'ntfs' ]]; then - options+=',permissions' + options+=',permissions,big_writes' fi @@ -1124,15 +1124,12 @@ Do you wish to ignore this warning, and, mount the drive regardless?" || return # Show reserved blocks percentage for ext4 drives behind capacity: if [[ ${aDRIVE_FSTYPE[$MENU_DRIVE_INDEX]} == 'ext4' ]]; then - local reserved_blocks_percent_current=0 - local fp_tmp='.dumpe2fs_out_tmp' + 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) + 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=$(bc -l <<< "scale=3;(100*$reserved_block_count)/$block_count") - # Correct rounding to final scale - reserved_blocks_percent_current=$(bc -l <<< "scale=2;(($reserved_blocks_percent_current*100)+0.5)/100" | sed 's/^\./0\./' | sed '/.0$/s/0$//' | sed 's/\.0$//') + 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 @@ -1280,26 +1277,18 @@ Please choose another drive or format this one with another file system, e.g. ex do G_WHIP_DEFAULT_ITEM=$reserved_blocks_percent_current - if G_WHIP_INPUTBOX 'Ext4 formatted drives allow the reservation of drive space for the root user to assure system functionality, if filled by other users or processes, and to avoid fragmentation of large files.\n + G_WHIP_INPUTBOX 'Ext4 formatted drives allow the reservation of drive space for the root user to assure system functionality, if filled by other users or processes, and to avoid fragmentation of large files.\n However, on modern drives, the default of 5% reserved blocks is often by orders of magnitude larger than necessary. You may want to reduce the percentage to an absolute reserved space of about 500 MiB, which should be enough, to enable root user starting and maintaining the system. Additionally, on non rootfs drives reserved blocks are not necessary at all.\n -Please enter the desired percentage of reserved blocks, e.g. "0.05" for 0.05% or "10" for 10%.\nNote: Only values between "0" and "50" are allowed.'; then +Please enter the desired percentage of reserved blocks, e.g. "0.05" for 0.05% or "10" for 10%.\nNote: Only values between "0" and "50" are allowed.' || break - if grep -qE '^[0-9]*\.?[0-9]*$' <<< "$G_WHIP_RETURNED_VALUE" && - [[ $G_WHIP_RETURNED_VALUE != '.' ]] && - (( $(bc -l <<< "$G_WHIP_RETURNED_VALUE <= 50") )); then + if [[ $G_WHIP_RETURNED_VALUE =~ ^[0-9]*\.?[0-9]*$ && $G_WHIP_RETURNED_VALUE != '.' && $(mawk '$1 <= 50' <<< $G_WHIP_RETURNED_VALUE) ]]; then - G_EXEC tune2fs -m "$G_WHIP_RETURNED_VALUE" "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" - break - - else - - G_WHIP_MSG 'Error: Allowed are only integers or floats between "0" and "50", e.g. "10" or "0.5".\n\nPlease try again...' - - fi + G_EXEC tune2fs -m "$G_WHIP_RETURNED_VALUE" "${aDRIVE_MOUNT_SOURCE[$MENU_DRIVE_INDEX]}" + break else - break + G_WHIP_MSG 'Error: Allowed are only integers or floats between "0" and "50", e.g. "10" or "0.5".\n\nPlease try again...' fi diff --git a/dietpi/dietpi-letsencrypt b/dietpi/dietpi-letsencrypt index 189a9df441..1905e4c935 100644 --- a/dietpi/dietpi-letsencrypt +++ b/dietpi/dietpi-letsencrypt @@ -43,18 +43,18 @@ Run_Lets_Encrypt(){ - G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Running CertBot' + G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Running Certbot' local fp_cert_dir="/etc/letsencrypt/live/$LETSENCRYPT_DOMAIN" #------------------------------------------------------------------------------------------------------ # Apache2 - if pgrep '[a]pache' &> /dev/null; then + if pgrep '[a]pache' > /dev/null; then G_DIETPI-NOTIFY 0 'Apache2 webserver detected' local fp_defaultsite='/etc/apache2/sites-available/000-default.conf' - # Add ServerName if it doesnt exist. This is required to prevent CertBot complaining about vhost with no domain. + # Add ServerName if it doesnt exist. This is required to prevent Certbot complaining about vhost with no domain. G_CONFIG_INJECT 'ServerName[[:blank:]]' "ServerName $LETSENCRYPT_DOMAIN" "$fp_defaultsite" ' /dev/null; then + elif pgrep '[l]ighttpd' > /dev/null; then G_DIETPI-NOTIFY 0 'Lighttpd webserver detected' + # Lighttpd-only support for multiple domains + fp_cert_dir=${fp_cert_dir%%,*} # Cert me up if [[ -f $fp_cert_dir'/cert.pem' ]]; then @@ -105,8 +107,8 @@ fi if (( $exit_code )); then - echo "[FAILED] CertBot failed with error code ($exit_code), please check its terminal output. Aborting..." | tee $FP_LOGFILE - (( $INPUT )) || G_WHIP_MSG "[FAILURE] CertBot failed with error code ($exit_code), please check its terminal output. Aborting..." + echo "[FAILED] Certbot failed with error code ($exit_code), please check its terminal output. Aborting..." | tee $FP_LOGFILE + (( $INPUT )) || G_WHIP_MSG "[FAILURE] Certbot failed with error code ($exit_code), please check its terminal output. Aborting..." return 1 fi @@ -115,8 +117,8 @@ cat "$fp_cert_dir/privkey.pem" "$fp_cert_dir/cert.pem" > "$fp_cert_dir/combined.pem" if [[ ! -f $fp_cert_dir'/combined.pem' ]]; then - echo "[FAILED] $fp_cert_dir/combined.pem could not be created. Please check existence of privkey.pem and cert.pem within this folder, as result of CertBot execution. Aborting..." | tee $FP_LOGFILE - (( $INPUT )) || G_WHIP_MSG "[FAILED] $fp_cert_dir/combined.pem could not be created. Please check existence of privkey.pem and cert.pem within this folder, as result of CertBot execution. Aborting..." + echo "[FAILED] $fp_cert_dir/combined.pem could not be created. Please check existence of privkey.pem and cert.pem within this folder, as result of Certbot execution. Aborting..." | tee $FP_LOGFILE + (( $INPUT )) || G_WHIP_MSG "[FAILED] $fp_cert_dir/combined.pem could not be created. Please check existence of privkey.pem and cert.pem within this folder, as result of Certbot execution. Aborting..." return 1 fi @@ -131,74 +133,77 @@ _EOF_ # Allow adding environment variables via: setenv.add-environment G_CONFIG_INJECT '"mod_setenv"' ' "mod_setenv",' /etc/lighttpd/lighttpd.conf '"mod_.+",' - cat << _EOF_ > /etc/lighttpd/conf-enabled/letsencrypt.conf -# Based on: https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=lighttpd-1.4.35&openssl=1.0.1t&hsts=yes&profile=intermediate + cat << _EOF_ > /etc/lighttpd/conf-available/50-dietpi-https.conf +# Based on: https://ssl-config.mozilla.org/#server=lighttpd&version=1.4.45&config=intermediate&openssl=1.1.0l&guideline=5.6 \$SERVER["socket"] == ":443" { - protocol = "https://" + protocol = "https://" ssl.engine = "enable" ssl.disable-client-renegotiation = "enable" # pemfile is cert+privkey, ca-file is the intermediate chain in one file - ssl.pemfile = "$fp_cert_dir/combined.pem" - ssl.ca-file = "$fp_cert_dir/fullchain.pem" + ssl.pemfile = "$fp_cert_dir/combined.pem" + ssl.ca-file = "$fp_cert_dir/fullchain.pem" - # for DH/DHE ciphers, dhparam should be >= 2048-bit - #ssl.dh-file = "/path/to/dhparam.pem" - # ECDH/ECDHE ciphers curve strength (see 'openssl ecparam -list_curves') - ssl.ec-curve = "secp384r1" - # Compression is by default off at compile-time, but use if needed - #ssl.use-compression = "disable" + # For DH/DHE ciphers, dhparam should be >= 2048-bit + #ssl.dh-file = "/path/to/dhparam.pem" + # ECDH/ECDHE ciphers curve strength, see "openssl ecparam -list_curves" + ssl.ec-curve = "secp384r1" # Environment flag for HTTPS enabled setenv.add-environment = ( "HTTPS" => "on" ) - # intermediate configuration, tweak to your needs + # Intermediate configuration, tweak to your needs ssl.use-sslv2 = "disable" ssl.use-sslv3 = "disable" - ssl.honor-cipher-order = "enable" - ssl.cipher-list = "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS" + ssl.cipher-list = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384" + ssl.honor-cipher-order = "disable" } _EOF_ - # Enable new "mod_openssl" on Buster - (( $G_DISTRO > 4 )) && sed -i '1i\server.modules += ( "mod_openssl" )\n' /etc/lighttpd/conf-enabled/letsencrypt.conf + (( $G_DISTRO > 4 )) && sed -i '1i\server.modules += ( "mod_openssl" )\n' /etc/lighttpd/conf-available/50-dietpi-https.conf + lighty-enable-mod dietpi-https # Redirect - [[ -f '/etc/lighttpd/conf-enabled/redirect.conf' ]] && rm /etc/lighttpd/conf-enabled/redirect.conf if (( $LETSENCRYPT_REDIRECT )); then - cat << _EOF_ > /etc/lighttpd/conf-enabled/redirect.conf + cat << _EOF_ > /etc/lighttpd/conf-available/98-dietpi-https_redirect.conf \$HTTP["scheme"] == "http" { - # capture vhost name with regex conditiona -> %0 in redirect pattern - # must be the most inner block to the redirect rule + # Capture vhost name with regex conditional %0 in redirect pattern + # Must be the most inner block to the redirect rule \$HTTP["host"] =~ ".*" { url.redirect = (".*" => "https://%0\$0") } } _EOF_ + lighty-enable-mod dietpi-https_redirect + + elif [[ -f '/etc/lighttpd/conf-available/98-dietpi-https_redirect.conf' ]]; then + + lighty-disable-mod dietpi-https_redirect + rm /etc/lighttpd/conf-available/98-dietpi-https_redirect.conf fi # HSTS if (( $LETSENCRYPT_HSTS )); then - cat << _EOF_ > /etc/lighttpd/conf-available/99-dietpi-hsts.conf + cat << _EOF_ > /etc/lighttpd/conf-available/98-dietpi-hsts.conf \$HTTP["scheme"] == "https" { setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=31536000; includeSubdomains;" ) } _EOF_ - lighttpd-enable-mod dietpi-hsts + lighty-enable-mod dietpi-hsts - elif [[ -f '/etc/lighttpd/conf-available/99-dietpi-hsts.conf' ]]; then + elif [[ -f '/etc/lighttpd/conf-available/98-dietpi-hsts.conf' ]]; then - lighttpd-disable-mod dietpi-hsts - rm /etc/lighttpd/conf-available/99-dietpi-hsts.conf + lighty-disable-mod dietpi-hsts + rm /etc/lighttpd/conf-available/98-dietpi-hsts.conf fi #------------------------------------------------------------------------------------------------------ # Nginx - elif pgrep '[n]ginx' &> /dev/null; then + elif pgrep '[n]ginx' > /dev/null; then G_DIETPI-NOTIFY 0 'Nginx webserver detected' local fp_defaultsite='/etc/nginx/sites-available/default' @@ -227,8 +232,8 @@ _EOF_ fi if (( $exit_code )); then - echo "[FAILURE] CertBot failed with error code ($exit_code), please check its terminal output. Aborting..." | tee $FP_LOGFILE - (( $INPUT )) || G_WHIP_MSG "[FAILURE] CertBot failed with error code ($exit_code), please check its terminal output. Aborting..." + echo "[FAILURE] Certbot failed with error code ($exit_code), please check its terminal output. Aborting..." | tee $FP_LOGFILE + (( $INPUT )) || G_WHIP_MSG "[FAILURE] Certbot failed with error code ($exit_code), please check its terminal output. Aborting..." return 1 fi @@ -243,7 +248,7 @@ _EOF_ #------------------------------------------------------------------------------------------------------ # Minio - elif pgrep '[m]inio' &> /dev/null; then + elif pgrep '[m]inio' > /dev/null; then G_DIETPI-NOTIFY 0 'Minio S3 server detected' @@ -262,8 +267,8 @@ _EOF_ fi if (( $exit_code )); then - echo "[FAILURE] CertBot failed with error code ($exit_code), please check its terminal output. Aborting..." | tee $FP_LOGFILE - (( $INPUT )) || G_WHIP_MSG "[FAILURE] CertBot failed with error code ($exit_code), please check its terminal output. Aborting..." + echo "[FAILURE] Certbot failed with error code ($exit_code), please check its terminal output. Aborting..." | tee $FP_LOGFILE + (( $INPUT )) || G_WHIP_MSG "[FAILURE] Certbot failed with error code ($exit_code), please check its terminal output. Aborting..." return 1 fi @@ -378,7 +383,7 @@ _EOF_ # MENUS #///////////////////////////////////////////////////////////////////////////////////// TARGETMENUID=0 - PREVIOUS_MENU_SELECTION= + PREVIOUS_MENU_SELECTION='Domain' Menu_Exit(){ @@ -389,8 +394,7 @@ _EOF_ Input_Box(){ - local input_value=$1 - local input_desc=$2 + local input_value=$1 input_desc=$2 G_WHIP_DEFAULT_ITEM=$input_value G_WHIP_INPUTBOX "Please enter a value for $input_desc" || return 1 @@ -415,7 +419,7 @@ _EOF_ 'Redirect' ": $redirect_text" 'HSTS' ": $hsts_text" 'Key Size' ": [$LETSENCRYPT_KEYSIZE bits]" - 'Apply' ': Runs CertBot with your chosen options' + 'Apply' ': Runs Certbot with your chosen options' ) @@ -429,8 +433,7 @@ _EOF_ 'Domain') - local new=$LETSENCRYPT_DOMAIN - local error= + local new=$LETSENCRYPT_DOMAIN error= while new=$(Input_Box "$new" "Website-Domain$error") do @@ -495,7 +498,7 @@ Enabling HSTS will prevent access to applications which use a standalone webserv 'Apply') - if G_WHIP_YESNO 'CertBot will now run, which will: + if G_WHIP_YESNO 'Certbot will now run, which will: - Create your free SSL certificate - Automatically apply your SSL certificate to the webserver - Enable HTTPS for all web applications which use "/var/www/" @@ -524,7 +527,7 @@ Enabling HSTS will prevent access to applications which use a standalone webserv #///////////////////////////////////////////////////////////////////////////////////// # Main Loop #///////////////////////////////////////////////////////////////////////////////////// - # Load Settings file. Generate if required. + # Load settings file. Generate if required. if [[ -f $FP_SETTINGS ]]; then Read_Settings_File @@ -537,18 +540,18 @@ Enabling HSTS will prevent access to applications which use a standalone webserv #----------------------------------------------------------------------------------- # Check installed - until command -v certbot &> /dev/null + until command -v certbot > /dev/null do # Menu - if (( ! $INPUT )) && G_WHIP_YESNO '[WARNING] No CertBot binary found\n -Would you like to install CertBot now via "dietpi-software"?'; then + if (( ! $INPUT )) && G_WHIP_YESNO '[WARNING] No Certbot binary found\n +Would you like to install Certbot now via "dietpi-software"?'; then /boot/dietpi/dietpi-software install 92 else - echo '[FAILURE] No CertBot binary found, please install it with "dietpi-software". Aborting...' | tee $FP_LOGFILE + echo '[FAILURE] No Certbot binary found, please install it with "dietpi-software". Aborting...' | tee $FP_LOGFILE exit 1 fi @@ -559,7 +562,8 @@ Would you like to install CertBot now via "dietpi-software"?'; then # Menu if (( ! $INPUT )); then - while (( $TARGETMENUID > -1 )); do + until (( $TARGETMENUID < 0 )) + do G_TERM_CLEAR Menu_Main diff --git a/dietpi/dietpi-login b/dietpi/dietpi-login index 9e71a57c1d..21ff862351 100644 --- a/dietpi/dietpi-login +++ b/dietpi/dietpi-login @@ -18,6 +18,7 @@ #///////////////////////////////////////////////////////////////////////////////////// FP_DIETPI_FIRSTRUNSETUP_LOG='/var/tmp/dietpi/logs/dietpi-firstrun-setup.log' FP_DIETPI_FIRSTRUNSETUP_PID='/tmp/.dietpi-login_firstrun_setup.pid' # Must be on RAM, in case of reboot from dietpi-software etc, to reset file before this script can remove it. + FP_DIETPI_FIRSTRUNSETUP_ERR='/tmp/.dietpi-login_firstrun_setup_err' # Error flag to allow a second instance kill and repeat firstrun setup Show_License(){ @@ -107,18 +108,33 @@ export G_INTERACTIVE=1 G_CONFIG_INJECT 'AUTO_SETUP_AUTOMATED=' 'AUTO_SETUP_AUTOMATED=0' /boot/dietpi.txt + local pid_loginerror=$$ + [[ -f $FP_DIETPI_FIRSTRUNSETUP_ERR ]] && pid_loginerror=$(<$FP_DIETPI_FIRSTRUNSETUP_ERR) + if [[ $pid_loginerror != $$ ]]; then + + G_WHIP_BUTTON_OK_TEXT='Take over' G_WHIP_BUTTON_CANCEL_TEXT='Retry' + G_WHIP_DEFAULT_ITEM='yes' G_WHIP_YESNO "[FAILED] Unknown install state/First run setup failed on another screen (PID=$pid_loginerror). +\nYou can the error handling on this screen and kill the other DietPi-Login session. +\nElse you can finish the error handling on the other DietPi-Login session and the login script on this session afterwards." || return + kill -9 $pid_loginerror + + fi + + echo $$ > $FP_DIETPI_FIRSTRUNSETUP_ERR if G_WHIP_DEFAULT_ITEM='yes' G_WHIP_YESNO "[FAILED] Unknown install state/First run setup failed\n An error has occured either during first run update or installs.\n First run setup will now attempt to re-apply the last step, forced as interactive run. If this repeatedly fails, please collect all terminal output and the content of $FP_DIETPI_FIRSTRUNSETUP_LOG if available and report this issue to: https://github.com/MichaIng/DietPi/issues\n Would you like to restart the first run setup and installation?"; then - # Reset and force re-run of first run + # Reset and force re-run of first run setup + rm $FP_DIETPI_FIRSTRUNSETUP_ERR killall -qw dietpi-software dietpi-update echo 0 > /boot/dietpi/.install_stage else + rm $FP_DIETPI_FIRSTRUNSETUP_ERR exit 1 fi @@ -132,15 +148,20 @@ Would you like to restart the first run setup and installation?"; then grep -q '^[[:blank:]]*AUTO_SETUP_AUTOMATED=1' /boot/dietpi.txt && export G_INTERACTIVE=0 # Prompt and wait if this script runs in other session already - local pid_firstrunsetup + local pid_firstrunsetup=$$ [[ -f $FP_DIETPI_FIRSTRUNSETUP_PID ]] && pid_firstrunsetup=$(<$FP_DIETPI_FIRSTRUNSETUP_PID) - if [[ $pid_firstrunsetup && $pid_firstrunsetup != $$ ]]; then - # First run setup running in other session + # Unknown install state/First run setup failed in other session, forcing interactive whiptail prompt. Allow to take over and repeat on this session. + if [[ -f $FP_DIETPI_FIRSTRUNSETUP_ERR ]]; then + + Prompt_on_Failure + + elif [[ $pid_firstrunsetup != $$ ]]; then + local additional_text='Please resume setup on the active screen.' [[ $G_INTERACTIVE == 0 ]] && additional_text='Automated setup is in progress. When completed, the system will be rebooted.' - G_WHIP_MSG "[INFO] DietPi first run setup: Currently running on another screen (PID=$pid_firstrunsetup).\n\n$additional_text" + G_WHIP_MSG "[ INFO ] DietPi first run setup is currently running on another screen (PID=$pid_firstrunsetup).\n\n$additional_text" local restart_loop_delay=5 G_DIETPI-NOTIFY 2 "Waiting $restart_loop_delay seconds before checking again. Please wait... (Press CTRL+C to abort)" @@ -148,9 +169,9 @@ Would you like to restart the first run setup and installation?"; then elif (( $UID )); then - G_WHIP_MSG '[ERROR] Root login required\n + G_WHIP_MSG '[FAILED] Root login required\n To finish DietPi first run setup, root permissions are required.\n -Please login again as user "root" with password "dietpi", respectively the one you chose in "dietpi.txt".' +Please login again as user "root" with password "dietpi", respectively the one you chose via "dietpi.txt".' exit 1 diff --git a/dietpi/dietpi-services b/dietpi/dietpi-services index 6052d334e8..27bcd5352d 100644 --- a/dietpi/dietpi-services +++ b/dietpi/dietpi-services @@ -73,9 +73,6 @@ Available services: 'mariadb' # - PHP - 'php5-fpm' - 'php7.0-fpm' - 'php7.1-fpm' 'php7.2-fpm' 'php7.3-fpm' 'php7.4-fpm' @@ -125,6 +122,8 @@ Available services: 'emby-server' 'spotify-connect-web' 'ubooquity' + 'komga' + 'jellyfin' # - Download/BitTorrent 'medusa' @@ -390,7 +389,7 @@ _EOF_ fi # Enable ownCloud and Nextcloud maintenance mode before all services being stopped or restarted - if [[ $command == 'stop' || $command == 'restart' && ! $index ]]; then + if [[ $command == 'stop' || $command == 'restart' ]] && [[ ! $index ]]; then [[ -f '/var/www/owncloud/config/config.php' ]] && grep -q "'maintenance' => false," /var/www/owncloud/config/config.php && G_EXEC_NOHALT=1 G_EXEC occ maintenance:mode --on [[ -f '/var/www/nextcloud/config/config.php' ]] && grep -q "'maintenance' => false," /var/www/nextcloud/config/config.php && G_EXEC_NOHALT=1 G_EXEC ncc maintenance:mode --on @@ -409,7 +408,7 @@ _EOF_ done # Disable ownCloud and Nextcloud maintenance mode after all services being started or restarted - if [[ $command == 'start' || $command == 'restart' && ! $index ]]; then + if [[ $command == 'start' || $command == 'restart' ]] && [[ ! $index ]]; then [[ -f '/var/www/owncloud/config/config.php' ]] && grep -q "'maintenance' => true," /var/www/owncloud/config/config.php && G_EXEC_NOHALT=1 G_EXEC occ maintenance:mode --off [[ -f '/var/www/nextcloud/config/config.php' ]] && grep -q "'maintenance' => true," /var/www/nextcloud/config/config.php && G_EXEC_NOHALT=1 G_EXEC ncc maintenance:mode --off @@ -444,12 +443,12 @@ _EOF_ # 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")" - if [[ $status =~ 'failed' ]]; then + status="${aSERVICE_NAME[$i]}${space}$(mawk '/Active/{print substr($0,12);exit}' <<< "$status_full")" + if [[ $status == *'failed'* ]]; then G_DIETPI-NOTIFY 1 "$status_full" - elif [[ $status =~ 'inactive' ]]; then + elif [[ $status == *'inactive'* ]]; then G_DIETPI-NOTIFY 2 "$status" @@ -650,8 +649,8 @@ _EOF_ done - if [[ $service_restart_list_systemd ]] && - G_WHIP_YESNO "[ INFO ] The following services require a restart, in order to apply your chosen settings:${service_restart_list_menu%[|:] }\n\nDo you wish to restart the above services now?"; then + if [[ $service_restart_list_systemd ]] && G_WHIP_YESNO "[ INFO ] The following services require a restart, in order to apply your chosen settings:${service_restart_list_menu%[|:] } +\nDo you wish to restart the above services now?"; then G_EXEC systemctl restart $service_restart_list_systemd @@ -957,6 +956,7 @@ Please uncomment and edit only the lines that you need to change.\n\nTo undo cha fi nano "$fp" SYSTEMD_RELOAD_REQUIRED=1 + aSERVICE_RESTART_REQUIRED[$MENU_SERVICE_INDEX]=1 ;; @@ -1066,20 +1066,19 @@ Info:\n - Negative values have a higher priority (eg: -10).\n - Positive values 'CPU Scheduling Priority') # 7 step description scale - local scale_value_lowest=1 local scale_value_highest=99 - local scale_value_lower=$(( $scale_value_highest / 6 )) - local scale_value_low=$(( $scale_value_highest / 6 * 2 )) - local scale_value_medium=$(( $scale_value_highest / 6 * 3 )) - local scale_value_high=$(( $scale_value_highest / 6 * 4 )) - local scale_value_higher=$(( $scale_value_highest / 6 * 5 )) + local scale_value_higher=$(( $scale_value_highest * 5/6 )) + local scale_value_high=$(( $scale_value_highest * 2/3 )) + local scale_value_medium=$(( $scale_value_highest * 1/2 )) + local scale_value_low=$(( $scale_value_highest * 1/3 )) + local scale_value_lower=$(( $scale_value_highest * 1/6 )) + local scale_value_lowest=1 local desc G_WHIP_MENU_ARRAY=('Reset' ': Reset CPU Scheduling Priority to system defaults') for ((i=$scale_value_highest; i>=$scale_value_lowest; i--)) do - desc= if (( $i == $scale_value_lowest )); then desc='(Lowest priority)' @@ -1108,6 +1107,10 @@ Info:\n - Negative values have a higher priority (eg: -10).\n - Positive values desc='(Highest priority)' + else + + desc= + fi G_WHIP_MENU_ARRAY+=($i ": $desc") @@ -1250,7 +1253,7 @@ NB: This only has an effect on drives handled by the CFQ scheduler."; then Load_Process_Tool_Arrays - while (( $MENU_TARGETID > -1 )) + until (( $MENU_TARGETID < 0 )) do if (( $MENU_TARGETID == 1 )); then diff --git a/dietpi/dietpi-software b/dietpi/dietpi-software index 3ddb48a1d5..c2a21dde7e 100644 --- a/dietpi/dietpi-software +++ b/dietpi/dietpi-software @@ -59,7 +59,7 @@ > $fp_target # Save installed states - for i in ${!aSOFTWARE_NAME[@]} + for i in "${!aSOFTWARE_NAME[@]}" do # Never save pending state for software (=1). Excluding temp saves. @@ -225,7 +225,7 @@ DietPi-Software will decrypt and use it for software installs. You can change it if (( $G_DISTRO > 5 )); then PHP_NAME='php7.4' - FP_PHP_BASE_DIR='/etc/php/7.4' + FP_PHP_BASE_DIR='/etc/php/7.4' fi @@ -353,8 +353,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='MATE' aSOFTWARE_DESC[$software_id]='desktop enviroment' - aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_REQUIRES_ALSA[$software_id]=1 aSOFTWARE_REQUIRES_XSERVERXORG[$software_id]=1 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=2073#p2073' @@ -478,7 +478,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it # - Odroid C1: No HDMI with current kernel aSOFTWARE_AVAIL_G_HW_MODEL[$software_id,10]=0 # - Odroid N1/C2: No support for arm64 on Debian Buster currently, disable if not found in repo: http://fuzon.co.uk/meveric/pool/main/k/kodi-odroid/ - [[ $G_HW_MODEL == 1[24] ]] && ! apt-cache show kodi-odroid &> /dev/null && aSOFTWARE_AVAIL_G_HW_MODEL[$software_id,$G_HW_MODEL]=0 + # - Odroid N2/C4: Amlogic SoCs are supported via fbdev build: http://fuzon.co.uk/meveric/pool/main/k/kodi-aml-fbdev-odroid/ + [[ $G_HW_MODEL == 1[24] ]] && ! apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* kodi-odroid(,|$)' && aSOFTWARE_AVAIL_G_HW_MODEL[$software_id,$G_HW_MODEL]=0 #------------------ software_id=32 @@ -515,12 +516,9 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_TYPE[$software_id]=0 aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=11280#p11280' - aSOFTWARE_REQUIRES_ALSA[$software_id]=1 aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 + aSOFTWARE_REQUIRES_ALSA[$software_id]=1 aSOFTWARE_REQUIRES_FFMPEG[$software_id]=1 - # - Buster: https://github.com/MichaIng/DietPi/issues/2787 - aSOFTWARE_AVAIL_G_DISTRO[$software_id,5]=0 - aSOFTWARE_AVAIL_G_DISTRO[$software_id,6]=0 #------------------ software_id=34 @@ -528,10 +526,10 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_DESC[$software_id]='web interface media streaming server' aSOFTWARE_TYPE[$software_id]=0 aSOFTWARE_CATEGORY_INDEX[$software_id]=2 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=213#p213' + aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 aSOFTWARE_REQUIRES_ALSA[$software_id]=1 aSOFTWARE_REQUIRES_FFMPEG[$software_id]=1 - aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 - aSOFTWARE_ONLINEDOC_URL[$software_id]='p=213#p213' # - Buster: https://github.com/MichaIng/DietPi/issues/2787 aSOFTWARE_AVAIL_G_DISTRO[$software_id,5]=0 aSOFTWARE_AVAIL_G_DISTRO[$software_id,6]=0 @@ -598,8 +596,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Plex Media Server' aSOFTWARE_DESC[$software_id]='web interface media streaming server' - aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=1949#p1949' # - ARMv6: https://github.com/MichaIng/DietPi/issues/648 aSOFTWARE_AVAIL_G_HW_ARCH[$software_id,1]=0 @@ -608,8 +606,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Murmur' aSOFTWARE_DESC[$software_id]='mumble voip server' - aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=1691#p1691' #------------------ software_id=118 @@ -709,8 +707,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Tautulli' aSOFTWARE_DESC[$software_id]='monitoring and tracking tool for Plex' - aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=7463#p7463' aSOFTWARE_REQUIRES_GIT[$software_id]=1 #------------------ @@ -718,8 +716,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Roon Server' aSOFTWARE_DESC[$software_id]='Roon capable audio player and core' - aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=2 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=7966#p7966' aSOFTWARE_REQUIRES_ALSA[$software_id]=1 aSOFTWARE_REQUIRES_FFMPEG[$software_id]=1 @@ -767,8 +765,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_DESC[$software_id]='spotify connect client' aSOFTWARE_TYPE[$software_id]=0 aSOFTWARE_CATEGORY_INDEX[$software_id]=2 - aSOFTWARE_REQUIRES_ALSA[$software_id]=1 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=9368#p9368' + aSOFTWARE_REQUIRES_ALSA[$software_id]=1 # - ARMv8 aSOFTWARE_AVAIL_G_HW_ARCH[$software_id,3]=0 # - x86_64 @@ -777,11 +775,20 @@ DietPi-Software will decrypt and use it for software installs. You can change it software_id=80 aSOFTWARE_NAME[$software_id]='Ubooquity' - aSOFTWARE_DESC[$software_id]='a free home server for your comics and ebooks library' + aSOFTWARE_DESC[$software_id]='free home server for your comics and ebooks library' aSOFTWARE_TYPE[$software_id]=0 aSOFTWARE_CATEGORY_INDEX[$software_id]=2 - aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=12969#p12969' + aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 + #------------------ + software_id=179 + + aSOFTWARE_NAME[$software_id]='Komga' + aSOFTWARE_DESC[$software_id]='Free and open source comics/mangas media server with web UI' + aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=2 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=26858#p26858' + aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 #------------------ software_id=86 @@ -789,9 +796,17 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_DESC[$software_id]='Manage extensions from within Roon' aSOFTWARE_TYPE[$software_id]=0 aSOFTWARE_CATEGORY_INDEX[$software_id]=2 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=13160#p13160' aSOFTWARE_REQUIRES_GIT[$software_id]=1 aSOFTWARE_REQUIRES_NODEJS[$software_id]=1 - aSOFTWARE_ONLINEDOC_URL[$software_id]='p=13160#p13160' + #------------------ + software_id=178 + + aSOFTWARE_NAME[$software_id]='Jellyfin' + aSOFTWARE_DESC[$software_id]='FOSS web interface media streaming server' + aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=2 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=26255#p26255' # BitTorrent #-------------------------------------------------------------------------------- @@ -867,6 +882,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_ONLINEDOC_URL[$software_id]='p=7212#p7212' aSOFTWARE_REQUIRES_BUILDESSENTIAL[$software_id]=1 aSOFTWARE_REQUIRES_GIT[$software_id]=1 + # Python2 only, hence not supported on Bullseye + aSOFTWARE_AVAIL_G_DISTRO[$software_id,6]=0 #------------------ software_id=144 @@ -915,10 +932,11 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='HTPC Manager' aSOFTWARE_DESC[$software_id]='manage your HTPC from anywhere' - aSOFTWARE_REQUIRES_GIT[$software_id]=1 - aSOFTWARE_CATEGORY_INDEX[$software_id]=3 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=3 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=8043#p8043' + aSOFTWARE_REQUIRES_BUILDESSENTIAL[$software_id]=1 + aSOFTWARE_REQUIRES_GIT[$software_id]=1 # Cloud / Backups #-------------------------------------------------------------------------------- @@ -1072,11 +1090,11 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='OpenTyrian' aSOFTWARE_DESC[$software_id]='a classic retro game, addictive' - aSOFTWARE_CATEGORY_INDEX[$software_id]=5 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=5 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=45#p45' aSOFTWARE_REQUIRES_ALSA[$software_id]=1 aSOFTWARE_REQUIRES_XSERVERXORG[$software_id]=1 - aSOFTWARE_ONLINEDOC_URL[$software_id]='p=45#p45' # RPi only for ((i=10; i<=$MAX_G_HW_MODEL; i++)) do @@ -1091,10 +1109,10 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='DXX-Rebirth' aSOFTWARE_DESC[$software_id]='Descent 1/2' - aSOFTWARE_CATEGORY_INDEX[$software_id]=5 aSOFTWARE_TYPE[$software_id]=0 - aSOFTWARE_REQUIRES_ALSA[$software_id]=1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=5 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=2963#p2963' + aSOFTWARE_REQUIRES_ALSA[$software_id]=1 # RPi only for ((i=10; i<=$MAX_G_HW_MODEL; i++)) do @@ -1107,8 +1125,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Cuberite' aSOFTWARE_DESC[$software_id]='minecraft server with web interface (c++)' - aSOFTWARE_CATEGORY_INDEX[$software_id]=5 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=5 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=2068#p2068' # - ARMv8 aSOFTWARE_AVAIL_G_HW_ARCH[$software_id,3]=0 @@ -1117,13 +1135,13 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='MineOS' aSOFTWARE_DESC[$software_id]='minecraft servers with web interface (java)' - aSOFTWARE_CATEGORY_INDEX[$software_id]=5 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=5 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=2069#p2069' aSOFTWARE_REQUIRES_BUILDESSENTIAL[$software_id]=1 aSOFTWARE_REQUIRES_GIT[$software_id]=1 aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 aSOFTWARE_REQUIRES_NODEJS[$software_id]=1 - aSOFTWARE_ONLINEDOC_URL[$software_id]='p=2069#p2069' #------------------ software_id=156 @@ -1148,10 +1166,10 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Nukkit' aSOFTWARE_DESC[$software_id]='A nuclear-powered server for Minecraft Pocket Edition' - aSOFTWARE_CATEGORY_INDEX[$software_id]=5 aSOFTWARE_TYPE[$software_id]=0 - aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=5 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=10675#p10675' + aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$software_id]=1 # Social Media #-------------------------------------------------------------------------------- @@ -1170,12 +1188,12 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Wordpress' aSOFTWARE_DESC[$software_id]='website blog and publishing platform' - aSOFTWARE_CATEGORY_INDEX[$software_id]=6 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=6 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=395#p395' aSOFTWARE_REQUIRES_WEBSERVER[$software_id]=1 aSOFTWARE_REQUIRES_PHP[$software_id]=1 aSOFTWARE_REQUIRES_MYSQL[$software_id]=1 - aSOFTWARE_ONLINEDOC_URL[$software_id]='p=395#p395' #------------------ software_id=38 @@ -1202,23 +1220,23 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='BaiKal' aSOFTWARE_DESC[$software_id]='lightweight caldav + carddav server' - aSOFTWARE_CATEGORY_INDEX[$software_id]=6 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=6 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=1502#p1502' aSOFTWARE_REQUIRES_WEBSERVER[$software_id]=1 aSOFTWARE_REQUIRES_PHP[$software_id]=1 aSOFTWARE_REQUIRES_MYSQL[$software_id]=1 - aSOFTWARE_ONLINEDOC_URL[$software_id]='p=1502#p1502' #------------------ software_id=58 aSOFTWARE_NAME[$software_id]='OpenBazaar' aSOFTWARE_DESC[$software_id]='decentralised peer to peer bitcoin market' - aSOFTWARE_CATEGORY_INDEX[$software_id]=6 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=6 + aSOFTWARE_ONLINEDOC_URL[$software_id]='p=1796#p1796' aSOFTWARE_REQUIRES_BUILDESSENTIAL[$software_id]=1 aSOFTWARE_REQUIRES_GIT[$software_id]=1 aSOFTWARE_REQUIRES_USERINPUT[$software_id]=1 - aSOFTWARE_ONLINEDOC_URL[$software_id]='p=1796#p1796' #------------------ software_id=133 @@ -1272,6 +1290,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_ONLINEDOC_URL[$software_id]='p=6610#p6610' aSOFTWARE_REQUIRES_FFMPEG[$software_id]=1 aSOFTWARE_REQUIRES_BUILDESSENTIAL[$software_id]=1 + # Python2 only, hence not supported on Bullseye + aSOFTWARE_AVAIL_G_DISTRO[$software_id,6]=0 # WiFi Hotspot #-------------------------------------------------------------------------------- @@ -1385,8 +1405,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='VirtualHere' aSOFTWARE_DESC[$software_id]='server: share USB devices over the network' - aSOFTWARE_CATEGORY_INDEX[$software_id]=10 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=10 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=6709#p6709' # Hardware projects @@ -1517,8 +1537,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Google AIY' aSOFTWARE_DESC[$software_id]='voice kit' - aSOFTWARE_CATEGORY_INDEX[$software_id]=11 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=11 aSOFTWARE_REQUIRES_ALSA[$software_id]=1 aSOFTWARE_REQUIRES_GIT[$software_id]=1 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=9486#p9486' @@ -1750,8 +1770,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='NFS Server' aSOFTWARE_DESC[$software_id]='network file system server' - aSOFTWARE_CATEGORY_INDEX[$software_id]=15 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=15 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=2821#p2821' #------------------ @@ -1761,8 +1781,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='OpenVPN' aSOFTWARE_DESC[$software_id]='vpn server' - aSOFTWARE_CATEGORY_INDEX[$software_id]=16 aSOFTWARE_TYPE[$software_id]=0 + aSOFTWARE_CATEGORY_INDEX[$software_id]=16 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=613#p613' #------------------ software_id=172 @@ -1839,6 +1859,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_AVAIL_G_HW_MODEL[$software_id,$i]=0 done + # Python2 only, hence not supported on Bullseye + aSOFTWARE_AVAIL_G_DISTRO[$software_id,6]=0 #------------------ software_id=157 @@ -1875,7 +1897,6 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_TYPE[$software_id]=0 aSOFTWARE_CATEGORY_INDEX[$software_id]=19 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=6630#p6630' - aSOFTWARE_REQUIRES_RSYSLOG[$software_id]=1 # Not required, but comes in as package dep #------------------ software_id=153 @@ -1896,9 +1917,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it software_id=0 aSOFTWARE_NAME[$software_id]='OpenSSH Client' - #aSOFTWARE_DESC[$software_id] - aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_TYPE[$software_id]=1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=0 # File server clients #-------------------------------------------------------------------------------- @@ -1992,10 +2012,10 @@ DietPi-Software will decrypt and use it for software installs. You can change it #------------------ software_id=130 - aSOFTWARE_NAME[$software_id]='Python Pip' - aSOFTWARE_DESC[$software_id]='python pip package installer' - aSOFTWARE_CATEGORY_INDEX[$software_id]=4 + aSOFTWARE_NAME[$software_id]='Python3 pip' + aSOFTWARE_DESC[$software_id]='Python3 package installer' aSOFTWARE_TYPE[$software_id]=1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=4 #------------------ software_id=150 @@ -2138,26 +2158,26 @@ DietPi-Software will decrypt and use it for software installs. You can change it #-------------------------------------------------------------------------------- software_id=101 - aSOFTWARE_NAME[$software_id]='Log Rotate' + aSOFTWARE_NAME[$software_id]='Logrotate' aSOFTWARE_DESC[$software_id]='rotates log files' - aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_TYPE[$software_id]=-1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=68#p68' #------------------ software_id=102 aSOFTWARE_NAME[$software_id]='Rsyslog' aSOFTWARE_DESC[$software_id]='system logging' - aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_TYPE[$software_id]=-1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=68#p68' #------------------ software_id=103 aSOFTWARE_NAME[$software_id]='DietPi-RAMlog' aSOFTWARE_DESC[$software_id]='minimal, optimised logging' - aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_TYPE[$software_id]=-1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=68#p68' #-------------------------------------------------------------------------------- @@ -2167,21 +2187,21 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_NAME[$software_id]='Dropbear' aSOFTWARE_DESC[$software_id]='lightweight ssh server' - aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_TYPE[$software_id]=-1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=62#p62' #------------------ software_id=105 aSOFTWARE_NAME[$software_id]='OpenSSH Server' aSOFTWARE_DESC[$software_id]='feature rich ssh server' - aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_TYPE[$software_id]=-1 + aSOFTWARE_CATEGORY_INDEX[$software_id]=0 aSOFTWARE_ONLINEDOC_URL[$software_id]='p=63#p63' #-------------------------------------------------------------------------------- # Init install state for defined software - for i in ${!aSOFTWARE_NAME[@]} + for i in "${!aSOFTWARE_NAME[@]}" do aSOFTWARE_INSTALL_STATE[$i]=0 @@ -2301,7 +2321,7 @@ DietPi-Software will decrypt and use it for software installs. You can change it aSOFTWARE_INSTALL_STATE[69]=1 # RPi.GPIO G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[69]} will be installed" - #aSOFTWARE_INSTALL_STATE[130]=1 # python-pip, enabled in "Software that requires Python-Pip" + #aSOFTWARE_INSTALL_STATE[130]=1 # Python3 pip, enabled in "Software that requires Python3 pip" fi @@ -2328,7 +2348,7 @@ DietPi-Software will decrypt and use it for software installs. You can change it WIFIHOTSPOT_RTL8188C_DEVICE=1 # Some repos (e.g. ARMbian) provide special packages - apt-cache show hostapd-realtek &> /dev/null && WIFIHOTSPOT_RTL8188C_PACKAGE=1 + apt-cache dumpavail | grep -qE '^P(ackage|rovides):.* hostapd-realtek(,|$)' && WIFIHOTSPOT_RTL8188C_PACKAGE=1 fi # - Domoticz (140): https://github.com/MichaIng/DietPi/issues/129#issuecomment-596255110 @@ -2357,17 +2377,16 @@ DietPi-Software will decrypt and use it for software installs. You can change it fi - # Software that requires Python-Pip: https://github.com/MichaIng/DietPi/issues/784 - # - Mopidy (118) - # - OctoPrint (153) + # Software that requires Python3 pip: https://github.com/MichaIng/DietPi/issues/784 + # - Mopidy (118) from Buster on + # - SABnzbd (139) + # - OctoPrint (153) from Buster on # - HTPC Manager (155) + # - Google AIY (169) software_id=130 - if (( ${aSOFTWARE_INSTALL_STATE[99]} == 1 || - ${aSOFTWARE_INSTALL_STATE[118]} == 1 || - ${aSOFTWARE_INSTALL_STATE[136]} == 1 || + if (( ( ${aSOFTWARE_INSTALL_STATE[118]} == 1 && $G_DISTRO > 4 ) || ${aSOFTWARE_INSTALL_STATE[139]} == 1 || - ${aSOFTWARE_INSTALL_STATE[142]} == 1 || - ${aSOFTWARE_INSTALL_STATE[153]} == 1 || + ( ${aSOFTWARE_INSTALL_STATE[153]} == 1 && $G_DISTRO > 4 ) || ${aSOFTWARE_INSTALL_STATE[155]} == 1 || ${aSOFTWARE_INSTALL_STATE[169]} == 1 )); then @@ -2377,9 +2396,9 @@ DietPi-Software will decrypt and use it for software installs. You can change it fi # Software that requires MPD - # - YMPD + # - ympd # - Cava - # - OMPD + # - O!MPD # - myMPD software_id=128 if (( ${aSOFTWARE_INSTALL_STATE[32]} == 1 || @@ -2407,7 +2426,7 @@ DietPi-Software will decrypt and use it for software installs. You can change it # Software that requires UnRAR # - rTorrent # - Medusa - # - SABnzbd + # - SABnzbd (139) software_id=170 if (( ${aSOFTWARE_INSTALL_STATE[107]} == 1 || ${aSOFTWARE_INSTALL_STATE[116]} == 1 || @@ -2557,7 +2576,7 @@ DietPi-Software will decrypt and use it for software installs. You can change it fi - software_id=17 # Git + software_id=17 # Git Client if (( ${aSOFTWARE_REQUIRES_GIT[$i]:=0} && aSOFTWARE_INSTALL_STATE[$software_id] != 1 )); then aSOFTWARE_INSTALL_STATE[$software_id]=1 @@ -2572,14 +2591,6 @@ DietPi-Software will decrypt and use it for software installs. You can change it fi - software_id=102 # Rsyslog - if (( ${aSOFTWARE_REQUIRES_RSYSLOG[$i]:=0} && aSOFTWARE_INSTALL_STATE[$software_id] != 1 )); then - - aSOFTWARE_INSTALL_STATE[$software_id]=1 - G_DIETPI-NOTIFY 2 "${aSOFTWARE_NAME[$software_id]} will be installed" - - fi - software_id=7 # FFmpeg if (( ${aSOFTWARE_REQUIRES_FFMPEG[$i]:=0} && aSOFTWARE_INSTALL_STATE[$software_id] != 1 )); then @@ -2654,10 +2665,10 @@ DietPi-Software will decrypt and use it for software installs. You can change it # Update PHP variables after all software titles have been marked # - Never install PHP7.2 if PHP7.3 or PHP7.4 is already present - if (( ${aSOFTWARE_INSTALL_STATE[89]} > 0 )) && ! command -v php7.3 &> /dev/null && ! command -v php7.4 &> /dev/null; then + if (( ${aSOFTWARE_INSTALL_STATE[89]} > 0 )) && ! command -v php7.3 > /dev/null && ! command -v php7.4 > /dev/null; then # Do not upgrade PHP7.2, since we can support it for a long time - if command -v php7.2 &> /dev/null; then + if command -v php7.2 > /dev/null; then PHP_NAME='php7.2' FP_PHP_BASE_DIR='/etc/php/7.2' @@ -2755,9 +2766,9 @@ DietPi-Software will decrypt and use it for software installs. You can change it Download_Test_Media(){ [[ -f $G_FP_DIETPI_USERDATA/$FOLDER_MUSIC/fourdee_tech.ogg ]] && return - wget https://dietpi.com/downloads/audio/fourdee_tech.ogg -O $G_FP_DIETPI_USERDATA/$FOLDER_MUSIC/fourdee_tech.ogg - chown dietpi:dietpi $G_FP_DIETPI_USERDATA/$FOLDER_MUSIC/fourdee_tech.ogg - chmod 664 $G_FP_DIETPI_USERDATA/$FOLDER_MUSIC/fourdee_tech.ogg + G_EXEC curl -sSfL https://dietpi.com/downloads/audio/fourdee_tech.ogg -o $G_FP_DIETPI_USERDATA/$FOLDER_MUSIC/fourdee_tech.ogg + G_EXEC chown dietpi:dietpi $G_FP_DIETPI_USERDATA/$FOLDER_MUSIC/fourdee_tech.ogg + G_EXEC chmod 664 $G_FP_DIETPI_USERDATA/$FOLDER_MUSIC/fourdee_tech.ogg } @@ -2844,7 +2855,7 @@ DietPi-Software will decrypt and use it for software installs. You can change it } # Usage: - # Download_Install 'https://file.com/file' /etc/install_here + # Download_Install 'https://file.com/file' [/path/to/target] # dps_index=$software_id Download_Install 'conf_0' /etc/conf.conf # Optional input variables: # fallback_url='http...' = URL to use if e.g. grabbing URL from api.github.com fails: https://dietpi.com/phpbb/viewtopic.php?p=17390#p17390 @@ -2856,8 +2867,8 @@ DietPi-Software will decrypt and use it for software installs. You can change it local url=$1 [[ ! $url && $fallback_url ]] && url=$fallback_url - local target=$2 # Extract target - local type=${url##*.} # Grab ext from URL | compatbile with >> deb|zip|tar(.gz|.bz2)|tgz|tbz2|7z + local target=$2 # Target path + local type=${url##*.} # Grab extension from URL to special handle deb|zip|tar(.gz|.bz2)|tgz|tbz2|7z [[ $type =~ ^t?(gz|bz2)$ ]] && type='tar' local file="$software_id.$type" @@ -2871,34 +2882,25 @@ DietPi-Software will decrypt and use it for software installs. You can change it (( $no_check_url )) || G_CHECK_URL "$url" - cd /tmp/$G_PROGRAM_NAME + cd /tmp/$G_PROGRAM_NAME # Failsafe # Download file if [[ $DEPS_LIST ]]; then # Download as background thread if dependencies are to be installed - G_THREAD_START wget "$url" -O $file + G_THREAD_START curl -sSfL "$url" -o $file G_AGI $DEPS_LIST DEPS_LIST= G_THREAD_WAIT else - G_EXEC wget "$url" -O $file + G_EXEC curl -sSfL "$url" -o $file fi # Process downloaded file - if [[ $type == dps_index ]]; then - - # Pre-create dir - local fp_dir=${target%/*} - [[ -d $fp_dir ]] || G_EXEC mkdir -p "$fp_dir" - - [[ -f $target ]] && G_DIETPI-NOTIFY 2 "Updating file: $target" - G_EXEC mv $file "$target" - - elif [[ $type == 'deb' ]]; then + if [[ $type == 'deb' ]]; then G_AGI ./$file @@ -2916,7 +2918,15 @@ DietPi-Software will decrypt and use it for software installs. You can change it else - G_DIETPI-NOTIFY 1 'Download_Install: Invalid file type, needs to be one of: deb|zip|tar(.gz|.bz2)|tgz|tbz2|7z' + # For all other types a target must be given to move/rename the download + G_EXEC_DESC="Verifying download target: ${target:-missing!}" G_EXEC eval "[[ $target ]]" + + # Pre-create target dir, if giveb + local fp_dir=${target%/*} + [[ ! $fp_dir || -d $fp_dir ]] || G_EXEC mkdir -p "$fp_dir" + + [[ -f $target ]] && G_DIETPI-NOTIFY 2 "Updating file: $target" + G_EXEC mv $file "$target" fi @@ -2977,6 +2987,9 @@ DietPi-Software will decrypt and use it for software installs. You can change it Banner_Installing G_AGI xfce4 xfce4-terminal gnome-icon-theme tango-icon-theme upower policykit-1 firefox-esr + # 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' ]] && rm /etc/xdg/autostart/xcompmgr.desktop + dpkg-query -s xcompmgr &> /dev/null && G_AGP xcompmgr # Safe to purge as it is no single dependant fi @@ -3075,7 +3088,7 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - G_AGI nfs-kernel-server rpcbind + G_AGI nfs-kernel-server fi @@ -3226,17 +3239,17 @@ Package: openssl libssl*\nPin: origin packages.sury.org\nPin-Priority: -1' > /et fi # Base PHP modules - # - Apache + # - Apache: mod_php if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then local package_list="libapache2-mod-$PHP_NAME" - # - Lighttpd or Nginx + # - Lighttpd and Nginx: PHP-FPM elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then local package_list="$PHP_NAME-fpm" - # - No webserver, /usr/bin/php cmd usage + # - No webserver: CLI usage only (php binary) else local package_list="$PHP_NAME-cli" @@ -3602,32 +3615,32 @@ _EOF_ # - 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 - local pip='pip' pip_modules='Mopidy-Local-Images' apt_packages= - - # ARMv8: Not supported by official repo, using Debian instead: https://github.com/mopidy/apt/tree/master/dists/buster/main - if (( $G_HW_ARCH == 3 )); then - - # Python3 since Bullseye, including Mopidy-Local-Images deprecation and dedicated mopidy-local APT package: https://packages.debian.org/mopidy - (( $G_DISTRO > 5 )) && pip+='3' pip_modules= apt_packages='mopidy-local' - - # Else use official repo - else + # 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 INSTALL_URL_ADDRESS='https://apt.mopidy.com/mopidy.gpg' G_CHECK_URL "$INSTALL_URL_ADDRESS" curl -sSfL "$INSTALL_URL_ADDRESS" | apt-key add - # No bullseye.list available yet, use buster.list instead: https://github.com/mopidy/apt/tree/master/dists - wget https://apt.mopidy.com/${G_DISTRO_NAME/bullseye/buster}.list -O /etc/apt/sources.list.d/mopidy.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 - # Python3 since Buster: https://raw.githubusercontent.com/mopidy/apt/master/dists/stretch/main/binary-armhf/Packages - (( $G_DISTRO > 4 )) && pip+='3' pip_modules= apt_packages='mopidy-local' - fi - G_AGI mopidy gstreamer1.0-alsa $apt_packages - $pip install Mopidy-MusicBox-Webclient $pip_modules - unset pip pip_modules apt_packages + # Stretch: Mopidy v2, pip2 and Mopidy-Local-Images + if (( $G_DISTRO < 5 )); then + + G_AGI mopidy gstreamer1.0-alsa python-pip python-dev + pip2 install -U pip setuptools wheel + 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 + pip3 install -U Mopidy-MusicBox-Webclient + + fi fi @@ -4042,6 +4055,8 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-c4-kodi.conf curl -sSfL "$INSTALL_URL_ADDRESS" -o install.sh chmod +x install.sh # - Skip Lighttpd install, since we allow to choose and install 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=1 G_EXEC_NOEXIT=1 G_EXEC_OUTPUT=1 G_EXEC ./install.sh --disable-install-webserver || aSOFTWARE_INSTALL_STATE[$software_id]=0 rm install.sh @@ -4051,13 +4066,10 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-c4-kodi.conf if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - INSTALL_URL_ADDRESS='https://api.github.com/repos/airsonic/airsonic/releases/latest' - G_CHECK_URL "$INSTALL_URL_ADDRESS" #full filepath below, returns --spider error :( - INSTALL_URL_ADDRESS=$(curl -sf "$INSTALL_URL_ADDRESS" | grep -m1 'browser_download_url.*\.war"' | cut -d \" -f 4) - - mkdir -p $G_FP_DIETPI_USERDATA/airsonic/transcode - wget "$INSTALL_URL_ADDRESS" -O $G_FP_DIETPI_USERDATA/airsonic/airsonic.war + G_CHECK_URL "$INSTALL_URL_ADDRESS" + local fallback_url='https://github.com/airsonic/airsonic/releases/download/v10.6.2/airsonic.war' + no_check_url=1 Download_Install "$(curl -sf "$INSTALL_URL_ADDRESS" | grep -m1 'browser_download_url.*\.war"' | cut -d \" -f 4)" $G_FP_DIETPI_USERDATA/airsonic/airsonic.war fi @@ -4065,7 +4077,6 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-c4-kodi.conf 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' @@ -4189,24 +4200,15 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-c4-kodi.conf (( $G_DISTRO < 5 || G_HW_ARCH == 1 )) && java='java8' INSTALL_URL_ADDRESS=$(curl -sf "$INSTALL_URL_ADDRESS" | grep -m1 "browser_download_url.*$java\.jar" | cut -d \" -f 4) - # Fallback URL - if [[ ! $INSTALL_URL_ADDRESS ]]; then - - INSTALL_URL_ADDRESS='https://github.com/blynkkk/blynk-server/releases/download/v0.41.12/server-0.41.12.jar' - (( $G_DISTRO < 5 || G_HW_ARCH == 1 )) && INSTALL_URL_ADDRESS='https://github.com/blynkkk/blynk-server/releases/download/v0.41.12/server-0.41.12-java8.jar' - - fi + local fallback_url='https://github.com/blynkkk/blynk-server/releases/download/v0.41.13/server-0.41.13.jar' + (( $G_DISTRO < 5 || G_HW_ARCH == 1 )) && fallback_url='https://github.com/blynkkk/blynk-server/releases/download/v0.41.12/server-0.41.13-java8.jar' - mkdir -p $G_FP_DIETPI_USERDATA/blynk/data - G_THREAD_START wget "$INSTALL_URL_ADDRESS" -O $G_FP_DIETPI_USERDATA/blynk/blynkserver.jar + DEPS_LIST='python' no_check_url=1 Download_Install "$INSTALL_URL_ADDRESS" $G_FP_DIETPI_USERDATA/blynk/blynkserver.jar # Install Blynk JS libary - G_AGI python npm i -g --unsafe-perm onoff npm i -g --unsafe-perm blynk-library - G_THREAD_WAIT - fi software_id=124 # NAA Daemon @@ -4345,6 +4347,8 @@ amvdec_vp9' > /etc/modules-load.d/dietpi-c4-kodi.conf Banner_Installing Download_Install 'https://wordpress.org/latest.tar.gz' /var/www + + chown -R www-data:www-data /var/www/wordpress/ fi @@ -4409,7 +4413,7 @@ enabled = true ignoreip = 127.0.0.1/8 ignorecommand = backend = systemd -filter = %(__name__)s +filter = %(__name__)s[mode=%(mode)s] findtime = 600 maxretry = 3 bantime = 600 @@ -4419,6 +4423,9 @@ 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_ G_AGI python3-systemd fail2ban @@ -4441,7 +4448,7 @@ _EOF_ INSTALL_URL_ADDRESS='https://repos.influxdata.com/influxdb.key' G_CHECK_URL "$INSTALL_URL_ADDRESS" - curl -sSfL "$INSTALL_URL_ADDRESS" | apt-key add - + G_EXEC eval "curl -sSLf '$INSTALL_URL_ADDRESS' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-influxdb.gpg --yes" # Use Buster branch on Bullseye echo "deb https://repos.influxdata.com/debian/ ${G_DISTRO_NAME/bullseye/buster} stable" > /etc/apt/sources.list.d/influxdb.list G_AGUP @@ -4458,15 +4465,15 @@ _EOF_ # 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_6.7.1_armhf.deb' + Download_Install 'https://dl.grafana.com/oss/release/grafana-rpi_7.1.1_armhf.deb' - # Else use official APT repo: https://grafana.com/docs/installation/debian/#apt-repository + # Else use official APT repo: https://grafana.com/docs/grafana/latest/installation/debian/#install-from-apt-repository else # APT key INSTALL_URL_ADDRESS='https://packages.grafana.com/gpg.key' G_CHECK_URL "$INSTALL_URL_ADDRESS" - curl -sSfL "$INSTALL_URL_ADDRESS" | apt-key add - + G_EXEC eval "curl -sSLf '$INSTALL_URL_ADDRESS' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-grafana.gpg --yes" # APT list echo 'deb https://packages.grafana.com/oss/deb/ stable main' > /etc/apt/sources.list.d/grafana.list @@ -4502,6 +4509,19 @@ _EOF_ fi + software_id=179 # Komga + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + + INSTALL_URL_ADDRESS='https://api.github.com/repos/gotson/komga/releases/latest' + G_CHECK_URL "$INSTALL_URL_ADDRESS" + + local fallback_url='https://github.com/gotson/komga/releases/download/v0.58.1/komga-0.58.1.jar' + no_check_url=1 Download_Install "$(curl -sf "$INSTALL_URL_ADDRESS" | mawk -F\" '/"browser_download_url": .*komga-[0-9.]*\.jar/{print $4;quit}')" $G_FP_DIETPI_USERDATA/komga/komga.jar + + fi + software_id=56 # PHP Image Gallery if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -4826,18 +4846,19 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- fi - software_id=99 # EmonHub + software_id=99 # EmonPi if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - DEPS_LIST='minicom python-serial python-configobj' + DEPS_LIST='minicom python-serial python-configobj python-pip python-dev' Download_Install 'https://github.com/Fourdee/emonhub/archive/emon-pi.zip' - pip install paho-mqtt pydispatcher + pip2 install -U pip setuptools wheel + pip2 install -U paho-mqtt pydispatcher # Move everything to /etc/emonhub - rm -R /etc/emonhub + [[ -d '/etc/emonhub' ]] && rm -R /etc/emonhub mv emonhub-* /etc/emonhub fi @@ -4969,21 +4990,17 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- # x86_64 if (( $G_HW_ARCH == 10 )); then - INSTALL_URL_ADDRESS='https://builds.cuberite.org/job/Cuberite%20Linux%20x64%20Master/lastSuccessfulBuild/artifact/Cuberite.tar.gz' + INSTALL_URL_ADDRESS='https://download.cuberite.org/linux-x86_64/Cuberite.tar.gz' - # 32bit ARM - elif (( $G_HW_ARCH == 1 || $G_HW_ARCH == 2 )); then + # ARMv6/7 + elif [[ $G_HW_ARCH == [12] ]]; then - INSTALL_URL_ADDRESS='https://builds.cuberite.org/job/Cuberite%20Linux%20raspi-armhf%20Master/lastSuccessfulBuild/artifact/Cuberite.tar.gz' + INSTALL_URL_ADDRESS='https://download.cuberite.org/linux-armhf-raspbian/Cuberite.tar.gz' fi Download_Install "$INSTALL_URL_ADDRESS" $G_FP_DIETPI_USERDATA/cubrite - # - Move everything into base directory (cuberite) - mv $G_FP_DIETPI_USERDATA/cubrite/Server/* $G_FP_DIETPI_USERDATA/cubrite/ - rm -R $G_FP_DIETPI_USERDATA/cubrite/Server - fi software_id=53 # MineOS @@ -5253,10 +5270,11 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- Banner_Installing # Prereqs + Motion - G_AGI v4l-utils python python-dev curl libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev motion + G_AGI v4l-utils python-pip python-dev curl libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev motion # Motioneye - pip install motioneye + pip2 install -U pip setuptools wheel + pip2 install -U motioneye fi @@ -5297,9 +5315,9 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- G_CHECK_URL "$INSTALL_URL_ADDRESS" - mkdir -p /etc/vhusbd - wget "$INSTALL_URL_ADDRESS" -O /etc/vhusbd/vhusbd - chmod +x /etc/vhusbd/vhusbd + G_EXEC mkdir -p /etc/vhusbd + G_EXEC curl -sSfL "$INSTALL_URL_ADDRESS" -o /etc/vhusbd/vhusbd + G_EXEC chmod +x /etc/vhusbd/vhusbd fi @@ -5308,27 +5326,31 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- Banner_Installing # https://sabnzbd.org/wiki/installation/install-off-modules - # Pre-reqs + # APT deps DEPS_LIST='par2 p7zip-full' # - Pre-compiling required on ARM (( $G_HW_ARCH < 10 )) && DEPS_LIST+=' libffi-dev libssl-dev' - Download_Install 'https://github.com/sabnzbd/sabnzbd/archive/master.tar.gz' + local branch='3.0.x' # Temporarily until v3 has been released: https://github.com/sabnzbd/sabnzbd/releases + Download_Install "https://github.com/sabnzbd/sabnzbd/archive/$branch.tar.gz" # Reinstall: Clear old install dir if [[ -d '/etc/sabnzbd' ]]; then # Preserve old config file - [[ -f '/etc/sabnzbd/sabnzbd.ini' ]] && mv /etc/sabnzbd/sabnzbd.ini sabnzbd-master/ - rm -R /etc/sabnzbd + [[ -f '/etc/sabnzbd/sabnzbd.ini' ]] && G_EXEC mv /etc/sabnzbd/sabnzbd.ini sabnzbd-$branch/ + G_EXEC_NOHALT=1 G_EXEC rm -R /etc/sabnzbd fi # Install new files - mv sabnzbd-master /etc/sabnzbd + G_EXEC mv sabnzbd-$branch /etc/sabnzbd + unset -v branch # Required Python modules - pip install cheetah cryptography sabyenc + G_EXEC cd /etc/sabnzbd + G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur requirements.txt + G_EXEC cd /tmp/$G_PROGRAM_NAME fi @@ -5347,7 +5369,7 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- Download_Install "$INSTALL_URL_ADDRESS" [[ -d '/opt/firefox-sync' ]] && rm -R /opt/firefox-sync mv syncserver-master /opt/firefox-sync - + # Build cd /opt/firefox-sync make build @@ -5372,13 +5394,14 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- Banner_Installing - DEPS_LIST='libffi-dev libssl-dev python-lxml python3-lxml' + DEPS_LIST='libffi-dev libssl-dev python-lxml python-pip python-dev' Download_Install 'https://github.com/CouchPotato/CouchPotatoServer/archive/master.tar.gz' [[ -d /etc/couchpotato ]] && rm -R /etc/couchpotato mv CouchPotato* /etc/couchpotato - pip install -U pyopenssl + pip2 install -U pip setuptools wheel + pip2 install -U pyopenssl fi @@ -5619,23 +5642,30 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- Banner_Installing - INSTALL_URL_ADDRESS='https://github.com/Hellowlol/HTPC-Manager.git' + INSTALL_URL_ADDRESS='https://github.com/gmiranda/HTPC-Manager.git' G_CHECK_URL "$INSTALL_URL_ADDRESS" + if [[ -d $G_FP_DIETPI_USERDATA/htpc-manager/.git ]]; then - G_THREAD_START git clone --depth=1 "$INSTALL_URL_ADDRESS" + G_EXEC cd $G_FP_DIETPI_USERDATA/htpc-manager + G_EXEC_OUTPUT=1 G_EXEC git remote set-url origin "$INSTALL_URL_ADDRESS" + 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' - # Pre-reqs - # - psutil for system stats - # - Python Image library: https://htpc.io/installation.html#linux - pip install psutil - G_AGI python-pil # pip install PIL fails at least on Debian Buster x86_64 + else - G_THREAD_WAIT + G_EXEC_OUTPUT=1 G_EXEC git clone --depth=1 "$INSTALL_URL_ADDRESS" + G_EXEC mkdir -p $G_FP_DIETPI_USERDATA/htpc-manager + G_EXEC cp -a HTPC-Manager/. $G_FP_DIETPI_USERDATA/htpc-manager/ + G_EXEC_NOHALT=1 G_EXEC rm -R HTPC-Manager + G_EXEC cd $G_FP_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 - # Move HTPC Manager to a 'better' location - mkdir -p $G_FP_DIETPI_USERDATA/htpc-manager - cp -a HTPC-Manager/* $G_FP_DIETPI_USERDATA/htpc-manager/ - rm -R HTPC-Manager + # Python deps + G_EXEC_OUTPUT=1 G_EXEC pip3 install -Ur requirements.txt fi @@ -5644,18 +5674,38 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- Banner_Installing - INSTALL_URL_ADDRESS='https://github.com/OctoPrint/OctoPrint.git' - G_CHECK_URL "$INSTALL_URL_ADDRESS" + if [[ -d $G_FP_DIETPI_USERDATA/octoprint/.git ]]; then - G_THREAD_START git clone "$INSTALL_URL_ADDRESS" - G_AGI libjpeg-dev - G_THREAD_WAIT - mv OctoPrint* $G_FP_DIETPI_USERDATA/octoprint + G_EXEC cd $G_FP_DIETPI_USERDATA/octoprint + G_EXEC_OUTPUT=1 G_EXEC git checkout + G_EXEC cd /tmp/$G_PROGRAM_NAME + + else + + INSTALL_URL_ADDRESS='https://github.com/OctoPrint/OctoPrint.git' + G_CHECK_URL "$INSTALL_URL_ADDRESS" + G_THREAD_START git clone --depth=1 "$INSTALL_URL_ADDRESS" + + fi + + local packages='libjpeg-dev' pip='pip3' + (( $G_DISTRO < 5 )) && packages+=' python-pip python-dev' pip='pip2' + G_AGI $packages + (( $G_DISTRO < 5 )) && G_EXEC_OUTPUT=1 G_EXEC pip2 install -U pip setuptools wheel + + if [[ ! -d $G_FP_DIETPI_USERDATA/octoprint/.git ]]; then + + G_THREAD_WAIT + G_EXEC mkdir -p $G_FP_DIETPI_USERDATA/octoprint + G_EXEC cp -a OctoPrint/. $G_FP_DIETPI_USERDATA/octoprint/ + G_EXEC_NOHALT=1 G_EXEC rm -R OctoPrint + + fi G_DIETPI-NOTIFY 2 'OctoPrint is now installing, please be patient and do not terminate this process, it may take some time...' - cd $G_FP_DIETPI_USERDATA/octoprint - G_EXEC pip install . - cd /tmp/$G_PROGRAM_NAME + G_EXEC cd $G_FP_DIETPI_USERDATA/octoprint + G_EXEC_OUTPUT=1 G_EXEC $pip install -U . + G_EXEC cd /tmp/$G_PROGRAM_NAME fi @@ -5789,13 +5839,7 @@ If you want to update ${aSOFTWARE_NAME[$software_id]}, please use it's internal if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - - INSTALL_URL_ADDRESS='https://ci.nukkitx.com/job/NukkitX/job/Nukkit/job/master/lastSuccessfulBuild/artifact/target/nukkit-1.0-SNAPSHOT.jar' - - G_CHECK_URL "$INSTALL_URL_ADDRESS" - - mkdir -p /usr/local/bin/nukkit - wget "$INSTALL_URL_ADDRESS" -O /usr/local/bin/nukkit/nukkit.jar + Download_Install 'https://ci.nukkitx.com/job/NukkitX/job/Nukkit/job/master/lastSuccessfulBuild/artifact/target/nukkit-1.0-SNAPSHOT.jar' /usr/local/bin/nukkit/nukkit.jar fi @@ -5902,7 +5946,7 @@ If you want to update ${aSOFTWARE_NAME[$software_id]}, please use it's internal pip3 install -U pip virtualenv virtualenv --system-site-packages -p python3 env - env/bin/pip install -r requirements.txt + env/bin/pip install -Ur requirements.txt #??? ARMv7 only (( $G_HW_ARCH == 2 )) && env/bin/pip install google-assistant-library==0.0.3 @@ -5948,7 +5992,7 @@ If you want to update ${aSOFTWARE_NAME[$software_id]}, please use it's internal # Create "mycroft" user with home=data dir beforehand, to have everything at right locations with right permissions directly local usercmd='useradd -rMU' getent passwd mycroft &> /dev/null && usercmd='usermod -a' - $usercmd -G audio -d $G_FP_DIETPI_USERDATA/mycroft-data -s $(command -v nologin) mycroft + G_EXEC $usercmd -G audio -d $G_FP_DIETPI_USERDATA/mycroft-data -s $(command -v nologin) mycroft mkdir -p $G_FP_DIETPI_USERDATA/mycroft-data chown -R mycroft:mycroft /etc/mycroft $G_FP_DIETPI_USERDATA/mycroft-{core,data} @@ -5957,7 +6001,7 @@ If you want to update ${aSOFTWARE_NAME[$software_id]}, please use it's internal ln -s $G_FP_DIETPI_USERDATA/mycroft-data /opt/mycroft # Assure 2 GiB overall memory is available - if (( $RAM_TOTAL + $(free -m | mawk '/^Swap:/ {print $2;exit}') < 2048 )); then + if (( $(free -tm | mawk '/^Total:/{print $2;exit}') < 2048 )); then G_WHIP_MSG '[WARNING] Insufficient overall memory size\n Mycroft AI requires at least 2 GiB memory on first start. We will now increase your swap file size to satisfy this requirement.' @@ -5993,6 +6037,25 @@ Mycroft AI requires at least 2 GiB memory on first start. We will now increase y fi + software_id=178 # Jellyfin + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Installing + + # Install APT repo key + INSTALL_URL_ADDRESS='https://repo.jellyfin.org/debian/jellyfin_team.gpg.key' + G_CHECK_URL "$INSTALL_URL_ADDRESS" + G_EXEC eval "curl -sSLf '$INSTALL_URL_ADDRESS' | gpg --dearmor -o /etc/apt/trusted.gpg.d/dietpi-jellyfin.gpg --yes" + + # Install APT repo + echo "deb https://repo.jellyfin.org/debian/ $G_DISTRO_NAME main" > /etc/apt/sources.list.d/dietpi-jellyfin.list + G_AGUP + + # Install Jellyfin + FFmpeg implementation + G_AGI jellyfin jellyfin-ffmpeg + + fi + software_id=27 # TasmoAdmin if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -6016,7 +6079,7 @@ Mycroft AI requires at least 2 GiB memory on first start. We will now increase y mv TasmoAdmin-master/tasmoadmin /var/www/ rm -R TasmoAdmin-master chown -R www-data:www-data /var/www/tasmoadmin - + fi # Configure the webserver @@ -6032,7 +6095,7 @@ Mycroft AI requires at least 2 GiB memory on first start. We will now increase y fi dps_index=$software_id Download_Install 'apache.tasmoadmin.conf' $tasmoadmin_conf - a2ensite dietpi-tasmoadmin 1> /dev/null + a2ensite dietpi-tasmoadmin 1> /dev/null elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 )); then @@ -6195,14 +6258,18 @@ sudo -u $ha_user dash -c '$ha_pyenv_activation; pip3 install -U homeassistant'" Banner_Installing + # 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 + local composition_manager= + (( ${aSOFTWARE_INSTALL_STATE[25]} > 0 )) || composition_manager='xcompmgr' + # Generic Xserver + Mesa OpenGL libraries and utilities - G_AGI xserver-xorg xinit xcompmgr xterm dbus-x11 xfonts-base x11-xserver-utils x11-utils libgl1-mesa-dri mesa-utils mesa-utils-extra + G_AGI xserver-xorg xinit $composition_manager xterm dbus-x11 xfonts-base x11-xserver-utils x11-utils libgl1-mesa-dri mesa-utils mesa-utils-extra # Disable DPMS and all screen blanking dps_index=$software_id Download_Install '99-dietpi-dpms_off.conf' /etc/X11/xorg.conf.d/99-dietpi-dpms_off.conf # Improve performance on all desktops and devices (eg: removes window lag in desktops) by limiting compositions - dps_index=$software_id Download_Install 'xcompmgr.desktop' /etc/xdg/autostart/xcompmgr.desktop + (( ${aSOFTWARE_INSTALL_STATE[25]} > 0 )) || dps_index=$software_id Download_Install 'xcompmgr.desktop' /etc/xdg/autostart/xcompmgr.desktop # RK3399: https://github.com/rockchip-linux/rk-rootfs-build/tree/master/packages/arm64 # - Odroid N1, RockPro64, NanoPC T4, Firefly RK3399, ROCK Pi 4 @@ -6309,7 +6376,7 @@ sudo -u $ha_user dash -c '$ha_pyenv_activation; pip3 install -U homeassistant'" fi - software_id=17 # Git client + software_id=17 # Git Client if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing @@ -6500,9 +6567,8 @@ sudo -u $ha_user dash -c '$ha_pyenv_activation; pip3 install -U homeassistant'" # Stop Dropbear service to unbind port 22 systemctl -q is-active dropbear && systemctl stop dropbear - G_AGI openssh-server - - # SSH server package also installs client. + # SSH server package pulls client as dependency. Mark client hence as installed and mark it explicitly so that it is not autoremoved with the server but must be marked for uninstall instead. + G_AGI openssh-server openssh-client aSOFTWARE_INSTALL_STATE[0]=2 # Allow root login @@ -6590,15 +6656,11 @@ sudo -u $ha_user dash -c '$ha_pyenv_activation; pip3 install -U homeassistant'" Banner_Installing - INSTALL_URL_ADDRESS='https://raw.githubusercontent.com/taaem/nodejs-linux-installer/master/node-install.sh' + INSTALL_URL_ADDRESS='https://raw.githubusercontent.com/MichaIng/nodejs-linux-installer/master/node-install.sh' G_CHECK_URL "$INSTALL_URL_ADDRESS" - G_EXEC wget "$INSTALL_URL_ADDRESS" - # ARMv6 workaround: https://github.com/MichaIng/DietPi/issues/2755 - (( $G_HW_ARCH == 1 )) && sed -i 's|nodejs.org/dist/latest/|nodejs.org/dist/latest-v11.x/|g' node-install.sh - - G_EXEC mkdir -p /usr/local # failsafe G_EXEC chmod +x node-install.sh + G_EXEC mkdir -p /usr/local # failsafe G_EXEC_OUTPUT=1 G_EXEC ./node-install.sh G_EXEC_NOHALT=1 G_EXEC rm node-install.sh @@ -6607,22 +6669,16 @@ sudo -u $ha_user dash -c '$ha_pyenv_activation; pip3 install -U homeassistant'" fi - software_id=130 # Python pip + software_id=130 # Python3 pip if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Installing - INSTALL_URL_ADDRESS='https://bootstrap.pypa.io/get-pip.py' G_CHECK_URL "$INSTALL_URL_ADDRESS" - - # Preqs - G_AGI python python-dev - - wget "$INSTALL_URL_ADDRESS" -O install.py - python ./install.py - rm install.py - - G_AGI python-pip python3-pip + G_AGI python3-dev + G_EXEC curl -sSfL "$INSTALL_URL_ADDRESS" -o get-pip.py + G_EXEC_OUTPUT=1 G_EXEC python3 ./get-pip.py + G_EXEC_NOHALT=1 G_EXEC rm get-pip.py fi @@ -6709,26 +6765,23 @@ sudo -u $ha_user dash -c '$ha_pyenv_activation; pip3 install -U homeassistant'" # Work out which file server needs removing (if any) if (( $INDEX_FILESERVER_TARGET != $INDEX_FILESERVER_CURRENT )); then - # Run uninstall of old file servers, after install loop - UNINSTALL_REQUIRED=1 - # No file server if (( $INDEX_FILESERVER_TARGET == 0 )); then - (( ${aSOFTWARE_INSTALL_STATE[94]} == 2 )) && aSOFTWARE_INSTALL_STATE[94]=-1 - (( ${aSOFTWARE_INSTALL_STATE[96]} == 2 )) && aSOFTWARE_INSTALL_STATE[96]=-1 + (( ${aSOFTWARE_INSTALL_STATE[94]} == 2 )) && aSOFTWARE_INSTALL_STATE[94]=-1 UNINSTALL_REQUIRED=1 + (( ${aSOFTWARE_INSTALL_STATE[96]} == 2 )) && aSOFTWARE_INSTALL_STATE[96]=-1 UNINSTALL_REQUIRED=1 # ProFTPD elif (( $INDEX_FILESERVER_TARGET == -1 )); then aSOFTWARE_INSTALL_STATE[94]=1 - (( ${aSOFTWARE_INSTALL_STATE[96]} == 2 )) && aSOFTWARE_INSTALL_STATE[96]=-1 + (( ${aSOFTWARE_INSTALL_STATE[96]} == 2 )) && aSOFTWARE_INSTALL_STATE[96]=-1 UNINSTALL_REQUIRED=1 # Samba elif (( $INDEX_FILESERVER_TARGET == -2 )); then aSOFTWARE_INSTALL_STATE[96]=1 - (( ${aSOFTWARE_INSTALL_STATE[94]} == 2 )) && aSOFTWARE_INSTALL_STATE[94]=-1 + (( ${aSOFTWARE_INSTALL_STATE[94]} == 2 )) && aSOFTWARE_INSTALL_STATE[94]=-1 UNINSTALL_REQUIRED=1 fi @@ -6745,36 +6798,33 @@ sudo -u $ha_user dash -c '$ha_pyenv_activation; pip3 install -U homeassistant'" # Work out which logging system needs removing (if any) if (( $INDEX_LOGGING_TARGET != $INDEX_LOGGING_CURRENT )); then - # Run uninstall of old logging systems, after install loop - UNINSTALL_REQUIRED=1 - # None if (( $INDEX_LOGGING_TARGET == 0 )); then - (( ${aSOFTWARE_INSTALL_STATE[101]} == 2 )) && aSOFTWARE_INSTALL_STATE[101]=-1 - (( ${aSOFTWARE_INSTALL_STATE[102]} == 2 )) && aSOFTWARE_INSTALL_STATE[102]=-1 - (( ${aSOFTWARE_INSTALL_STATE[103]} == 2 )) && 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 + (( ${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 - (( ${aSOFTWARE_INSTALL_STATE[102]} == 2 )) && aSOFTWARE_INSTALL_STATE[102]=-1 + (( ${aSOFTWARE_INSTALL_STATE[101]} == 2 )) && aSOFTWARE_INSTALL_STATE[101]=-1 UNINSTALL_REQUIRED=1 + (( ${aSOFTWARE_INSTALL_STATE[102]} == 2 )) && aSOFTWARE_INSTALL_STATE[102]=-1 UNINSTALL_REQUIRED=1 # RAMlog - backup every hour to /root/logfile_storage, then clear elif (( $INDEX_LOGGING_TARGET == -2 )); then aSOFTWARE_INSTALL_STATE[103]=1 - (( ${aSOFTWARE_INSTALL_STATE[101]} == 2 )) && aSOFTWARE_INSTALL_STATE[101]=-1 - (( ${aSOFTWARE_INSTALL_STATE[102]} == 2 )) && aSOFTWARE_INSTALL_STATE[102]=-1 + (( ${aSOFTWARE_INSTALL_STATE[101]} == 2 )) && aSOFTWARE_INSTALL_STATE[101]=-1 UNINSTALL_REQUIRED=1 + (( ${aSOFTWARE_INSTALL_STATE[102]} == 2 )) && aSOFTWARE_INSTALL_STATE[102]=-1 UNINSTALL_REQUIRED=1 # Logrotate + Rsyslog - logs to disk elif (( $INDEX_LOGGING_TARGET == -3 )); then aSOFTWARE_INSTALL_STATE[101]=1 aSOFTWARE_INSTALL_STATE[102]=1 - (( ${aSOFTWARE_INSTALL_STATE[103]} == 2 )) && aSOFTWARE_INSTALL_STATE[103]=-1 + (( ${aSOFTWARE_INSTALL_STATE[103]} == 2 )) && aSOFTWARE_INSTALL_STATE[103]=-1 UNINSTALL_REQUIRED=1 fi @@ -7044,90 +7094,67 @@ _EOF_ Banner_Configuration - # Apache2 has its own PHP module - if (( ${aSOFTWARE_INSTALL_STATE[83]} > 0 )); then - - # https://github.com/MichaIng/DietPi/issues/1144 - local php_service='/lib/systemd/system/apache2.service' - - # Nginx and Lighttpd use PHP-FPM - elif (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then + # PHP-FPM + if (( ${aSOFTWARE_INSTALL_STATE[84]} > 0 || ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - local php_service="/lib/systemd/system/${PHP_NAME}-fpm.service" - - # - PHP-FPM confs + # Base sed -i '/cgi.fix_pathinfo=/c\cgi.fix_pathinfo=1' "$FP_PHP_BASE_DIR"/fpm/php.ini - # - PHP-FPM optimizations based on total cores + # Optimizations 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 - # - Enviroment PHP settings: + # Enviroment 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 - # /tmp is mounted to RAM, so use DISK (/var/tmp) instead - sed -i "/env\[TMP\]/c\env\[TMP\] = /var/tmp" "$FP_PHP_BASE_DIR"/fpm/pool.d/www.conf - sed -i "/env\[TMPDIR\]/c\env\[TMPDIR\] = /var/tmp" "$FP_PHP_BASE_DIR"/fpm/pool.d/www.conf - sed -i "/env\[TEMP\]/c\env\[TEMP\] = /var/tmp" "$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=98' > $target_php_ini - - # - Set upload_tmp_dir to disk. Can't be /tmp as its ramdisk and limited size. Also used by ownCloud/Nextcloud uploads - # - If PHP uses PrivateTmp, we must not use own subfolder: https://github.com/MichaIng/DietPi/issues/1144 - if [[ -f $php_service ]] && grep -q '^[[:blank:]]*PrivateTmp=true' $php_service; then - - local upload_tmp_dir='/var/tmp' - - else + echo -e '; DietPi PHP settings\n; priority=97' > $target_php_ini - local upload_tmp_dir='/var/tmp/php_upload_tmp' - mkdir -p $upload_tmp_dir - chown -R www-data:www-data $upload_tmp_dir - - fi - G_CONFIG_INJECT 'upload_tmp_dir[[:blank:]]*=' "upload_tmp_dir=$upload_tmp_dir" $target_php_ini - - # - Max upload size - local php_max_upload_size="$(( $(php -r 'print(PHP_INT_MAX);') / 1024 / 1024))M" - # - upload_max_filesize - G_CONFIG_INJECT 'upload_max_filesize[[:blank:]]*=' "upload_max_filesize=$php_max_upload_size" $target_php_ini - # - post_max_size - G_CONFIG_INJECT 'post_max_size[[:blank:]]*=' "post_max_size=$php_max_upload_size" $target_php_ini - # - Nginx: Set client_max_body_size to avoid 2MB upload error: https://github.com/MichaIng/DietPi/issues/546 - if (( ${aSOFTWARE_INSTALL_STATE[85]} > 0 )); then - - sed -i "/client_max_body_size/c\ client_max_body_size $php_max_upload_size;" /etc/nginx/nginx.conf - - fi - - # - Set UTF-8 + # Set UTF-8 G_CONFIG_INJECT 'default_charset[[:blank:]]*=' 'default_charset="UTF-8"' $target_php_ini - # - PHP cache settings + # 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_TOTAL / 30 )) (( $target_php_cachesize < 10 )) && target_php_cachesize=10 - # - OPcache + # - OPcache G_CONFIG_INJECT 'opcache.enable[[:blank:]]*=' 'opcache.enable=1' $target_php_ini G_CONFIG_INJECT 'opcache.memory_consumption[[:blank:]]*=' "opcache.memory_consumption=$target_php_cachesize" $target_php_ini - G_CONFIG_INJECT 'opcache.revalidate_freq[[:blank:]]*=' 'opcache.revalidate_freq=60' $target_php_ini - # - APCu + # Assure that interned_strings_buffer is never larger than hald 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 TTL + G_CONFIG_INJECT 'apc.ttl[[:blank:]]*=' 'apc.ttl=259200' $target_php_ini # 3 days # Enable all available PHP modules phpenmod $(ls $FP_PHP_BASE_DIR/mods-available | sed -n '/\.ini$/{s/\.ini$//;p}') - # 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 + # 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 @@ -7167,7 +7194,7 @@ _EOF_ fi # Optimise for reduced memory use: https://github.com/MichaIng/DietPi/issues/605#issue-188930987 - #cat << _EOF_ > /etc/mysql/mariadb.conf.d/99-dietpi.cnf + #cat << _EOF_ > /etc/mysql/mariadb.conf.d/97-dietpi.cnf #[mysqld] #key_buffer_size=8M #max_connections=30 @@ -7383,7 +7410,7 @@ _EOF_ phpenmod ctype curl dom gd iconv intl json mbstring pdo_mysql posix simplexml xmlreader xmlwriter zip fileinfo opcache apcu redis exif G_DIETPI-NOTIFY 2 '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=99\napc.enable_cli=1' > $FP_PHP_BASE_DIR/mods-available/dietpi-owncloud.ini + echo -e '; ownCloud PHP settings\n; priority=98\napc.enable_cli=1' > $FP_PHP_BASE_DIR/mods-available/dietpi-owncloud.ini phpenmod dietpi-owncloud # Get version string @@ -7590,6 +7617,9 @@ location = /.well-known/caldav { # Enable maintenance mode to allow handling by dietpi-services: grep -q "^[[:blank:]]*'maintenance' => true," $config_php || occ maintenance:mode --on + # On <1 GiB devices assure at least 512 MiB swap space are available to stand 512 MiB file uploads + increased PHP cache and session file usage: https://github.com/MichaIng/DietPi/issues/2293 + (( $RAM_TOTAL < 900 && $(free -m | mawk '/^Swap:/{print $2;exit}') < 512 )) && /boot/dietpi/func/dietpi-set_swapfile 512 + fi software_id=114 # Nextcloud @@ -7601,7 +7631,7 @@ location = /.well-known/caldav { phpenmod ctype curl dom gd iconv intl json mbstring pdo_mysql posix simplexml xmlreader xmlwriter zip fileinfo opcache apcu redis exif G_DIETPI-NOTIFY 2 'Optimising APCu and OPcache modules 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=99\napc.enable_cli=1\nopcache.enable=1\nopcache.interned_strings_buffer=8 + 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=1' > $FP_PHP_BASE_DIR/mods-available/dietpi-nextcloud.ini phpenmod dietpi-nextcloud @@ -7824,6 +7854,13 @@ The install script will now exit. After applying one of the the above, rerun die 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'" + # 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 clarifiations: 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'" + # 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 @@ -7838,6 +7875,9 @@ The install script will now exit. After applying one of the the above, rerun die # Enable maintenance mode to allow handling by dietpi-services: grep -q "^[[:blank:]]*'maintenance' => true," $config_php || ncc maintenance:mode --on + # On <1 GiB devices assure at least 512 MiB swap space are available to stand 512 MiB file uploads + increased PHP cache and session file usage: https://github.com/MichaIng/DietPi/issues/2293 + (( $RAM_TOTAL < 900 && $(free -m | mawk '/^Swap:/{print $2;exit}') < 512 )) && /boot/dietpi/func/dietpi-set_swapfile 512 + fi software_id=168 # Nextcloud Talk @@ -8105,7 +8145,7 @@ _EOF_ # JustBoom specials if grep -q '^[[:blank:]]*CONFIG_SOUNDCARD=justboom' /boot/dietpi.txt; then - # Name displayed in YMPD sound button + # Name displayed in ympd sound button local justboom_soundcard_desc='JustBoom DietPi' G_CONFIG_INJECT 'name "' "name \"$justboom_soundcard_desc\"" /etc/mpd.conf G_CONFIG_INJECT 'zeroconf_name "' "zeroconf_name \"$justboom_soundcard_desc\"" /etc/mpd.conf @@ -8177,7 +8217,8 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Configuration - echo "$G_FP_DIETPI_USERDATA *(rw,async,no_root_squash,fsid=0,crossmnt,no_subtree_check)" > /etc/exports + mkdir -p /etc/exports.d + [[ -f '/etc/exports.d/dietpi.exports' ]] || echo "$G_FP_DIETPI_USERDATA *(rw,async,no_root_squash,fsid=0,crossmnt,no_subtree_check)" > /etc/exports.d/dietpi.exports fi @@ -8186,11 +8227,10 @@ _EOF_ Banner_Configuration + # User local usercmd='useradd -rMU' getent passwd ympd &> /dev/null && usercmd='usermod -a' $usercmd -G dietpi,audio -s $(command -v nologin) ympd - # - Add to new "render" group on Buster - (( $G_DISTRO > 4 )) && usermod -aG render ympd # Service cat << _EOF_ > /etc/systemd/system/ympd.service @@ -8214,8 +8254,7 @@ _EOF_ Banner_Configuration - # Use primary group "dietpi" to allow media access and create media files with "dietpi" group: - # - https://github.com/MichaIng/DietPi/issues/3382 + # Use primary group "dietpi" to allow media access and create media files with "dietpi" group: https://github.com/MichaIng/DietPi/issues/3382 usermod -g dietpi mympd getent group mympd &> /dev/null && delgroup mympd @@ -8459,12 +8498,12 @@ _EOF_ # Failsafe: Directory required for "noip2 -C" to create the config file mkdir -p /usr/local/etc - # noip2 service file + # Service cat << _EOF_ > /etc/systemd/system/noip2.service [Unit] Description=No-IP update client (DietPi) Wants=network-online.target -After=network-online.target rsyslog.service +After=network-online.target dietpi-boot.service ConditionPathExists=/usr/local/etc/no-ip2.conf [Service] @@ -8475,7 +8514,6 @@ ExecStop=$(command -v killall) -w noip2 [Install] WantedBy=multi-user.target _EOF_ - fi software_id=108 # Amiberry @@ -8817,16 +8855,16 @@ Do you want to enable the Pi-hole blocking page?'; then Banner_Configuration + # User local usercmd='useradd -rMU' getent passwd airsonic &> /dev/null && usercmd='usermod -a' - $usercmd -G dietpi,audio -d $G_FP_DIETPI_USERDATA/airsonic -s $(command -v nologin) airsonic - # - Add to new "render" group on Buster - (( $G_DISTRO > 4 )) && usermod -aG render airsonic + G_EXEC $usercmd -G dietpi,audio -d $G_FP_DIETPI_USERDATA/airsonic -s $(command -v nologin) airsonic # Optimise memory limit - local airsonic_memory_max=$(( $RAM_TOTAL / 5 )) - (( $airsonic_memory_max < 200 )) && airsonic_memory_max=200 + local memory_limit=$(( $RAM_TOTAL / 5 )) + (( $memory_limit < 200 )) && memory_limit=200 + # Service cat << _EOF_ > /etc/systemd/system/airsonic.service [Unit] Description=Airsonic Media Server (DietPi) @@ -8837,17 +8875,18 @@ After=network-online.target remote-fs.target User=airsonic Group=dietpi WorkingDirectory=$G_FP_DIETPI_USERDATA/airsonic -ExecStart=$(command -v java) -Xmx${airsonic_memory_max}m -Dairsonic.home=$G_FP_DIETPI_USERDATA/airsonic -Dserver.context-path=/airsonic -Dserver.port=8080 -jar $G_FP_DIETPI_USERDATA/airsonic/airsonic.war +ExecStart=$(command -v java) -Xmx${memory_limit}m -Dairsonic.home=$G_FP_DIETPI_USERDATA/airsonic -Dserver.context-path=/airsonic -Dserver.port=8080 -jar $G_FP_DIETPI_USERDATA/airsonic/airsonic.war [Install] WantedBy=multi-user.target _EOF_ - - # Symlink FFmpeg to Airsonic transcoder - command -v ffmpeg &> /dev/null && ln -sf $(command -v ffmpeg) $G_FP_DIETPI_USERDATA/airsonic/transcode + # Enable FFmpeg transcode + G_EXEC mkdir -p $G_FP_DIETPI_USERDATA/airsonic/transcode + command -v ffmpeg > /dev/null && G_EXEC ln -sf $(command -v ffmpeg) $G_FP_DIETPI_USERDATA/airsonic/transcode # Permissions - chown -R airsonic:airsonic $G_FP_DIETPI_USERDATA/airsonic + G_EXEC chmod +x $G_FP_DIETPI_USERDATA/airsonic/airsonic.war + G_EXEC chown airsonic: $G_FP_DIETPI_USERDATA/airsonic # Grab our test media for user Download_Test_Media @@ -8859,22 +8898,21 @@ _EOF_ Banner_Configuration + # User local usercmd='useradd -rMU' getent passwd subsonic &> /dev/null && usercmd='usermod -a' - $usercmd -G dietpi,audio -d /var/subsonic -s $(command -v nologin) subsonic - # - Add to new "render" group on Buster - (( $G_DISTRO > 4 )) && usermod -aG render subsonic - - # Optimise memory limit - local subsonic_memory_max=$(( $RAM_TOTAL / 5 )) - (( $subsonic_memory_max < 200 )) && subsonic_memory_max=200 + G_EXEC $usercmd -G dietpi,audio -d /var/subsonic -s $(command -v nologin) subsonic + # Config + # - Optimise memory limit + local memory_limit=$(( $RAM_TOTAL / 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=$subsonic_memory_max --default-music-folder=$G_FP_DIETPI_USERDATA/$FOLDER_MUSIC --default-podcast-folder=$G_FP_DIETPI_USERDATA/$FOLDER_MUSIC --default-playlist-folder=$G_FP_DIETPI_USERDATA/$FOLDER_MUSIC'" /etc/default/subsonic + G_CONFIG_INJECT 'SUBSONIC_ARGS=' "SUBSONIC_ARGS='--quiet --pidfile=/run/subsonic.pid --max-memory=$memory_limit --default-music-folder=$G_FP_DIETPI_USERDATA/$FOLDER_MUSIC --default-podcast-folder=$G_FP_DIETPI_USERDATA/$FOLDER_MUSIC --default-playlist-folder=$G_FP_DIETPI_USERDATA/$FOLDER_MUSIC'" /etc/default/subsonic - # Symlink FFmpeg to Subsonic transcoder - mkdir -p /var/subsonic/transcode - command -v ffmpeg &> /dev/null && ln -sf $(command -v ffmpeg) /var/subsonic/transcode + # 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 @@ -9302,7 +9340,7 @@ _EOF_ # User local usercmd='useradd -rMU' - getent passwd ubooquity &> /dev/null && usercmd='usermod -a' + getent passwd ubooquity > /dev/null && usercmd='usermod -a' G_EXEC $usercmd -G dietpi -d $G_FP_DIETPI_USERDATA/ubooquity -s $(command -v nologin) ubooquity # Data @@ -9313,6 +9351,10 @@ _EOF_ G_EXEC mkdir -p /var/log/ubooquity G_EXEC ln -s /var/log/ubooquity $G_FP_DIETPI_USERDATA/ubooquity/logs + # Optimise memory limit + local memory_limit=$(( $RAM_TOTAL / 5 )) + (( $memory_limit < 200 )) && memory_limit=200 + # Service G_DIETPI-NOTIFY 2 "Generating systemd service to start ${aSOFTWARE_NAME[$software_id]} on boot" cat << _EOF_ > /etc/systemd/system/ubooquity.service @@ -9324,7 +9366,7 @@ After=network-online.target dietpi-boot.service [Service] User=ubooquity WorkingDirectory=$G_FP_DIETPI_USERDATA/ubooquity -ExecStart=$(command -v java) -jar $G_FP_DIETPI_USERDATA/ubooquity/Ubooquity.jar --headless --remoteadmin --adminport 2038 --libraryport 2039 +ExecStart=$(command -v java) -Xmx${memory_limit}m -jar $G_FP_DIETPI_USERDATA/ubooquity/Ubooquity.jar --headless --remoteadmin --adminport 2038 --libraryport 2039 [Install] WantedBy=multi-user.target @@ -9337,6 +9379,71 @@ _EOF_ fi + software_id=179 # Komga + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Configuration + + # User + local usercmd='useradd -rMU' + getent passwd komga > /dev/null && usercmd='usermod -a' + G_EXEC $usercmd -G dietpi -d $G_FP_DIETPI_USERDATA/komga -s $(command -v nologin) komga + + # Data + G_EXEC mkdir -p $G_FP_DIETPI_USERDATA/{ebooks,comics} + + # Config + [[ -f $G_FP_DIETPI_USERDATA/komga/application.yml ]] || cat << _EOF_ > $G_FP_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 + database: + file: $G_FP_DIETPI_USERDATA/komga/database.sqlite + database-backup: + enabled: true # Enable database backups + startup: false # Do not create a backup at startup + schedule: "* 22 4 * * *" # Create a backup every night at 4:22 + path: $G_FP_DIETPI_USERDATA/komga/database-backup.zip + 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 +spring: + datasource: + url: jdbc:h2:$G_FP_DIETPI_USERDATA/komga/database.h2 +_EOF_ + # Optimise memory limit + local memory_limit=$(( $RAM_TOTAL / 5 )) + (( $memory_limit < 200 )) && memory_limit=200 + + # Service + cat << _EOF_ > /etc/systemd/system/komga.service +[Unit] +Description=Komga (DietPi) +Wants=network-online.target +After=network-online.target dietpi-boot.service + +[Service] +User=komga +WorkingDirectory=$G_FP_DIETPI_USERDATA/komga +ExecStart=$(command -v java) -Xmx${memory_limit}m -jar komga.jar + +[Install] +WantedBy=multi-user.target +_EOF_ + # Permissions + G_EXEC chmod +x $G_FP_DIETPI_USERDATA/komga/komga.jar + G_EXEC chown -R komga $G_FP_DIETPI_USERDATA/komga + G_EXEC chown komga:dietpi $G_FP_DIETPI_USERDATA/{ebooks,comics} + G_EXEC chmod 775 $G_FP_DIETPI_USERDATA/{ebooks,comics} + + fi + software_id=64 # phpSysInfo if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then @@ -9906,7 +10013,7 @@ _EOF_ fi - software_id=99 # EmonHub + software_id=99 # EmonPi if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then Banner_Configuration @@ -9922,7 +10029,6 @@ _EOF_ chmod +x -R /etc/emonhub # Disable onboard Bluetooth, if present, to recover ttyAMA0 - # RPi4: Test required if (( $G_HW_ONBOARD_WIFI )); then /boot/dietpi/func/dietpi-set_hardware bluetooth disable @@ -9930,15 +10036,15 @@ _EOF_ # 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' $FP_RPI_CONFIG + 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 - # - Apply user API KEY - USER_EMONHUB_APIKEY_CURRENT=$(grep -m1 '^[[:blank:]]*SOFTWARE_EMONHUB_APIKEY=' /boot/dietpi.txt | sed 's/^[^=]*=//') + # Apply user API KEY + USER_EMONHUB_APIKEY_CURRENT=$(sed -n '/^[[:blank:]]*SOFTWARE_EMONHUB_APIKEY=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) sed -i "/apikey/c\ apikey = $USER_EMONHUB_APIKEY_CURRENT" /etc/emonhub/conf/emonhub.conf fi @@ -10140,10 +10246,12 @@ location = /.well-known/caldav { Banner_Configuration + # User local usercmd='useradd -rMU' - getent passwd cuberite &> /dev/null && usercmd='usermod -a' - $usercmd -G dietpi -d $G_FP_DIETPI_USERDATA/cubrite -s $(command -v nologin) cuberite + getent passwd cuberite &> /dev/null && usercmd='usermod' + $usercmd -d $G_FP_DIETPI_USERDATA/cubrite -s $(command -v nologin) cuberite + # Service cat << _EOF_ > /etc/systemd/system/cuberite.service [Unit] Description=Cuberite Server (DietPi) @@ -10151,16 +10259,14 @@ Description=Cuberite Server (DietPi) [Service] Type=forking User=cuberite -Group=dietpi WorkingDirectory=$G_FP_DIETPI_USERDATA/cubrite ExecStart=$G_FP_DIETPI_USERDATA/cubrite/Cuberite --service [Install] WantedBy=multi-user.target _EOF_ - - # WebUI settings - cat << _EOF_ > $G_FP_DIETPI_USERDATA/cubrite/webadmin.ini + # WebUI settings: Do not overwrite existing! + [[ -f $G_FP_DIETPI_USERDATA/cubrite/webadmin.ini ]] || cat << _EOF_ > $G_FP_DIETPI_USERDATA/cubrite/webadmin.ini [User:admin] Password=$GLOBAL_PW @@ -10168,9 +10274,8 @@ Password=$GLOBAL_PW Ports=1339 Enabled=1 _EOF_ - # Permissions - chown -R cuberite:dietpi $G_FP_DIETPI_USERDATA/cubrite + chown -R cuberite:cuberite $G_FP_DIETPI_USERDATA/cubrite fi @@ -10270,17 +10375,24 @@ _EOF_ # User local usercmd='useradd -rMN' - getent passwd qbittorrent &> /dev/null && usercmd='usermod' - $usercmd -g dietpi -s $(command -v nologin) qbittorrent - # - Set password only on fresh install + getent passwd qbittorrent > /dev/null && usercmd='usermod' + G_EXEC $usercmd -g dietpi -s $(command -v nologin) qbittorrent + # - Set password on fresh install [[ $usercmd == 'useradd'* ]] && chpasswd <<< "qbittorrent:$GLOBAL_PW" # Config: Create only on fresh install - mkdir -p /home/qbittorrent/.config/qBittorrent - [[ -f '/home/qbittorrent/.config/qBittorrent/qBittorrent.conf' ]] || cat << _EOF_ > /home/qbittorrent/.config/qBittorrent/qBittorrent.conf + if [[ ! -f '/home/qbittorrent/.config/qBittorrent/qBittorrent.conf' ]]; then + + G_EXEC mkdir -p /home/qbittorrent/.config/qBittorrent /var/log/qbittorrent + G_EXEC chown -R qbittorrent: /var/log/qbittorrent + cat << _EOF_ > /home/qbittorrent/.config/qBittorrent/qBittorrent.conf [General] ported_to_new_savepath_system=true +[Application] +FileLogger\Enabled=true +FileLogger\Path=/var/log/qbittorrent + [Preferences] Downloads\DiskWriteCacheSize=$(Optimise_BitTorrent 0) Downloads\DiskWriteCacheTTL=60 @@ -10354,6 +10466,8 @@ Accepted=true enabled=false program= _EOF_ + fi + # Service cat << _EOF_ > /etc/systemd/system/qbittorrent.service [Unit] @@ -10365,13 +10479,13 @@ After=network-online.target dietpi-boot.service [Service] User=qbittorrent UMask=002 -ExecStart=$(command -v qbittorrent-nox) --webui-port=1340 +ExecStart=$(command -v qbittorrent-nox) [Install] WantedBy=multi-user.target _EOF_ # Permissions - chown -R qbittorrent:dietpi /home/qbittorrent + G_EXEC chown -R qbittorrent: /home/qbittorrent fi @@ -11118,10 +11232,10 @@ _EOF_ Banner_Configuration + # Service cat << _EOF_ > /etc/systemd/system/virtualhere.service [Unit] Description=VirtualHere (DietPi) -After=local-fs.target [Service] ExecStart=/etc/vhusbd/vhusbd -r /var/log/virtualhere.log @@ -11129,7 +11243,7 @@ ExecStart=/etc/vhusbd/vhusbd -r /var/log/virtualhere.log [Install] WantedBy=multi-user.target _EOF_ - + # Config echo "ServerName='DietPi'" > /etc/vhusbd/config.ini fi @@ -11142,11 +11256,11 @@ _EOF_ # User local usercmd='useradd -rMU' getent passwd sabnzbd &> /dev/null && usercmd='usermod -a' - $usercmd -G dietpi -d /etc/sabnzbd -s $(command -v nologin) sabnzbd + G_EXEC $usercmd -G dietpi -d /etc/sabnzbd -s $(command -v nologin) 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 python2.7 explicitly to avoid version conflicts) + # "-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 @@ -11155,12 +11269,12 @@ _EOF_ Description=SABnzbd (DietPi) Documentation=https://sabnzbd.org/wiki/ Wants=network-online.target -After=network-online.target +After=network-online.target dietpi-boot.service [Service] User=sabnzbd Group=dietpi -ExecStart=$(command -v python2.7) -OO /etc/sabnzbd/SABnzbd.py -b 0 -f /etc/sabnzbd/sabnzbd.ini +ExecStart=$(command -v python3) -OO /etc/sabnzbd/SABnzbd.py -b 0 -f /etc/sabnzbd/sabnzbd.ini Restart=on-failure [Install] @@ -11168,8 +11282,8 @@ WantedBy=multi-user.target _EOF_ # Log dir and permissions - mkdir -p /var/log/sabnzbd - chown -R sabnzbd:sabnzbd /etc/sabnzbd /var/log/sabnzbd + G_EXEC mkdir -p /var/log/sabnzbd + G_EXEC chown -R sabnzbd:sabnzbd /etc/sabnzbd /var/log/sabnzbd # Create config # - Touch only if it does not yet exist, assume reinstall otherwise and preserve custom changes @@ -11177,11 +11291,11 @@ _EOF_ # - 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 - systemctl daemon-reload - systemctl start sabnzbd + G_EXEC systemctl daemon-reload + G_EXEC systemctl start sabnzbd G_DIETPI-NOTIFY 2 'Generating initial config, please wait...' - while [[ ! -f '/etc/sabnzbd/sabnzbd.ini' ]] + until [[ -f '/etc/sabnzbd/sabnzbd.ini' ]] do sleep 0.5 @@ -11189,7 +11303,7 @@ _EOF_ done sleep 2 - systemctl stop sabnzbd + G_EXEC_NOHALT=1 G_EXEC systemctl stop sabnzbd sleep 2 # Additional wait, config being overwritten after below changes: https://dietpi.com/phpbb/viewtopic.php?p=7082#p7082 G_CONFIG_INJECT 'download_dir =' "download_dir = $G_FP_DIETPI_USERDATA/$FOLDER_DOWNLOADS/incomplete" /etc/sabnzbd/sabnzbd.ini @@ -11197,7 +11311,7 @@ _EOF_ G_CONFIG_INJECT 'nzb_backup_dir =' "nzb_backup_dir = $G_FP_DIETPI_USERDATA/$FOLDER_DOWNLOADS/sabnzbd_nzb_backup" /etc/sabnzbd/sabnzbd.ini G_CONFIG_INJECT 'admin_dir =' "admin_dir = $G_FP_DIETPI_USERDATA/$FOLDER_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 '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 @@ -11206,9 +11320,9 @@ _EOF_ fi # Install language packs: https://github.com/MichaIng/DietPi/issues/1917#issue-340631943 - cd /etc/sabnzbd - G_EXEC python2.7 tools/make_mo.py - cd /tmp/$G_PROGRAM_NAME + G_EXEC cd /etc/sabnzbd + G_EXEC python3 tools/make_mo.py + G_EXEC cd /tmp/$G_PROGRAM_NAME fi @@ -11279,7 +11393,7 @@ _EOF_ [Unit] Description=Spotify Connect Web (DietPi) Wants=network-online.target -After=network-online.target sound.target +After=network-online.target sound.target [Service] WorkingDirectory=$G_FP_DIETPI_USERDATA/spotify-connect-web @@ -11645,6 +11759,7 @@ _EOF_ sed -i "/ArticleCache=/c\ArticleCache=$(Optimise_BitTorrent 0)" $G_FP_DIETPI_USERDATA/nzbget/nzbget.conf sed -i "/WriteBuffer=/c\WriteBuffer=$(Optimise_BitTorrent 0)" $G_FP_DIETPI_USERDATA/nzbget/nzbget.conf + # Service cat << _EOF_ > /etc/systemd/system/nzbget.service [Unit] Description=NZBget (DietPi) @@ -11659,7 +11774,6 @@ ExecStart=$G_FP_DIETPI_USERDATA/nzbget/nzbget -D [Install] WantedBy=multi-user.target _EOF_ - # Permissions chown -R nzbget:dietpi $G_FP_DIETPI_USERDATA/nzbget @@ -11670,19 +11784,20 @@ _EOF_ Banner_Configuration + # Service cat << _EOF_ > /etc/systemd/system/htpc-manager.service [Unit] Description=HTPC Manager (DietPi) Wants=network-online.target -After=network-online.target +After=network-online.target dietpi-boot.service [Service] -ExecStart=$(command -v python) $G_FP_DIETPI_USERDATA/htpc-manager/Htpc.py +SyslogIdentifier=HTPC Manager +ExecStart=$(command -v python3) $G_FP_DIETPI_USERDATA/htpc-manager/Htpc.py [Install] WantedBy=multi-user.target _EOF_ - fi software_id=153 # OctoPrint @@ -11690,6 +11805,7 @@ _EOF_ Banner_Configuration + # Service cat << _EOF_ > /etc/systemd/system/octoprint.service [Unit] Description=OctoPrint (DietPi) @@ -11715,7 +11831,7 @@ _EOF_ [Unit] Description=Roon Server (DietPi) Wants=network-online.target -After=network-online.target +After=network-online.target dietpi-boot.service [Service] SyslogIdentifier=roonserver @@ -12154,15 +12270,12 @@ _EOF_ Banner_Configuration - # RPi enable i2c required for GUI + # RPi enable I2C required for GUI (( $G_HW_MODEL < 10 )) && /boot/dietpi/func/dietpi-set_hardware i2c enable - mkdir -p /var/lib/dietpi/dietpi-software/installed/pijuice - cat << _EOF_ > /var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func1.sh -#!/bin/bash -poweroff -_EOF_ - chmod +x /var/lib/dietpi/dietpi-software/installed/pijuice/pijuice_func1.sh + 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 { @@ -12227,6 +12340,32 @@ _EOF_ } } _EOF_ + fi + + software_id=178 # Jellyfin + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == 1 )); then + + Banner_Configuration + + # Grant dietpi group permissions + G_EXEC usermod -aG dietpi -d $G_FP_DIETPI_USERDATA/jellyfin jellyfin + + # Config: Only apply on fresh install, assumed when $G_FP_DIETPI_USERDATA/jellyfin does not yet exist + if [[ ! -d $G_FP_DIETPI_USERDATA/jellyfin ]]; then + + # Data dir + [[ -d '/var/lib/jellyfin' ]] && G_EXEC mv /var/lib/jellyfin $G_FP_DIETPI_USERDATA/jellyfin || G_EXEC mkdir -p $G_FP_DIETPI_USERDATA/jellyfin + G_CONFIG_INJECT 'JELLYFIN_DATA_DIR=' "JELLYFIN_DATA_DIR=$G_FP_DIETPI_USERDATA/jellyfin" /etc/default/jellyfin + # Cache dir + [[ -d '/var/cache/jellyfin' ]] && G_EXEC mv /var/cache/jellyfin $G_FP_DIETPI_USERDATA/jellyfin/cache || G_EXEC mkdir -p $G_FP_DIETPI_USERDATA/jellyfin/cache + G_CONFIG_INJECT 'JELLYFIN_CACHE_DIR=' "JELLYFIN_CACHE_DIR=$G_FP_DIETPI_USERDATA/jellyfin/cache" /etc/default/jellyfin + + fi + + # Permissions + G_EXEC chown -R jellyfin: $G_FP_DIETPI_USERDATA/jellyfin + + Download_Test_Media fi @@ -12352,12 +12491,12 @@ _EOF_ fi - software_id=24 + software_id=24 # Desktop MATE if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling apt-mark auto upower policykit-1 firefox-esr - G_AGP mate-desktop-environment-extras + G_AGP mate-desktop-environment-core fi @@ -12670,7 +12809,6 @@ _EOF_ software_id=148 # myMPD if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then - #apt-mark auto libmpdclient2 cmake cppcheck pkg-config libmpdclient-dev libssl-dev libmediainfo-dev if [[ -f '/lib/systemd/system/mympd.service' ]]; then systemctl unmask mympd @@ -12681,8 +12819,7 @@ _EOF_ getent passwd mympd &> /dev/null && userdel -rf mympd getent group mympd &> /dev/null && groupdel mympd # pre-v6.29 command -v mympd &> /dev/null && rm $(command -v mympd) - rm -Rf /{etc,var/lib,usr/share}/mympd /etc/mympd.conf* - rm -f /usr/share/man/man1/mympd.* + rm -Rf /{etc,var/lib,usr/share}/mympd /etc/mympd.conf* /etc/systemd/system/mympd.service.d /usr/share/man/man1/mympd.* fi @@ -12697,10 +12834,10 @@ _EOF_ rm -R /lib/systemd/system/mpd.service* fi + [[ -d '/etc/systemd/system/mpd.service.d' ]] && rm -R /etc/systemd/system/mpd.service.d [[ -f '/lib/systemd/system/mpd.socket' ]] && rm /lib/systemd/system/mpd.socket getent passwd mpd &> /dev/null && userdel -rf mpd getent group mpd &> /dev/null && groupdel mpd # pre-v6.29 - #apt-mark auto libavformat57 libupnp6 libao-common libao4 libasound2 libasound2-data libasyncns0 libaudiofile1 libavahi-client3 libavahi-common-data libavahi-common3 libavcodec56 libavformat56 libavresample2 libavutil54 libbinio1ldbl libcaca0 libcdio-cdda1 libcdio-paranoia1 libcdio13 libcups2 libcurl3-gnutls libdirectfb-1.2-9 libdnet libfaad2 libflac8 libfluidsynth1 libgme0 libgomp1 libgsm1 libice6 libid3tag0 libiso9660-8 libjack-jackd2-0 libjson-c2 libldb1 libmad0 libmikmod3 libmms0 libmodplug1 libmp3lame0 libmpcdec6 libmpg123-0 libnfs4 libntdb1 libogg0 libopenal-data libopenal1 libopenjpeg5 libopus0 liborc-0.4-0 libpulse0 libresid-builder0c2a libroar2 libsamplerate0 libschroedinger-1.0-0 libsdl1.2debian libshout3 libsidplay2 libsidutils0 libslp1 libsm6 libsmbclient libsndfile1 libsoxr0 libspeex1 libspeexdsp1 libsqlite3-0 libtalloc2 libtdb1 libtevent0 libtheora0 libva1 libvorbis0a libvorbisenc2 libvorbisfile3 libvpx1 libwavpack1 libwbclient0 libwildmidi-config libwildmidi1 libx11-6 libx11-data libx11-xcb1 libx264-142 libxau6 libxcb1 libxdmcp6 libxext6 libxi6 libxtst6 libxvidcore4 libyajl2 libzzip-0-13 mime-support python python-talloc python2.7 samba-libs x11-common file &> /dev/null G_AGP mpd libmpdclient2 [[ -d '/var/log/mpd' ]] && rm -R /var/log/mpd [[ -d $G_FP_DIETPI_USERDATA/.mpd_cache ]] && rm -R $G_FP_DIETPI_USERDATA/.mpd_cache @@ -12785,14 +12922,6 @@ _EOF_ fi - software_id=130 - if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then - - Banner_Uninstalling - G_AGP python-pip python3-pip - - fi - software_id=131 # Blynk Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then @@ -12860,18 +12989,17 @@ _EOF_ fi - software_id=134 + software_id=134 # Tonido if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - #apt-mark auto libjpeg8 libpng12-0 libfontconfig1 libssl1.0.0 &> /dev/null - if [[ -f '/etc/systemd/system/tonido.service' ]]; then systemctl disable --now tonido rm -R /etc/systemd/system/tonido.service* fi + [[ -d '/etc/systemd/system/tonido.service.d' ]] && rm -R /etc/systemd/system/tonido.service.d getent passwd tonido &> /dev/null && userdel -rf tonido [[ -d $G_FP_DIETPI_USERDATA/tonido ]] && rm -R $G_FP_DIETPI_USERDATA/tonido [[ -d '/home/tonido' ]] && rm -R /home/tonido @@ -12902,10 +13030,10 @@ _EOF_ rm -R /etc/systemd/system/motioneye.service* fi - #apt-mark auto v4l-utils python python-dev libssl-dev libcurl4-openssl-dev libjpeg-dev zlib1g-dev libx264-142 libavcodec56 libavformat56 libmysqlclient18 libswscale3 libpq5 2> /dev/null + [[ -d '/etc/systemd/system/motioneye.service.d' ]] && rm -R /etc/systemd/system/motioneye.service.d + pip2 uninstall -y motioneye G_AGP motion [[ -d '/etc/motioneye' ]] && rm -R /etc/motioneye - pip uninstall -y motioneye fi @@ -12917,12 +13045,18 @@ _EOF_ fi - software_id=138 + software_id=138 # VirtualHere if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - rm -R /etc/vhusbd - rm /etc/systemd/system/virtualhere.service + if [[ -f '/etc/systemd/system/virtualhere.service' ]]; then + + systemctl disable --now virtualhere + rm -R /etc/systemd/system/virtualhere.service* + + fi + [[ -d '/etc/systemd/system/virtualhere.service.d' ]] && rm -R /etc/systemd/system/virtualhere.service.d + [[ -d '/etc/vhusbd' ]] && rm -R /etc/vhusbd fi @@ -12936,7 +13070,9 @@ _EOF_ rm -R /etc/systemd/system/sabnzbd.service* fi + [[ -d '/etc/systemd/system/sabnzbd.service.d' ]] && rm -R /etc/systemd/system/sabnzbd.service.d getent passwd sabnzbd &> /dev/null && userdel -rf sabnzbd + getent group sabnzbd &> /dev/null && groupdel sabnzbd [[ -d '/etc/sabnzbd' ]] && rm -R /etc/sabnzbd fi @@ -12951,6 +13087,7 @@ _EOF_ rm -R /etc/systemd/system/firefox-sync.service* fi + [[ -d '/etc/systemd/system/firefox-sync.service.d' ]] && rm -R /etc/systemd/system/firefox-sync.service.d getent passwd ffsync &> /dev/null && userdel -rf ffsync getent group ffsync &> /dev/null && groupdel ffsync [[ -d '/opt/firefox-sync' ]] && rm -R /opt/firefox-sync @@ -12967,14 +13104,22 @@ _EOF_ fi - software_id=142 + software_id=142 # CouchPotato if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - rm -R /etc/couchpotato - rm -R $G_FP_DIETPI_USERDATA/couchpotato - rm /etc/init.d/couchpotato - #userdel -rf couchpotato + if [[ -f '/etc/init.d/couchpotato' ]]; then + + systemctl unmask couchpotato + systemctl disable --now couchpotato + rm /etc/init.d/couchpotato + update-rc.d -f couchpotato remove + + fi + [[ -d '/etc/systemd/system/couchpotato.service.d' ]] && rm -R /etc/systemd/system/couchpotato.service.d + getent passwd couchpotato &> /dev/null && userdel -rf couchpotato + [[ -d '/etc/couchpotato' ]] && rm -R /etc/couchpotato + [[ -d $G_FP_DIETPI_USERDATA/couchpotato ]] && rm -R $G_FP_DIETPI_USERDATA/couchpotato fi @@ -13087,21 +13232,27 @@ _EOF_ fi - software_id=155 + software_id=155 # HTPC Manager if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - rm -R $G_FP_DIETPI_USERDATA/htpc-manager - rm /etc/systemd/system/htpc-manager.service + if [[ -f '/etc/systemd/system/htpc-manager.service' ]]; then + + systemctl disable --now htpc-manager + rm -R /etc/systemd/system/htpc-manager.service* + + fi + [[ -d '/etc/systemd/system/htpc-manager.service.d' ]] && rm -R /etc/systemd/system/htpc-manager.service.d + [[ -d $G_FP_DIETPI_USERDATA/htpc-manager ]] && rm -R $G_FP_DIETPI_USERDATA/htpc-manager fi - software_id=150 + software_id=150 # Mono if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling apt-mark auto mono-complete mono-devel mono-runtime libmono-cil-dev 2>/dev/null - rm /etc/apt/sources.list.d/mono-xamarin.list + [[ -f '/etc/apt/sources.list.d/mono-xamarin.list' ]] && rm /etc/apt/sources.list.d/mono-xamarin.list fi @@ -13128,7 +13279,6 @@ _EOF_ getent passwd shairport-sync &> /dev/null && userdel -rf shairport-sync getent group shairport-sync &> /dev/null && groupdel shairport-sync # Pre-v6.29 - #apt-mark auto libssl1.0.0 openssl libsoxr0 libavahi-client3 libtool libconfig9 libpopt0 libdaemon0 2> /dev/null rm -f /usr/local/bin/shairport-sync /usr/local/etc/shairport-sync.conf* /usr/local/share/man/man7/shairport-sync.7.gz fi @@ -13151,15 +13301,13 @@ _EOF_ rm -R /etc/systemd/system/octoprint.service* fi + [[ -d '/etc/systemd/system/octoprint.service.d' ]] && rm -R /etc/systemd/system/octoprint.service.d if [[ -d $G_FP_DIETPI_USERDATA/octoprint ]]; then - if command -v pip &> /dev/null; then - - cd $G_FP_DIETPI_USERDATA/octoprint - pip uninstall . - cd /tmp/$G_PROGRAM_NAME - - fi + cd $G_FP_DIETPI_USERDATA/octoprint + command -v pip3 &> /dev/null && pip3 uninstall -y . + command -v pip2 &> /dev/null && pip2 uninstall -y . # Stretch + pre-v6.32 + cd /tmp/$G_PROGRAM_NAME rm -R $G_FP_DIETPI_USERDATA/octoprint fi @@ -13210,7 +13358,6 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - #apt-mark auto libpulse0 libfftw3-3 libncursesw5 2> /dev/null G_AGP cava rm -Rf /{root,home/*}/.config/cava rm -f /{root,home/*}/cava.psf @@ -13221,10 +13368,10 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - G_AGP mopidy + G_AGP 'mopidy*' [[ -f '/etc/apt/sources.list.d/mopidy.list' ]] && rm /etc/apt/sources.list.d/mopidy.list - command -v pip &> /dev/null && pip uninstall -y Mopidy-MusicBox-Webclient Mopidy-Local-Images + 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 -rf mopidy @@ -13311,7 +13458,7 @@ _EOF_ if [[ -f '/etc/systemd/system/deluged.service' ]]; then systemctl disable --now deluged - rm -R /etc/systemd/system/deluged.service* + rm -R /etc/systemd/system/deluged.service* fi G_AGP deluged deluge-web deluge-console @@ -13353,6 +13500,7 @@ _EOF_ Banner_Uninstalling G_AGP nfs-kernel-server + rm -Rfv /etc/exports{,.d} fi @@ -13366,6 +13514,7 @@ _EOF_ rm -R /etc/systemd/system/noip2.service* fi + [[ -d '/etc/systemd/system/noip2.service.d' ]] && rm -R /etc/systemd/system/noip2.service.d [[ -f '/usr/local/bin/noip2' ]] && rm /usr/local/bin/noip2 [[ -f '/usr/local/etc/no-ip2.conf' ]] && rm /usr/local/etc/no-ip2.conf @@ -13483,14 +13632,13 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - #apt-mark auto libpcre3-dev libssl-dev zlib1g-dev libsystemd-dev &> /dev/null if [[ -f '/etc/systemd/system/haproxy.service' ]]; then systemctl disable --now haproxy rm -R /etc/systemd/system/haproxy.service* fi - rm -Rf /{etc,var/lib,/usr/local/{doc,sbin}}/haproxy /usr/local/share/man/man1/haproxy.1 + rm -Rf /{etc,var/lib,/usr/local/{doc,sbin}}/haproxy /usr/local/share/man/man1/haproxy.1 /etc/systemd/system/haproxy.service.d fi @@ -13713,7 +13861,6 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - #apt-mark auto libnl-3-200 libssl1.0.0 &> /dev/null G_AGP hostapd isc-dhcp-server [[ -f '/etc/dhcp/dhcpd.conf' ]] && rm /etc/dhcp/dhcpd.conf @@ -13781,13 +13928,21 @@ _EOF_ fi - software_id=99 + software_id=99 # EmonPi if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - rm -R /etc/emonhub - rm /etc/init.d/emonhub - rm /etc/default/emonhub + if [[ -f '/etc/init.d/emonhub' ]]; then + + systemctl unmask emonhub + systemctl disable --now emonhub + rm /etc/init.d/emonhub + update-rc.d -f emonhub remove + + fi + [[ -d '/etc/systemd/system/emonhub.service.d' ]] && rm -R /etc/systemd/system/emonhub.service.d + [[ -f '/etc/default/emonhub' ]] && rm /etc/default/emonhub + [[ -d '/etc/emonhub' ]] && rm -R /etc/emonhub fi @@ -13825,7 +13980,6 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - #apt-mark auto zlib1g-dev &> /dev/null # 1.2.0+ G_AGP netdata @@ -13891,17 +14045,19 @@ _EOF_ fi - software_id=52 + software_id=52 # Cuberite if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling if [[ -f '/etc/systemd/system/cuberite.service' ]]; then systemctl disable --now cuberite - rm /etc/systemd/system/cuberite.service + rm -R /etc/systemd/system/cuberite.service* fi - getent passwd cuberite &> /dev/null && userdel -rf cuberite + [[ -d '/etc/systemd/system/cuberite.service.d' ]] && rm -R /etc/systemd/system/cuberite.service.d + getent passwd cuberite > /dev/null && userdel -rf cuberite + getent group cuberite > /dev/null && groupdel cuberite [[ -f '/etc/cuberite' ]] && rm -R /etc/cuberite # pre v6.11 [[ -d $G_FP_DIETPI_USERDATA/cubrite ]] && rm -R $G_FP_DIETPI_USERDATA/cubrite @@ -13953,13 +14109,15 @@ _EOF_ if [[ -f '/etc/systemd/system/qbittorrent.service' ]]; then systemctl disable --now qbittorrent - rm -R /etc/systemd/system/qbittorrent.service* + G_EXEC_NOHALT=1 G_EXEC rm -R /etc/systemd/system/qbittorrent.service* fi + [[ -d '/etc/systemd/system/qbittorrent.service.d' ]] && G_EXEC_NOHALT=1 G_EXEC rm -R /etc/systemd/system/qbittorrent.service.d G_AGP qbittorrent-nox - getent passwd qbittorrent &> /dev/null && userdel -rf qbittorrent - getent group qbittorrent &> /dev/null && groupdel qbittorrent # pre-v6.29 - [[ -d '/home/qbittorrent' ]] && rm -R /home/qbittorrent + getent passwd qbittorrent > /dev/null && userdel -rf qbittorrent + getent group qbittorrent > /dev/null && groupdel qbittorrent # pre-v6.29 + [[ -d '/home/qbittorrent' ]] && G_EXEC_NOHALT=1 G_EXEC rm -R /home/qbittorrent + [[ -d '/var/log/qbittorrent' ]] && G_EXEC_NOHALT=1 G_EXEC rm -R /var/log/qbittorrent fi @@ -13980,7 +14138,7 @@ _EOF_ fi - software_id=116 + software_id=116 # Medusa if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -13990,9 +14148,9 @@ _EOF_ rm -R /etc/systemd/system/medusa.service* fi + [[ -d '/etc/systemd/system/medusa.service.d' ]] && rm -R /etc/systemd/system/medusa.service.d [[ -d $G_FP_DIETPI_USERDATA/medusa ]] && rm -R $G_FP_DIETPI_USERDATA/medusa getent passwd medusa &> /dev/null && userdel -rf medusa - #apt-mark auto python python3 mediainfo libssl-dev fi @@ -14065,7 +14223,6 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - #apt-mark auto libgnome-keyring0 libnspr4 libnss3 libnss3-1d libspeechd2 libxslt1.1 libxss1 xdg-utils libgnome-keyring-common libltdl7 &> /dev/null rm /etc/chromium.d/custom_flags rm /var/lib/dietpi/dietpi-software/installed/chromium-autostart.sh @@ -14079,8 +14236,6 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - #apt-mark auto gcc libc6-dev make zlib1g-dev libbz2-dev libreadline-dev libssl-dev libsqlite3-dev libffi-dev - # Pre-v6.27: cmake daemon gcc nmap net-tools swig uuid-dev libc-ares-dev libgnutls28-dev libgnutlsxx28 libglib2.0-dev libudev-dev libusb-1.0-0 libssl-dev libffi-dev libbz2-dev zlib1g-dev libreadline-dev libsqlite3-dev libncurses5-dev libncursesw5-dev # Remove the service if [[ -f '/etc/systemd/system/home-assistant.service' ]]; then @@ -14089,6 +14244,7 @@ _EOF_ rm -R /etc/systemd/system/home-assistant.service* fi + [[ -d '/etc/systemd/system/home-assistant.service.d' ]] && rm -R /etc/systemd/system/home-assistant.service.d # Remove the user and all files which removes his home + pyenv incl. HA as well getent passwd homeassistant &> /dev/null && userdel -rf homeassistant @@ -14165,7 +14321,7 @@ _EOF_ fi - software_id=169 + software_id=169 # Google AIY if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -14184,8 +14340,8 @@ _EOF_ # Service if [[ -f '/etc/systemd/system/mycroft.service' ]]; then - systemctl disable mycroft - rm /etc/systemd/system/mycroft.service + systemctl disable --now mycroft + rm -R /etc/systemd/system/mycroft.service* fi [[ -d '/etc/systemd/system/mycroft.service.d' ]] && rm -R /etc/systemd/system/mycroft.service.d @@ -14202,16 +14358,16 @@ _EOF_ fi - software_id=100 + software_id=100 # PiJuice if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling G_AGP pijuice-base - rm -R /var/lib/dietpi/dietpi-software/installed/pijuice + [[ -d '/var/lib/dietpi/dietpi-software/installed/pijuice' ]] && G_EXEC_NOHALT=1 G_EXEC rm -R /var/lib/dietpi/dietpi-software/installed/pijuice fi - software_id=158 + software_id=158 # Minio if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -14292,8 +14448,8 @@ _EOF_ rm -R /etc/systemd/system/gmrender.service* fi + [[ -d '/etc/systemd/system/gmrender.service.d' ]] && rm -R /etc/systemd/system/gmrender.service.d getent passwd gmrender &> /dev/null && userdel -rf gmrender - #apt-mark auto libupnp6 libupnp13 gstreamer1.0-alsa gstreamer1.0-libav gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly 2> /dev/null [[ -f '/usr/local/bin/gmediarender' ]] && rm /usr/local/bin/gmediarender fi @@ -14343,8 +14499,10 @@ _EOF_ rm -R /lib/systemd/system/influxdb.service* fi + [[ -d '/etc/systemd/system/influxdb.service.d' ]] && rm -R /etc/systemd/system/influxdb.service.d G_AGP influxdb [[ -f '/etc/apt/sources.list.d/influxdb.list' ]] && rm /etc/apt/sources.list.d/influxdb.list + [[ -f '/etc/apt/trusted.gpg.d/dietpi-influxdb.gpg' ]] && rm /etc/apt/trusted.gpg.d/dietpi-influxdb.gpg rm -Rf /var/lib/influxdb # Symlink [[ -d $G_FP_DIETPI_USERDATA/influxdb ]] && rm -R $G_FP_DIETPI_USERDATA/influxdb @@ -14357,8 +14515,9 @@ _EOF_ G_AGP grafana [[ -f '/etc/apt/sources.list.d/grafana.list' ]] && rm /etc/apt/sources.list.d/grafana.list - getent passwd grafana &> /dev/null && userdel -rf grafana - rm -Rf {$G_FP_DIETPI_USERDATA,/var/lib,/var/log,/etc}/grafana + [[ -f '/etc/apt/trusted.gpg.d/dietpi-grafana.gpg' ]] && rm /etc/apt/trusted.gpg.d/dietpi-grafana.gpg + getent passwd grafana > /dev/null && userdel -rf grafana + rm -Rfv {$G_FP_DIETPI_USERDATA,/var/lib,/var/log,/etc}/grafana /etc/systemd/system/grafana.service.d fi @@ -14373,24 +14532,54 @@ _EOF_ rm -R /etc/systemd/system/ubooquity.service* fi - getent passwd ubooquity &> /dev/null && userdel -rf ubooquity - getent group ubooquity &> /dev/null && groupdel ubooquity - [[ -d $G_FP_DIETPI_USERDATA/ubooquity ]] && rm -R $G_FP_DIETPI_USERDATA/ubooquity + [[ -d '/etc/systemd/system/ubooquity.service.d' ]] && G_EXEC_NOHALT=1 G_EXEC rm -R /etc/systemd/system/ubooquity.service.d + getent passwd ubooquity > /dev/null && userdel -rf ubooquity + getent group ubooquity > /dev/null && groupdel ubooquity + [[ -d $G_FP_DIETPI_USERDATA/ubooquity ]] && G_EXEC_NOHALT=1 G_EXEC rm -R $G_FP_DIETPI_USERDATA/ubooquity fi - software_id=86 + software_id=179 # Komga if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - UNINSTALL_URL_ADDRESS='https://github.com/TheAppgineer/roon-extension-manager-packaging/raw/master/linux/setup.sh' + if [[ -f '/etc/systemd/system/komga.service' ]]; then + + systemctl disable --now komga + rm -R /etc/systemd/system/komga.service* + + fi + [[ -d '/etc/systemd/system/komga.service.d' ]] && G_EXEC_NOHALT=1 G_EXEC rm -R /etc/systemd/system/komga.service.d + getent passwd komga > /dev/null && userdel -rf komga + getent group komga > /dev/null && groupdel komga + [[ -d $G_FP_DIETPI_USERDATA/komga ]] && G_EXEC_NOHALT=1 G_EXEC rm -R $G_FP_DIETPI_USERDATA/komga + + fi + + software_id=86 # Roon Extension Manager + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + + Banner_Uninstalling + UNINSTALL_URL_ADDRESS='https://raw.githubusercontent.com/TheAppgineer/roon-extension-manager-packaging/master/linux/setup.sh' G_CHECK_URL "$UNINSTALL_URL_ADDRESS" + G_EXEC curl -sSfL "$UNINSTALL_URL_ADDRESS" -o setup.sh + G_EXEC chmod +x setup.sh + G_EXEC_OUTPUT=1 G_EXEC ./setup.sh --uninstall + G_EXEC_NOHALT=1 G_EXEC rm setup.sh - wget -O setup.sh "$UNINSTALL_URL_ADDRESS" - chmod +x setup.sh - ./setup.sh --uninstall - rm setup.sh + fi + + software_id=178 # Jellyfin + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + + Banner_Uninstalling + G_AGP jellyfin jellyfin-ffmpeg + rm -f /usr/bin/jellyfin # Symlink created but left on package purge + [[ -f '/etc/apt/sources.list.d/dietpi-jellyfin.list' ]] && G_EXEC_NOHALT=1 G_EXEC rm /etc/apt/sources.list.d/dietpi-jellyfin.list + [[ -f '/etc/apt/trusted.gpg.d/dietpi-jellyfin.gpg' ]] && G_EXEC_NOHALT=1 G_EXEC rm /etc/apt/trusted.gpg.d/dietpi-jellyfin.gpg + [[ -d '/etc/systemd/system/jellyfin.service.d' ]] && G_EXEC_NOHALT=1 G_EXEC rm -R /etc/systemd/system/jellyfin.service.d + [[ -d $G_FP_DIETPI_USERDATA/jellyfin ]] && G_EXEC_NOHALT=1 G_EXEC rm -R $G_FP_DIETPI_USERDATA/jellyfin fi @@ -14478,7 +14667,7 @@ _EOF_ fi - software_id=0 + software_id=0 # OpenSSH Client if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -14513,6 +14702,7 @@ _EOF_ rm -R /etc/systemd/system/urbackupsrv.service* fi + [[ -d '/etc/systemd/system/urbackupsrv.service.d' ]] && rm -R /etc/systemd/system/urbackupsrv.service.d [[ -d $G_FP_DIETPI_USERDATA/urbackup ]] && rm -R $G_FP_DIETPI_USERDATA/urbackup [[ -d '/usr/share/urbackup' ]] && rm -R /usr/share/urbackup [[ -d '/usr/local/share/urbackup' ]] && rm -R /usr/local/share/urbackup @@ -14531,13 +14721,8 @@ _EOF_ Banner_Uninstalling umount -f /mnt/nfs_client - #nfs-kernel-server depends on nfs-common - if (( ${aSOFTWARE_INSTALL_STATE[109]} == 0 )); then - - G_AGP nfs-common - #apt-mark auto netbase - - fi + # nfs-kernel-server depends on nfs-common + (( ${aSOFTWARE_INSTALL_STATE[109]} == 0 )) && G_AGP nfs-common # Disable in fstab sed -i '/\/mnt\/nfs_client/c\#\/mnt\/nfs_client . Please use DietPi-Drive_Manager to setup this mount' /etc/fstab @@ -14555,7 +14740,7 @@ _EOF_ fi - software_id=17 + software_id=17 # Git Client if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -14563,7 +14748,7 @@ _EOF_ fi - software_id=5 + software_id=5 # ALSA if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -14575,8 +14760,8 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - apt-mark auto $(dpkg --get-selections x11-* dbus-x11 libgl1-mesa-dri mesa-* libdrm-rockchip1 libmali-rk-utgard-450-r7p0 xf86-video-* malit628-odroid mali450-odroid aml-libs-odroid libump* firmware-samsung 2> /dev/null | mawk '{print $1}') - G_AGP xorg* xserver-xorg* xinit xcompmgr xterm xfonts-base + apt-mark auto $(dpkg --get-selections 'x11-*' dbus-x11 libgl1-mesa-dri 'mesa-*' libdrm-rockchip1 libmali-rk-utgard-450-r7p0 'xf86-video-*' malit628-odroid mali450-odroid aml-libs-odroid 'libump*' firmware-samsung 2> /dev/null | mawk '{print $1}') + G_AGP 'xorg*' 'xserver-xorg*' xinit xcompmgr xterm xfonts-base rm -f /etc/xdg/autostart/xcompmgr.desktop /etc/X11/xorg.conf /etc/X11/xorg.conf.d/99-dietpi-dpms_off.conf fi @@ -14593,7 +14778,7 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - apt-mark auto $(dpkg --get-selections default-jre* default-jdk* openjdk-* ca-certificates-java 2> /dev/null | mawk '{print $1}') + apt-mark auto $(dpkg --get-selections 'default-jre*' 'default-jdk*' 'openjdk-*' ca-certificates-java 2> /dev/null | mawk '{print $1}') fi @@ -14601,18 +14786,15 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - G_AGP dropbear* + G_AGP 'dropbear*' fi - software_id=105 + software_id=105 # OpenSSH Server if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - G_AGP openssh-* - - # This also clears OpenSSH client - aSOFTWARE_INSTALL_STATE[0]=0 + G_AGP openssh-{,sftp-}server fi @@ -14626,14 +14808,13 @@ _EOF_ cat << _EOF_ > /etc/systemd/system/dietpi-ramlog_disable.service [Unit] Description=DietPi-RAMlog_disable | Disables DietPi-RAMlog after it has restored log metadata back to /var/log -After=dietpi-ramlog.service dietpi-ramdisk.service -Requires=dietpi-ramdisk.service +After=dietpi-ramlog.service Before=dietpi-preboot.service rsyslog.service syslog.service [Service] Type=oneshot StandardOutput=tty -ExecStart=/bin/dash -c '/var/lib/dietpi/dietpi-ramlog/disable.sh 2>&1 > /var/tmp/dietpi/logs/dietpi-ramlog_disable_debug.log' +ExecStart=/bin/dash -c '/var/lib/dietpi/dietpi-ramlog/disable.sh > /var/tmp/dietpi/logs/dietpi-ramlog_disable_debug.log 2>&1' [Install] WantedBy=local-fs.target @@ -14657,7 +14838,7 @@ _EOF_ fi - software_id=101 + software_id=101 # Logrotate if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling @@ -14665,11 +14846,12 @@ _EOF_ fi - software_id=102 + software_id=102 # Rsyslog if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then Banner_Uninstalling - G_AGP rsyslog + G_DIETPI-NOTIFY 2 'Marking rsyslog for autoremoval, hence it stays installed if any other package depends on it' + apt-mark auto rsyslog # https://github.com/MichaIng/DietPi/issues/2454 fi @@ -14716,12 +14898,21 @@ _EOF_ fi + software_id=130 # Python3 pip + if (( ${aSOFTWARE_INSTALL_STATE[$software_id]} == -1 )); then + + Banner_Uninstalling + pip3 uninstall -y pip + G_AGP python3-pip # Pre-v6.32 + + fi + G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Finalise uninstall' # Uninstall finished, set all uninstalled software to state 0 (not installed) # - Apply same states to Allo and Allo_update (( ${aSOFTWARE_INSTALL_STATE[159]} == -1 || ${aSOFTWARE_INSTALL_STATE[160]} == -1 )) && { aSOFTWARE_INSTALL_STATE[159]=0; aSOFTWARE_INSTALL_STATE[160]=0; } - for i in ${!aSOFTWARE_INSTALL_STATE[@]} + for i in "${!aSOFTWARE_INSTALL_STATE[@]}" do (( ${aSOFTWARE_INSTALL_STATE[$i]} == -1 )) && aSOFTWARE_INSTALL_STATE[$i]=0 @@ -14840,7 +15031,7 @@ _EOF_ # Install finished, set all installed software to state 2 (installed) # - Apply same states to Allo and Allo_update (( ${aSOFTWARE_INSTALL_STATE[159]} == 1 || ${aSOFTWARE_INSTALL_STATE[160]} == 1 )) && { aSOFTWARE_INSTALL_STATE[159]=2; aSOFTWARE_INSTALL_STATE[160]=2; } - for i in ${!aSOFTWARE_NAME[@]} + for i in "${!aSOFTWARE_NAME[@]}" do (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && aSOFTWARE_INSTALL_STATE[$i]=2 @@ -14908,7 +15099,7 @@ _EOF_ /boot/dietpi/dietpi-autostart $AUTOINSTALL_AUTOSTARTTARGET # Set Install Stage to Finished - export G_DIETPI_INSTALL_STAGE=2 + G_DIETPI_INSTALL_STAGE=2 echo $G_DIETPI_INSTALL_STAGE > /boot/dietpi/.install_stage fi @@ -15005,9 +15196,8 @@ _EOF_ for i in $input do - # - Check if input software ID exists, install state was defined - if disable_error=1 G_CHECK_VALIDINT "$i" 0 && - disable_error=1 G_CHECK_VALIDINT "${aSOFTWARE_INSTALL_STATE[$i]}"; then + # Check if input software ID exists, install state was defined + if disable_error=1 G_CHECK_VALIDINT "$i" 0 && disable_error=1 G_CHECK_VALIDINT "${aSOFTWARE_INSTALL_STATE[$i]}"; then if [[ $1 == 'uninstall' ]]; then @@ -15108,7 +15298,7 @@ _EOF_ # List software IDs, names and additional info elif [[ $1 == 'list' ]]; then - for i in ${!aSOFTWARE_NAME[@]} + for i in "${!aSOFTWARE_NAME[@]}" do local string="\e[0mID $i | " @@ -15119,7 +15309,6 @@ _EOF_ (( ${aSOFTWARE_REQUIRES_ALSA[$i]:=0} == 1 )) && string+=' +ALSA' (( ${aSOFTWARE_REQUIRES_XSERVERXORG[$i]:=0} == 1 )) && string+=' +XSERVER' (( ${aSOFTWARE_REQUIRES_DESKTOP[$i]:=0} == 1 )) && string+=' +DESKTOP' - (( ${aSOFTWARE_REQUIRES_RSYSLOG[$i]:=0} == 1 )) && string+=' +RSYSLOG' (( ${aSOFTWARE_REQUIRES_FFMPEG[$i]:=0} == 1 )) && string+=' +FFMPEG' (( ${aSOFTWARE_REQUIRES_JAVA_JRE_JDK[$i]:=0} == 1 )) && string+=' +JAVA' (( ${aSOFTWARE_REQUIRES_NODEJS[$i]:=0} == 1 )) && string+=' +NODEJS' @@ -15159,7 +15348,7 @@ _EOF_ # Get highest software array index local max=0 - for max in ${!aSOFTWARE_NAME[@]}; do :; done + for max in "${!aSOFTWARE_NAME[@]}"; do :; done # Check for unused indices local free= @@ -15191,12 +15380,12 @@ _EOF_ if (( $input_mode == -1 )); then local search_string= # show all - display_software_menu=0 #prevent display of CHECKLIST if no results found + display_software_menu=0 # prevent display of CHECKLIST if no results found if G_WHIP_INPUTBOX 'Please enter a software title/index to search (eg: desktop/cloud/media/torrent)'; then G_WHIP_CHECKLIST_ARRAY=() search_string=$G_WHIP_RETURNED_VALUE - for i in ${!aSOFTWARE_NAME[@]} + for i in "${!aSOFTWARE_NAME[@]}" do if (( ${aSOFTWARE_AVAIL_G_HW_MODEL[$i,$G_HW_MODEL]:=1} && ${aSOFTWARE_AVAIL_G_HW_ARCH[$i,$G_HW_ARCH]:=1} && ${aSOFTWARE_AVAIL_G_DISTRO[$i,$G_DISTRO]:=1} )) && @@ -15206,13 +15395,7 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$i]} > 0 )); then selected='on' - - if (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )); then - - # Reset to 0. Menu checklists will apply back to 1 - aSOFTWARE_INSTALL_STATE[$i]=0 - - fi + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && aSOFTWARE_INSTALL_STATE[$i]=0 # Reset to 0. Menu checklists will apply back to 1 fi @@ -15255,7 +15438,7 @@ _EOF_ local category_enabled=0 # Now run through all available software - for j in ${!aSOFTWARE_CATEGORY_INDEX[@]} + for j in "${!aSOFTWARE_CATEGORY_INDEX[@]}" do # Check if this software matches the current category and software type for this menu. @@ -15275,22 +15458,22 @@ _EOF_ if (( ${aSOFTWARE_INSTALL_STATE[$j]} == 1 )); then - #Reset to 0. Menu checklists will apply back to 1 + # Reset to 0. Menu checklists will apply back to 1 aSOFTWARE_INSTALL_STATE[$j]=0 fi fi - # - Add category + # Add category if (( $category_enabled == 0 )); then - # - dietpi + # dietpi if (( $input_mode == 0 )); then G_WHIP_CHECKLIST_ARRAY+=('' "${aSOFTWARE_CATEGORIES_DIETPI[$i]}" 'off') - # - linux + # linux elif (( $input_mode == 1 )); then G_WHIP_CHECKLIST_ARRAY+=('' "${aSOFTWARE_CATEGORIES_LINUX[$i]}" 'off') @@ -15344,16 +15527,16 @@ _EOF_ # DietPi-Drive_Manager can be used to setup Samba/NFS shares with ease! if (( ${aSOFTWARE_INSTALL_STATE[1]} == 1 || ${aSOFTWARE_INSTALL_STATE[110]} == 1 )); then - G_WHIP_MSG "NFS/Samba client info:\n\nDietPi-Drive_Manager is a powerful tool which vastly simplifies the mounting of NFS and Samba shares.\n -Once $G_PROGRAM_NAME has finished installation, simply run 'dietpi-drive_manager' to setup required network mounts." + G_WHIP_MSG "NFS/Samba client info:\n\nDietPi-Drive_Manager is a powerful tool which vastly simplifies the mounting of NFS and Samba shares. +\nOnce $G_PROGRAM_NAME has finished installation, simply run 'dietpi-drive_manager' to setup required network mounts." fi # Gogs: Requires OpenSSH for ssh-keygen binary: https://github.com/MichaIng/DietPi/issues/442 if (( ${aSOFTWARE_INSTALL_STATE[49]} == 1 && $INDEX_SSHSERVER_TARGET != -2 )); then - if G_WHIP_YESNO "Gogs requires OpenSSH server to function.\n\nIf you continue, OpenSSH will be selected for install on your system. OpenSSH will also replace Dropbear (if currently installed).\n -Would you like to continue with the Gogs installation?"; then + if G_WHIP_YESNO "Gogs requires OpenSSH server to function.\n\nIf you continue, OpenSSH will be selected for install on your system. OpenSSH will also replace Dropbear (if currently installed). +\nWould you like to continue with the Gogs installation?"; then # - Use SSH target index to ensure Dropbear gets removed if installed. INDEX_SSHSERVER_TARGET=-2 @@ -15373,20 +15556,20 @@ Would you like to continue with the Gogs installation?"; then # Please let DietPi install them for you... if (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )); then - G_WHIP_MSG 'DietPi will automatically install a webserver stack (based on your Webserver Preference) when any software that requires a webserver is selected for installation (eg: ownCloud, Pi-hole etc).\n -It is highly recommended that you allow DietPi to do this for you, ensuring compatibility and stability across DietPi installed programs.\n\nPlease only select a webserver stack if you specifically require it, and, no other webserver stack is installed.\n -TLDR: You do NOT need to select a webserver stack for installation with DietPi. Its all automatic.' + G_WHIP_MSG 'DietPi will automatically install a webserver stack (based on your Webserver Preference) when any software that requires a webserver is selected for installation (eg: ownCloud, Pi-hole etc). +\nIt is highly recommended that you allow DietPi to do this for you, ensuring compatibility and stability across DietPi installed programs.\n\nPlease only select a webserver stack if you specifically require it, and, no other webserver stack is installed. +\nTLDR: You do NOT need to select a webserver stack for installation with DietPi. Its all automatic.' break fi done - # RPiCamInterface - warn user of locking out camera: https://github.com/MichaIng/DietPi/issues/249 + # RPi Cam Interface - warn user of locking out camera: https://github.com/MichaIng/DietPi/issues/249 if (( ${aSOFTWARE_INSTALL_STATE[59]} == 1 )); then - G_WHIP_MSG 'RPi Cam Control Interface will automatically start and activate the camera during boot. This will prevent other programs (eg: raspistill) from using the camera.\n -You can free up the camera by selecting "Stop Camera" from the web interface:\n - http://myip/rpicam' + 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' fi @@ -15397,7 +15580,8 @@ You can free up the camera by selecting "Stop Camera" from the web interface:\n # Grab key from dietpi.txt USER_EMONHUB_APIKEY_CURRENT=$(sed -n '/^[[:blank:]]*SOFTWARE_EMONHUB_APIKEY=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - while (( $USER_EMONHUB_APIKEY_COMPLETED == 0 )); do + while (( $USER_EMONHUB_APIKEY_COMPLETED == 0 )) + do if G_WHIP_INPUTBOX "EmonHUB/EmonPi:\n\nPlease enter the \"Write API KEY\":\n - Visit https://emoncms.org to register an account and login. - Select \"Setup\" from the top right of screen, then select \"My Account\"\n - Enter the \"Write API Key\" into the box below."; then @@ -15423,12 +15607,12 @@ You can free up the camera by selecting "Stop Camera" from the web interface:\n if (( ${aSOFTWARE_INSTALL_STATE[93]} == 1 )); then # Prompt for static IP - if G_WHIP_YESNO 'A static IP address is essential for Pi-hole installations. DietPi-Config can be used to quickly setup your static IP address.\n -If you have already setup your static IP, please ignore this message.\n\nWould you like to setup your static IP address now?'; then + if G_WHIP_YESNO 'A static IP address is essential for Pi-hole installations. DietPi-Config can be used to quickly setup your static IP address. +\nIf you have already setup your static IP, please ignore this message.\n\nWould you like to setup your static IP address now?'; then - G_WHIP_MSG 'DietPi-Config will now be launched. Simply select your Ethernet or Wifi connection from the menu to access the IP address settings.\n -The "copy current address to STATIC" menu option can be used to quickly setup your static IP. Please ensure you change the mode "DHCP" to "STATIC".\n -Once completed, select "Apply Save Changes", then exit DietPi-Config to resume setup.' + G_WHIP_MSG 'DietPi-Config will now be launched. Simply select your Ethernet or Wifi connection from the menu to access the IP address settings. +\nThe "copy current address to STATIC" menu option can be used to quickly setup your static IP. Please ensure you change the mode "DHCP" to "STATIC". +\nOnce completed, select "Apply Save Changes", then exit DietPi-Config to resume setup.' /boot/dietpi/dietpi-config 8 1 fi @@ -15498,8 +15682,8 @@ Once completed, select "Apply Save Changes", then exit DietPi-Config to resume s # Weaved/Remot3.it if (( ${aSOFTWARE_INSTALL_STATE[68]} == 1 )); then - G_WHIP_MSG 'Remot3.it requires you to create an online account, and, link it this device.\n -Once DietPi has completed your software installations, and rebooted, please follow the First Run tutorial link below:\nhttps://dietpi.com/phpbb/viewtopic.php?p=188#p188' + G_WHIP_MSG 'Remot3.it requires you to create an online account, and, link it this device. +\nOnce DietPi has completed your software installations, and rebooted, please follow the First Run tutorial link below:\nhttps://dietpi.com/phpbb/viewtopic.php?p=188#p188' fi @@ -15515,8 +15699,8 @@ Once DietPi has completed your software installations, and rebooted, please foll # - No-IP if (( ${aSOFTWARE_INSTALL_STATE[67]} == 1 )); then - if G_WHIP_YESNO 'No-IP can be setup and configured by using DietPi-Config. Would you like to complete this now? \n\n- Once finished, exit DietPi-Config to resume setup.\n - - More information:\nhttps://dietpi.com/phpbb/viewtopic.php?p=58#p58'; then + if G_WHIP_YESNO 'No-IP can be setup and configured by using DietPi-Config. Would you like to complete this now?\n\n - Once finished, exit DietPi-Config to resume setup. +\n - More information:\nhttps://dietpi.com/phpbb/viewtopic.php?p=58#p58'; then # Write installed states to temp Write_InstallFileList temp @@ -15555,8 +15739,8 @@ Once DietPi has completed your software installations, and rebooted, please foll ${aSOFTWARE_INSTALL_STATE[173]} == 1 )); then # Set Boot Order - G_WHIP_YESNO 'Would you like to configure the auto boot options for DietPi?\n -This will allow you to choose which program loads automatically, after the system has booted up, eg: + G_WHIP_YESNO 'Would you like to configure the auto boot options for DietPi? +\nThis will allow you to choose which program loads automatically, after the system has booted up, e.g.: - Console\n - Desktop\n - Kodi' && /boot/dietpi/dietpi-autostart fi @@ -15595,11 +15779,11 @@ This will allow you to choose which program loads automatically, after the syste local index_logging_text='None' if (( $INDEX_LOGGING_TARGET == -1 )); then - index_logging_text='DietPi-Ramlog #1' + index_logging_text='DietPi-RAMlog #1' elif (( $INDEX_LOGGING_TARGET == -2 )); then - index_logging_text='DietPi-Ramlog #2' + index_logging_text='DietPi-RAMlog #2' elif (( $INDEX_LOGGING_TARGET == -3 )); then @@ -15708,10 +15892,10 @@ This will allow you to choose which program loads automatically, after the syste G_WHIP_DEFAULT_ITEM=$index_sshserver_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Please select desired SSH server:\n -- None: Selecting this option will uninstall all SSH servers. This reduces system resources and improves performance. Useful for users who do NOT require networked/remote terminal access.\n -- Dropbear (Recommended): Lightweight SSH server, installed by default on DietPi systems.\n -- OpenSSH: A feature rich SSH server with SFTP/SCP support, at the cost of increased resource usage.'; then + if G_WHIP_MENU 'Please select desired SSH server: +\n- None: Selecting this option will uninstall all SSH servers. This reduces system resources and improves performance. Useful for users who do NOT require networked/remote terminal access. +\n- Dropbear (Recommended): Lightweight SSH server, installed by default on DietPi systems. +\n- OpenSSH: A feature rich SSH server with SFTP/SCP support, at the cost of increased resource usage.'; then # Assign target index if [[ $G_WHIP_RETURNED_VALUE == 'None' ]]; then @@ -15761,10 +15945,11 @@ This will allow you to choose which program loads automatically, after the syste G_WHIP_DEFAULT_ITEM=$index_fileserver_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Please select desired fileserver:\n -- None: Select this option if you do NOT require a method of accessing files and folders on this device, over a network.\n -- ProFTPD (Recommended for RPi v1): Allows you to access/share files on this device efficiently with minimal cpu usage. Uses FTP protocol.\n -- Samba (Recommended for RPi v2): Allows you to easily access/share files on this device, at the cost of higher cpu usage.\n\nMore info: https://dietpi.com/phpbb/viewtopic.php?f=8&t=15#p19'; then + if G_WHIP_MENU 'Please select desired fileserver: +\n- None: Select this option if you do NOT require a method of accessing files and folders on this device, over a network. +\n- ProFTPD (Recommended for RPi v1): Allows you to access/share files on this device efficiently with minimal cpu usage. Uses FTP protocol. +\n- Samba (Recommended for RPi v2): Allows you to easily access/share files on this device, at the cost of higher cpu usage. +\nMore info: https://dietpi.com/phpbb/viewtopic.php?p=19#p19'; then # Assign target index if [[ $G_WHIP_RETURNED_VALUE == 'None' ]]; then @@ -15807,32 +15992,32 @@ This will allow you to choose which program loads automatically, after the syste G_WHIP_MENU_ARRAY=( 'None' ': Not required / manual setup' - 'DietPi-Ramlog #1' ': Hourly clear (recommended)' - 'DietPi-Ramlog #2' ': Hourly save, then clear' + 'DietPi-RAMlog #1' ': Hourly clear (recommended)' + 'DietPi-RAMlog #2' ': Hourly save, then clear' 'Full' ': Logrotate and Rsyslog' ) G_WHIP_DEFAULT_ITEM=$index_logging_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Please select desired logging system:\n -- None: Selecting this option will uninstall DietPi-Ramlog, Logrotate, Rsyslog.\n -- DietPi-Ramlog #1 (Max performance): Mounts /var/log to RAM, reducing filesystem IO. Logfiles are cleared every hour. Does NOT save logfiles to disk.\n -- DietPi-Ramlog #2: Same as #1, with the added feature of saving logfile contents to disk (/root/logfile_storage/*), before being cleared.\n -- Full (Reduces performance): Mounts /var/log to DISK, reduces SDcard lifespan. Full logging system with Logrotate and Rsyslog.'; then + if G_WHIP_MENU 'Please select desired logging system: +\n- None: Selecting this option will uninstall DietPi-RAMlog, Logrotate, Rsyslog. +\n- DietPi-RAMlog #1 (Max performance): Mounts /var/log to RAM, reducing filesystem IO. Logfiles are cleared every hour. Does NOT save logfiles to disk. +\n- DietPi-RAMlog #2: Same as #1, with the added feature of saving logfile contents to disk (/root/logfile_storage/*), before being cleared. +\n- Full (Reduces performance): Mounts /var/log to DISK, reduces SDcard lifespan. Full logging system with Logrotate and Rsyslog.'; then # Assign target index if [[ $G_WHIP_RETURNED_VALUE == 'None' ]]; then INDEX_LOGGING_TARGET=0 - toberemoved_text='DietPi-Ramlog, Logrotate, Rsyslog' + toberemoved_text='DietPi-RAMlog, Logrotate, Rsyslog' - elif [[ $G_WHIP_RETURNED_VALUE == 'DietPi-Ramlog #1' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'DietPi-RAMlog #1' ]]; then INDEX_LOGGING_TARGET=-1 toberemoved_text='Logrotate, Rsyslog' - elif [[ $G_WHIP_RETURNED_VALUE == 'DietPi-Ramlog #2' ]]; then + elif [[ $G_WHIP_RETURNED_VALUE == 'DietPi-RAMlog #2' ]]; then INDEX_LOGGING_TARGET=-2 toberemoved_text='Logrotate, Rsyslog' @@ -15840,7 +16025,7 @@ This will allow you to choose which program loads automatically, after the syste elif [[ $G_WHIP_RETURNED_VALUE == 'Full' ]]; then INDEX_LOGGING_TARGET=-3 - toberemoved_text='DietPi-Ramlog' + toberemoved_text='DietPi-RAMlog' # Reset to current else @@ -15876,8 +16061,9 @@ This will allow you to choose which program loads automatically, after the syste ) G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Choose where to store your user data. User data includes software such as ownCloud data store, BitTorrent downloads etc.\n -More information on user data in DietPi:\n- https://dietpi.com/phpbb/viewtopic.php?p=2087\n\n- DietPi-Drive_Manager: Launch DietPi-Drive_Manager to setup external drives, and, move user data to different locations.'; then + if G_WHIP_MENU 'Choose where to store your user data. User data includes software such as ownCloud data store, BitTorrent downloads etc. +\nMore information on user data in DietPi:\n- https://dietpi.com/phpbb/viewtopic.php?p=2087 +\n- DietPi-Drive_Manager: Launch DietPi-Drive_Manager to setup external drives, and, move user data to different locations.'; then # DriveMan if [[ $G_WHIP_RETURNED_VALUE == 'Drive' ]]; then @@ -15948,10 +16134,10 @@ More information on user data in DietPi:\n- https://dietpi.com/phpbb/viewtopic.p G_WHIP_DEFAULT_ITEM=$index_webserver_text G_WHIP_BUTTON_CANCEL_TEXT='Back' - if G_WHIP_MENU 'Please select a Webserver preference, more info https://dietpi.com/phpbb/viewtopic.php?p=1549#p1549:\n -- Apache2: Feature-rich and popular. Recommended for beginners and users who are looking to follow Apache2 based guides.\n -- Nginx: Lightweight alternative to Apache2. Nginx claims faster webserver performance compared to Apache2.\n -- Lighttpd: Extremely lightweight and is generally considered to offer the \"best\" webserver performance for SBCs. Recommended for users who expect low webserver traffic.'; then + if G_WHIP_MENU 'Please select a Webserver preference, more info https://dietpi.com/phpbb/viewtopic.php?p=1549#p1549: +\n- Apache2: Feature-rich and popular. Recommended for beginners and users who are looking to follow Apache2 based guides. +\n- Nginx: Lightweight alternative to Apache2. Nginx claims faster webserver performance compared to Apache2. +\n- Lighttpd: Extremely lightweight and is generally considered to offer the \"best\" webserver performance for SBCs. Recommended for users who expect low webserver traffic.'; then # Assign target index if [[ $G_WHIP_RETURNED_VALUE == 'Apache2' ]]; then @@ -16006,15 +16192,15 @@ More information on user data in DietPi:\n- https://dietpi.com/phpbb/viewtopic.p INDEX_WEBSERVER_TARGET=$INDEX_WEBSERVER_CURRENT # Inform user - G_WHIP_MSG "Error: Incompatible Webserver Preference:\n\nUnable to change your webserver preference to $G_WHIP_RETURNED_VALUE.\n -This is due to an existing and incompatible webserver installation on your system ($info_currently_installed_webserver). Please remove all webserver based software (using dietpi-software > uninstall), before trying again." + G_WHIP_MSG "Error: Incompatible Webserver Preference:\n\nUnable to change your webserver preference to $G_WHIP_RETURNED_VALUE. +\nThis is due to an existing and incompatible webserver installation on your system ($info_currently_installed_webserver). Please remove all webserver based software (using dietpi-software > uninstall), before trying again." # Apply preference selection else # Inform user - G_WHIP_MSG "Webserver Preference Changed:\n\n$G_WHIP_RETURNED_VALUE has been selected as your webserver preference.\n -When you select any software for install that requires a webserver, DietPi will automatically install your prefered choice ($G_WHIP_RETURNED_VALUE)." + G_WHIP_MSG "Webserver Preference Changed:\n\n$G_WHIP_RETURNED_VALUE has been selected as your webserver preference. +\nWhen you select any software for install that requires a webserver, DietPi will automatically install your prefered choice ($G_WHIP_RETURNED_VALUE)." # NB: INDEX_WEBSERVER_CURRENT=$INDEX_WEBSERVER_TARGET | is applied during installation with func Apply_Webserver_Preference(). fi @@ -16048,13 +16234,12 @@ List of installed software and their URL links for online docs: ───────────────────────────────────────────────────────────────\n' # Installed software - for i in ${!aSOFTWARE_INSTALL_STATE[@]} + for i in "${!aSOFTWARE_INSTALL_STATE[@]}" do if (( ${aSOFTWARE_INSTALL_STATE[i]} > 0 )) && [[ ${aSOFTWARE_ONLINEDOC_URL[$i]} ]]; then - string+="\n${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" - string+="\n$FP_ONLINEDOC_URL${aSOFTWARE_ONLINEDOC_URL[$i]}\n" + string+="\n${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}\n$FP_ONLINEDOC_URL${aSOFTWARE_ONLINEDOC_URL[$i]}\n" fi @@ -16095,12 +16280,10 @@ List of installed software and their URL links for online docs: # Standard exit elif (( $G_DIETPI_INSTALL_STAGE == 2 )); then - if G_WHIP_YESNO 'Do you wish to exit DietPi-Software?\n\nAll changes to software selections will be cleared.'; then + G_WHIP_YESNO 'Do you wish to exit DietPi-Software?\n\nAll changes to software selections will be cleared.' || return 0 - Banner_Aborted - exit 0 - - fi + Banner_Aborted + exit 0 fi @@ -16110,36 +16293,27 @@ List of installed software and their URL links for online docs: # Obtain list of pending software installation: local string_output - for i in ${!aSOFTWARE_INSTALL_STATE[@]} + for i in "${!aSOFTWARE_INSTALL_STATE[@]}" do - if (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )); then - - string_output+="\n - ${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" - - fi + (( ${aSOFTWARE_INSTALL_STATE[$i]} == 1 )) && string_output+="\n - ${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}" done - [[ $G_SERVICE_CONTROL == 0 ]] || string_output+='\nNB: Software services will be temporarily controlled (stopped) by DietPi during this process. Please inform connected users, before continuing. SSH is not affected.' + [[ $G_SERVICE_CONTROL == 0 ]] || string_output+='\nNB: Software services will be temporarily controlled (stopped) by DietPi during this process. Please inform connected users, before continuing. SSH and VNC is not affected.' # Confirm Software install - if G_WHIP_YESNO "DietPi is now ready to install your software choices: $string_output\n -Software details, usernames, passwords etc:\n - https://dietpi.com/software\n\nWould you like to begin?"; then - - TARGETMENUID=-1 # Exit menu loop - GOSTARTINSTALL=1 # Set install start flag + G_WHIP_YESNO "DietPi is now ready to install your software choices: $string_output +\nSoftware details, usernames, passwords etc:\n - https://dietpi.com/software\n\nWould you like to begin?" || return 0 - fi + TARGETMENUID=-1 # Exit menu loop + GOSTARTINSTALL=1 # Set install start flag } Menu_StartInstall(){ # Check if user made/changed software selections - if (( $INSTALL_SOFTWARE_CHOICESMADE || - $INSTALL_SSHSERVER_CHOICESMADE || - $INSTALL_FILESERVER_CHOICESMADE || - $INSTALL_LOGGING_CHOICESMADE )); then + if (( $INSTALL_SOFTWARE_CHOICESMADE || $INSTALL_SSHSERVER_CHOICESMADE || $INSTALL_FILESERVER_CHOICESMADE || $INSTALL_LOGGING_CHOICESMADE )); then # List selections and ask for confirmation Menu_ConfirmInstall @@ -16147,15 +16321,13 @@ Software details, usernames, passwords etc:\n - https://dietpi.com/software\n\nW # Allow to finish first run setup without any selections elif (( $G_DIETPI_INSTALL_STAGE == 1 )); then - if G_WHIP_YESNO 'DietPi was unable to detect any additional software selections for install.\n -NB: You can use dietpi-software at a later date, to install optimised software from our catalogue as required.\n -Do you wish to continue with DietPi as a pure minimal image?'; then - - TARGETMENUID=-1 # Exit menu loop - DISABLE_REBOOT=1 # Skip reboot as no software will be installed - GOSTARTINSTALL=1 # Set install start flag + G_WHIP_YESNO 'DietPi was unable to detect any additional software selections for install. +\nNB: You can use dietpi-software at a later date, to install optimised software from our catalogue as required. +\nDo you wish to continue with DietPi as a pure minimal image?' || return 0 - fi + TARGETMENUID=-1 # Exit menu loop + DISABLE_REBOOT=1 # Skip reboot as no software will be installed + GOSTARTINSTALL=1 # Set install start flag # After first run setup has finished, abort install without any selections elif (( $G_DIETPI_INSTALL_STAGE == 2 )); then @@ -16172,9 +16344,8 @@ Do you wish to continue with DietPi as a pure minimal image?'; then G_WHIP_CHECKLIST_ARRAY=() # Obtain list of installed software - local software_available_for_uninstall=0 - local i - for i in ${!aSOFTWARE_INSTALL_STATE[@]} + local i software_available_for_uninstall=0 + for i in "${!aSOFTWARE_INSTALL_STATE[@]}" do if (( ${aSOFTWARE_INSTALL_STATE[$i]} == 2 && ${aSOFTWARE_TYPE[$i]:=-2} > -2 )); then @@ -16198,49 +16369,44 @@ Do you wish to continue with DietPi as a pure minimal image?'; then if G_WHIP_CHECKLIST 'Use the spacebar to select the software you would like to remove:'; then # - Create list for user to review before removal - local output_string='The following software will be REMOVED from your system:\n' + local output_string='The following software will be REMOVED from your system:' for i in $G_WHIP_RETURNED_VALUE do - output_string+=" - ${aSOFTWARE_NAME[$i]}: ${aSOFTWARE_DESC[$i]}\n" + output_string+="\n - ${aSOFTWARE_NAME[$i]} (ID=$i): ${aSOFTWARE_DESC[$i]}" UNINSTALL_REQUIRED=1 done - [[ $G_SERVICE_CONTROL == 0 ]] || output_string+='\nNB: Software services will be temporarily controlled (stopped) by DietPi during this process. Please inform connected users, before continuing. SSH is not affected.' - - if (( $UNINSTALL_REQUIRED )); then - if G_WHIP_YESNO "$output_string\n\nDo you wish to continue?"; then + (( $UNINSTALL_REQUIRED )) || return 0 - # Stop services - [[ $G_SERVICE_CONTROL == 0 ]] || /boot/dietpi/dietpi-services stop + [[ $G_SERVICE_CONTROL == 0 ]] || output_string+='\n\nNB: Software services will be STOPPED by DietPi during this process. Please inform connected users, before continuing. SSH and VNC is not affected.' - # Mark for uninstall - for i in $G_WHIP_RETURNED_VALUE - do + G_WHIP_YESNO "$output_string +\nNB: Uninstalling usually PURGES any related userdata and configs. If you only need to repair or update software, please use \"dietpi-software reinstall \" instead. +\nDo you wish to continue?" || { UNINSTALL_REQUIRED=0; return 0; } - aSOFTWARE_INSTALL_STATE[$i]=-1 + # Stop services + [[ $G_SERVICE_CONTROL == 0 ]] || /boot/dietpi/dietpi-services stop - done - - # Run uninstall - Uninstall_Software - - # Save - Write_InstallFileList + # Mark for uninstall + for i in $G_WHIP_RETURNED_VALUE + do - # Start services - [[ $G_SERVICE_CONTROL == 0 ]] || /boot/dietpi/dietpi-services start + aSOFTWARE_INSTALL_STATE[$i]=-1 - G_WHIP_MSG 'Uninstall completed' + done - else + # Run uninstall + Uninstall_Software - UNINSTALL_REQUIRED=0 + # Save install states + Write_InstallFileList - fi + # Start services + [[ $G_SERVICE_CONTROL == 0 ]] || /boot/dietpi/dietpi-services start - fi + G_WHIP_MSG 'Uninstall completed' fi @@ -16352,8 +16518,8 @@ Do you wish to continue with DietPi as a pure minimal image?'; then # 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 + # - ROCKPro64: Fails to boot into kernel without + # - NanoPi NEO Air: Required for end users/debugging/setting up WiFi without automation 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 )) && @@ -16369,10 +16535,10 @@ Do you wish to continue with DietPi as a pure minimal image?'; then if [[ $keep_serial0 == 1 && -L '/dev/serial0' ]]; then - tty=$(readlink -f /dev/serial0); tty={tty#/dev/} - if [[ $( -1 )); do + while (( $TARGETMENUID > -1 )) + do G_TERM_CLEAR Menu_Main @@ -16429,13 +16596,10 @@ Do you wish to continue with DietPi as a pure minimal image?'; then # Unmask systemd-logind if set in dietpi.txt / libpam-systemd was installed / Kodi if [[ $(readlink /etc/systemd/system/systemd-logind.service) == '/dev/null' ]] && - { grep -q '^[[:blank:]]*AUTO_UNMASK_LOGIND=1' /boot/dietpi.txt || - dpkg-query -s 'libpam-systemd' &> /dev/null || - (( ${aSOFTWARE_INSTALL_STATE[31]} > 0 )); }; then + { grep -q '^[[:blank:]]*AUTO_UNMASK_LOGIND=1' /boot/dietpi.txt || dpkg-query -s 'libpam-systemd' &> /dev/null || (( ${aSOFTWARE_INSTALL_STATE[31]} > 0 )); }; then G_EXEC systemctl unmask systemd-logind - # systemd-logind is currently a static unit, but to be failsafe: - systemctl enable --now systemd-logind &> /dev/null + G_EXEC systemctl start systemd-logind fi diff --git a/dietpi/dietpi-sync b/dietpi/dietpi-sync index 99339a8cdd..5476c379ec 100644 --- a/dietpi/dietpi-sync +++ b/dietpi/dietpi-sync @@ -110,7 +110,7 @@ _EOF_ G_WHIP_MSG "[FAILED] Unable to pre-create target directory: $FP_TARGET\n\n\"mkdir\" reported the following error:\n$(<$FP_LOG)" # We cannot log to target dir, use $FP_LOG_ALT instead - echo "$(date +"%d-%m-%Y_%T") [FAILED] Unable to pre-create target directory: $FP_TARGET" >> $FP_LOG + echo "$(date +"%Y-%m-%d_%T") [FAILED] Unable to pre-create target directory: $FP_TARGET" >> $FP_LOG mv $FP_LOG $FP_LOG_ALT # Error: Empty source dir @@ -118,14 +118,14 @@ _EOF_ G_WHIP_MSG "[FAILED] The chosen source directory is empty: $FP_SOURCE\n\nPlease check it's path and in case verify that it's mount is active." # Log to target dir directly, preserve previous rsync log - echo "$(date +"%d-%m-%Y_%T") [FAILED] The chosen source directory is empty: $FP_SOURCE" >> "$FP_TARGET/$FP_LOG" + echo "$(date +"%Y-%m-%d_%T") [FAILED] The chosen source directory is empty: $FP_SOURCE" >> "$FP_TARGET/$FP_LOG" # Error: Rsync still running elif pgrep '[r]sync' &> /dev/null; then G_WHIP_MSG '[FAILED] Rsync is already running and failed to stop gracefully\n\nPlease check active rsync processes e.g. via "htop" and finish or kill them.' # Log to target dir directly, preserve previous rsync log - echo "$(date +"%d-%m-%Y_%T") [FAILED] Rsync is already running and failed to stop gracefully" >> "$FP_TARGET/$FP_LOG" + echo "$(date +"%Y-%m-%d_%T") [FAILED] Rsync is already running and failed to stop gracefully" >> "$FP_TARGET/$FP_LOG" # Start sync, beginning with dry run else @@ -162,7 +162,7 @@ _EOF_ if (( $INPUT == 1 )); then - echo "$(date +"%d-%m-%Y_%T") [FAILED] Insufficient free space" >> "$FP_TARGET/$FP_LOG" + echo "$(date +"%Y-%m-%d_%T") [FAILED] Insufficient free space" >> "$FP_TARGET/$FP_LOG" return 1 else @@ -219,12 +219,12 @@ Continue only if you know what you are doing and after checking the log!" if (( $EXIT_CODE )); then - echo "$(date +"%d-%m-%Y_%T") [FAILED] Please see the log file for more information: $FP_TARGET/$FP_LOG" >> $FP_LOG + echo "$(date +"%Y-%m-%d_%T") [FAILED] Please see the log file for more information: $FP_TARGET/$FP_LOG" >> $FP_LOG G_WHIP_MSG "[FAILED] $FP_SOURCE > $FP_TARGET\n\nYou will given an option to view the logfile on the next screen. Please check it for information and/or errors." else - echo "$(date +"%d-%m-%Y_%T") [ OK ] Sync completed" >> $FP_LOG + echo "$(date +"%Y-%m-%d_%T") [ OK ] Sync completed" >> $FP_LOG G_WHIP_MSG "[ OK ] Sync completed:\n - $FP_SOURCE > $FP_TARGET" fi @@ -276,11 +276,11 @@ _EOF_ MENU_LASTITEM_MAIN= Menu_Main(){ - SYNC_MODE_TEXT='[Off]' - (( $SYNC_DELETE_MODE )) && SYNC_MODE_TEXT='[On]' + SYNC_MODE_TEXT='Off' + (( $SYNC_DELETE_MODE )) && SYNC_MODE_TEXT='On' - SYNC_CRONDAILY_TEXT='[Off]' - (( $SYNC_CRONDAILY )) && SYNC_CRONDAILY_TEXT='[On]' + SYNC_CRONDAILY_TEXT='Off' + (( $SYNC_CRONDAILY )) && SYNC_CRONDAILY_TEXT='On' if [[ -f $FP_TARGET/$FP_LOG ]]; then @@ -303,8 +303,8 @@ _EOF_ '' '●─ Options ' 'Source Location' ": [$FP_SOURCE]" 'Target Location' ": [$FP_TARGET]" - 'Delete Mode' ": $SYNC_MODE_TEXT" - 'Daily Sync' ": $SYNC_CRONDAILY_TEXT" + 'Delete Mode' ": [$SYNC_MODE_TEXT]" + 'Daily Sync' ": [$SYNC_CRONDAILY_TEXT]" '' '●─ Run ' 'Dry run + Sync' ': Sync from Source to Target (Dry run included!)' @@ -479,18 +479,18 @@ More information:\n - https://dietpi.com/phpbb/viewtopic.php?p=256#p256' G_WHIP_MENU_ARRAY=( - '[Off]' ': Only add/update, but never remove data in target location' - '[On]' ': Sync removals from source to target as well => Exact copy' + 'Off' ': Only add/update, but never remove data in target location' + 'On' ': Sync removals from source to target as well => Exact copy' ) G_WHIP_DEFAULT_ITEM=$SYNC_MODE_TEXT if G_WHIP_MENU 'Please select the Sync delete mode.\n -[Off]: (safe)\nIf files and folders exist in the Target location, that are not in the Source, they will be left alone.\n -[On]: (WARNING, if in doubt, DO NOT enable)\nAn exact copy of the Source location will be created at the Target location. +Off: (safe)\nIf files and folders exist in the Target location, that are not in the Source, they will be left alone.\n +On: (WARNING, if in doubt, DO NOT enable)\nAn exact copy of the Source location will be created at the Target location. If files are in the Target location that do not exist in the Source, they will be DELETED.'; then - [[ $G_WHIP_RETURNED_VALUE == '[On]' ]] && SYNC_DELETE_MODE=1 || SYNC_DELETE_MODE=0 + [[ $G_WHIP_RETURNED_VALUE == 'On' ]] && SYNC_DELETE_MODE=1 || SYNC_DELETE_MODE=0 fi @@ -500,17 +500,17 @@ If files are in the Target location that do not exist in the Source, they will b G_WHIP_MENU_ARRAY=( - '[Off]' ': Manual sync only' - '[On]' ': Automatically sync once a day' + 'Off' ': Manual sync only' + 'On' ': Automatically sync once a day' ) 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 + 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 - [[ $G_WHIP_RETURNED_VALUE == '[On]' ]] && SYNC_CRONDAILY=1 || SYNC_CRONDAILY=0 + [[ $G_WHIP_RETURNED_VALUE == 'On' ]] && SYNC_CRONDAILY=1 || SYNC_CRONDAILY=0 fi diff --git a/dietpi/dietpi-update b/dietpi/dietpi-update index b6d52ae3ec..97f5fdd8c4 100644 --- a/dietpi/dietpi-update +++ b/dietpi/dietpi-update @@ -29,9 +29,6 @@ G_INIT # Import DietPi-Globals -------------------------------------------------------------- - # Move tmp log to persistent location on exit - G_EXIT_CUSTOM(){ [[ -f $FP_LOG_TMP ]] && mv $FP_LOG_TMP $FP_LOG; } - # Grab input disable_error=1 G_CHECK_VALIDINT "$1" && INPUT=$1 || INPUT=0 @@ -42,7 +39,6 @@ # UPDATE Vars #///////////////////////////////////////////////////////////////////////////////////// FP_LOG='/var/tmp/dietpi/logs/dietpi-update.log' - FP_LOG_TMP='dietpi-update.log' DIETPIUPDATE_VERSION_CORE=6 # Version of dietpi-update / set server_version-6 line one to value++ and obsolete previous dietpi-update scripts CHANGELOG_DOWNLOADED=0 # Prevent redownload of changelog if already done in this session @@ -168,8 +164,7 @@ If this error persists, please report at: https://github.com/MichaIng/DietPi/iss Please download the latest DietPi image from: https://dietpi.com/#download' # Update available - elif (( $G_DIETPI_VERSION_SUB < $SUBVERSION_SERVER || - ( $G_DIETPI_VERSION_SUB == $SUBVERSION_SERVER && $G_DIETPI_VERSION_RC < $RCVERSION_SERVER ) )); then + elif (( $G_DIETPI_VERSION_SUB < $SUBVERSION_SERVER || ( $G_DIETPI_VERSION_SUB == $SUBVERSION_SERVER && $G_DIETPI_VERSION_RC < $RCVERSION_SERVER ) )); then UPDATE_AVAILABLE=1 @@ -184,7 +179,7 @@ Please download the latest DietPi image from: https://dietpi.com/#download' # Mark 1st run update as completed Apply_1st_Run_Update_Success - # Remove .update_available flag file + # Remove flag file [[ -f '/run/dietpi/.update_available' ]] && rm /run/dietpi/.update_available G_DIETPI-NOTIFY 0 'No update required, your DietPi installation is already up to date:' @@ -425,7 +420,7 @@ Do you wish to continue and update DietPi to v$COREVERSION_SERVER.$SUBVERSION_SE # Run_Update: https://github.com/MichaIng/DietPi/issues/1877#issuecomment-403866204 # - Log to file by redirecting to subshell instead of piping, else G_EXEC cannot exit the script via "kill -INT $$": https://github.com/MichaIng/DietPi/issues/3127 - Run_Update &> >(tee $FP_LOG_TMP); wait $! + Run_Update &> >(tee $FP_LOG); wait $! # Mark 1st run update as completed Apply_1st_Run_Update_Success @@ -450,7 +445,7 @@ Do you wish to continue and update DietPi to v$COREVERSION_SERVER.$SUBVERSION_SE #---------------------------------------------------------------- # Desktop run, exit key prompt - pgrep 'lxsession' &> /dev/null && read -rp 'Press any key to exit DietPi-Update...' + pgrep 'lxsession' > /dev/null && read -rp 'Press any key to exit DietPi-Update...' fi #---------------------------------------------------------------- diff --git a/dietpi/func/create_mysql_db b/dietpi/func/create_mysql_db index a57a26108e..e2147672df 100644 --- a/dietpi/func/create_mysql_db +++ b/dietpi/func/create_mysql_db @@ -10,12 +10,9 @@ # - /boot/dietpi/func/create_mysql_db # # Drop database: - # - mysqladmin drop phpbb3 -f + # - mysqladmin -f drop phpbb3 #//////////////////////////////////// - DATABASE_NAME=$1 - DATABASE_USER=$2 - DATABASE_PW=$3 # Import DietPi-Globals -------------------------------------------------------------- . /boot/dietpi/func/dietpi-globals G_PROGRAM_NAME='DietPi-Create_MySQL_DB' @@ -23,27 +20,32 @@ G_INIT # Import DietPi-Globals -------------------------------------------------------------- + # Grab input + DATABASE_NAME=$1 + DATABASE_USER=$2 + DATABASE_PW=$3 + MESSAGE="Creating MariaDB database $DATABASE_NAME for user $DATABASE_USER" + #///////////////////////////////////////////////////////////////////////////////////// # Main Loop #///////////////////////////////////////////////////////////////////////////////////// # Skip database creation, if already existent - [[ -d '/var/lib/mysql/'$DATABASE_NAME ]] && G_DIETPI-NOTIFY 2 "\"$DATABASE_NAME\" MariaDB database already exists. Aborting..." && exit + [[ -d '/var/lib/mysql/'$DATABASE_NAME ]] && { G_DIETPI-NOTIFY 2 "MariaDB database $DATABASE_NAME already exists. Aborting..."; exit 0; } - # Start MySQL if not running. - systemctl start mariadb &> /dev/null + # Start MariaDB (No effect if running) + systemctl start mariadb - G_DIETPI-NOTIFY 2 "Creating MariaDB database: $DATABASE_NAME" + G_DIETPI-NOTIFY 2 "$MESSAGE" # Generate DB # - 'identified by' can overwrite unix_socket authentication, thus use this for non-root users only. - grant_privileges='' - [[ $DATABASE_USER == 'root' ]] || grant_privileges="grant all privileges on \`$DATABASE_NAME\`.* to $DATABASE_USER@localhost identified by '$DATABASE_PW';flush privileges" + grant_privileges="grant all privileges on \`$DATABASE_NAME\`.* to \`$DATABASE_USER\`@localhost identified by '$DATABASE_PW';flush privileges" + [[ $DATABASE_USER != 'root' ]] || grant_privileges= mysql -e "create database \`$DATABASE_NAME\`;$grant_privileges" - G_DIETPI-NOTIFY -1 "$?" "Creating MariaDB database: $DATABASE_NAME |" - #----------------------------------------------------------------------------------- - exit + G_DIETPI-NOTIFY -1 $? "$MESSAGE" + exit $? #----------------------------------------------------------------------------------- } diff --git a/dietpi/func/dietpi-banner b/dietpi/func/dietpi-banner index 07704b8a42..08091d04c5 100644 --- a/dietpi/func/dietpi-banner +++ b/dietpi/func/dietpi-banner @@ -153,7 +153,7 @@ $GREEN_LINE" [[ -f '/boot/dietpi/.prep_info' ]] && mawk 'NR==1 {sub(/^0$/,"DietPi Core Team");a=$0} NR==2 {print " Image : "a" (pre-image: "$0")"}' /boot/dietpi/.prep_info - echo ' Web : https://dietpi.com | https://twitter.com/dietpi_ + echo ' Web : https://dietpi.com | https://twitter.com/DietPi_ Patreon Legends : Bryce Donate : https://dietpi.com/#donate' diff --git a/dietpi/func/dietpi-benchmark b/dietpi/func/dietpi-benchmark index 51c7cb382b..08aab1fbb8 100644 --- a/dietpi/func/dietpi-benchmark +++ b/dietpi/func/dietpi-benchmark @@ -219,11 +219,8 @@ _EOF_ G_DIETPI-NOTIFY 2 "Testing Seq Write Speed ($BENCH_FILESIZE MiB)" sleep 1 - local bench_write_result=$(dd bs=4K count=$(( $BENCH_FILESIZE * 1024 / 4 )) if=/dev/zero of=$FP_BENCHFILE conv=fdatasync 2>&1 | grep 'copied') - local temp_bytes_result=$(mawk '{print $1}' <<< "$bench_write_result") - local temp_time_result=$(mawk '{print $8}' <<< "$bench_write_result") - # - Convert results from bytes and time to MiB/s - bench_write_result=$(( $temp_bytes_result / $temp_time_result / 1024 / 1024 )) + local bench_write_result=$(dd bs=4K count=$(( $BENCH_FILESIZE * 256 )) if=/dev/zero of=$FP_BENCHFILE conv=fdatasync 2>&1 | grep -m1 'copied') + bench_write_result=$(mawk '{printf "%.0f",$1/$8/1024^2}' <<< "$bench_write_result") # - Clear cache sync @@ -231,11 +228,8 @@ _EOF_ G_DIETPI-NOTIFY 2 "Testing Seq Read Speed ($BENCH_FILESIZE MiB)" sleep 1 - local bench_read_result=$(dd bs=4K count=$(( $BENCH_FILESIZE * 1024 / 4 )) if=$FP_BENCHFILE of=/dev/null conv=fdatasync 2>&1 | grep 'copied') - temp_bytes_result=$(mawk '{print $1}' <<< "$bench_read_result") - temp_time_result=$(mawk '{print $8}' <<< "$bench_read_result") - # - Convert results from bytes and time to MiB/s - bench_read_result=$(( $temp_bytes_result / $temp_time_result / 1024 / 1024 )) + local bench_read_result=$(dd bs=4K count=$(( $BENCH_FILESIZE * 256 )) if=$FP_BENCHFILE of=/dev/null 2>&1 | grep -m1 'copied') + bench_read_result=$(mawk '{printf "%.0f",$1/$8/1024^2}' <<< "$bench_read_result") # - RootFS if [[ $FP_BENCHFILE == '/'$benchmark_file_name ]]; then @@ -306,7 +300,7 @@ You can compare results against other users and hardware using the following lin if df -t tmpfs /tmp &> /dev/null; then FP_BENCHFILE='/tmp' - BENCH_FILESIZE=$(( $(mawk '/^MemFree:/{print $2;exit}' /proc/meminfo) / 1024 / 2 )) # Assure 50% of physical mem stays free, so swapping can be ruled out: KiB => MiB / 2 + BENCH_FILESIZE=$(mawk '/^MemFree:/{printf "%.0f",$2/2048;exit}' /proc/meminfo) # Assure 50% of physical mem stays free, so swapping can be ruled out: KiB => MiB / 2 Filesystem_Benchmark else @@ -355,7 +349,7 @@ Compare these results online with other users, using the link below: BENCH_NET_LAN_SPEED=$(iperf -c $IPERF_SERVER_IP -p 5001 -t 5 -y C | sed 's/.*,//g') if disable_error=1 G_CHECK_VALIDINT "$BENCH_NET_LAN_SPEED"; then - BENCH_NET_LAN_SPEED=$(( $BENCH_NET_LAN_SPEED / 8 / 1024 / 1024 )) + BENCH_NET_LAN_SPEED=$(( $BENCH_NET_LAN_SPEED / 8 / 1024**2 )) G_WHIP_MSG "Network LAN benchmark completed:\n - Transfer rate = $BENCH_NET_LAN_SPEED MiB/s" else diff --git a/dietpi/func/dietpi-globals b/dietpi/func/dietpi-globals index a0af394747..607295c2d5 100644 --- a/dietpi/func/dietpi-globals +++ b/dietpi/func/dietpi-globals @@ -69,8 +69,8 @@ [[ -f '/boot/dietpi/.version' ]] && . /boot/dietpi/.version # - Assign defaults/code version as fallback [[ $G_DIETPI_VERSION_CORE ]] || G_DIETPI_VERSION_CORE=6 - [[ $G_DIETPI_VERSION_SUB ]] || G_DIETPI_VERSION_SUB=31 - [[ $G_DIETPI_VERSION_RC ]] || G_DIETPI_VERSION_RC=2 + [[ $G_DIETPI_VERSION_SUB ]] || G_DIETPI_VERSION_SUB=32 + [[ $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 @@ -180,65 +180,50 @@ $(ps f -eo pid,user,tty,cmd | grep -i '[d]ietpi')"; then # Printing terminal height - 1 newlines seems to be the fastes method that is compatible with all terminal types. local lines=$(stty size) i newlines for ((i=1;i<${lines% *};i++)); do newlines+='\n'; done - printf "\e[0m$newlines\e[H" + echo -ne "\e[0m$newlines\e[H" } # DietPi-Notify # $1: - # -2=process animation - # - $2 = text - # -1=autodetect_fail_ok - # - $2 = EXIT_CODE - # 0=OK - # - $2 = text - # 1=failed - # - $2 = text - # 2=info - # - $2 = text - # 3=DietPi banner style - # - $2 = txt program name - # - $3 = txt mode, prefixed with "${G_NOTIFY_3_MODE}: ", defaults to "Mode: " + # -2 = Processing + # $2+ = message + # -1 = Autodetect ok or failed + # $2 = exit code + # $3+ = message + # 0 = Ok + # $2+ = message + # 1 = Failed + # $2+ = message + # 2 = Info + # $2+ = message + # 3 = Header + # $2 = program name + # $3+ = message, prefixed with "${G_NOTIFY_3_MODE}: ", defaults to "Mode: " G_DIETPI-NOTIFY(){ - local ainput_string=("$@") - local output_string - local bracket_l='\e[0m\e[90m[\e[0m' - local bracket_r='\e[0m\e[90m]\e[0m' - - # Funcs - Clean_Process_Animation(){ + local ainput_string=("$@") output_string grey green red reset yellow dietpi_green + # If this is a terminal, it understands ANSI escape sequences, so use colour, always start left-aligned with colour reset and clear screen from cursor til end. + # - Assume if STDIN is a terminal that STDOUT is one as well, e.g. covered by "tee" + if [[ -t 0 || -t 1 ]]; then - if [[ -t 0 && -w '/tmp/dietpi-process.pid' ]]; then + output_string='\e[0m\r\e[J' grey='\e[90m' green='\e[32m' red='\e[31m' reset='\e[0m' yellow='\e[33m' dietpi_green='\e[38;5;154m' + # Kill existing process animation if this is not a processing message + if [[ $1 != '-2' && -w '/tmp/dietpi-process.pid' ]]; then - kill -9 $( /dev/null + kill -9 "$( /dev/null rm -f /tmp/dietpi-process.pid &> /dev/null fi - # To cover multiline output, clean from cursor (animation position) until end of screen. - output_string='\r\e[J' - - } - - Status_Ok(){ - - Clean_Process_Animation - output_string+="$bracket_l\e[32m OK $bracket_r " - } - - Status_Failed(){ - - Clean_Process_Animation - output_string+="$bracket_l\e[31mFAILED$bracket_r " - - } + fi + local bracket_l="${grey}[$reset" bracket_r="$grey]$reset" + local ok="$bracket_l$green OK $bracket_r " failed="$bracket_l${red}FAILED$bracket_r " - # Print all input string on same line - # - $1 = start printing from word number $1 - Print_Output_String(){ + # Print input array from index $1 + Print(){ - [[ $1 == 1 && $G_PROGRAM_NAME ]] && output_string+="\e[90m$G_PROGRAM_NAME | \e[0m" + [[ $1 == 1 && $G_PROGRAM_NAME ]] && output_string+="$grey$G_PROGRAM_NAME |$reset " local i for ((i=$1; i<${#ainput_string[@]}; i++)) do @@ -246,84 +231,101 @@ $(ps f -eo pid,user,tty,cmd | grep -i '[d]ietpi')"; then output_string+=${ainput_string[$i]} done - echo -ne "$output_string\e[0m" + echo -ne "$output_string$reset" } #-------------------------------------------------------------------------------------- # Main Loop #-------------------------------------------------------------------------------------- - # Exit code, print OK or Failed + # Autodetect ok or failed # $2 = exit code - # - Use this at end of DietPi scripts, EG: G_DIETPI-NOTIFY -1 ${EXIT_CODE:=0} + # $3+ = message + # - Use this at end of DietPi scripts, e.g. G_DIETPI-NOTIFY -1 ${EXIT_CODE:=0} if (( $1 == -1 )); then - if (( ! $2 )); then + if (( $2 )); then - Status_Ok - ainput_string+=(' Completed\n') + output_string+=$failed + ainput_string+=(' | Exited with error\n') else - Status_Failed - ainput_string+=(' An issue has occurred\n') + output_string+=$ok + ainput_string+=(' | Completed\n') fi - Print_Output_String 2 + Print 2 #-------------------------------------------------------------------------------------- - # Status Processing - # $@ = txt desc + # Processing + # $3+ = message + # NB: Do not use this with newlines, literally or "\n", as this would cause parts of the processing message not being overwritten as intended. elif (( $1 == -2 )); then - output_string="\r\e[J$bracket_l\e[33m .... $bracket_r " - Print_Output_String 1 + # If this is a terminal, it understands control codes, so make any next output overwrite the processing message. + if [[ -t 0 || -t 1 ]]; then - if [[ -t 0 ]]; then - - Print_Process_Animation(){ - - local bright_dot='\e[1;33m.' - local dimmed_dot='\e[0;33m.' - # Alternative: \u23F9 - local aprocess_string=( - "$bright_dot " - "$dimmed_dot$bright_dot " - " $dimmed_dot$bright_dot " - " $dimmed_dot$bright_dot " - " $dimmed_dot$bright_dot " - " $dimmed_dot$bright_dot" - " $bright_dot" - " $bright_dot$dimmed_dot" - " $bright_dot$dimmed_dot " - " $bright_dot$dimmed_dot " - " $bright_dot$dimmed_dot " - "$bright_dot$dimmed_dot " - ) - - local i - for (( i=0; i<=${#aprocess_string[@]}; i++ )); do - - (( i == ${#aprocess_string[@]} )) && i=0 - [[ -w '/tmp/dietpi-process.pid' ]] && echo -ne "\r$bracket_l${aprocess_string[$i]}$bracket_r " || return - sleep 0.15 - - done - - } - - # Calculate the amount of output lines and in case move cursor up for correct animation and to allow cleaning the whole output. + # Calculate the amount of output lines and in case move cursor up for correct animation position and to allow overwriting the whole output. local input_string=$(mawk '{gsub("\\\e[[0-9][;0-9]*m","");print}' <<< "${G_PROGRAM_NAME:+$G_PROGRAM_NAME | }$*") # Remove colour codes - local screen_width=$(stty size) + local screen_width + [[ -t 0 ]] && screen_width=$(stty size) || screen_width=$(tput cols) # stty requires STDIN, tput requires either STDOUT or STDERR until Stretch local output_lines=$(( ( ${#input_string} + 5 ) / ${screen_width#* } )) # +5 = [ .... ] - $1 - (( $output_lines )) && echo -ne "\e[${output_lines}A" + (( $output_lines )) && ainput_string+=("\e[${output_lines}A") + # If we do not print the animation, move the cursor left as well to allow overwriting the whole first line. + [[ -t 0 ]] || ainput_string+=('\r') + + # Else, we add a newline to leave processing message complete. + else + + ainput_string+=('\n') + + fi + + # Print animation only if this is the terminal control process as otherwise foreign output might cause a mess and we might be not able to kill the animation. + if [[ -t 0 ]]; then + + output_string+="$bracket_l $bracket_r " + Print 1 + # If redirect to existent PID file fails due to noclobber, don't start processing animation. # - This method prevents a tiny condition race from checking file existance until creating it, when doing: [[ ! -e file ]] && > file set -C if { > /tmp/dietpi-process.pid; } &> /dev/null; then set +C - { Print_Process_Animation & echo $! > /tmp/dietpi-process.pid; disown; } 2> /dev/null + Start_Process_Animation(){ + + local bright_dot='\e[1;33m.' + local dimmed_dot='\e[0;33m.' + # Alternative: \u23F9 + local aprocess_string=( + "$bright_dot " + "$dimmed_dot$bright_dot " + " $dimmed_dot$bright_dot " + " $dimmed_dot$bright_dot " + " $dimmed_dot$bright_dot " + " $dimmed_dot$bright_dot" + " $bright_dot" + " $bright_dot$dimmed_dot" + " $bright_dot$dimmed_dot " + " $bright_dot$dimmed_dot " + " $bright_dot$dimmed_dot " + "$bright_dot$dimmed_dot " + ) + + local i + for (( i=0; i<=${#aprocess_string[@]}; i++ )); do + + (( i == ${#aprocess_string[@]} )) && i=0 + [[ -w '/tmp/dietpi-process.pid' ]] && echo -ne "\e[2G${aprocess_string[$i]}$reset\e[C" || return + sleep 0.15 + + done + + } + { Start_Process_Animation & echo $! > /tmp/dietpi-process.pid; disown; } 2> /dev/null + unset -f Start_Process_Animation else @@ -331,67 +333,72 @@ $(ps f -eo pid,user,tty,cmd | grep -i '[d]ietpi')"; then fi - unset -f Print_Process_Animation + else + + output_string+="$bracket_l $yellow.... $bracket_r " + Print 1 fi - # Status Ok - # $@ = txt desc + #-------------------------------------------------------------------------------------- + # Ok + # $2+ = message elif (( $1 == 0 )); then - Status_Ok + output_string+=$ok ainput_string+=('\n') - Print_Output_String 1 + Print 1 - # Status failed - # $@ = txt desc + #-------------------------------------------------------------------------------------- + # Failed + # $2+ = message elif (( $1 == 1 )); then - Status_Failed + output_string+=$failed ainput_string+=('\n') - Print_Output_String 1 + Print 1 - # Status Info - # $@ = txt desc + #-------------------------------------------------------------------------------------- + # Info + # $2+ = message elif (( $1 == 2 )); then - Clean_Process_Animation output_string+="$bracket_l INFO $bracket_r " # Keep info messages in gray, even if "$G_PROGRAM_NAME | \e[0m" is added: - ainput_string[1]="\e[90m${ainput_string[1]}" + ainput_string[1]="$grey${ainput_string[1]}" ainput_string+=('\n') - Print_Output_String 1 + Print 1 - # DietPi banner style - # $2 = txt program name - # $3 = txt mode + #-------------------------------------------------------------------------------------- + # Header + # $2 = program name + # $3+ = message, prefixed with "${G_NOTIFY_3_MODE}: ", defaults to "Mode: " elif (( $1 == 3 )); then - Clean_Process_Animation if disable_error=1 G_CHECK_VALIDINT "$HIERARCHY" 1; then local status_subfunction="$HIERARCHY " # > 9 should never occur, however, if it is, lets make it line up regardless (( $HIERARCHY > 9 )) && status_subfunction=$HIERARCHY - output_string+="$bracket_l\e[33m SUB$status_subfunction$bracket_r $2 > " + output_string+="$bracket_l$yellow SUB$status_subfunction$bracket_r $2 > " ainput_string+=('\n') else output_string+=" - \e[38;5;154m$2\e[0m -\e[90m───────────────────────────────────────────────────── - ${G_NOTIFY_3_MODE:-Mode}: \e[0m" + $dietpi_green$2$reset +$grey───────────────────────────────────────────────────── + ${G_NOTIFY_3_MODE:-Mode}:$reset " ainput_string+=('\n\n') fi - Print_Output_String 2 + Print 2 fi #----------------------------------------------------------------------------------- # Unset internal functions, otherwise they are accessible from terminal - unset -f Clean_Process_Animation Status_Ok Status_Failed Print_Output_String + unset -f Print #----------------------------------------------------------------------------------- } @@ -919,7 +926,7 @@ $(ps f -eo pid,user,tty,cmd | grep -i '[d]ietpi')"; then # Print $G_EXEC_DESC if given, else raw input command string and show current non-interactive attempt count if $G_EXEC_RETRIES is given G_DIETPI-NOTIFY 2 "${G_EXEC_DESC:-$*}, please wait...${G_EXEC_RETRIES:+ ($attempt/$((G_EXEC_RETRIES+1)))}" - [[ $G_EXEC_OUTPUT_COL ]] && printf "$G_EXEC_OUTPUT_COL" + [[ $G_EXEC_OUTPUT_COL ]] && echo -ne "$G_EXEC_OUTPUT_COL" "${acommand[@]}" 2>&1 | tee $fp_log exit_code=${PIPESTATUS[0]} [[ $G_EXEC_OUTPUT_COL ]] && printf '\e[0m' @@ -1062,7 +1069,7 @@ $log_content" || break # Exit error handler menu loop on cancel G_DIETPI-NOTIFY 2 "Executing alternative command: $G_WHIP_RETURNED_VALUE" $G_WHIP_RETURNED_VALUE exit_code=$? - G_DIETPI-NOTIFY -1 $exit_code 'Alternative command execution |' + G_DIETPI-NOTIFY -1 $exit_code 'Alternative command execution' # Exit retry loop if alternative command succeeded, else stay in menu loop and wait for key press to allow reviewing alternative command output [[ $exit_code == 0 ]] && break 2 || read -rp 'Press any key to return to error handler menu...' @@ -1257,7 +1264,7 @@ $log_content" || break # Exit error handler menu loop on cancel while : do - if ! mkdir -p $input; then + if ! mkdir -p "$input"; then G_WHIP_MSG "Error creating directory $input, unable to check filesystem permissions" break @@ -1265,7 +1272,7 @@ $log_content" || break # Exit error handler menu loop on cancel fi local fp_target="$input/.test" - if ! > $fp_target; then + if ! > "$fp_target"; then G_WHIP_MSG "Error creating test file $fp_target, unable to check filesystem permissions" break @@ -1275,21 +1282,21 @@ $log_content" || break # Exit error handler menu loop on cancel # Apply and check permissions support, twice (just incase the current value is already set) local permissions_failed=0 - chmod 600 $fp_target - if [[ $(stat -c "%a" $fp_target) != '600' ]]; then + chmod 600 "$fp_target" + if [[ $(stat -c "%a" "$fp_target") != '600' ]]; then permissions_failed=1 else - chmod 644 $fp_target - [[ $(stat -c "%a" $fp_target) != '644' ]] && permissions_failed=1 + chmod 644 "$fp_target" + [[ $(stat -c "%a" "$fp_target") != '644' ]] && permissions_failed=1 fi if (( $permissions_failed )); then - G_WHIP_MSG "ERROR: Filesystem does not support permissions (eg: FAT16/32):\n\n$fp_target\n\nPlease select a different drive and/or format it with ext4, ensuring support for filesystem permissions.\n\nUnable to continue, aborting..." + G_WHIP_MSG "ERROR: Filesystem does not support permissions (e.g.: FAT16/32):\n\n$fp_target\n\nPlease select a different drive and/or format it with ext4, ensuring support for filesystem permissions.\n\nUnable to continue, aborting..." break fi @@ -1300,7 +1307,7 @@ $log_content" || break # Exit error handler menu loop on cancel done - [[ -f $fp_target ]] && rm -f $fp_target + [[ -f $fp_target ]] && rm -f "$fp_target" return $result } @@ -1455,26 +1462,18 @@ $log_content" || break # Exit error handler menu loop on cancel # MISC: Commands #----------------------------------------------------------------------------------- # Treesize - # - $1 = Optional input directory (eg: G_TREESIZE /etc/apt) + # - $1 = Optional input directory, e.g.: G_TREESIZE /var/cache/apt G_TREESIZE(){ - G_CHECK_ROOT_USER 1 - - du -k --max-depth=1 $1 | sort -nr | mawk ' - BEGIN { - split("KB,MB,GB,TB", Units, ","); - } + du -B 1 -d 1 ${1:+"$1"} | sort -nr | mawk ' + BEGIN { split("bytes,KiB,MiB,GiB,TiB", unit, ",") } { - u = 1; - while ($1 >= 1024) - { - $1 = $1 / 1024; - u += 1; - } - $1 = sprintf("%.1f %s", $1, Units[u]); - print $0; - } - ' + u=1 + while ($1>=1024) { $1=$1/1024; u+=1 } + $1=sprintf("%.1f %s", $1, unit[u]) + print $0 + }' + } # Returns current CPU temp 'C @@ -1503,10 +1502,10 @@ $log_content" || break # Exit error handler menu loop on cancel ) - for i in ${afp_temperature[@]} + for i in "${afp_temperature[@]}" do - [[ -f $i ]] && { temp=$(<$i); break; } + [[ -f $i ]] && { temp=$(<"$i"); break; } done @@ -1560,22 +1559,24 @@ $log_content" || break # Exit error handler menu loop on cancel } - # Returns current CPU usage % + # Returns current CPU usage in % G_OBTAIN_CPU_USAGE(){ - # PS (inaccurate, but fast??) - local cpu_usage=0 - while read -r line + local usage=0 + + # ps: inaccurate but fast + while read -r line # Aside reasing raw, -r removes leading and trailing white spaces each line do - cpu_usage=$(bc -l <<< "scale=1;$cpu_usage + $line") + line=${line/.} # Remove decimal dot + ((usage+=${line#0})) # Remove leading zero, if present, then sum up - done <<< "$(ps -eo %cpu | sed -n '1!{s/^ //p}')" + done < <(ps --no-headers -eo %cpu) # Single core usage in xy.z - # ps returns usage of each core, so we devide the total by #n cores - cpu_usage=$(bc -l <<< "scale=1;$cpu_usage / $G_HW_CPU_CORES") + # ps returns single core usage, so we devide by core count + usage=$(printf '%.1f' "$(($usage*10/$G_HW_CPU_CORES+1))e-2") # Divide by 10 to compensate decimal dot removal, re-add decimal dot via printf conversion but assure last digit is rounded correctly - echo $cpu_usage + echo "$usage" } @@ -1591,23 +1592,18 @@ $log_content" || break # Exit error handler menu loop on cancel local return_value=1 local input_path=$1 local input_required_space=$2 - local available_space=$(df -m --output=avail $input_path | mawk 'NR==2 {print $1}') - - if [[ ! $input_required_space ]]; then + local available_space=$(df -m --output=avail "$input_path" | mawk 'NR==2 {print $1}') - if (( $info_autoscale )); then + if ! disable_error=1 G_CHECK_VALIDINT "$available_space"; then - (( $available_space > 9999 )) && available_space="$(( $available_space / 1024 )) GiB" || available_space+=' MiB' + G_WHIP_MSG 'G_CHECK_FREESPACE: Invalid integer from df result' - fi + elif [[ ! $input_required_space ]]; then - echo $available_space + (( $info_autoscale )) && { (( $available_space > 9999 )) && available_space="$(( $available_space / 1024 )) GiB" || available_space+=' MiB'; } + echo "$available_space" return_value=0 - elif ! disable_error=1 G_CHECK_VALIDINT $available_space; then - - G_WHIP_MSG 'G_CHECK_FREESPACE: invalid integer from df result' - else (( $available_space > $input_required_space )) && return_value=0 @@ -1696,7 +1692,7 @@ $log_content" || break # Exit error handler menu loop on cancel # Check physical location exists and is mounted fp_actual=$(readlink -f $G_FP_DIETPI_USERDATA) - df -P $fp_actual &> /dev/null || return_value=1 + df -P "$fp_actual" &> /dev/null || return_value=1 fi @@ -1780,21 +1776,20 @@ $log_content" || break # Exit error handler menu loop on cancel # Run in blocking mode if [[ $G_THREADING_ENABLED == 0 ]]; then - local command=$* - G_DIETPI-NOTIFY 2 "G_THREADING disabled, running command in blocking mode | $command" - $command + G_DIETPI-NOTIFY 2 "G_THREADING disabled, running command in blocking mode | $*" + "$@" # Launch as background process else [[ $G_THREAD_COUNT =~ ^[0-9]+$ ]] || G_THREAD_COUNT=-1 ((G_THREAD_COUNT++)) - G_THREAD_COMMAND[$G_THREAD_COUNT]=$* + G_THREAD_COMMAND[$G_THREAD_COUNT]=$* # Store for later output with G_THREAD_WAIT - echo -1337 > /tmp/.G_THREAD_EXITCODE_$G_THREAD_COUNT - { { G_INTERACTIVE=0 ${G_THREAD_COMMAND[$G_THREAD_COUNT]} &> /tmp/.G_THREAD_COMMAND_$G_THREAD_COUNT; echo $? > /tmp/.G_THREAD_EXITCODE_$G_THREAD_COUNT; } & disown; } &> /dev/null + echo -1337 > "/tmp/.G_THREAD_EXITCODE_$G_THREAD_COUNT" + { { G_INTERACTIVE=0 "$@" &> "/tmp/.G_THREAD_COMMAND_$G_THREAD_COUNT"; echo $? > "/tmp/.G_THREAD_EXITCODE_$G_THREAD_COUNT"; } & disown; } &> /dev/null - G_DIETPI-NOTIFY 2 "G_THREAD_START_$G_THREAD_COUNT | ${G_THREAD_COMMAND[$G_THREAD_COUNT]}" + G_DIETPI-NOTIFY 2 "G_THREAD_START_$G_THREAD_COUNT | $*" fi @@ -1805,43 +1800,38 @@ $log_content" || break # Exit error handler menu loop on cancel #local wait_for_specific_thread_pid=-1 #[[ $1 ]] && wait_for_specific_thread_pid=$1 - local thread_active i waiting=-1 + local i waiting_for exit_code + # Wait until all theads finished while : do - thread_active=0 - - for i in ${!G_THREAD_COMMAND[@]} + for i in "${!G_THREAD_COMMAND[@]}" do - if [[ -f /tmp/.G_THREAD_EXITCODE_$i && $(&1); then + elif error=$(grep -Eq "^[[:blank:]]*$pattern" "$file" 2>&1); then # As an error within the condition leads to result "false", it can be caught only in next "elif"/"else" statement. if [[ $GCI_PRESERVE == 1 ]]; then - G_DIETPI-NOTIFY 0 "Current setting in \e[33m$file\e[0m will be preserved: \e[33m$([[ $GCI_PASSWORD == 1 ]] && echo "${setting_raw//\\/\\\\}" || grep -Em1 "^[[:blank:]]*$pattern" $file | sed 's|\\|\\\\|g')\e[0m" + G_DIETPI-NOTIFY 0 "Current setting in \e[33m$file\e[0m will be preserved: \e[33m$([[ $GCI_PASSWORD == 1 ]] && echo "${setting_raw//\\/\\\\}" || grep -Em1 "^[[:blank:]]*$pattern" "$file" | sed 's|\\|\\\\|g')\e[0m" - elif error=$(grep -Eq "^[[:blank:]]*$setting([[:space:]]|$)" $file 2>&1); then + elif error=$(grep -Eq "^[[:blank:]]*$setting([[:space:]]|$)" "$file" 2>&1); then - G_DIETPI-NOTIFY 0 "Desired setting in \e[33m$file\e[0m was already set: \e[33m$([[ $GCI_PASSWORD == 1 ]] && echo "${setting_raw//\\/\\\\}" || grep -Em1 "^[[:blank:]]*$pattern" $file | sed 's|\\|\\\\|g')\e[0m" + G_DIETPI-NOTIFY 0 "Desired setting in \e[33m$file\e[0m was already set: \e[33m$([[ $GCI_PASSWORD == 1 ]] && echo "${setting_raw//\\/\\\\}" || grep -Em1 "^[[:blank:]]*$pattern" "$file" | sed 's|\\|\\\\|g')\e[0m" - elif error=$( (( $(grep -Ec "^[[:blank:]]*$pattern" $file 2>&1) > 1 )) 2>&1); then + elif error=$( (( $(grep -Ec "^[[:blank:]]*$pattern" "$file" 2>&1) > 1 )) 2>&1); then [[ $error ]] && { syntax_error; return 1; } G_WHIP_MSG "[FAILED] Setting was found multiple times @@ -1985,7 +1975,7 @@ NB: was found multiple times in file \$3 $file \n____________ -$(grep -En "^[[:blank:]]*$pattern" $file) +$(grep -En "^[[:blank:]]*$pattern" "$file") ____________ \nEither the pattern \$1 needs to be more specific or the desired setting can appear multiple times by design and it cannot be predicted which instance to edit. Please retry with more specific parameter \$1 or apply the setting manually: @@ -1994,17 +1984,17 @@ Please retry with more specific parameter \$1 or apply the setting manually: else [[ $error ]] && { syntax_error; return 1; } - [[ $GCI_BACKUP == 1 && ! -f $file.bak ]] && cp -a $file $file.bak && G_DIETPI-NOTIFY 2 "Config file backup created: \e[33m$file.bak\e[0m" - error=$(sed -Ei "0,/^[[:blank:]]*$pattern.*$/s//$setting/" $file 2>&1) || { syntax_error; return 1; } + [[ $GCI_BACKUP == 1 && ! -f $file.bak ]] && cp -a "$file" "$file.bak" && G_DIETPI-NOTIFY 2 "Config file backup created: \e[33m$file.bak\e[0m" + error=$(sed -Ei "0,/^[[:blank:]]*$pattern.*$/s//$setting/" "$file" 2>&1) || { syntax_error; return 1; } G_DIETPI-NOTIFY 0 "Setting in \e[33m$file\e[0m adjusted: \e[33m${setting_raw//\\/\\\\}\e[0m" fi - elif error=$(grep -Eq "^[[:blank:]#;]*$pattern" $file 2>&1); then + elif error=$(grep -Eq "^[[:blank:]#;]*$pattern" "$file" 2>&1); then [[ $error ]] && { syntax_error; return 1; } - [[ $GCI_BACKUP == 1 && ! -f $file.bak ]] && cp -a $file $file.bak && G_DIETPI-NOTIFY 2 "Config file backup created: \e[33m$file.bak\e[0m" - error=$(sed -Ei "0,/^[[:blank:]#;]*$pattern.*$/s//$setting/" $file 2>&1) || { syntax_error; return 1; } + [[ $GCI_BACKUP == 1 && ! -f $file.bak ]] && cp -a "$file" "$file.bak" && G_DIETPI-NOTIFY 2 "Config file backup created: \e[33m$file.bak\e[0m" + error=$(sed -Ei "0,/^[[:blank:]#;]*$pattern.*$/s//$setting/" "$file" 2>&1) || { syntax_error; return 1; } G_DIETPI-NOTIFY 0 "Comment in \e[33m$file\e[0m converted to setting: \e[33m${setting_raw//\\/\\\\}\e[0m" else @@ -2012,11 +2002,11 @@ Please retry with more specific parameter \$1 or apply the setting manually: if [[ $after ]]; then - if error=$(grep -Eq "^[[:blank:]]*$after" $file 2>&1); then + if error=$(grep -Eq "^[[:blank:]]*$after" "$file" 2>&1); then - [[ $GCI_BACKUP == 1 && ! -f $file.bak ]] && cp -a $file $file.bak && G_DIETPI-NOTIFY 2 "Config file backup created: \e[33m$file.bak\e[0m" - error=$(sed -Ei "0,/^[[:blank:]]*$after.*$/s//&\n$setting/" $file 2>&1) || { syntax_error; return 1; } - G_DIETPI-NOTIFY 0 "Added setting \e[33m${setting_raw//\\/\\\\}\e[0m to \e[33m$file\e[0m after line \e[33m$(grep -Em1 "^[[:blank:]]*$after" $file | sed 's|\\|\\\\|g')\e[0m" + [[ $GCI_BACKUP == 1 && ! -f $file.bak ]] && cp -a "$file" "$file.bak" && G_DIETPI-NOTIFY 2 "Config file backup created: \e[33m$file.bak\e[0m" + error=$(sed -Ei "0,/^[[:blank:]]*$after.*$/s//&\n$setting/" "$file" 2>&1) || { syntax_error; return 1; } + G_DIETPI-NOTIFY 0 "Added setting \e[33m${setting_raw//\\/\\\\}\e[0m to \e[33m$file\e[0m after line \e[33m$(grep -Em1 "^[[:blank:]]*$after" "$file" | sed 's|\\|\\\\|g')\e[0m" else [[ $error ]] && { syntax_error; return 1; } @@ -2033,10 +2023,10 @@ could not be found in file \$3 else - [[ $GCI_BACKUP == 1 && ! -f $file.bak ]] && cp -a $file $file.bak && G_DIETPI-NOTIFY 2 "Config file backup created: \e[33m$file.bak\e[0m" + [[ $GCI_BACKUP == 1 && ! -f $file.bak ]] && cp -a "$file" "$file.bak" && G_DIETPI-NOTIFY 2 "Config file backup created: \e[33m$file.bak\e[0m" # The following sed does not work on empty files: - [[ ! -s $file ]] && echo '# Added by DietPi:' >> $file - error=$(sed -Ei "\$a\\$setting" $file 2>&1) || { syntax_error; return 1; } + [[ ! -s $file ]] && echo '# Added by DietPi:' >> "$file" + error=$(sed -Ei "\$a\\$setting" "$file" 2>&1) || { syntax_error; return 1; } G_DIETPI-NOTIFY 0 "Added setting \e[33m${setting_raw//\\/\\\\}\e[0m to end of file \e[33m$file\e[0m" fi @@ -2048,7 +2038,6 @@ could not be found in file \$3 #----------------------------------------------------------------------------------- [[ $G_DEBUG == 1 ]] && G_DIETPI-NOTIFY 2 'DietPi-Globals loaded' #----------------------------------------------------------------------------------- - # Return exit code 0, by triggering null as last command to output - : + : # Return exit code 0, by triggering null as last command to output #----------------------------------------------------------------------------------- } diff --git a/dietpi/func/dietpi-obtain_hw_model b/dietpi/func/dietpi-obtain_hw_model index b63b919488..e67341f271 100644 --- a/dietpi/func/dietpi-obtain_hw_model +++ b/dietpi/func/dietpi-obtain_hw_model @@ -10,9 +10,9 @@ # Info: # - Location: /boot/dietpi/func/dietpi-obtain_hw_model # - Generates /boot/dietpi/.hw_model - # - Called from /boot/dietpi/preboot and /boot/dietpi/func/dietpi-globals + # - Called from /boot/dietpi/preboot, called by /etc/systemd/system/dietpi-preboot.service # - # In DietPi-Software: Need to match highest values in dietpi-obtain_hw_model + # Developer note: Sync highest IDs with dietpi-software: # - MAX_G_HW_MODEL=73 # - MAX_G_HW_ARCH=10 # - MAX_G_DISTRO=6 @@ -34,12 +34,15 @@ # G_HW_MODEL 59 ZeroPi # G_HW_MODEL 58 NanoPi M4V2 # G_HW_MODEL 57 NanoPi NEO Plus2 + # G_HW_MODEL 56 NanoPi NEO3 + # G_HW_MODEL 55 NanoPi R2S + # G_HW_MODEL 54 NanoPi K2 # G_HW_MODEL 53 BananaPi (sinovoip) # G_HW_MODEL 52 ASUS Tinker Board # G_HW_MODEL 51 BananaPi Pro (Lemaker) # G_HW_MODEL 50 BananaPi M2+ (sinovoip) # G_HW_MODEL 45 PINE H64 - # G_HW_MODEL 44 Pinebook A64 + # G_HW_MODEL 44 Pinebook # G_HW_MODEL 43 ROCK64 # G_HW_MODEL 42 ROCKPro64 # G_HW_MODEL 41 OrangePi PC Plus @@ -82,6 +85,8 @@ # G_HW_CPUID 3 Rockchip RK3399 # G_HW_CPUID 4 Amlogic S922X # G_HW_CPUID 5 Allwinner H6 + # G_HW_CPUID 6 Rockchip RK3328 + # G_HW_CPUID 7 Amlogic S905 # ---------------- # G_DISTRO 0 unknown/unsupported # G_DISTRO 1 Debian Wheezy (No longer supported: https://dietpi.com/phpbb/viewtopic.php?p=1898) @@ -103,6 +108,7 @@ # Read .hw_model if existent to preserve existing G_HW_UUID G_HW_UUID= [[ -f '/boot/dietpi/.hw_model' ]] && . /boot/dietpi/.hw_model + [[ $G_HW_UUID ]] || G_HW_UUID=$(256M on a 512M model + if (( $(mawk '/^MemTotal:/{print $2;exit}' /proc/meminfo) < 262144 )); then G_HW_MODEL=0 G_HW_MEMORY_SIZE=256 @@ -397,6 +388,21 @@ G_HW_MODEL_NAME='NanoPi NEO Plus2' G_HW_CPUID=2 + elif (( $G_HW_MODEL == 56 )); then + + G_HW_MODEL_NAME='NanoPi NEO3' + G_HW_CPUID=6 + + elif (( $G_HW_MODEL == 55 )); then + + G_HW_MODEL_NAME='NanoPi R2S' + G_HW_CPUID=6 + + elif (( $G_HW_MODEL == 54 )); then + + G_HW_MODEL_NAME='NanoPi K2' + G_HW_CPUID=7 + elif (( $G_HW_MODEL == 53 )); then G_HW_MODEL_NAME='BananaPi' @@ -426,6 +432,7 @@ elif (( $G_HW_MODEL == 43 )); then G_HW_MODEL_NAME='ROCK64' + G_HW_CPUID=6 elif (( $G_HW_MODEL == 42 )); then @@ -517,6 +524,7 @@ elif (( $G_HW_MODEL == 12 )); then G_HW_MODEL_NAME='Odroid C2' + G_HW_CPUID=7 elif (( $G_HW_MODEL == 11 )); then diff --git a/dietpi/func/dietpi-set_hardware b/dietpi/func/dietpi-set_hardware index 0806cbb788..f3207bf7e8 100644 --- a/dietpi/func/dietpi-set_hardware +++ b/dietpi/func/dietpi-set_hardware @@ -1065,11 +1065,11 @@ _EOF_ if [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then # RPi - if (( $G_HW_MODEL < 10 )); then + if (( $G_HW_MODEL < 10 )) && (( $G_HW_ONBOARD_WIFI )); then systemctl disable --now hciuart 2> /dev/null # Disable onboard BT via dtoverlay - (( $G_HW_ONBOARD_WIFI )) && G_CONFIG_INJECT 'dtoverlay=disable-bt' 'dtoverlay=disable-bt' /boot/config.txt + G_CONFIG_INJECT 'dtoverlay=disable-bt' 'dtoverlay=disable-bt' /boot/config.txt # ASUS TB elif (( $G_HW_MODEL == 52 )); then @@ -1077,7 +1077,7 @@ _EOF_ systemctl disable --now hciuart 2> /dev/null # Broadcom-based models that need brcm_patchram_plus - elif (( $G_HW_MODEL == 61 || $G_HW_MODEL == 62 )); then + elif [[ $G_HW_MODEL == 6[12] ]]; then systemctl disable --now brcm_patchram_plus 2> /dev/null @@ -1109,21 +1109,14 @@ _EOF_ [[ -f '/etc/modprobe.d/dietpi-disable_bluetooth.conf' ]] && rm /etc/modprobe.d/dietpi-disable_bluetooth.conf # Pre-Reqs - if (( $G_HW_MODEL < 10 )); then + if (( $G_HW_MODEL < 10 )) && (( $G_HW_ONBOARD_WIFI )); then # Login console on ttyAMA0 must be disabled: https://github.com/MichaIng/DietPi/issues/2607#issuecomment-470523194 if systemctl -q is-active serial-getty@ttyAMA0; then - if G_WHIP_YESNO '[WARNING] A serial login console is currently active on ttyAMA0\n -Do you want to continue and disable the serial login console?'; then - - INPUT_DEVICE_VALUE='disable' INPUT_ADDITIONAL='ttyAMA0' Serial_Main - - else - - exit 0 - - fi + G_WHIP_YESNO '[WARNING] A serial login console is currently active on ttyAMA0\n +Do you want to continue and disable the serial login console?' || return 1 + INPUT_DEVICE_VALUE='disable' INPUT_ADDITIONAL='ttyAMA0' Serial_Main fi @@ -1152,10 +1145,10 @@ Do you want to continue and disable the serial login console?'; then done # Failsafe, unblock all Bluetooth adapters - rfkill unblock bluetooth &> /dev/null + command -v rfkill > /dev/null && rfkill unblock bluetooth # Broadcom-based models that need brcm_patchram_plus - if (( $G_HW_MODEL == 61 || $G_HW_MODEL == 62 )); then + if [[ $G_HW_MODEL == 6[12] ]]; then G_EXEC systemctl enable --now brcm_patchram_plus @@ -1164,7 +1157,7 @@ Do you want to continue and disable the serial login console?'; then G_EXEC systemctl enable --now bluetooth # RPi - (( $G_HW_MODEL < 10 )) && G_EXEC systemctl enable --now hciuart + (( $G_HW_MODEL > 9 )) || (( ! $G_HW_ONBOARD_WIFI )) || G_EXEC systemctl enable --now hciuart else @@ -1222,11 +1215,13 @@ Do you want to continue and disable the serial login console?'; then fi # Failsafe: Comment "disable_ipv6" entries in all other sysctl config files - local i='' + local i for i in /etc/sysctl{,.d/*}.conf do - [[ ! -f $i || $i == *'dietpi-disable_ipv6.conf' ]] && continue + [[ $i != '/etc/sysctl.d/dietpi-disable_ipv6.conf' && -f $i ]] || continue + grep -q '^[[:blank:]]*net.ipv6.conf.[^[:blank:]]*.disable_ipv6[[:blank:]]*=' $i || continue + i=$(readlink -f $i) # https://github.com/MichaIng/DietPi/issues/3003#issuecomment-669464255 sed -i 's/^[[:blank:]]*net.ipv6.conf.[^[:blank:]]*.disable_ipv6[[:blank:]]*=/#&/' $i done @@ -1325,7 +1320,7 @@ Do you want to continue and disable the serial login console?'; then fi # APT packages - local packages='iw wireless-tools crda rfkill wpasupplicant' + local packages='iw wireless-tools crda wpasupplicant' if [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then @@ -1389,7 +1384,7 @@ _EOF_ G_AG_CHECK_INSTALL_PREREQ $packages || EXIT_CODE=1 # Failsafe, unblock all WiFi adapters: https://github.com/MichaIng/DietPi/issues/1627 - rfkill unblock wifi &> /dev/null + command -v rfkill > /dev/null && rfkill unblock wifi elif [[ $INPUT_DEVICE_VALUE == 'onboard_enable' ]]; then @@ -1455,16 +1450,9 @@ _EOF_ # RPi: Warn if on RPi ttyAMA0 is about to be enabled while Bluetooth is up if [[ $G_HW_MODEL == [0-9] && $INPUT_ADDITIONAL == 'ttyAMA0' ]] && systemctl -q is-active hciuart; then - if G_WHIP_YESNO '[WARNING] ttyAMA0 is currently used by Bluetooth\n -Do you want to continue and DISABLE Bluetooth now?'; then - - INPUT_DEVICE_VALUE='disable' Bluetooth_Main - - else - - exit 0 - - fi + G_WHIP_YESNO '[WARNING] ttyAMA0 is currently used by Bluetooth\n +Do you want to continue and DISABLE Bluetooth now?' || return 1 + INPUT_DEVICE_VALUE='disable' Bluetooth_Main fi @@ -1481,30 +1469,30 @@ Do you want to continue and DISABLE Bluetooth now?'; then # - RPi if (( $G_HW_MODEL < 10 )); then - grep -q "console=$INPUT_ADDITIONAL" /boot/cmdline.txt || sed -i "/root=/s/$/ console=$INPUT_ADDITIONAL,115200/" /boot/cmdline.txt + grep -q "console=$INPUT_ADDITIONAL" /boot/cmdline.txt || sed -i "/root=/s/[[:blank:]]*$/ console=$INPUT_ADDITIONAL,115200/" /boot/cmdline.txt # - Odroid C2 elif (( $G_HW_MODEL == 12 )); then - local old='' - [[ -f '/boot/boot.ini' ]] && old=$(grep -m1 '^setenv condev "' /boot/boot.ini) || return - [[ $old =~ console=$INPUT_ADDITIONAL ]] && return + local old= + [[ -f '/boot/boot.ini' ]] && old=$(grep -m1 '^setenv condev "' /boot/boot.ini) || return 0 + [[ $old == *"console=$INPUT_ADDITIONAL"* ]] && return 0 old=$(cut -d \" -f 2 <<< "$old") G_CONFIG_INJECT 'setenv condev "' "setenv condev \"$old console=$INPUT_ADDITIONAL,115200n8\"" /boot/boot.ini # - Odroid XU4 elif (( $G_HW_MODEL == 11 )); then - local old='' - [[ -f '/boot/boot.ini' ]] && old=$(grep -m1 '^setenv bootrootfs "' /boot/boot.ini) || return - [[ $old =~ console=$INPUT_ADDITIONAL ]] && return + local old= + [[ -f '/boot/boot.ini' ]] && old=$(grep -m1 '^setenv bootrootfs "' /boot/boot.ini) || return 0 + [[ $old == *"console=$INPUT_ADDITIONAL"* ]] && return 0 old=$(cut -d \" -f 2 <<< "$old") G_CONFIG_INJECT 'setenv bootrootfs "' "setenv bootrootfs \"$old console=$INPUT_ADDITIONAL,115200n8\"" /boot/boot.ini - # - ARMbian: armbianEnv.txt only allows to toggle a fixed serial console depending on device + # - Armbian: armbianEnv.txt only allows to toggle a fixed serial console depending on device elif (( $ARMBIAN )); then - grep -q "console=$INPUT_ADDITIONAL" /boot/boot.cmd || return + grep -q "console=$INPUT_ADDITIONAL" /boot/boot.cmd || return 0 if grep -qE 'console=(display|both)' $FP_UENV; then G_CONFIG_INJECT 'console=' 'console=both' $FP_UENV @@ -1515,10 +1503,10 @@ Do you want to continue and DISABLE Bluetooth now?'; then fi - # - Pine A64: On ARMbian ttyS0 boot output is forced and custom console is not possible via armbianEnv.txt + # - PINE A64: On Armbian ttyS0 boot output is forced and custom console is not possible via armbianEnv.txt elif (( $G_HW_MODEL == 40 )); then - [[ ! -f $FP_UENV ]] || grep -q "console=$INPUT_ADDITIONAL" $FP_UENV && return + [[ ! -f $FP_UENV ]] || grep -q "console=$INPUT_ADDITIONAL" $FP_UENV && return 0 echo "console=$INPUT_ADDITIONAL,115200n8" >> $FP_UENV #elif (( $G_HW_MODEL == 70 )); then @@ -1540,7 +1528,7 @@ Do you want to continue and DISABLE Bluetooth now?'; then done # On RPi enable primary UART device - (( $G_HW_MODEL < 10 )) && G_CONFIG_INJECT 'enable_uart=' 'enable_uart=1' /boot/config.txt + (( $G_HW_MODEL > 9 )) || G_CONFIG_INJECT 'enable_uart=' 'enable_uart=1' /boot/config.txt # Update dietpi.txt global var G_CONFIG_INJECT 'CONFIG_SERIAL_CONSOLE_ENABLE=' 'CONFIG_SERIAL_CONSOLE_ENABLE=1' /boot/dietpi.txt @@ -1557,7 +1545,7 @@ Do you want to continue and DISABLE Bluetooth now?'; then G_DIETPI-NOTIFY 2 "Disabling serial-getty on: /dev/$INPUT_ADDITIONAL" # Stop getty only if not currently attached, failsafe estimation in case of symlinks local stop='--now' - [[ $(readlink -f $(tty)) == $(readlink -f /dev/$INPUT_ADDITIONAL) ]] && stop='' + [[ $(readlink -f $(tty)) == $(readlink -f /dev/$INPUT_ADDITIONAL) ]] && stop= systemctl disable $stop serial-getty@$INPUT_ADDITIONAL # Place a mask only if device exists [[ -e /dev/$INPUT_ADDITIONAL ]] && systemctl mask serial-getty@$INPUT_ADDITIONAL @@ -1566,7 +1554,7 @@ Do you want to continue and DISABLE Bluetooth now?'; then # - RPi if (( $G_HW_MODEL < 10 )); then - sed -i "s/[[:blank:]]*console=${INPUT_ADDITIONAL}[^\"[:blank:]]*//" /boot/cmdline.txt + sed -Ei "s/[[:blank:]]*console=${INPUT_ADDITIONAL}[^[:blank:]]*([[:blank:]]*$)?//" /boot/cmdline.txt # - Odroid C1/C2/XU4 elif (( $G_HW_MODEL < 12 )); then @@ -1575,7 +1563,7 @@ Do you want to continue and DISABLE Bluetooth now?'; then elif (( $ARMBIAN )); then - grep -q "console=$INPUT_ADDITIONAL" /boot/boot.cmd || return + grep -q "console=$INPUT_ADDITIONAL" /boot/boot.cmd || return 0 if grep -qE 'console=(display|both)' $FP_UENV; then G_CONFIG_INJECT 'console=' 'console=display' $FP_UENV @@ -1586,10 +1574,10 @@ Do you want to continue and DISABLE Bluetooth now?'; then fi - # - Pine A64: On ARMbian ttyS0 boot output is forced and custom console is not possible via armbianEnv.txt + # - PINE A64: On Armbian ttyS0 boot output is forced and custom console is not possible via armbianEnv.txt elif (( $G_HW_MODEL == 40 )); then - sed -i "/^[[:blank:]]*console=${INPUT_ADDITIONAL}[^\"[:blank:]]*$/d" $FP_UENV # New style: One variable each line + sed -i "/^[[:blank:]]*console=${INPUT_ADDITIONAL}[^\"[:blank:]]*[[:blank:]]*$/d" $FP_UENV # New style: One variable each line sed -i "s/[[:blank:]]*console=${INPUT_ADDITIONAL}[^\"[:blank:]]*//" $FP_UENV # Old style: Multiple variables possible each line #elif (( $G_HW_MODEL == 70 )); then @@ -1621,7 +1609,7 @@ Do you want to continue and DISABLE Bluetooth now?'; then done # On RPi disable primary UART device - (( $G_HW_MODEL < 10 )) && G_CONFIG_INJECT 'enable_uart=' 'enable_uart=0' /boot/config.txt + (( $G_HW_MODEL > 9 )) || G_CONFIG_INJECT 'enable_uart=' 'enable_uart=0' /boot/config.txt # Update dietpi.txt global var G_CONFIG_INJECT 'CONFIG_SERIAL_CONSOLE_ENABLE=' 'CONFIG_SERIAL_CONSOLE_ENABLE=0' /boot/dietpi.txt @@ -1747,14 +1735,14 @@ Do you want to continue and DISABLE Bluetooth now?'; then Soundcard_Reset_H2(){ # Set 3.5mm - [[ $INPUT_DEVICE_VALUE == 'none' ]] || amixer set -c 0 'Audio lineout' unmute &> /dev/null + [[ $INPUT_DEVICE_VALUE == 'none' ]] || amixer set -c 0 'Audio lineout' unmute 2> /dev/null } Soundcard_Reset_H3(){ # Set HDMI - [[ $INPUT_DEVICE_VALUE == 'none' ]] || amixer set -c 0 'Audio lineout' mute &> /dev/null + [[ $INPUT_DEVICE_VALUE == 'none' ]] || amixer set -c 0 'Audio lineout' mute 2> /dev/null SOUNDCARD_TARGET_CARD=1 } @@ -2197,7 +2185,7 @@ _EOF_ elif [[ $INPUT_DEVICE_NAME == 'bluetooth' ]]; then - Bluetooth_Main + Bluetooth_Main || EXIT_CODE=1 elif [[ $INPUT_DEVICE_NAME == 'wifimodules' ]]; then @@ -2262,7 +2250,7 @@ _EOF_ fi #----------------------------------------------------------------------------------- - G_DIETPI-NOTIFY -1 $EXIT_CODE "$INPUT_DEVICE_NAME $INPUT_DEVICE_VALUE |" + G_DIETPI-NOTIFY -1 $EXIT_CODE "$INPUT_DEVICE_NAME $INPUT_DEVICE_VALUE" #----------------------------------------------------------------------------------- exit $EXIT_CODE #----------------------------------------------------------------------------------- diff --git a/dietpi/func/dietpi-set_software b/dietpi/func/dietpi-set_software index ea81888ebe..9bdd2b498e 100644 --- a/dietpi/func/dietpi-set_software +++ b/dietpi/func/dietpi-set_software @@ -595,7 +595,7 @@ It is highly recommended to change this password, ideally, it should be differen fi #----------------------------------------------------------------------------------- - G_DIETPI-NOTIFY -1 $EXIT_CODE "$INPUT_MODE_NAME $INPUT_MODE_VALUE |" + G_DIETPI-NOTIFY -1 $EXIT_CODE "$INPUT_MODE_NAME $INPUT_MODE_VALUE" #----------------------------------------------------------------------------------- exit $EXIT_CODE #----------------------------------------------------------------------------------- diff --git a/dietpi/func/dietpi-set_swapfile b/dietpi/func/dietpi-set_swapfile index 4a3365a361..e55f3588de 100644 --- a/dietpi/func/dietpi-set_swapfile +++ b/dietpi/func/dietpi-set_swapfile @@ -1,7 +1,7 @@ #!/bin/bash { #//////////////////////////////////// - # DietPi Function: Swapfile + # DietPi Function: swap file # #//////////////////////////////////// # Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com @@ -9,12 +9,13 @@ #//////////////////////////////////// # # Info: - # - DietPi Swapfile control for setting enable/disable/size/location. + # - Location: /boot/dietpi/func/dietpi-set_swapfile + # - Allows set the swap file size and path or disable it, based in input arguments, dietpi.txt entry, existing swap file or default, in that priority order. # # Usage: - # - $1 = 0=disable, 1=enable+autosize, >=2=enable+size - # - $2 = optional location - # - /boot/dietpi/func/dietpi-set_swapfile = Print current swap size and location + # - = Print currently active swap locations from /proc/swaps + # - $1 = swap file size [MiB], use "0" to disable or "1" for auto-choice assuring min 2048 MiB total memory, respectively 50% of RAM size when used with "zram" + # - $2 = swap file path, or use "zram" to create a zram-swap on /dev/zram0 instead #//////////////////////////////////// # Import DietPi-Globals -------------------------------------------------------------- @@ -24,130 +25,184 @@ G_INIT # Import DietPi-Globals -------------------------------------------------------------- - SWAP_SIZE=$(sed -n '/^[[:blank:]]*AUTO_SETUP_SWAPFILE_SIZE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - SWAP_LOCATION=$(sed -n '/^[[:blank:]]*AUTO_SETUP_SWAPFILE_LOCATION=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) + EXIT_CODE=0 - disable_error=1 G_CHECK_VALIDINT "$1" && SWAP_SIZE_TARGET=$1 || SWAP_SIZE_TARGET=$SWAP_SIZE - [[ $2 ]] && SWAP_LOCATION_TARGET=$2 || SWAP_LOCATION_TARGET=$SWAP_LOCATION + # Check and apply valid input, else dietpi.txt entry, else current swap file, else revert to defaults + # - Size + if disable_error=1 G_CHECK_VALIDINT "$1"; then + + SWAP_SIZE=$1 + + elif ! SWAP_SIZE=$(sed -n '/^[[:blank:]]*AUTO_SETUP_SWAPFILE_SIZE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) || ! disable_error=1 G_CHECK_VALIDINT "$SWAP_SIZE"; then + + SWAP_SIZE=$(mawk '$2=="file" {printf "%.0f",$3/1024;exit}' /proc/swaps) && disable_error=1 G_CHECK_VALIDINT "$SWAP_SIZE" || SWAP_SIZE=1 + + fi + # - Path: Store current saved (only absolute paths to exclude zram) and active paths for later use + SWAP_PATH_CURRENT=$(sed -n '/^[[:blank:]]*AUTO_SETUP_SWAPFILE_LOCATION=\//{s/^[^=]*=//p;q}' /boot/dietpi.txt) + read -ra SWAP_FILES_ACTIVE < <(mawk '$2=="file" {print $1}' /proc/swaps) + if [[ $2 == '/'* || $2 == 'zram' ]]; then + + SWAP_PATH=$2 + + elif SWAP_PATH=$SWAP_PATH_CURRENT; [[ $SWAP_PATH != '/'* && $2 != 'zram' ]]; then + + SWAP_SIZE=$(mawk '$2=="file" {print $1;exit}' /proc/swaps) && [[ $2 == '/'* || $2 == 'zram' ]] || SWAP_PATH='/var/swap' + + fi Update_DietPi_Conf(){ G_CONFIG_INJECT 'AUTO_SETUP_SWAPFILE_SIZE=' "AUTO_SETUP_SWAPFILE_SIZE=$SWAP_SIZE" /boot/dietpi.txt - G_CONFIG_INJECT 'AUTO_SETUP_SWAPFILE_LOCATION=' "AUTO_SETUP_SWAPFILE_LOCATION=$SWAP_LOCATION" /boot/dietpi.txt + [[ $SWAP_FS == 'zram' ]] && SWAP_PATH='zram' # Revert zram path to input value + G_CONFIG_INJECT 'AUTO_SETUP_SWAPFILE_LOCATION=' "AUTO_SETUP_SWAPFILE_LOCATION=$SWAP_PATH" /boot/dietpi.txt } Update_Tmp(){ # Set /tmp to 50% of RAM+SWAP: https://github.com/MichaIng/DietPi/issues/1027#issuecomment-369373082 - local tmp_target_size="$(( $(free -tm | mawk '/^Total:/{print $2;exit}') / 2 ))M" + local tmp_size=$(( $(free -tm | mawk '/^Total:/{print $2;exit}') / 2 )) - G_DIETPI-NOTIFY 2 "Setting /tmp tmpfs size: $tmp_target_size" + G_DIETPI-NOTIFY 2 "Setting /tmp tmpfs size: $tmp_size MiB" - sed -i "/[[:blank:]]\/tmp[[:blank:]]/ctmpfs \/tmp tmpfs size=$tmp_target_size,noatime,lazytime,nodev,nosuid,mode=1777" /etc/fstab + # Apply to existing fstab entry + sed -i "/[[:blank:]]\/tmp[[:blank:]]/ctmpfs \/tmp tmpfs size=${tmp_size}M,noatime,lazytime,nodev,nosuid,mode=1777" /etc/fstab systemctl daemon-reload - mount -a # Required if /tmp was somehow not mounted before. Will be skipped if already mounted - G_EXEC mount -o remount /tmp # Required to apply new settings/size. "remount" required to preserve current content, or, doubled mount + + # Apply now to existing mount via "remount" to preserve current content and avoid doubled mount + findmnt /tmp > /dev/null && G_EXEC mount -o remount /tmp } Swap_Disable(){ - G_DIETPI-NOTIFY 0 'Disable swapfile' - + G_DIETPI-NOTIFY 2 'Disabling and deleting all existing swap files' G_EXEC swapoff -a - if [[ -f $SWAP_LOCATION ]]; then - - G_DIETPI-NOTIFY 2 "Deleting existing swapfile: $SWAP_LOCATION" - rm "$SWAP_LOCATION" - - fi + rm -fv "$SWAP_PATH_CURRENT" "${SWAP_FILES_ACTIVE[@]}" sed -i '/[[:blank:]]swap[[:blank:]]/d' /etc/fstab - - SWAP_SIZE=0 - SWAP_LOCATION='/var/swap' + # zram-swap + [[ -f '/etc/modules-load.d/dietpi-zram-swap.conf' ]] && rm -v /etc/modules-load.d/dietpi-zram-swap.conf + [[ -f '/etc/udev/rules.d/98-dietpi-zram-swap.rules' ]] && rm -v /etc/udev/rules.d/98-dietpi-zram-swap.rules } + # Create new swappey whappey Swap_Enable(){ - local swap_dir="${SWAP_LOCATION_TARGET%/*}/" - local fs_type=$(findmnt -no FSTYPE -T "$swap_dir") - - # Exclude devices - # - BBB - if (( $G_HW_MODEL == 71 )); then + G_DIETPI-NOTIFY 0 'Generating new swap space' + G_DIETPI-NOTIFY 2 "Size = $SWAP_SIZE MiB" + G_DIETPI-NOTIFY 2 "Path = $SWAP_PATH" - G_DIETPI-NOTIFY 1 "Disabled swapfile generation for: $G_HW_MODEL_NAME" + # zram + if [[ $SWAP_FS == 'zram' ]]; then - # Exclude file systems - elif [[ $fs_type == 'btrfs' ]]; then + [[ -b '/dev/zram0' ]] || G_EXEC modprobe zram + G_EXEC eval 'echo 1 > /sys/block/zram0/reset' + G_EXEC eval "echo '${SWAP_SIZE}M' > /sys/block/zram0/disksize" - G_DIETPI-NOTIFY 1 "Swapfile not supported on file system: $fs_type" + # Pre-allocate for filesystems which do no support quick-allocate with fallocate + elif [[ $SWAP_FS == 'f2fs' || $SWAP_FS == 'xfs' || $SWAP_FS == 'vfat' ]]; then - # Free spacey, checkey weckey - elif ! G_CHECK_FREESPACE "$swap_dir" $SWAP_SIZE_TARGET; then + G_EXEC dd if=/dev/zero of="$SWAP_PATH" bs=4K count=$(( $SWAP_SIZE * 1024 / 4 )) - G_DIETPI-NOTIFY 1 'Unable to generate swapfile due to insufficient disk space. Swap has been disabled.' - - # Create new swappey whappey else - SWAP_SIZE=$SWAP_SIZE_TARGET - SWAP_LOCATION=$SWAP_LOCATION_TARGET + G_EXEC fallocate -l $SWAP_SIZE'M' "$SWAP_PATH" - G_DIETPI-NOTIFY 0 'Generating new swapfile' - G_DIETPI-NOTIFY 2 "Size = $SWAP_SIZE MB" - G_DIETPI-NOTIFY 2 "Location = $SWAP_LOCATION" + fi - # - Pre-allocate for filesystems which do no support quick-allocate with fallocate - if [[ $fs_type == 'f2fs' || $fs_type == 'xfs' || $fs_type == 'vfat' ]]; then + G_EXEC mkswap "$SWAP_PATH" + [[ $SWAP_FS == 'zram' ]] || G_EXEC_NOHALT=1 G_EXEC chmod 600 "$SWAP_PATH" # Allow to fail on filesystems without UNIX permission support + G_EXEC swapon "$SWAP_PATH" - G_EXEC dd if=/dev/zero of="$SWAP_LOCATION" bs=4K count=$(( $SWAP_SIZE * 1024 / 4 )) + # Make persistent, proceed with failure in case of R/O rootfs + # - zram + if [[ $SWAP_FS == 'zram' ]]; then - else + G_EXEC_NOHALT=1 G_EXEC eval "echo 'zram' > /etc/modules-load.d/dietpi-zram-swap.conf" || EXIT_CODE=1 + G_EXEC_NOHALT=1 G_EXEC eval "echo 'SUBSYSTEM==\"block\", KERNEL==\"zram0\", ACTION==\"add\", ATTR{disksize}=\"${SWAP_SIZE}M\", RUN+=\"/sbin/mkswap /dev/zram0\", RUN+=\"/sbin/swapon /dev/zram0\"' > /etc/udev/rules.d/98-dietpi-zram-swap.rules" || EXIT_CODE=1 + G_EXEC_NOHALT=1 G_EXEC eval "echo 'swappiness=50' > /etc/sysctl.d/98-dietpi-zram-swap.conf" || EXIT_CODE=1 - G_EXEC fallocate -l $SWAP_SIZE'M' "$SWAP_LOCATION" + # - swap file + else - fi + G_EXEC_NOHALT=1 G_EXEC eval "echo '$SWAP_PATH none swap sw' >> /etc/fstab" || EXIT_CODE=1 - G_EXEC mkswap "$SWAP_LOCATION" - chmod 600 "$SWAP_LOCATION" - G_EXEC swapon "$SWAP_LOCATION" + fi - echo "$SWAP_LOCATION none swap sw 0 0" >> /etc/fstab + } - fi + Error_Reset(){ + + G_DIETPI-NOTIFY 1 "$*" + G_DIETPI-NOTIFY 2 'Leaving swap space disabled' + SWAP_SIZE=0 EXIT_CODE=1 } #///////////////////////////////////////////////////////////////////////////////////// # Main Loop #///////////////////////////////////////////////////////////////////////////////////// - # Info mode - Print Size / Location - if [[ ! $1 ]]; then + G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" "Applying $SWAP_SIZE $SWAP_PATH" - echo "$SWAP_SIZE $SWAP_LOCATION" + # Always reset existing swap files + Swap_Disable - # Remove/Create swap + # zram-swap + if [[ $SWAP_PATH == 'zram' ]]; then + + (( $SWAP_SIZE == 1 )) && SWAP_SIZE=$(( $(free -m | mawk '/^Mem:/{print $2;exit}') / 2 )) # Auto size + SWAP_PATH='/dev/zram0' SWAP_FS='zram' + + # swap file else - G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" 'Apply' + # Auto size: Skip if size would be less than 100 MiB, since else on all 2 GiB SBCs there is a non-reasonable ~50 MiB swap file created + if (( $SWAP_SIZE == 1 )); then + + SWAP_SIZE=$(( 2048 - $(free -m | mawk '/^Mem:/{print $2;exit}') )) + if (( $SWAP_SIZE > 1 && $SWAP_SIZE < 100 )); then + + G_DIETPI-NOTIFY 0 "Skipping the auto-creation of a tiny $SWAP_SIZE MiB swap file" + G_DIETPI-NOTIFY 0 'Set < 100 MiB values manually to create such small swap files' + SWAP_SIZE=0 + + fi + + fi + SWAP_DIR="${SWAP_PATH%/*}/" SWAP_FS=$(findmnt -no FSTYPE -T "$SWAP_DIR") + + fi + + # Disable + if (( $SWAP_SIZE < 1 )); then + + SWAP_SIZE=0 + + # Unsupported on Btrfs + elif [[ $SWAP_FS == 'btrfs' ]]; then - # Always reset/remove existing swap - Swap_Disable + Error_Reset 'Swap files are not supported on Btrfs file system.' - # Auto size? - (( $SWAP_SIZE_TARGET == 1 )) && SWAP_SIZE_TARGET=$(( 2048 - $(free -m | mawk '/^Mem:/{print $2;exit}') )) + # Free spacey, checkey weckey: zram < RAM size + elif [[ $SWAP_FS == 'zram' ]] && (( $(free -m | mawk '/^Mem:/{print $2;exit}') <= $SWAP_SIZE )); then - # Configure new swapfile? - (( $SWAP_SIZE_TARGET > 0 )) && Swap_Enable + Error_Reset 'Insufficient RAM size for desired zram-swap size' - Update_DietPi_Conf - Update_Tmp + elif [[ $SWAP_FS != 'zram' ]] && ! G_CHECK_FREESPACE "$SWAP_DIR" $SWAP_SIZE; then + + Error_Reset 'Insufficient free space for desired swap files size' + + else + + Swap_Enable fi + + Update_DietPi_Conf + Update_Tmp #----------------------------------------------------------------------------------- - exit 0 + exit $EXIT_CODE #----------------------------------------------------------------------------------- } diff --git a/dietpi/func/dietpi-set_userdata b/dietpi/func/dietpi-set_userdata index 118299b3e6..631330d76d 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 SOURCE_DIRECTORY TARGET_DIRECTORY | Setup user data directory, move data if needed. If TARGET_DIRECTORY='auto', auto target location. Returns 1 if failed. #//////////////////////////////////// # Import DietPi-Globals -------------------------------------------------------------- @@ -40,13 +40,13 @@ /boot/dietpi/dietpi-services stop # Copy source to target, if it contains any files/folders - if [[ -z $(find $SOURCE_DIRECTORY -maxdepth 0 -empty) ]]; then + if [[ -z $(find "$SOURCE_DIRECTORY" -maxdepth 0 -empty) ]]; then G_DIETPI-NOTIFY 0 "Moving your existing data from $SOURCE_DIRECTORY to $TARGET_DIRECTORY" G_DIETPI-NOTIFY 2 'Please wait...\n' # Begin transfer - if cp -a "$SOURCE_DIRECTORY"/. "$TARGET_DIRECTORY"/; then + if cp -a "$SOURCE_DIRECTORY/." "$TARGET_DIRECTORY/"; then # Remove source rm -R "$SOURCE_DIRECTORY" @@ -59,11 +59,11 @@ fi - LOGFILE_OUTPUT_TEXT="SUCCESS: Successfully moved your data from $SOURCE_DIRECTORY to $TARGET_DIRECTORY" + LOGFILE_OUTPUT_TEXT="[ OK ] Successfully moved your data from $SOURCE_DIRECTORY to $TARGET_DIRECTORY" else - LOGFILE_OUTPUT_TEXT="ERROR: Failed to copy $SOURCE_DIRECTORY/ to $TARGET_DIRECTORY." + LOGFILE_OUTPUT_TEXT="[FAILED] Failed to copy $SOURCE_DIRECTORY/ to $TARGET_DIRECTORY." EXIT_CODE=1 fi @@ -88,30 +88,30 @@ # - Check for both inputs if [[ ! $SOURCE_DIRECTORY || ! $TARGET_DIRECTORY ]]; then - LOGFILE_OUTPUT_TEXT="ERROR: Please provide a source ($SOURCE_DIRECTORY) and target ($TARGET_DIRECTORY) directory for input." + LOGFILE_OUTPUT_TEXT="[FAILED] Please provide a source ($SOURCE_DIRECTORY) and target ($TARGET_DIRECTORY) directory for input." EXIT_CODE=1 # - Check if symlink is already pointing to target directory - elif [[ $(readlink -f $G_FP_DIETPI_USERDATA) == $TARGET_DIRECTORY ]]; then + elif [[ $(readlink -f $G_FP_DIETPI_USERDATA) == "$TARGET_DIRECTORY" ]]; then - LOGFILE_OUTPUT_TEXT="INFO: $G_FP_DIETPI_USERDATA is already symlinked to target directory." + LOGFILE_OUTPUT_TEXT="[ INFO ] $G_FP_DIETPI_USERDATA is already symlinked to target directory." # - Check if source directory exists elif [[ ! -d $SOURCE_DIRECTORY ]]; then - LOGFILE_OUTPUT_TEXT="ERROR: Source directory $SOURCE_DIRECTORY does not exist." + LOGFILE_OUTPUT_TEXT="[FAILED] Source directory $SOURCE_DIRECTORY does not exist." EXIT_CODE=1 # - Check for disallowed directory match elif [[ $SOURCE_DIRECTORY =~ $TARGET_DIRECTORY || $TARGET_DIRECTORY =~ $SOURCE_DIRECTORY ]]; then - LOGFILE_OUTPUT_TEXT="ERROR: $SOURCE_DIRECTORY and $TARGET_DIRECTORY cannot be within each other. Disallowed directory match." + LOGFILE_OUTPUT_TEXT="[FAILED] $SOURCE_DIRECTORY and $TARGET_DIRECTORY cannot be within each other. Disallowed directory match." EXIT_CODE=1 # - Only allow full filepaths elif [[ $SOURCE_DIRECTORY != '/'* || $TARGET_DIRECTORY != '/'* ]]; then - LOGFILE_OUTPUT_TEXT="ERROR: Both source ($SOURCE_DIRECTORY) and target directories ($TARGET_DIRECTORY) must contain the full filepath (eg: /mnt/drive1)" + LOGFILE_OUTPUT_TEXT="[FAILED] Both source ($SOURCE_DIRECTORY) and target directories ($TARGET_DIRECTORY) must contain the full filepath (eg: /mnt/drive1)" EXIT_CODE=1 else @@ -121,9 +121,9 @@ mkdir -p "$TARGET_DIRECTORY" # - Ensure we can create, write and set permissions to target directory - if ! G_CHECK_FS_PERMISSION_SUPPORT $TARGET_DIRECTORY; then + if ! G_CHECK_FS_PERMISSION_SUPPORT "$TARGET_DIRECTORY"; then - LOGFILE_OUTPUT_TEXT="ERROR: $TARGET_DIRECTORY does not support filesystem permissions. Transfer aborted." + LOGFILE_OUTPUT_TEXT="[FAILED] $TARGET_DIRECTORY does not support filesystem permissions. Transfer aborted." EXIT_CODE=1 else @@ -132,9 +132,9 @@ # "-m" => result in MiB actual disc 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 + if ! G_CHECK_FREESPACE "$TARGET_DIRECTORY" "$FREESPACE_REQUIRED_SOURCE"; then - LOGFILE_OUTPUT_TEXT="ERROR: Not enough free space in target directory $TARGET_DIRECTORY.\n - Required: $FREESPACE_REQUIRED_SOURCE MiB" + LOGFILE_OUTPUT_TEXT="[FAILED] Not enough free space in target directory $TARGET_DIRECTORY.\n - Required: $FREESPACE_REQUIRED_SOURCE MiB" EXIT_CODE=1 else @@ -171,7 +171,7 @@ fi #----------------------------------------------------------------------------------- - G_DIETPI-NOTIFY -1 $EXIT_CODE + G_DIETPI-NOTIFY -1 $EXIT_CODE "$G_PROGRAM_NAME" #----------------------------------------------------------------------------------- exit $EXIT_CODE #----------------------------------------------------------------------------------- diff --git a/dietpi/func/run_ntpd b/dietpi/func/run_ntpd index 4e9476fb49..e543657b0c 100644 --- a/dietpi/func/run_ntpd +++ b/dietpi/func/run_ntpd @@ -120,7 +120,7 @@ NB: We highly recommend choosing "Retry" first. Failing that, try to change the [[ $INPUT != 1 && -f $FP_EXIT_CODE && $(<$FP_EXIT_CODE) == 0 ]] && EXIT_CODE=0 || Update_NTPD # Return status - G_DIETPI-NOTIFY -1 $EXIT_CODE 'Network time sync |' + G_DIETPI-NOTIFY -1 $EXIT_CODE 'Network time sync' if (( $EXIT_CODE )); then G_DIETPI-NOTIFY 2 'Please check the service status for more information:' diff --git a/dietpi/misc/start_kodi b/dietpi/misc/start_kodi index bc8f6cc7cf..0992b34597 100644 --- a/dietpi/misc/start_kodi +++ b/dietpi/misc/start_kodi @@ -33,13 +33,7 @@ elif [[ $DISPLAY ]]; then # C2 fix for stuttering and laggy audio: https://github.com/MichaIng/DietPi/issues/399#issuecomment-229413994 - if (( $G_HW_MODEL == 12 )); then - - killall -w xcompmgr - xcompmgr -a & - sleep 2 - - fi + (( $G_HW_MODEL == 12 )) && command -v xcompmgr > /dev/null && killall -w xcompmgr && xcompmgr -a & && sleep 2 kodi diff --git a/dietpi/patch_file b/dietpi/patch_file index 724270cc67..73e41c194d 100644 --- a/dietpi/patch_file +++ b/dietpi/patch_file @@ -1126,8 +1126,8 @@ You will not face any practical differences, since both services start the same # v6.27 Allo GUI: https://github.com/MichaIng/DietPi/issues/2305 # v6.27 GMrender: Due to Allo GUI service enable failure. # Xorg: XU4 conf - # Pydio: https://github.com/MichaIng/DietPi/issues/2308 - (( $G_DIETPI_INSTALL_STAGE == 2 )) && echo 6 48 113 >> /var/tmp/dietpi/dietpi-update_reinstalls + # v6.23 Pydio: https://github.com/MichaIng/DietPi/issues/2308 + (( $G_DIETPI_INSTALL_STAGE == 2 )) && echo 6 113 >> /var/tmp/dietpi/dietpi-update_reinstalls #------------------------------------------------------------------------------- elif (( $G_DIETPI_VERSION_SUB == 19 )); then @@ -1543,11 +1543,10 @@ Further info and usage: https://dietpi.com/phpbb/viewtopic.php?f=8&t=5828' fi #----------------------------------------------------------------------- # PHP7.3 migration: https://github.com/MichaIng/DietPi/issues/2367 - local upgrade_php= # - Only upgrade versions lower than 7.2 and skip any check version Buster+ where this is impossible if (( $G_DISTRO < 5 )) && grep -q '^aSOFTWARE_INSTALL_STATE\[89\]=2' /boot/dietpi/.installed && ! command -v php7.{2,3} &> /dev/null; then - upgrade_php=89 + echo 89 >> /var/tmp/dietpi/dietpi-update_reinstalls # Software which does not support PHP7.3, install PHP7.2 instead local PHP_NAME='php7.3' @@ -1575,13 +1574,11 @@ NBB: Reinstall manually installed PHP modules via: G_AGI $PHP_NAME-" # - Nginx [[ -f '/etc/nginx/nginx.conf' ]] && sed -i "s#/run/php.*-fpm.sock#/run/php/$PHP_NAME-fpm.sock#g" /etc/nginx/nginx.conf - fi - #----------------------------------------------------------------------- - # Re-create /etc/sysctl.d/99-sysctl.conf -> ../sysctl.conf symlink if not existent: https://github.com/MichaIng/DietPi/issues/2505 - if [[ ! -L '/etc/sysctl.d/99-sysctl.conf' ]]; then + # Mark old PHP packages for autoremoval + apt-mark auto $(dpkg --get-selections php7.{0,1}-* libapache2-mod-php7.{0,1} 2> /dev/null | mawk '{print $1}') 2> /dev/null - [[ -e '/etc/sysctl.d/99-sysctl.conf' ]] && mv /etc/sysctl.d/99-sysctl.conf /etc/sysctl.conf - ln -sf ../sysctl.conf /etc/sysctl.d/99-sysctl.conf + # Disable old mod-php so that new version is enabled automatically on package install + command -v a2dismod &> /dev/null && a2dismod php7.{0,1} 2> /dev/null fi #----------------------------------------------------------------------- @@ -1597,6 +1594,7 @@ NBB: Reinstall manually installed PHP modules via: G_AGI $PHP_NAME-" mv /etc/systemd/system/squeezeboxserver.service /etc/systemd/system/logitechmediaserver.service fi + [[ -d '/etc/systemd/system/squeezeboxserver.service.d' ]] && mv /etc/systemd/system/squeezeboxserver.service.d /etc/systemd/system/logitechmediaserver.service.d # SABnzbd: https://github.com/MichaIng/DietPi/pull/2768 # v6.27 Jackett: https://github.com/MichaIng/DietPi/pull/2773 if [[ -d '/opt/jackett/.config' ]]; then @@ -1605,34 +1603,7 @@ NBB: Reinstall manually installed PHP modules via: G_AGI $PHP_NAME-" rm -R /opt/jackett/.config fi - echo 34 35 42 139 $upgrade_php >> /var/tmp/dietpi/dietpi-update_reinstalls - #----------------------------------------------------------------------- - # Remove old PHP version - if [[ $upgrade_php ]]; then - - G_AGP php{7.0,7.1}-* libapache2-mod-php{7.0,7.1} - # New mod-php must be enabled manually since this is skipped by APT as long as prior version is active - command -v a2enmod &> /dev/null && a2enmod $PHP_NAME - - # Recover ownCloud, Nextcloud and Pydio PHP modules - if grep -q '^aSOFTWARE_INSTALL_STATE\[47\]=2' /boot/dietpi/.installed; then - - G_AGI $PHP_NAME-intl - echo -e '; ownCloud PHP settngs\n; priority=99\napc.enable_cli=1' > /etc/php/${PHP_NAME#php}/mods-available/dietpi-owncloud.ini - phpenmod dietpi-owncloud - - fi - if grep -q '^aSOFTWARE_INSTALL_STATE\[114\]=2' /boot/dietpi/.installed; then - - G_AGI $PHP_NAME-intl - echo -e '; Nextcloud PHP settngs\n; priority=99\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=1' > /etc/php/${PHP_NAME#php}/mods-available/dietpi-nextcloud.ini - phpenmod dietpi-nextcloud - - fi - grep -q '^aSOFTWARE_INSTALL_STATE\[48\]=2' /boot/dietpi/.installed && G_AGI $PHP_NAME-intl - - fi + echo 34 35 42 47 48 114 139 >> /var/tmp/dietpi/dietpi-update_reinstalls fi #------------------------------------------------------------------------------- @@ -2098,37 +2069,6 @@ _EOF_ # Unhold ARMbian packages (set on hold via DietPi-PREP until v6.27) [[ -f '/etc/armbian-release' ]] && apt-mark unhold $(dpkg-query -Wf '${package }' linux-{dtb,u,image,$G_DISTRO_NAME}-* sunxi-tools 2> /dev/null) #------------------------------------------------------------------------------- - # RPi: Update USBridgeSig Ethernet driver via postinst kernel script, until it has been merged into official RPi kernel: https://github.com/allocom/USBridgeSig/tree/master/ethernet - if (( $G_HW_MODEL < 10 )); then - - cat << _EOF_ > /etc/kernel/postinst.d/dietpi-USBridgeSig -#!/bin/bash -# Only apply to ARMv7+ kernel -[[ \$1 == *'-v7+' ]] || exit 0 -echo "[ INFO ] Updating asix ax88179 driver for kernel \$1, as provided by allo.com:" -echo '[ INFO ] - https://github.com/allocom/USBridgeSig/tree/master/ethernet' -echo '[ INFO ] Downloading driver...' -wget http://3.230.113.73:9011/Allocom/USBridgeSig/rpi-usbs-\$1/ax88179_178a.ko -O /tmp/ax88179_178a.ko || exit 0 -echo '[ INFO ] Installing driver...' -install -vpm 644 /tmp/ax88179_178a.ko /lib/modules/\$1/kernel/drivers/net/usb || exit 0 -echo '[ INFO ] Running depmod...' -depmod \$1 || exit 0 -echo '[ INFO ] Cleaning up...' -rm -v /tmp/ax88179_178a.ko || exit 0 -_EOF_ - chmod +x /etc/kernel/postinst.d/dietpi-USBridgeSig - # Update for all installed ARMv7+ kernel versions now - for i in /lib/modules/*-v7+ - do - - [[ -d $i ]] || continue - i=${i##*/} - /etc/kernel/postinst.d/dietpi-USBridgeSig $i - - done - - fi - #------------------------------------------------------------------------------- # Reinstalls # Syncthing: https://github.com/MichaIng/DietPi/pull/3202 # Grafana: https://github.com/MichaIng/DietPi/issues/3213 @@ -2463,6 +2403,89 @@ To reinstall now, run: "dietpi-software reinstall 106 144 145" fi #------------------------------------------------------------------------------- + + elif (( $G_DIETPI_VERSION_SUB == 31 )); then + + #------------------------------------------------------------------------------- + # APT configs have been merged into a single file, contained in update archive + rm -fv /etc/apt/apt.conf.d/{99-dietpi-norecommends,98-dietpi-no_translations,99-dietpi-forceconf} + #------------------------------------------------------------------------------- + # RPi: Update USBridgeSig Ethernet driver via postinst kernel script, until it has been merged into official RPi kernel: https://github.com/allocom/USBridgeSig/tree/master/ethernet + if (( $G_HW_MODEL < 10 )); then + + cat << _EOF_ > /etc/kernel/postinst.d/dietpi-USBridgeSig +#!/bin/bash +# Only apply to v7+ and v8+ kernel +[[ \$1 == *'-v'[78]'+' ]] || exit 0 +echo "[ INFO ] Updating asix ax88179 driver for kernel \$1, as provided by allo.com:" +echo '[ INFO ] - https://github.com/allocom/USBridgeSig/tree/master/ethernet' +echo '[ INFO ] Downloading driver...' +wget http://3.230.113.73:9011/Allocom/USBridgeSig/rpi-usbs-\$1/ax88179_178a.ko -O /tmp/ax88179_178a.ko || exit 0 +echo '[ INFO ] Installing driver...' +install -vpm 644 /tmp/ax88179_178a.ko /lib/modules/\$1/kernel/drivers/net/usb || exit 0 +echo '[ INFO ] Running depmod...' +depmod \$1 || exit 0 +echo '[ INFO ] Cleaning up...' +rm -v /tmp/ax88179_178a.ko || exit 0 +_EOF_ + chmod +x /etc/kernel/postinst.d/dietpi-USBridgeSig + # Update for all installed v7+ and v8+ kernel versions now + for i in /lib/modules/*-v[78]+ + do + + [[ -d $i ]] || continue + i=${i##*/} + /etc/kernel/postinst.d/dietpi-USBridgeSig $i + + done + + fi + #------------------------------------------------------------------------------- + [[ $G_HW_MODEL == [0-3] ]] && G_EXEC_DESC='Commenting "arm_freq_min" in config.txt until related system instabilities have been solved' G_EXEC sed -i 's/^[[:blank:]]*arm_freq_min=/#arm_freq_min=/' /boot/config.txt + #------------------------------------------------------------------------------- + [[ -f '/boot/config.txt' ]] && G_EXEC_DESC='Removing deprecated "max_usb_current" from config.txt' G_EXEC_NOHALT=1 G_EXEC sed -i '/^[[:blank:]#]*max_usb_current=/d' /boot/config.txt + #----------------------------------------------------------------------- + # Recreate /etc/sysctl.d/99-sysctl.conf -> ../sysctl.conf symlink if not existent: https://github.com/MichaIng/DietPi/issues/3003#issuecomment-669464255 + if [[ ! -L '/etc/sysctl.d/99-sysctl.conf' ]]; then + + [[ -e '/etc/sysctl.d/99-sysctl.conf' ]] && mv /etc/sysctl.d/99-sysctl.conf /etc/sysctl.conf + ln -sf ../sysctl.conf /etc/sysctl.d/99-sysctl.conf + + fi + #------------------------------------------------------------------------------- + # DietPi-LetsEncrypt: Lighttpd: Rename HTTPS config files to new scheme: https://github.com/MichaIng/DietPi/pull/3734 + if [[ $G_DIETPI_INSTALL_STAGE == 2 && -f '/boot/dietpi/.dietpi-letsencrypt' && -d '/etc/lighttpd/conf-enabled' ]]; then + + local f='/etc/lighttpd/conf-enabled/letsencrypt.conf' + if [[ -f $f && ! -L $f ]]; then + mv -v "$f" /etc/lighttpd/conf-available/50-dietpi-https.conf + lighty-enable-mod dietpi-https + fi + f='/etc/lighttpd/conf-enabled/redirect.conf' + if [[ -f $f && ! -L $f ]]; then + mv -v "$f" /etc/lighttpd/conf-available/98-dietpi-https_redirect.conf + lighty-enable-mod dietpi-https_redirect + fi + f='/etc/lighttpd/conf-available/99-dietpi-hsts.conf' + if [[ -f $f ]]; then + mv -v "$f" "${f/99/98}" + [[ -L ${f/available/enabled} ]] && { lighty-disable-mod dietpi-hsts; lighty-enable-mod dietpi-hsts; } + fi + + fi + #------------------------------------------------------------------------------- + # https://github.com/jirka-h/haveged/pull/7 https://github.com/MichaIng/DietPi/issues/3689#issuecomment-678322767 + if [[ $G_DISTRO == 5 && $G_HW_ARCH == [23] && $G_HW_MODEL -gt 9 ]] && dpkg-query -s haveged &> /dev/null; then + + G_DIETPI-NOTIFY 2 'Upgrading haveged entropy daemon to fix an issue on ARM:' + G_DIETPI-NOTIFY 2 ' - https://github.com/jirka-h/haveged/pull/7' + G_EXEC curl -sSfLO "https://dietpi.com/downloads/binaries/buster/libhavege2_$G_HW_ARCH_NAME.deb" + G_EXEC curl -sSfLO "https://dietpi.com/downloads/binaries/buster/haveged_$G_HW_ARCH_NAME.deb" + G_AGI "./libhavege2_$G_HW_ARCH_NAME.deb" "./haveged_$G_HW_ARCH_NAME.deb" + G_EXEC_NOHALT=1 G_EXEC rm "./libhavege2_$G_HW_ARCH_NAME.deb" "./haveged_$G_HW_ARCH_NAME.deb" + + fi + #------------------------------------------------------------------------------- # Last subversion patch completed # - Apply reinstalls if [[ -f '/var/tmp/dietpi/dietpi-update_reinstalls' ]]; then diff --git a/dietpi/postboot b/dietpi/postboot index cfce0f923a..9c640d221c 100644 --- a/dietpi/postboot +++ b/dietpi/postboot @@ -10,17 +10,14 @@ # # Info: # - Location: /boot/dietpi/postboot - # - Moves boot logs from /tmp to persistent dir # - DietPi-Update check and DietPi-Services start on regular boot # - Executes optional user scripts from: /var/lib/dietpi/postboot.d/ # - Prints login banner #//////////////////////////////////// + EXIT_CODE=0 G_DIETPI_INSTALL_STAGE=$( /dev/null & # Start DietPi controlled services - /boot/dietpi/dietpi-services start + /boot/dietpi/dietpi-services start || EXIT_CODE=$? fi @@ -38,8 +35,8 @@ [[ $f != *'/readme.txt' && -f $f ]] || continue [[ -x $f ]] || chmod +x $f - echo "DietPi-PostBoot | Running user script: ${f##*/}" - $f + echo -e "\e[90m[\e[0m INFO \e[90m] DietPi-PostBoot | Running user script: ${f##*/}\e[0m" + $f || { EXIT_CODE=$?; echo -e "\e[90m[\e[31mFAILED\e[90m] DietPi-PostBoot |\e[0m User script ${f##*/} failed with exit code: $EXIT_CODE"; } done @@ -55,6 +52,6 @@ fi #----------------------------------------------------------------------------------- - exit + exit $EXIT_CODE #----------------------------------------------------------------------------------- } diff --git a/dietpi/pre-patch_file b/dietpi/pre-patch_file index 7ec69af258..832175b47a 100644 --- a/dietpi/pre-patch_file +++ b/dietpi/pre-patch_file @@ -234,12 +234,20 @@ Package: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin- fi #------------------------------------------------------------------------------- # Pre-patch 21: Assure C.UTF-8 locale being available - if ! locale -a | grep -qiE '^C.UTF-?8'; then + if (( $G_DIETPI_VERSION_SUB < 31 )) && ! locale -a | grep -qiE '^C.UTF-?8'; then echo -e '\e[90m[\e[0m INFO \e[90m]\e[0m Pre-patch 21 | Compile C.UTF-8 locale as new DietPi default' localedef -ci C -f UTF-8 C.UTF-8 locale -a | grep -qiE '^C.UTF-?8' || exit 21 + fi + #------------------------------------------------------------------------------- + # Pre-patch 22: Switch to our new Meveric's Odroid repo mirror on https://dietpi.com/meveric/ + if (( $G_DIETPI_VERSION_SUB < 32 && $G_HW_MODEL > 10 && $G_HW_MODEL < 20 )); then + + echo -e "\e[90m[\e[0m INFO \e[90m]\e[0m Pre-patch 22 | Switch to our new Meveric's Odroid repo mirror on https://dietpi.com/meveric/" + sed -Ei 's|http://fuzon.co.uk|https://dietpi.com|' /etc/apt/sources.list{,.d/*.list} || exit 22 + fi #------------------------------------------------------------------------------- # Finished diff --git a/dietpi/server_version-6 b/dietpi/server_version-6 index e72506a847..4698899e51 100644 --- a/dietpi/server_version-6 +++ b/dietpi/server_version-6 @@ -1,3 +1,3 @@ 6 -31 -2 +32 +0 diff --git a/rootfs/etc/apt/apt.conf.d/97dietpi b/rootfs/etc/apt/apt.conf.d/97dietpi new file mode 100644 index 0000000000..cd7dee19fa --- /dev/null +++ b/rootfs/etc/apt/apt.conf.d/97dietpi @@ -0,0 +1,27 @@ +# DietPi APT config: /etc/apt/apt.conf.d/97dietpi +# Docs: https://manpages.debian.org/apt.conf +# NB: Overwrite via e.g. /etc/apt/apt.conf.d/99local, as this file is overwritten on dietpi-update. + +# Skip automated install of recommends/suggests and allow their autoremoval +APT::Install-Recommends "false"; +APT::Install-Suggests "false"; +APT::AutoRemove::RecommendsImportant "false"; +APT::AutoRemove::SuggestsImportant "false"; + +# Skip detailed and translated package description downloads +Acquire::Languages "none"; + +# Disable source package cache which most users will never use +Dir::Cache::srcpkgcache ""; + +# Keep lists xz-compressed which reduces list read speed significantly +# but reduces disk usage and writes in two ways: +# - Debian and Raspbian repos ship lists xz-compressed. +# - Using any other format (default: lz4) needs them to be uncompressed or recompressed, all performed on disk by default. +Acquire::GzipIndexes "true"; +Acquire::IndexTargets::deb::Packages::KeepCompressedAs "xz"; +Acquire::IndexTargets::deb::Translations::KeepCompressedAs "xz"; +Acquire::IndexTargets::deb-src::Sources::KeepCompressedAs "xz"; + +# Preserve modified and missing DEB package config files +DPkg::options:: "--force-confdef,confold"; diff --git a/rootfs/etc/bashrc.d/dietpi.bash b/rootfs/etc/bashrc.d/dietpi.bash index 1e9e0a4f96..ed328e0463 100644 --- a/rootfs/etc/bashrc.d/dietpi.bash +++ b/rootfs/etc/bashrc.d/dietpi.bash @@ -15,7 +15,7 @@ #//////////////////////////////////// # Failsafe: Never load this script in non-interactive shells, e.g. SFTP, SCP or rsync - [[ -t 0 && $PS1 && $- == *'i'* ]] || return 0 + [[ -t 0 && $- == *'i'* ]] || return 0 # DietPi-Globals: dietpi-* aliases, G_* functions and variables . /boot/dietpi/func/dietpi-globals || { echo -e '[\e[31mFAILED\e[0m] DietPi-Login | Failed to load DietPi-Globals. Skipping DietPi login scripts...'; return 1; } @@ -24,19 +24,20 @@ [[ $PROMPT_COMMAND == *'dietpi-process.pid'* ]] || PROMPT_COMMAND="[[ -w '/tmp/dietpi-process.pid' ]] && rm -f /tmp/dietpi-process.pid &> /dev/null && echo -ne '\r\e[J'; $PROMPT_COMMAND" # Workaround if SSH client overrides locale with "POSIX" fallback: https://github.com/MichaIng/DietPi/issues/1540#issuecomment-367066178 - if [[ $(locale) == *'POSIX'* ]]; then + if [[ ${LC_ALL:-${LANG:-POSIX}} == 'POSIX' ]]; then current_locale=$(sed -n '/^[[:blank:]]*AUTO_SETUP_LOCALE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - export LC_ALL=${current_locale:-C.UTF-8} - unset current_locale + export LC_ALL=${current_locale:=C.UTF-8} LANG=$current_locale + unset -v current_locale fi # Workaround if SSH client sets an unsupported $TERM string: https://github.com/MichaIng/DietPi/issues/2034 - if [[ $SSH_TTY ]] && ! toe -a | grep -q "^${TERM}[[:blank:]]"; then + if [[ $SSH_TTY ]] && ! infocmp "$TERM" &> /dev/null; then TERM_old=$TERM - [[ $TERM == *'256'* ]] && export TERM='xterm-256color' || export TERM='xterm' + export TERM='xterm' + [[ $TERM_old == *'256'* ]] && TERM+='-256color' G_WHIP_MENU_ARRAY=('0' 'Ignore for now, I will change the SSH clients terminal.') ncurses_term= @@ -51,7 +52,7 @@ G_PROGRAM_NAME='Unsupported SSH client terminal' G_WHIP_MENU "[WARNING] Your SSH client passed an unsupported terminal: TERM=$TERM_old\n As a workaround we fooled the server by setting: TERM=$TERM. This is not the cleanest solution, since commands might expect colours or formats, that are not supported by the actual terminal.\n Please change your SSH clients terminal, respectively the passed \$TERM string$ncurses_term." && (( $G_WHIP_RETURNED_VALUE )) && G_AGI ncurses-term - unset TERM_old ncurses_term + unset -v TERM_old ncurses_term fi diff --git a/rootfs/etc/bashrc.d/readme.txt b/rootfs/etc/bashrc.d/readme.txt new file mode 100644 index 0000000000..cfaf1c862d --- /dev/null +++ b/rootfs/etc/bashrc.d/readme.txt @@ -0,0 +1,3 @@ +# /etc/bashrc.d/ is implemented by DietPi to source custom scripts user-wide on interactive bash session starts. +# It works like /etc/profile.d/ but for all interactive bash shells as contained scripts are sourced from /etc/bash.bashrc. +# All files with .sh or .bash endings are sourced. diff --git a/rootfs/etc/systemd/system/dietpi-boot.service b/rootfs/etc/systemd/system/dietpi-boot.service index 25996f55da..e4d6982a83 100644 --- a/rootfs/etc/systemd/system/dietpi-boot.service +++ b/rootfs/etc/systemd/system/dietpi-boot.service @@ -8,8 +8,9 @@ Before=getty-pre.target getty@tty1.service getty.target ssh.service dropbear.ser [Service] Type=oneshot RemainAfterExit=yes -StandardOutput=tty -ExecStart=/bin/dash -c '/boot/dietpi/boot 2>&1 | tee /tmp/dietpi-boot.log' +StandardOutput=journal+console +SyslogIdentifier=DietPi-Boot +ExecStart=/boot/dietpi/boot [Install] WantedBy=multi-user.target diff --git a/rootfs/etc/systemd/system/dietpi-firstboot.service b/rootfs/etc/systemd/system/dietpi-firstboot.service index d2b453e9f0..3796aef851 100644 --- a/rootfs/etc/systemd/system/dietpi-firstboot.service +++ b/rootfs/etc/systemd/system/dietpi-firstboot.service @@ -9,7 +9,8 @@ Before=network-pre.target dietpi-boot.service Type=oneshot RemainAfterExit=yes StandardOutput=tty -ExecStart=/bin/dash -c '/var/lib/dietpi/services/dietpi-firstboot.bash 2>&1 | tee /tmp/dietpi-firstboot.log' +ExecStartPre=/bin/mkdir -p /var/tmp/dietpi/logs +ExecStart=/bin/dash -c '/var/lib/dietpi/services/dietpi-firstboot.bash 2>&1 | tee /var/tmp/dietpi/logs/dietpi-firstboot.log' [Install] WantedBy=multi-user.target diff --git a/rootfs/etc/systemd/system/dietpi-preboot.service b/rootfs/etc/systemd/system/dietpi-preboot.service index f022a956a8..b5ebcf938d 100644 --- a/rootfs/etc/systemd/system/dietpi-preboot.service +++ b/rootfs/etc/systemd/system/dietpi-preboot.service @@ -8,8 +8,9 @@ Before=network-pre.target [Service] Type=oneshot RemainAfterExit=yes -StandardOutput=tty -ExecStart=/bin/dash -c '/boot/dietpi/preboot 2>&1 | tee /tmp/dietpi-preboot.log' +StandardOutput=journal+console +SyslogIdentifier=DietPi-PreBoot +ExecStart=/boot/dietpi/preboot [Install] WantedBy=multi-user.target diff --git a/rootfs/etc/systemd/system/dietpi-ramlog.service b/rootfs/etc/systemd/system/dietpi-ramlog.service index 97bc4faf07..0b55889e36 100644 --- a/rootfs/etc/systemd/system/dietpi-ramlog.service +++ b/rootfs/etc/systemd/system/dietpi-ramlog.service @@ -1,15 +1,15 @@ [Unit] Description=DietPi-RAMlog # Order 1 -After=local-fs.target var-log.mount -.mount +After=local-fs.target var-log.mount boot.mount -.mount Before=syslog.service rsyslog.service [Service] Type=oneshot RemainAfterExit=yes ExecStartPre=/bin/mkdir -p /var/tmp/dietpi/logs -ExecStart=/bin/dash -c '/boot/dietpi/func/dietpi-ramlog 0 2>&1 >> /var/tmp/dietpi/logs/dietpi-ramlog.log' -ExecStop=/bin/dash -c '/boot/dietpi/func/dietpi-ramlog 1 2>&1 >> /var/tmp/dietpi/logs/dietpi-ramlog.log' +ExecStart=/bin/dash -c '/boot/dietpi/func/dietpi-ramlog 0 >> /var/tmp/dietpi/logs/dietpi-ramlog.log 2>&1' +ExecStop=/bin/dash -c '/boot/dietpi/func/dietpi-ramlog 1 > /var/tmp/dietpi/logs/dietpi-ramlog.log 2>&1' [Install] WantedBy=multi-user.target diff --git a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash index 513cdb82e7..9ae7ba43ff 100755 --- a/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash +++ b/rootfs/var/lib/dietpi/services/dietpi-firstboot.bash @@ -96,9 +96,8 @@ if [[ -f '/boot/Automation_Custom_PreScript.sh' ]]; then G_DIETPI-NOTIFY 2 'Running custom script, please wait...' - chmod +x /boot/Automation_Custom_PreScript.sh - if /boot/Automation_Custom_PreScript.sh | tee /tmp/dietpi-automation_custom_prescript.log; then + if /boot/Automation_Custom_PreScript.sh 2>&1 | tee /var/tmp/dietpi/logs/dietpi-automation_custom_prescript.log; then G_DIETPI-NOTIFY 0 'Custom script' @@ -112,20 +111,15 @@ fi # Create swap file - local swap_size=$(sed -n '/^[[:blank:]]*AUTO_SETUP_SWAPFILE_SIZE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - disable_error=1 G_CHECK_VALIDINT "$swap_size" 0 || swap_size=1 - local swap_location=$(sed -n '/^[[:blank:]]*AUTO_SETUP_SWAPFILE_LOCATION=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - [[ $swap_location == '/'* ]] || swap_location='/var/swap' - /boot/dietpi/func/dietpi-set_swapfile $swap_size "$swap_location" + /boot/dietpi/func/dietpi-set_swapfile # Apply time zone local autoinstall_timezone=$(sed -n '/^[[:blank:]]*AUTO_SETUP_TIMEZONE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt) - if [[ $autoinstall_timezone && $autoinstall_timezone != $( /etc/systemd/system/getty@tty1.service.d/dietpi-autologin.conf +[Service] +ExecStart= +ExecStart=-/sbin/agetty -a root %I \$TERM +_EOF_ + + fi # Disable serial console, if set in dietpi.txt grep -q '^[[:blank:]]*CONFIG_SERIAL_CONSOLE_ENABLE=0' /boot/dietpi.txt && /boot/dietpi/func/dietpi-set_hardware serialconsole disable @@ -180,7 +183,7 @@ /boot/dietpi/func/dietpi-set_software apt-mirror "$(sed -n "/^[[:blank:]]*$target_repo=/{s/^[^=]*=//p;q}" /boot/dietpi.txt)" # Regenerate unique Dropbear host keys - rm -f /etc/dropbear/*_host_key + rm -fv /etc/dropbear/dropbear_*_host_key if (( $G_DISTRO < 6 )); then dpkg-reconfigure -f noninteractive dropbear-run diff --git a/rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh b/rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh index 1f35c7cd6b..69a200142a 100644 --- a/rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh +++ b/rootfs/var/lib/dietpi/services/dietpi-wifi-monitor.sh @@ -19,10 +19,10 @@ do # Get current gateway for ping - URL_PING=$(ip r l 0/0 dev $ADAPTER | mawk '{print $3}') + URL_PING=$(ip r l 0/0 dev "$ADAPTER" | mawk '{print $3}') [[ $G_DEBUG == 1 ]] && echo "Checking connection for: $ADAPTER via ping to $URL_PING" - if [[ $URL_PING ]] && ping -qI $ADAPTER -c 1 $URL_PING &> /dev/null; then + if [[ $URL_PING ]] && ping -qI "$ADAPTER" -c 1 "$URL_PING" &> /dev/null; then [[ $G_DEBUG == 1 ]] && echo "Connection valid for: $ADAPTER" @@ -31,9 +31,9 @@ [[ -e /sys/class/net/$ADAPTER ]] || { echo "ERROR: WiFi adapter has been unplugged: $ADAPTER. Exiting..."; exit 1; } echo "Detected connection loss: $ADAPTER. Reconnecting..." - ifdown $ADAPTER + ifdown "$ADAPTER" sleep 1 - ifup $ADAPTER + ifup "$ADAPTER" echo 'Completed' fi diff --git a/rootfs/var/lib/dietpi/services/fs_partition_resize.sh b/rootfs/var/lib/dietpi/services/fs_partition_resize.sh index 71454e319d..057574a6c5 100644 --- a/rootfs/var/lib/dietpi/services/fs_partition_resize.sh +++ b/rootfs/var/lib/dietpi/services/fs_partition_resize.sh @@ -5,20 +5,21 @@ # Grab root device # Naming scheme: https://askubuntu.com/questions/56929/what-is-the-linux-drive-naming-scheme - # - SCSI/SATA: /dev/sd[a-z][0-9] - # - IDE: /dev/hd[a-z][0-9] - # - eMMC: /dev/mmcblk[0-9]p[0-9] - # - NVMe: /dev/nvme[0-9]n[0-9]p[0-9] + # - SCSI/SATA: /dev/sd[a-z][1-9] + # - IDE: /dev/hd[a-z][1-9] + # - eMMC: /dev/mmcblk[0-9]p[1-9] + # - NVMe: /dev/nvme[0-9]n[0-9]p[1-9] + # - loop: /dev/loop[0-9]p[1-9] TARGET_DEV=$(findmnt -no SOURCE /) - if [[ $TARGET_DEV == '/dev/mmcblk'* || $TARGET_DEV == '/dev/nvme'* ]]; then + if [[ $TARGET_DEV =~ ^/dev/(mmcblk|nvme|loop)[0-9] ]]; then TARGET_PARTITION=${TARGET_DEV##*p} # /dev/mmcblk0p1 => 1 - TARGET_DRIVE=${TARGET_DEV%p[0-9]} # /dev/mmcblk0p1 => /dev/mmcblk0 + TARGET_DRIVE=${TARGET_DEV%p[1-9]} # /dev/mmcblk0p1 => /dev/mmcblk0 - elif [[ $TARGET_DEV == /dev/[sh]d[a-z]* ]]; then + elif [[ $TARGET_DEV == /dev/[sh]d[a-z][1-9] ]]; then TARGET_PARTITION=${TARGET_DEV##*[a-z]} # /dev/sda1 => 1 - TARGET_DRIVE=${TARGET_DEV%[0-9]} # /dev/sda1 => /dev/sda + TARGET_DRIVE=${TARGET_DEV%[1-9]} # /dev/sda1 => /dev/sda else @@ -28,19 +29,19 @@ fi # Maximize partition, only if drive actually contains a partition table - if [[ $TARGET_PARTITION == [0-9] ]]; then + if [[ $TARGET_PARTITION == [1-9] ]]; then # Failsafe: Sync changes to disk before touching partitions sync # GPT detection | Modified version of ayufan-rock64 resize script: # Move GPT alternate header to end of disk - sfdisk $TARGET_DRIVE -l | grep -qi 'disklabel type: gpt' && sgdisk -e $TARGET_DRIVE + sfdisk "$TARGET_DRIVE" -l | grep -qi 'disklabel type: gpt' && sgdisk -e "$TARGET_DRIVE" # Maximize partition size - sfdisk --no-reread $TARGET_DRIVE -fN$TARGET_PARTITION <<< ',+,,,' + sfdisk --no-reread --no-tell-kernel -fN"$TARGET_PARTITION" "$TARGET_DRIVE" <<< ',+' # Reread partition table - partprobe $TARGET_DRIVE + partprobe "$TARGET_DRIVE" else @@ -49,7 +50,7 @@ fi # Maximize file system - resize2fs $TARGET_DEV + resize2fs "$TARGET_DEV" exit 0 }