From d2050181d429e5f863ca0b173a83e95c131cac8d Mon Sep 17 00:00:00 2001
From: Dan Bungert <daniel.bungert@canonical.com>
Date: Thu, 27 Feb 2025 17:15:02 -0700
Subject: [PATCH] subiquity: easier bridge kernel setup

For subiquity installs, make it easier to enable bridge kernel, just a
boolean to set true/false.  Don't enable yet though.
---
 live-build/auto/config       | 40 ++++++++++++++----------------------
 live-build/functions         | 36 ++++++++++++++++++++++++++++++++
 live-build/lb_binary_layered |  3 ++-
 3 files changed, 53 insertions(+), 26 deletions(-)

diff --git a/live-build/auto/config b/live-build/auto/config
index ddbe2970..ef279cb5 100755
--- a/live-build/auto/config
+++ b/live-build/auto/config
@@ -78,6 +78,14 @@ BINARY_HOOKS=
 
 APT_OPTIONS=" --yes -oDebug::pkgDepCache::AutoInstall=yes "
 
+# Should we attempt to offer both the bridge and default kernel?
+USE_BRIDGE_KERNEL=false
+# Why are we using bridge kernel?  Value is ignored for USE_BRIDGE_KERNEL=false.
+# Possible reasons are zfs, drivers.
+BRIDGE_KERNEL_REASONS="zfs,drivers"
+# When building install-sources, what kernel is the default?
+DEFAULT_KERNEL=
+
 PASSES_TO_LAYERS=false
 _PASSES_TO_LAYERS=		# Stores the initial value of PASSES_TO_LAYERS
 PASSES=
@@ -240,28 +248,6 @@ add_snap ()
 	done
 }
 
-write_kernel_yaml () {
-	# Generate the kernel.yaml fragment used as input for
-	# update-source-catalog.  Handles default kernel specification.
-	# $1 kernel metapackage name
-	local metapkg="$1"
-	cat <<-EOF > config/kernel.yaml
-		kernel:
-		  default: "$metapkg"
-	EOF
-
-	# To specify fallback to a bridge kernel, construct a kernel.yaml
-	# with the following:
-	#
-	# kernel:
-	#   default: foo
-	#   bridge: bar
-	#   bridge_reasons: [zfs, drivers]
-	#
-	# If an install is using zfs or "drivers", use the bridge kernel, else
-	# use the default kernel.
-}
-
 get_seeded_languages () {
 	# We assume any seed name of the form ${no_lang_seed}-${foo} where
 	# ${foo} is only two or three characters long is a default language
@@ -812,7 +798,7 @@ do_layered_desktop_image() {
 		EOF
 	fi
 
-	write_kernel_yaml "linux-$KERNEL_FLAVOURS"
+	DEFAULT_KERNEL="linux-$KERNEL_FLAVOURS"
 
 	if [ "$LOCALE_SUPPORT" != none ]; then
 		/usr/share/livecd-rootfs/checkout-translations-branch \
@@ -1105,7 +1091,7 @@ case $PROJECT in
 				esac
 				NO_SQUASHFS_PASSES=ubuntu-server-minimal.ubuntu-server.installer.$flavor.netboot
 
-				write_kernel_yaml $kernel_metapkg
+				DEFAULT_KERNEL="$kernel_metapkg"
 				/usr/share/livecd-rootfs/checkout-translations-branch \
 					https://git.launchpad.net/subiquity po config/catalog-translations
 				;;
@@ -1133,7 +1119,8 @@ case $PROJECT in
 	    add_package base.live linux-image-generic
 
 	    # Core installer images use the pc-kernel snap for its kernel
-	    write_kernel_yaml "snap:pc-kernel"
+	    USE_BRIDGE_KERNEL=false
+	    DEFAULT_KERNEL="snap:pc-kernel"
 
 	    /usr/share/livecd-rootfs/checkout-translations-branch \
 		https://git.launchpad.net/subiquity po config/catalog-translations
@@ -1399,6 +1386,9 @@ echo "BUILDSTAMP=\"$NOW\"" >> config/binary
 echo "SUBPROJECT=\"${SUBPROJECT:-}\"" >> config/binary
 echo "LB_DISTRIBUTION=\"$SUITE\"" >> config/binary
 echo "CHANNEL=\"${CHANNEL:-}\"" >> config/binary
+echo "USE_BRIDGE_KERNEL=\"${USE_BRIDGE_KERNEL:-}\"" >> config/binary
+echo "BRIDGE_KERNEL_REASONS=\"${BRIDGE_KERNEL_REASONS:-}\"" >> config/binary
+echo "DEFAULT_KERNEL=\"${DEFAULT_KERNEL:-}\"" >> config/binary
 
 if [ "${IMAGE_HAS_HARDCODED_PASSWORD:-}" = "1" ]; then
 	echo IMAGE_HAS_HARDCODED_PASSWORD=1 >> config/binary
diff --git a/live-build/functions b/live-build/functions
index 39d53971..4f26e087 100644
--- a/live-build/functions
+++ b/live-build/functions
@@ -1337,3 +1337,39 @@ reset_snapd_state() {
     chroot "$rootdir" apt-get install --reinstall -y snapd
     teardown_mountpoint "$rootdir"
 }
+
+write_kernel_yaml() {
+    # Generate the kernel.yaml fragment used as input for
+    # update-source-catalog.
+    #
+    # the newer kernel is the default kernel!
+    # bridge is the older, fallback kernel.
+    # $1 string, default kernel, such as "linux-generic"
+    # $2 string with comma seperated list of bridge reasons,
+    #    usually "zfs,drivers"
+    local default="$1"
+    local reasons="$2"
+
+    cat <<EOF > config/kernel.yaml
+kernel:
+  default: "$default"
+EOF
+
+    # To specify fallback to a bridge kernel, construct a kernel.yaml
+    # with the following:
+    #
+    # kernel:
+    #   default: linux-foo
+    #   bridge: linux-foo-brg-YY.MM
+    #   bridge_reasons: [zfs, drivers]
+    #
+    # If an install is using zfs or "drivers", use the bridge kernel, else
+    # use the default kernel.
+
+    if $USE_BRIDGE_KERNEL ; then
+        cat <<EOF >> config/kernel.yaml
+  bridge: "${default}-brg-$(release_ver)"
+  bridge_reasons: [$reasons]
+EOF
+    fi
+}
diff --git a/live-build/lb_binary_layered b/live-build/lb_binary_layered
index e64ecaee..75dfe9c7 100755
--- a/live-build/lb_binary_layered
+++ b/live-build/lb_binary_layered
@@ -204,7 +204,8 @@ do
 	build_layered_squashfs "${_PASS}" ${*}
 done
 
-if [ -f config/kernel.yaml ]; then
+if [ -n "$DEFAULT_KERNEL" -a -f livecd.${PROJECT_FULL}.install-sources.yaml ]; then
+	write_kernel_yaml "$DEFAULT_KERNEL" "$BRIDGE_KERNEL_REASONS"
 	/usr/share/livecd-rootfs/update-source-catalog merge \
 		--output livecd.${PROJECT_FULL}.install-sources.yaml \
 		--template config/kernel.yaml