aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Hart <matthew.hart@linaro.org>2015-07-28 11:47:20 +0100
committerLinaro Code Review <review@review.linaro.org>2015-08-07 12:14:33 +0000
commitd690dc9be55153d77846c0588463f345701206c3 (patch)
tree5ffcaa06577d5d74d0dfecd0b2d4f2355dbb522e
parent59290358db2c0ae0a1e1183ea060091017dabcb1 (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-xcheck-git-repos.py117
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])