diff options
author | James E. Blair <jim@acmegating.com> | 2022-05-28 17:34:08 -0700 |
---|---|---|
committer | James E. Blair <jim@acmegating.com> | 2022-05-30 07:31:16 -0700 |
commit | 3ffbf10f250788ecff5c0ade3030a275eca54481 (patch) | |
tree | f5fe8616f256d35e719b8a375edb5af8df90c23f /zuul/cmd | |
parent | 326ede243fdc34d6788c7e68737c644289058553 (diff) | |
download | zuul-3ffbf10f250788ecff5c0ade3030a275eca54481.tar.gz |
Add prune-database command
This adds a zuul-admin command which allows operators to delete old
database entries.
Change-Id: I4e277a07394aa4852a563f4c9cdc39b5801ab4ba
Diffstat (limited to 'zuul/cmd')
-rwxr-xr-x | zuul/cmd/client.py | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/zuul/cmd/client.py b/zuul/cmd/client.py index b72b7626b..3638564f2 100755 --- a/zuul/cmd/client.py +++ b/zuul/cmd/client.py @@ -1,5 +1,6 @@ # Copyright 2012 Hewlett-Packard Development Company, L.P. # Copyright 2013 OpenStack Foundation +# Copyright 2022 Acme Gating, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -16,6 +17,8 @@ import argparse import babel.dates import datetime +import dateutil.parser +import dateutil.tz import json import jwt import logging @@ -40,6 +43,28 @@ from zuul.zk.layout import LayoutState, LayoutStateStore from zuul.zk.components import COMPONENT_REGISTRY +def parse_cutoff(now, before, older_than): + if before and not older_than: + cutoff = dateutil.parser.parse(before) + if cutoff.tzinfo and cutoff.tzinfo != dateutil.tz.tzutc(): + raise RuntimeError("Timestamp must be specified as UTC") + cutoff = cutoff.replace(tzinfo=dateutil.tz.tzutc()) + return cutoff + elif older_than and not before: + value = older_than[:-1] + suffix = older_than[-1] + if suffix == 'd': + delta = datetime.timedelta(days=int(value)) + elif suffix == 'h': + delta = datetime.timedelta(hours=int(value)) + else: + raise RuntimeError("Unsupported relative time") + return now - delta + else: + raise RuntimeError( + "Either --before or --older-than must be supplied") + + # todo This should probably live somewhere else class ZuulRESTClient(object): """Basic client for Zuul's REST API""" @@ -498,6 +523,27 @@ class Client(zuul.cmd.ZuulApp): help='tenant name') cmd_delete_pipeline_state.add_argument('pipeline', type=str, help='pipeline name') + + # DB Maintenance + cmd_prune_database = subparsers.add_parser( + 'prune-database', + help='prune old database entries', + formatter_class=argparse.RawDescriptionHelpFormatter, + description=textwrap.dedent('''\ + Prune old database entries + + This command will delete database entries older than the + specified cutoff (which can be specified as either an + absolute or relative time).''')) + cmd_prune_database.set_defaults(command='prune-database') + cmd_prune_database.add_argument( + '--before', + help='absolute timestamp (e.g., "2022-01-31 12:00:00")') + cmd_prune_database.add_argument( + '--older-than', + help='relative time (e.g., "24h" or "180d")') + cmd_prune_database.set_defaults(func=self.prune_database) + return parser def parseArguments(self, args=None): @@ -1007,6 +1053,16 @@ class Client(zuul.cmd.ZuulApp): sys.exit(0) + def prune_database(self): + logging.basicConfig(level=logging.INFO) + args = self.args + now = datetime.datetime.now(dateutil.tz.tzutc()) + cutoff = parse_cutoff(now, args.before, args.older_than) + self.configure_connections(source_only=False, require_sql=True) + connection = self.connections.getSqlConnection() + connection.deleteBuildsets(cutoff) + sys.exit(0) + def main(): if sys.argv[0].endswith('zuul'): |