diff options
| author | Joshua Watt <JPEWhacker@gmail.com> | 2023-02-15 15:13:46 -0600 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2023-02-19 07:47:53 +0000 |
| commit | ceb95cf9c2c6948645bf798e4e9554d955a8c8fb (patch) | |
| tree | e8c8e3896c80589d6e094b31e18b71520b888d68 /meta | |
| parent | c980c93c5df6747b6194cdb8df1f90aa9d31beb7 (diff) | |
| download | poky-ceb95cf9c2c6948645bf798e4e9554d955a8c8fb.tar.gz | |
classes/create-spdx-2.2: Report downloads as separate packages
Moves the downloaded items from SRC_URI into separate packages in the
recipe document. This is much better than the previous implementation
because:
1) It can report multiple download locations in SRC_URI, instead of
just the first one reported.
2) It prevents the assumption that the source files listed in the
recipe are the exact file from the source URL; in particular, files
that come from file:// SRC_URI entries, and source files that have
been patched were problematic, since these aren't from the upstream
source.
3) It allows the checksums to be specified
(From OE-Core rev: 1dd4369b3638637a2cbba2a3c37c6b6f4df335cd)
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
| -rw-r--r-- | meta/classes/create-spdx-2.2.bbclass | 58 | ||||
| -rw-r--r-- | meta/lib/oe/sbom.py | 4 | ||||
| -rw-r--r-- | meta/lib/oe/spdx.py | 13 |
3 files changed, 67 insertions, 8 deletions
diff --git a/meta/classes/create-spdx-2.2.bbclass b/meta/classes/create-spdx-2.2.bbclass index 28a42e009f..454dd7a7a0 100644 --- a/meta/classes/create-spdx-2.2.bbclass +++ b/meta/classes/create-spdx-2.2.bbclass | |||
| @@ -406,6 +406,54 @@ def collect_dep_sources(d, dep_recipes): | |||
| 406 | 406 | ||
| 407 | return sources | 407 | return sources |
| 408 | 408 | ||
| 409 | def add_download_packages(d, doc, recipe): | ||
| 410 | import os.path | ||
| 411 | from bb.fetch2 import decodeurl, CHECKSUM_LIST | ||
| 412 | import bb.process | ||
| 413 | import oe.spdx | ||
| 414 | import oe.sbom | ||
| 415 | |||
| 416 | for download_idx, src_uri in enumerate(d.getVar('SRC_URI').split()): | ||
| 417 | f = bb.fetch2.FetchData(src_uri, d) | ||
| 418 | |||
| 419 | for name in f.names: | ||
| 420 | package = oe.spdx.SPDXPackage() | ||
| 421 | package.name = "%s-source-%d" % (d.getVar("PN"), download_idx + 1) | ||
| 422 | package.SPDXID = oe.sbom.get_download_spdxid(d, download_idx + 1) | ||
| 423 | |||
| 424 | if f.type == "file": | ||
| 425 | continue | ||
| 426 | |||
| 427 | uri = f.type | ||
| 428 | proto = getattr(f, "proto", None) | ||
| 429 | if proto is not None: | ||
| 430 | uri = uri + "+" + proto | ||
| 431 | uri = uri + "://" + f.host + f.path | ||
| 432 | |||
| 433 | if f.method.supports_srcrev(): | ||
| 434 | uri = uri + "@" + f.revisions[name] | ||
| 435 | |||
| 436 | if f.method.supports_checksum(f): | ||
| 437 | for checksum_id in CHECKSUM_LIST: | ||
| 438 | if checksum_id.upper() not in oe.spdx.SPDXPackage.ALLOWED_CHECKSUMS: | ||
| 439 | continue | ||
| 440 | |||
| 441 | expected_checksum = getattr(f, "%s_expected" % checksum_id) | ||
| 442 | if expected_checksum is None: | ||
| 443 | continue | ||
| 444 | |||
| 445 | c = oe.spdx.SPDXChecksum() | ||
| 446 | c.algorithm = checksum_id.upper() | ||
| 447 | c.checksumValue = expected_checksum | ||
| 448 | package.checksums.append(c) | ||
| 449 | |||
| 450 | package.downloadLocation = uri | ||
| 451 | doc.packages.append(package) | ||
| 452 | doc.add_relationship(doc, "DESCRIBES", package) | ||
| 453 | # In the future, we might be able to do more fancy dependencies, | ||
| 454 | # but this should be sufficient for now | ||
| 455 | doc.add_relationship(package, "BUILD_DEPENDENCY_OF", recipe) | ||
| 456 | |||
| 409 | python do_create_spdx() { | 457 | python do_create_spdx() { |
| 410 | from datetime import datetime, timezone | 458 | from datetime import datetime, timezone |
| 411 | import oe.sbom | 459 | import oe.sbom |
| @@ -458,14 +506,6 @@ python do_create_spdx() { | |||
| 458 | if bb.data.inherits_class("native", d) or bb.data.inherits_class("cross", d): | 506 | if bb.data.inherits_class("native", d) or bb.data.inherits_class("cross", d): |
| 459 | recipe.annotations.append(create_annotation(d, "isNative")) | 507 | recipe.annotations.append(create_annotation(d, "isNative")) |
| 460 | 508 | ||
| 461 | for s in d.getVar('SRC_URI').split(): | ||
| 462 | if not s.startswith("file://"): | ||
| 463 | s = s.split(';')[0] | ||
| 464 | recipe.downloadLocation = s | ||
| 465 | break | ||
| 466 | else: | ||
| 467 | recipe.downloadLocation = "NOASSERTION" | ||
| 468 | |||
| 469 | homepage = d.getVar("HOMEPAGE") | 509 | homepage = d.getVar("HOMEPAGE") |
| 470 | if homepage: | 510 | if homepage: |
| 471 | recipe.homepage = homepage | 511 | recipe.homepage = homepage |
| @@ -507,6 +547,8 @@ python do_create_spdx() { | |||
| 507 | doc.packages.append(recipe) | 547 | doc.packages.append(recipe) |
| 508 | doc.add_relationship(doc, "DESCRIBES", recipe) | 548 | doc.add_relationship(doc, "DESCRIBES", recipe) |
| 509 | 549 | ||
| 550 | add_download_packages(d, doc, recipe) | ||
| 551 | |||
| 510 | if process_sources(d) and include_sources: | 552 | if process_sources(d) and include_sources: |
| 511 | recipe_archive = deploy_dir_spdx / "recipes" / (doc.name + ".tar.zst") | 553 | recipe_archive = deploy_dir_spdx / "recipes" / (doc.name + ".tar.zst") |
| 512 | with optional_tarfile(recipe_archive, archive_sources) as archive: | 554 | with optional_tarfile(recipe_archive, archive_sources) as archive: |
diff --git a/meta/lib/oe/sbom.py b/meta/lib/oe/sbom.py index bbf466bbad..22ed5070ea 100644 --- a/meta/lib/oe/sbom.py +++ b/meta/lib/oe/sbom.py | |||
| @@ -14,6 +14,10 @@ def get_recipe_spdxid(d): | |||
| 14 | return "SPDXRef-%s-%s" % ("Recipe", d.getVar("PN")) | 14 | return "SPDXRef-%s-%s" % ("Recipe", d.getVar("PN")) |
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | def get_download_spdxid(d, idx): | ||
| 18 | return "SPDXRef-Download-%s-%d" % (d.getVar("PN"), idx) | ||
| 19 | |||
| 20 | |||
| 17 | def get_package_spdxid(pkg): | 21 | def get_package_spdxid(pkg): |
| 18 | return "SPDXRef-Package-%s" % pkg | 22 | return "SPDXRef-Package-%s" % pkg |
| 19 | 23 | ||
diff --git a/meta/lib/oe/spdx.py b/meta/lib/oe/spdx.py index c74ea68878..7aaf2af5ed 100644 --- a/meta/lib/oe/spdx.py +++ b/meta/lib/oe/spdx.py | |||
| @@ -216,6 +216,18 @@ class SPDXPackageVerificationCode(SPDXObject): | |||
| 216 | 216 | ||
| 217 | 217 | ||
| 218 | class SPDXPackage(SPDXObject): | 218 | class SPDXPackage(SPDXObject): |
| 219 | ALLOWED_CHECKSUMS = [ | ||
| 220 | "SHA1", | ||
| 221 | "SHA224", | ||
| 222 | "SHA256", | ||
| 223 | "SHA384", | ||
| 224 | "SHA512", | ||
| 225 | "MD2", | ||
| 226 | "MD4", | ||
| 227 | "MD5", | ||
| 228 | "MD6", | ||
| 229 | ] | ||
| 230 | |||
| 219 | name = _String() | 231 | name = _String() |
| 220 | SPDXID = _String() | 232 | SPDXID = _String() |
| 221 | versionInfo = _String() | 233 | versionInfo = _String() |
| @@ -234,6 +246,7 @@ class SPDXPackage(SPDXObject): | |||
| 234 | hasFiles = _StringList() | 246 | hasFiles = _StringList() |
| 235 | packageFileName = _String() | 247 | packageFileName = _String() |
| 236 | annotations = _ObjectList(SPDXAnnotation) | 248 | annotations = _ObjectList(SPDXAnnotation) |
| 249 | checksums = _ObjectList(SPDXChecksum) | ||
| 237 | 250 | ||
| 238 | 251 | ||
| 239 | class SPDXFile(SPDXObject): | 252 | class SPDXFile(SPDXObject): |
