summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kanavin <alex.kanavin@gmail.com>2023-12-18 09:43:59 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-01-05 11:59:08 +0000
commitc45ffa9e9489956444cfe0189aea34af883656c4 (patch)
treee40cecca8540dae8f9d6c2c13141c7904c38ee68
parent71c0d311baad6874c7c832fa3334a238a99cc661 (diff)
downloadpoky-c45ffa9e9489956444cfe0189aea34af883656c4.tar.gz
sstatesig/find_siginfo: unify a disjointed API
find_siginfo() returns two different data structures depending on whether its third argument (list of hashes to find) is empty or not: - a dict of timestamps keyed by path - a dict of paths keyed by hash This is not a good API design; it's much better to return a dict of dicts that include both timestamp and path, keyed by hash. Then the API consumer can decide how they want to use these fields, particularly for additional diagnostics or informational output. I also took the opportunity to add a binary field that tells if the match came from sstate or local stamps dir, which will help prioritize local stamps when looking up most recent task signatures. (From OE-Core rev: 8721c52041e910bd4d8a9235b52f274f4f02c8a3) Signed-off-by: Alexander Kanavin <alex@linutronix.de> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oe/buildhistory_analysis.py2
-rw-r--r--meta/lib/oe/sstatesig.py31
-rw-r--r--meta/lib/oeqa/selftest/cases/sstatetests.py10
3 files changed, 19 insertions, 24 deletions
diff --git a/meta/lib/oe/buildhistory_analysis.py b/meta/lib/oe/buildhistory_analysis.py
index b1856846b6..4edad01580 100644
--- a/meta/lib/oe/buildhistory_analysis.py
+++ b/meta/lib/oe/buildhistory_analysis.py
@@ -562,7 +562,7 @@ def compare_siglists(a_blob, b_blob, taskdiff=False):
562 elif not hash2 in hashfiles: 562 elif not hash2 in hashfiles:
563 out.append("Unable to find matching sigdata for %s with hash %s" % (desc, hash2)) 563 out.append("Unable to find matching sigdata for %s with hash %s" % (desc, hash2))
564 else: 564 else:
565 out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, collapsed=True) 565 out2 = bb.siggen.compare_sigfiles(hashfiles[hash1]['path'], hashfiles[hash2]['path'], recursecb, collapsed=True)
566 for line in out2: 566 for line in out2:
567 m = hashlib.sha256() 567 m = hashlib.sha256()
568 m.update(line.encode('utf-8')) 568 m.update(line.encode('utf-8'))
diff --git a/meta/lib/oe/sstatesig.py b/meta/lib/oe/sstatesig.py
index 8a97fb0c04..0342bcdc87 100644
--- a/meta/lib/oe/sstatesig.py
+++ b/meta/lib/oe/sstatesig.py
@@ -349,7 +349,6 @@ def find_siginfo(pn, taskname, taskhashlist, d):
349 pn, taskname = key.split(':', 1) 349 pn, taskname = key.split(':', 1)
350 350
351 hashfiles = {} 351 hashfiles = {}
352 filedates = {}
353 352
354 def get_hashval(siginfo): 353 def get_hashval(siginfo):
355 if siginfo.endswith('.siginfo'): 354 if siginfo.endswith('.siginfo'):
@@ -357,6 +356,12 @@ def find_siginfo(pn, taskname, taskhashlist, d):
357 else: 356 else:
358 return siginfo.rpartition('.')[2] 357 return siginfo.rpartition('.')[2]
359 358
359 def get_time(fullpath):
360 try:
361 return os.stat(fullpath).st_mtime
362 except OSError:
363 return None
364
360 # First search in stamps dir 365 # First search in stamps dir
361 localdata = d.createCopy() 366 localdata = d.createCopy()
362 localdata.setVar('MULTIMACH_TARGET_SYS', '*') 367 localdata.setVar('MULTIMACH_TARGET_SYS', '*')
@@ -372,24 +377,21 @@ def find_siginfo(pn, taskname, taskhashlist, d):
372 filespec = '%s.%s.sigdata.*' % (stamp, taskname) 377 filespec = '%s.%s.sigdata.*' % (stamp, taskname)
373 foundall = False 378 foundall = False
374 import glob 379 import glob
380 bb.debug(1, "Calling glob.glob on {}".format(filespec))
375 for fullpath in glob.glob(filespec): 381 for fullpath in glob.glob(filespec):
376 match = False 382 match = False
377 if taskhashlist: 383 if taskhashlist:
378 for taskhash in taskhashlist: 384 for taskhash in taskhashlist:
379 if fullpath.endswith('.%s' % taskhash): 385 if fullpath.endswith('.%s' % taskhash):
380 hashfiles[taskhash] = fullpath 386 hashfiles[taskhash] = {'path':fullpath, 'sstate':False, 'time':get_time(fullpath)}
381 if len(hashfiles) == len(taskhashlist): 387 if len(hashfiles) == len(taskhashlist):
382 foundall = True 388 foundall = True
383 break 389 break
384 else: 390 else:
385 try:
386 filedates[fullpath] = os.stat(fullpath).st_mtime
387 except OSError:
388 continue
389 hashval = get_hashval(fullpath) 391 hashval = get_hashval(fullpath)
390 hashfiles[hashval] = fullpath 392 hashfiles[hashval] = {'path':fullpath, 'sstate':False, 'time':get_time(fullpath)}
391 393
392 if not taskhashlist or (len(filedates) < 2 and not foundall): 394 if not taskhashlist or (len(hashfiles) < 2 and not foundall):
393 # That didn't work, look in sstate-cache 395 # That didn't work, look in sstate-cache
394 hashes = taskhashlist or ['?' * 64] 396 hashes = taskhashlist or ['?' * 64]
395 localdata = bb.data.createCopy(d) 397 localdata = bb.data.createCopy(d)
@@ -412,22 +414,15 @@ def find_siginfo(pn, taskname, taskhashlist, d):
412 localdata.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/") 414 localdata.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/")
413 filespec = '%s.siginfo' % localdata.getVar('SSTATE_PKG') 415 filespec = '%s.siginfo' % localdata.getVar('SSTATE_PKG')
414 416
417 bb.debug(1, "Calling glob.glob on {}".format(filespec))
415 matchedfiles = glob.glob(filespec) 418 matchedfiles = glob.glob(filespec)
416 for fullpath in matchedfiles: 419 for fullpath in matchedfiles:
417 actual_hashval = get_hashval(fullpath) 420 actual_hashval = get_hashval(fullpath)
418 if actual_hashval in hashfiles: 421 if actual_hashval in hashfiles:
419 continue 422 continue
420 hashfiles[hashval] = fullpath 423 hashfiles[actual_hashval] = {'path':fullpath, 'sstate':True, 'time':get_time(fullpath)}
421 if not taskhashlist:
422 try:
423 filedates[fullpath] = os.stat(fullpath).st_mtime
424 except:
425 continue
426 424
427 if taskhashlist: 425 return hashfiles
428 return hashfiles
429 else:
430 return filedates
431 426
432bb.siggen.find_siginfo = find_siginfo 427bb.siggen.find_siginfo = find_siginfo
433 428
diff --git a/meta/lib/oeqa/selftest/cases/sstatetests.py b/meta/lib/oeqa/selftest/cases/sstatetests.py
index 9eecb4381b..393eaf6339 100644
--- a/meta/lib/oeqa/selftest/cases/sstatetests.py
+++ b/meta/lib/oeqa/selftest/cases/sstatetests.py
@@ -761,14 +761,14 @@ addtask tmptask2 before do_tmptask1
761 hashes = [hash1, hash2] 761 hashes = [hash1, hash2]
762 hashfiles = find_siginfo(key, None, hashes) 762 hashfiles = find_siginfo(key, None, hashes)
763 self.assertCountEqual(hashes, hashfiles) 763 self.assertCountEqual(hashes, hashfiles)
764 bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb) 764 bb.siggen.compare_sigfiles(hashfiles[hash1]['path'], hashfiles[hash2]['path'], recursecb)
765 765
766 for pn in pns: 766 for pn in pns:
767 recursecb_count = 0 767 recursecb_count = 0
768 filedates = find_siginfo(pn, "do_tmptask1") 768 matches = find_siginfo(pn, "do_tmptask1")
769 self.assertGreaterEqual(len(filedates), 2) 769 self.assertGreaterEqual(len(matches), 2)
770 latestfiles = sorted(filedates.keys(), key=lambda f: filedates[f])[-2:] 770 latesthashes = sorted(matches.keys(), key=lambda h: matches[h]['time'])[-2:]
771 bb.siggen.compare_sigfiles(latestfiles[-2], latestfiles[-1], recursecb) 771 bb.siggen.compare_sigfiles(matches[latesthashes[-2]]['path'], matches[latesthashes[-1]]['path'], recursecb)
772 self.assertEqual(recursecb_count,1) 772 self.assertEqual(recursecb_count,1)
773 773
774class SStatePrintdiff(SStateBase): 774class SStatePrintdiff(SStateBase):