def set_repo_publishing(repo_name, publish): """Set the publishing flag on a repository. A publishing repository turns its pushed commits into public phased commits. It is the default behavior. Non-publishing repositories have their commits stay in the draft phase when pushed. """ user = os.getenv('USER') user_repo_dir = user.replace('@', '_') repo_path = get_and_validate_user_repo(repo_name) config_path, config = get_user_repo_config(repo_path) if not config.has_section('phases'): config.add_section('phases') value = 'True' if publish else 'False' config.set('phases', 'publish', value) with open(config_path, 'w') as fh: config.write(fh) run_command('%s -R %s replicatehgrc' % (HG, repo_path)) if publish: sys.stderr.write('Repository marked as publishing: changesets will ' 'change to public phase when pushed.\n') else: sys.stderr.write('Repository marked as non-publishing: draft ' 'changesets will remain in the draft phase when pushed.\n')
def edit_repo_description(repo_name): user = os.getenv('USER') user_repo_dir = user.replace('@', '_') print(EDIT_DESCRIPTION.format(user_dir=user_repo_dir, repo=repo_name)) selection = prompt_user('Proceed?', ['yes', 'no']) if selection != 'yes': return repo_path = get_and_validate_user_repo(repo_name) repo_description = raw_input('Enter a one line descripton for the ' 'repository: ') if repo_description == '': return repo_description = escape(repo_description) config_path, config = get_user_repo_config(repo_path) if not config.has_section('web'): config.add_section('web') config.set('web', 'description', repo_description) with open(config_path, 'w+') as fh: config.write(fh) run_command('%s -R %s replicatehgrc' % (HG, repo_path))
def edit_repo_description (cname, repo_name): global doc_root user = os.getenv ('USER') user_repo_dir = user.replace ('@', '_') print 'You are about to edit the description for hg.mozilla.org/users/%s/%s.' % (user_repo_dir, repo_name) print 'If you need to edit the description for a top level repo, please quit now and file an IT bug for it.' selection = prompt_user ('Proceed?', ['yes', 'no']) if (selection == 'yes'): if os.path.exists ('%s/users/%s/%s' % (doc_root[cname], user_repo_dir, repo_name)): repo_description = raw_input ('Enter a one line descripton for the repository: ') if (repo_description != ''): repo_description = escape (repo_description) repo_config = ConfigParser.RawConfigParser () repo_config_file = '%s/users/%s/%s' % (doc_root[cname], user_repo_dir, repo_name) + '/.hg/hgrc' if not os.path.isfile (repo_config_file): run_command ('touch ' + repo_config_file) run_command ('chown ' + user + ':scm_level_1 ' + repo_config_file) if repo_config.read (repo_config_file): repo_config_file = open (repo_config_file, 'w+') else: sys.stderr.write ('Could not read the hgrc file for /users/%s/%s.\n' % (user_repo_dir, repo_name)) sys.stderr.write ('Please file an IT bug to troubleshoot this.') sys.exit (1) if not repo_config.has_section ('web'): repo_config.add_section ('web') repo_config.set ('web', 'description', repo_description) repo_config.write (repo_config_file) repo_config_file.close () else: sys.stderr.write ('Could not find the repository at /users/%s/%s.\n' % (user_repo_dir, repo_name)) sys.exit (1)
def do_delete(repo_dir, repo_name): run_command('rm -rf %s/users/%s/%s' % (DOC_ROOT, repo_dir, repo_name)) # TODO implement vcsreplicator support for deleting repos run_command('/usr/bin/sudo -u hg /usr/local/bin/repo-push.sh -d -e users/%s/%s' % (repo_dir, repo_name)) purge_log = open('/tmp/pushlog_purge.%s' % os.getpid(), "a") purge_log.write('echo users/%s/%s\n' % (repo_dir, repo_name)) purge_log.close()
def fix_user_repo_perms(repo_name): user = os.getenv('USER') user_repo_dir = user.replace('@', '_') print "Fixing permissions, don't interrupt." try: run_command('/var/hg/version-control-tools/scripts/repo-permissions %s/users/%s/%s %s scm_level_1 wwr' % (DOC_ROOT, user_repo_dir, repo_name, user)) except Exception, e: print "Exception %s" % (e)
def do_delete(cname, repo_dir, repo_name, verbose=False): global doc_root if verbose: print "Deleting..." run_command ('rm -rf %s/users/%s/%s' % (doc_root[cname], repo_dir, repo_name)) if verbose: print "Finished deleting" purge_log = open ('/tmp/pushlog_purge.%s' % os.getpid(), "a") purge_log.write ('echo users/%s/%s\n' % (repo_dir, repo_name)) purge_log.close()
def do_delete(repo_dir, repo_name, verbose=False): if verbose: print "Deleting..." run_command('rm -rf %s/users/%s/%s' % (DOC_ROOT, repo_dir, repo_name)) run_repo_push('-d -e users/%s/%s' % (repo_dir, repo_name)) if verbose: print "Finished deleting" purge_log = open('/tmp/pushlog_purge.%s' % os.getpid(), "a") purge_log.write('echo users/%s/%s\n' % (repo_dir, repo_name)) purge_log.close()
def run_hg_clone(user_repo_dir, repo_name, source_repo_path): userdir = "%s/users/%s" % (DOC_ROOT, user_repo_dir) dest_dir = "%s/%s" % (userdir, repo_name) dest_url = "/users/%s/%s" % (user_repo_dir, repo_name) if os.path.exists(dest_dir): print(USER_REPO_EXISTS % repo_name) sys.exit(1) if (not os.path.exists('%s/%s' % (DOC_ROOT, source_repo_path)) or not check_repo_name(source_repo_path)): print(NO_SOURCE_REPO % source_repo_path) sys.exit(1) if not os.path.exists(userdir): run_command('mkdir %s' % userdir) print 'Please wait. Cloning /%s to %s' % (source_repo_path, dest_url) run_command('nohup %s --config format.usegeneraldelta=true init %s' % (HG, dest_dir)) run_command('nohup %s -R %s pull %s/%s' % (HG, dest_dir, DOC_ROOT, source_repo_path)) run_command('nohup %s -R %s replicatesync' % (HG, dest_dir)) # TODO ensure user WSGI files are in place on hgweb machine. # (even better don't rely on per-use WSGI files) print "Clone complete."
def get_user_repo_config(repo_dir): """Obtain a ConfigParser for a repository. If the hgrc file doesn't exist, it will be created automatically. """ user = os.getenv('USER') path = '%s/.hg/hgrc' % repo_dir if not os.path.isfile(path): run_command('touch %s' % path) run_command('chown %s:scm_level_1 %s' % (user, path)) config = ConfigParser.RawConfigParser() if not config.read(path): sys.stderr.write('Could not read the hgrc file for this repo\n') sys.stderr.write('Please file a Developer Services :: hg.mozilla.org bug\n') sys.exit(1) return path, config
def run_hg_clone(user_repo_dir, repo_name, source_repo_path, verbose=False): userdir = "%s/users/%s" % (DOC_ROOT, user_repo_dir) dest_dir = "%s/%s" % (userdir, repo_name) dest_url = "/users/%s/%s" % (user_repo_dir, repo_name) if os.path.exists(dest_dir): print(USER_REPO_EXISTS % repo_name) sys.exit(1) if (not os.path.exists('%s/%s' % (DOC_ROOT, source_repo_path)) or not check_repo_name(source_repo_path)): print(NO_SOURCE_REPO % source_repo_path) sys.exit(1) if not os.path.exists(userdir): run_command('mkdir %s' % userdir) print 'Please wait. Cloning /%s to %s' % (source_repo_path, dest_url) if(verbose): run_command('nohup %s clone --debug --verbose --time --pull -U %s/%s %s' % (HG, DOC_ROOT, source_repo_path, dest_dir), verbose=True) else: run_command('nohup %s clone --pull -U %s/%s %s' % (HG, DOC_ROOT, source_repo_path, dest_dir)) print "Clone complete."
def run_hg_clone (cname, user_repo_dir, repo_name, source_repo_path, verbose=False): global doc_root userdir = "%s/users/%s" % (doc_root[cname], user_repo_dir) dest_dir = "%s/%s" % (userdir, repo_name) dest_url = "/users/%s/%s" % (user_repo_dir, repo_name) if os.path.exists (dest_dir): print 'Sorry, you already have a repo called %s' % repo_name print 'If you think this is wrong, please file an IT bug' sys.exit (1) else: if (os.path.exists ('%s/%s' % (doc_root[cname], source_repo_path))) and (check_repo_name (source_repo_path)): if not os.path.exists (userdir): run_command ('mkdir %s' % userdir) print 'Please wait. Cloning /%s to %s' % (source_repo_path, dest_url) if(verbose): run_command ('nohup /usr/bin/hg clone --debug --verbose --time --pull -U %s/%s %s' % (doc_root[cname], source_repo_path, dest_dir), verbose=True) else: run_command ('nohup /usr/bin/hg clone --pull -U %s/%s %s' % (doc_root[cname], source_repo_path, dest_dir)) print "Clone complete." else: print 'Sorry, there is no source repo called %s.' % source_repo_path print 'If you think this is wrong, please file an IT bug' sys.exit (1)
def set_repo_obsolescence(repo_name, enabled): """Enable or disable obsolescence support on a repository.""" user = os.getenv('USER') user_repo_dir = user.replace('@', '_') repo_path = get_and_validate_user_repo(repo_name) config_path, config = get_user_repo_config(repo_path) if not config.has_section('experimental'): config.add_section('experimental') if enabled: config.set('experimental', 'evolution', 'all') else: config.remove_option('experimental', 'evolution') with open(config_path, 'w') as fh: config.write(fh) run_command('%s -R %s replicatehgrc' % (HG, repo_path)) if enabled: print(OBSOLESCENCE_ENABLED) else: print('Obsolescence is now disabled for this repo.')
def run_hg_clone(user_repo_dir, repo_name, source_repo_path): userdir = "%s/users/%s" % (DOC_ROOT, user_repo_dir) dest_dir = "%s/%s" % (userdir, repo_name) dest_url = "/users/%s/%s" % (user_repo_dir, repo_name) if os.path.exists(dest_dir): print(USER_REPO_EXISTS % repo_name) sys.exit(1) if (not os.path.exists('%s/%s' % (DOC_ROOT, source_repo_path)) or not check_repo_name(source_repo_path)): print(NO_SOURCE_REPO % source_repo_path) sys.exit(1) if not os.path.exists(userdir): run_command('mkdir %s' % userdir) print 'Please wait. Cloning /%s to %s' % (source_repo_path, dest_url) run_command('nohup %s init %s' % (HG, dest_dir)) run_command('nohup %s -R %s pull %s/%s' % (HG, dest_dir, DOC_ROOT, source_repo_path)) run_command('nohup %s -R %s replicatesync' % (HG, dest_dir)) # TODO ensure user WSGI files are in place on hgweb machine. # (even better don't rely on per-use WSGI files) print "Clone complete."
def run_repo_push(args): """Run repo-push.sh, signaling mirror-pull on mirrors to do something.""" command = '/usr/bin/sudo -u hg /usr/local/bin/repo-push.sh %s' % args return run_command(command)
def make_repo_clone(cname, repo_name, quick_src, source_repo=''): user = os.getenv('USER') user_repo_dir = user.replace('@', '_') source_repo = '' if quick_src: run_hg_clone(user_repo_dir, repo_name, quick_src) fix_user_repo_perms(repo_name) # New user repositories are non-publishing by default. set_repo_publishing(repo_name, False) sys.exit(0) return print(MAKING_REPO.format(repo=repo_name, user=user, cname=cname, user_dir=user_repo_dir)) selection = prompt_user('Proceed?', ['yes', 'no']) if selection != 'yes': return print 'You can clone an existing public repo or a users private repo.' print 'You can also create an empty repository.' selection = prompt_user('Source repository:', [ 'Clone a public repository', 'Clone a private repository', 'Create an empty repository']) if (selection == 'Clone a public repository'): exec_command = "/usr/bin/find " + DOC_ROOT + " -maxdepth 3 -mindepth 2 -type d -name .hg" args = shlex.split(exec_command) with open(os.devnull, 'wb') as devnull: p = Popen(args, stdout=PIPE, stdin=PIPE, stderr=devnull) repo_list = p.communicate()[0].split("\n") if repo_list: print "We have the repo_list" repo_list = map(lambda x: x.replace(DOC_ROOT + '/', ''), repo_list) repo_list = map(lambda x: x.replace('/.hg', ''), repo_list) repo_list = [x.strip() for x in sorted(repo_list) if x.strip()] print 'List of available public repos' source_repo = prompt_user('Pick a source repo:', repo_list, period=False) elif (selection == 'Clone a private repository'): source_user = raw_input('Please enter the e-mail address of the user ' 'owning the repo: ') valid_user = is_valid_user(source_user) if valid_user == True: source_user = source_user.replace('@', '_') elif valid_user == False: sys.stderr.write('Unknown user.\n') sys.exit(1) elif valid_user == 'Invalid Email Address': sys.stderr.write('Invalid Email Address.\n') sys.exit(1) source_user_path = run_command('find ' + DOC_ROOT + '/users/' + source_user + ' -maxdepth 1 -mindepth 1 -type d') if not source_user_path: print 'That user does not have any private repositories.' print 'Check https://' + cname + '/users for a list of valid users.' sys.exit(1) else: user_repo_list = run_command('find ' + DOC_ROOT + '/users/' + source_user + ' -maxdepth 3 -mindepth 2 -type d -name .hg') user_repo_list = map(lambda x: x.replace(DOC_ROOT + '/users/' + source_user, ''), user_repo_list) user_repo_list = map(lambda x: x.replace('/.hg', ''), user_repo_list) user_repo_list = map(lambda x: x.strip('/'), user_repo_list) user_repo_list = sorted(user_repo_list) print 'Select the users repo you wish to clone.' source_repo = prompt_user('Pick a source repo:', user_repo_list, period=False) source_repo = 'users/' + source_user + '/' + source_repo elif (selection == 'Create an empty repository'): source_repo = '' else: # We should not get here source_repo = '' if source_repo != '': print 'About to clone /%s to /users/%s/%s' % (source_repo, user_repo_dir, repo_name) response = prompt_user('Proceed?', ['yes', 'no']) if (response == 'yes'): print 'Please do not interrupt this operation.' run_hg_clone(user_repo_dir, repo_name, source_repo) else: print "About to create an empty repository at /users/%s/%s" % (user_repo_dir, repo_name) response = prompt_user('Proceed?', ['yes', 'no']) if (response == 'yes'): if not os.path.exists('%s/users/%s' % (DOC_ROOT, user_repo_dir)): try: exec_command = '/bin/mkdir %s/users/%s' % (DOC_ROOT, user_repo_dir) run_command(exec_command) except Exception, e: print "Exception %s" % (e) run_command('/usr/bin/nohup %s --config format.usegeneraldelta=true init %s/users/%s/%s' % (HG, DOC_ROOT, user_repo_dir, repo_name))
def make_repo_clone(cname, repo_name, quick_src, source_repo=''): user = os.getenv('USER') user_repo_dir = user.replace('@', '_') source_repo = '' if quick_src: run_hg_clone(user_repo_dir, repo_name, quick_src) fix_user_repo_perms(repo_name) # New user repositories are non-publishing by default. set_repo_publishing(repo_name, False) sys.exit(0) return print(MAKING_REPO.format(repo=repo_name, user=user, cname=cname, user_dir=user_repo_dir)) selection = prompt_user('Proceed?', ['yes', 'no']) if selection != 'yes': return print 'You can clone an existing public repo or a users private repo.' print 'You can also create an empty repository.' selection = prompt_user('Source repository:', [ 'Clone a public repository', 'Clone a private repository', 'Create an empty repository']) if (selection == 'Clone a public repository'): exec_command = "/usr/bin/find " + DOC_ROOT + " -maxdepth 3 -mindepth 2 -type d -name .hg" args = shlex.split(exec_command) with open(os.devnull, 'wb') as devnull: p = Popen(args, stdout=PIPE, stdin=PIPE, stderr=devnull) repo_list = p.communicate()[0].split("\n") if repo_list: print "We have the repo_list" repo_list = map(lambda x: x.replace(DOC_ROOT + '/', ''), repo_list) repo_list = map(lambda x: x.replace('/.hg', ''), repo_list) repo_list = [x.strip() for x in sorted(repo_list) if x.strip()] print 'List of available public repos' source_repo = prompt_user('Pick a source repo:', repo_list, period=False) elif (selection == 'Clone a private repository'): source_user = raw_input('Please enter the e-mail address of the user ' 'owning the repo: ') valid_user = is_valid_user(source_user) if valid_user == True: source_user = source_user.replace('@', '_') elif valid_user == False: sys.stderr.write('Unknown user.\n') sys.exit(1) elif valid_user == 'Invalid Email Address': sys.stderr.write('Invalid Email Address.\n') sys.exit(1) source_user_path = run_command('find ' + DOC_ROOT + '/users/' + source_user + ' -maxdepth 1 -mindepth 1 -type d') if not source_user_path: print 'That user does not have any private repositories.' print 'Check https://' + cname + '/users for a list of valid users.' sys.exit(1) else: user_repo_list = run_command('find ' + DOC_ROOT + '/users/' + source_user + ' -maxdepth 3 -mindepth 2 -type d -name .hg') user_repo_list = map(lambda x: x.replace(DOC_ROOT + '/users/' + source_user, ''), user_repo_list) user_repo_list = map(lambda x: x.replace('/.hg', ''), user_repo_list) user_repo_list = map(lambda x: x.strip('/'), user_repo_list) user_repo_list = sorted(user_repo_list) print 'Select the users repo you wish to clone.' source_repo = prompt_user('Pick a source repo:', user_repo_list, period=False) source_repo = 'users/' + source_user + '/' + source_repo elif (selection == 'Create an empty repository'): source_repo = '' else: # We should not get here source_repo = '' if source_repo != '': print 'About to clone /%s to /users/%s/%s' % (source_repo, user_repo_dir, repo_name) response = prompt_user('Proceed?', ['yes', 'no']) if (response == 'yes'): print 'Please do not interrupt this operation.' run_hg_clone(user_repo_dir, repo_name, source_repo) else: print "About to create an empty repository at /users/%s/%s" % (user_repo_dir, repo_name) response = prompt_user('Proceed?', ['yes', 'no']) if (response == 'yes'): if not os.path.exists('%s/users/%s' % (DOC_ROOT, user_repo_dir)): try: exec_command = '/bin/mkdir %s/users/%s' % (DOC_ROOT, user_repo_dir) run_command(exec_command) except Exception, e: print "Exception %s" % (e) run_command('/usr/bin/nohup %s init %s/users/%s/%s' % (HG, DOC_ROOT, user_repo_dir, repo_name))
def do_delete(repo_dir, repo_name): repo_path = '%s/users/%s/%s' % (DOC_ROOT, repo_dir, repo_name) run_command('nohup %s -R %s replicatedelete' % (HG, repo_path)) purge_log = open('/tmp/pushlog_purge.%s' % os.getpid(), "a") purge_log.write('echo users/%s/%s\n' % (repo_dir, repo_name)) purge_log.close()
def make_repo_clone (cname, repo_name, quick_src, verbose=False, source_repo=''): global doc_root user = os.getenv ('USER') user_repo_dir = user.replace ('@', '_') dest_url = "/users/%s" % user_repo_dir source_repo = '' if quick_src: if(user in verbose_users): verbose=True run_hg_clone (cname, user_repo_dir, repo_name, quick_src, True) else: run_hg_clone (cname, user_repo_dir, repo_name, quick_src) fix_user_repo_perms (cname, repo_name) sys.exit(0) else: #make_wsgi_dir(cname, user_repo_dir) print "Making repo %s for %s." % (repo_name, user) print "This repo will appear as %s/users/%s/%s." % (cname, user_repo_dir, repo_name) print 'If you need a top level repo, please quit now and file a bug for IT to create one for you.' selection = prompt_user ('Proceed?', ['yes', 'no']) if (selection == 'yes'): print 'You can clone an existing public repo or a users private repo.' print 'You can also create an empty repository.' selection = prompt_user ('Source repository:', ['Clone a public repository', 'Clone a private repository', 'Create an empty repository']) if (selection == 'Clone a public repository'): exec_command = "/usr/bin/find " + doc_root[cname] + " -maxdepth 3 -mindepth 2 -type d -name .hg" args = shlex.split(exec_command) #repo_list = run_command (exec_command) p = Popen(args, stdout=PIPE, stdin=PIPE, stderr=STDOUT) repo_list = p.communicate()[0].split("\n") if repo_list: print "We have the repo_list" repo_list = map (lambda x: x.replace (doc_root[cname] + '/', ''), repo_list) repo_list = map (lambda x: x.replace ('/.hg', ''), repo_list) print 'List of available public repos' source_repo = prompt_user ('Pick a source repo:', repo_list) elif (selection == 'Clone a private repository'): source_user = raw_input ('Please enter the e-mail address of the user owning the repo: ') valid_user = is_valid_user(source_user) if valid_user == True: source_user = source_user.replace ('@', '_') elif valid_user == False: sys.stderr.write ('Unknown user.\n') sys.exit (1) elif valid_user == 'Invalid Email Address': sys.stderr.write ('Invalid Email Address.\n') sys.exit (1) source_user_path = run_command ('find ' + doc_root[cname] + '/users/' + source_user + ' -maxdepth 1 -mindepth 1 -type d') if not source_user_path: print 'That user does not have any private repositories.' print 'Check https://' + cname + '/users for a list of valid users.' sys.exit (1) else: user_repo_list = run_command ('find ' + doc_root[cname] + '/users/' + source_user + ' -maxdepth 3 -mindepth 2 -type d -name .hg') user_repo_list = map (lambda x: x.replace (doc_root[cname] + '/users/' + source_user, ''), user_repo_list) user_repo_list = map (lambda x: x.replace ('/.hg', ''), user_repo_list) user_repo_list = map (lambda x: x.strip ('/'), user_repo_list) print 'Select the users repo you wish to clone.' source_repo = prompt_user ('Pick a source repo:', user_repo_list) source_repo = 'users/' + source_user + '/' + source_repo elif (selection == 'Create an empty repository'): source_repo='' else: # We should not get here source_repo='' if source_repo != '': print 'About to clone /%s to /users/%s/%s' % (source_repo, user_repo_dir, repo_name) response = prompt_user ('Proceed?', ['yes', 'no']) if (response == 'yes'): print 'Please do not interrupt this operation.' run_hg_clone (cname, user_repo_dir, repo_name, source_repo) else: print "About to create an empty repository at /users/%s/%s" % (user_repo_dir, repo_name) response = prompt_user ('Proceed?', ['yes', 'no']) if (response == 'yes'): if not os.path.exists ('%s/users/%s' % (doc_root[cname], user_repo_dir)): try: exec_command = '/bin/mkdir %s/users/%s' % (doc_root[cname], user_repo_dir) run_command (exec_command) except Exception, e: print "Exception %s" % (e) run_command ('/usr/bin/nohup /usr/bin/hg init %s/users/%s/%s' % (doc_root[cname], user_repo_dir, repo_name)) fix_user_repo_perms (cname, repo_name) sys.exit (0)
def fix_user_repo_perms (cname, repo_name): global doc_root user = os.getenv ('USER') user_repo_dir = user.replace ('@', '_') print "Fixing permissions, don't interrupt." try: run_command ('chown %s:scm_level_1 %s/users/%s' % (user, doc_root[cname], user_repo_dir)) run_command ('chmod g+w %s/users/%s' % (doc_root[cname], user_repo_dir)) run_command ('chmod g+s %s/users/%s' % (doc_root[cname], user_repo_dir)) run_command ('chown -R %s:scm_level_1 %s/users/%s/%s' % (user, doc_root[cname], user_repo_dir, repo_name)) run_command ('chmod -R g+w %s/users/%s/%s' % (doc_root[cname], user_repo_dir, repo_name)) run_command ('find %s/users/%s/%s -depth -type d | xargs chmod g+s' % (doc_root[cname], user_repo_dir, repo_name)) except Exception, e: print "Exception %s" % (e)