X-Git-Url: https://scripts.mit.edu/gitweb/wizard.git/blobdiff_plain/40de76124826c6f24a11c0a7d752e37a7af977d9..193c996c0df943f6bd955bdb475548b04ec9e711:/lib/wizard/command/migrate.py diff --git a/lib/wizard/command/migrate.py b/lib/wizard/command/migrate.py index f626322..dbf93d3 100644 --- a/lib/wizard/command/migrate.py +++ b/lib/wizard/command/migrate.py @@ -1,26 +1,157 @@ import optparse import sys +import os +import shutil +import logging.handlers +from wizard import * import wizard.deploy as wd +import wizard.shell as sh -def main(argv, global_options): +class PermissionsError(UserException): + def __init__(self, dir): + self.dir = dir + def __str__(self): + return """ + +ERROR: You don't have permissions to access this directory. +Do you have tickets for AFS with your root instance, and +is your root instance on scripts-security-upd? + +You can check by running the commands 'klist' and +'blanche scripts-security-upd'. We recommend getting +root tickets using Nelson Elhage's krbroot script +at /mit/nelhage/Public/krbroot (for which you run +'krbroot shell' and then 'aklog'). +""" + +class NoSuchDirectoryError(UserException): + def __init__(self, dir): + self.dir = dir + def __str__(self): + return """ + +ERROR: No such directory... check your typing +""" + +class AlreadyMigratedError(UserException): + def __init__(self, dir): + self.dir = dir + def __str__(self): + return """ + +ERROR: Directory already contains a .git directory. +Did you already migrate it? +""" + +class NotAutoinstallError(UserException): + def __init__(self, dir): + self.dir = dir + def __str__(self): + return """ + +ERROR: Could not find .scripts-version file. Are you sure +this is an autoinstalled application? +""" + +class NoRepositoryError(UserException): + def __init__(self, app): + self.app = app + def __str__(self): + return """ + +ERROR: Could not find repository for this application. Have +you converted the repository over? Is the name %s +the same as the name of the .git folder? +""" % self.app + +class NoTagError(UserException): + def __init__(self, version): + self.version = version + def __str__(self): + return """ + +ERROR: Could not find tag v%s-scripts in repository +for %s. Double check and make sure +the repository was prepared with all necessary tags! +""" % (self.version.version, self.version.application.name) + +def migrate(argv, global_options, logger = None): usage = """usage: %prog migrate [ARGS] DIR Migrates a directory to our Git-based autoinstall format. Performs basic sanity checking and intelligently determines -what repository and tag to use. - -NOTICE: Currently doesn't do anything.""" - parser = optparse.OptionParser(usage) - parser.add_option("-v", "--verbose", dest="verbose", action="store_true", - default=False, help="Print all commands and outputs") +what repository and tag to use.""" + parser = WizardOptionParser(usage) parser.add_option("--dry-run", dest="dry_run", action="store_true", default=False, help="Prints would would be run without changing anything") - options, args = parser.parse_args(argv) + options, args, logger = parser.parse_all(argv, logger) if len(args) > 1: parser.error("too many arguments") elif not args: parser.error("must specify directory") dir = args[0] - print dir - print options + try: + os.chdir(dir) + except OSError as e: + if e.errno == 13: + raise PermissionsError(dir) + elif e.errno == 2: + raise NoSuchDirectoryError(dir) + else: raise e + if os.path.isdir(".git"): + raise AlreadyMigratedError(dir) + try: + deploy = wd.Deployment.fromDir(".") + version = deploy.getAppVersion() + except IOError as e: + if e.errno == 2: + raise NotAutoinstallError(dir) + else: raise e + # calculate the repository we'll be pulling out of + application = version.application + app = application.name + repo = os.path.join("/afs/athena.mit.edu/contrib/scripts/wizard/srv", app + ".git") + if not os.path.isdir(repo): + raise NoRepositoryError(app) + # begin the command line process + shell = sh.Shell(logger, options.dry_run) + # check if the version we're trying to convert exists. We assume + # a convention here, namely, v1.2.3-scripts is what we want. If + # you broke the convention... shame on you. + try: + tag = "v%s-scripts" % version.version + shell.call("git", "--git-dir", repo, "rev-parse", tag) + except sh.CalledProcessError: + raise NoTagError(version) + did_git_init = False + did_git_checkout_scripts = False + try: + # create repository + shell.call("git", "init") + did_git_init = True + # configure our remote + shell.call("git", "remote", "add", "origin", repo) + # configure what would normally be set up on a 'git clone' for consistency + shell.call("git", "config", "branch.master.remote", "origin") + shell.call("git", "config", "branch.master.merge", "refs/heads/master") + # perform the initial fetch + shell.call("git", "fetch", "origin") + # soft reset to our tag + shell.call("git", "reset", tag) + # checkout the .scripts directory + shell.call("git", "checkout", ".scripts") + did_git_checkout_scripts = True + # XXX: setup .scripts/version??? + # for verbose purposes, give us a git status and git diff + raise NotImplementedError + if options.verbose: + shell.call("git", "status") + shell.call("git", "diff") + except: + logger.error("ERROR: Exception detected! Rolling back...") + if did_git_init: + shell.call("rm", "-Rf", ".git") + if did_git_checkout_scripts: + shell.call("rm", "-Rf", ".scripts") + raise