8d419f
From 0f4ea4aee6e404dfbd6e3c4bbfb4f805e4e257f6 Mon Sep 17 00:00:00 2001
8d419f
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
8d419f
Date: Wed, 19 Jan 2022 12:20:22 +0100
8d419f
Subject: [PATCH] kernel-install: add "$KERNEL_INSTALL_STAGING_AREA" directory
8d419f
8d419f
The general approach of kernel-install was that each plugin would drop in some
8d419f
files into the entry directory. But this doesn't scale well, because if we have
8d419f
multiple initrd generators, or multiple initrds, each generator would need to
8d419f
recreate the logic to put the generated files in the right place.
8d419f
8d419f
Also, effective cleanup is impossible if anything goes wrong on the way, so we
8d419f
could end up with unused files in $BOOT.
8d419f
8d419f
So let's invert the process: plugins drop files into $KERNEL_INSTALL_STAGING_AREA,
8d419f
and at the end 90-loaderentry.install DTRT with those files.
8d419f
8d419f
This allow new plugins like 50-mkosi-initrd.install to be significantly simpler.
8d419f
8d419f
(cherry picked from commit 367165a4069ac0c04882a05a8a80f6afb1e42760)
8d419f
8d419f
Related: #2065061
8d419f
---
8d419f
 man/kernel-install.xml                    |  4 ++++
8d419f
 src/kernel-install/90-loaderentry.install | 13 ++++++++++---
8d419f
 src/kernel-install/kernel-install         | 10 ++++++++++
8d419f
 3 files changed, 24 insertions(+), 3 deletions(-)
8d419f
8d419f
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
8d419f
index bb76074d2e..685617863e 100644
8d419f
--- a/man/kernel-install.xml
8d419f
+++ b/man/kernel-install.xml
8d419f
@@ -180,6 +180,10 @@
8d419f
     This should be configured as <varname>initrd_generator=</varname> in <filename>install.conf</filename>.
8d419f
     </para>
8d419f
 
8d419f
+    <para><varname>KERNEL_INSTALL_STAGING_AREA=...</varname> is set for plugins to a path to a directory.
8d419f
+    Plugins may drop files in that directory, and they will be installed as part of the loader entry, based
8d419f
+    on the file name and extension.</para>
8d419f
+
8d419f
     <variablelist>
8d419f
       <varlistentry>
8d419f
         <term>bls</term>
8d419f
diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install
8d419f
index 6a396910cb..0888c260e2 100644
8d419f
--- a/src/kernel-install/90-loaderentry.install
8d419f
+++ b/src/kernel-install/90-loaderentry.install
8d419f
@@ -18,6 +18,8 @@
8d419f
 # You should have received a copy of the GNU Lesser General Public License
8d419f
 # along with systemd; If not, see <http://www.gnu.org/licenses/>.
8d419f
 
8d419f
+shopt -s nullglob
8d419f
+
8d419f
 COMMAND="$1"
8d419f
 KERNEL_VERSION="$2"
8d419f
 ENTRY_DIR_ABS="$3"
8d419f
@@ -88,7 +90,8 @@ install -g root -o root -m 0644 "$KERNEL_IMAGE" "$ENTRY_DIR_ABS/linux" || {
8d419f
 }
8d419f
 
8d419f
 shift "$INITRD_OPTIONS_SHIFT"
8d419f
-for initrd; do
8d419f
+# All files listed as arguments, and staged files called "initrd*" are installed as initrds.
8d419f
+for initrd in "$@" "${KERNEL_INSTALL_STAGING_AREA}"/initrd*; do
8d419f
     [ -f "$initrd" ] || {
8d419f
         echo "Error: initrd '$initrd' not a file." >&2
8d419f
         exit 1
8d419f
@@ -114,11 +117,15 @@ mkdir -p "${LOADER_ENTRY%/*}" || {
8d419f
     echo "machine-id $MACHINE_ID"
8d419f
     echo "options    $BOOT_OPTIONS"
8d419f
     echo "linux      $ENTRY_DIR/linux"
8d419f
-    for initrd; do
8d419f
+
8d419f
+    have_initrd=
8d419f
+    for initrd in "${@}" "${KERNEL_INSTALL_STAGING_AREA}"/initrd*; do
8d419f
         echo "initrd     $ENTRY_DIR/${initrd##*/}"
8d419f
+        have_initrd=yes
8d419f
     done
8d419f
+
8d419f
     # Try "initrd", generated by dracut in its kernel-install hook, if no initrds were supplied
8d419f
-    [ $# -eq 0 ] && [ -f "$ENTRY_DIR_ABS/initrd" ] && echo "initrd     $ENTRY_DIR/initrd"
8d419f
+    [ -z "$have_initrd" ] && [ -f "$ENTRY_DIR_ABS/initrd" ] && echo "initrd     $ENTRY_DIR/initrd"
8d419f
     :
8d419f
 } >"$LOADER_ENTRY" || {
8d419f
     echo "Error: could not create loader entry '$LOADER_ENTRY'." >&2
8d419f
diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install
8d419f
index a73a205d79..8cfef3208d 100755
8d419f
--- a/src/kernel-install/kernel-install
8d419f
+++ b/src/kernel-install/kernel-install
8d419f
@@ -128,10 +128,20 @@ fi
8d419f
 
8d419f
 ENTRY_DIR_ABS="$BOOT_ROOT/$MACHINE_ID/$KERNEL_VERSION"
8d419f
 
8d419f
+# Provide a directory where to store generated initrds
8d419f
+cleanup() {
8d419f
+    [ -n "$KERNEL_INSTALL_STAGING_AREA" ] && rm -rf "$KERNEL_INSTALL_STAGING_AREA"
8d419f
+}
8d419f
+
8d419f
+trap cleanup EXIT
8d419f
+
8d419f
+KERNEL_INSTALL_STAGING_AREA="$(mktemp -d -t -p /tmp kernel-install.staging.XXXXXXX)"
8d419f
+
8d419f
 export KERNEL_INSTALL_MACHINE_ID="$MACHINE_ID"
8d419f
 export KERNEL_INSTALL_BOOT_ROOT="$BOOT_ROOT"
8d419f
 export KERNEL_INSTALL_LAYOUT="$layout"
8d419f
 export KERNEL_INSTALL_INITRD_GENERATOR="$initrd_generator"
8d419f
+export KERNEL_INSTALL_STAGING_AREA
8d419f
 
8d419f
 [ "$layout" = "bls" ]
8d419f
 MAKE_ENTRY_DIR_ABS=$?