diff --git a/bootstrapvz/base/main.py b/bootstrapvz/base/main.py index 80a4c4d..882ac5f 100644 --- a/bootstrapvz/base/main.py +++ b/bootstrapvz/base/main.py @@ -20,8 +20,12 @@ def main(): # Set up logging setup_loggers(opts) + # Load the manifest + from manifest import Manifest + manifest = Manifest(path=opts['MANIFEST']) + # Everything has been set up, begin the bootstrapping process - run(opts['MANIFEST'], + run(manifest, debug=opts['--debug'], pause_on_error=opts['--pause-on-error'], dry_run=opts['--dry-run']) @@ -68,15 +72,11 @@ def setup_loggers(opts): root.addHandler(console_handler) -def run(manifest_path, debug=False, pause_on_error=False, dry_run=False): +def run(manifest, debug=False, pause_on_error=False, dry_run=False): """Runs the bootstrapping process :params dict opts: Dictionary of options from the commandline """ - # Load the manifest - from manifest import Manifest - manifest = Manifest(manifest_path) - # Get the tasklist from tasklist import load_tasks from tasklist import TaskList diff --git a/bootstrapvz/base/manifest.py b/bootstrapvz/base/manifest.py index 8151bdd..969dfbf 100644 --- a/bootstrapvz/base/manifest.py +++ b/bootstrapvz/base/manifest.py @@ -2,6 +2,7 @@ to determine which tasks should be added to the tasklist, what arguments various invocations should have etc.. """ +from bootstrapvz.common.exceptions import ManifestError from bootstrapvz.common.tools import load_data import logging log = logging.getLogger(__name__) @@ -14,32 +15,44 @@ class Manifest(object): Currently, immutability is not enforced and it would require a fair amount of code to enforce it, instead we just rely on tasks behaving properly. """ - def __init__(self, path): + 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 + :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.load() + self.load(data) + self.initialize() self.validate() self.parse() - def load(self): + def load(self, data=None): """Loads the manifest and performs a basic validation. - This function reads the manifest, loads the specified provider and plugins, and performs - some basic validation of the manifest itself to ensure that the properties - required for initalization are accessible + 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). - Once the provider and plugins are loaded, - the initialize() function is called on each of them (if it exists). - The provider must have an initialize function. """ - self.data = load_data(self.path) + 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) + def initialize(self): + """Initializes the provider and the plugins. + This function loads the specified provider and plugins. + Once the provider and plugins are loaded, + the initialize() function is called on each of them (if it exists). + The provider must have an initialize function. + """ # Get the provider name from the manifest and load the corresponding module provider_modname = 'bootstrapvz.providers.' + self.data['provider']['name'] log.debug('Loading provider ' + provider_modname) @@ -116,5 +129,4 @@ class Manifest(object): :param list data_path: A path to the location in the manifest where the error occurred :raises ManifestError: With absolute certainty """ - from bootstrapvz.common.exceptions import ManifestError raise ManifestError(message, self.path, data_path) diff --git a/tests/integration/manifests_tests.py b/tests/integration/manifests_tests.py index 74a89d7..fd2b4b6 100644 --- a/tests/integration/manifests_tests.py +++ b/tests/integration/manifests_tests.py @@ -29,7 +29,7 @@ def validate_manifests(path): and checks that all the data values have successfully been created. """ - manifest = Manifest(path) + manifest = Manifest(path=path) assert_true(manifest.data) assert_true(manifest.data['provider'])