From f17603d02a75290ecc5b7febc6dac0bd311aa429 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Tue, 20 Feb 2018 12:04:03 +0100 Subject: [PATCH] Add to dist-git the scripts we use for mass-branching Signed-off-by: Pierre-Yves Chibon --- roles/distgit/files/mass-branching-git.py | 79 ++++++++++++ .../distgit/files/mass-branching-gitolite.py | 119 ++++++++++++++++++ roles/distgit/tasks/main.yml | 10 ++ 3 files changed, 208 insertions(+) create mode 100644 roles/distgit/files/mass-branching-git.py create mode 100644 roles/distgit/files/mass-branching-gitolite.py diff --git a/roles/distgit/files/mass-branching-git.py b/roles/distgit/files/mass-branching-git.py new file mode 100644 index 0000000000..cad68f4b60 --- /dev/null +++ b/roles/distgit/files/mass-branching-git.py @@ -0,0 +1,79 @@ +#!/usr/bin/python + +""" +This script is meant to be run in pkgs01.stg or pkgs02 (ie the dist-git +servers) and will be adding the specified new git branch to the specified +git repositories. + +Basically the script takes two inputs, the new branch name (for example +f28, f29, epel8....) and a file containing the namespace/name of all the +git repositories for which that branch should be created. + +""" +from __future__ import print_function + +import argparse +import os +import subprocess +import sys + +_base_path = '/srv/git/repositories' +_branch_from = 'master' + + +def _get_arguments(): + """ Set and retrieve the command line arguments. """ + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + 'gitbranch', + help='The new git branch to create') + parser.add_argument( + 'inputfile', + help='The input file listing the repositories to update') + + return parser.parse_args() + + +def create_git_branch(path, gitbranch): + """ Create the specified git branch in the specified git repository. """ + cmd = ['git', 'branch', gitbranch, _branch_from] + return subprocess.check_output( + cmd, stderr=subprocess.STDOUT, shell=False, cwd=path) + + +def main(): + """ Main function of the program. """ + + args = _get_arguments() + + if not os.path.isfile(args.inputfile): + print('%s does not appear to be a file' % args.inputfile) + return 1 + + with open(args.inputfile) as stream: + data = [row.strip() for row in stream] + + if not data: + print('%s appears to be empty' % args.inputfile) + return 1 + + for entry in sorted(data): + if entry.startswith('rpm/'): + entry = 'rpms/%s' % entry[4:] + elif entry.startswith('module/'): + entry = 'modules/%s' % entry[7:] + + path = os.path.join(_base_path, '%s.git' % entry) + print('Processing %s' % path) + try: + create_git_branch(path, args.gitbranch) + except subprocess.CalledProcessError as err: + print( + ' ERROR: %s failed to branch, return code: %s\n %s' % ( + err.returncode, err.output)) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/roles/distgit/files/mass-branching-gitolite.py b/roles/distgit/files/mass-branching-gitolite.py new file mode 100644 index 0000000000..8461f75546 --- /dev/null +++ b/roles/distgit/files/mass-branching-gitolite.py @@ -0,0 +1,119 @@ +#!/usr/bin/python + +""" +This script is meant to be run in pkgs01.stg or pkgs02 (ie the dist-git +servers) and will be adding the specified new git branch to the gitolite +configuration so users can push to that branch. + +Basically the script takes two inputs, the new branch name (for example +f28, f29, epel8....) and a file containing the namespace/name of all the +git repositories for which the gitolite configuration should be updated. + +""" +from __future__ import print_function + +import argparse +import os +import sys + +_base_path = '/srv/git/' +_branch_from = 'master' + + +def _get_arguments(): + """ Set and retrieve the command line arguments. """ + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + 'gitbranch', + help='The new git branch to create') + parser.add_argument( + 'inputfile', + help='The input file listing the repositories to update') + parser.add_argument( + '--output', + help='File where to write the new config (It may be a good idea to ' + 'not over-write the current configuration file so you can diff ' + 'the current with the new one') + + return parser.parse_args() + + +def main(): + """ Main function of the program. """ + + print( + 'Did you stop the service `pagure_gitolite_worker` to ensure ' + 'nothing touches this file while we work on it?') + answer = raw_input('[y/N] ') + if answer.lower() != 'y': + print('You said no, so you know what to do ;-)') + return 1 + + args = _get_arguments() + + if not os.path.isfile(args.inputfile): + print('%s does not appear to be a file' % args.inputfile) + return 1 + + repos = None + with open(args.inputfile) as stream: + repos = [row.strip() for row in stream] + + if not repos: + print('%s appears to be empty' % args.inputfile) + return 1 + + config_file = os.path.join( + _base_path, '.gitolite', 'conf', 'gitolite.conf') + + if not os.path.isfile(config_file): + print('%s does not appear to be a file or to exist' % config_file) + return 1 + + config = None + with open(config_file) as stream: + config = [row.rstrip() for row in stream] + + if not data: + print('%s appears to be empty' % config_file) + return 1 + + output = [] + process = False + for row in config: + if row.strip().startswith('repo '): + name = row.strip().split()[-1] + + if name.startswith('rpm/'): + name = 'rpms/%s' % name[4:] + elif name.startswith('module/'): + name = 'modules/%s' % name[7:] + + if name in repos: + process = True + else: + process = False + if process and row.strip().startswith('RWC master ='): + new_row = row + new_row = new_row.replace(' master =', ' {} ='.format(args.branch), 1) + output.append(new_row) + output.append(row) + + print( + 'Done updating the config, writing the new content to {}'.format( + args.output)) + + with open(args.output, 'w') as stream: + stream.write('\n'.join(output)) + + print( + 'Now put the new configuration file in place (if it needs to be) ' + 'then run `` sudo -u pagure HOME=/srv/git gitolite compile `` ' + 'followed by `` sudo -u pagure HOME=/srv/git gitolite compile `` ' + 'and finally, restart the `pagure_gitolite_worker` service.') + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/roles/distgit/tasks/main.yml b/roles/distgit/tasks/main.yml index 9d8c949bf0..7d1f280e2f 100644 --- a/roles/distgit/tasks/main.yml +++ b/roles/distgit/tasks/main.yml @@ -154,6 +154,16 @@ tags: - distgit +- name: install the two scripts needed for mass-branching + copy: src={{item}} dest=/usr/local/bin/{{item}} owner=root group=root mode=0755 + with_items: + - mass-branching-git.py + - mass-branching-gitolite.py + tags: + - config + - distgit + - mass-branching + # -- Gitolite -------------------------------------------- # This is the permission management for package maintainers, using Gitolite. - name: create the /var/log/gitolite directory