def setCommitEmailHook(reponame, enable): prepare(reponame) reposdir = repository.directory('git', reponame) hook_dir = reposdir + 'hooks' + 'post-receive.d' mkdirs(hook_dir) hook_dest = hook_dir + '001-commit-email.hook' if enable: variables = { 'submin_lib_dir': options.lib_path(), 'base_url': options.url_path('base_url_submin'), 'http_vhost': options.http_vhost(), 'hook_version': HOOK_VERSIONS['commit-email'], } hook = evaluate('plugins/vcs/git/post-receive', variables) try: os.unlink(hook_dest) except OSError as e: if e.errno != errno.ENOENT: raise try: with file(hook_dest, 'w') as f: f.write(hook) os.chmod(hook_dest, 0o755) except OSError as e: raise repository.PermissionError("Enabling hook failed: %s" % (str(e), )) try: cfg = repository.directory('git', reponame) + 'config' email = options.value( 'commit_email_from', 'Please configure commit_email_from <*****@*****.**>') set_git_config(cfg, 'multimailhook.emailmaxlines', '2000') prefix = '[%s]' % reponame set_git_config(cfg, 'multimailhook.emailprefix', prefix) set_git_config(cfg, 'multimailhook.envelopesender', email) except SetGitConfigError as e: raise repository.PermissionError( "Enabling hook succeeded, but configuring it failed: %s" % (str(e))) else: try: os.unlink(hook_dest) except OSError as e: if e.errno != errno.ENOENT: raise repository.PermissionError("Removing hook failed: %s" % (str(e), ))
def setCommitEmailHook(reponame, enable): prepare(reponame) reposdir = repository.directory('git', reponame) hook_dir = reposdir + 'hooks' + 'post-receive.d' mkdirs(hook_dir) hook_dest = hook_dir + '001-commit-email.hook' if enable: variables = { 'submin_lib_dir': options.lib_path(), 'base_url': options.url_path('base_url_submin'), 'http_vhost': options.http_vhost(), 'hook_version': HOOK_VERSIONS['commit-email'], } hook = evaluate('plugins/vcs/git/post-receive', variables) try: os.unlink(hook_dest) except OSError as e: if e.errno != errno.ENOENT: raise try: with file(hook_dest, 'w') as f: f.write(hook) os.chmod(hook_dest, 0o755) except OSError as e: raise repository.PermissionError( "Enabling hook failed: %s" % (str(e),)) try: cfg = repository.directory('git', reponame) + 'config' email = options.value('commit_email_from', 'Please configure commit_email_from <*****@*****.**>') set_git_config(cfg, 'multimailhook.emailmaxlines', '2000') prefix = '[%s]' % reponame set_git_config(cfg, 'multimailhook.emailprefix', prefix) set_git_config(cfg, 'multimailhook.envelopesender', email) except SetGitConfigError as e: raise repository.PermissionError( "Enabling hook succeeded, but configuring it failed: %s" % (str(e))) else: try: os.unlink(hook_dest) except OSError as e: if e.errno != errno.ENOENT: raise repository.PermissionError( "Removing hook failed: %s" % (str(e),))
def setTracSyncHook(reponame, enable): prepare(reponame) hook_dir = repository.directory('git', reponame) + 'hooks' hook = hook_dir + 'post-receive.d' + '002-trac-sync.hook' try: os.unlink(hook) except OSError as e: if e.errno != errno.ENOENT: raise repository.PermissionError( "Removing trac-sync hook failed: %s" % (str(e), )) if not enable: return variables = { 'submin_env': str(options.env_path()), 'repository': reponame, 'hook_version': HOOK_VERSIONS['trac-sync'], } contents = evaluate('plugins/vcs/git/trac-sync', variables) with file(hook, 'w') as f: f.writelines(contents) os.chmod(hook, 0o755)
def setTracSyncHook(reponame, enable): prepare(reponame) hook_dir = repository.directory('git', reponame) + 'hooks' hook = hook_dir + 'post-receive.d' + '002-trac-sync.hook' try: os.unlink(hook) except OSError as e: if e.errno != errno.ENOENT: raise repository.PermissionError( "Removing trac-sync hook failed: %s" % (str(e),)) if not enable: return variables = { 'submin_env': str(options.env_path()), 'repository': reponame, 'hook_version': HOOK_VERSIONS['trac-sync'], } contents = evaluate('plugins/vcs/git/trac-sync', variables) with file(hook, 'w') as f: f.writelines(contents) os.chmod(hook, 0o755)
def prepare(reponame): """Make sure basic things are in place for post-receive scripts to work. The post-receive hook calls hook-mux, which multiplexes everything on standard input to multiple scripts found in the post-recieve.d directory. This makes it possible to have multiple (post-receive) hooks. """ hook_dir = repository.directory('git', reponame) + 'hooks' # Make sure multiplexer script is in place. It should be a shell script # that calls the actual real script. The old situation is that the # post-receive script was actually a script to call only git-multimail.py. # The reason why we have a call to the script instead of a symlink, is # because we can not guarantee the executable bit of the target. if not shellscript.hasSignature(hook_dir + 'post-receive', signature): rewrite_hook(reponame, 'post-receive', 'hook-mux', interpreter='/bin/bash', args='post-receive') # make sure multiplexer dir exists # because www user can check if files in this directory exists, but # we can't chgrp() the dir, we set the mode explicitly to 0755. The # parent dir is only open to git user and www group, with mode 0750. mkdirs(hook_dir + 'post-receive.d', mode=0o755)
def rewrite_hook(reponame, hookname, targetname, interpreter='/usr/bin/python', args='"$@"'): if reponame: repositories = [reponame] else: repositories = [x['name'] for x in repository.Repository.list_all() if x['vcs'] == 'git'] for reponame in repositories: reposdir = repository.directory('git', reponame) backup_old_hook(reposdir, hookname) enable_hook(reposdir, hookname, targetname, interpreter, args)
def run(username): if "SSH_ORIGINAL_COMMAND" not in os.environ: print ("No command provided. " \ + "Expected something like git-receive-pack", file=sys.stderr) sys.exit(1) orig_cmd = os.environ["SSH_ORIGINAL_COMMAND"] if not orig_cmd.startswith("git") or orig_cmd[3] not in (' ', '-'): print ("Not a git-command. Expected something like " \ + "git-receive-pack",file=sys.stderr) sys.exit(1) # command is something like `git-receive-pack repo.git' # or `git receive-pack repo.git' cmd, repo = orig_cmd.split(" ", 1) if repo[0] == repo[-1] == "'": repo = repo[1:-1] # git 1.5 adds a slash? if repo[0] == '/': repo = repo[1:] repo = repo[:-4] # remove '.git' sub_cmd = cmd[4:] u = user.User(username) readable_paths = permissions.list_readable_user_paths(repo, "git", u) if not readable_paths: print("Permission denied for %s to user %s" % (repo, u), file=sys.stderr) sys.exit(1) if sub_cmd not in WRITE_CMDS + READ_CMDS: print("Unrecognized command:", cmd, file=sys.stderr) sys.exit(1) elif sub_cmd in WRITE_CMDS: # check if we have write access writeable_paths = permissions.list_writeable_user_paths(repo, "git", u) if not writeable_paths: print ("Permission denied for writing, for %s to user %s" % \ (repo, u),file=sys.stderr) sys.exit(1) # To pass on to the git-hook os.environ["SUBMIN_USERNAME"] = username os.environ["SUBMIN_REPO"] = repo repo_path = repository.directory('git', repo) print("Original command: %s" % orig_cmd, file=sys.stderr) print("executing git-%s '%s'" % (sub_cmd, repo_path), file=sys.stderr) # XXX: retreive git-path from options. os.execvp('git', ['git', 'shell', '-c', "git-%s '%s'" % (sub_cmd, repo_path)])
def run(reposname): reposdir = repository.directory('git', reposname) old_path = os.environ["PATH"] os.environ["PATH"] = options.value("env_path") cmd = 'rm -rf "%s"' % str(reposdir) (exitstatus, outtext) = commands.getstatusoutput(cmd) os.environ["PATH"] = old_path if exitstatus != 0: raise PermissionError( "External command '%s' failed: %s" % \ (cmd, outtext))
def run(reponame): reposdir = repository.directory("git", reponame) old_path = os.environ["PATH"] os.environ["PATH"] = options.value("env_path") cmd = 'GIT_DIR="%s" git --bare init' % str(reposdir) (exitstatus, outtext) = commands.getstatusoutput(cmd) os.environ["PATH"] = old_path rewrite_hooks(reponame) post_receive_hook.rewrite_hooks(reponame) if exitstatus != 0: raise PermissionError("External command 'GIT_DIR=\"%s\" git --bare init' failed: %s" % (name, outtext))
def run(reponame): reposdir = repository.directory('git', reponame) old_path = os.environ["PATH"] os.environ["PATH"] = options.value("env_path") cmd = 'GIT_DIR="%s" git --bare init' % str(reposdir) (exitstatus, outtext) = commands.getstatusoutput(cmd) os.environ["PATH"] = old_path rewrite_hooks(reponame) post_receive_hook.rewrite_hooks(reponame) if exitstatus != 0: raise PermissionError( "External command 'GIT_DIR=\"%s\" git --bare init' failed: %s" % \ (name, outtext))
def rewrite_hook(reponame, hookname, targetname, interpreter='/usr/bin/python', args='"$@"'): if reponame: repositories = [reponame] else: repositories = [ x['name'] for x in repository.Repository.list_all() if x['vcs'] == 'git' ] for reponame in repositories: reposdir = repository.directory('git', reponame) backup_old_hook(reposdir, hookname) enable_hook(reposdir, hookname, targetname, interpreter, args)
def run(username): if "SSH_ORIGINAL_COMMAND" not in os.environ: print >>sys.stderr, "No command provided. " + "Expected something like git-receive-pack" sys.exit(1) orig_cmd = os.environ["SSH_ORIGINAL_COMMAND"] if not orig_cmd.startswith("git") or orig_cmd[3] not in (" ", "-"): print >>sys.stderr, "Not a git-command. Expected something like " + "git-receive-pack" sys.exit(1) # command is something like `git-receive-pack repo.git' # or `git receive-pack repo.git' cmd, repo = orig_cmd.split(" ", 1) if repo[0] == repo[-1] == "'": repo = repo[1:-1] # git 1.5 adds a slash? if repo[0] == "/": repo = repo[1:] repo = repo[:-4] # remove '.git' sub_cmd = cmd[4:] u = user.User(username) readable_paths = permissions.list_readable_user_paths(repo, "git", u) if not readable_paths: print >>sys.stderr, "Permission denied for %s to user %s" % (repo, u) sys.exit(1) if sub_cmd not in WRITE_CMDS + READ_CMDS: print >>sys.stderr, "Unrecognized command:", cmd sys.exit(1) elif sub_cmd in WRITE_CMDS: # check if we have write access writeable_paths = permissions.list_writeable_user_paths(repo, "git", u) if not writeable_paths: print >>sys.stderr, "Permission denied for writing, for %s to user %s" % (repo, u) sys.exit(1) # To pass on to the git-hook os.environ["SUBMIN_USERNAME"] = username os.environ["SUBMIN_REPO"] = repo repo_path = repository.directory("git", repo) print >>sys.stderr, "Original command: %s" % orig_cmd print >>sys.stderr, "executing git-%s '%s'" % (sub_cmd, repo_path) # XXX: retreive git-path from options. os.execvp("git", ["git", "shell", "-c", "git-%s '%s'" % (sub_cmd, repo_path)])
def handle_trac_sync(self, path): if len(path) != 2: return {'errormsgs': ['wrong path']} self.vcs_type, self.repo = path errormsgs = [] # migration from inconsistent usage of extension if self.repo.endswith('.git'): self.repo = self.repo[:-4] errormsgs.append( 'Please let the submin administrator know to run diagnostics') self.env_copy = os.environ.copy() self.env_copy['PATH'] = options.value('env_path', '/bin:/usr/bin') trac_dir = options.env_path('trac_dir') repo_dir = repository.directory(self.vcs_type, self.repo) self.trac_env = trac_dir + self.repo oldwd = os.getcwd() try: os.chdir(repo_dir) except OSError as e: return { 'errormsgs': [ 'Directory does not exist', str(e), 'Please check Submin diagnostics' ], 'success': False } for jobid, lines in jobs(self.vcs_type, self.repo, 'trac-sync'): job_succeeded = True errormsg = self.job_sync(jobid, lines) if len(errormsg) == 0: job_done(jobid) else: errormsgs.append(errormsg) os.chdir(oldwd) return {'errormsgs': errormsgs, 'success': True}
def update_notification(reposname, user_notifications): emails = [] for u_n in user_notifications: u, u_notif = u_n if reposname in u_notif: if u_notif[reposname]['enabled']: email = "%s <%s>" % (u.fullname, u.email) emails.append(email) # make unique emails = set(emails) # set git config cfg = repository.directory('git', reposname) + 'config' if len(emails) > 0: val = ','.join(emails) else: val = None set_git_config(cfg, 'multimailhook.mailinglist', val)
def handle_trac_sync(self, path): if len(path) != 2: return {'errormsgs': ['wrong path']} self.vcs_type, self.repo = path errormsgs = [] # migration from inconsistent usage of extension if self.repo.endswith('.git'): self.repo = self.repo[:-4] errormsgs.append( 'Please let the submin administrator know to run diagnostics') self.env_copy = os.environ.copy() self.env_copy['PATH'] = options.value('env_path', '/bin:/usr/bin') trac_dir = options.env_path('trac_dir') repo_dir = repository.directory(self.vcs_type, self.repo) self.trac_env = trac_dir + self.repo oldwd = os.getcwd() try: os.chdir(repo_dir) except OSError as e: return {'errormsgs': ['Directory does not exist', str(e), 'Please check Submin diagnostics'], 'success': False} for jobid, lines in jobs(self.vcs_type, self.repo, 'trac-sync'): job_succeeded = True errormsg = self.job_sync(jobid, lines) if len(errormsg) == 0: job_done(jobid) else: errormsgs.append(errormsg) os.chdir(oldwd) return {'errormsgs': errormsgs, 'success': True}