diff options
Diffstat (limited to 'poky/meta/lib/oe')
-rw-r--r-- | poky/meta/lib/oe/spdx.py | 64 | ||||
-rw-r--r-- | poky/meta/lib/oe/sstatesig.py | 47 |
2 files changed, 100 insertions, 11 deletions
diff --git a/poky/meta/lib/oe/spdx.py b/poky/meta/lib/oe/spdx.py index 9814fbfd66..4416194e06 100644 --- a/poky/meta/lib/oe/spdx.py +++ b/poky/meta/lib/oe/spdx.py @@ -2,6 +2,18 @@ # SPDX-License-Identifier: GPL-2.0-only # +# +# This library is intended to capture the JSON SPDX specification in a type +# safe manner. It is not intended to encode any particular OE specific +# behaviors, see the sbom.py for that. +# +# The documented SPDX spec document doesn't cover the JSON syntax for +# particular configuration, which can make it hard to determine what the JSON +# syntax should be. I've found it is actually much simpler to read the official +# SPDX JSON schema which can be found here: https://github.com/spdx/spdx-spec +# in schemas/spdx-schema.json +# + import hashlib import itertools import json @@ -9,7 +21,16 @@ import json SPDX_VERSION = "2.2" +# +# The following are the support classes that are used to implement SPDX object +# + class _Property(object): + """ + A generic SPDX object property. The different types will derive from this + class + """ + def __init__(self, *, default=None): self.default = default @@ -19,6 +40,10 @@ class _Property(object): class _String(_Property): + """ + A scalar string property for an SPDX object + """ + def __init__(self, **kwargs): super().__init__(**kwargs) @@ -39,6 +64,10 @@ class _String(_Property): class _Object(_Property): + """ + A scalar SPDX object property of a SPDX object + """ + def __init__(self, cls, **kwargs): super().__init__(**kwargs) self.cls = cls @@ -62,6 +91,10 @@ class _Object(_Property): class _ListProperty(_Property): + """ + A list of SPDX properties + """ + def __init__(self, prop, **kwargs): super().__init__(**kwargs) self.prop = prop @@ -82,16 +115,28 @@ class _ListProperty(_Property): class _StringList(_ListProperty): + """ + A list of strings as a property for an SPDX object + """ + def __init__(self, **kwargs): super().__init__(_String(), **kwargs) class _ObjectList(_ListProperty): + """ + A list of SPDX objects as a property for an SPDX object + """ + def __init__(self, cls, **kwargs): super().__init__(_Object(cls), **kwargs) class MetaSPDXObject(type): + """ + A metaclass that allows properties (anything derived from a _Property + class) to be defined for a SPDX object + """ def __new__(mcls, name, bases, attrs): attrs["_properties"] = {} @@ -105,6 +150,9 @@ class MetaSPDXObject(type): class SPDXObject(metaclass=MetaSPDXObject): + """ + The base SPDX object; all SPDX spec classes must derive from this class + """ def __init__(self, **d): self._spdx = {} @@ -122,6 +170,21 @@ class SPDXObject(metaclass=MetaSPDXObject): return raise KeyError("%r is not a valid SPDX property" % name) +# +# These are the SPDX objects implemented from the spec. The *only* properties +# that can be added to these objects are ones directly specified in the SPDX +# spec, however you may add helper functions to make operations easier. +# +# Defaults should *only* be specified if the SPDX spec says there is a certain +# required value for a field (e.g. dataLicense), or if the field is mandatory +# and has some sane "this field is unknown" (e.g. "NOASSERTION") +# + +class SPDXAnnotation(SPDXObject): + annotationDate = _String() + annotationType = _String() + annotator = _String() + comment = _String() class SPDXChecksum(SPDXObject): algorithm = _String() @@ -164,6 +227,7 @@ class SPDXPackage(SPDXObject): packageVerificationCode = _Object(SPDXPackageVerificationCode) hasFiles = _StringList() packageFileName = _String() + annotations = _ObjectList(SPDXAnnotation) class SPDXFile(SPDXObject): diff --git a/poky/meta/lib/oe/sstatesig.py b/poky/meta/lib/oe/sstatesig.py index dd6b9de7bb..0c3b4589c5 100644 --- a/poky/meta/lib/oe/sstatesig.py +++ b/poky/meta/lib/oe/sstatesig.py @@ -108,7 +108,6 @@ class SignatureGeneratorOEBasicHashMixIn(object): self.unlockedrecipes = (data.getVar("SIGGEN_UNLOCKED_RECIPES") or "").split() self.unlockedrecipes = { k: "" for k in self.unlockedrecipes } - self.buildarch = data.getVar('BUILD_ARCH') self._internal = False pass @@ -147,13 +146,6 @@ class SignatureGeneratorOEBasicHashMixIn(object): self.dump_lockedsigs(sigfile) return super(bb.siggen.SignatureGeneratorBasicHash, self).dump_sigs(dataCache, options) - def prep_taskhash(self, tid, deps, dataCaches): - super().prep_taskhash(tid, deps, dataCaches) - if hasattr(self, "extramethod"): - (mc, _, _, fn) = bb.runqueue.split_tid_mcfn(tid) - inherits = " ".join(dataCaches[mc].inherits[fn]) - if inherits.find("/native.bbclass") != -1 or inherits.find("/cross.bbclass") != -1: - self.extramethod[tid] = ":" + self.buildarch def get_taskhash(self, tid, deps, dataCaches): if tid in self.lockedhashes: @@ -478,6 +470,8 @@ def OEOuthashBasic(path, sigfile, task, d): import stat import pwd import grp + import re + import fnmatch def update_hash(s): s = s.encode('utf-8') @@ -487,6 +481,8 @@ def OEOuthashBasic(path, sigfile, task, d): h = hashlib.sha256() prev_dir = os.getcwd() + 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": include_owners = False @@ -497,8 +493,17 @@ def OEOuthashBasic(path, sigfile, task, d): include_root = False extra_content = d.getVar('HASHEQUIV_HASH_VERSION') + filemaps = {} + for m in (d.getVar('SSTATE_HASHEQUIV_FILEMAP') or '').split(): + entry = m.split(":") + if len(entry) != 3 or entry[0] != task: + continue + filemaps.setdefault(entry[1], []) + filemaps[entry[1]].append(entry[2]) + try: os.chdir(path) + basepath = os.path.normpath(path) update_hash("OEOuthashBasic\n") if extra_content: @@ -580,8 +585,13 @@ def OEOuthashBasic(path, sigfile, task, d): else: update_hash(" " * 9) + filterfile = False + for entry in filemaps: + if fnmatch.fnmatch(path, entry): + filterfile = True + update_hash(" ") - if stat.S_ISREG(s.st_mode): + if stat.S_ISREG(s.st_mode) and not filterfile: update_hash("%10d" % s.st_size) else: update_hash(" " * 10) @@ -590,9 +600,24 @@ def OEOuthashBasic(path, sigfile, task, d): fh = hashlib.sha256() if stat.S_ISREG(s.st_mode): # Hash file contents - with open(path, 'rb') as d: - for chunk in iter(lambda: d.read(4096), b""): + if filterfile: + # Need to ignore paths in crossscripts and postinst-useradd files. + with open(path, 'rb') as d: + chunk = d.read() + chunk = chunk.replace(bytes(basepath, encoding='utf8'), b'') + for entry in filemaps: + if not fnmatch.fnmatch(path, entry): + continue + for r in filemaps[entry]: + if r.startswith("regex-"): + chunk = re.sub(bytes(r[6:], encoding='utf8'), b'', chunk) + else: + chunk = chunk.replace(bytes(r, encoding='utf8'), b'') fh.update(chunk) + else: + with open(path, 'rb') as d: + for chunk in iter(lambda: d.read(4096), b""): + fh.update(chunk) update_hash(fh.hexdigest()) else: update_hash(" " * len(fh.hexdigest())) |