Please hold off on this version, there is an error in the layers set() handling. I will send a v2.
On Fri, Oct 27, 2023 at 3:19 PM Tim Orling via lists.yoctoproject.org <ticotimo=gmail....@lists.yoctoproject.org> wrote: > This is a handy helper script to query the Buildbot REST API to > create a list of Yocto Project Compatible 2.0 layers, as defined by > successful running of the "check-layers*" jobs. > > The script only considers the 'jobs' ("Builders" in Buildbot speak) you > ask it to query. > > The script looks at the latest -n successful builds for a branch that > matches from a list. The number of builds approach was used because > the property_list cannot be queried for "branch" in the "builders" API. > > It looks for a "step" name pattern via a regex, with which all currently > running "check-layer" and "check-layer-nightly" jobs conform. > > Once a branch has successfully been queried, it is removed from the list > in further iterations. The intent is to only find the latest passing > list of compatible layers, for each branch. > > The output is a yp_compatible_layers.json file which can > be pretty printed with: > > cat yp_compatible_layers.json | jq > > Signed-off-by: Tim Orling <tim.orl...@konsulko.com> > --- > scripts/list-yp-compatible-layers.py | 155 +++++++++++++++++++++++++++ > 1 file changed, 155 insertions(+) > create mode 100755 scripts/list-yp-compatible-layers.py > > diff --git a/scripts/list-yp-compatible-layers.py > b/scripts/list-yp-compatible-layers.py > new file mode 100755 > index 0000000..f247057 > --- /dev/null > +++ b/scripts/list-yp-compatible-layers.py > @@ -0,0 +1,155 @@ > +#!/usr/bin/env python3 > + > +# Query layers that are Yocto Project Compatible (2.0) on the AutoBuilder > +# and make a yp_compatible_layers.json file as an output > +# > +# Copyright (C) 2023 Konsulko Group > +# Author: Tim Orling <tim.orl...@konsulko.com> > +# > +# Licensed under the MIT license, see COPYING.MIT for details > +# > +# SPDX-License-Identifier: MIT > +# > +# Variables that should be modified for your needs (could become args) > +# > +# api_url: > +# the url for the Buildbot REST API on the AutoBuilder > +# desired_branches: > +# list of branches to find a matching build for > +# desired_jobs: > +# list of "Builders" on the AutoBuilder that perform the > +# actual compatibility checks > +# output_filename: > +# name for the json file to output > +# > +# For "pretty" output: > +# cat yp_compatible_layers.json | jq > + > +import sys > +import os > + > +sys.path.insert(0, > os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))) > + > +import argparse > +import logging > +import re > +import requests > +import json > + > + > +def main(): > + # Setup logging > + logging.basicConfig(level=logging.INFO, format="%(levelname)s: > %(message)s") > + logger = logging.getLogger('list-yocto-project-compatible-layers') > + > + parser = argparse.ArgumentParser(description='query Yocto AutoBuilder > check-layer* jobs and create a json file of Yocto Compatible 2.0 layers') > + > + parser.add_argument("-n", "--num-builds", > + help = "Limit the number of Auto Builder builds to query", > + action="store", dest="num_builds", default=20) > + parser.add_argument("-d", "--debug", > + help = "Enable debug output", > + action="store_const", const=logging.DEBUG, dest="loglevel", > default=logging.INFO) > + parser.add_argument("-q", "--quiet", > + help = "Hide all output except error messages", > + action="store_const", const=logging.ERROR, dest="loglevel") > + > + args = parser.parse_args() > + > + logger.setLevel(args.loglevel) > + > + api_url = 'https://autobuilder.yoctoproject.org/typhoon/api/v2' > + desired_branches = {"dunfell", "kirkstone", "mickledore", "nanbield", > "master"} > + desired_jobs = {"check-layer", "check-layer-nightly"} > + num_builds = args.num_builds > + output_filename = 'yp_compatible_layers.json' > + builder_id=dict() > + # get info about a builder > + # curl > https://autobuilder.yoctoproject.org/typhoon/api/v2/builders?name=check-layer > + builder_id['check_layer']=39 > + builder_id['check_layer_nightly']=121 > + # get the "api" > + # curl > https://autobuilder.yoctoproject.org/typhoon/api/v2/application.spec > + > + # get a specific step raw stdio log > + # curl > https://autobuilder.yoctoproject.org/typhoon/api/v2/builders/121/builds/1651/steps/11/logs/stdio/raw > + > + # filter for strings in the name of a step > + # curl > https://autobuilder.yoctoproject.org/typhoon/api/v2/builders/check-layer-nightly/builds/1651/steps?name__contains=Test > + # curl > https://autobuilder.yoctoproject.org/typhoon/api/v2/builders/check-layer-nightly/builds/1651/steps?name__contains=Run&field=name&field=number > + # > + # get the latest build (NOTE: - in front of 'number' does reverse > order) > + # > https://autobuilder.yoctoproject.org/typhoon/api/v2/builders/check-layer-nightly/builds?order=-number&limit=1 > + # > + # get list of properties for a build > + # > https://autobuilder.yoctoproject.org/typhoon/api/v2/builds/453477/property_list > + # > + # get the buildid of a build from builders/ so the builds/<buildid> > api can be queried for property_list > + # otherwise, we have no way to get the 'branch' > + # > https://autobuilder.yoctoproject.org/typhoon/api/v2/builders/check-layer-nightly/builds?limit=10&field=buildid > + > + def latest_builds(job, limit): > + # limit to successful builds (however, this includes Skip) > + url_str = > f'{api_url}/builders/{job}/builds?state_string__contains=successful&limit={str(limit)}&order=-buildid&field=buildid&field=state_string' > + r = requests.get(url_str) > + return r > + > + # set objects are not JSON serializable, so we convert our set to a > list > + class YPCompatibleJSONEncoder(json.JSONEncoder): > + def default(self, obj): > + if isinstance(obj, set): > + return list(obj) > + return json.JSONEncoder.default(self, obj) > + > + #latest_20 = requests.get(' > https://autobuilder.yoctoproject.org/typhoon/api/v2/builders/check-layer-nightly/builds?limit=20&order=-buildid&field=buildid > ') > + compatible_dict = dict().fromkeys(desired_jobs, > dict().fromkeys(desired_branches, set())) > + for job in desired_jobs: > + # we want a list we can decrement once a valid branch has been > found > + copy_desired_branches = desired_branches.copy() > + logger.info(f'Processing at most {num_builds} builds for > AutoBuilder job: {job}...') > + for builds in latest_builds(job, num_builds).json()['builds']: > + build_id=builds['buildid'] > + logger.debug(f'\tProcessing build: {build_id}...') > + url_str = > f'{api_url}/builds/{build_id}/property_list?name=yp_build_branch' > + #r = requests.get(' > https://autobuilder.yoctoproject.org/typhoon/api/v2/builds/%s/property_list?name=yp_build_branch' > % builds['buildid']) > + r = requests.get(url_str) > + try: > + result_dict = r.json()['_properties'][0] > + branch = result_dict['value'].replace('"','') > + except: > + pass > + if branch in copy_desired_branches: > + logger.info(f'\tProcessing branch: {branch}...') > + url_str = > f'{api_url}/builds/{build_id}/steps?name__contains=Run&field=name&field=number' > + steps_req = requests.get(url_str) > + steps_dict = steps_req.json()['steps'] > + for step in steps_dict: > + try: > + step_num = step['number'] > + # currently, meta-virtualization does not have > 'cmds' so use a look ahead > + repo_regex = re.compile(r"^Test (.+) YP > Compatibility: Run(?: cmds)$") > + repo = repo_regex.match(step['name']).group(1) > + except: > + pass > + try: > + url_str = > f'{api_url}/builds/{build_id}/steps/{step_num}/logs/stdio/raw' > + log_req = requests.get(url_str) > + log = log_req.content.decode("utf-8") > + # We only care about layers that have passed > + layer_regex = re.compile(r"^INFO: (.+) ... > PASS$", re.MULTILINE) > + layers = layer_regex.findall(log) > + if len(layers) > 0: > + logger.info(f'\t\tDetected {layers}') > + for layer in layers: > + compatible_dict[job][branch].add(layer) > + except: > + sys.exit(1) > + copy_desired_branches.remove(branch) > + with open(output_filename, 'w') as f: > + json.dump(compatible_dict, f, cls=YPCompatibleJSONEncoder) > + > + sys.exit(0) > + > + > +if __name__ == "__main__": > + main() > -- > 2.34.1 > > > > >
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#61505): https://lists.yoctoproject.org/g/yocto/message/61505 Mute This Topic: https://lists.yoctoproject.org/mt/102231417/21656 Group Owner: yocto+ow...@lists.yoctoproject.org Unsubscribe: https://lists.yoctoproject.org/g/yocto/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-