[v4,1/7] initramfs-hook: Add infrastructure to ease writing hooks

Message ID 1d32929bfb26982f9950737f689ea20f2056a45c.1731755581.git.jan.kiszka@siemens.com
State Superseded, archived
Headers show
Series Simplify writing initramfs hooks | expand

Commit Message

Jan Kiszka Nov. 16, 2024, 11:12 a.m. UTC
From: Jan Kiszka <jan.kiszka@siemens.com>

This recipe include shall simplify writing of initramfs hooks. It
provides the usual headers for the installation hook as well as the boot
scripts, allow to generate that code that installs executables and
modules into the image, but also supports expanding the scripts with own
snippets.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../initramfs-hook/files/hook-header.tmpl     | 39 ++++++++++
 .../initramfs-hook/files/script-header.tmpl   | 26 +++++++
 .../recipes-initramfs/initramfs-hook/hook.inc | 76 +++++++++++++++++++
 3 files changed, 141 insertions(+)
 create mode 100644 meta/recipes-initramfs/initramfs-hook/files/hook-header.tmpl
 create mode 100644 meta/recipes-initramfs/initramfs-hook/files/script-header.tmpl
 create mode 100644 meta/recipes-initramfs/initramfs-hook/hook.inc

Comments

Jan Kiszka Nov. 18, 2024, 2:35 p.m. UTC | #1
On 16.11.24 12:12, 'Jan Kiszka' via isar-users wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
> 
> This recipe include shall simplify writing of initramfs hooks. It
> provides the usual headers for the installation hook as well as the boot
> scripts, allow to generate that code that installs executables and
> modules into the image, but also supports expanding the scripts with own
> snippets.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  .../initramfs-hook/files/hook-header.tmpl     | 39 ++++++++++
>  .../initramfs-hook/files/script-header.tmpl   | 26 +++++++
>  .../recipes-initramfs/initramfs-hook/hook.inc | 76 +++++++++++++++++++
>  3 files changed, 141 insertions(+)
>  create mode 100644 meta/recipes-initramfs/initramfs-hook/files/hook-header.tmpl
>  create mode 100644 meta/recipes-initramfs/initramfs-hook/files/script-header.tmpl
>  create mode 100644 meta/recipes-initramfs/initramfs-hook/hook.inc
> 
> diff --git a/meta/recipes-initramfs/initramfs-hook/files/hook-header.tmpl b/meta/recipes-initramfs/initramfs-hook/files/hook-header.tmpl
> new file mode 100644
> index 00000000..ee30d691
> --- /dev/null
> +++ b/meta/recipes-initramfs/initramfs-hook/files/hook-header.tmpl
> @@ -0,0 +1,39 @@
> +#!/bin/sh
> +#
> +# Copyright (c) Siemens AG, 2024
> +#
> +# Authors:
> +#  Jan Kiszka <jan.kiszka@siemens.com>
> +#
> +# SPDX-License-Identifier: MIT
> +#
> +
> +set -e
> +
> +prereqs()
> +{
> +	echo "${HOOK_PREREQ}"
> +}
> +
> +case $1 in
> +prereqs)
> +	prereqs
> +	exit 0
> +	;;
> +esac
> +
> +. /usr/share/initramfs-tools/hook-functions
> +
> +for module in ${HOOK_ADD_MODULES}; do
> +	manual_add_modules $module
> +done
> +
> +for executable in ${HOOK_COPY_EXECS}; do
> +	if exec_path=$(command -v $executable 2>/dev/null); then
> +		copy_exec "$exec_path"
> +	else
> +		echo "(ERROR): Unable to copy $executable" >&2
> +		exit 1
> +	fi
> +done
> +
> diff --git a/meta/recipes-initramfs/initramfs-hook/files/script-header.tmpl b/meta/recipes-initramfs/initramfs-hook/files/script-header.tmpl
> new file mode 100644
> index 00000000..faa1a644
> --- /dev/null
> +++ b/meta/recipes-initramfs/initramfs-hook/files/script-header.tmpl
> @@ -0,0 +1,26 @@
> +#!/bin/sh
> +#
> +# Copyright (c) Siemens AG, 2024
> +#
> +# Authors:
> +#  Jan Kiszka <jan.kiszka@siemens.com>
> +#
> +# SPDX-License-Identifier: MIT
> +#
> +
> +set -e
> +
> +prereqs()
> +{
> +	echo "${SCRIPT_PREREQ}"
> +}
> +
> +case $1 in
> +prereqs)
> +	prereqs
> +	exit 0
> +	;;
> +esac
> +
> +. /scripts/functions
> +
> diff --git a/meta/recipes-initramfs/initramfs-hook/hook.inc b/meta/recipes-initramfs/initramfs-hook/hook.inc
> new file mode 100644
> index 00000000..b0e7c66c
> --- /dev/null
> +++ b/meta/recipes-initramfs/initramfs-hook/hook.inc
> @@ -0,0 +1,76 @@
> +#
> +# Copyright (c) Siemens AG, 2024
> +#
> +# Authors:
> +#  Jan Kiszka <jan.kiszka@siemens.com>
> +#
> +# SPDX-License-Identifier: MIT
> +#
> +
> +FILESPATH:append := ":${FILE_DIRNAME}/files"
> +
> +inherit dpkg-raw
> +
> +SRC_URI = " \
> +    file://hook-header.tmpl \
> +    file://script-header.tmpl"
> +
> +TEMPLATE_FILES = " \
> +    hook-header.tmpl \
> +    script-header.tmpl"
> +
> +TEMPLATE_VARS:append = " \
> +    HOOK_PREREQ \
> +    HOOK_ADD_MODULES \
> +    HOOK_COPY_EXECS \
> +    SCRIPT_PREREQ"
> +
> +HOOK_PREREQ ?= ""
> +HOOK_ADD_MODULES ?= ""
> +HOOK_COPY_EXECS ?= ""
> +SCRIPT_PREREQ ?= ""
> +
> +DEBIAN_DEPENDS = "initramfs-tools"
> +
> +def get_initramfs_hook_name(d):
> +    name = d.getVar('BPN')
> +    if name.startswith("initramfs-"):
> +        name = name[10:]
> +    if name.endswith("-hook"):
> +        name = name[:-5]
> +    return name
> +
> +INITRAMFS_HOOK_NAME ?= "${@get_initramfs_hook_name(d)}"
> +
> +do_install() {
> +	if [ -f "${WORKDIR}/hook" ] || [ -n "${HOOK_COPY_EXECS}" ] || \
> +	   [ -n "${HOOK_ADD_MODULES}" ]; then
> +		rm -rf "${D}/usr/share/initramfs-tools/hooks"
> +		install -d -m 0755 "${D}/usr/share/initramfs-tools/hooks"
> +
> +		install -m 0755 "${WORKDIR}/hook-header" \
> +			"${D}/usr/share/initramfs-tools/hooks/${INITRAMFS_HOOK_NAME}"
> +		if [ -f "${WORKDIR}/hook" ]; then
> +			cat "${WORKDIR}/hook" >> \
> +			    "${D}/usr/share/initramfs-tools/hooks/${INITRAMFS_HOOK_NAME}"
> +		else
> +			echo "exit 0" >> \
> +			    "${D}/usr/share/initramfs-tools/hooks/${INITRAMFS_HOOK_NAME}"
> +		fi
> +	fi
> +
> +	for script in init-top init-premount local-top nfs-top local-block \
> +		      local-premount nfs-premount local-bottom nfs-bottom \
> +		      init-bottom; do
> +		if [ ! -f "${WORKDIR}/$script" ]; then
> +			continue
> +		fi
> +
> +		rm -rf "${D}/usr/share/initramfs-tools/scripts/$script"
> +		install -d -m 0755 "${D}/usr/share/initramfs-tools/scripts/$script"
> +		install -m 0755 "${WORKDIR}/script-header" \
> +			"${D}/usr/share/initramfs-tools/scripts/$script/${INITRAMFS_HOOK_NAME}"
> +		cat "${WORKDIR}/$script" >> \
> +		    "${D}/usr/share/initramfs-tools/scripts/$script/${INITRAMFS_HOOK_NAME}"
> +	done
> +}

OK, will need v5: Unconditionally adding a script header is too
inflexible. There are cases where the users are better of providing a
complete script themselves, e.g. when the PREREQ are function-generated
or when there are multiple boot scripts at multiple stages in the same
recipe with different PREREQs. We need an opt-out.

Jan

Patch

diff --git a/meta/recipes-initramfs/initramfs-hook/files/hook-header.tmpl b/meta/recipes-initramfs/initramfs-hook/files/hook-header.tmpl
new file mode 100644
index 00000000..ee30d691
--- /dev/null
+++ b/meta/recipes-initramfs/initramfs-hook/files/hook-header.tmpl
@@ -0,0 +1,39 @@ 
+#!/bin/sh
+#
+# Copyright (c) Siemens AG, 2024
+#
+# Authors:
+#  Jan Kiszka <jan.kiszka@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+set -e
+
+prereqs()
+{
+	echo "${HOOK_PREREQ}"
+}
+
+case $1 in
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+
+for module in ${HOOK_ADD_MODULES}; do
+	manual_add_modules $module
+done
+
+for executable in ${HOOK_COPY_EXECS}; do
+	if exec_path=$(command -v $executable 2>/dev/null); then
+		copy_exec "$exec_path"
+	else
+		echo "(ERROR): Unable to copy $executable" >&2
+		exit 1
+	fi
+done
+
diff --git a/meta/recipes-initramfs/initramfs-hook/files/script-header.tmpl b/meta/recipes-initramfs/initramfs-hook/files/script-header.tmpl
new file mode 100644
index 00000000..faa1a644
--- /dev/null
+++ b/meta/recipes-initramfs/initramfs-hook/files/script-header.tmpl
@@ -0,0 +1,26 @@ 
+#!/bin/sh
+#
+# Copyright (c) Siemens AG, 2024
+#
+# Authors:
+#  Jan Kiszka <jan.kiszka@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+set -e
+
+prereqs()
+{
+	echo "${SCRIPT_PREREQ}"
+}
+
+case $1 in
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /scripts/functions
+
diff --git a/meta/recipes-initramfs/initramfs-hook/hook.inc b/meta/recipes-initramfs/initramfs-hook/hook.inc
new file mode 100644
index 00000000..b0e7c66c
--- /dev/null
+++ b/meta/recipes-initramfs/initramfs-hook/hook.inc
@@ -0,0 +1,76 @@ 
+#
+# Copyright (c) Siemens AG, 2024
+#
+# Authors:
+#  Jan Kiszka <jan.kiszka@siemens.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+FILESPATH:append := ":${FILE_DIRNAME}/files"
+
+inherit dpkg-raw
+
+SRC_URI = " \
+    file://hook-header.tmpl \
+    file://script-header.tmpl"
+
+TEMPLATE_FILES = " \
+    hook-header.tmpl \
+    script-header.tmpl"
+
+TEMPLATE_VARS:append = " \
+    HOOK_PREREQ \
+    HOOK_ADD_MODULES \
+    HOOK_COPY_EXECS \
+    SCRIPT_PREREQ"
+
+HOOK_PREREQ ?= ""
+HOOK_ADD_MODULES ?= ""
+HOOK_COPY_EXECS ?= ""
+SCRIPT_PREREQ ?= ""
+
+DEBIAN_DEPENDS = "initramfs-tools"
+
+def get_initramfs_hook_name(d):
+    name = d.getVar('BPN')
+    if name.startswith("initramfs-"):
+        name = name[10:]
+    if name.endswith("-hook"):
+        name = name[:-5]
+    return name
+
+INITRAMFS_HOOK_NAME ?= "${@get_initramfs_hook_name(d)}"
+
+do_install() {
+	if [ -f "${WORKDIR}/hook" ] || [ -n "${HOOK_COPY_EXECS}" ] || \
+	   [ -n "${HOOK_ADD_MODULES}" ]; then
+		rm -rf "${D}/usr/share/initramfs-tools/hooks"
+		install -d -m 0755 "${D}/usr/share/initramfs-tools/hooks"
+
+		install -m 0755 "${WORKDIR}/hook-header" \
+			"${D}/usr/share/initramfs-tools/hooks/${INITRAMFS_HOOK_NAME}"
+		if [ -f "${WORKDIR}/hook" ]; then
+			cat "${WORKDIR}/hook" >> \
+			    "${D}/usr/share/initramfs-tools/hooks/${INITRAMFS_HOOK_NAME}"
+		else
+			echo "exit 0" >> \
+			    "${D}/usr/share/initramfs-tools/hooks/${INITRAMFS_HOOK_NAME}"
+		fi
+	fi
+
+	for script in init-top init-premount local-top nfs-top local-block \
+		      local-premount nfs-premount local-bottom nfs-bottom \
+		      init-bottom; do
+		if [ ! -f "${WORKDIR}/$script" ]; then
+			continue
+		fi
+
+		rm -rf "${D}/usr/share/initramfs-tools/scripts/$script"
+		install -d -m 0755 "${D}/usr/share/initramfs-tools/scripts/$script"
+		install -m 0755 "${WORKDIR}/script-header" \
+			"${D}/usr/share/initramfs-tools/scripts/$script/${INITRAMFS_HOOK_NAME}"
+		cat "${WORKDIR}/$script" >> \
+		    "${D}/usr/share/initramfs-tools/scripts/$script/${INITRAMFS_HOOK_NAME}"
+	done
+}