diff options
Diffstat (limited to 'meta/lib/oe/sbom.py')
-rw-r--r-- | meta/lib/oe/sbom.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/meta/lib/oe/sbom.py b/meta/lib/oe/sbom.py new file mode 100644 index 0000000000..22ed5070ea --- /dev/null +++ b/meta/lib/oe/sbom.py | |||
@@ -0,0 +1,84 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: GPL-2.0-only | ||
5 | # | ||
6 | |||
7 | import collections | ||
8 | |||
9 | DepRecipe = collections.namedtuple("DepRecipe", ("doc", "doc_sha1", "recipe")) | ||
10 | DepSource = collections.namedtuple("DepSource", ("doc", "doc_sha1", "recipe", "file")) | ||
11 | |||
12 | |||
13 | def get_recipe_spdxid(d): | ||
14 | return "SPDXRef-%s-%s" % ("Recipe", d.getVar("PN")) | ||
15 | |||
16 | |||
17 | def get_download_spdxid(d, idx): | ||
18 | return "SPDXRef-Download-%s-%d" % (d.getVar("PN"), idx) | ||
19 | |||
20 | |||
21 | def get_package_spdxid(pkg): | ||
22 | return "SPDXRef-Package-%s" % pkg | ||
23 | |||
24 | |||
25 | def get_source_file_spdxid(d, idx): | ||
26 | return "SPDXRef-SourceFile-%s-%d" % (d.getVar("PN"), idx) | ||
27 | |||
28 | |||
29 | def get_packaged_file_spdxid(pkg, idx): | ||
30 | return "SPDXRef-PackagedFile-%s-%d" % (pkg, idx) | ||
31 | |||
32 | |||
33 | def get_image_spdxid(img): | ||
34 | return "SPDXRef-Image-%s" % img | ||
35 | |||
36 | |||
37 | def get_sdk_spdxid(sdk): | ||
38 | return "SPDXRef-SDK-%s" % sdk | ||
39 | |||
40 | |||
41 | def write_doc(d, spdx_doc, subdir, spdx_deploy=None, indent=None): | ||
42 | from pathlib import Path | ||
43 | |||
44 | if spdx_deploy is None: | ||
45 | spdx_deploy = Path(d.getVar("SPDXDEPLOY")) | ||
46 | |||
47 | dest = spdx_deploy / subdir / (spdx_doc.name + ".spdx.json") | ||
48 | dest.parent.mkdir(exist_ok=True, parents=True) | ||
49 | with dest.open("wb") as f: | ||
50 | doc_sha1 = spdx_doc.to_json(f, sort_keys=True, indent=indent) | ||
51 | |||
52 | l = spdx_deploy / "by-namespace" / spdx_doc.documentNamespace.replace("/", "_") | ||
53 | l.parent.mkdir(exist_ok=True, parents=True) | ||
54 | l.symlink_to(os.path.relpath(dest, l.parent)) | ||
55 | |||
56 | return doc_sha1 | ||
57 | |||
58 | |||
59 | def read_doc(fn): | ||
60 | import hashlib | ||
61 | import oe.spdx | ||
62 | import io | ||
63 | import contextlib | ||
64 | |||
65 | @contextlib.contextmanager | ||
66 | def get_file(): | ||
67 | if isinstance(fn, io.IOBase): | ||
68 | yield fn | ||
69 | else: | ||
70 | with fn.open("rb") as f: | ||
71 | yield f | ||
72 | |||
73 | with get_file() as f: | ||
74 | sha1 = hashlib.sha1() | ||
75 | while True: | ||
76 | chunk = f.read(4096) | ||
77 | if not chunk: | ||
78 | break | ||
79 | sha1.update(chunk) | ||
80 | |||
81 | f.seek(0) | ||
82 | doc = oe.spdx.SPDXDocument.from_json(f) | ||
83 | |||
84 | return (doc, sha1.hexdigest()) | ||