- reponame = args.repository
- if reponame is None and args.hook:
- reponame = find_repo_by_directory(os.getcwd())
- if reponame is None:
- raise Exception("Unable to detect repository, please use --repository.")
-
- # now sync this repository
- repo = repos[reponame]
- if args.hook:
- # parse the information we get from stdin
- for line in sys.stdin:
- (oldsha, newsha, ref) = line.split()
- repo.update_ref(newsha, ref, source=None)
- else:
- raise Exception("I am unsure what to do here.")
+ try:
+ # All arguments are *untrusted* input, as we may be called via sudo from the webserver. So we fix the configuration file location.
+ conffile = os.path.join(os.path.dirname(__file__), 'git-mirror.conf')
+ conf = read_config(conffile)
+ repos = {}
+ for name, section in conf.items():
+ if name != 'DEFAULT':
+ repos[name] = Repo(section)
+
+ # find the repository we are dealing with
+ reponame = args.repository
+ if reponame is None and args.git_hook:
+ reponame = find_repo_by_directory(repos, os.getcwd())
+ if reponame is None or reponame not in repos:
+ raise Exception("Unknown or missing repository name.")
+
+ # now sync this repository
+ repo = repos[reponame]
+ if args.git_hook:
+ # parse the information we get from stdin
+ for line in sys.stdin:
+ (oldsha, newsha, ref) = line.split()
+ repo.update_ref(ref, source = None)
+ elif args.web_hook:
+ data = get_github_payload()
+ ref = data["ref"]
+ # validate the ref name
+ if re.match('refs/[a-z/]+', ref) is None:
+ raise Exception("Invalid ref name {0}".format(ref))
+ # collect URLs of this repository
+ urls = []
+ for key in ("git_url", "ssh_url", "clone_url"):
+ urls.append(data["repository"][key])
+ source = repo.find_mirror_by_url(urls)
+ if source is None:
+ raise Exception("Could not find the source.")
+ repo.update_ref(ref, source = source, suppress_stderr = True)
+ # print an answer
+ print("Content-Type: text/plain")
+ print()
+ print("Updated {0}:{1} from source {2}".format(reponame, ref, source))
+ else:
+ raise Exception("No manual mode is implemented so far.")
+ except Exception as e:
+ # don't leak filenames etc. when we are running as a hook
+ if args.web_hook:
+ print("Status: 500 Internal Server Error")
+ print("Content-Type: text/plain")
+ print()
+ print(str(e))
+ elif args.git_hook:
+ #sys.stderr.write(str(e))
+ traceback.print_exc()
+ else:
+ traceback.print_exc()