mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 07:26:29 +00:00
Switch to docopt for options parsing
Add option to not log to any file.
This commit is contained in:
parent
c154347849
commit
2017806d1f
3 changed files with 49 additions and 47 deletions
|
@ -5,19 +5,6 @@ both to a file and to the console.
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
def create_log_dir():
|
|
||||||
"""Creates the log directory
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str. The path to the logdirectory
|
|
||||||
"""
|
|
||||||
log_dir_path = '/var/log/bootstrap-vz'
|
|
||||||
import os
|
|
||||||
if not os.path.exists(log_dir_path):
|
|
||||||
os.makedirs(log_dir_path)
|
|
||||||
return log_dir_path
|
|
||||||
|
|
||||||
|
|
||||||
def get_log_filename(manifest_path):
|
def get_log_filename(manifest_path):
|
||||||
"""Returns the path to a logfile given a manifest
|
"""Returns the path to a logfile given a manifest
|
||||||
The logfile name is constructed from the current timestamp and the basename of the manifest
|
The logfile name is constructed from the current timestamp and the basename of the manifest
|
||||||
|
@ -49,14 +36,16 @@ def setup_logger(logfile=None, debug=False):
|
||||||
# Make sure all logging statements are processed by our handlers, they decide the log level
|
# Make sure all logging statements are processed by our handlers, they decide the log level
|
||||||
root.setLevel(logging.NOTSET)
|
root.setLevel(logging.NOTSET)
|
||||||
|
|
||||||
# Create a file log handler
|
# Only enable logging to file if a destination was supplied
|
||||||
file_handler = logging.FileHandler(logfile)
|
if logfile is not None:
|
||||||
# Absolute timestamps are rather useless when bootstrapping, it's much more interesting
|
# Create a file log handler
|
||||||
# to see how long things take, so we log in a relative format instead
|
file_handler = logging.FileHandler(logfile)
|
||||||
file_handler.setFormatter(FileFormatter('[%(relativeCreated)s] %(levelname)s: %(message)s'))
|
# Absolute timestamps are rather useless when bootstrapping, it's much more interesting
|
||||||
# The file log handler always logs everything
|
# to see how long things take, so we log in a relative format instead
|
||||||
file_handler.setLevel(logging.DEBUG)
|
file_handler.setFormatter(FileFormatter('[%(relativeCreated)s] %(levelname)s: %(message)s'))
|
||||||
root.addHandler(file_handler)
|
# The file log handler always logs everything
|
||||||
|
file_handler.setLevel(logging.DEBUG)
|
||||||
|
root.addHandler(file_handler)
|
||||||
|
|
||||||
# Create a console log handler
|
# Create a console log handler
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -13,45 +13,57 @@ def main():
|
||||||
Exception
|
Exception
|
||||||
"""
|
"""
|
||||||
# Get the commandline arguments
|
# Get the commandline arguments
|
||||||
args = get_args()
|
opts = get_opts()
|
||||||
# Require root privileges, except when doing a dry-run where they aren't needed
|
# Require root privileges, except when doing a dry-run where they aren't needed
|
||||||
import os
|
import os
|
||||||
if os.geteuid() != 0 and not args.dry_run:
|
if os.geteuid() != 0 and not opts['--dry-run']:
|
||||||
raise Exception('This program requires root privileges.')
|
raise Exception('This program requires root privileges.')
|
||||||
# Setup logging
|
|
||||||
import log
|
import log
|
||||||
log_dir = log.create_log_dir()
|
# Log to file unless --log is a single dash
|
||||||
log_filename = log.get_log_filename(args.manifest)
|
if opts['--log'] != '-':
|
||||||
logfile = os.path.join(log_dir, log_filename)
|
# Setup logging
|
||||||
log.setup_logger(logfile=logfile, debug=args.debug)
|
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'])
|
||||||
|
|
||||||
# Everything has been set up, begin the bootstrapping process
|
# Everything has been set up, begin the bootstrapping process
|
||||||
run(args)
|
run(opts)
|
||||||
|
|
||||||
|
|
||||||
def get_args():
|
def get_opts():
|
||||||
"""Creates an argument parser and returns the arguments it has parsed
|
"""Creates an argument parser and returns the arguments it has parsed
|
||||||
"""
|
"""
|
||||||
from argparse import ArgumentParser
|
from docopt import docopt
|
||||||
parser = ArgumentParser(description='Bootstrap Debian for the cloud.')
|
usage = """bootstrap-vz
|
||||||
parser.add_argument('--debug', action='store_true',
|
|
||||||
help='Print debugging information')
|
Usage: bootstrap-vz [options] MANIFEST
|
||||||
parser.add_argument('--pause-on-error', action='store_true',
|
|
||||||
help='Pause on error, before rollback')
|
Options:
|
||||||
parser.add_argument('--dry-run', action='store_true',
|
--log <path> Log to given directory [default: /var/log/bootstrap-vz]
|
||||||
help='Dont\'t actually run the tasks')
|
If <path> is `-' file logging will be disabled.
|
||||||
parser.add_argument('manifest', help='Manifest file to use for bootstrapping', metavar='MANIFEST')
|
--pause-on-error Pause on error, before rollback
|
||||||
return parser.parse_args()
|
--dry-run Don't actually run the tasks
|
||||||
|
--debug Print debugging information
|
||||||
|
-h, --help show this help
|
||||||
|
"""
|
||||||
|
opts = docopt(usage)
|
||||||
|
return opts
|
||||||
|
|
||||||
|
|
||||||
def run(args):
|
def run(opts):
|
||||||
"""Runs the bootstrapping process
|
"""Runs the bootstrapping process
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
args (dict): Dictionary of arguments from the commandline
|
opts (dict): Dictionary of options from the commandline
|
||||||
"""
|
"""
|
||||||
# Load the manifest
|
# Load the manifest
|
||||||
from manifest import Manifest
|
from manifest import Manifest
|
||||||
manifest = Manifest(args.manifest)
|
manifest = Manifest(opts['MANIFEST'])
|
||||||
|
|
||||||
# Get the tasklist
|
# Get the tasklist
|
||||||
from tasklist import TaskList
|
from tasklist import TaskList
|
||||||
|
@ -61,17 +73,17 @@ def run(args):
|
||||||
|
|
||||||
# Create the bootstrap information object that'll be used throughout the bootstrapping process
|
# Create the bootstrap information object that'll be used throughout the bootstrapping process
|
||||||
from bootstrapinfo import BootstrapInformation
|
from bootstrapinfo import BootstrapInformation
|
||||||
bootstrap_info = BootstrapInformation(manifest=manifest, debug=args.debug)
|
bootstrap_info = BootstrapInformation(manifest=manifest, debug=opts['--debug'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Run all the tasks the tasklist has gathered
|
# Run all the tasks the tasklist has gathered
|
||||||
tasklist.run(info=bootstrap_info, dry_run=args.dry_run)
|
tasklist.run(info=bootstrap_info, dry_run=opts['--dry-run'])
|
||||||
# We're done! :-)
|
# We're done! :-)
|
||||||
log.info('Successfully completed bootstrapping')
|
log.info('Successfully completed bootstrapping')
|
||||||
except (Exception, KeyboardInterrupt) as e:
|
except (Exception, KeyboardInterrupt) as e:
|
||||||
# When an error occurs, log it and begin rollback
|
# When an error occurs, log it and begin rollback
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
if args.pause_on_error:
|
if opts['--pause-on-error']:
|
||||||
# The --pause-on-error is useful when the user wants to inspect the volume before rollback
|
# The --pause-on-error is useful when the user wants to inspect the volume before rollback
|
||||||
raw_input('Press Enter to commence rollback')
|
raw_input('Press Enter to commence rollback')
|
||||||
log.error('Rolling back')
|
log.error('Rolling back')
|
||||||
|
@ -96,6 +108,6 @@ def run(args):
|
||||||
rollback_tasklist.load('resolve_rollback_tasks', manifest, counter_task)
|
rollback_tasklist.load('resolve_rollback_tasks', manifest, counter_task)
|
||||||
|
|
||||||
# Run the rollback tasklist
|
# Run the rollback tasklist
|
||||||
rollback_tasklist.run(info=bootstrap_info, dry_run=args.dry_run)
|
rollback_tasklist.run(info=bootstrap_info, dry_run=opts['--dry-run'])
|
||||||
log.info('Successfully completed rollback')
|
log.info('Successfully completed rollback')
|
||||||
raise e
|
raise e
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -20,6 +20,7 @@ setup(name='bootstrap-vz',
|
||||||
'fysom >= 1.0.15',
|
'fysom >= 1.0.15',
|
||||||
'jsonschema >= 2.3.0',
|
'jsonschema >= 2.3.0',
|
||||||
'pyyaml >= 3.10',
|
'pyyaml >= 3.10',
|
||||||
|
'docopt >= 0.6.1',
|
||||||
],
|
],
|
||||||
license='Apache License, Version 2.0',
|
license='Apache License, Version 2.0',
|
||||||
description='Bootstrap Debian images for virtualized environments',
|
description='Bootstrap Debian images for virtualized environments',
|
||||||
|
|
Loading…
Add table
Reference in a new issue