From d014c4f7d2ffc6bdbfe7126d380df61268cf4376 Mon Sep 17 00:00:00 2001 From: Jose Quaresma Date: Wed, 8 Jul 2026 15:25:01 +0100 Subject: [PATCH] images: add support to store the images artifacts on sstate-cache Signed-off-by: Jose Quaresma --- .github/workflows/compile.yml | 4 +- ci/base.yml | 1 + ci/ci.yml | 14 ++++++ classes-recipe/image-on-sstate.bbclass | 17 +++++++ ...001-oe-spdx30_tasks-fix-image-deploy.patch | 30 ++++++++++++ ...UILD_ID-vardepsexclude-with-weak-ass.patch | 28 +++++++++++ ...ge_complete-needs-to-run-with-pseudo.patch | 47 +++++++++++++++++++ 7 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 classes-recipe/image-on-sstate.bbclass create mode 100644 patches/oe-core/0001-oe-spdx30_tasks-fix-image-deploy.patch create mode 100644 patches/oe-core/0001-os-release-set-BUILD_ID-vardepsexclude-with-weak-ass.patch create mode 100644 patches/oe-core/0001-sstatesig-do_image_complete-needs-to-run-with-pseudo.patch diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index c2a0b7815..5ecc2bf57 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -93,7 +93,9 @@ jobs: version: 14 local_conf_header: build-id: | - BUILD_ID = "${BUILD_ID}" + GITHUB_ID = "${BUILD_ID}" + BUILD_ID = "\${GITHUB_ID}" + BUILD_ID[vardepsexclude] = "GITHUB_ID" EOF env: INPUTS_CACHE_DIR: ${{inputs.cache_dir}} diff --git a/ci/base.yml b/ci/base.yml index 7aa44a702..c5721ab0d 100644 --- a/ci/base.yml +++ b/ci/base.yml @@ -67,6 +67,7 @@ local_conf_header: # orders the merged local.conf fragments. OS_RELEASE_FIELDS:append = " BUILD_ID" BUILD_ID ?= "local-${DATETIME}" + BUILD_ID[vardepsexclude] ?= "local-${DATETIME}" machine: unset diff --git a/ci/ci.yml b/ci/ci.yml index 5dffb4786..eedeba24b 100644 --- a/ci/ci.yml +++ b/ci/ci.yml @@ -8,6 +8,20 @@ header: local_conf_header: ci: | BB_SIGNATURE_HANDLER = "OEBasicHash" + IMAGE_CLASSES += "image-on-sstate" FIRMWARE_COMPRESSION:qcom-armv8a = "zst" # Workaround needed due https://bugzilla.yoctoproject.org/show_bug.cgi?id=16010 PACKAGE_CLASSES = "package_rpm" + +repos: + oe-core: + patches: + sstatesig-do_image_complete-1: + repo: meta-qcom + path: patches/oe-core/0001-sstatesig-do_image_complete-needs-to-run-with-pseudo.patch + sstatesig-do_image_complete-2: + repo: meta-qcom + path: patches/oe-core/0001-os-release-set-BUILD_ID-vardepsexclude-with-weak-ass.patch + sstatesig-do_image_complete-3: + repo: meta-qcom + path: patches/oe-core/0001-oe-spdx30_tasks-fix-image-deploy.patch diff --git a/classes-recipe/image-on-sstate.bbclass b/classes-recipe/image-on-sstate.bbclass new file mode 100644 index 000000000..7af54424c --- /dev/null +++ b/classes-recipe/image-on-sstate.bbclass @@ -0,0 +1,17 @@ +# Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +python __anonymous() { + bb_signature_handler = d.getVar('BB_SIGNATURE_HANDLER') + if bb_signature_handler != 'OEBasicHash': + bb.fatal("BB_SIGNATURE_HANDLER='%s' but image-on-sstate class only works with 'OEBasicHash'" % bb_signature_handler) +} + +SSTATE_SKIP_CREATION_INITRAMFS_ONLY ?= "0" + +SSTATE_SKIP_CREATION_IMAGE = "${@'0' if d.getVar('INITRAMFS_FSTYPES') == d.getVar('IMAGE_FSTYPES') else '${SSTATE_SKIP_CREATION_INITRAMFS_ONLY}'}" + +SSTATE_SKIP_CREATION:task-image-complete = "${SSTATE_SKIP_CREATION_IMAGE}" +SSTATE_SKIP_CREATION:task-image-qa = "${SSTATE_SKIP_CREATION_IMAGE}" +SSTATE_SKIP_CREATION:task-create-image-spdx = "${SSTATE_SKIP_CREATION_IMAGE}" +SSTATE_SKIP_CREATION:task-create-image-sbom-spdx = "${SSTATE_SKIP_CREATION_IMAGE}" diff --git a/patches/oe-core/0001-oe-spdx30_tasks-fix-image-deploy.patch b/patches/oe-core/0001-oe-spdx30_tasks-fix-image-deploy.patch new file mode 100644 index 000000000..87dd4352f --- /dev/null +++ b/patches/oe-core/0001-oe-spdx30_tasks-fix-image-deploy.patch @@ -0,0 +1,30 @@ +From 8f048e9f396dd92229bda35c61f16f41d2ba7764 Mon Sep 17 00:00:00 2001 +From: Jose Quaresma +Date: Wed, 8 Jul 2026 18:43:09 +0100 +Subject: [PATCH] oe/spdx30_tasks: fix image deploy + +IMGDEPLOYDIR is not populated when the artifacts comes from sstate-cache. + +Upstream-Status: Pending + +Signed-off-by: Jose Quaresma +--- + meta/lib/oe/spdx30_tasks.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py +index 79e18db11d..52255108a6 100644 +--- a/meta/lib/oe/spdx30_tasks.py ++++ b/meta/lib/oe/spdx30_tasks.py +@@ -1435,7 +1435,7 @@ def create_rootfs_spdx(d): + def create_image_spdx(d): + import oe.sbom30 + +- image_deploy_dir = Path(d.getVar("IMGDEPLOYDIR")) ++ image_deploy_dir = Path(d.getVar("DEPLOY_DIR_IMAGE")) + manifest_path = Path(d.getVar("IMAGE_OUTPUT_MANIFEST")) + spdx_work_dir = Path(d.getVar("SPDXIMAGEWORK")) + +-- +2.55.0 + diff --git a/patches/oe-core/0001-os-release-set-BUILD_ID-vardepsexclude-with-weak-ass.patch b/patches/oe-core/0001-os-release-set-BUILD_ID-vardepsexclude-with-weak-ass.patch new file mode 100644 index 000000000..5d280690e --- /dev/null +++ b/patches/oe-core/0001-os-release-set-BUILD_ID-vardepsexclude-with-weak-ass.patch @@ -0,0 +1,28 @@ +From 3bd3d449dfc9ee8cbfd7df003763e2c50eba92c1 Mon Sep 17 00:00:00 2001 +From: Jose Quaresma +Date: Wed, 8 Jul 2026 17:39:14 +0100 +Subject: [PATCH] os-release: set BUILD_ID vardepsexclude with weak assignment + +Upstream-Status: Pending + +Signed-off-by: Jose Quaresma +--- + meta/recipes-core/os-release/os-release.bb | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/meta/recipes-core/os-release/os-release.bb b/meta/recipes-core/os-release/os-release.bb +index e1906d05d8..bbbf9e3e11 100644 +--- a/meta/recipes-core/os-release/os-release.bb ++++ b/meta/recipes-core/os-release/os-release.bb +@@ -41,7 +41,7 @@ CPE_DISTRO ??= "${DISTRO}" + CPE_NAME = "cpe:/o:openembedded:${CPE_DISTRO}:${VERSION_ID}" + + BUILD_ID ?= "${DATETIME}" +-BUILD_ID[vardepsexclude] = "DATETIME" ++BUILD_ID[vardepsexclude] ?= "DATETIME" + + def sanitise_value(ver): + # unquoted fields like VERSION_ID should be (from os-release(5)): +-- +2.55.0 + diff --git a/patches/oe-core/0001-sstatesig-do_image_complete-needs-to-run-with-pseudo.patch b/patches/oe-core/0001-sstatesig-do_image_complete-needs-to-run-with-pseudo.patch new file mode 100644 index 000000000..265e8c5c2 --- /dev/null +++ b/patches/oe-core/0001-sstatesig-do_image_complete-needs-to-run-with-pseudo.patch @@ -0,0 +1,47 @@ +From ee405c653f6795940bf10941b0287bc4559a55c9 Mon Sep 17 00:00:00 2001 +From: Jose Quaresma +Date: Thu, 13 Jul 2023 11:02:44 +0000 +Subject: [PATCH] sstatesig: do_image_complete needs to run with pseudo disbale + +sstate_report_unihash function from sstate.bbclass needs to +run with pseudo disbaled when running do_image_complete task. +This is because it have the deploy content with uid and gid +of the user that run bitbake on the build machine. + +By default the creation of sstate is skiped in the task do_image_complete +in the image.bbclass using SSTATE_SKIP_CREATION:task-image-complete=1 +so the issue is not triggered. + +There are some situation when is useful to store the image artifacts on the +sstate cache for future reuse and speedup the build without need to pruduce +the same image again. These cases are especially useful in the case of the +initramfs images used by the kernel. + +The issue can be reproduced in oe-core with: + echo "SSTATE_SKIP_CREATION:task-image-complete = '0'" >> meta/recipes-core/images/core-image-minimal-initramfs.bb + bitbake core-image-minimal-initramfs -C do_image_complete + +Upstream-Status: Pending + +Signed-off-by: Jose Quaresma +Signed-off-by: Jose Quaresma +--- + meta/lib/oe/sstatesig.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/meta/lib/oe/sstatesig.py b/meta/lib/oe/sstatesig.py +index f016fc6770..d81c94a488 100644 +--- a/meta/lib/oe/sstatesig.py ++++ b/meta/lib/oe/sstatesig.py +@@ -561,7 +561,7 @@ def OEOuthashBasic(path, sigfile, task, d): + corebase = d.getVar("COREBASE") + tmpdir = d.getVar("TMPDIR") + include_owners = os.environ.get('PSEUDO_DISABLED') == '0' +- if "package_write_" in task or task == "package_qa": ++ if "package_write_" in task or task == "package_qa" or task == "image_complete": + include_owners = False + include_timestamps = False + include_root = True +-- +2.55.0 +