Exemple #1
0
def boot_manifest(manifest_data, boot_vars={}):
    from bootstrapvz.common.tools import load_data
    build_servers = load_data('build-servers.yml')
    from bootstrapvz.remote.build_servers import pick_build_server
    build_server = pick_build_server(build_servers, manifest_data)

    manifest_data = build_server.apply_build_settings(manifest_data)
    from bootstrapvz.base.manifest import Manifest
    manifest = Manifest(data=manifest_data)

    import importlib
    provider_module = importlib.import_module('tests.system.providers.' +
                                              manifest.provider['name'])

    prepare_bootstrap = getattr(provider_module, 'prepare_bootstrap', noop)
    with prepare_bootstrap(manifest, build_server):
        bootstrap_info = None
        log.info('Connecting to build server')
        with build_server.connect() as connection:
            log.info('Building manifest')
            bootstrap_info = connection.run(manifest)

        log.info('Creating and booting instance')
        with provider_module.boot_image(manifest, build_server, bootstrap_info,
                                        **boot_vars) as instance:
            yield instance
Exemple #2
0
def pick_build_server(build_servers, manifest, preferences={}):
    # Validate the build servers list
    from bootstrapvz.common.tools import load_data, rel_path

    schema = load_data(rel_path(__file__, 'build-servers-schema.yml'))
    import jsonschema
    jsonschema.validate(build_servers, schema)

    if manifest['provider']['name'] == 'ec2':
        must_bootstrap = 'ec2-' + manifest['volume']['backing']
    else:
        must_bootstrap = manifest['provider']['name']

    def matches(name, settings):
        if preferences.get('name', name) != name:
            return False
        if preferences.get('release', settings['release']) != settings['release']:
            return False
        if must_bootstrap not in settings['can_bootstrap']:
            return False
        return True

    for name, settings in build_servers.iteritems():
        if not matches(name, settings):
            continue
        if settings['type'] == 'local':  # pylint: disable=no-else-return
            from .local import LocalBuildServer
            return LocalBuildServer(name, settings)
        else:
            from .remote import RemoteBuildServer
            return RemoteBuildServer(name, settings)

    raise Exception('Unable to find a build server that matches your preferences.')
def pick_build_server(build_servers, manifest, preferences={}):
	# Validate the build servers list
	from bootstrapvz.common.tools import load_data
	import os.path
	schema = load_data(os.path.normpath(os.path.join(os.path.dirname(__file__), 'build-servers-schema.yml')))
	import jsonschema
	jsonschema.validate(build_servers, schema)

	if manifest['provider']['name'] == 'ec2':
		must_bootstrap = 'ec2-' + manifest['volume']['backing']
	else:
		must_bootstrap = manifest['provider']['name']

	def matches(name, settings):
		if preferences.get('name', name) != name:
			return False
		if preferences.get('release', settings['release']) != settings['release']:
			return False
		if must_bootstrap not in settings['can_bootstrap']:
			return False
		return True

	for name, settings in build_servers.iteritems():
		if not matches(name, settings):
			continue
		if settings['type'] == 'local':
			from local import LocalBuildServer
			return LocalBuildServer(name, settings)
		else:
			from remote import RemoteBuildServer
			return RemoteBuildServer(name, settings)
	raise Exception('Unable to find a build server that matches your preferences.')
Exemple #4
0
def main():
    """Main function for invoking the bootstrap process remotely
	"""
    # Get the commandline arguments
    opts = get_opts()

    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'])

    # load the build servers file
    build_servers = load_data(opts['--servers'])
    # 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']
    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)

    # Set up logging
    from bootstrapvz.base.main import setup_loggers
    setup_loggers(opts)

    # Register deserialization handlers for objects
    # that will pass between server and client
    from . import register_deserialization_handlers
    register_deserialization_handlers()

    # Everything has been set up, connect to the server and begin the bootstrapping process
    with build_server.connect() as connection:
        connection.run(manifest,
                       debug=opts['--debug'],
                       dry_run=opts['--dry-run'])
Exemple #5
0
def main():
    """Main function for invoking the bootstrap process remotely
    """
    # Get the commandline arguments
    opts = get_opts()

    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'])

    # load the build servers file
    build_servers = load_data(opts['--servers'])
    # 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']
    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)

    # Set up logging
    from bootstrapvz.base.main import setup_loggers
    setup_loggers(opts)

    # Register deserialization handlers for objects
    # that will pass between server and client
    from . import register_deserialization_handlers
    register_deserialization_handlers()

    # Everything has been set up, connect to the server and begin the bootstrapping process
    with build_server.connect() as connection:
        connection.run(manifest,
                       debug=opts['--debug'],
                       dry_run=opts['--dry-run'])
Exemple #6
0
	def load_data(self, data=None):
		"""Loads the manifest and performs a basic validation.
		This function reads the manifest and performs some basic validation of
		the manifest itself to ensure that the properties required for initalization are accessible
		(otherwise the user would be presented with some cryptic error messages).
		"""
		if data is None:
			self.data = load_data(self.path)
		else:
			self.data = data

		from . import validate_manifest
		# Validate the manifest with the base validation function in __init__
		validate_manifest(self.data, self.schema_validator, self.validation_error)
Exemple #7
0
	def schema_validator(self, data, schema_path):
		"""This convenience function is passed around to all the validation functions
		so that they may run a json-schema validation by giving it the data and a path to the schema.

		:param dict data: Data to validate (normally the manifest data)
		:param str schema_path: Path to the json-schema to use for validation
		"""
		import jsonschema

		schema = load_data(schema_path)
		try:
			jsonschema.validate(data, schema)
		except jsonschema.ValidationError as e:
			self.validation_error(e.message, e.path)
Exemple #8
0
    def schema_validator(self, data, schema_path):
        """This convenience function is passed around to all the validation functions
		so that they may run a json-schema validation by giving it the data and a path to the schema.

		:param dict data: Data to validate (normally the manifest data)
		:param str schema_path: Path to the json-schema to use for validation
		"""
        import jsonschema

        schema = load_data(schema_path)
        try:
            jsonschema.validate(data, schema)
        except jsonschema.ValidationError as e:
            self.validation_error(e.message, e.path)
Exemple #9
0
    def load_data(self, data=None):
        """Loads the manifest and performs a basic validation.
        This function reads the manifest and performs some basic validation of
        the manifest itself to ensure that the properties required for initalization are accessible
        (otherwise the user would be presented with some cryptic error messages).
        """
        if data is None:
            self.data = load_data(self.path)
        else:
            self.data = data

        from . import validate_manifest
        # Validate the manifest with the base validation function in __init__
        validate_manifest(self.data, self.schema_validator, self.validation_error)
Exemple #10
0
    def __init__(self, path=None, data=None):
        """Initializer: Given a path we load, validate and parse the manifest.
        To create the manifest from dynamic data instead of the contents of a file,
        provide a properly constructed dict as the data argument.

        :param str path: The path to the manifest (ignored, when `data' is provided)
        :param str data: The manifest data, if it is not None, it will be used instead of the contents of `path'
        """
        if path is None and data is None:
            raise ManifestError('`path\' or `data\' must be provided')
        self.path = path

        self.metaschema = load_data(rel_path(__file__, 'metaschema.json'))

        self.load_data(data)
        self.load_modules()
        self.validate()
        self.parse()
Exemple #11
0
def boot_manifest(manifest_data, boot_vars={}):
	from bootstrapvz.common.tools import load_data
	build_servers = load_data('build-servers.yml')
	from bootstrapvz.remote.build_servers import pick_build_server
	build_server = pick_build_server(build_servers, manifest_data)

	manifest_data = build_server.apply_build_settings(manifest_data)
	from bootstrapvz.base.manifest import Manifest
	manifest = Manifest(data=manifest_data)

	import importlib
	provider_module = importlib.import_module('tests.integration.providers.' + manifest.provider['name'])

	prepare_bootstrap = getattr(provider_module, 'prepare_bootstrap', noop)
	with prepare_bootstrap(manifest, build_server):
		bootstrap_info = None
		log.info('Connecting to build server')
		with build_server.connect() as connection:
			log.info('Building manifest')
			bootstrap_info = connection.run(manifest)

		log.info('Creating and booting instance')
		with provider_module.boot_image(manifest, build_server, bootstrap_info, **boot_vars) as instance:
			yield instance
import os.path
import glob
import random
import string
from bootstrapvz.common.tools import load_data

partial_json = glob.glob(os.path.join(os.path.dirname(__file__), '*.yml'))
partial_yaml = glob.glob(os.path.join(os.path.dirname(__file__), '*.json'))

partials = {}
for path in partial_json + partial_yaml:
    key = os.path.splitext(os.path.basename(path))[0]
    if key in partials:
        msg = 'Error when loading partial manifests: The partial {key} exists twice'.format(key=key)
        raise Exception(msg)
    partials[key] = load_data(path)

pool = string.ascii_uppercase + string.ascii_lowercase + string.digits
random_password = ''.join(random.choice(pool) for _ in range(16))
partials['root_password']['plugins']['root_password']['password'] = random_password


def merge_manifest_data(standard_partials=[], custom=[]):
    import yaml
    manifest_data = [partials[name] for name in standard_partials]
    manifest_data.extend(yaml.load(data) for data in custom)
    return merge_dicts(*manifest_data)


# Snatched from here: http://stackoverflow.com/a/7205107
def merge_dicts(*args):
Exemple #13
0
import os.path
import glob
import random
import string
from bootstrapvz.common.tools import load_data

partial_json = glob.glob(os.path.join(os.path.dirname(__file__), '*.yml'))
partial_yaml = glob.glob(os.path.join(os.path.dirname(__file__), '*.json'))

partials = {}
for path in partial_json + partial_yaml:
	key = os.path.splitext(os.path.basename(path))[0]
	if key in partials:
		msg = 'Error when loading partial manifests: The partial {key} exists twice'.format(key=key)
		raise Exception(msg)
	partials[key] = load_data(path)

pool = string.ascii_uppercase + string.ascii_lowercase + string.digits
random_password = ''.join(random.choice(pool) for _ in range(16))
partials['root_password']['plugins']['root_password']['password'] = random_password


def merge_manifest_data(standard_partials=[], custom=[]):
	import yaml
	manifest_data = [partials[name] for name in standard_partials]
	manifest_data.extend(yaml.load(data) for data in custom)
	return merge_dicts(*manifest_data)


# Snatched from here: http://stackoverflow.com/a/7205107
def merge_dicts(*args):