bootstrap-vz/bootstrapvz/base/main.py

112 lines
3.8 KiB
Python
Raw Normal View History

2014-03-23 16:04:03 +01:00
"""Main module containing all the setup necessary for running the bootstrapping process
"""
import logging
log = logging.getLogger(__name__)
2013-05-16 08:00:28 +02:00
def main():
2014-03-23 16:04:03 +01:00
"""Main function for invoking the bootstrap process
:raises Exception: When the invoking user is not root and --dry-run isn't specified
2014-03-23 16:04:03 +01:00
"""
# Get the commandline arguments
opts = get_opts()
# Require root privileges, except when doing a dry-run where they aren't needed
2014-04-07 21:46:46 +02:00
import os
if os.geteuid() != 0 and not opts['--dry-run']:
raise Exception('This program requires root privileges.')
import log
# Log to file unless --log is a single dash
if opts['--log'] != '-':
# Setup logging
if not os.path.exists(opts['--log']):
os.makedirs(opts['--log'])
log_filename = log.get_log_filename(opts['MANIFEST'])
logfile = os.path.join(opts['--log'], log_filename)
else:
logfile = None
log.setup_logger(logfile=logfile, debug=opts['--debug'])
2014-03-23 16:04:03 +01:00
# Everything has been set up, begin the bootstrapping process
run(opts)
2013-06-09 20:29:54 +02:00
2013-06-26 20:14:37 +02:00
def get_opts():
2014-03-23 16:04:03 +01:00
"""Creates an argument parser and returns the arguments it has parsed
"""
from docopt import docopt
usage = """bootstrap-vz
Usage: bootstrap-vz [options] MANIFEST
Options:
--log <path> Log to given directory [default: /var/log/bootstrap-vz]
If <path> is `-' file logging will be disabled.
--pause-on-error Pause on error, before rollback
--dry-run Don't actually run the tasks
--debug Print debugging information
-h, --help show this help
"""
opts = docopt(usage)
return opts
def run(opts):
2014-03-23 16:04:03 +01:00
"""Runs the bootstrapping process
:params dict opts: Dictionary of options from the commandline
2014-03-23 16:04:03 +01:00
"""
# Load the manifest
from manifest import Manifest
manifest = Manifest(opts['MANIFEST'])
2013-05-16 08:00:28 +02:00
2014-03-23 16:04:03 +01:00
# Get the tasklist
from tasklist import load_tasks
2013-06-09 16:23:08 +02:00
from tasklist import TaskList
tasks = load_tasks('resolve_tasks', manifest)
tasklist = TaskList(tasks)
2014-03-23 16:04:03 +01:00
# 'resolve_tasks' is the name of the function to call on the provider and plugins
2013-05-16 08:00:28 +02:00
2014-03-23 16:04:03 +01:00
# Create the bootstrap information object that'll be used throughout the bootstrapping process
2013-06-09 16:15:23 +02:00
from bootstrapinfo import BootstrapInformation
bootstrap_info = BootstrapInformation(manifest=manifest, debug=opts['--debug'])
try:
2014-03-23 16:04:03 +01:00
# Run all the tasks the tasklist has gathered
tasklist.run(info=bootstrap_info, dry_run=opts['--dry-run'])
2014-03-23 16:04:03 +01:00
# We're done! :-)
log.info('Successfully completed bootstrapping')
return bootstrap_info
2013-06-30 20:06:49 +02:00
except (Exception, KeyboardInterrupt) as e:
2014-03-23 16:04:03 +01:00
# When an error occurs, log it and begin rollback
log.exception(e)
if opts['--pause-on-error']:
2014-03-23 16:04:03 +01:00
# The --pause-on-error is useful when the user wants to inspect the volume before rollback
raw_input('Press Enter to commence rollback')
log.error('Rolling back')
2014-03-23 16:04:03 +01:00
# Create a useful little function for the provider and plugins to use,
# when figuring out what tasks should be added to the rollback list.
def counter_task(taskset, task, counter):
2014-03-23 16:04:03 +01:00
"""counter_task() adds the second argument to the rollback tasklist
if the first argument is present in the list of completed tasks
:param set taskset: The taskset to add the rollback task to
:param Task task: The task to look for in the completed tasks list
:param Task counter: The task to add to the rollback tasklist
2014-03-23 16:04:03 +01:00
"""
if task in tasklist.tasks_completed and counter not in tasklist.tasks_completed:
taskset.add(counter)
2014-03-23 16:04:03 +01:00
# Ask the provider and plugins for tasks they'd like to add to the rollback tasklist
# Any additional arguments beyond the first two are passed directly to the provider and plugins
rollback_tasks = load_tasks('resolve_rollback_tasks', manifest, tasklist.tasks_completed, counter_task)
rollback_tasklist = TaskList(rollback_tasks)
2014-03-23 16:04:03 +01:00
# Run the rollback tasklist
rollback_tasklist.run(info=bootstrap_info, dry_run=opts['--dry-run'])
log.info('Successfully completed rollback')
raise e