From 63c84fcf2006a6d64c7fb16ae1e1579f4100cdb4 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 10 Sep 2023 13:58:50 -0700 Subject: [PATCH] v8.22 (#6602) - General | DietPi images are now shipped with a trailing FAT partition which contains dietpi.txt and other config files for easier pre-configuration and automation from Windows and macOS hosts. Related CLI flags have been added to our build scripts. Many thanks to @dirkhh for implementing this feature: https://github.com/MichaIng/DietPi/pull/6602 Signed-off-by: Dirk Hohndel Co-authored-by: MichaIng --- .build/images/dietpi-build | 42 ++++++++- .build/images/dietpi-imager | 93 +++++++++++++++---- CHANGELOG.txt | 1 + .../dietpi/services/fs_partition_resize.sh | 17 ++++ 4 files changed, 131 insertions(+), 22 deletions(-) diff --git a/.build/images/dietpi-build b/.build/images/dietpi-build index dd40cbc50f..85bde4234e 100755 --- a/.build/images/dietpi-build +++ b/.build/images/dietpi-build @@ -45,6 +45,7 @@ GITBRANCH='master' GITOWNER='MichaIng' EDITION= SUFFIX= +ADD_DOS_PART=1 while (( $# )) do case $1 in @@ -59,6 +60,7 @@ do '-o') shift; GITOWNER=$1;; '-e') shift; EDITION=$1;; '-s') shift; SUFFIX=$1;; + '--no-dos-part') ADD_DOS_PART=0;; *) G_DIETPI-NOTIFY 1 "Invalid input \"$1\", aborting..."; exit 1;; esac shift @@ -170,6 +172,10 @@ case $PTTYPE in *) G_DIETPI-NOTIFY 1 "Invalid partition table type \"$PTTYPE\" passed, aborting..."; exit 1;; esac +# Do not add trailing FAT partitions for VM, container and (Clonezilla) installer images, and if there is a boot FAT partition already +[[ $HW_MODEL == 20 || $HW_MODEL == 75 || $ITYPE == 'Installer' ]] && ADD_DOS_PART=0 +[[ $boot_size -gt 0 && $boot_fstype == 'fat'* ]] && ADD_DOS_PART=0 + fsname='' apackages=() afs_opts=() afsck=() aresize=() case $FSTYPE in 'ext4') apackages+=('e2fsprogs') afs_opts=('-e' 'remount-ro') afsck=('e2fsck' '-fyD') aresize=('resize2fs');; @@ -419,6 +425,7 @@ _EOF_ cat << _EOF_ >> rootfs/etc/rc.local export GITOWNER='$GITOWNER' GITBRANCH='$GITBRANCH' HW_MODEL='$HW_MODEL' IMAGE_CREATOR=0 PREIMAGE_INFO=0 WIFI_REQUIRED=1 DISTRO_TARGET=$DISTRO +echo '[ INFO ] Running DietPi-Installer for $G_GITOWNER/$G_GITBRANCH' bash -c "\$(curl -sSf 'https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.build/images/dietpi-installer')" || poweroff _EOF_ @@ -464,7 +471,13 @@ G_EXEC losetup -d "$FP_LOOP" # Do not pack and upload raw VM image if not explicitly requested [[ $VMTYPE && ! $VMTYPE =~ ^(raw|all)$ ]] && SKIP_ARCHIVE=1 || SKIP_ARCHIVE=0 export FP_ROOT_DEV CLONING_TOOL OUTPUT_IMG_NAME MOUNT_IT='Off' SKIP_ARCHIVE SKIP_FIRSTBOOT_RESIZE=1 -[[ $EDITION && $EDITION != 'all' ]] || bash -c "$(curl -sSf "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.build/images/dietpi-imager")" 'DietPi-Imager' "$OUTPUT_IMG_NAME.img" || exit 1 +IMAGER_ARGS=("$OUTPUT_IMG_NAME.img") +(( $ADD_DOS_PART )) && IMAGER_ARGS+=('--add-dos-part') +if [[ ! $EDITION || $EDITION == 'all' ]] +then + G_DIETPI-NOTIFY 2 "Running DietPi-Imager for $G_GITOWNER/$G_GITBRANCH" + bash -c "$(curl -sSf "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.build/images/dietpi-imager")" 'DietPi-Imager' "${IMAGER_ARGS[@]}" || exit 1 +fi # Amiberry edition: Install automatically on first boot, enable autostart option and onboard audio on RPi if [[ $EDITION == 'Amiberry' || ( $EDITION == 'all' && $HW_MODEL == 0 ) ]] @@ -478,6 +491,15 @@ then G_EXEC partprobe "$FP_LOOP" G_EXEC partx -u "$FP_LOOP" + # Remove added DOS partition, it will be re-added by DietPi-Imager + if (( $ADD_DOS_PART )) && [[ $(lsblk -nrbo FSTYPE,LABEL "$FP_LOOP" | tail -1) == 'vfat DIETPISETUP' ]] + then + SETUP_PART=$(sfdisk -lqo DEVICE "$FP_LOOP" | tail -1) + G_EXEC_OUTPUT=1 G_EXEC sfdisk --no-reread --no-tell-kernel --delete "$FP_LOOP" "${SETUP_PART: -1}" + G_EXEC partprobe "$FP_LOOP" + G_EXEC partx -u "$FP_LOOP" + fi + # Mount filesystems G_EXEC mkdir rootfs if (( $boot_size )) @@ -502,7 +524,8 @@ then G_EXEC rmdir rootfs G_EXEC losetup -d "$FP_LOOP" - bash -c "$(curl -sSf "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.build/images/dietpi-imager")" 'DietPi-Imager' "$OUTPUT_IMG_NAME.img" || exit 1 + G_DIETPI-NOTIFY 2 "Running DietPi-Imager for $G_GITOWNER/$G_GITBRANCH" + bash -c "$(curl -sSf "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.build/images/dietpi-imager")" 'DietPi-Imager' "${IMAGER_ARGS[@]}" || exit 1 fi # AlloGUI edition: Pre-install Allo GUI with all managed audiophile software @@ -517,7 +540,17 @@ then G_EXEC losetup "$FP_LOOP" "$OUTPUT_IMG_NAME.img" G_EXEC partprobe "$FP_LOOP" G_EXEC partx -u "$FP_LOOP" - # Raise partition and filesystem size as well, since resize2fs within the image returns "Nothing to do!" + + # Remove added DOS partition, it will be re-added by DietPi-Imager + if (( $ADD_DOS_PART )) && [[ $(lsblk -nrbo FSTYPE,LABEL "$FP_LOOP" | tail -1) == 'vfat DIETPISETUP' ]] + then + SETUP_PART=$(sfdisk -lqo DEVICE "$FP_LOOP" | tail -1) + G_EXEC_OUTPUT=1 G_EXEC sfdisk --no-reread --no-tell-kernel --delete "$FP_LOOP" "${SETUP_PART: -1}" + G_EXEC partprobe "$FP_LOOP" + G_EXEC partx -u "$FP_LOOP" + fi + + # Raise partition and filesystem sizes as well, since partprobe cannot inform the host kernel about the changed size from within the container G_EXEC_OUTPUT=1 G_EXEC eval "sfdisk -fN2 '$FP_LOOP' <<< ',+'" G_EXEC partprobe "$FP_LOOP" G_EXEC partx -u "$FP_LOOP" @@ -625,7 +658,8 @@ _EOF_ G_EXEC rmdir rootfs G_EXEC losetup -d "$FP_LOOP" - bash -c "$(curl -sSf "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.build/images/dietpi-imager")" 'DietPi-Imager' "$OUTPUT_IMG_NAME.img" || exit 1 + G_DIETPI-NOTIFY 2 "Running DietPi-Imager for $G_GITOWNER/$G_GITBRANCH" + bash -c "$(curl -sSf "https://raw.githubusercontent.com/$G_GITOWNER/DietPi/$G_GITBRANCH/.build/images/dietpi-imager")" 'DietPi-Imager' "${IMAGER_ARGS[@]}" || exit 1 fi [[ $VMTYPE && $VMTYPE != 'raw' ]] || exit 0 diff --git a/.build/images/dietpi-imager b/.build/images/dietpi-imager index 29d309d052..b6996ec194 100755 --- a/.build/images/dietpi-imager +++ b/.build/images/dietpi-imager @@ -46,22 +46,11 @@ exit 1 } - # Inputs + ########################################## + # Process inputs + ########################################## SOURCE_TYPE='Drive' FP_SOURCE_IMG= - if [[ -b $1 ]] - then - FP_SOURCE=$1 - - elif [[ -f $1 ]] - then - SOURCE_TYPE='Image' - FP_SOURCE_IMG=$1 - - elif [[ $1 ]] - then - Error_Exit "Input source $1 does not exist, aborting..." - fi PART_TABLE_TYPE= #FP_ROOT_DEV= ROOT_FS_TYPE= @@ -69,9 +58,32 @@ OUTPUT_IMG_EXT='img' #OUTPUT_IMG_NAME= [[ $MOUNT_IT == 'On' ]] || MOUNT_IT='Off' + [[ $SKIP_FIRSTBOOT_RESIZE == 1 ]] || SKIP_FIRSTBOOT_RESIZE=0 [[ $SHRINK_ONLY == 1 ]] || SHRINK_ONLY=0 [[ $SKIP_ARCHIVE == 1 ]] || SKIP_ARCHIVE=0 - [[ $SKIP_FIRSTBOOT_RESIZE == 1 ]] || SKIP_FIRSTBOOT_RESIZE=0 + ADD_DOS_PART=0 + while (( $# )) + do + case $1 in + '--add-dos-part') ADD_DOS_PART=1;; + *) + if [[ -b $1 ]] + then + FP_SOURCE=$1 + + elif [[ -f $1 ]] + then + SOURCE_TYPE='Image' + FP_SOURCE_IMG=$1 + + elif [[ $1 ]] + then + Error_Exit "Input source $1 does not exist, aborting..." + fi + ;; + esac + shift + done Unmount_tmp() { @@ -494,12 +506,57 @@ G_EXEC partx -u "$FP_SOURCE" fi + # Derive target image size from last partition end + 1 sector + IMAGE_SIZE=$(( ( $(sfdisk -qlo End "$FP_SOURCE" | tail -1) + 1 ) * 512 )) # 512 byte sectors => bytes + + # Add trailing FAT partition to simplify first run setup if requested + # - WARNING: this assumes that the partitions in the table are in order (which we do in other places as well) + if (( $ADD_DOS_PART )) + then + G_DIETPI-NOTIFY 2 'Adding a 1 MiB FAT partition to simplify first run setup' + # Increase source image size if required + [[ $SOURCE_TYPE == 'Image' ]] && (( $(stat -c '%s' "$FP_SOURCE_IMG") < $IMAGE_SIZE + 1048576 )) && G_EXEC truncate -s "$(( $IMAGE_SIZE + 1048576 ))" "$FP_SOURCE_IMG" && G_EXEC losetup -c "$FP_SOURCE" + # Add new DOS partition + local type='EBD0A0A2-B9E5-4433-87C0-68B6B72699C7' # https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs + [[ $PART_TABLE_TYPE == 'dos' ]] && type='c' + G_EXEC eval "sfdisk -a '$FP_SOURCE' <<< 'start=$IMAGE_SIZE,size=2048,type=$type'" # size in sectors + G_EXEC partprobe "$FP_SOURCE" + G_EXEC partx -u "$FP_SOURCE" + # create a FAT filesystem and add config files to it + local new_dos_part=$(sfdisk -l "$FP_SOURCE" | mawk "/ $IMAGE_SIZE /{print \$1;exit}") + G_EXE_OUTPUT=1 G_EXEC mkfs.fat -F 16 -n DIETPISETUP "$new_dos_part" + local fat_mountpoint=$(mktemp -d) + local root_mountpoint=$(mktemp -d) + G_EXEC mount "$new_dos_part" "$fat_mountpoint" + G_EXEC mount "$FP_ROOT_DEV" "$root_mountpoint" + G_DIETPI-NOTIFY 2 'Copying dietpi.txt and other config files to the DIETPISETUP partition' + for f in 'dietpi.txt' 'dietpi-wifi.txt' 'dietpiEnv.txt' 'unattended_pivpn.conf' 'Automation_Custom_PreScript.sh' 'Automation_Custom_Script.sh' + do + [[ -f $root_mountpoint/boot/$f ]] && G_EXEC cp "$root_mountpoint/boot/$f" "$fat_mountpoint/" + done + cat << '_EOF_' > "$fat_mountpoint/Readme-DietPi-Config.txt" +DietPi pre-boot configuration + +You can edit the files in this folder to setup some configuration options +or even a completely automated install. Please check the documentation and +dietpi.txt for details: https://dietpi.com/docs/install/ + +This folder also supports the following additional files. Please ensure that +they have UNIX style LF line endings: +- unattended_pivpn.conf +- Automation_Custom_PreScript.sh +- Automation_Custom_Script.sh +_EOF_ + G_EXEC umount "$root_mountpoint" "$fat_mountpoint" + G_EXEC rmdir "$root_mountpoint" "$fat_mountpoint" + ((IMAGE_SIZE+=1048576)) + fi + # Exit now if source shall be shrunk only (( $SHRINK_ONLY )) && exit 0 - # Finished: Derive final image size from last partition end + 1 sector - IMAGE_SIZE=$(( ( $(sfdisk -qlo End "$FP_SOURCE" | tail -1) + 1 ) * 512 )) # 512 byte sectors => bytes - [[ $PART_TABLE_TYPE == 'gpt' ]] && IMAGE_SIZE=$(( $IMAGE_SIZE + 33*512 )) # Add 33 (34 overall) sectors for GPT backup partition table + # Add 33 (34 overall) sectors for GPT backup partition table + [[ $PART_TABLE_TYPE == 'gpt' ]] && IMAGE_SIZE=$(( $IMAGE_SIZE + 33*512 )) # Image file source and dd target if [[ $FP_SOURCE_IMG && $CLONING_TOOL == 'dd' ]] diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 968a2642c5..1cb46eb0dc 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,6 +5,7 @@ New software: - ADS-B Feeder | Track airplanes using SDRs and feed the data to ADS-B aggregators. Many thanks to @dirkhh for maintaining and implementing this software option: https://github.com/MichaIng/DietPi/pull/6587 Enhancements: +- General | DietPi images are now shipped with a trailing FAT partition which contains dietpi.txt and other config files for easier pre-configuration and automation from Windows and macOS hosts. Related CLI flags have been added to our build scripts. Many thanks to @dirkhh for implementing this feature: https://github.com/MichaIng/DietPi/pull/6602 - DietPi-Software | Docker: Enabled for Trixie and RISC-V via "docker.io" package from Debian repository. - DietPi-Software | Portainer: Enabled for RISC-V as Docker is now supported on RISC-V as well. diff --git a/rootfs/var/lib/dietpi/services/fs_partition_resize.sh b/rootfs/var/lib/dietpi/services/fs_partition_resize.sh index 5495eb128a..7140597829 100755 --- a/rootfs/var/lib/dietpi/services/fs_partition_resize.sh +++ b/rootfs/var/lib/dietpi/services/fs_partition_resize.sh @@ -39,6 +39,23 @@ exit 1 fi + # Check if the last partition contains a FAT filesystem with DIETPISETUP label + if [[ $(lsblk -nrbo FSTYPE,LABEL "$ROOT_DRIVE" | tail -1) == 'vfat DIETPISETUP' ]] + then + # Mount it and copy files if present and newer + SETUP_PART=$(sfdisk -lqo DEVICE "$ROOT_DRIVE" | tail -1) + TMP_MOUNT=$(mktemp -d) + mount "$SETUP_PART" "$TMP_MOUNT" + for f in 'dietpi.txt' 'dietpi-wifi.txt' 'dietpiEnv.txt' 'unattended_pivpn.conf' 'Automation_Custom_PreScript.sh' 'Automation_Custom_Script.sh' + do + [[ -f $TMP_MOUNT/$f ]] && cp -u "$TMP_MOUNT/$f" /boot/ + done + umount "$SETUP_PART" + rmdir "$TMP_MOUNT" + # Finally delete the partition so the resizing works + sfdisk --no-reread --no-tell-kernel --delete "$ROOT_DRIVE" "${SETUP_PART: -1}" + fi + # Only increase partition size if not yet done on first boot if [[ -f '/dietpi_skip_partition_resize' ]] then