--- /dev/null
+import optparse
+import os
+
+import wizard
+from wizard import deploy
+from wizard import util
+from wizard import shell
+from wizard.command import _base
+from wizard.command import migrate
+
+def main(argv, global_options, logger = None):
+ usage = """usage: %prog massmigrate [ARGS] APPLICATION
+
+Mass migrates an application to the new repository format.
+Essentially equivalent to running '%prog migrate' on all
+autoinstalls for a particular application found by parallel-find,
+but with advanced reporting.
+"""
+ parser = _base.WizardOptionParser(usage)
+ parser.add_option("--no-parallelize", dest="no_parallelize", action="store_true",
+ default=False, help="Turn off parallelization")
+ parser.add_option("--dry-run", dest="dry_run", action="store_true",
+ default=False, help="Print commands that would be run. Implies --no-parallelize")
+ parser.add_option("--max", dest="max",
+ default=10, help="Maximum subprocesses to run concurrently")
+ options, args, logger = parser.parse_all(argv, logger)
+ if len(args) > 1:
+ parser.error("too many arguments")
+ elif not args:
+ parser.error("must specify application to migrate")
+ if options.verbose or options.dry_run:
+ options.no_parallelize = True
+ app = args[0]
+ errors = {}
+ base_args = _base.makeBaseArgs(options, dry_run="--dry-run")
+ # check if we have root
+ uid = os.getuid()
+ user = None
+ # dry run is purposely omitted
+ if options.no_parallelize:
+ sh = shell.DummyParallelShell(logger=logger)
+ else:
+ sh = shell.ParallelShell(logger=logger, max=int(options.max))
+ for line in deploy.getInstallLines(global_options):
+ # validate and filter the deployments
+ try:
+ d = deploy.Deployment.parse(line)
+ except deploy.DeploymentParseError, deploy.NoSuchApplication:
+ continue
+ name = d.getApplication().name
+ if name != app: continue
+ # actual meat
+ def on_success(stdout, stderr): pass # yay! don't do anything
+ def make_on_error(d): # make it early binding
+ def on_error(e):
+ if e.name == "wizard.command.migrate.AlreadyMigratedError":
+ logger.info("Skipped already migrated %s" % d.location)
+ else:
+ name = e.name
+ if name not in errors: errors[name] = []
+ errors[name].append(d)
+ logger.error("ERROR [%s] in %s" % (name, d.location))
+ return on_error
+ on_error = make_on_error(d)
+ sh.wait() # wait for a parallel processing slot to be available
+ sh.callAsUser(shell.wizard, "migrate", d.location, *base_args,
+ user=user, on_success=on_success, on_error=on_error)
+ sh.join()
+ for name, deploys in errors.items():
+ logger.warning("ERROR [%s] from %d installs" % (name, len(deploys)))