* [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