From 2caea102288c8977892e10a06afa3b22cdcc0ff4 Mon Sep 17 00:00:00 2001 From: Lon Hohberger Date: Wed, 2 Jun 2021 11:02:40 -0400 Subject: [PATCH 1/4] Add support for JSON-parsed DLRN results Signed-off-by: Lon Hohberger --- tag_utils/delta.py | 24 ++++++++++++++++++++++-- tag_utils/dlrn.py | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 tag_utils/dlrn.py diff --git a/tag_utils/delta.py b/tag_utils/delta.py index 58722f1..af89ce1 100644 --- a/tag_utils/delta.py +++ b/tag_utils/delta.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +from urllib.parse import urlparse + import koji_wrapper from koji_wrapper.base import KojiWrapperBase from koji_wrapper.tag import KojiTag @@ -9,6 +11,7 @@ from .basic import file_as_nevr from .compose import compose_as_nevr +from .dlrn import json_api_as_nevr from .et import get_build_for_release from .koji import latest_tagged_as_nevr @@ -55,11 +58,29 @@ def tag_to_latest_builds(tag, **kwargs): return latest_tagged_as_nevr(koji_tag) +def _url_as_nevr(inp): + parsed_url = urlparse(inp) + + if not parsed_url.path: + raise ValueError('Invalid URL: ' + inp) + + if parsed_url.path.startswith('/dlrn/versions/'): + # drln API (JSON) - preferred + ret = json_api_as_nevr(inp) + else: + # fetch compose data + ret = compose_as_nevr(inp) + return ret + + # Automatically resolve input class to dict of: # {'n': 'n-e:v-r', 'm': 'm-e:v-r'} # Supports: # - pungi compose # - koji tag +# - flat file (list of NVRs +# - errata tool build lists +# - JSON-parsed DLRN results def input_to_nevr_dict(inp, **kwargs): ret = None @@ -67,8 +88,7 @@ def input_to_nevr_dict(inp, **kwargs): if ( inp.startswith('http://') or # NOQA inp.startswith('https://') or # NOQA inp.startswith('/')): - # fetch compose data - ret = compose_as_nevr(inp) + ret = _url_as_nevr(inp) elif inp.startswith('et:'): ret = release_set_as_nevr(inp, __koji_session, **kwargs) elif inp.startswith('file:'): diff --git a/tag_utils/dlrn.py b/tag_utils/dlrn.py new file mode 100644 index 0000000..40f7fe2 --- /dev/null +++ b/tag_utils/dlrn.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +import json + +import requests + + +from .common import tidy_nevra + + +def fetch_json_data(url): + ret = requests.get(url) + if ret.status_code == 200: + return json.loads(ret.text) + + +def json_api_as_nevr(url): + md = fetch_json_data(url) + ret = {} + for p in md['packages']: + ret[p['name']] = tidy_nevra(p['nvr']) + return ret From 268c635aec6645e51f39cbff6c8ac4b398c9c0db Mon Sep 17 00:00:00 2001 From: Lon Hohberger Date: Tue, 2 Aug 2022 13:25:28 -0400 Subject: [PATCH 2/4] Tag-delta: Allow file:// to point to local composes --- tag_utils/compose.py | 14 ++++++++++++++ tag_utils/delta.py | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tag_utils/compose.py b/tag_utils/compose.py index 6e694f5..1425921 100644 --- a/tag_utils/compose.py +++ b/tag_utils/compose.py @@ -19,6 +19,20 @@ def check_compose(url, verify=True): raise ValueError('Failed to check compose; HTTP code ' + str(ret.status_code)) +def fetch_or_read(url): + if url.startswith('file://'): + filename = url[7:] + fp = open(filename, 'r') + ret = fp.read() + fp.close() + return ret + else: + ret = requests.get(url) + if ret.status_code == 200: + return ret.text + raise ValueError('Failed to check compose; HTTP code ' + str(ret.status_code)) + + def fetch_rpm_metadata(url, verify=True): check_compose(url) full_url = os.path.join(url, 'compose/metadata/rpms.json') diff --git a/tag_utils/delta.py b/tag_utils/delta.py index af89ce1..abf2140 100644 --- a/tag_utils/delta.py +++ b/tag_utils/delta.py @@ -87,7 +87,7 @@ def input_to_nevr_dict(inp, **kwargs): if isinstance(inp, str): if ( inp.startswith('http://') or # NOQA inp.startswith('https://') or # NOQA - inp.startswith('/')): + inp.startswith('file://')): ret = _url_as_nevr(inp) elif inp.startswith('et:'): ret = release_set_as_nevr(inp, __koji_session, **kwargs) From 8fd9d9a5e1b628ddbdaf8a779048519b77b1f6f2 Mon Sep 17 00:00:00 2001 From: Lon Hohberger Date: Mon, 21 Aug 2023 11:09:57 -0400 Subject: [PATCH 3/4] Allow et::X to specify a specific advisory ID --- tag_utils/cli/tag_delta.py | 1 + tag_utils/delta.py | 18 +++++++++++++++++- tag_utils/et.py | 35 +++++++++++++++++++++++------------ 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/tag_utils/cli/tag_delta.py b/tag_utils/cli/tag_delta.py index d7c75e7..f8596a3 100755 --- a/tag_utils/cli/tag_delta.py +++ b/tag_utils/cli/tag_delta.py @@ -19,6 +19,7 @@ def main(): ' | file: ' '| http[s]:// ' '| et: (Errata Tool Release name or id) ' + '| et:: (Single Errata Tool advisory id) ' '| - (use stdin as list of nvr to compare against)') parser.add_argument('--new', action='store_true', default=False, diff --git a/tag_utils/delta.py b/tag_utils/delta.py index abf2140..948fbf4 100644 --- a/tag_utils/delta.py +++ b/tag_utils/delta.py @@ -12,7 +12,7 @@ from .basic import file_as_nevr from .compose import compose_as_nevr from .dlrn import json_api_as_nevr -from .et import get_build_for_release +from .et import get_build_for_release, get_build_for_advisory from .koji import latest_tagged_as_nevr __koji_session = None @@ -32,6 +32,20 @@ def release_set_as_nevr(release_name_or_id, koji_session, **kwargs): return get_build_for_release(release_name_or_id.strip('et:'), __koji_session) +def erratum_set_as_nevr(errata_id, koji_session, **kwargs): + global __koji_session + + if 'session' in kwargs: + __koji_session = kwargs['session'] + + if __koji_session is None: + __koji_session = KojiWrapperBase(profile='brew') + if __koji_session is None: + raise Exception('Could not connect to koji') + + return get_build_for_advisory(errata_id.strip('et::'), __koji_session) + + def tag_to_latest_builds(tag, **kwargs): global __koji_session inherit = False @@ -89,6 +103,8 @@ def input_to_nevr_dict(inp, **kwargs): inp.startswith('https://') or # NOQA inp.startswith('file://')): ret = _url_as_nevr(inp) + elif inp.startswith('et::'): + ret = erratum_set_as_nevr(inp, __koji_session, **kwargs) elif inp.startswith('et:'): ret = release_set_as_nevr(inp, __koji_session, **kwargs) elif inp.startswith('file:'): diff --git a/tag_utils/et.py b/tag_utils/et.py index 72bcc68..ba83cef 100644 --- a/tag_utils/et.py +++ b/tag_utils/et.py @@ -33,18 +33,7 @@ def get_advisory_list(errata_tool_release, debug=False): return [Erratum(errata_id=advisory_id) for advisory_id in advisory_ids] -def get_build_for_release(release_name_or_id, koji_session, debug=False): - if debug: - print('got in "{0}"'.format(release_name_or_id)) - try: - rel = errata_tool.release.Release(id=int(release_name_or_id)) - advisories = [i for i in rel.advisories() if i["status"] not in ('SHIPPED_LIVE', 'DROP_NO_SHIP')] - advisory_list = [Erratum(errata_id=i['id']) for i in advisories] - if debug: - print("Got list of advisories:", advisories) - except ValueError: - advisory_list = get_advisory_list(release_name_or_id, debug=debug) - +def _get_builds_for_advisory_list(advisory_list, koji_session, debug=False): all_builds = set() for advisory in advisory_list: if debug: @@ -61,3 +50,25 @@ def get_build_for_release(release_name_or_id, koji_session, debug=False): return_data[build_data['name']] = koji_build_to_nevr(build_data) return return_data + + +def get_build_for_release(release_name_or_id, koji_session, debug=False): + if debug: + print('got in "{0}"'.format(release_name_or_id)) + try: + rel = errata_tool.release.Release(id=int(release_name_or_id)) + advisories = [i for i in rel.advisories() if i["status"] not in ('SHIPPED_LIVE', 'DROP_NO_SHIP')] + advisory_list = [Erratum(errata_id=i['id']) for i in advisories] + if debug: + print("Got list of advisories:", advisories) + except ValueError: + advisory_list = get_advisory_list(release_name_or_id, debug=debug) + + return _get_builds_for_advisory_list(advisory_list, koji_session, debug=debug) + + +def get_build_for_advisory(advisory_id, koji_session, debug=False): + if debug: + print('got advisory "{0}"'.format(advisory_id)) + erratum = Erratum(errata_id=advisory_id) + return _get_builds_for_advisory_list([erratum], koji_session, debug=debug) From 26052ca800294f537f56d5fa41b8b3efd701144f Mon Sep 17 00:00:00 2001 From: Lon Hohberger Date: Mon, 21 Aug 2023 12:11:19 -0400 Subject: [PATCH 4/4] Bump to 0.0.9 --- HISTORY.rst | 9 +++++++++ PKG-INFO | 2 +- setup.py | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index add9e8d..3d4a1c4 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,15 @@ ======= History ======= +0.0.9 (2023-08-21) +------------------ +* Support DLRN results, local composes +* Allow et:: to look at one specific advisory instead of a release +* Allow skipping downgrades or upgrades +* Improve help output +* Allow specifying verify parameter to requests +* Allow multi-arch non-RPM builds when cleaning tags + 0.0.8 (2020-09-10) ------------------ * Use argparse for tag-over diff --git a/PKG-INFO b/PKG-INFO index 7237b22..ee29586 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: tag_utils -Version: 0.0.7 +Version: 0.0.9 Summary: Pungi/Koji tag utilities for Release Depot Author: release-depot Author-email: lon@metamorphism.com diff --git a/setup.py b/setup.py index 57fb1c8..064c3cf 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ setup( name='tag_utils', - version='0.0.8', + version='0.0.9', install_requires=['pyyaml', 'koji', 'toolchest>=0.0.6', 'koji_wrapper'], tests_require=TEST_REQUIRES, extras_require={'test': TEST_REQUIRES,