From patchwork Tue May 12 17:01:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?J=C3=A9r=C3=A9mie_Dautheribes_=28Schneider_Electric_=29?= X-Patchwork-Id: 87912 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 866B7CD4F24 for ; Tue, 12 May 2026 17:02:35 +0000 (UTC) Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.80920.1778605353315876604 for ; Tue, 12 May 2026 10:02:33 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=BlSGbwr6; spf=pass (domain: bootlin.com, ip: 185.246.85.4, mailfrom: jeremie.dautheribes@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 773BE4E42C1C for ; Tue, 12 May 2026 17:02:31 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4A76B60646 for ; Tue, 12 May 2026 17:02:31 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 14C0C11AF8D4D; Tue, 12 May 2026 19:02:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1778605348; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=0WBE+VRE/fr7veHn0z1toKi0kNQ1hQPAv39gR8Tj7mw=; b=BlSGbwr6/Jkh8Vup6SrcJanZOG6uDGXCYioRH8Gph5MZOYMisVXyqA7Yjz7BN/+Z+zTb+A ISlKGBtx+UM+UvM/tC0cM9vHG2jhDifcvyT508zrQoBqT1t337W4wF8smkcwWmWu4y6kOX ovOioqTJlrnEYyhqqZgOkrxub7xyWxZaVtW7Kiya8r+afw95aykot8bzW1QYNkKMWjoTUR Z0a6OSPY8kQ1w3D5XplesLFfbVSzn92FN5Gvp+fYHrXtNx6Y2Rqfu9ReQ8HUXYFjXcK+eG 3VJt2zBICjmRDOAZpIaIqnwviFCh1VNPmYH8G2zLhxDPQJEAjgY6fmlUTgCKjQ== From: =?utf-8?q?J=C3=A9r=C3=A9mie_Dautheribes_=28Schneider_Electric_=29?= Date: Tue, 12 May 2026 19:01:56 +0200 Subject: [OE-core][PATCH 1/2] spdx3: introduce SPDX_SBOM_EXT variable MIME-Version: 1.0 Message-Id: <20260512-sbom-zstd-support-v1-1-93273381d548@bootlin.com> References: <20260512-sbom-zstd-support-v1-0-93273381d548@bootlin.com> In-Reply-To: <20260512-sbom-zstd-support-v1-0-93273381d548@bootlin.com> To: openembedded-core@lists.openembedded.org Cc: =?utf-8?q?J=C3=A9r=C3=A9mie_Dautheribes_=28Schneider_Electric=29?= , miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, benjamin.robin@bootlin.com X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4804; i=jeremie.dautheribes@bootlin.com; h=from:subject:message-id; bh=y5QOv9N8X1J3rTXBKjEpk3uJu2CGyWwR535+tWNlvak=; b=owEBbQKS/ZANAwAKASsAXqAbWo8DAcsmYgBqA10dCnUTDoN6a0aZE4c1biFuh8kotAbFFXVur Ah1m6CLgGWJAjMEAAEKAB0WIQT7FK2Qhtu4QpBIBAkrAF6gG1qPAwUCagNdHQAKCRArAF6gG1qP A+cnEAC0vYdtNoVjxiRo3CFWV02+uEQQwBGPtZZJxX7ncVTxabpgw8z86mbFjTJP+zUDYdF0qJh wck/D5rugiaebc0XUfwT0BoHE6rddTOrbexSJLYQEd6FsXGA2/mIs+7PDYUe2a6wQUTo9sIoveV kH7P8NkVqMZo7rxuO0jtANg3ecoa89ruYr+Ggx2wC5H3nboNfZBoUfEj/0d3W+HqAMh+Fy7DNX4 vsqNoVYkZGRFAJAvwknafvgFVaN8DG8CwzzA/j7DBC9yhWqjW7n8XZJHWmdZTW6pYSwBiQm3pOx IajeebyZp2CImdPsFeArxIEggkNQ4h9gp2Lwv0WUrcqj+7myY4DBUS8c1L4iG7qozrJyPLhrM5v XOiESl0EIbb9Duhnpe7ehtDiqc9ZUIv+z9d7tQlbBRneZFYoTJv+yeo7qVbzJAMwxc167n58+Hg B3cg9x6Ec7i2wcrjF+4Ks9vZIRikj9zRlZ81d/5hhqIxH9cQ6E1ruf4xYJbxL1IftQAY1O+YDBo EJEB6Hn8GCA0hLpfbL80z+GGFSqf+mKRwXe5wnZztKSbqNckRrGfy1ygjxxIPPCt463XM2m33Qr DYIrEwIH/VMw2GuTIOFwGd4sjtmF69BJPKfooF+ZQoDGNhiKrgnHO7bF8FzG2IOlafuX2ENxwqF YV6ziRKmNq7bWKw== X-Developer-Key: i=jeremie.dautheribes@bootlin.com; a=openpgp; fpr=FB14AD9086DBB842904804092B005EA01B5A8F03 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 12 May 2026 17:02:35 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/236896 In preparation for upcoming work, introduce a new SPDX_SBOM_EXT variable explicitly telling the file extension name for SBOMs. Keep the default value ".spdx.json" to maintain compatibility with the current behavior. Co-authored-by: Benjamin Robin (Schneider Electric) Signed-off-by: Jérémie Dautheribes (Schneider Electric) --- meta/classes-recipe/sbom-cve-check.bbclass | 2 +- meta/classes/create-spdx-3.0.bbclass | 3 +++ meta/classes/sbom-cve-check-recipe.bbclass | 2 +- meta/lib/oe/spdx30_tasks.py | 12 +++++++----- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/meta/classes-recipe/sbom-cve-check.bbclass b/meta/classes-recipe/sbom-cve-check.bbclass index fe145a2212..ddecb82e52 100644 --- a/meta/classes-recipe/sbom-cve-check.bbclass +++ b/meta/classes-recipe/sbom-cve-check.bbclass @@ -14,7 +14,7 @@ python do_sbom_cve_check() { """ Task: Run sbom-cve-check analysis on SBOM. """ - sbom_path = d.expand("${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.spdx.json") + sbom_path = d.expand("${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}${SPDX_SBOM_EXT}") image_name = d.getVar("IMAGE_NAME") link_name = d.getVar("IMAGE_LINK_NAME") run_sbom_cve_check(d, sbom_path, image_name, link_name) diff --git a/meta/classes/create-spdx-3.0.bbclass b/meta/classes/create-spdx-3.0.bbclass index 56fd01fd53..785edb9865 100644 --- a/meta/classes/create-spdx-3.0.bbclass +++ b/meta/classes/create-spdx-3.0.bbclass @@ -74,6 +74,9 @@ SPDX_IMPORTS[doc] = "SPDX_IMPORTS is the base variable that describes how to \ algorithms, as described by the HashAlgorithm vocabulary in the\ SPDX 3 spec. Optional but recommended" +SPDX_SBOM_EXT ??= ".spdx.json" +SPDX_SBOM_EXT[doc] = "SBOM file extension name." + # Agents # Bitbake variables can be used to describe an SPDX Agent that may be used # during the build. An Agent is specified using a set of variables which all diff --git a/meta/classes/sbom-cve-check-recipe.bbclass b/meta/classes/sbom-cve-check-recipe.bbclass index c80b8ac83f..eaad73ddaf 100644 --- a/meta/classes/sbom-cve-check-recipe.bbclass +++ b/meta/classes/sbom-cve-check-recipe.bbclass @@ -16,7 +16,7 @@ python do_sbom_cve_check_recipe() { """ Task: Run sbom-cve-check analysis on a recipe SBOM. """ - sbom_path = d.expand("${DEPLOY_DIR_IMAGE}/${SPDX_RECIPE_SBOM_NAME}.spdx.json") + sbom_path = d.expand("${DEPLOY_DIR_IMAGE}/${SPDX_RECIPE_SBOM_NAME}${SPDX_SBOM_EXT}") recipe = d.getVar("SPDX_RECIPE_SBOM_NAME") run_sbom_cve_check(d, sbom_path, recipe) } diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py index 1821dd7de4..63d93c7901 100644 --- a/meta/lib/oe/spdx30_tasks.py +++ b/meta/lib/oe/spdx30_tasks.py @@ -1526,8 +1526,9 @@ def create_image_sbom_spdx(d): image_link_name = d.getVar("IMAGE_LINK_NAME") imgdeploydir = Path(d.getVar("SPDXIMAGEDEPLOYDIR")) machine = d.getVar("MACHINE") + sbom_ext = d.getVar("SPDX_SBOM_EXT") - spdx_path = imgdeploydir / (image_name + ".spdx.json") + spdx_path = imgdeploydir / f"{image_name}{sbom_ext}" root_elements = [] @@ -1567,7 +1568,7 @@ def create_image_sbom_spdx(d): if link != target_path: link.symlink_to(os.path.relpath(target_path, link.parent)) - make_image_link(spdx_path, ".spdx.json") + make_image_link(spdx_path, sbom_ext) def sdk_create_spdx(d, sdk_type, spdx_work_dir, toolchain_outputname): @@ -1603,6 +1604,7 @@ def sdk_create_spdx(d, sdk_type, spdx_work_dir, toolchain_outputname): def create_sdk_sbom(d, sdk_deploydir, spdx_work_dir, toolchain_outputname): + sbom_ext = d.getVar("SPDX_SBOM_EXT") # Load the document written earlier rootfs_objset = oe.sbom30.load_jsonld( d, spdx_work_dir / "sdk-rootfs.spdx.json", required=True @@ -1681,15 +1683,15 @@ def create_sdk_sbom(d, sdk_deploydir, spdx_work_dir, toolchain_outputname): elem.suppliedBy = supplier_id oe.sbom30.write_jsonld_doc( - d, objset, sdk_deploydir / (toolchain_outputname + ".spdx.json") + d, objset, sdk_deploydir / f"{toolchain_outputname}{sbom_ext}" ) def create_recipe_sbom(d, deploydir): sbom_name = d.getVar("SPDX_RECIPE_SBOM_NAME") - + sbom_ext = d.getVar("SPDX_SBOM_EXT") recipe, recipe_objset = load_recipe_spdx(d) objset, sbom = oe.sbom30.create_sbom(d, sbom_name, [recipe], [recipe_objset]) - oe.sbom30.write_jsonld_doc(d, objset, deploydir / (sbom_name + ".spdx.json")) + oe.sbom30.write_jsonld_doc(d, objset, deploydir / f"{sbom_name}{sbom_ext}") From patchwork Tue May 12 17:01:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?J=C3=A9r=C3=A9mie_Dautheribes_=28Schneider_Electric_=29?= X-Patchwork-Id: 87913 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9700ECD4F25 for ; Tue, 12 May 2026 17:02:35 +0000 (UTC) Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.80921.1778605353918831403 for ; Tue, 12 May 2026 10:02:34 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=IbtX9X0c; spf=pass (domain: bootlin.com, ip: 185.246.85.4, mailfrom: jeremie.dautheribes@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 4B4DD4E42C00 for ; Tue, 12 May 2026 17:02:32 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 18A8A60646 for ; Tue, 12 May 2026 17:02:32 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2A7EF11AF8D57; Tue, 12 May 2026 19:02:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1778605351; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=/F1six9UBAQi7TuKPbCP94iEf4zrxvASKncaayWJbc0=; b=IbtX9X0cc222Gh4IR9x6cXDXFNglVN9Tc2JXwXfB7YtqCcGL+O11uOMZwQZ2e9xOB3XFme Q1CxQoH2NySweYA7mV1grPGdvPxD6C6urfHj9zqcr675LGg03dGMRYNBrTCJAwOY8Eg+yL nOZedCqOCpytly/koAuTTTAszf2h5dNvaKTFqIHDBS5kz7I4QxG9m24PqMQsTz3krM7F4e czHspy0PPH6VMi7xWgMgWMACck0FDyHyx+1u4qG9PVkhPdjcw/c7iwb85aQEENTg3gz6qR zh9MZi0P7jXUDDw04tB8mtFwectbDFHh3oc0Lroo4CYgat3HDEZgpLIyW9ZcNg== From: =?utf-8?q?J=C3=A9r=C3=A9mie_Dautheribes_=28Schneider_Electric_=29?= Date: Tue, 12 May 2026 19:01:57 +0200 Subject: [OE-core][PATCH 2/2] spdx3: support SBOM compression based on SPDX_SBOM_EXT MIME-Version: 1.0 Message-Id: <20260512-sbom-zstd-support-v1-2-93273381d548@bootlin.com> References: <20260512-sbom-zstd-support-v1-0-93273381d548@bootlin.com> In-Reply-To: <20260512-sbom-zstd-support-v1-0-93273381d548@bootlin.com> To: openembedded-core@lists.openembedded.org Cc: =?utf-8?q?J=C3=A9r=C3=A9mie_Dautheribes_=28Schneider_Electric=29?= , miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com, benjamin.robin@bootlin.com X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2032; i=jeremie.dautheribes@bootlin.com; h=from:subject:message-id; bh=MF/HT/Y8UK7IxXN/7lUI8cq11fEc2zuDT2xjjcfc6Rw=; b=owEBbQKS/ZANAwAKASsAXqAbWo8DAcsmYgBqA10exSMEjd2wsd3wOparc9uSHuJsqBQJntKZO Q8TRUyXKLCJAjMEAAEKAB0WIQT7FK2Qhtu4QpBIBAkrAF6gG1qPAwUCagNdHgAKCRArAF6gG1qP A1W+D/0ccAsy65lNvDP46Vw6b33R8mfkY3j8CSXORMvyVHMHyIoZOs+VsuccDPVLz+r6SybCyJr bdY/wruWMYGza3E2suSE48bHO+EYcXzi5iPmIZxnW0wI+gYT1EJzWc8W73sLiva+qhkK8GHUuEp Mpn1LlM0oFcenffpkKog4OpGh/PxxnfbZp31LOXLrAEjU+cGHwIRJK3YhuSNe/loq3EsU2yw6NX V/EOO+McgseDPREZiSsENImGRD2/bGk9RBwVsnlicBOrC6f6VtDi9w8ICDKdJCQ/U//+WlObefj nvnD6R+rdzQS5CrtGNBR1jcCQjUgXhz7fSg71dpXsWSu8ougP04+6nYoseE2HoJ3vrVM3A0BStv u4yOMTTBKoHkPTAtjfg9Qlcl4uxYDlnryfDdea2DQnHmFq0gPWlAhPrHuBjCZG3EX0N18JFpxbB 7Uf6KqoQ1hcxDgcdqFdyxUNWILvZ25DZWVu/LWUCKRQkaadVAEzAC7AMd1m90+++LMCSJs0bAPL HvwNsxsl+H+Ob7Yet7P6RH3mYR4eBuodGRtzD3rQ9zjrliy7ztdUVuL7c4wsrB8gYQOKsiN8xfc KDWgzn9Nj85HPbhHXstGNSdRVnfMzkwwNEVZDPbuRqEx15CMrtYIRBeGe/5bJR5BSaUIIZrOrJj n6G0LvwxfJe10Mg== X-Developer-Key: i=jeremie.dautheribes@bootlin.com; a=openpgp; fpr=FB14AD9086DBB842904804092B005EA01B5A8F03 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 12 May 2026 17:02:35 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/236897 Add support for optional zstd compression for all types of SBOMs, including: - image SBOM - recipe SBOM - SDK SBOM Zstd compression is applied if SPDX_SBOM_EXT ends with ".zst". Co-authored-by: Benjamin Robin (Schneider Electric) Signed-off-by: Jérémie Dautheribes (Schneider Electric) --- meta/classes/create-spdx-3.0.bbclass | 3 ++- meta/lib/oe/sbom30.py | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/meta/classes/create-spdx-3.0.bbclass b/meta/classes/create-spdx-3.0.bbclass index 785edb9865..6cf8fa4688 100644 --- a/meta/classes/create-spdx-3.0.bbclass +++ b/meta/classes/create-spdx-3.0.bbclass @@ -75,7 +75,8 @@ SPDX_IMPORTS[doc] = "SPDX_IMPORTS is the base variable that describes how to \ SPDX 3 spec. Optional but recommended" SPDX_SBOM_EXT ??= ".spdx.json" -SPDX_SBOM_EXT[doc] = "SBOM file extension name." +SPDX_SBOM_EXT[doc] = "SBOM file extension name.\ + If it ends with '.zst', SBOMs are automatically compressed using Zstd." # Agents # Bitbake variables can be used to describe an SPDX Agent that may be used diff --git a/meta/lib/oe/sbom30.py b/meta/lib/oe/sbom30.py index 0f1f9281ad..2184c1a07f 100644 --- a/meta/lib/oe/sbom30.py +++ b/meta/lib/oe/sbom30.py @@ -1036,8 +1036,15 @@ def write_jsonld_doc(d, objset, dest): serializer = oe.spdx30.JSONLDInlineSerializer() objset.objects.add(objset.doc) - with dest.open("wb") as f: - serializer.write(objset, f, force_at_graph=True) + + if dest.name.endswith(".zst"): + num_threads = int(d.getVar("BB_NUMBER_THREADS")) + with bb.compress.zstd.open(dest, "w", num_threads=num_threads) as f: + serializer.write(objset, f, force_at_graph=True) + else: + with dest.open("wb") as f: + serializer.write(objset, f, force_at_graph=True) + objset.objects.remove(objset.doc)