Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package sdbootutil for openSUSE:Factory checked in at 2024-03-22 15:17:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/sdbootutil (Old) and /work/SRC/openSUSE:Factory/.sdbootutil.new.1905 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sdbootutil" Fri Mar 22 15:17:15 2024 rev:17 rq:1159807 version:1+git20240320.8b35615 Changes: -------- --- /work/SRC/openSUSE:Factory/sdbootutil/sdbootutil.changes 2024-02-21 17:52:44.975341064 +0100 +++ /work/SRC/openSUSE:Factory/.sdbootutil.new.1905/sdbootutil.changes 2024-03-22 15:18:45.616839918 +0100 @@ -1,0 +2,32 @@ +Wed Mar 20 10:02:58 UTC 2024 - [email protected] + +- Update to version 1+git20240320.8b35615: + * Revert "Remove GRUB2 package conflict" + +------------------------------------------------------------------- +Thu Mar 14 14:14:31 UTC 2024 - [email protected] + +- Update to version 1+git20240314.3472899: + * Add minimal grub configuration + * Add systemd.machine_id to kernel command line + * Add SNAPSHOT parameter to bootloader command + * Remove GRUB2 package conflict + * Resolve some shellcheck issues + * Remove unused variable + * Change tempfile name + * needs-update and update meets grub2 + * Consider grub2 when installing the bootloader + * Add grub2 detector and command + * fix: delete correct initrd file after installation + * feat: add add-all-kernels-clean function + * refactor: use snapshot as argument for all commands + * Set SYSTEMD_LOG_LEVEL=warning for pcrlock + * Don't require /etc/sysconfig/fde-tools for pcr-oracle + * add loader.conf to locking + * Make sure there are actually entries + * Prefer pcr-oracle if it's actually configured + * Don't log to syslog ourselves + * Fix typo + * fix: remove Tumbleweed version from regular entries + +------------------------------------------------------------------- Old: ---- sdbootutil-1+git20240215.cb7e392.obscpio New: ---- sdbootutil-1+git20240320.8b35615.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ sdbootutil.spec ++++++ --- /var/tmp/diff_new_pack.6mgGUs/_old 2024-03-22 15:18:46.580875350 +0100 +++ /var/tmp/diff_new_pack.6mgGUs/_new 2024-03-22 15:18:46.584875497 +0100 @@ -27,7 +27,7 @@ %define git_version %{nil} %endif Name: sdbootutil -Version: 1+git20240215.cb7e392%{git_version} +Version: 1+git20240320.8b35615%{git_version} Release: 0 Summary: script to install shim with sd-boot License: MIT @@ -86,6 +86,11 @@ %install install -D -m 755 sdbootutil %{buildroot}%{_bindir}/sdbootutil +# services +for i in sdbootutil-update-predictions.service; do + install -D -m 644 "$i" %{buildroot}%{_unitdir}/"$i" +done + mkdir -p %{buildroot}%{_prefix}/lib/module-init-tools/kernel-scriptlets for a in rpm; do install -m 755 "$a-script" %{buildroot}%{_prefix}/lib/module-init-tools/kernel-scriptlets @@ -132,6 +137,7 @@ %files %license LICENSE %{_bindir}/sdbootutil +%{_unitdir}/sdbootutil-update-predictions.service %files rpm-scriptlets %dir %{_prefix}/lib/module-init-tools ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.6mgGUs/_old 2024-03-22 15:18:46.616876673 +0100 +++ /var/tmp/diff_new_pack.6mgGUs/_new 2024-03-22 15:18:46.620876820 +0100 @@ -3,6 +3,6 @@ <param name="url">https://github.com/lnussel/sdbootutil.git</param> <param name="changesrevision">708592a5033bb41d14e378172466ae9e90dfb3c4</param></service><service name="tar_scm"> <param name="url">https://github.com/openSUSE/sdbootutil.git</param> - <param name="changesrevision">cb7e392f6dd267f735aa7e96e1611a9e2757d06f</param></service></servicedata> + <param name="changesrevision">8b35615850e2642bc7dc2513847e641739acb8cc</param></service></servicedata> (No newline at EOF) ++++++ sdbootutil-1+git20240215.cb7e392.obscpio -> sdbootutil-1+git20240320.8b35615.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sdbootutil-1+git20240215.cb7e392/50-sdbootutil.install new/sdbootutil-1+git20240320.8b35615/50-sdbootutil.install --- old/sdbootutil-1+git20240215.cb7e392/50-sdbootutil.install 2024-02-15 16:03:55.000000000 +0100 +++ new/sdbootutil-1+git20240320.8b35615/50-sdbootutil.install 2024-03-20 11:02:36.000000000 +0100 @@ -25,7 +25,7 @@ ;; add) if [ "${KERNEL_IMAGE#/usr/lib/modules/$KERNEL_VERSION}" = "$KERNEL_IMAGE" ]; then - echo "Unupported kernel location $KERNEL_IMAGE" >&2 + echo "Unsupported kernel location $KERNEL_IMAGE" >&2 exit 1 fi exec /usr/bin/sdbootutil "${args[@]}" 'add-kernel' "$KERNEL_VERSION" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sdbootutil-1+git20240215.cb7e392/sdbootutil new/sdbootutil-1+git20240320.8b35615/sdbootutil --- old/sdbootutil-1+git20240215.cb7e392/sdbootutil 2024-02-15 16:03:55.000000000 +0100 +++ new/sdbootutil-1+git20240320.8b35615/sdbootutil 2024-03-20 11:02:36.000000000 +0100 @@ -6,13 +6,12 @@ # set to --keep-title to use altenate screen. Better for debugging but causes flicker dialog_altenate_screen= -dialog_backtitle="Systemd-boot" +dialog_backtitle="sdbootutil" interactive= verbose= nl=$'\n' shimdir="/usr/share/efi/$(uname -m)" -sdboot_vendor="systemd" -sdboot_dst="/EFI/$sdboot_vendor" +grub2moddir="/usr/share/grub2/$(uname -m)-efi" arg_esp_path="$SYSTEMD_ESP_PATH" arg_entry_token= arg_arch= @@ -30,7 +29,7 @@ rollback=() -tmpdir=$(mktemp -d -t sdboot.XXXXXX) +tmpdir=$(mktemp -d -t sdbootutil.XXXXXX) cleanup() { local i @@ -49,7 +48,6 @@ entryfile="$tmpdir/entries.json" snapperfile="$tmpdir/snapper.json" -title_sort_file="$tmpdir/title_sort.txt" tmpfile="$tmpdir/tmp" helpandquit() @@ -67,13 +65,20 @@ -h, --help This screen COMMAND: - add-kernel VERSION [SUBVOL] + bootloader [SNAPSHOT] + Print the detected bootloader + + add-kernel VERSION [SNAPSHOT] Create boot entry for specified kernel add-all-kernels [SNAPSHOT] Create boot entries for all kernels in SNAPSHOT - remove-kernel VERSION [SUBVOL] + mkinitrd [SNAPSHOT] + Create boot entries for all kernels in SNAPSHOT, + assumes --no-reuse-initrd to regenerate initrds + + remove-kernel VERSION [SNAPSHOT] Remove boot entry for specified kernel remove-all-kernels [SNAPSHOT] @@ -151,6 +156,25 @@ fi } +is_sdboot() +{ + # If systemd-boot and grub2 are co-installed, we favor grub2 + # in the detection + local sdboot grub2 + sdboot="$(find_sdboot "${1-$root_snapshot}")" + grub2="$(find_grub2 "${1-$root_snapshot}")" + [ -e "$sdboot" ] && [ ! -e "$grub2" ] +} + +is_grub2() +{ + # If systemd-boot and grub2 are co-installed, we favor grub2 + # in the detection + local grub2 + grub2="$(find_grub2 "${1-$root_snapshot}")" + [ -e "$grub2" ] +} + reset_rollback() { for i in "${rollback[@]}"; do @@ -188,6 +212,7 @@ } stty_size() { + # shellcheck disable=SC2046 set -- $(stty size 2>/dev/null) LINES="$1" COLUMNS="$2" @@ -199,7 +224,6 @@ fi dh_menu=$((LINES-15)) - dh_text=$((LINES-5)) } # check whether it's a transactional system @@ -213,17 +237,17 @@ local subvol="${1:?}" while read -r line; do [ "$line" = "ro=true" ] && return 0 - done < <(btrfs prop get -t s "${subvol#${subvol_prefix}}" ro) + done < <(btrfs prop get -t s "${subvol#"${subvol_prefix}"}" ro) return 1 } detect_parent() { local subvol="$1" - parent_uuid="$(btrfs subvol show "${subvol#${subvol_prefix}}" | sed -ne 's/\s*Parent UUID:\s*//p')" + parent_uuid="$(btrfs subvol show "${subvol#"${subvol_prefix}"}" | sed -ne 's/\s*Parent UUID:\s*//p')" [ "$parent_uuid" != '-' ] || parent_uuid= [ -n "$parent_uuid" ] || return 0 - parent_subvol="$(/sbin/btrfs subvol show -u "$parent_uuid" "${subvol#${subvol_prefix}}" | head -1)" - parent_snapshot="${parent_subvol#${subvol_prefix}/.snapshots/}" + parent_subvol="$(/sbin/btrfs subvol show -u "$parent_uuid" "${subvol#"${subvol_prefix}"}" | head -1)" + parent_snapshot="${parent_subvol#"${subvol_prefix}"/.snapshots/}" if [ "$parent_subvol" = "$parent_snapshot" ]; then unset parent_subvol parent_snapshot else @@ -237,15 +261,32 @@ # - delete BOOT_IMAGE= and initrd= # - make sure root= refers to uuid # - replace or add rootflags to point at correct subvolume - sed -e "s/[ \t]\+/ /g;s/\<\(BOOT_IMAGE\|initrd\)=[^ ]* \?//;s/\<root=[^ ]*/root=UUID=$root_uuid/;tr;:r;s,\<rootflags=subvol=[^ ]*,rootflags=subvol=$subvol,;tx; s,\$, rootflags=subvol=$subvol,;:x" + # - replace or add systemd.machine-id to match current machine-id + # + # from the sed manual: + # âtâ + # branch conditionally (that is: jump to a label) _only if_ a âs///â + # command has succeeded since the last input line was read or another + # conditional branch was taken. + # we use the t command to jump over an expression that appends a + # parameter if replacing the parameter succeeded (ie it was + # already there). Since we always operate on the same line, + # "empty" t jumps are used to reset the condition after very + # s///. + sed -e "s/[ \t]\+/ /g" \ + -e "s/\<\(BOOT_IMAGE\|initrd\)=[^ ]* \?//" \ + -e "ta;:a" \ + -e "s/\<root=[^ ]*/root=UUID=$root_uuid/;tb;s,\$, root=UUID=$root_uuid,;tc;:c;:b" \ + -e "s,\<rootflags=subvol=[^ ]*,rootflags=subvol=$subvol,;td;s,\$, rootflags=subvol=$subvol,;te;:e;:d" \ + -e "s,\<systemd.machine_id=[^ ]*,systemd.machine_id=$machine_id,;tf;s,\$, systemd.machine_id=$machine_id,;tg;:g;:f" + } remove_kernel() { - local subvol="$1" + local snapshot="${1:?}" + local subvol="${subvol_prefix}/.snapshots/${snapshot}/snapshot" local kernel_version="$2" - local snapshot="${subvol#${subvol_prefix}/.snapshots/}" - snapshot="${snapshot%/*}" local id="$entry_token-$kernel_version-$snapshot.conf" run_command_output bootctl unlink "$id" @@ -266,7 +307,7 @@ mv "$dst" "$dst.bak" || return "$?" fi rollback+=("$dst") - install -m 0644 "$src" "$dst" || return "$?" + install -p -m 0644 "$src" "$dst" || return "$?" chown root:root "$dst" 2>/dev/null || : log_info "installed $dst" } @@ -284,13 +325,14 @@ update_snapper + # shellcheck disable=SC2046 IFS="|" read -r type date desc important pre_num <<< \ $(jq -r --arg snapshot "$snapshot" \ '.["root"][]|select(.number==( $snapshot|tonumber))|[.type,.date,(.description|gsub("\\|";"_")),.userdata.important,."pre-number"//""]|join("|")'\ < "$snapperfile") if [ -z "$desc" ] && [ "$type" = "post" ] && [ -n "$pre_num" ]; then - read -r desc <<< $(jq -r --arg snapshot "$pre_num" '.["root"][]|select(.number==($snapshot|tonumber))|.description' < "$snapperfile") + read -r desc <<< "$(jq -r --arg snapshot "$pre_num" '.["root"][]|select(.number==($snapshot|tonumber))|.description' < "$snapperfile")" fi if [ "$important" = "yes" ]; then important="*"; else important=""; fi @@ -344,7 +386,7 @@ local snapshot_dir="$1" IFS=',' read -ra fields <<< \ - $(findmnt --tab-file "${snapshot_dir}/etc/fstab" --noheadings --nofsroot --output OPTIONS /etc | sed 's#/sysroot##g' | sed 's#:/etc,#:'${snapshot_dir}'/etc,#g') + $(findmnt --tab-file "${snapshot_dir}/etc/fstab" --noheadings --nofsroot --output OPTIONS /etc | sed 's#/sysroot##g' | sed 's#:/etc,#:'"${snapshot_dir}"'/etc,#g') local lower="" local upper="" @@ -363,23 +405,25 @@ umount "${snapshot_dir}/etc" } +add_version_to_title() +{ + # TW pretty name does not include the version + [ -n "$os_release_VERSION" ] || title="$title $os_release_VERSION_ID" +} + install_kernel() { - local subvol="$1" + local snapshot="${1:?}" + local subvol="${subvol_prefix}/.snapshots/${snapshot}/snapshot" local kernel_version="$2" - local initrd=() local dstinitrd=() - local src="${subvol#${subvol_prefix}}/lib/modules/$kernel_version/$image" - local initrddir="${subvol#${subvol_prefix}}/usr/lib/initrd" + local src="${subvol#"${subvol_prefix}"}/lib/modules/$kernel_version/$image" + local initrddir="${subvol#"${subvol_prefix}"}/usr/lib/initrd" test -e "$src" || err "Can't find $src" calc_chksum "$src" local dst="/$entry_token/$kernel_version/linux-$chksum" - # XXX: fix calling with snapshot instead of subvol - local snapshot="${subvol#${subvol_prefix}/.snapshots/}" - snapshot="${snapshot%/snapshot}" - local initrd="${src%/*}/initrd" mkdir -p "$boot_root${dst%/*}" @@ -429,12 +473,13 @@ fi title="${os_release_PRETTY_NAME:-Linux $kernel_version}" - # TW pretty name does not include the version - [ -n "$os_release_VERSION" ] || title="$title $os_release_VERSION_ID" # shellcheck disable=SC2154 sort_key="$os_release_ID" - if ! is_transactional && subvol_is_ro "$subvol"; then + if is_transactional; then + add_version_to_title + elif subvol_is_ro "$subvol"; then + add_version_to_title set_snapper_title_and_sortkey "$snapshot" fi @@ -463,6 +508,7 @@ while [ -e "$tmpdir/initrd-$i" ]; do if [ ! -e "$boot_root${dstinitrd[$i]}" ]; then install_with_rollback "$tmpdir/initrd-$i" "$boot_root${dstinitrd[$i]}" || { failed=initrd; break; } + rm -f "$tmpdir/initrd-$i" fi ((++i)) done @@ -470,9 +516,8 @@ if [ -z "$failed" ]; then loader_entry="$boot_root/loader/entries/$entry_token-$kernel_version-$snapshot.conf" install_with_rollback "$tmpdir/entry.conf" "$loader_entry" || failed="bootloader entry" + rm -f "$tmpdir/entry.conf" fi - rm -f "$tmpdir/initrd" - rm -f "$tmpdir/entry.conf" [ -z "$failed" ] || err "Failed to install $failed" reset_rollback @@ -482,21 +527,21 @@ install_all_kernels() { - local subvol="${subvol_prefix}/.snapshots/${1:?}/snapshot" - find_kernels "$subvol" + local snapshot="${1:?}" + find_kernels "$snapshot" for kv in "${!found_kernels[@]}"; do log_info "installing $kv" - install_kernel "${subvol}" "$kv" + install_kernel "${snapshot}" "$kv" done } remove_all_kernels() { - local subvol="${subvol_prefix}/.snapshots/${1:?}/snapshot" - find_kernels "$subvol" + local snapshot="${1:?}" + find_kernels "$snapshot" for kv in "${!found_kernels[@]}"; do - remove_kernel "${subvol}" "$kv" + remove_kernel "${snapshot}" "$kv" done } @@ -703,7 +748,7 @@ if [ "$isdefault" = "true" ]; then id="\e[1;4m$id\e[m" fi - update_kernels "${subvol_prefix}/.snapshots/$n/snapshot" + update_kernels "$n" [ "$is_bootable" = 1 ] || id="!$id" echo -e "$id $title" done < <(jq '.root|.[]|[.number, .default, .description]|join(" ")' -r < "$snapperfile") @@ -726,7 +771,7 @@ default="$n" title="\\Zb\Zu$title\\Zn" fi - update_kernels "${subvol_prefix}/.snapshots/$n/snapshot" + update_kernels "$n" [ "$is_bootable" = 1 ] || title="!$title" list+=("$n" "$title") done < <(jq '.root|.[]|[.number, .default, .description]|join(" ")' -r < "$snapperfile") @@ -774,11 +819,11 @@ declare -A found_kernels find_kernels() { - local subvol="${1:?}" + local subvol="${subvol_prefix}/.snapshots/${1:?}/snapshot" local fn kv found_kernels=() - for fn in "${subvol#${subvol_prefix}}"/usr/lib/modules/*/"$image"; do + for fn in "${subvol#"${subvol_prefix}"}"/usr/lib/modules/*/"$image"; do kv="${fn%/*}" kv="${kv##*/}" calc_chksum "$fn" @@ -795,16 +840,16 @@ is_bootable= update_kernels() { - local subvol="${1:?}" + local snapshot="${1:?}" local path id installed_kernels=() stale_kernels=() is_bootable= - find_kernels "$subvol" + find_kernels "$snapshot" for kv in "${!found_kernels[@]}"; do installed_kernels["/$entry_token/$kv/linux-${found_kernels[$kv]}"]='' done - update_entries_for_subvol "$subvol" + update_entries_for_snapshot "$snapshot" # XXX: maybe we should parse the actual path in the entry while read -r path id; do @@ -820,8 +865,8 @@ list_kernels() { - subvol="${subvol_prefix}/.snapshots/${1:?}/snapshot" - update_kernels "$subvol" + local snapshot="${1:?}" + update_kernels "$snapshot" local kernelfiles=("${!installed_kernels[@]}") for k in "${kernelfiles[@]}"; do local id="${installed_kernels[$k]}" @@ -842,8 +887,8 @@ is_bootable() { - subvol="${subvol_prefix}/.snapshots/${1:?}/snapshot" - update_kernels "$subvol" + local snapshot="${1:?}" + update_kernels "$snapshot" [ "$is_bootable" = 1 ] || return 1 return 0 @@ -851,9 +896,10 @@ show_kernels() { + local snapshot="${1:?}" subvol="${subvol_prefix}/.snapshots/${1:?}/snapshot" while true; do - update_kernels "$subvol" + update_kernels "$snapshot" local list=() local n=0 local default= @@ -910,7 +956,7 @@ break # might have selected delete so refresh ;; install) - install_kernel "$subvol" "$kv" + install_kernel "$snapshot" "$kv" break ;; esac @@ -918,27 +964,35 @@ done } -sdboot_version() +bootloader_version() { local fn="$1" if [ -z "$1" ]; then if [ -e "$shimdir/shim.efi" ]; then - fn="$boot_root$sdboot_dst/grub.efi" + fn="$boot_root$boot_dst/grub.efi" else - local sdboot - sdboot="$(find_sdboot)" - fn="$boot_root$sdboot_dst/${sdboot##*/}" + local bootloader + bootloader="$(find_bootloader)" + fn="$boot_root$boot_dst/${bootloader##*/}" fi fi [ -e "$fn" ] || return 1 - read -r _ _ _ v _ < <(grep -ao '#### LoaderInfo: systemd-boot [^#]\+ ####' "$fn") + if is_sdboot; then + read -r _ _ _ v _ < <(grep -ao '#### LoaderInfo: systemd-boot [^#]\+ ####' "$fn") + else + # Useless as it reports mayor.minor, so append the + # last update time until the minutes, as the FAT store + # dates differently than other filesystems + read -r _ _ _ v _ < <(grep -aoP 'GNU GRUB version %s\x00[^\x00]+\x00' "$fn") + v="${v:2}-$(date -r "$fn" +'%Y%m%d%H%M')" + fi [ -n "$v" ] || return 1 echo "$v" } is_installed() { - sdboot_version > /dev/null && [ -e "$boot_root/$sdboot_dst/installed_by_sdbootutil" ] + bootloader_version > /dev/null && [ -e "$boot_root/$boot_dst/installed_by_sdbootutil" ] } find_sdboot() @@ -948,33 +1002,54 @@ # systemd-boot from a separate package local sdboot="$prefix/usr/lib/systemd-boot/systemd-boot$firmware_arch.efi" [ -e "$sdboot" ] || sdboot="$prefix/usr/lib/systemd/boot/efi/systemd-boot$firmware_arch.efi" - [ -e "$sdboot" ] || err "missing $sdboot" echo "$sdboot" } -sdboot_needs_update() +find_grub2() +{ + local prefix="/.snapshots/${1-$root_snapshot}/snapshot" + local grub2="$prefix/usr/share/efi/$(uname -m)/grub.efi" + [ -e "$grub2" ] || grub2="$prefix/usr/share/grub2/$(uname -m)-efi/grub.efi" + echo "$grub2" +} + +find_bootloader() +{ + if is_sdboot "${1-$root_snapshot}"; then + find_sdboot "${1-$root_snapshot}" + elif is_grub2 "${1-$root_snapshot}"; then + find_grub2 "${1-$root_snapshot}" + else + err "Bootloader not detected" + fi +} + +bootloader_needs_update() { local snapshot="${1-$root_snapshot}" local prefix="/.snapshots/${snapshot}/snapshot" + local bldr_name local v nv - v="$(sdboot_version)" + v="$(bootloader_version)" [ -n "$v" ] || return 1 log_info "deployed version $v" - nv="$(sdboot_version "$(find_sdboot "$snapshot")")" + nv="$(bootloader_version "$(find_bootloader "$snapshot")")" [ -n "$v" ] || return 1 log_info "system version $nv" systemd-analyze compare-versions "$v" lt "$nv" 2>/dev/null || return 1 - log_info "systemd-boot needs to be updated" + bldr_name=$(bootloader_name "$snapshot") + log_info "$bldr_name needs to be updated" return 0 } -install_sdboot() +install_bootloader() { local snapshot="${1:-$root_snapshot}" local prefix="/.snapshots/${root_snapshot}/snapshot" - local sdboot blkpart drive partno + local bootloader bldr_name blkpart drive partno - sdboot=$(find_sdboot "$1") + bootloader=$(find_bootloader "$snapshot") + bldr_name=$(bootloader_name "$snapshot") mkdir -p "$boot_root/loader/entries" @@ -987,36 +1062,57 @@ read -r partno < "/sys/class/block/${blkpart##*/}"/partition if [ -e "$prefix$shimdir/shim.efi" ]; then - log_info "Installing systemd-boot with shim into $boot_root" - entry="$sdboot_dst/shim.efi" + log_info "Installing $bldr_name with shim into $boot_root" + entry="$boot_dst/shim.efi" for i in MokManager shim; do - install -D "$prefix$shimdir/$i.efi" "$boot_root$sdboot_dst/$i.efi" + install -p -D "$prefix$shimdir/$i.efi" "$boot_root$boot_dst/$i.efi" done - install -D "$sdboot" "$boot_root$sdboot_dst/grub.efi" + install -p -D "$bootloader" "$boot_root$boot_dst/grub.efi" # boot entry point for i in MokManager fallback; do - install -D "$prefix$shimdir/$i.efi" "$boot_root/EFI/BOOT/$i.efi" + install -p -D "$prefix$shimdir/$i.efi" "$boot_root/EFI/BOOT/$i.efi" done - install -D "$prefix$shimdir/shim.efi" "$boot_root/EFI/BOOT/BOOT${firmware_arch^^}.EFI" + install -p -D "$prefix$shimdir/shim.efi" "$boot_root/EFI/BOOT/BOOT${firmware_arch^^}.EFI" else - log_info "Installing systemd-boot into $boot_root" - entry="$sdboot_dst/${sdboot##*/}" - install -D "$sdboot" "$boot_root$entry" - install -D "$sdboot" "$boot_root/EFI/BOOT/BOOT${firmware_arch^^}.EFI" + log_info "Installing $bldr_name into $boot_root" + entry="$boot_dst/${bootloader##*/}" + install -p -D "$bootloader" "$boot_root$entry" + install -p -D "$bootloader" "$boot_root/EFI/BOOT/BOOT${firmware_arch^^}.EFI" fi # this is for shim to create the entry if missing - echo "${entry##*/},openSUSE Boot Manager" | iconv -f ascii -t ucs2 > "$boot_root/$sdboot_dst/boot.csv" + echo "${entry##*/},openSUSE Boot Manager" | iconv -f ascii -t ucs2 > "$boot_root/$boot_dst/boot.csv" mkdir -p "$boot_root/$entry_token" - echo "$entry_token" > "$boot_root/$sdboot_dst/installed_by_sdbootutil" + echo "$entry_token" > "$boot_root/$boot_dst/installed_by_sdbootutil" mkdir -p "/etc/kernel" [ -s /etc/kernel/entry-token ] || echo "$entry_token" > /etc/kernel/entry-token update_random_seed - [ -s "$boot_root/loader/entries.srel" ] || echo type1 > "$boot_root/loader/entries.srel" - - [ -e "$boot_root/loader/loader.conf" ] || echo -e "#timeout 3\n#console-mode keep\n" > "$boot_root/loader/loader.conf" + if is_sdboot "$snapshot"; then + [ -s "$boot_root/loader/entries.srel" ] || echo type1 > "$boot_root/loader/entries.srel" + [ -e "$boot_root/loader/loader.conf" ] || echo -e "#timeout 3\n#console-mode keep\n" > "$boot_root/loader/loader.conf" + elif is_grub2 "$snapshot"; then + # Minimal configuration file for now. The theme can + # come later with: + # * rsync the theme in /boot/efi + # * grub memdisk, removing unused modules (fs, + # crypto, LVM, RAID) + [ -e "$boot_root$boot_dst/grub.cfg" ] || cat > "$boot_root$boot_dst/grub.cfg" <<-EOF + timeout=8 + function load_video { + # A load_video call is added for each bls entry + true + } + # Required to populate EFI varidables + insmod bli + blscfg + EOF + + [ -e "$boot_root/EFI/BOOT/grub.cfg" ] || cp "$boot_root$boot_dst/grub.cfg" "$boot_root/EFI/BOOT/grub.cfg" + mkdir -p "$boot_root$boot_dst/$(uname -m)-efi" + cp -a "$prefix$grub2moddir/bli.mod" "$boot_root$boot_dst/$(uname -m)-efi" + fi # Create boot menu entry if it does not exist [ -n "$arg_no_variables" ] || efibootmgr | grep -q 'Boot.*openSUSE Boot Manager' || efibootmgr -q --create --disk "$drive" --part "$partno" --label "openSUSE Boot Manager" --loader "$entry" || true @@ -1073,14 +1169,14 @@ mv "$boot_root/loader/random-seed.new" "$boot_root/loader/random-seed" } -install_sdboot_interactive() +install_bootloader_interactive() { local v - v="$(sdboot_version)" + v="$(bootloader_version)" if [ -n "$v" ]; then - if sdboot_needs_update; then + if bootloader_needs_update; then local nv - nv="$(sdboot_version "$(find_sdboot)")" + nv="$(bootloader_version "$(find_bootloader)")" d --aspect 60 --yesno "Update systemd-boot from $v to $nv?" 0 0 || return 0 else d --aspect 60 --yesno "systemd-boot already at current version $v. Install again?" 0 0 || return 0 @@ -1089,7 +1185,7 @@ d --aspect 60 --yesno "Are you sure you want to install systemd-boot into $boot_root?\n This will overwrite any existing bootloaders" 0 0 || return 0 fi - install_sdboot + install_bootloader d --aspect 60 --msgbox "Installed into $boot_root" 0 0 } @@ -1131,20 +1227,12 @@ } # TODO: Maybe share this code outside -run_log() -{ - "$@" 2>&1 | logger -t sdbootutil -} - -# TODO: Maybe share this code outside -info_log() -{ - logger -t sdbootutil "$@" +have_pcrlock() { + [ -e /usr/lib/systemd/systemd-pcrlock ] } -# TODO: Maybe share this code outside -is_pcrlock() { - [ -e /usr/lib/systemd/systemd-pcrlock ] +pcrlock() { + SYSTEMD_LOG_LEVEL="${SYSTEMD_LOG_LEVEL:-warning}" /usr/lib/systemd/systemd-pcrlock "$@" } # TODO: Maybe share this code outside @@ -1168,18 +1256,19 @@ done < <(jq -r '.root[]|select(.active==true or .default==true)|.number' "$snapperfile") if is_transactional && [ -e "${state_file}" ]; then - . "${state_file}" - for id in $LAST_WORKING_SNAPSHOTS; do - snapshots[$id]=1 - done + # shellcheck disable=SC1090 + . "${state_file}" + for id in $LAST_WORKING_SNAPSHOTS; do + snapshots[$id]=1 + done fi - info_log "Creating predictions for snapshots: ${!snapshots[*]}" + log_info "Creating predictions for snapshots: ${!snapshots[*]}" local re if [ "${#snapshots[@]}" = 1 ]; then - re="${!snapshots[*]}" + re="${!snapshots[*]}" else - IFS='|' eval re='"(:?${!snapshots[*]})"' + IFS='|' eval re='"(:?${!snapshots[*]})"' fi update_entries_for_snapshot "$re" @@ -1194,11 +1283,11 @@ # 710-kernel-cmdline-initrd-entry.pcrlock.d is not part of the # pcrlock standards echo "$cmdline" > "$tmpdir/cmdline" - run_log /usr/lib/systemd/systemd-pcrlock \ + pcrlock \ lock-kernel-cmdline \ --pcrlock="$tmpdir/cmdline.pcrlock" \ "$tmpdir/cmdline" - run_log /usr/lib/systemd/systemd-pcrlock \ + pcrlock \ lock-kernel-initrd \ --pcrlock="$tmpdir/initrd.pcrlock" \ "${boot_root}/$initrd" @@ -1214,7 +1303,7 @@ # pcrlock standards echo -ne "$cmdline\0" > "$tmpdir/cmdline" iconv -t UTF-16LE -o "$tmpdir/cmdline.utf16" "$tmpdir/cmdline" - run_log /usr/lib/systemd/systemd-pcrlock \ + pcrlock \ lock-raw \ --pcr=12 \ --pcrlock="/var/lib/pcrlock.d/710-kernel-cmdline-boot-loader.pcrlock.d/cmdline-$suffix.pcrlock" \ @@ -1234,30 +1323,37 @@ # predictions at minimum and decrease the combinations rm -fr /var/lib/pcrlock.d/* - run_log /usr/lib/systemd/systemd-pcrlock lock-firmware-code - run_log /usr/lib/systemd/systemd-pcrlock lock-firmware-config + pcrlock lock-firmware-code + pcrlock lock-firmware-config # If secure boot is disabled, this can fail. There is patch # for the policy generation, and for the authority is planned - run_log /usr/lib/systemd/systemd-pcrlock lock-secureboot-policy || true - run_log /usr/lib/systemd/systemd-pcrlock lock-secureboot-authority || true - # TODO: what drive should be here? - # run_log /usr/lib/systemd/systemd-pcrlock lock-gpt "$drive" + /usr/lib/systemd/systemd-pcrlock lock-secureboot-policy || true + /usr/lib/systemd/systemd-pcrlock lock-secureboot-authority || true + # uses / by default + pcrlock lock-gpt # 630-shim-efi-application is not part of the pcrlock standards # TODO: move to shim-pcrlock.rpm - run_log /usr/lib/systemd/systemd-pcrlock \ + pcrlock \ lock-pe \ --pcrlock=/var/lib/pcrlock.d/630-shim-efi-application.pcrlock.d/generated.pcrlock \ - "${boot_root}${sdboot_dst}/shim.efi" + "${boot_root}${boot_dst}/shim.efi" # 640-boot-loader-efi-application is not part of the pcrlock # standards # This is measuing the systemd-boot EFI binary (named grub.efi) # TODO: move to systemd-boot-pcrlock.rpm - run_log /usr/lib/systemd/systemd-pcrlock \ + pcrlock \ lock-pe \ --pcrlock=/var/lib/pcrlock.d/640-boot-loader-efi-application.pcrlock.d/generated.pcrlock \ - "${boot_root}${sdboot_dst}/grub.efi" + "${boot_root}${boot_dst}/grub.efi" + + if [ -e "$boot_root/loader/loader.conf" ]; then + pcrlock \ + lock-raw /boot/efi/loader/loader.conf \ + --pcr=5 \ + --pcrlock=/var/lib/pcrlock.d/641-sdboot-loader-conf.pcrlock + fi # 650-kernel-efi-application.pcrlock is not part of the # pcrlock standards @@ -1265,7 +1361,7 @@ local n=0 while read -r i; do n=$((n+1)) - run_log /usr/lib/systemd/systemd-pcrlock \ + pcrlock \ lock-pe \ --pcrlock=/var/lib/pcrlock.d/650-kernel-efi-application.pcrlock.d/linux-"$n".pcrlock \ "${boot_root}/$i" @@ -1292,11 +1388,11 @@ pcrlock_cmdline_initrd "$cmdline" "$initrd" "0" fi - run_log /usr/lib/systemd/systemd-pcrlock --pcr="$pcrs" make-policy + pcrlock --pcr="$pcrs" make-policy # Publish the assets in the ESP, so can be imported by # dracut-pcr-signature - [ -e /var/lib/systemd/pcrlock.json ] && cp /var/lib/systemd/pcrlock.json "${boot_root}${sdboot_dst}" + [ -e /var/lib/systemd/pcrlock.json ] && cp /var/lib/systemd/pcrlock.json "${boot_root}${boot_dst}" } get_pcrs() { @@ -1320,14 +1416,24 @@ select_entries_for_prediction all_pcrs=$(get_pcrs) - [ -z "$all_pcrs" ] || rm -f /etc/systemd/tpm2-pcr-signature.json + if [ -z "$all_pcrs" ]; then + warn "PCR Oracle configured but not enrolled in any LUKS header" + return 0 + fi + + rm -f /etc/systemd/tpm2-pcr-signature.json # We make as many predictions as |all_pcrs| * |entries| to # cover all the combinations. pcr-oracle is smart to include # the entry only one time, so we will not have duplications. # This is a step for multi device configurations. + declare -a entries + mapfile -t entries < <(jq -r '.[]|.id' "$entryfile") + if [ -z "${entries[0]}" ]; then + err "No bootloader entries found" + fi for pcrs in $all_pcrs; do - while read -r entry; do + for entry in "${entries[@]}"; do log_info "Generate prediction for $entry with PCRs $pcrs" if ! pcr-oracle \ --private-key /etc/systemd/tpm2-pcr-private-key.pem \ @@ -1336,15 +1442,15 @@ --target-platform=systemd \ --boot-entry "${entry}" \ sign "$pcrs"; then - err "Failed to install TPM predictions for ${entry_id}" + err "Failed to install TPM predictions for ${entry}" fi - done < <(jq -r '.[]|.id' "$entryfile") + done done # Publish the assets in the ESP, so can be imported by # dracut-pcr-signature - cp /etc/systemd/tpm2-pcr-public-key.pem "${boot_root}${sdboot_dst}" - [ -e /etc/systemd/tpm2-pcr-signature.json ] && cp /etc/systemd/tpm2-pcr-signature.json "${boot_root}${sdboot_dst}" + cp /etc/systemd/tpm2-pcr-public-key.pem "${boot_root}${boot_dst}" + [ -e /etc/systemd/tpm2-pcr-signature.json ] && cp /etc/systemd/tpm2-pcr-signature.json "${boot_root}${boot_dst}" } @@ -1353,19 +1459,26 @@ { [ -e /etc/crypttab ] || return 0 grep -q "tpm2-device" /etc/crypttab || return 0 - [ -e /etc/sysconfig/fde-tools ] || return 0 - . /etc/sysconfig/fde-tools + if is_pcr_oracle; then + generate_tpm2_predictions_pcr_oracle + elif have_pcrlock; then + [ -e /etc/sysconfig/fde-tools ] || return 0 + # shellcheck disable=SC1091 + . /etc/sysconfig/fde-tools - if is_pcrlock && is_pcr_oracle; then - echo "pcrlock and signed policies are mutually exclusive, remove one set of files to continue" - return 0 + generate_tpm2_predictions_pcrlock "${FDE_SEAL_PCR_LIST}" fi +} - if is_pcrlock; then - generate_tpm2_predictions_pcrlock "${FDE_SEAL_PCR_LIST}" - elif is_pcr_oracle; then - generate_tpm2_predictions_pcr_oracle +bootloader_name() +{ + if is_sdboot "${1-$root_snapshot}"; then + echo "systemd-boot" + elif is_grub2 "${1-$root_snapshot}"; then + echo "grub2" + else + err "Bootloader not detected" fi } @@ -1380,7 +1493,7 @@ snapper) show_snapper ;; sd-boot) update_entries cat; show_entries ;; kernels) show_kernels "$root_snapshot";; - install) install_sdboot_interactive ;; + install) install_bootloader_interactive ;; esac done } @@ -1409,7 +1522,7 @@ done case "$1" in - install|needs-update|update|force-update|add-kernel|remove-kernel|set-default-snapshot|add-all-kernels|remove-all-kernels|is-installed|list-snapshots|list-entries|list-kernels|is-bootable|update-predictions) ;; + install|needs-update|update|force-update|add-kernel|remove-kernel|set-default-snapshot|add-all-kernels|mkinitrd|remove-all-kernels|is-installed|list-snapshots|list-entries|list-kernels|is-bootable|update-predictions|bootloader) ;; kernels|snapshots|entries|"") stty_size; interactive=1 ;; *) err "unknown command $1" ;; esac @@ -1447,23 +1560,37 @@ *) err "Unsupported architecture $firmware_arch" ;; esac -root_snapshot="${root_subvol#${subvol_prefix}/.snapshots/}" +root_snapshot="${root_subvol#"${subvol_prefix}"/.snapshots/}" root_snapshot="${root_snapshot%/snapshot}" +# XXX: Unify both in /EFI/opensuse? +if is_sdboot; then + boot_dst="/EFI/systemd" +elif is_grub2; then + boot_dst="/EFI/opensuse" +else + err "Bootloader not detected" +fi + if [ "$1" = "install" ]; then - install_sdboot "${2:-$root_snapshot}" + install_bootloader "${2:-$root_snapshot}" elif [ "$1" = "needs-update" ]; then - sdboot_needs_update "${2:-$root_snapshot}" + bootloader_needs_update "${2:-$root_snapshot}" elif [ "$1" = "update" ]; then - if sdboot_needs_update "${2:-$root_snapshot}"; then install_sdboot "${2:-$root_snapshot}"; else :; fi + if bootloader_needs_update "${2:-$root_snapshot}"; then install_bootloader "${2:-$root_snapshot}"; else :; fi elif [ "$1" = "force-update" ]; then - if is_installed; then install_sdboot "${2:-$root_snapshot}"; else :; fi + if is_installed; then install_bootloader "${2:-$root_snapshot}"; else :; fi +elif [ "$1" = "bootloader" ]; then + bootloader_name "${2:-$root_snapshot}" elif [ "$1" = "add-kernel" ]; then - install_kernel "${3:-$root_subvol}" "$2" + install_kernel "${3:-$root_snapshot}" "$2" elif [ "$1" = "add-all-kernels" ]; then install_all_kernels "${2:-$root_snapshot}" +elif [ "$1" = "mkinitrd" ]; then + arg_no_reuse_initrd=1 + install_all_kernels "${2:-$root_snapshot}" elif [ "$1" = "remove-kernel" ]; then - remove_kernel "${3:-$root_subvol}" "$2" + remove_kernel "${3:-$root_snapshot}" "$2" elif [ "$1" = "remove-all-kernels" ]; then remove_all_kernels "${2:-$root_snapshot}" elif [ "$1" = "set-default-snapshot" ]; then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sdbootutil-1+git20240215.cb7e392/sdbootutil-update-predictions.service new/sdbootutil-1+git20240320.8b35615/sdbootutil-update-predictions.service --- old/sdbootutil-1+git20240215.cb7e392/sdbootutil-update-predictions.service 1970-01-01 01:00:00.000000000 +0100 +++ new/sdbootutil-1+git20240320.8b35615/sdbootutil-update-predictions.service 2024-03-20 11:02:36.000000000 +0100 @@ -0,0 +1,7 @@ +[Unit] +Description=Update TPM predictions +ConditionSecurity=tpm2 + +[Service] +Type=oneshot +ExecStart=/usr/bin/sdbootutil update-predictions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sdbootutil-1+git20240215.cb7e392/sdbootutil.spec new/sdbootutil-1+git20240320.8b35615/sdbootutil.spec --- old/sdbootutil-1+git20240215.cb7e392/sdbootutil.spec 2024-02-15 16:03:55.000000000 +0100 +++ new/sdbootutil-1+git20240320.8b35615/sdbootutil.spec 2024-03-20 11:02:36.000000000 +0100 @@ -86,6 +86,11 @@ %install install -D -m 755 sdbootutil %{buildroot}%{_bindir}/sdbootutil +# services +for i in sdbootutil-update-predictions.service; do + install -D -m 644 "$i" %{buildroot}%{_unitdir}/"$i" +done + mkdir -p %{buildroot}%{_prefix}/lib/module-init-tools/kernel-scriptlets for a in rpm; do install -m 755 "$a-script" %{buildroot}%{_prefix}/lib/module-init-tools/kernel-scriptlets @@ -132,6 +137,7 @@ %files %license LICENSE %{_bindir}/sdbootutil +%{_unitdir}/sdbootutil-update-predictions.service %files rpm-scriptlets %dir %{_prefix}/lib/module-init-tools ++++++ sdbootutil.obsinfo ++++++ --- /var/tmp/diff_new_pack.6mgGUs/_old 2024-03-22 15:18:46.728880790 +0100 +++ /var/tmp/diff_new_pack.6mgGUs/_new 2024-03-22 15:18:46.728880790 +0100 @@ -1,5 +1,5 @@ name: sdbootutil -version: 1+git20240215.cb7e392 -mtime: 1708009435 -commit: cb7e392f6dd267f735aa7e96e1611a9e2757d06f +version: 1+git20240320.8b35615 +mtime: 1710928956 +commit: 8b35615850e2642bc7dc2513847e641739acb8cc
