From c692676da712310d5d334432df41f040f0f8d2ae Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Sat, 29 Apr 2023 12:41:51 +0200 Subject: [PATCH] kernel-debs: postinst/etc: fix: unify `is_boot_dev_vfat()` function; make work during image build too via env var - determinining if `/boot` is vfat is more complex than it looks; - use a common function to unify across all scripts - during image build, the kernel install is always done with a non-fat, non-mounted /boot - use a special variable passed through the env so unified function can know ahead of time - introduce `extra_apt_envs` param to `chroot_sdcard_apt_get()`; array with extra environment vars - if vfat /boot: - `linux-update-symlinks` is not called (Debian would just choke on this) - don't even try to symlink Armbian stuff, move instead - more/better logging board-side (unfortunately mixed in all the set -x debugs) --- lib/functions/compilation/kernel-debs.sh | 61 ++++++++++++++++++------ lib/functions/image/rootfs-to-image.sh | 2 + lib/functions/logging/runners.sh | 12 ++++- lib/functions/rootfs/apt-install.sh | 3 ++ 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/lib/functions/compilation/kernel-debs.sh b/lib/functions/compilation/kernel-debs.sh index 1668dede31..1c474b7c73 100644 --- a/lib/functions/compilation/kernel-debs.sh +++ b/lib/functions/compilation/kernel-debs.sh @@ -153,6 +153,27 @@ function kernel_package_hook_helper() { #!/bin/bash echo "Armbian '${package_name}' for '${kernel_version_family}': '${script}' starting." set -e # Error control + + function is_boot_dev_vfat() { + # When installing these packages during image build, /boot is not mounted, and will most definitely not be vfat. + # Use an environment variable to signal that it _will_ be a fat32, so symlinks are not created. + # This is passed by install_deb_chroot() explicitly via the runners. + if [[ "\${ARMBIAN_IMAGE_BUILD_BOOTFS_TYPE:-"unknown"}" == "fat" ]]; then + echo "Armbian: ARMBIAN_IMAGE_BUILD_BOOTFS_TYPE: '\${ARMBIAN_IMAGE_BUILD_BOOTFS_TYPE:-"not set"}'" + return 0 + fi + if ! mountpoint -q /boot; then + return 1 + fi + local boot_partition bootfstype + boot_partition=\$(findmnt --nofsroot -n -o SOURCE /boot) + bootfstype=\$(blkid -s TYPE -o value \$boot_partition) + if [[ "\$bootfstype" == "vfat" ]]; then + return 0 + fi + return 1 + } + set -x # Debugging $(cat "${contents}") @@ -244,6 +265,7 @@ function kernel_package_callback_linux_image() { mkdir -p "${package_directory}${debian_kernel_hook_dir}/${script}.d" # create kernel hook dir, make sure. kernel_package_hook_helper "${script}" <( + # Common for all of postinst/postrm/preinst/prerm cat <<- KERNEL_HOOK_DELEGATION # Reference: linux-image-6.1.0-7-amd64.postinst from Debian export DEB_MAINT_PARAMS="\$*" # Pass maintainer script parameters to hook scripts export INITRD=$(if_enabled_echo CONFIG_BLK_DEV_INITRD Yes No) # Tell initramfs builder whether it's wanted @@ -253,31 +275,34 @@ function kernel_package_callback_linux_image() { if [[ "${script}" == "preinst" ]]; then cat <<- HOOK_FOR_REMOVE_VFAT_BOOT_FILES - check_boot_dev (){ - boot_partition=\$(findmnt --nofsroot -n -o SOURCE /boot) - bootfstype=\$(blkid -s TYPE -o value \$boot_partition) - if [ "\$bootfstype" = "vfat" ]; then - rm -f /boot/System.map* /boot/config* /boot/vmlinuz* /boot/$image_name /boot/uImage - fi - } - mountpoint -q /boot && check_boot_dev + if is_boot_dev_vfat; then + rm -f /boot/System.map* /boot/config* /boot/vmlinuz* /boot/$image_name /boot/uImage + fi HOOK_FOR_REMOVE_VFAT_BOOT_FILES fi # @TODO: only if u-boot, only for postinst. Gotta find a hook scheme for these... if [[ "${script}" == "postinst" ]]; then cat <<- HOOK_FOR_LINK_TO_LAST_INSTALLED_KERNEL # image_name="${NAME_KERNEL}", above - echo "Armbian: update last-installed kernel symlink to '$image_name'..." - ln -sfv $(basename "${installed_image_path}") /boot/$image_name || mv -v /${installed_image_path} /boot/${image_name} touch /boot/.next + if is_boot_dev_vfat; then + echo "Armbian: FAT32 /boot: move last-installed kernel to '$image_name'..." + mv -v /${installed_image_path} /boot/${image_name} + else + echo "Armbian: update last-installed kernel symlink to '$image_name'..." + ln -sfv $(basename "${installed_image_path}") /boot/$image_name + fi HOOK_FOR_LINK_TO_LAST_INSTALLED_KERNEL # Reference: linux-image-6.1.0-7-amd64.postinst from Debian cat <<- HOOK_FOR_DEBIAN_COMPAT_SYMLINK - echo "Armbian: Debian compat: linux-update-symlinks install ${kernel_version_family} ${installed_image_path}" # call debian helper, for compatibility. this symlinks things according to /etc/kernel-img.conf # "install" or "upgrade" are decided in a very contrived way by Debian (".fresh-install" file) - linux-update-symlinks install ${kernel_version_family} ${installed_image_path} || true + # do NOT do this if /boot is a vfat, though. + if ! is_boot_dev_vfat; then + echo "Armbian: Debian compat: linux-update-symlinks install ${kernel_version_family} ${installed_image_path}" + linux-update-symlinks install "${kernel_version_family}" "${installed_image_path}" || true + fi HOOK_FOR_DEBIAN_COMPAT_SYMLINK fi ) @@ -301,7 +326,7 @@ function kernel_package_callback_linux_dtb() { Package: ${package_name} Architecture: ${ARCH} Provides: linux-dtb, linux-dtb-armbian, armbian-$BRANCH - Description: Armbian Linux $BRANCH DTBs ${artifact_version_reason:-"${kernel_version_family}"} + Description: Armbian Linux $BRANCH DTBs ${artifact_version_reason:-"${kernel_version_family}"} in /boot/dtb-${kernel_version_family} This package contains device blobs from the Linux kernel, version ${kernel_version_family} CONTROL_FILE @@ -315,7 +340,13 @@ function kernel_package_callback_linux_dtb() { kernel_package_hook_helper "postinst" <( cat <<- EOT cd /boot - ln -sfT dtb-${kernel_version_family} dtb || mv dtb-${kernel_version_family} dtb + if ! is_boot_dev_vfat; then + echo "Armbian: DTB: symlinking /boot/dtb to /boot/dtb-${kernel_version_family}..." + ln -sfTv "dtb-${kernel_version_family}" dtb + else + echo "Armbian: DTB: FAT32: moving /boot/dtb-${kernel_version_family} to /boot/dtb ..." + mv -v "dtb-${kernel_version_family}" dtb + fi EOT ) @@ -384,7 +415,7 @@ function kernel_package_callback_linux_headers() { # the tools/vm dir was renamed to tools/mm. Unfortunately tools/Makefile still expects it to exist, # and "make clean" in the "/tools" dir fails. Drop in a fake Makefile there to work around this. if [[ ! -f "${headers_target_dir}/tools/vm/Makefile" ]]; then - display_alert "Creating fake tools/vm/Makefile" "6.3+ hackfix" "warn" + display_alert "Creating fake tools/vm/Makefile" "6.3+ hackfix" "debug" mkdir -p "${headers_target_dir}/tools/vm" echo -e "clean:\n\techo fake clean for tools/vm" > "${headers_target_dir}/tools/vm/Makefile" fi diff --git a/lib/functions/image/rootfs-to-image.sh b/lib/functions/image/rootfs-to-image.sh index 825bece688..bc21c23970 100644 --- a/lib/functions/image/rootfs-to-image.sh +++ b/lib/functions/image/rootfs-to-image.sh @@ -58,6 +58,8 @@ function create_image_from_sdcard_rootfs() { display_alert "Copying files to" "/boot (MOUNT /boot)" if [[ $(findmnt --noheadings --output FSTYPE --target "$MOUNT/boot" --uniq) == vfat ]]; then run_host_command_logged rsync -rLtWh --info=progress0,stats1 "$SDCARD/boot" "$MOUNT" # fat32 + # @TODO: -L causes symlinks to be replaced with copies, but what if they don't exist? + # Also: what's the sense in replacing symlinks with copies? else run_host_command_logged rsync -aHWXh --info=progress0,stats1 "$SDCARD/boot" "$MOUNT" # ext4 fi diff --git a/lib/functions/logging/runners.sh b/lib/functions/logging/runners.sh index 7c26743ee9..62f8ed9996 100644 --- a/lib/functions/logging/runners.sh +++ b/lib/functions/logging/runners.sh @@ -93,8 +93,18 @@ function chroot_sdcard_apt_get() { skip_error_info="yes" run_host_command_logged mount --bind "${LOCAL_APT_CACHE_INFO[HOST_LISTS_DIR]}" "${LOCAL_APT_CACHE_INFO[SDCARD_LISTS_DIR]}" fi + declare -a extra_envs=("DEBIAN_FRONTEND=noninteractive") + # shellcheck disable=SC2154 # extra_apt_envs is defined in the caller + if [[ "${#extra_apt_envs[@]}" -gt 0 ]]; then + extra_envs+=("${extra_apt_envs[@]}") + else + display_alert "No extra envs for apt" "none" "debug" + fi + + display_alert "Extra envs for apt:" "${extra_envs[*]@Q}" "debug" + local chroot_apt_result=1 - chroot_sdcard "${prelude_clean_env[@]}" DEBIAN_FRONTEND=noninteractive apt-get "${apt_params[@]}" "$@" && chroot_apt_result=0 + chroot_sdcard "${prelude_clean_env[@]}" "${extra_envs[@]}" apt-get "${apt_params[@]}" "$@" && chroot_apt_result=0 local_apt_deb_cache_prepare "after 'apt-get $*'" # sets LOCAL_APT_CACHE_INFO if [[ "${LOCAL_APT_CACHE_INFO[USE]}" == "yes" ]]; then diff --git a/lib/functions/rootfs/apt-install.sh b/lib/functions/rootfs/apt-install.sh index bbf46546c0..0ee5a433bf 100644 --- a/lib/functions/rootfs/apt-install.sh +++ b/lib/functions/rootfs/apt-install.sh @@ -80,7 +80,10 @@ function install_deb_chroot() { # install in chroot via apt-get, not dpkg, so dependencies are also installed from repo if needed. declare -g if_error_detail_message="Installation of $install_target failed ${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}" + declare -a extra_apt_envs=() + extra_apt_envs+=("ARMBIAN_IMAGE_BUILD_BOOTFS_TYPE=${BOOTFS_TYPE:-"unset"}") # used by package postinst scripts to bevahe DONT_MAINTAIN_APT_CACHE="yes" chroot_sdcard_apt_get --no-install-recommends install "${install_target}" # don't auto-maintain apt cache when installing from packages. + unset extra_apt_envs # @TODO: mysterious. store installed/downloaded packages in deb storage. only used for u-boot deb. why? # this is some contrived way to get the uboot.deb when installing from repo; image builder needs the deb to be able to deploy uboot later, even though it is already installed inside the chroot, it needs deb to be in host to reuse code later