#!/usr/bin/env python # Copyright 2014-2015 Antoine "hashar" Musso # Copyright 2014-2015 Wikimedia Foundation Inc. # # 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 # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # pylint: disable=locally-disabled, invalid-name """ Zuul references cleaner. Clear up references under /refs/zuul/ by inspecting the age of the commit the reference points to. If the commit date is older than a number of days specificed by --until, the reference is deleted from the git repository. Use --dry-run --verbose to finely inspect the script behavior. """ import argparse import git import logging import time import sys NOW = int(time.time()) DEFAULT_DAYS = 360 ZUUL_REF_PREFIX = 'refs/zuul/' parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('--until', dest='days_ago', default=DEFAULT_DAYS, type=int, help='references older than this number of day will ' 'be deleted. Default: %s' % DEFAULT_DAYS) parser.add_argument('-n', '--dry-run', dest='dryrun', action='store_true', help='do not delete references') parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='set log level from info to debug') parser.add_argument('gitrepo', help='path to a Zuul git repository') args = parser.parse_args() logging.basicConfig() log = logging.getLogger('zuul-clear-refs') if args.verbose: log.setLevel(logging.DEBUG) else: log.setLevel(logging.INFO) try: repo = git.Repo(args.gitrepo) except git.exc.InvalidGitRepositoryError: log.error("Invalid git repo: %s" % args.gitrepo) sys.exit(1) for ref in repo.references: if not ref.path.startswith(ZUUL_REF_PREFIX): continue if type(ref) is not git.refs.reference.Reference: # Paranoia: ignore heads/tags/remotes .. continue try: commit_ts = ref.commit.committed_date except LookupError: # GitPython does not properly handle PGP signed tags log.exception("Error in commit: %s, ref: %s. Type: %s", ref.commit, ref.path, type(ref)) continue commit_age = int((NOW - commit_ts) / 86400) # days log.debug( "%s at %s is %3s days old", ref.commit, ref.path, commit_age, ) if commit_age > args.days_ago: if args.dryrun: log.info("Would delete old ref: %s (%s)", ref.path, ref.commit) else: log.info("Deleting old ref: %s (%s)", ref.path, ref.commit) ref.delete(repo, ref.path)