[OS-BUILD PATCHv2 1/2] redhat/kernel.spec: add uki_addons to create UKI kernel cmdline addons

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Emanuele Giuseppe Esposito <eesposit@xxxxxxxxxx>

redhat/kernel.spec: add uki_addons to create UKI kernel cmdline addons

Upstream Status: RHEL-Only

By defininig an addon in uki_cmdline_addons.conf, the script
uki_addons.py will automatically create an UKI addon to be shipped
together in the same package.

For additional info on how to format uki_cmdline_addons.conf, check
uki_addons.py head comment.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@xxxxxxxxxx>

diff --git a/redhat/Makefile b/redhat/Makefile
index blahblah..blahblah 100644
--- a/redhat/Makefile
+++ b/redhat/Makefile
@@ -690,6 +690,7 @@ sources-rh: $(TARBALL) generate-testpatch-tmp setup-source dist-configs-check
 		scripts/mod/mod-partner.list \
 		scripts/mod/mod-sign.sh \
 		scripts/mod/mod-kvm.list \
+		scripts/uki_addons.py \
 		configs/flavors \
 		configs/generate_all_configs.sh \
 		configs/merge.py \
@@ -698,6 +699,7 @@ sources-rh: $(TARBALL) generate-testpatch-tmp setup-source dist-configs-check
 		README.rst \
 		kernel-local \
 		dracut-virt.conf \
+		uki_cmdline_addons.conf \
 		$(SOURCES)/
 	@cat $$(ls -1 $(SPECPACKAGE_NAME).changelog-* | sort -t '.' -k 3 -n -r) \
 		> $(SOURCES)/kernel.changelog
diff --git a/redhat/kernel.spec.template b/redhat/kernel.spec.template
index blahblah..blahblah 100644
--- a/redhat/kernel.spec.template
+++ b/redhat/kernel.spec.template
@@ -792,6 +792,8 @@ BuildRequires: binutils
 BuildRequires: lvm2
 BuildRequires: systemd-boot-unsigned
 # For systemd-stub and systemd-pcrphase
+BuildRequires: systemd-ukify
+# For UKI kernel cmdline addons
 BuildRequires: systemd-udev >= 252-1
 # For TPM operations in UKI initramfs
 BuildRequires: tpm2-tools
@@ -933,6 +935,9 @@ Source86: dracut-virt.conf
 
 Source87: flavors
 
+Source151: uki_addons.py
+Source152: uki_cmdline_addons.conf
+
 Source100: rheldup3.x509
 Source101: rhelkpatch1.x509
 
@@ -2537,6 +2542,15 @@ BuildKernel() {
     	fi
     	mv $KernelUnifiedImage.signed $KernelUnifiedImage
 
+      KernelAddonsDir="$KernelUnifiedImageDir/addons"
+      mkdir -p $KernelAddonsDir
+      python3 %{SOURCE151} %{SOURCE152} $KernelAddonsDir
+      for addon in "$KernelAddonsDir"/*; do
+        %pesign -s -i $addon -o $addon.signed -a %{secureboot_ca_1} -c %{secureboot_key_1} -n %{pesign_name_1}
+        rm -f $addon
+        mv $addon.signed $addon
+      done
+
 # signkernel
 %endif
 
@@ -3692,6 +3706,7 @@ fi\
 /lib/modules/%{KVERREL}%{?3:+%{3}}/config\
 /lib/modules/%{KVERREL}%{?3:+%{3}}/modules.builtin*\
 %attr(0644, root, root) /lib/modules/%{KVERREL}%{?3:+%{3}}/%{?-k:%{-k*}}%{!?-k:vmlinuz}-virt.efi\
+/lib/modules/%{KVERREL}%{?3:+%{3}}/addons/*.addon.efi\
 %ghost /%{image_install_path}/efi/EFI/Linux/%{?-k:%{-k*}}%{!?-k:*}-%{KVERREL}%{?3:+%{3}}.efi\
 %endif\
 %endif\
diff --git a/redhat/scripts/uki_addons.py b/redhat/scripts/uki_addons.py
new file mode 100644
index blahblah..blahblah 100644
--- /dev/null
+++ b/redhat/scripts/uki_addons.py
@@ -0,0 +1,137 @@
+#!/bin/bash
+#
+# This script reads a given uki addons config file list, and creates an addon
+# for each definition given.
+#
+# Usage: python uki_addons.py cfgfile cert.pem key output_dir
+#
+# This tool requires the systemd-ukify and systemd-boot yum packages.
+#
+# Cfgfile definition
+#-------------------
+# Each addon is separate from the next by an empty line.
+# Each addon has 3 mandatory fields, plus one optional (sbat).
+# Each field (except the fourth) is terminated by a single newline.
+# No multiline fields! If a cmdline starts to be too long, maybe it's time to
+# create multiple addons.
+#
+# Cfgfile fields
+#---------------
+# - Name: name of the addon. This tool will create an addon called <name>.addon.efi
+#         and put it in @output_dir. Name might or might not contain .addon.efi.
+#         If it is missing, it will be added automatically.
+# - Description: human readable description of the addon. Not included in the
+#                generated file.
+# - Command line: the command line to be inserted into the addon.
+# - SBAT (optional): If this field is specified, replace .sbat with the provided
+#                    one. This field can be multiline, but must have an additional
+#                    newline (or EOF) to separate from the next addon.
+
+import os
+import sys
+import collections
+import subprocess
+
+SYSTEMD_STUB_PATH = '/usr/lib/systemd/boot/efi/addonx64.efi.stub'
+UKIFY_PATH = '/usr/lib/systemd/ukify'
+
+def usage(err):
+    print(f'Usage: {os.path.basename(__file__)} cfgfile cert.pem key output_dir')
+    if err:
+        print(f'Error:{err}')
+        sys.exit(1)
+
+def cfgfile_fields_help():
+    print("Cfgfile fields")
+    print("---------------")
+    print(" - Name: name of the addon. This tool will create an addon called <name>.addon.efi")
+    print("         and put it in @output_dir. Name might or might not contain .addon.efi.")
+    print("         If it is missing, it will be added automatically.")
+    print(" - Description: human readable description of the addon. Not included in the")
+    print("                generated file.")
+    print(" - Command line: the command line to be inserted into the addon.")
+    print(" - SBAT (optional): If this field is specified, replace .sbat with the provided")
+    print("                    one. This field can be multiline, but must have an additional")
+    print("                    newline (or EOF) to separate from the next addon.")
+    sys.exit(1)
+
+def check_arguments(cfgfile, output):
+    if not os.path.isfile(cfgfile):
+        usage(f'cfgfile {cfgfile} is not a file, or does not exist!')
+
+    if not os.path.isdir(output):
+        usage(f'output_dir {output} is not a dir, or does not exist!')
+
+UKICmdlineAddon = collections.namedtuple('UKICmdlineAddon', ['name', 'desc', 'cmdline', 'sbat'])
+
+def create_uki_addon(start, end, lines):
+    name = lines[start].rstrip()
+    if not name.endswith('.addon.efi'):
+        name += '.addon.efi'
+    desc = lines[start + 1].rstrip()
+    cmdline = lines[start + 2].rstrip()
+    sbat = ''.join(lines[start+3:end])
+    return UKICmdlineAddon(name, desc, cmdline, sbat)
+
+def parse_addon(i, lines):
+    start = -1
+    while i < len(lines) and start < 0:
+        if lines[i] != '\n':
+            start = i
+        i += 1
+
+    end = -1
+    while i < len(lines) and end < 0:
+        if lines[i] == '\n':
+            end = i
+        i += 1
+    if i == len(lines) and end < 0:
+        end = i
+
+    if start < 0 or end < 0:
+        return None, i
+
+    if start + 3 > end: # too small, fields ignored
+        print(f'Addon line {start+1}:{end} ignored, must contain at least name-descr-cmdline')
+        return None, i
+
+    return create_uki_addon(start, end, lines), i
+
+def main(cfgfile, output):
+    if not output.endswith('/'):
+        output += '/'
+
+    with open(cfgfile, 'r') as addons:
+        lines = addons.readlines()
+
+    i = 0
+    while i < len(lines):
+        addon, i = parse_addon(i, lines)
+        if not addon:
+            continue
+        out_path = output + addon.name
+        cmd = [
+            f'{UKIFY_PATH}', 'build',
+            f'--stub={SYSTEMD_STUB_PATH}',
+            f'--cmdline="{addon.cmdline}"',
+            f'--output={out_path}']
+        if addon.sbat != '':
+            cmd.append('--sbat=' + addon.sbat.rstrip() +'')
+
+        # print(''.join(cmd))
+        print(cmd)
+        print()
+        subprocess.check_call(cmd, text=True)
+
+if __name__ == "__main__":
+    argc = len(sys.argv) - 1
+    if argc != 2:
+        usage('too few or too many parameters!')
+
+    cfgfile = sys.argv[1]
+    output = sys.argv[2]
+
+    check_arguments(cfgfile, output)
+    main(cfgfile, output)
+
+
diff --git a/redhat/uki_cmdline_addons.conf b/redhat/uki_cmdline_addons.conf
new file mode 100644
index blahblah..blahblah 100644
--- /dev/null
+++ b/redhat/uki_cmdline_addons.conf

--
https://gitlab.com/cki-project/kernel-ark/-/merge_requests/2917
--
_______________________________________________
kernel mailing list -- kernel@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to kernel-leave@xxxxxxxxxxxxxxxxxxxxxxx
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/kernel@xxxxxxxxxxxxxxxxxxxxxxx
Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue




[Index of Archives]     [Fedora General Discussion]     [Older Fedora Users Archive]     [Fedora Advisory Board]     [Fedora Security]     [Fedora Devel Java]     [Fedora Legacy]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Mentors]     [Fedora Package Announce]     [Fedora Package Review]     [Fedora Music]     [Fedora Packaging]     [Centos]     [Fedora SELinux]     [Coolkey]     [Yum Users]     [Tux]     [Yosemite News]     [KDE Users]     [Fedora Art]     [Fedora Docs]     [USB]     [Asterisk PBX]

  Powered by Linux