* [PATCH] classes/sbom-cve-check: fall back to the stable SBOM symlink
@ 2026-08-04 11:24 roosesweb
2026-08-17 19:10 ` Paul Barker
0 siblings, 1 reply; 9+ messages in thread
From: roosesweb @ 2026-08-04 11:24 UTC (permalink / raw)
To: openembedded-core; +Cc: Thomas Roos
do_sbom_cve_check builds its input path from ${IMAGE_NAME}, which carries
${IMAGE_VERSION_SUFFIX} and so ${DATETIME}. That value is excluded from task
hashes but changes on every bitbake invocation, so the path is only correct when
do_create_image_sbom_spdx ran in the same invocation.
It does not when the class is newly enabled on an existing build tree: the image
SBOM is already deployed and stamped from an earlier build, do_sbom_cve_check has
never run, so bitbake executes only the latter and it looks for a file whose
timestamp belongs to the current invocation. The same happens on any forced re-run
of just this task:
$ bitbake -f -c sbom_cve_check core-image-minimal
ERROR: core-image-minimal-1.0-r0 do_sbom_cve_check: sbom-cve-check failed: [...]
sbom-cve-check: error: [Errno 2] No such file or directory:
'.../core-image-minimal-qemux86-64.rootfs-20260804101106.spdx.json'
$ ls tmp/deploy/images/qemux86-64/*.spdx.json
core-image-minimal-qemux86-64.rootfs-20260804095834.spdx.json
core-image-minimal-qemux86-64.rootfs.spdx.json -> ...-20260804095834.spdx.json
The file is there under ${IMAGE_LINK_NAME}, the symlink do_create_image_sbom_spdx
maintains. Keep preferring the timestamped name, so behaviour is unchanged whenever
it exists, and fall back to the symlink rather than failing. Guarded on link_name
being set, since IMAGE_LINK_NAME can be empty.
Signed-off-by: Thomas Roos <roosesweb@gmail.com>
---
meta/classes-recipe/sbom-cve-check.bbclass | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/meta/classes-recipe/sbom-cve-check.bbclass b/meta/classes-recipe/sbom-cve-check.bbclass
index 451595f..b184c12 100644
--- a/meta/classes-recipe/sbom-cve-check.bbclass
+++ b/meta/classes-recipe/sbom-cve-check.bbclass
@@ -14,9 +14,20 @@ python do_sbom_cve_check() {
"""
Task: Run sbom-cve-check analysis on SBOM.
"""
- sbom_path = d.expand("${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.spdx.json")
+ import os
+
image_name = d.getVar("IMAGE_NAME")
link_name = d.getVar("IMAGE_LINK_NAME")
+ deploy_dir = d.getVar("DEPLOY_DIR_IMAGE")
+
+ # IMAGE_NAME carries DATETIME, which changes on every invocation while being
+ # excluded from task hashes, so this path is only valid when
+ # do_create_image_sbom_spdx ran in the same invocation. Fall back to the
+ # symlink it maintains, which is stable across builds.
+ sbom_path = os.path.join(deploy_dir, "%s.spdx.json" % image_name)
+ if not os.path.exists(sbom_path) and link_name:
+ sbom_path = os.path.join(deploy_dir, "%s.spdx.json" % link_name)
+
run_sbom_cve_check(d, sbom_path, image_name, link_name)
}
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH] classes/sbom-cve-check: fall back to the stable SBOM symlink 2026-08-04 11:24 [PATCH] classes/sbom-cve-check: fall back to the stable SBOM symlink roosesweb @ 2026-08-17 19:10 ` Paul Barker 2026-08-19 6:22 ` [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently Thomas Roos 2026-08-19 6:30 ` [PATCH] classes/sbom-cve-check: fall back to the stable SBOM symlink Thomas Roos 0 siblings, 2 replies; 9+ messages in thread From: Paul Barker @ 2026-08-17 19:10 UTC (permalink / raw) To: roosesweb, openembedded-core On Tue, 2026-08-04 at 13:24 +0200, roosesweb@gmail.com wrote: > do_sbom_cve_check builds its input path from ${IMAGE_NAME}, which carries > ${IMAGE_VERSION_SUFFIX} and so ${DATETIME}. That value is excluded from task > hashes but changes on every bitbake invocation, so the path is only correct when > do_create_image_sbom_spdx ran in the same invocation. > > It does not when the class is newly enabled on an existing build tree: the image > SBOM is already deployed and stamped from an earlier build, do_sbom_cve_check has > never run, so bitbake executes only the latter and it looks for a file whose > timestamp belongs to the current invocation. The same happens on any forced re-run > of just this task: > > $ bitbake -f -c sbom_cve_check core-image-minimal > ERROR: core-image-minimal-1.0-r0 do_sbom_cve_check: sbom-cve-check failed: [...] > sbom-cve-check: error: [Errno 2] No such file or directory: > '.../core-image-minimal-qemux86-64.rootfs-20260804101106.spdx.json' > > $ ls tmp/deploy/images/qemux86-64/*.spdx.json > core-image-minimal-qemux86-64.rootfs-20260804095834.spdx.json > core-image-minimal-qemux86-64.rootfs.spdx.json -> ...-20260804095834.spdx.json > > The file is there under ${IMAGE_LINK_NAME}, the symlink do_create_image_sbom_spdx > maintains. Keep preferring the timestamped name, so behaviour is unchanged whenever > it exists, and fall back to the symlink rather than failing. Guarded on link_name > being set, since IMAGE_LINK_NAME can be empty. > > Signed-off-by: Thomas Roos <roosesweb@gmail.com> Hi Thomas, This code has already changed recently in commit 2a80840a4fe0 ("sbom-cve-check: Fix breakage with empty IMAGE_LINK_NAME"). Perhaps we should have just added a fallback to IMAGE_NAME if IMAGE_LINK_NAME is unset. A quick scan of the code shows that there are other places where it is assumed that IMAGE_LINK_NAME is valid, such as vex.bbclass. Best regards, -- Paul Barker ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently 2026-08-17 19:10 ` Paul Barker @ 2026-08-19 6:22 ` Thomas Roos 2026-08-19 6:22 ` [PATCH v2 1/5] sbom-cve-check: read the image SBOM through the stable symlink Thomas Roos ` (4 more replies) 2026-08-19 6:30 ` [PATCH] classes/sbom-cve-check: fall back to the stable SBOM symlink Thomas Roos 1 sibling, 5 replies; 9+ messages in thread From: Thomas Roos @ 2026-08-19 6:22 UTC (permalink / raw) To: openembedded-core; +Cc: Paul Barker v1 fixed the sbom-cve-check input path. Paul noted that 2a80840a4fe0 ("sbom-cve-check: Fix breakage with empty IMAGE_LINK_NAME") had already touched this class, and that other classes make the same assumption. That commit guarded the export symlinks; the input path is separate and still built from IMAGE_NAME. Patch 1 now uses the shape Paul suggested, and patches 2-4 fix the other sites found by auditing meta/classes*, meta/lib/oe and meta/lib/oeqa. Read and write sites need opposite handling of an empty value: read sites fall back to IMAGE_NAME, write sites skip the link. A central default (pin IMAGE_LINK_NAME to IMAGE_NAME when empty) does not work, as create_symlinks and multiubi_mkfs have no link != target check and IMAGE_NAME is itself derived from IMAGE_LINK_NAME. Tested on qemux86-64, each fix confirmed in both directions. Patch 5 covers patches 2-4 in one build; patch 1 was checked by hand, as a selftest would need the sbom-cve-check databases (~8.7G of git). AI-Generated: Uses Claude Opus 5 Thomas Roos (5): sbom-cve-check: read the image SBOM through the stable symlink vex: skip the VEX symlink when IMAGE_LINK_NAME is empty testexport: fall back to IMAGE_NAME when IMAGE_LINK_NAME is empty image_types: skip multiubi symlinks when IMAGE_LINK_NAME is empty oeqa/selftest/imagefeatures: test an empty IMAGE_LINK_NAME meta/classes-recipe/image_types.bbclass | 2 +- meta/classes-recipe/sbom-cve-check.bbclass | 3 +- meta/classes-recipe/testexport.bbclass | 2 +- meta/classes/vex.bbclass | 3 +- meta/lib/oeqa/selftest/cases/imagefeatures.py | 42 +++++++++++++++++++ 5 files changed, 48 insertions(+), 4 deletions(-) -- 2.55.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/5] sbom-cve-check: read the image SBOM through the stable symlink 2026-08-19 6:22 ` [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently Thomas Roos @ 2026-08-19 6:22 ` Thomas Roos 2026-08-19 6:22 ` [PATCH v2 2/5] vex: skip the VEX symlink when IMAGE_LINK_NAME is empty Thomas Roos ` (3 subsequent siblings) 4 siblings, 0 replies; 9+ messages in thread From: Thomas Roos @ 2026-08-19 6:22 UTC (permalink / raw) To: openembedded-core; +Cc: Paul Barker The input path was built from IMAGE_NAME, which carries DATETIME and so only resolves within the invocation that wrote the SBOM: enabling the class on an existing build tree, or "bitbake -f -c sbom_cve_check", failed with ENOENT. Read IMAGE_LINK_NAME instead, falling back to IMAGE_NAME when it is unset. AI-Generated: Uses Claude Opus 5 Signed-off-by: Thomas Roos <roosesweb@gmail.com> --- meta/classes-recipe/sbom-cve-check.bbclass | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meta/classes-recipe/sbom-cve-check.bbclass b/meta/classes-recipe/sbom-cve-check.bbclass index 451595f..ca47834 100644 --- a/meta/classes-recipe/sbom-cve-check.bbclass +++ b/meta/classes-recipe/sbom-cve-check.bbclass @@ -14,9 +14,10 @@ python do_sbom_cve_check() { """ Task: Run sbom-cve-check analysis on SBOM. """ - sbom_path = d.expand("${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.spdx.json") image_name = d.getVar("IMAGE_NAME") link_name = d.getVar("IMAGE_LINK_NAME") + sbom_path = os.path.join(d.getVar("DEPLOY_DIR_IMAGE"), + "%s.spdx.json" % (link_name or image_name)) run_sbom_cve_check(d, sbom_path, image_name, link_name) } -- 2.55.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/5] vex: skip the VEX symlink when IMAGE_LINK_NAME is empty 2026-08-19 6:22 ` [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently Thomas Roos 2026-08-19 6:22 ` [PATCH v2 1/5] sbom-cve-check: read the image SBOM through the stable symlink Thomas Roos @ 2026-08-19 6:22 ` Thomas Roos 2026-08-19 6:22 ` [PATCH v2 3/5] testexport: fall back to IMAGE_NAME " Thomas Roos ` (2 subsequent siblings) 4 siblings, 0 replies; 9+ messages in thread From: Thomas Roos @ 2026-08-19 6:22 UTC (permalink / raw) To: openembedded-core; +Cc: Paul Barker An empty IMAGE_LINK_NAME left a bare ".vex.json" symlink in the deploy directory. Skip the link, as image.bbclass and rootfs-postcommands do. AI-Generated: Uses Claude Opus 5 Signed-off-by: Thomas Roos <roosesweb@gmail.com> --- meta/classes/vex.bbclass | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meta/classes/vex.bbclass b/meta/classes/vex.bbclass index b3c2aca..eee3af6 100644 --- a/meta/classes/vex.bbclass +++ b/meta/classes/vex.bbclass @@ -204,7 +204,8 @@ python vex_write_rootfs_manifest () { with open(manifest_name, "w") as f: json.dump(json_data, f, indent=2) - update_symlinks(manifest_name, link_path) + if link_name: + update_symlinks(manifest_name, link_path) bb.plain("Image VEX JSON report stored in: %s" % manifest_name) } -- 2.55.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/5] testexport: fall back to IMAGE_NAME when IMAGE_LINK_NAME is empty 2026-08-19 6:22 ` [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently Thomas Roos 2026-08-19 6:22 ` [PATCH v2 1/5] sbom-cve-check: read the image SBOM through the stable symlink Thomas Roos 2026-08-19 6:22 ` [PATCH v2 2/5] vex: skip the VEX symlink when IMAGE_LINK_NAME is empty Thomas Roos @ 2026-08-19 6:22 ` Thomas Roos 2026-08-19 6:22 ` [PATCH v2 4/5] image_types: skip multiubi symlinks " Thomas Roos 2026-08-19 6:22 ` [PATCH v2 5/5] oeqa/selftest/imagefeatures: test an empty IMAGE_LINK_NAME Thomas Roos 4 siblings, 0 replies; 9+ messages in thread From: Thomas Roos @ 2026-08-19 6:22 UTC (permalink / raw) To: openembedded-core; +Cc: Paul Barker copy_needed_files() built the manifest and testdata paths from IMAGE_LINK_NAME alone, so an empty value made it copy ".manifest" and fail. testexport_main() in the same file already falls back to IMAGE_NAME. AI-Generated: Uses Claude Opus 5 Signed-off-by: Thomas Roos <roosesweb@gmail.com> --- meta/classes-recipe/testexport.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta/classes-recipe/testexport.bbclass b/meta/classes-recipe/testexport.bbclass index 12b7e17..a0be7cd 100644 --- a/meta/classes-recipe/testexport.bbclass +++ b/meta/classes-recipe/testexport.bbclass @@ -134,7 +134,7 @@ def copy_needed_files(d, tc): # Copy test data image_name = ("%s/%s" % (d.getVar('DEPLOY_DIR_IMAGE'), - d.getVar('IMAGE_LINK_NAME'))) + d.getVar('IMAGE_LINK_NAME') or d.getVar('IMAGE_NAME'))) image_manifest = "%s.manifest" % image_name tdname = "%s.testdata.json" % image_name test_data_path = os.path.join(export_path, 'data') -- 2.55.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/5] image_types: skip multiubi symlinks when IMAGE_LINK_NAME is empty 2026-08-19 6:22 ` [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently Thomas Roos ` (2 preceding siblings ...) 2026-08-19 6:22 ` [PATCH v2 3/5] testexport: fall back to IMAGE_NAME " Thomas Roos @ 2026-08-19 6:22 ` Thomas Roos 2026-08-19 6:22 ` [PATCH v2 5/5] oeqa/selftest/imagefeatures: test an empty IMAGE_LINK_NAME Thomas Roos 4 siblings, 0 replies; 9+ messages in thread From: Thomas Roos @ 2026-08-19 6:22 UTC (permalink / raw) To: openembedded-core; +Cc: Paul Barker An empty IMAGE_LINK_NAME made multiubi_mkfs link the named volumes from the suffix alone, e.g. "_volume.ubifs". Guard the block. AI-Generated: Uses Claude Opus 5 Signed-off-by: Thomas Roos <roosesweb@gmail.com> --- meta/classes-recipe/image_types.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta/classes-recipe/image_types.bbclass b/meta/classes-recipe/image_types.bbclass index ca13729..6c620a5 100644 --- a/meta/classes-recipe/image_types.bbclass +++ b/meta/classes-recipe/image_types.bbclass @@ -217,7 +217,7 @@ multiubi_mkfs() { mv ubinize${vname}-${IMAGE_NAME}.cfg ${IMGDEPLOYDIR}/ # Create own symlinks for 'named' volumes - if [ -n "$vname" ]; then + if [ -n "$vname" ] && [ -n "${IMAGE_LINK_NAME}" ]; then cd ${IMGDEPLOYDIR} if [ -e ${IMAGE_NAME}${vname}.ubifs ]; then ln -sf ${IMAGE_NAME}${vname}.ubifs \ -- 2.55.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 5/5] oeqa/selftest/imagefeatures: test an empty IMAGE_LINK_NAME 2026-08-19 6:22 ` [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently Thomas Roos ` (3 preceding siblings ...) 2026-08-19 6:22 ` [PATCH v2 4/5] image_types: skip multiubi symlinks " Thomas Roos @ 2026-08-19 6:22 ` Thomas Roos 4 siblings, 0 replies; 9+ messages in thread From: Thomas Roos @ 2026-08-19 6:22 UTC (permalink / raw) To: openembedded-core; +Cc: Paul Barker Nothing covered this configuration, which is why the vex, multiubi and testexport sites went unnoticed. One core-image-minimal build with IMAGE_LINK_NAME cleared covers all three; the test fails without them. AI-Generated: Uses Claude Opus 5 Signed-off-by: Thomas Roos <roosesweb@gmail.com> --- meta/lib/oeqa/selftest/cases/imagefeatures.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/imagefeatures.py b/meta/lib/oeqa/selftest/cases/imagefeatures.py index 87c3da2..fac1d47 100644 --- a/meta/lib/oeqa/selftest/cases/imagefeatures.py +++ b/meta/lib/oeqa/selftest/cases/imagefeatures.py @@ -332,3 +332,45 @@ CORE_IMAGE_EXTRA_INSTALL = "man-pages" status, output = qemu.run_serial("man --pager=cat intro") self.assertEqual(status, 1, 'Failed to run man: %s' % (output)) self.assertIn("introduction to user commands", output) + + def test_empty_image_link_name(self): + """ + Test that an empty IMAGE_LINK_NAME suppresses the artifact symlinks + and that the classes reading an artifact back still locate it. + """ + image = 'core-image-minimal' + vname = 'mtd_4_256' + config = """ +INHERIT += "vex" +IMAGE_CLASSES += "testexport" +IMAGE_LINK_NAME = "" +IMAGE_NAME = "${IMAGE_BASENAME}${IMAGE_MACHINE_SUFFIX}${IMAGE_NAME_SUFFIX}" +IMAGE_FSTYPES += "multiubi" +MULTIUBI_BUILD = "%s" +MKUBIFS_ARGS_%s ?= "-m 4096 -e 253952 -c 4096" +UBINIZE_ARGS_%s ?= "-m 4096 -p 256KiB" +TEST_TARGET_IP = "192.168.7.2" +TEST_SERVER_IP = "192.168.7.1" +""" % (vname, vname, vname) + self.write_config(config) + + bitbake(image) + bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_NAME', 'TEST_EXPORT_DIR'], image) + deploy_dir = bb_vars['DEPLOY_DIR_IMAGE'] + + # Artifacts are still named after IMAGE_NAME + for name in ("%s.vex.json" % bb_vars['IMAGE_NAME'], + "%s_%s.ubifs" % (bb_vars['IMAGE_NAME'], vname)): + self.assertTrue(os.path.exists(os.path.join(deploy_dir, name)), + "%s is missing from %s" % (name, deploy_dir)) + + # ...and nothing is linked from the suffix alone + for name in (".vex.json", "_%s.ubifs" % vname, "_%s.ubi" % vname): + self.assertFalse(os.path.lexists(os.path.join(deploy_dir, name)), + "%s was created from an empty IMAGE_LINK_NAME" % name) + + # testexport copies these back out of DEPLOY_DIR_IMAGE + bitbake("-c testexport %s" % image) + for name in ('manifest', 'testdata.json'): + path = os.path.join(bb_vars['TEST_EXPORT_DIR'], 'data', name) + self.assertTrue(os.path.exists(path), "%s was not exported" % path) -- 2.55.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] classes/sbom-cve-check: fall back to the stable SBOM symlink 2026-08-17 19:10 ` Paul Barker 2026-08-19 6:22 ` [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently Thomas Roos @ 2026-08-19 6:30 ` Thomas Roos 1 sibling, 0 replies; 9+ messages in thread From: Thomas Roos @ 2026-08-19 6:30 UTC (permalink / raw) To: openembedded-core [-- Attachment #1: Type: text/plain, Size: 370 bytes --] Hi Paul, updated patch and added also a fix for the other places. Together with a test case. Let me know if such patches are not welcome, acc. to the discussion of yesterdays engineering sync. I do not want to loose my reputation and end up in hell ;) I just want to contribute a bit back to the greatest project in the world! So please tell me! Cheers, Thomas [-- Attachment #2: Type: text/html, Size: 409 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-08-19 6:30 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-04 11:24 [PATCH] classes/sbom-cve-check: fall back to the stable SBOM symlink roosesweb 2026-08-17 19:10 ` Paul Barker 2026-08-19 6:22 ` [PATCH v2 0/5] Handle an empty IMAGE_LINK_NAME consistently Thomas Roos 2026-08-19 6:22 ` [PATCH v2 1/5] sbom-cve-check: read the image SBOM through the stable symlink Thomas Roos 2026-08-19 6:22 ` [PATCH v2 2/5] vex: skip the VEX symlink when IMAGE_LINK_NAME is empty Thomas Roos 2026-08-19 6:22 ` [PATCH v2 3/5] testexport: fall back to IMAGE_NAME " Thomas Roos 2026-08-19 6:22 ` [PATCH v2 4/5] image_types: skip multiubi symlinks " Thomas Roos 2026-08-19 6:22 ` [PATCH v2 5/5] oeqa/selftest/imagefeatures: test an empty IMAGE_LINK_NAME Thomas Roos 2026-08-19 6:30 ` [PATCH] classes/sbom-cve-check: fall back to the stable SBOM symlink Thomas Roos
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox