From 4112e572aadbbc552749398010257be3a3ba802b Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Fri, 14 Aug 2015 13:09:57 +0200 Subject: Add a restore command to the SSH interface Implement a new command that can be used to restore deleted package bases without having to push a new commit. Signed-off-by: Lukas Fleischer --- conf/config.proto | 1 + doc/git-interface.txt | 1 + git-interface/git-serve.py | 19 +++++++++++++++++++ git-interface/git-update.py | 21 ++++++++++++--------- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/conf/config.proto b/conf/config.proto index 52da7967..2c798b74 100644 --- a/conf/config.proto +++ b/conf/config.proto @@ -51,6 +51,7 @@ ssh-options = no-port-forwarding,no-X11-forwarding,no-pty repo-path = /srv/http/aurweb/aur.git/ repo-regex = [a-z0-9][a-z0-9.+_-]*$ git-shell-cmd = /usr/bin/git-shell +git-update-cmd = /srv/http/aurweb/git-interface/git-update.py ssh-cmdline = ssh aur@aur.archlinux.org [aurblup] diff --git a/doc/git-interface.txt b/doc/git-interface.txt index b34e112e..9ded20f6 100644 --- a/doc/git-interface.txt +++ b/doc/git-interface.txt @@ -44,6 +44,7 @@ The git-serve command, the "aurweb shell", provides different subcommands: * The help command shows a list of available commands. * The list-repos command lists all repositories of the authenticated user. * The setup-repo command can be used to create a new repository. +* The restore command can be used to restore a deleted package base. * The git-{receive,upload}-pack commands are redirected to git-shell(1). The requested command is extracted from the SSH_ORIGINAL_COMMAND environment diff --git a/git-interface/git-serve.py b/git-interface/git-serve.py index 8316cf7d..45c9a01b 100755 --- a/git-interface/git-serve.py +++ b/git-interface/git-serve.py @@ -19,6 +19,7 @@ aur_db_socket = config.get('database', 'socket') repo_path = config.get('serve', 'repo-path') repo_regex = config.get('serve', 'repo-regex') git_shell_cmd = config.get('serve', 'git-shell-cmd') +git_update_cmd = config.get('serve', 'git-update-cmd') ssh_cmdline = config.get('serve', 'ssh-cmdline') enable_maintenance = config.getboolean('options', 'enable-maintenance') @@ -152,10 +153,28 @@ elif action == 'setup-repo': if len(cmdargv) > 2: die_with_help("{:s}: too many arguments".format(action)) create_pkgbase(cmdargv[1], user) +elif action == 'restore': + if len(cmdargv) < 2: + die_with_help("{:s}: missing repository name".format(action)) + if len(cmdargv) > 2: + die_with_help("{:s}: too many arguments".format(action)) + + pkgbase = cmdargv[1] + if not re.match(repo_regex, pkgbase): + die('{:s}: invalid repository name: {:s}'.format(action, pkgbase)) + + if pkgbase_exists(pkgbase): + die('{:s}: package base exists: {:s}'.format(action, pkgbase)) + create_pkgbase(pkgbase, user) + + os.environ["AUR_USER"] = user + os.environ["AUR_PKGBASE"] = pkgbase + os.execl(git_update_cmd, git_update_cmd, 'restore') elif action == 'help': die("Commands:\n" + " help Show this help message and exit.\n" + " list-repos List all your repositories.\n" + + " restore Restore a deleted package base.\n" + " setup-repo Create an empty repository.\n" + " git-receive-pack Internal command used with Git.\n" + " git-upload-pack Internal command used with Git.") diff --git a/git-interface/git-update.py b/git-interface/git-update.py index d2583859..5ff8b285 100755 --- a/git-interface/git-update.py +++ b/git-interface/git-update.py @@ -176,22 +176,25 @@ def die_commit(msg, commit): sys.stderr.write("error: {:s}\n".format(msg)) exit(1) -if len(sys.argv) != 4: - die("invalid arguments") - -refname = sys.argv[1] -sha1_old = sys.argv[2] -sha1_new = sys.argv[3] +repo = pygit2.Repository(repo_path) user = os.environ.get("AUR_USER") pkgbase = os.environ.get("AUR_PKGBASE") privileged = (os.environ.get("AUR_PRIVILEGED", '0') == '1') +if len(sys.argv) == 2 and sys.argv[1] == "restore": + if 'refs/heads/' + pkgbase not in repo.listall_references(): + die('{:s}: repository not found: {:s}'.format(sys.argv[1], pkgbase)) + refname = "refs/heads/master" + sha1_old = sha1_new = repo.lookup_reference('refs/heads/' + pkgbase).target +elif len(sys.argv) == 4: + refname, sha1_old, sha1_new = sys.argv[1:3] +else: + die("invalid arguments") + if refname != "refs/heads/master": die("pushing to a branch other than master is restricted") -repo = pygit2.Repository(repo_path) - db = mysql.connector.connect(host=aur_db_host, user=aur_db_user, passwd=aur_db_pass, db=aur_db_name, unix_socket=aur_db_socket, buffered=True) @@ -291,7 +294,7 @@ if srcinfo_pkgbase != pkgbase: # Ensure that packages are neither blacklisted nor overwritten. cur.execute("SELECT ID FROM PackageBases WHERE Name = %s", [pkgbase]) -pkgbase_id = cur.fetchone()[0] +pkgbase_id = cur.fetchone()[0] if cur.rowcount == 1 else 0 cur.execute("SELECT Name FROM PackageBlacklist") blacklist = [row[0] for row in cur.fetchall()] -- cgit v1.2.3-24-g4f1b