summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/classes/create-spdx-2.2.bbclass41
-rw-r--r--meta/lib/oe/sbom.py34
2 files changed, 57 insertions, 18 deletions
diff --git a/meta/classes/create-spdx-2.2.bbclass b/meta/classes/create-spdx-2.2.bbclass
index 9b28d124c7..a2b96da61a 100644
--- a/meta/classes/create-spdx-2.2.bbclass
+++ b/meta/classes/create-spdx-2.2.bbclass
@@ -349,6 +349,8 @@ def collect_dep_recipes(d, doc, spdx_recipe):
349 349
350 deploy_dir_spdx = Path(d.getVar("DEPLOY_DIR_SPDX")) 350 deploy_dir_spdx = Path(d.getVar("DEPLOY_DIR_SPDX"))
351 spdx_deps_file = Path(d.getVar("SPDXDEPS")) 351 spdx_deps_file = Path(d.getVar("SPDXDEPS"))
352 package_archs = d.getVar("SSTATE_ARCHS").split()
353 package_archs.reverse()
352 354
353 dep_recipes = [] 355 dep_recipes = []
354 356
@@ -356,7 +358,9 @@ def collect_dep_recipes(d, doc, spdx_recipe):
356 deps = json.load(f) 358 deps = json.load(f)
357 359
358 for dep_pn, dep_hashfn in deps: 360 for dep_pn, dep_hashfn in deps:
359 dep_recipe_path = oe.sbom.doc_path_by_hashfn(deploy_dir_spdx, "recipe-" + dep_pn, dep_hashfn) 361 dep_recipe_path = oe.sbom.doc_find_by_hashfn(deploy_dir_spdx, package_archs, "recipe-" + dep_pn, dep_hashfn)
362 if not dep_recipe_path:
363 bb.fatal("Cannot find any SPDX file for recipe %s, %s" % (dep_pn, dep_hashfn))
360 364
361 spdx_dep_doc, spdx_dep_sha1 = oe.sbom.read_doc(dep_recipe_path) 365 spdx_dep_doc, spdx_dep_sha1 = oe.sbom.read_doc(dep_recipe_path)
362 366
@@ -385,6 +389,7 @@ def collect_dep_recipes(d, doc, spdx_recipe):
385 389
386 return dep_recipes 390 return dep_recipes
387 391
392collect_dep_recipes[vardepsexclude] = "SSTATE_ARCHS"
388 393
389def collect_dep_sources(d, dep_recipes): 394def collect_dep_sources(d, dep_recipes):
390 import oe.sbom 395 import oe.sbom
@@ -533,6 +538,7 @@ python do_create_spdx() {
533 include_sources = d.getVar("SPDX_INCLUDE_SOURCES") == "1" 538 include_sources = d.getVar("SPDX_INCLUDE_SOURCES") == "1"
534 archive_sources = d.getVar("SPDX_ARCHIVE_SOURCES") == "1" 539 archive_sources = d.getVar("SPDX_ARCHIVE_SOURCES") == "1"
535 archive_packaged = d.getVar("SPDX_ARCHIVE_PACKAGED") == "1" 540 archive_packaged = d.getVar("SPDX_ARCHIVE_PACKAGED") == "1"
541 pkg_arch = d.getVar("SSTATE_PKGARCH")
536 542
537 creation_time = datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") 543 creation_time = datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
538 544
@@ -620,7 +626,7 @@ python do_create_spdx() {
620 626
621 dep_recipes = collect_dep_recipes(d, doc, recipe) 627 dep_recipes = collect_dep_recipes(d, doc, recipe)
622 628
623 doc_sha1 = oe.sbom.write_doc(d, doc, d.getVar("SSTATE_PKGARCH"), "recipes", indent=get_json_indent(d)) 629 doc_sha1 = oe.sbom.write_doc(d, doc, pkg_arch, "recipes", indent=get_json_indent(d))
624 dep_recipes.append(oe.sbom.DepRecipe(doc, doc_sha1, recipe)) 630 dep_recipes.append(oe.sbom.DepRecipe(doc, doc_sha1, recipe))
625 631
626 recipe_ref = oe.spdx.SPDXExternalDocumentRef() 632 recipe_ref = oe.spdx.SPDXExternalDocumentRef()
@@ -685,7 +691,7 @@ python do_create_spdx() {
685 691
686 add_package_sources_from_debug(d, package_doc, spdx_package, package, package_files, sources) 692 add_package_sources_from_debug(d, package_doc, spdx_package, package, package_files, sources)
687 693
688 oe.sbom.write_doc(d, package_doc, d.getVar("SSTATE_PKGARCH"), "packages", indent=get_json_indent(d)) 694 oe.sbom.write_doc(d, package_doc, pkg_arch, "packages", indent=get_json_indent(d))
689} 695}
690do_create_spdx[vardepsexclude] += "BB_NUMBER_THREADS" 696do_create_spdx[vardepsexclude] += "BB_NUMBER_THREADS"
691# NOTE: depending on do_unpack is a hack that is necessary to get it's dependencies for archive the source 697# NOTE: depending on do_unpack is a hack that is necessary to get it's dependencies for archive the source
@@ -756,6 +762,9 @@ python do_create_runtime_spdx() {
756 creation_time = datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") 762 creation_time = datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
757 763
758 providers = collect_package_providers(d) 764 providers = collect_package_providers(d)
765 pkg_arch = d.getVar("SSTATE_PKGARCH")
766 package_archs = d.getVar("SSTATE_ARCHS").split()
767 package_archs.reverse()
759 768
760 if not is_native: 769 if not is_native:
761 bb.build.exec_func("read_subpackage_metadata", d) 770 bb.build.exec_func("read_subpackage_metadata", d)
@@ -772,7 +781,7 @@ python do_create_runtime_spdx() {
772 if not oe.packagedata.packaged(package, localdata): 781 if not oe.packagedata.packaged(package, localdata):
773 continue 782 continue
774 783
775 pkg_spdx_path = oe.sbom.doc_path(deploy_dir_spdx, pkg_name, d.getVar("SSTATE_PKGARCH"), "packages") 784 pkg_spdx_path = oe.sbom.doc_path(deploy_dir_spdx, pkg_name, pkg_arch, "packages")
776 785
777 package_doc, package_doc_sha1 = oe.sbom.read_doc(pkg_spdx_path) 786 package_doc, package_doc_sha1 = oe.sbom.read_doc(pkg_spdx_path)
778 787
@@ -827,7 +836,9 @@ python do_create_runtime_spdx() {
827 if dep in dep_package_cache: 836 if dep in dep_package_cache:
828 (dep_spdx_package, dep_package_ref) = dep_package_cache[dep] 837 (dep_spdx_package, dep_package_ref) = dep_package_cache[dep]
829 else: 838 else:
830 dep_path = oe.sbom.doc_path_by_hashfn(deploy_dir_spdx, dep_pkg, dep_hashfn) 839 dep_path = oe.sbom.doc_find_by_hashfn(deploy_dir_spdx, package_archs, dep_pkg, dep_hashfn)
840 if not dep_path:
841 bb.fatal("No SPDX file found for package %s, %s" % (dep_pkg, dep_hashfn))
831 842
832 spdx_dep_doc, spdx_dep_sha1 = oe.sbom.read_doc(dep_path) 843 spdx_dep_doc, spdx_dep_sha1 = oe.sbom.read_doc(dep_path)
833 844
@@ -855,10 +866,10 @@ python do_create_runtime_spdx() {
855 ) 866 )
856 seen_deps.add(dep) 867 seen_deps.add(dep)
857 868
858 oe.sbom.write_doc(d, runtime_doc, d.getVar("SSTATE_PKGARCH"), "runtime", spdx_deploy, indent=get_json_indent(d)) 869 oe.sbom.write_doc(d, runtime_doc, pkg_arch, "runtime", spdx_deploy, indent=get_json_indent(d))
859} 870}
860 871
861do_create_runtime_spdx[vardepsexclude] += "OVERRIDES" 872do_create_runtime_spdx[vardepsexclude] += "OVERRIDES SSTATE_ARCHS"
862 873
863addtask do_create_runtime_spdx after do_create_spdx before do_build do_rm_work 874addtask do_create_runtime_spdx after do_create_spdx before do_build do_rm_work
864SSTATETASKS += "do_create_runtime_spdx" 875SSTATETASKS += "do_create_runtime_spdx"
@@ -993,6 +1004,8 @@ def combine_spdx(d, rootfs_name, rootfs_deploydir, rootfs_spdxid, packages, spdx
993 import bb.compress.zstd 1004 import bb.compress.zstd
994 1005
995 providers = collect_package_providers(d) 1006 providers = collect_package_providers(d)
1007 package_archs = d.getVar("SSTATE_ARCHS").split()
1008 package_archs.reverse()
996 1009
997 creation_time = datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") 1010 creation_time = datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
998 deploy_dir_spdx = Path(d.getVar("DEPLOY_DIR_SPDX")) 1011 deploy_dir_spdx = Path(d.getVar("DEPLOY_DIR_SPDX"))
@@ -1022,7 +1035,10 @@ def combine_spdx(d, rootfs_name, rootfs_deploydir, rootfs_spdxid, packages, spdx
1022 1035
1023 pkg_name, pkg_hashfn = providers[name] 1036 pkg_name, pkg_hashfn = providers[name]
1024 1037
1025 pkg_spdx_path = oe.sbom.doc_path_by_hashfn(deploy_dir_spdx, pkg_name, pkg_hashfn) 1038 pkg_spdx_path = oe.sbom.doc_find_by_hashfn(deploy_dir_spdx, package_archs, pkg_name, pkg_hashfn)
1039 if not pkg_spdx_path:
1040 bb.fatal("No SPDX file found for package %s, %s" % (pkg_name, pkg_hashfn))
1041
1026 pkg_doc, pkg_doc_sha1 = oe.sbom.read_doc(pkg_spdx_path) 1042 pkg_doc, pkg_doc_sha1 = oe.sbom.read_doc(pkg_spdx_path)
1027 1043
1028 for p in pkg_doc.packages: 1044 for p in pkg_doc.packages:
@@ -1039,7 +1055,10 @@ def combine_spdx(d, rootfs_name, rootfs_deploydir, rootfs_spdxid, packages, spdx
1039 else: 1055 else:
1040 bb.fatal("Unable to find package with name '%s' in SPDX file %s" % (name, pkg_spdx_path)) 1056 bb.fatal("Unable to find package with name '%s' in SPDX file %s" % (name, pkg_spdx_path))
1041 1057
1042 runtime_spdx_path = oe.sbom.doc_path_by_hashfn(deploy_dir_spdx, "runtime-" + name, pkg_hashfn) 1058 runtime_spdx_path = oe.sbom.doc_find_by_hashfn(deploy_dir_spdx, package_archs, "runtime-" + name, pkg_hashfn)
1059 if not runtime_spdx_path:
1060 bb.fatal("No runtime SPDX document found for %s, %s" % (name, pkg_hashfn))
1061
1043 runtime_doc, runtime_doc_sha1 = oe.sbom.read_doc(runtime_spdx_path) 1062 runtime_doc, runtime_doc_sha1 = oe.sbom.read_doc(runtime_spdx_path)
1044 1063
1045 runtime_ref = oe.spdx.SPDXExternalDocumentRef() 1064 runtime_ref = oe.spdx.SPDXExternalDocumentRef()
@@ -1111,7 +1130,7 @@ def combine_spdx(d, rootfs_name, rootfs_deploydir, rootfs_spdxid, packages, spdx
1111 }) 1130 })
1112 1131
1113 for ref in doc.externalDocumentRefs: 1132 for ref in doc.externalDocumentRefs:
1114 ref_path = oe.sbom.doc_path_by_namespace(deploy_dir_spdx, ref.spdxDocument) 1133 ref_path = oe.sbom.doc_find_by_namespace(deploy_dir_spdx, package_archs, ref.spdxDocument)
1115 collect_spdx_document(ref_path) 1134 collect_spdx_document(ref_path)
1116 1135
1117 collect_spdx_document(image_spdx_path) 1136 collect_spdx_document(image_spdx_path)
@@ -1134,4 +1153,4 @@ def combine_spdx(d, rootfs_name, rootfs_deploydir, rootfs_spdxid, packages, spdx
1134 1153
1135 tar.addfile(info, fileobj=index_str) 1154 tar.addfile(info, fileobj=index_str)
1136 1155
1137combine_spdx[vardepsexclude] += "BB_NUMBER_THREADS" 1156combine_spdx[vardepsexclude] += "BB_NUMBER_THREADS SSTATE_ARCHS"
diff --git a/meta/lib/oe/sbom.py b/meta/lib/oe/sbom.py
index 1130fa668b..fd4b6895d8 100644
--- a/meta/lib/oe/sbom.py
+++ b/meta/lib/oe/sbom.py
@@ -38,16 +38,34 @@ def get_sdk_spdxid(sdk):
38 return "SPDXRef-SDK-%s" % sdk 38 return "SPDXRef-SDK-%s" % sdk
39 39
40 40
41def doc_path_by_namespace(spdx_deploy, doc_namespace): 41def _doc_path_by_namespace(spdx_deploy, arch, doc_namespace):
42 return spdx_deploy / "by-namespace" / doc_namespace.replace("/", "_") 42 return spdx_deploy / "by-namespace" / arch / doc_namespace.replace("/", "_")
43 43
44 44
45def doc_path_by_hashfn(spdx_deploy, doc_name, hashfn): 45def doc_find_by_namespace(spdx_deploy, search_arches, doc_namespace):
46 return spdx_deploy / "by-hash" / hashfn.split()[1] / (doc_name + ".spdx.json") 46 for pkgarch in search_arches:
47 p = _doc_path_by_namespace(spdx_deploy, pkgarch, doc_namespace)
48 if os.path.exists(p):
49 return p
50 return None
51
52
53def _doc_path_by_hashfn(spdx_deploy, arch, doc_name, hashfn):
54 return (
55 spdx_deploy / "by-hash" / arch / hashfn.split()[1] / (doc_name + ".spdx.json")
56 )
57
58
59def doc_find_by_hashfn(spdx_deploy, search_arches, doc_name, hashfn):
60 for pkgarch in search_arches:
61 p = _doc_path_by_hashfn(spdx_deploy, pkgarch, doc_name, hashfn)
62 if os.path.exists(p):
63 return p
64 return None
47 65
48 66
49def doc_path(spdx_deploy, doc_name, arch, subdir): 67def doc_path(spdx_deploy, doc_name, arch, subdir):
50 return spdx_deploy / arch/ subdir / (doc_name + ".spdx.json") 68 return spdx_deploy / arch / subdir / (doc_name + ".spdx.json")
51 69
52 70
53def write_doc(d, spdx_doc, arch, subdir, spdx_deploy=None, indent=None): 71def write_doc(d, spdx_doc, arch, subdir, spdx_deploy=None, indent=None):
@@ -61,11 +79,13 @@ def write_doc(d, spdx_doc, arch, subdir, spdx_deploy=None, indent=None):
61 with dest.open("wb") as f: 79 with dest.open("wb") as f:
62 doc_sha1 = spdx_doc.to_json(f, sort_keys=True, indent=indent) 80 doc_sha1 = spdx_doc.to_json(f, sort_keys=True, indent=indent)
63 81
64 l = doc_path_by_namespace(spdx_deploy, spdx_doc.documentNamespace) 82 l = _doc_path_by_namespace(spdx_deploy, arch, spdx_doc.documentNamespace)
65 l.parent.mkdir(exist_ok=True, parents=True) 83 l.parent.mkdir(exist_ok=True, parents=True)
66 l.symlink_to(os.path.relpath(dest, l.parent)) 84 l.symlink_to(os.path.relpath(dest, l.parent))
67 85
68 l = doc_path_by_hashfn(spdx_deploy, spdx_doc.name, d.getVar("BB_HASHFILENAME")) 86 l = _doc_path_by_hashfn(
87 spdx_deploy, arch, spdx_doc.name, d.getVar("BB_HASHFILENAME")
88 )
69 l.parent.mkdir(exist_ok=True, parents=True) 89 l.parent.mkdir(exist_ok=True, parents=True)
70 l.symlink_to(os.path.relpath(dest, l.parent)) 90 l.symlink_to(os.path.relpath(dest, l.parent))
71 91