Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DietPi-Imager | Add option to add FAT partition after rootfs to simplify setup #6602

Merged
merged 13 commits into from
Sep 10, 2023
42 changes: 38 additions & 4 deletions .build/images/dietpi-build
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ GITBRANCH='master'
GITOWNER='MichaIng'
EDITION=
SUFFIX=
ADD_DOS_PART=1
while (( $# ))
do
case $1 in
Expand All @@ -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
Expand Down Expand Up @@ -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');;
Expand Down Expand Up @@ -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_

Expand Down Expand Up @@ -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 ) ]]
Expand All @@ -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 ))
Expand All @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down
93 changes: 75 additions & 18 deletions .build/images/dietpi-imager
Original file line number Diff line number Diff line change
Expand Up @@ -46,32 +46,44 @@
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=
#CLONING_TOOL=
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()
{
Expand Down Expand Up @@ -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' ]]
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
17 changes: 17 additions & 0 deletions rootfs/var/lib/dietpi/services/fs_partition_resize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down