From ddfe5098d84e17e61f9b6cf804ee84cf3619cad0 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 23 May 2022 20:07:50 +0200 Subject: [PATCH] New experimental script test/merge_2_debian_isos --- test/merge_2_debian_isos | 357 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100755 test/merge_2_debian_isos diff --git a/test/merge_2_debian_isos b/test/merge_2_debian_isos new file mode 100755 index 00000000..dd0f9fe0 --- /dev/null +++ b/test/merge_2_debian_isos @@ -0,0 +1,357 @@ +#!/bin/bash + +usage() { + echo "usage: $(basename "$0") "'\' >&2 + echo " boot_iso boot_mount add_iso add_mount result_iso [for_dist]" >&2 + echo >&2 + echo "Mounts by sudo the boot_iso at directory boot_mount and add_iso at" >&2 + echo "add_mount, if not already mounted that way. Then both Debian pools" >&2 + echo "and package lists get merged and a new ISO 9660 image result_iso" >&2 + echo "is produced, which must not yet exist." >&2 + echo "If boot_iso is bootable then the new image will be bootable by the" >&2 + echo "same means." >&2 + echo "This script creates the following temporary tree and files which" >&2 + echo "must not yet exist in the current working directory:" >&2 + echo " ./merged_dists , ./merged_md5sum.txt , ./merged_REAMDE.txt" >&2 + echo " ./temp_file" >&2 + echo "The optional sixth argument for_dist should only be given if" >&2 + echo "this script refuses to work and proposes to give this argument." >&2 + echo "Exported non-empty variable MERGE_DATE enforces a particular" >&2 + echo "date string in the text which gets prepended to /README.txt ." >&2 + echo "Exported non-empty variable XORRISO overrides command xorriso," >&2 + echo "which may be needed if installed xorriso is older than 1.4.2." >&2 + echo "Example using GNU xorriso-1.5.4 instead of /usr/bin/xorriso:" >&2 + echo " export XORRISO="'$HOME'"/xorriso-1.5.4/xorriso/xorriso" >&2 + echo " $(basename "$0") debian-11.2.0-amd64-DVD-1.iso /mnt/iso1 "'\' >&2 + echo " debian-11.2.0-amd64-DVD-2.iso /mnt/iso2 merged.iso" >&2 +} + +if test "$#" -lt 5 +then + usage + exit 1 +fi + +BOOT_ISO="$1" +BOOT_ISO_MOUNT="$2" +ADD_ISO="$3" +ADD_ISO_MOUNT="$4" +RESULT_ISO="$5" + +# The sixth argument is optional +FOR_DIST="$6" + + +## Check arguments + +if test -e "$RESULT_ISO" +then + echo "--- A file '""$RESULT_ISO""' is already existing." >&2 + echo "--- Will not overwrite it by the resulting ISO image." >&2 + exit 1 +fi +if test -e merged_dists || test -e merged_md5sum.txt || test -e temp_file \ + || test -e merged_README.txt +then + echo "--- At least one of ./merged_dists, ./merged_md5sum.txt, ./temp_file," >&2 + echo "--- or merged_README.txt is already existing. Will not overwrite them." >&2 + exit 1 +fi +if test "$BOOT_ISO" = "$RESULT_ISO" || test "$BOOT_ISO" = "$ADD_ISO" || \ + test "$ADD_ISO" = "$RESULT_ISO" +then + echo "--- At least two of the three given ISO image paths are equal." >&2 + echo "--- boot_iso and add_iso must exist and differ, result_iso must not exist." >&2 + usage + exit 1 +fi + + +## Mount and copy out the files which need to be changed + +do_mount_1=1 +x=$(mount | grep " $BOOT_ISO_MOUNT " | awk '{print $1}') +if test -n "$x" +then + i1=$(ls -i "$x" | awk '{print $1}') + i2=$(ls -i "$BOOT_ISO" | awk '{print $1}') + if test "$i1" = "$i2" + then + do_mount_1=0 + echo "Note: Found $BOOT_ISO already mounted at $BOOT_ISO_MOUNT" + fi +fi +if test "$do_mount_1" = 1 +then + echo "Note: sudo mount $BOOT_ISO $BOOT_ISO_MOUNT" + sudo mount "$BOOT_ISO" "$BOOT_ISO_MOUNT" || exit 3 +fi +cp -a "$BOOT_ISO_MOUNT/dists" merged_dists +cp -a "$BOOT_ISO_MOUNT/md5sum.txt" merged_md5sum.txt +chmod -R u+w merged_dists +chmod u+w merged_md5sum.txt + +do_mount_2=1 +x=$(mount | grep " $ADD_ISO_MOUNT " | awk '{print $1}') +if test -n "$x" +then + i1=$(ls -i "$x" | awk '{print $1}') + i2=$(ls -i "$ADD_ISO" | awk '{print $1}') + if test "$i1" = "$i2" + then + do_mount_2=0 + echo "Note: Found $ADD_ISO already mounted at $ADD_ISO_MOUNT" + fi +fi +if test "$do_mount_2" = 1 +then + echo "Note: sudo mount $ADD_ISO $ADD_ISO_MOUNT" + if sudo mount "$ADD_ISO" "$ADD_ISO_MOUNT" + then + dummy=dummy + else + if test "$do_mount_1" + then + sudo umount "$BOOT_ISO_MOUNT" + fi + exit 3 + fi +fi + + +## Helper functions + +# Put out the list of checksummed paths as listed in /dists/$dist/Release +extract_checksum_paths() { + mode=0 + cat "$1" | \ + while true + do + read x || break + if test "$x" = "MD5Sum:" || test "$x" = "SHA1:" \ + || test "$x" = "SHA256:" || test "$x" = "SHA512:" + then + if test "$mode" = 0 + then + mode=1 + elif test "$mode" = 1 + then + break + fi + elif test "$mode" = 1 + then + echo "$x" + fi + done +} + +# Put out the part before the first checksum field +extract_release_head() { + cat "$1" | \ + while true + do + read x || break + if test "$x" = "MD5Sum:" || test "$x" = "SHA1:" \ + || test "$x" = "SHA256:" || test "$x" = "SHA512:" + then + break + fi + echo "$x" + done +} + + +## Determine which Debian release is on BOOT_ISO + +dist= +for i in $(ls -1d "$BOOT_ISO_MOUNT"/dists/*) +do + if test -d "$i" + then + if test -L "$i" + then +continue + fi + test -n "$dist" && dist="$dist " + dist="$dist""$(basename $i)" + fi +done +if test -z "$dist" +then + if test -z "$FOR_DIST" + then + echo "--- Cannot determine Debian release from directories in /dists" >&2 + echo "--- (You may provide the release name as sixth argument)" >&2 + echo >&2 + usage + exit 2 + fi +elif test "$(echo "$dist" | wc -w)" -gt 1 +then + if test -z "$FOR_DIST" + then + echo "--- More than one Debian release found in /dists: $dist" >&2 + echo "--- (You may provide the release name as sixth argument)" >&2 + echo >&2 + usage + exit 2 + fi +fi +if test -n "$FOR_DIST" +then + echo "Note: Overriding release name '$dist' by '""$FOR_DIST""'" >&2 + dist="$FOR_DIST" +fi +if test -d "$BOOT_ISO_MOUNT"/dists/"$dist" +then + echo "Note: Will work along $BOOT_ISO_MOUNT"/dists/"$dist"/Release >&2 +else + echo "--- Cannot find directory $BOOT_ISO_MOUNT"/dists/"$dist" >&2 + exit 2 +fi + + +## Prepend info to /README.txt + +if test -z "$MERGE_DATE" +then + MERGE_DATE=$(date +'%Y%m%d-%H:%M') +fi +printf 'Result of a run of %s at %s\r\n' \ + "$(basename $0)" "$MERGE_DATE" >temp_file +printf 'Package pools and Packages lists were merged.\r\n' >>temp_file +printf 'The other files stem from the first input ISO.\r\n' >>temp_file +printf '\r\n' >>temp_file +printf 'Input ISO: %s\r\n' "$BOOT_ISO" >>temp_file +head -2 "$BOOT_ISO_MOUNT"/README.txt >>temp_file +printf '\r\n' >>temp_file +printf 'Input ISO: %s\r\n' "$ADD_ISO" >>temp_file +head -2 "$ADD_ISO_MOUNT"/README.txt >>temp_file +printf '\r\n' >>temp_file +printf '%s%s\r\n' " --------------------------------------" \ + "----------------------------------------" >>temp_file +printf '\r\n' >>temp_file +cat "$BOOT_ISO_MOUNT"/README.txt >>temp_file + +mv temp_file merged_README.txt + + +## Merge package description files with those from "$ADD_ISO" + +# /md5sum.txt seems to be the only overall package list +cat merged_md5sum.txt "$ADD_ISO_MOUNT"/md5sum.txt | sort >temp_file +mv temp_file merged_md5sum.txt + +# Determine the files which are mentioned with checksum in main Release files +path_list=$( (extract_checksum_paths merged_dists/"$dist"/Release + extract_checksum_paths "$ADD_ISO_MOUNT"/dists/"$dist"/Release ) \ + | awk '{print $3}' | sort | uniq ) + +# Merge .gz files (Release should not be merged. Unclear what others need.) +for i in $path_list +do + if echo "$i" | grep -v '.gz$' >/dev/null + then +continue + fi + if test -e merged_dists/"$dist"/"$i" + then + if test -e "$ADD_ISO_MOUNT"/dists/"$dist"/"$i" + then + if test "$(gunzip temp_file + mv temp_file merged_dists/"$dist"/"$i" + fi + elif test -e "$ADD_ISO_MOUNT"/dists/"$dist"/"$i" + then + if test -e $(dirname merged_dists/"$dist"/"$i") + then + dummy=dummy + else + mkdir -p $(dirname merged_dists/"$dist"/"$i") + fi + cp "$ADD_ISO_MOUNT"/dists/"$dist"/"$i" merged_dists/"$dist"/"$i" + fi + test -e temp_file && rm temp_file +done + + +## Update dists/"$dist"/Release + +extract_release_head merged_dists/"$dist"/Release >temp_file + +# Re-create "MD5Sum:", "SHA256:", "SHA512:" sections +for cmd in md5sum sha1sum sha256sum sha512sum +do + if type "$cmd" >/dev/null + then + case "$cmd" in + md5sum) echo "MD5Sum:" ;; + sha1sum) echo "SHA1:" ;; + sha256sum) echo "SHA256:" ;; + sha512sum) echo "SHA512:" ;; + esac + for i in $path_list + do + file=merged_dists/"$dist"/"$i" + if test -e "$file" + then + sum=$("$cmd" "$file" | awk '{print $1}') + size=$(stat -c '%s' "$file") + elif test -e "$file".gz + then + sum=$(gunzip <"$file".gz | "$cmd" | awk '{print $1}') + size=$(gunzip <"$file".gz | wc -c) + else + continue + fi + list_path=$(echo "$file" | sed -e 's/^merged_dists\/'"$dist"'\///') + printf ' %s %8ld %s\n' "$sum" "$size" "$list_path" + done + fi +done >>temp_file + +mv temp_file merged_dists/"$dist"/Release + + +## Produce the new ISO image + +if test -z "$XORRISO" +then + XORRISO=xorriso +fi + +"$XORRISO" \ + -indev "$BOOT_ISO" \ + -outdev "$RESULT_ISO" \ + -map "$ADD_ISO_MOUNT"/pool /pool \ + -map merged_dists /dists \ + -map merged_md5sum.txt /md5sum.txt \ + -map merged_README.txt /README.txt \ + -chown_r 0 /dists /md5sum.txt /README.txt -- \ + -chgrp_r 0 /dists /md5sum.txt /README.txt -- \ + -chmod_r a-w /dists /md5sum.txt -- \ + -chmod_r a=r /README.txt -- \ + -boot_image any replay \ + -stdio_sync off \ + -padding included \ + -compliance no_emul_toc + +if test "$do_mount_1" = 1 +then + sudo umount "$BOOT_ISO_MOUNT" +fi +if test "$do_mount_2" = 1 +then + sudo umount "$ADD_ISO_MOUNT" +fi + +rm -r merged_dists merged_md5sum.txt merged_README.txt +