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