installs
- Push su code to migrate, not mass-migrate (only do it
as root, this serves as a safe guard)
-- Rename massmigrate to mass-migrate
- Move migration code into Wizard, since we already deal
with installation there anyway (this TODO has been updated
accordingly)
- Make parallel-find.pl use `sudo -u username git describe --tags`
to determine version
- Remove .scripts/version generation in install script
-- Make the installer use 'wizard install'
+- Make the installer use 'wizard install' /or/ do a migration
+ after doing a normal install (the latter makes it easier
+ for mass-rollbacks).
- Better error message if daemon/scripts-security-upd
is not on scripts-security-upd list
this runs the risk of filling up the tubes. Maybe just
create a log directory and give each process different
files.
-- Remove log functionality; we don't care about it besides
- for parsing old style installs
- The great initial deploy:
- Turn on mediawiki new autoinstaller
Its commands are:
configure Configures an autoinstall (database, etc) to work
errors Lists all broken autoinstall metadata
- info Reports information about an autoinstall
install Installs an application
list Lists autoinstalls, with optional filtering
- massmigrate Performs mass migration of autoinstalls of an application
+ mass-migrate Performs mass migration of autoinstalls of an application
migrate Migrate autoinstalls from old format to Git-based format
prepare-config Prepares configuration files for versioning
summary Generate statistics (see help for subcommands)
+++ /dev/null
-import optparse
-import sys
-import subprocess
-
-from wizard import deploy, log
-
-def main(argv, baton):
- options, args = parse_args(argv)
- d = deploy.Deployment(args[0])
- d.log # force the log to be loaded, to pre-empt errors
- with PipeToLess():
- print_log(d, options)
-
-def parse_args(argv):
- usage = """usage: %prog info [ARGS] DIR
-
-Prints information about an autoinstalled directory,
-including its history and current version."""
- parser = optparse.OptionParser(usage)
- parser.add_option("--reverse", dest="reverse", action="store_true",
- default=False, help="Print entries in chronological order (default is reverse)")
- options, args = parser.parse_args(argv)
- if len(args) > 1:
- parser.error("too many arguments")
- elif not args:
- parser.error("must specify directory")
- return options, args
-
-def print_log(d, options):
- if options.reverse:
- dlog = reversed(d.log)
- else:
- dlog = d.log
- for entry in dlog:
- print "%s %s" % (entry.version.application.name, entry.version.version)
- print "User: %s" % entry.user
- print "Date: %s" % entry.datetime.strftime("%a %b %0d %H:%M:%S %Y %z")
- print
- info = "Unknown"
- if isinstance(entry.source, log.TarballInstall):
- info = "Installed with tarball at:\n%s" % \
- prettify(entry.source.location)
- print indent(info, 4)
- print
-
-class PipeToLess(object):
- def __enter__(self):
- self.proc = subprocess.Popen("less", stdin=subprocess.PIPE)
- self.old_stdout = sys.stdout
- sys.stdout = self.proc.stdin
- def __exit__(self, *args):
- if self.proc:
- self.proc.stdin.close()
- self.proc.wait()
- sys.stdout = self.old_stdout
-
-def prettify(loc):
- return loc.replace("/afs/athena.mit.edu/contrib/scripts", "~scripts")
-
-def indent(text, indent):
- # There should be a built-in
- return "\n".join([" " * indent + x for x in text.split("\n")])
logging.warning("%s from %d installs" % (name, len(deploys)))
def parse_args(argv, baton):
- usage = """usage: %prog massmigrate [ARGS] APPLICATION
+ usage = """usage: %prog mass-migrate [ARGS] APPLICATION
Mass migrates an application to the new repository format.
Essentially equivalent to running '%prog migrate' on all
but with advanced reporting.
When doing an actual run, it is recommended to use --seen to
-be able to resume gracefully (without it, massmigrate must
+be able to resume gracefully (without it, mass-migrate must
stat every install to find out if it migrated it yet).
This command is intended to be run as root on a server with
import logging
import wizard
-from wizard import git, log, util
+from wizard import git, old_log, util
## -- Global Functions --
self._app_version = version
# some cache variables
self._read_cache = {}
- self._log = None
+ self._old_log = None
def read(self, file, force = False):
"""
Reads a file's contents, possibly from cache unless ``force``
"""The :class:`Application` of this deployment."""
return self.app_version.application
@property
- def log(self):
- """The :class:`wizard.deploy.Log` of this deployment."""
- if not self._log:
- self._log = log.DeployLog.load(self)
- return self._log
+ def old_log(self):
+ """
+ The :class:`wizard.old_log.Log` of this deployment. This
+ is only applicable to un-migrated autoinstalls.
+ """
+ if not self._old_log:
+ self._old_log = old_log.DeployLog.load(self)
+ return self._old_log
@property
def version(self):
"""
appname, _, version = git.describe().partition('-')
self._app_version = ApplicationVersion.make(appname, version)
else:
- self._app_version = self.log[-1].version
+ self._app_version = self.old_log[-1].version
return self._app_version
@staticmethod
def parse(line):
super(ParallelShell, self).__init__(dry=dry)
self.running = {}
self.max = max # maximum of commands to run in parallel
- def _async(self, proc, args, python, on_success, on_error):
+ def _async(self, proc, args, python, on_success, on_error, **kwargs):
"""
Gets handed a :class:`subprocess.Proc` object from our deferred
execution. See :meth:`Shell.call` source code for details.
def __iter__(self):
return self.dict.__iter__()
+class PipeToLess(object):
+ """
+ Context for printing output to a pager. Use this if output
+ is expected to be long.
+ """
+ def __enter__(self):
+ self.proc = subprocess.Popen("less", stdin=subprocess.PIPE)
+ self.old_stdout = sys.stdout
+ sys.stdout = self.proc.stdin
+ def __exit__(self, *args):
+ if self.proc:
+ self.proc.stdin.close()
+ self.proc.wait()
+ sys.stdout = self.old_stdout
+
def dictmap(f, d):
"""
A map function for dictionaries. Only changes values.