From 0939d5bd86f4ad757dc230256e39246d35db1743 Mon Sep 17 00:00:00 2001 From: Jon Turney Date: Mon, 16 Jan 2023 14:03:58 +0000 Subject: Add 'calm-tool vault' --- calm/calm.py | 4 +++- calm/db.py | 33 +++++++++++++++++++++++++++++ calm/package.py | 15 +++++++++++++- calm/tool_util.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ calm/untest.py | 26 +++++------------------ calm/vault.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 177 insertions(+), 23 deletions(-) create mode 100644 calm/tool_util.py create mode 100644 calm/vault.py diff --git a/calm/calm.py b/calm/calm.py index dc66926..17a9932 100755 --- a/calm/calm.py +++ b/calm/calm.py @@ -314,11 +314,13 @@ def remove_stale_packages(args, packages, state): to_vault['noarch'] = MoveList() to_vault['src'] = MoveList() + vault_requests = db.vault_requests(args) + for arch in common_constants.ARCHES: logging.debug("checking for stale packages for arch %s" % (arch)) # find stale packages - to_vault[arch] = package.stale_packages(packages[arch]) + to_vault[arch] = package.stale_packages(packages[arch], vault_requests) # remove stale packages from package set to_vault[arch].map(lambda p, f: package.delete(packages[arch], p, f)) diff --git a/calm/db.py b/calm/db.py index c1efbcf..b7f7040 100644 --- a/calm/db.py +++ b/calm/db.py @@ -42,6 +42,12 @@ def connect(args): conn.execute('''CREATE TABLE IF NOT EXISTS historic_package_names (name TEXT NOT NULL PRIMARY KEY )''') + + conn.execute('''CREATE TABLE IF NOT EXISTS vault_requests + (srcpackage TEXT NOT NULL, + vr TEXT NOT NULL + )''') + conn.commit() return conn @@ -71,3 +77,30 @@ def update_package_names(args, packages): # - names which the removed package provide:d # - other packages which might provide: the name of a removed package return (historic_names - current_names) + + +# +# vault requests made via 'calm-tool vault' +# +def vault_requests(args): + requests = {} + + with connect(args) as conn: + conn.row_factory = sqlite3.Row + + cur = conn.execute("SELECT * FROM vault_requests") + for row in cur.fetchall(): + spkg = row['srcpackage'] + if spkg not in requests: + requests[spkg] = set() + requests[spkg].add(row['vr']) + + # remove all rows + cur = conn.execute("DELETE FROM vault_requests") + + return requests + + +def vault_request_add(args, p, v): + with connect(args) as conn: + conn.execute('INSERT INTO vault_requests (srcpackage, vr) VALUES (?,?)', (p, v)) diff --git a/calm/package.py b/calm/package.py index 641030c..72c03f0 100755 --- a/calm/package.py +++ b/calm/package.py @@ -1545,7 +1545,7 @@ def mark_package_fresh(packages, p, v, mark=Freshness.fresh): SO_AGE_THRESHOLD_YEARS = 5 -def stale_packages(packages): +def stale_packages(packages, vault_requests): certain_age = time.time() - (SO_AGE_THRESHOLD_YEARS * 365.25 * 24 * 60 * 60) logging.debug("cut-off date for soversion package to be considered old is %s" % (time.strftime("%F %T %Z", time.localtime(certain_age)))) @@ -1617,6 +1617,19 @@ def stale_packages(packages): mark = noretain_hint_mark + # - marked via 'calm-tool vault' + # + es = po.srcpackage(bv, suffix=False) + if es in vault_requests: + def vault_requests_mark(v): + if v in vault_requests[es]: + logging.info("package '%s' version '%s' not retained due vault request" % (pn, v)) + return Freshness.conditional + else: + return Freshness.fresh + + mark = vault_requests_mark + # mark any versions explicitly listed in the keep: override hint (unconditionally) for v in po.override_hints.get('keep', '').split(): if v in po.versions(): diff --git a/calm/tool_util.py b/calm/tool_util.py new file mode 100644 index 0000000..09e40e8 --- /dev/null +++ b/calm/tool_util.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2023 Jon Turney +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +import logging +import os +import re + +from . import common_constants +from . import maintainers + + +def split(pvr): + # split name and vr + match = re.match(r'^(.+?)-(\d.*)', pvr) + if not match: + logging.error("unable to determine package and version-release from '%s'" % (pvr)) + return (None, None) + + p = match.group(1) + vr = match.group(2) + + return (p, vr) + + +def permitted(p): + # check CYGNAME is a maintainer for package + cygname = os.environ.get('CYGNAME', None) + + mlist = {} + mlist = maintainers.add_packages(mlist, common_constants.PKGMAINT, orphanMaint=common_constants.ORPHANMAINT) + + if cygname not in mlist: + logging.error("'%s' is not a package maintainer" % (cygname)) + return False + + if p not in mlist[cygname].pkgs: + logging.error("package '%s' is not in the package list for maintainer '%s'" % (p, cygname)) + return False + + return True diff --git a/calm/untest.py b/calm/untest.py index f3995e7..7d6d774 100644 --- a/calm/untest.py +++ b/calm/untest.py @@ -28,31 +28,15 @@ import re import sys from . import common_constants -from . import maintainers +from . import tool_util def untest(pvr): - # split name and vr - match = re.match(r'^(.+?)-(\d.*)', pvr) - if not match: - logging.error("unable to determine package and version-release from '%s'" % (pvr)) + p, vr = tool_util.split(pvr) + if not p: return - p = match.group(1) - vr = match.group(2) - - # check CYGNAME is a maintainer for package - cygname = os.environ['CYGNAME'] - - mlist = {} - mlist = maintainers.add_packages(mlist, common_constants.PKGMAINT, orphanMaint=common_constants.ORPHANMAINT) - - if cygname not in mlist: - logging.error("'%s' is not a package maintainer" % (cygname)) - return - - if p not in mlist[cygname].pkgs: - logging.error("package '%s' is not in the package list for maintainer '%s'" % (p, cygname)) + if not tool_util.permitted(p): return # remove '^test:' lines from any package and subpackage hints @@ -85,7 +69,7 @@ def untest(pvr): def main(): parser = argparse.ArgumentParser(description='remove test: hint') - parser.add_argument('package', nargs='*', metavar='PVR') + parser.add_argument('package', nargs='+', metavar='SPVR') (args) = parser.parse_args() logging.getLogger().setLevel(logging.INFO) diff --git a/calm/vault.py b/calm/vault.py new file mode 100644 index 0000000..76cb8ad --- /dev/null +++ b/calm/vault.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2023 Jon Turney +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +import argparse +import logging +import os +import sys +import types + +from . import common_constants +from . import db +from . import tool_util + + +def vault(pvr): + p, vr = tool_util.split(pvr) + if not p: + return + + if not tool_util.permitted(p): + return + + args = types.SimpleNamespace() + args.htdocs = os.path.join(common_constants.HTDOCS, 'packages') + + db.vault_request_add(args, p, vr) + + +def main(): + parser = argparse.ArgumentParser(description='mark packages for vaulting') + parser.add_argument('package', nargs='+', metavar='SPVR') + (args) = parser.parse_args() + + logging.getLogger().setLevel(logging.INFO) + logging.basicConfig(format='vault: %(message)s') + + for p in args.package: + vault(p) + + +if __name__ == "__main__": + sys.exit(main()) -- cgit v1.2.3