diff options
author | Matt Hart <matthew.hart@linaro.org> | 2015-07-28 11:47:20 +0100 |
---|---|---|
committer | Linaro Code Review <review@review.linaro.org> | 2015-08-07 12:14:33 +0000 |
commit | d690dc9be55153d77846c0588463f345701206c3 (patch) | |
tree | 5ffcaa06577d5d74d0dfecd0b2d4f2355dbb522e | |
parent | 59290358db2c0ae0a1e1183ea060091017dabcb1 (diff) |
Replace the update-server-info-fallback script
Beginning of work thats described in:
https://projects.linaro.org/browse/SYS-18
Change-Id: Iac8da3656606931dbe337225f1e6a31996bb11dd
-rwxr-xr-x | check-git-repos.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/check-git-repos.py b/check-git-repos.py new file mode 100755 index 0000000..b073641 --- /dev/null +++ b/check-git-repos.py @@ -0,0 +1,117 @@ +#!/usr/bin/python +from subprocess import check_output, STDOUT, CalledProcessError +import os +import time +import argparse +import logging +import stat + +# Root location of git repos +GITROOT = "/srv/repositories" +# Max age of the refs file (in minutes) before processing a repo +MAXAGE = 60 +# Process so many repos per invocation +CHUNK = 500 +# Export filename +EXPORT_FILE = "git-daemon-export-ok" + +logging.basicConfig() +log = logging.getLogger('check-git-repos') + + +def run_command(cmd, dir): + log.debug("executing %s in %s", cmd, dir) + try: + out = check_output(cmd, stderr=STDOUT, + cwd=dir) + except CalledProcessError as e: + return e.returncode, e.output + return 0, out + + +def update_server_info(path): + return run_command(["git", "update-server-info"], path) + + +def get_file_refs(path): + filerefs = {} + with open(os.path.join(path, "info/refs")) as f: + for line in f: + if line: + data = line.split() + filerefs[data[1]] = data[0] + return filerefs + + +def get_git_refs(path): + ret, out = run_command(["git", "show-ref"], path) + lines = out.split("\n") + gitrefs = {} + for line in lines: + if line: + data = line.split() + gitrefs[data[1]] = data[0] + return gitrefs + + +def perms_check(file): + st_mode = os.stat(file).st_mode + mode = stat.S_IFREG | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | \ + stat.S_IROTH + if st_mode != mode: + log.warn("Permissions wrong for file %s, changing %s=>%s", file, + oct(st_mode), oct(mode)) + os.chmod(file, mode) + + +def get_repos(): + paths = [] + for root, dirs, files in os.walk(GITROOT, followlinks=True): + if root.endswith(".git/info"): + if "refs" in files: + log.debug("found refs file %s", root+"/refs") + paths.append(os.path.dirname(root)) + return paths + + +def check_ref_status(path): + filerefs = get_file_refs(path) + gitrefs = get_git_refs(path) + diff = set(filerefs.items()) ^ set(gitrefs.items()) + if len(diff) > 0: + log.warn("%s refs file out of date, diff: %s", path, diff) + ret, out = update_server_info(path) + if ret != 0: + log.error("error processing %s, exited %i", path, ret) + log.error(out) + + +def check_export_file(path): + if not os.path.exists(os.path.join(path, EXPORT_FILE)): + log.warn("%s not found in %s", EXPORT_FILE, path) + + +def process(paths): + for path in paths: + refsfile = os.path.join(path, "info/refs") + perms_check(refsfile) + perms_check(path+"/objects/info/packs") + check_export_file(path) + modified_time = os.stat(refsfile).st_mtime + current_time = time.time() + earliest_time = current_time - (MAXAGE * 60) + if modified_time < earliest_time: + log.debug("%s mtime was older than %sm", refsfile, MAXAGE) + check_ref_status(path) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='Check git repositories') + parser.add_argument('--log', default='WARN', + choices=('WARN', 'INFO', 'DEBUG'), + help='Logging level to use. Default=%(default)s') + args = parser.parse_args() + log.setLevel(getattr(logging, args.log)) + pathlist = get_repos() + process(pathlist[:CHUNK]) |