X-Git-Url: https://scripts.mit.edu/gitweb/wizard.git/blobdiff_plain/3f3c8a7ec822d73f7af28b6b7ef94f3476863527..43b45d678fe3d445b0ba6b32ef5605f215cd7d10:/lib/wizard/command/migrate.py diff --git a/lib/wizard/command/migrate.py b/lib/wizard/command/migrate.py index fcf1247..056d448 100644 --- a/lib/wizard/command/migrate.py +++ b/lib/wizard/command/migrate.py @@ -2,72 +2,130 @@ 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) + parser.add_option("--force", "-f", dest="force", action="store_true", + default=False, help="If .git or .scripts directory already exists, delete them and migrate") + 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 "Changing working directory to autoinstall directory" try: os.chdir(dir) except OSError as e: if e.errno == 13: - print - print "ERROR: You don't have permissions to access this directory." - print "Do you have tickets for AFS with your root instance, and" - print "is your root instance on scripts-security-upd?" - print - print "You can check by running the commands 'klist' and" - print "'blanche scripts-security-upd'. We recommend getting" - print "root tickets using Nelson Elhage's krbroot script" - print "at /mit/nelhage/Public/krbroot (for which you run" - print "'krbroot shell' and then 'aklog')." - raise SystemExit(-1) + raise PermissionsError(dir) elif e.errno == 2: - print - print "ERROR: No such directory... check your typing" - raise SystemExit(-1) + raise NoSuchDirectoryError(dir) else: raise e + if os.path.isdir(".git") or os.path.isdir(".scripts"): + if not options.force: + raise AlreadyMigratedError(dir) + else: + if os.path.isdir(".git"): + logger.warning("Force removing .git directory") + if not options.dry_run: shutil.rmtree(".git") + if os.path.isdir(".scripts"): + logger.warning("Force removing .scripts directory") + if not options.dry_run: shutil.rmtree(".scripts") try: deploy = wd.Deployment.fromDir(".") version = deploy.getAppVersion() except IOError as e: if e.errno == 2: - print - print "ERROR: Could not find .scripts-version file. Are you sure" - print "this is an autoinstalled application?" - raise SystemExit(-1) + 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): - print - print "ERROR: Could not find repository for this application. Have" - print "you converted the repository over? Is the name %s" % app - print "the same as the the name of the foo.git folder?" - raise SystemExit(-1) + raise NoRepositoryError(app) # begin the command line process - shell = sh.Shell(options.verbose, options.dry_run) + 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. @@ -75,16 +133,12 @@ NOTICE: Currently doesn't do anything.""" tag = "v%s-scripts" % version.version shell.call("git", "--git-dir", repo, "rev-parse", tag) except sh.CalledProcessError: - print - print "ERROR: Could not find tag v%s-scripts for" % version.version - print "this application's version. Double check and make sure" - print "the repository was prepared with all necessary tags!" - raise SystemExit(-1) + raise NoTagError(version) did_git_init = False did_git_checkout_scripts = False try: # create repository - shell.call("git", "init") + shell.call("git", "--git-dir=.git", "init") did_git_init = True # configure our remote shell.call("git", "remote", "add", "origin", repo) @@ -94,21 +148,20 @@ NOTICE: Currently doesn't do anything.""" # perform the initial fetch shell.call("git", "fetch", "origin") # soft reset to our tag - shell.call("git", "reset", 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 - shell.call("git", "status") - shell.call("git", "diff") + if options.verbose: + shell.call("git", "status") + shell.call("git", "diff") except: - print - print "ERROR: Exception detected! Rolling back..." + # this... is pretty bad + logger.critical("ERROR: Exception detected! Rolling back...") if did_git_init: - print "Deleting .git directory" shell.call("rm", "-Rf", ".git") if did_git_checkout_scripts: - print "Deleting .scripts directory" shell.call("rm", "-Rf", ".scripts") raise