bootstrap-vz/bootstrapvz/remote/main.py

115 lines
4.1 KiB
Python
Raw Normal View History

2014-11-25 21:12:37 +01:00
"""Main module containing all the setup necessary for running the remote bootstrapping process
"""
2014-11-25 20:14:56 +01:00
def main():
"""Main function for invoking the bootstrap process remotely
"""
# Get the commandline arguments
opts = get_opts()
2014-11-30 15:54:31 +01:00
from bootstrapvz.common.tools import load_data
# load the manifest data, we might want to modify it later on
manifest_data = load_data(opts['MANIFEST'])
2014-11-25 20:14:56 +01:00
2014-11-30 15:42:38 +01:00
# load the build servers file
2014-11-25 20:14:56 +01:00
build_servers = load_data(opts['--servers'])
2014-11-30 15:42:38 +01:00
# Pick a build server
from build_servers import pick_build_server
preferences = {}
if opts['--name'] is not None:
preferences['name'] = opts['--name']
if opts['--release'] is not None:
preferences['release'] = opts['--release']
2014-11-30 15:54:31 +01:00
build_server = pick_build_server(build_servers, manifest_data, preferences)
# Apply the build server settings to the manifest (e.g. the virtualbox guest additions path)
manifest_data = build_server.apply_build_settings(manifest_data)
# Load the manifest
from bootstrapvz.base.manifest import Manifest
manifest = Manifest(path=opts['MANIFEST'], data=manifest_data)
2014-11-25 20:14:56 +01:00
# Set up logging
from bootstrapvz.base.main import setup_loggers
setup_loggers(opts)
2014-11-25 21:12:37 +01:00
# Register deserialization handlers for objects
# that will pass between server and client
2014-11-25 20:14:56 +01:00
from . import register_deserialization_handlers
register_deserialization_handlers()
2014-11-25 21:12:37 +01:00
# Everything has been set up, connect to the server and begin the bootstrapping process
run(manifest,
2014-11-30 15:42:38 +01:00
build_server,
2014-11-25 21:12:37 +01:00
debug=opts['--debug'],
dry_run=opts['--dry-run'])
def get_opts():
"""Creates an argument parser and returns the arguments it has parsed
"""
from docopt import docopt
usage = """bootstrap-vz-remote
2014-11-30 15:42:38 +01:00
Usage: bootstrap-vz-remote [options] --servers=<path> MANIFEST
2014-11-25 21:12:37 +01:00
Options:
2014-11-30 15:42:38 +01:00
--servers <path> Path to list of build servers
--name <name> Selects specific server from the build servers list
--release <release> Require the build server OS to be a specific release
--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
2014-11-30 14:13:43 +01:00
--color=auto|always|never
Colorize the console output [default: auto]
2014-11-30 15:42:38 +01:00
--debug Print debugging information
-h, --help show this help
2014-11-25 21:12:37 +01:00
"""
return docopt(usage)
2014-11-30 15:42:38 +01:00
def run(manifest, build_server, debug=False, dry_run=False):
2014-11-25 21:12:37 +01:00
"""Connects to the remote build server, starts an RPC daemin
on the other side and initiates a remote bootstrapping procedure
"""
2014-11-25 20:14:56 +01:00
bootstrap_info = None
try:
2014-11-30 15:42:38 +01:00
# Connect to the build server
connection = build_server.connect()
2014-11-25 21:12:37 +01:00
# Start a callback server on this side, so that we may receive log entries
2014-11-25 20:14:56 +01:00
from callback import CallbackServer
2014-11-30 15:42:38 +01:00
callback_server = CallbackServer(listen_port=build_server.local_callback_port,
remote_port=build_server.remote_callback_port)
2014-11-25 20:14:56 +01:00
try:
2014-11-25 21:12:37 +01:00
# Start the callback server (in a background thread)
2014-11-30 19:16:27 +01:00
callback_server.start()
2014-11-25 21:12:37 +01:00
# Tell the RPC daemon about the callback server
2014-11-30 19:16:27 +01:00
connection.set_callback_server(callback_server)
2014-11-25 20:14:56 +01:00
2014-11-30 19:19:14 +01:00
# Replace the standard SIGINT handler with a remote call to the server
# so that it may abort the run.
def abort(signum, frame):
import logging
logging.getLogger(__name__).warn('SIGINT received, asking remote to abort.')
callback_server.abort_run()
import signal
orig_sigint = signal.signal(signal.SIGINT, abort)
2014-11-25 20:14:56 +01:00
# Everything has been set up, begin the bootstrapping process
2014-11-30 15:42:38 +01:00
bootstrap_info = connection.run(manifest,
debug=debug,
# We can't pause the bootstrapping process remotely, yet...
pause_on_error=False,
dry_run=dry_run)
2014-11-30 19:19:14 +01:00
# Restore the old SIGINT handler
signal.signal(signal.SIGINT, orig_sigint)
2014-11-25 20:14:56 +01:00
finally:
2014-11-25 21:12:37 +01:00
# Stop the callback server
2014-11-25 20:14:56 +01:00
callback_server.stop()
finally:
2014-11-25 21:12:37 +01:00
# Stop the RPC daemon and close the SSH connection
2014-11-30 15:42:38 +01:00
build_server.disconnect()
2014-11-25 20:14:56 +01:00
return bootstrap_info