|
74 | 74 | ADD_DOS_PART=0 # trailing FAT partition for first boot config files, automatically imported and partition removed on first boot |
75 | 75 | CONFIGS_TO_BOOT=0 # for new RPi kernel/firmware stack where a boot FAT partition exists, but is mounted to /boot/firmware instead of /boot |
76 | 76 | SIGN_PASS= |
| 77 | + RAW_HASH_SIZE=0 # store SHA256 and size for the uncompressed image, mainly used for Raspberry Pi Imager JSON |
77 | 78 | while (( $# )) |
78 | 79 | do |
79 | 80 | case $1 in |
|
82 | 83 | '--add-dos-part') ADD_DOS_PART=1;; |
83 | 84 | '--configs-to-boot') CONFIGS_TO_BOOT=1;; |
84 | 85 | '--sign') shift; SIGN_PASS=$1;; |
| 86 | + '--raw-hash-size') RAW_HASH_SIZE=1;; |
85 | 87 | *) |
86 | 88 | if [[ -b $1 ]] |
87 | 89 | then |
|
201 | 203 | G_EXEC modprobe loop |
202 | 204 | Delete_Loopback # Prevent doubled loop device |
203 | 205 | FP_SOURCE=$(losetup -f) |
204 | | - G_EXEC_NOEXIT=1 G_EXEC losetup "$FP_SOURCE" "$FP_SOURCE_IMG" || return 1 |
205 | | - G_EXEC_NOEXIT=1 G_EXEC partprobe "$FP_SOURCE" || return 1 |
206 | | - G_EXEC_NOEXIT=1 G_EXEC partx -u "$FP_SOURCE" || return 1 |
| 206 | + G_EXEC_NOEXIT=1 G_EXEC losetup -P "$FP_SOURCE" "$FP_SOURCE_IMG" || return 1 |
207 | 207 | G_DIETPI-NOTIFY 0 "Attached the image ($FP_SOURCE_IMG) as loopback device: $FP_SOURCE" |
208 | 208 | G_SLEEP 0.5 # Give the root filesystem a little time to be detected |
209 | 209 | fi |
|
316 | 316 | G_EXEC modprobe loop |
317 | 317 | Delete_Loopback # Prevent doubled loop device |
318 | 318 | FP_SOURCE=$(losetup -f) |
319 | | - G_EXEC losetup "$FP_SOURCE" "$FP_SOURCE_IMG" |
320 | | - G_EXEC partprobe "$FP_SOURCE" |
321 | | - G_EXEC partx -u "$FP_SOURCE" |
| 319 | + G_EXEC losetup -P "$FP_SOURCE" "$FP_SOURCE_IMG" |
322 | 320 | G_DIETPI-NOTIFY 0 "Mounted the image ($FP_SOURCE_IMG) as loopback device: $FP_SOURCE" |
323 | 321 | FP_ROOT_DEV="${FP_SOURCE}p${FP_ROOT_DEV: -1}" |
324 | 322 | fi |
325 | | - [[ $CLONING_TOOL == 'dd' ]] && OUTPUT_IMG_EXT='img' || OUTPUT_IMG_EXT='iso' SKIP_ARCHIVE=1 # Flashing tools do not support xz-compressed ISOs |
| 323 | + [[ $CLONING_TOOL == 'dd' ]] && OUTPUT_IMG_EXT='img' || OUTPUT_IMG_EXT='iso' |
326 | 324 | G_DIETPI-NOTIFY 0 "\e[0mCreating minified image from: |
327 | 325 | - $SOURCE_TYPE: ${FP_SOURCE_IMG:-$FP_SOURCE} |
328 | 326 | - Root device: $FP_ROOT_DEV |
|
341 | 339 |
|
342 | 340 | FP_FINAL="$FP_ORIGIN/$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT" |
343 | 341 |
|
| 342 | + # Flashing tools do not support xz-compressed ISOs |
| 343 | + [[ $OUTPUT_IMG_EXT == 'iso' ]] && SKIP_ARCHIVE=1 |
| 344 | + |
344 | 345 | # Detect partition table type, failsafe detection of MBR to debug possibly other/unknown wording/partition table types |
345 | 346 | PART_TABLE_TYPE=$(lsblk -no PTTYPE "$FP_ROOT_DEV") |
346 | 347 | if [[ $PART_TABLE_TYPE == 'dos' ]] |
|
389 | 390 | # Failsafe |
390 | 391 | G_EXEC partprobe "$FP_SOURCE" |
391 | 392 | G_EXEC partx -u "$FP_SOURCE" |
392 | | - Run_fsck |
393 | 393 |
|
394 | 394 | # Shrink last filesystem to minimum |
395 | | - local last_part_dev=$(lsblk -rnpo NAME "$FP_SOURCE" | tail -1) |
| 395 | + # - resize2fs: "Please run 'e2fsck -f /dev/loop0p1' first." |
| 396 | + Run_fsck |
| 397 | + # - Use sfdisk to detect last partition, as lsblk with "-r" option on Bullseye does not sort partitions well: https://github.com/MichaIng/DietPi/issues/7527 |
| 398 | + local last_part_dev=$(sfdisk -qlo Device "$FP_SOURCE" | tail -1) |
396 | 399 | local last_fs_type=$(lsblk -no FSTYPE "$last_part_dev") |
397 | 400 | if [[ $last_fs_type == 'ext4' ]] |
398 | 401 | then |
|
479 | 482 | FS_SIZE=$(( $FS_SIZE / 512 )) # bytes => 512 byte sectors |
480 | 483 | fi |
481 | 484 |
|
482 | | - Run_fsck |
483 | | - |
484 | 485 | G_DIETPI-NOTIFY 2 'Overriding filesystems free space with zeros to purge removed data and allow better compression...' |
485 | 486 | while read -r path type |
486 | 487 | do |
@@ -762,37 +763,54 @@ _EOF_ |
762 | 763 | G_EXEC sync |
763 | 764 | fi |
764 | 765 |
|
765 | | - # Generate xz archive if requested |
766 | | - local archive_text='' |
767 | | - if (( ! $SKIP_ARCHIVE )) |
| 766 | + # Generate hashes, size info and compress image if requested |
| 767 | + local result_test="\nImage file: $FP_FINAL" |
| 768 | + local upload_list=() |
| 769 | + if (( $RAW_HASH_SIZE )) |
| 770 | + then |
| 771 | + G_EXEC_DESC='Generating image size file' G_EXEC eval "stat -c '%s' '$FP_FINAL' > '$FP_FINAL.size'" |
| 772 | + result_test+="\nImage size: $FP_FINAL.size" |
| 773 | + upload_list+=("$FP_FINAL.size") |
| 774 | + fi |
| 775 | + if (( $SKIP_ARCHIVE )) |
768 | 776 | then |
| 777 | + G_EXEC_DESC='Generating image hash' G_EXEC eval "sha256sum '$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT' > '$FP_FINAL.sha256'" |
| 778 | + result_test+="\nImage hash: $FP_FINAL.sha256" |
| 779 | + upload_list+=("$FP_FINAL" "$FP_FINAL.sha256") |
| 780 | + else |
| 781 | + if (( $RAW_HASH_SIZE )) |
| 782 | + then |
| 783 | + G_EXEC_DESC='Generating image hash' G_EXEC eval "sha256sum '$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT' > '$FP_FINAL.sha256'" |
| 784 | + result_test+="\nImage hash: $FP_FINAL.sha256" |
| 785 | + upload_list+=("$FP_FINAL.sha256") |
| 786 | + fi |
769 | 787 | [[ -f $FP_FINAL.xz ]] && G_EXEC rm "$FP_FINAL.xz" |
770 | | - G_EXEC_DESC='Creating final xz archive' G_EXEC xz -9e -T0 -M75% -k "$FP_FINAL" |
| 788 | + G_EXEC_DESC='Generating xz-compressed image' G_EXEC xz -9e -T0 -M75% -k "$FP_FINAL" |
| 789 | + result_test+="\nxz file: $FP_FINAL.xz" |
| 790 | + upload_list+=("$FP_FINAL.xz") |
| 791 | + |
| 792 | + G_EXEC_DESC='Generating xz hash' G_EXEC eval "sha256sum '$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT.xz' > '$FP_FINAL.xz.sha256'" |
| 793 | + result_test+="\nxz hash: $FP_FINAL.xz.sha256" |
| 794 | + upload_list+=("$FP_FINAL.xz.sha256") |
771 | 795 | FP_FINAL+='.xz' |
772 | | - archive_text="\nxz archive: $FP_FINAL" |
773 | 796 | fi |
774 | 797 |
|
775 | | - # Generate SHA256 hash |
776 | | - G_EXEC_DESC='Generating SHA256 hash' G_EXEC eval "sha256sum '$OUTPUT_IMG_NAME.$OUTPUT_IMG_EXT' > '$FP_FINAL.sha256'" |
777 | | - |
778 | 798 | # Generate GPG signature if requested |
779 | | - local sig_text='' signature=() |
780 | 799 | if [[ $SIGN_PASS ]] |
781 | 800 | then |
782 | 801 | G_DIETPI-NOTIFY 2 "Signing $FP_FINAL ..." |
783 | 802 | gpg --batch --pinentry-mode loopback --passphrase "$SIGN_PASS" -b --armor "$FP_FINAL" || exit 1 |
784 | | - sig_text="\nSignature: $FP_FINAL.asc" signature=("$FP_FINAL.asc") |
| 803 | + result_test+="\nSignature: $FP_FINAL.asc" |
| 804 | + upload_list+=("$FP_FINAL.asc") |
785 | 805 | fi |
786 | 806 |
|
787 | | - G_DIETPI-NOTIFY 0 "DietPi-Imager has successfully finished. |
788 | | -Image file: ${FP_FINAL%.xz}$archive_text |
789 | | -SHA256 hash: $FP_FINAL.sha256$sig_text" |
| 807 | + G_DIETPI-NOTIFY 0 "DietPi-Imager has successfully finished.$result_test" |
790 | 808 |
|
791 | 809 | # Upload if requested |
792 | 810 | if [[ $UPLOAD_SCRIPT ]] |
793 | 811 | then |
794 | 812 | [[ -x "$UPLOAD_SCRIPT" ]] || { G_DIETPI-NOTIFY 1 "Upload script $UPLOAD_SCRIPT does not exist or is not executable. Aborting ..."; exit 1; } |
795 | | - G_EXEC_OUTPUT=1 G_EXEC ./upload.sh "$FP_FINAL"{,.sha256} "${signature[@]}" && (( ! $SKIP_ARCHIVE )) && G_EXEC rm -R "$FP_FINAL"{,.sha256} "${signature[@]}" |
| 813 | + G_EXEC_OUTPUT=1 G_EXEC ./upload.sh "${upload_list[@]}" |
796 | 814 | fi |
797 | 815 | } |
798 | 816 |
|
|
0 commit comments