[v2,2/5] start_vm: Add secureboot support

Message ID 20240617150901.55853-3-amikan@ilbers.de
State Superseded, archived
Headers show
Series Remove code duplications for start_vm | expand

Commit Message

Anton Mikanovich June 17, 2024, 3:08 p.m. UTC
Add sb_copy_vars()/sb_cleanup() API for creation of OVMF variables file
copy in case it was declared in QEMU_DISK_ARGS value.
If OVMF_VARS_4M.ms.fd is already exists it will be reused, otherwise
created copy will be deleted after QEMU exit.

sb_copy_vars() returns True if cleanup needed.

Signed-off-by: Anton Mikanovich <amikan@ilbers.de>
---
 meta-isar/conf/machine/qemuamd64-sb.conf |  2 +-
 testsuite/cibuilder.py                   | 13 ++++++---
 testsuite/start_vm.py                    | 37 +++++++++++++++++++++---
 3 files changed, 43 insertions(+), 9 deletions(-)

Patch

diff --git a/meta-isar/conf/machine/qemuamd64-sb.conf b/meta-isar/conf/machine/qemuamd64-sb.conf
index 2bec553b..9ad5f8d6 100644
--- a/meta-isar/conf/machine/qemuamd64-sb.conf
+++ b/meta-isar/conf/machine/qemuamd64-sb.conf
@@ -18,4 +18,4 @@  IMAGER_INSTALL:wic += "${GRUB_DEBIAN_SB_MOK}"
 IMAGE_PREINSTALL += "mokutil"
 
 # overwrite qemu disk args for signed boot
-QEMU_DISK_ARGS = "-drive file=##ROOTFS_IMAGE##,format=raw -global driver=cfi.pflash01,property=secure,value=on -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,readonly=on"
+QEMU_DISK_ARGS = "-drive file=##ROOTFS_IMAGE##,format=raw -global driver=cfi.pflash01,property=secure,value=on -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,readonly=on -drive if=pflash,format=raw,unit=1,file=OVMF_VARS_4M.ms.fd"
diff --git a/testsuite/cibuilder.py b/testsuite/cibuilder.py
index 12c48180..a51d6f7e 100755
--- a/testsuite/cibuilder.py
+++ b/testsuite/cibuilder.py
@@ -477,6 +477,8 @@  BBPATH .= ":${LAYERDIR}"\
                                                boot_log, None, enforce_pcbios)
         cmdline.insert(1, '-nographic')
 
+        need_sb_cleanup = start_vm.sb_copy_vars(cmdline)
+
         self.log.info('QEMU boot line:\n' + ' '.join(cmdline))
         self.log.info('QEMU boot log:\n' + boot_log)
 
@@ -485,7 +487,7 @@  BBPATH .= ":${LAYERDIR}"\
                               universal_newlines=True)
         self.log.info("Started VM with pid %s" % (p1.pid))
 
-        return p1, cmdline, boot_log
+        return p1, cmdline, boot_log, need_sb_cleanup
 
 
     def vm_wait_boot(self, p1, timeout):
@@ -564,6 +566,9 @@  BBPATH .= ":${LAYERDIR}"\
         pid = self.vm_dict[vm][0]
         os.kill(pid, signal.SIGKILL)
 
+        if self.vm_dict[vm][3]:
+            start_vm.sb_cleanup()
+
         del(self.vm_dict[vm])
         self.vm_dump_dict(vm)
 
@@ -600,7 +605,7 @@  BBPATH .= ":${LAYERDIR}"\
         stderr = ""
 
         if vm in self.vm_dict:
-            pid, cmdline, boot_log = self.vm_dict[vm]
+            pid, cmdline, boot_log, need_sb_cleanup = self.vm_dict[vm]
 
             # Check that corresponding process exists
             proc = subprocess.run("ps -o cmd= %d" % (pid), shell=True, text=True,
@@ -612,8 +617,8 @@  BBPATH .= ":${LAYERDIR}"\
         if run_qemu:
             self.log.info("No qemu-system process for `%s` found, run new VM" % (vm))
 
-            p1, cmdline, boot_log = self.vm_turn_on(arch, distro, image, enforce_pcbios)
-            self.vm_dict[vm] = p1.pid, cmdline, boot_log
+            p1, cmdline, boot_log, need_sb_cleanup = self.vm_turn_on(arch, distro, image, enforce_pcbios)
+            self.vm_dict[vm] = p1.pid, cmdline, boot_log, need_sb_cleanup
             self.vm_dump_dict(vm)
 
             rc = self.vm_wait_boot(p1, timeout)
diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index 2c07b816..45e509a7 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -1,15 +1,18 @@ 
 #!/usr/bin/env python3
 #
 # Helper script to start QEMU with Isar image
-# Copyright (c) 2019, ilbers GmbH
+# Copyright (c) 2019-2024, ilbers GmbH
 
 import argparse
 import os
 import socket
 import subprocess
 import sys
+import shutil
 import time
 
+OVMF_VARS_PATH = '/usr/share/OVMF/OVMF_VARS_4M.ms.fd'
+
 def get_bitbake_env(arch, distro, image):
     multiconfig = 'mc:qemu' + arch + '-' + distro + ':' + image
     output = subprocess.check_output(['bitbake', '-e', str(multiconfig)])
@@ -91,16 +94,42 @@  def format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios=Fal
 
     return cmd
 
+def sb_copy_vars(cmdline):
+    ovmf_vars_filename = os.path.basename(OVMF_VARS_PATH)
+
+    for param in cmdline:
+        if ovmf_vars_filename in param:
+            if os.path.exists(ovmf_vars_filename):
+                break
+            if not os.path.exists(OVMF_VARS_PATH):
+                print('%s required but not found!' % OVMF_VARS_PATH, file=sys.stderr)
+                break
+            shutil.copy(OVMF_VARS_PATH, ovmf_vars_filename)
+            return True
+
+    return False
+
+def sb_cleanup():
+    os.remove(os.path.basename(OVMF_VARS_PATH))
+
 def start_qemu(arch, build, distro, image, out, pid, enforce_pcbios):
-    cmdline = format_qemu_cmdline(arch, build, distro, image, out, pid, enforce_pcbios)
+    cmdline = format_qemu_cmdline(arch, build, distro, image, out, pid,
+                                  enforce_pcbios)
     cmdline.insert(1, '-nographic')
 
+    need_cleanup = sb_copy_vars(cmdline)
+
     print(cmdline)
-    p1 = subprocess.call('exec ' + ' '.join(cmdline), shell=True)
+
+    try:
+        subprocess.call('exec ' + ' '.join(cmdline), shell=True)
+    finally:
+        if need_cleanup:
+            sb_cleanup()
 
 def parse_args():
     parser = argparse.ArgumentParser()
-    parser.add_argument('-a', '--arch', choices=['arm', 'arm64', 'amd64', 'i386', 'mipsel'], help='set isar machine architecture.', default='arm')
+    parser.add_argument('-a', '--arch', choices=['arm', 'arm64', 'amd64', 'amd64-sb', 'i386', 'mipsel'], help='set isar machine architecture.', default='arm')
     parser.add_argument('-b', '--build', help='set path to build directory.', default=os.getcwd())
     parser.add_argument('-d', '--distro', choices=['buster', 'bullseye', 'bookworm', 'trixie', 'focal', 'jammy'], help='set isar Debian distribution.', default='bookworm')
     parser.add_argument('-i', '--image', help='set image name.', default='isar-image-base')