From 0d5da9477703212d3cfb63828c5c38afdb162e43 Mon Sep 17 00:00:00 2001 From: Steffen Greber Date: Mon, 27 Oct 2025 22:42:56 +0100 Subject: [PATCH] wic: add wic tests and support setting GPT diskid Also extend implementation to allow defining the diskid for GPT partitions. Add unit tests for wic.py to cover new setting. Signed-off-by: Steffen Greber Signed-off-by: Mathieu Dubois-Briand Signed-off-by: Richard Purdie --- meta/lib/oeqa/selftest/cases/wic.py | 36 ++++++++++++++++++++++++ scripts/lib/wic/ksparser.py | 21 +++++++++++++- scripts/lib/wic/plugins/imager/direct.py | 14 +++++---- 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py index bb4ac23ebf3..d7a9b146584 100644 --- a/meta/lib/oeqa/selftest/cases/wic.py +++ b/meta/lib/oeqa/selftest/cases/wic.py @@ -1905,6 +1905,42 @@ INITRAMFS_IMAGE = "core-image-initramfs-boot" self.assertIn("Source parameter 'fill' only works with the '--fixed-size' option, exiting.", result.output) self.assertNotEqual(0, result.status) + def test_diskid_on_msdos_partition(self): + """Test diksid on msdos partions""" + img = 'core-image-minimal' + diskid = "0xdeadbbef" + with NamedTemporaryFile("w", suffix=".wks") as wks: + wks.writelines(['bootloader --ptable msdos --diskid %s\n' % diskid, + 'part /boot --size=100M --active --fstype=ext4 --label boot\n' + 'part / --source rootfs --fstype=ext4 --label root\n']) + wks.flush() + cmd = "wic create %s -e %s -o %s" % (wks.name, img, self.resultdir) + runCmd(cmd) + wksname = os.path.splitext(os.path.basename(wks.name))[0] + out = glob(os.path.join(self.resultdir, "%s-*direct" % wksname)) + self.assertEqual(1, len(out)) + sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools') + result = runCmd("%s/usr/sbin/sfdisk -l %s | grep 'Disk identifier:'" % (sysroot, out[0])) + self.assertEqual("Disk identifier: %s" % diskid.lower(), result.output) + + def test_diskid_on_gpt_partition(self): + """Test diksid on gpt partions""" + img = 'core-image-minimal' + diskid = "deadbeef-cafe-babe-f00d-cec2ea4eface" + with NamedTemporaryFile("w", suffix=".wks") as wks: + wks.writelines(['bootloader --ptable gpt --diskid %s\n' % diskid, + 'part /boot --size=100M --active --fstype=ext4 --label boot\n' + 'part / --source rootfs --fstype=ext4 --label root\n']) + wks.flush() + cmd = "wic create %s -e %s -o %s" % (wks.name, img, self.resultdir) + runCmd(cmd) + wksname = os.path.splitext(os.path.basename(wks.name))[0] + out = glob(os.path.join(self.resultdir, "%s-*direct" % wksname)) + self.assertEqual(1, len(out)) + sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools') + result = runCmd("%s/usr/sbin/sfdisk -l %s | grep 'Disk identifier:'" % (sysroot, out[0])) + self.assertEqual("Disk identifier: %s" % diskid.upper(), result.output) + class ModifyTests(WicTestCase): def test_wic_ls(self): """Test listing image content using 'wic ls'""" diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py index 48b5b09ddd1..4ccd70dc555 100644 --- a/scripts/lib/wic/ksparser.py +++ b/scripts/lib/wic/ksparser.py @@ -16,6 +16,7 @@ import os import shlex import logging import re +import uuid from argparse import ArgumentParser, ArgumentError, ArgumentTypeError @@ -196,7 +197,7 @@ class KickStart(): bootloader.add_argument('--configfile') bootloader.add_argument('--ptable', choices=('msdos', 'gpt', 'gpt-hybrid'), default='msdos') - bootloader.add_argument('--diskid', type=lambda x: int(x, 0)) + bootloader.add_argument('--diskid') bootloader.add_argument('--timeout', type=int) bootloader.add_argument('--source') @@ -297,6 +298,24 @@ class KickStart(): if append_var: self.bootloader.append = ' '.join(filter(None, \ (self.bootloader.append, append_var))) + if parsed.diskid: + if parsed.ptable == "msdos": + try: + self.bootloader.diskid = int(parsed.diskid, 0) + except ValueError: + err = "with --ptbale msdos only 32bit integers " \ + "are allowed for --diskid. %s could not " \ + "be parsed" % self.ptable + raise KickStartError(err) + else: + try: + self.bootloader.diskid = uuid.UUID(parsed.diskid) + except ValueError: + err = "with --ptable %s only valid uuids are " \ + "allowed for --diskid. %s could not be " \ + "parsed" % (parsed.ptable, parsed.diskid) + raise KickStartError(err) + else: err = "%s:%d: more than one bootloader specified" \ % (confpath, lineno) diff --git a/scripts/lib/wic/plugins/imager/direct.py b/scripts/lib/wic/plugins/imager/direct.py index f40f033a3d2..ad922cfbf12 100644 --- a/scripts/lib/wic/plugins/imager/direct.py +++ b/scripts/lib/wic/plugins/imager/direct.py @@ -315,7 +315,14 @@ class PartitionedImage(): # all partitions (in bytes) self.ptable_format = ptable_format # Partition table format # Disk system identifier - if disk_id: + if disk_id and ptable_format in ('gpt', 'gpt-hybrid'): + self.disk_guid = disk_id + elif os.getenv('SOURCE_DATE_EPOCH'): + self.disk_guid = uuid.UUID(int=int(os.getenv('SOURCE_DATE_EPOCH'))) + else: + self.disk_guid = uuid.uuid4() + + if disk_id and ptable_format == 'msdos': self.identifier = disk_id elif os.getenv('SOURCE_DATE_EPOCH'): self.identifier = random.Random(int(os.getenv('SOURCE_DATE_EPOCH'))).randint(1, 0xffffffff) @@ -545,11 +552,6 @@ class PartitionedImage(): def _write_disk_guid(self): if self.ptable_format in ('gpt', 'gpt-hybrid'): - if os.getenv('SOURCE_DATE_EPOCH'): - self.disk_guid = uuid.UUID(int=int(os.getenv('SOURCE_DATE_EPOCH'))) - else: - self.disk_guid = uuid.uuid4() - logger.debug("Set disk guid %s", self.disk_guid) sfdisk_cmd = "sfdisk --sector-size %s --disk-id %s %s" % \ (self.sector_size, self.path, self.disk_guid) -- 2.47.3