Fix bug with task list generation

Only tasks from the loaded provider and plugins were
considered, when creating the task graph.
This was a problem with the prebootstrapped plugin
specifically, which could be used with both ec2 and
vbox.
Fixed the problem by loading all known plugins and
providers and adding them to the taskgraph, nothing
less will do.
This commit is contained in:
Anders Ingemann 2016-06-05 11:41:18 +02:00
parent 4031fd6f84
commit e030b9f84f

View file

@ -23,9 +23,10 @@ class TaskList(object):
""" """
# Get a hold of every task we can find, so that we can topologically sort # Get a hold of every task we can find, so that we can topologically sort
# all tasks, rather than just the subset we are going to run. # all tasks, rather than just the subset we are going to run.
from bootstrapvz.common import tasks as common_tasks # We pass in the modules which the manifest has already loaded in order
modules = [common_tasks, info.manifest.modules['provider']] + info.manifest.modules['plugins'] # to support third-party plugins, which are not in the bootstrapvz package
all_tasks = set(get_all_tasks(modules)) # and therefore wouldn't be discovered.
all_tasks = set(get_all_tasks([info.manifest.modules['provider']] + info.manifest.modules['plugins']))
# Create a list for us to run # Create a list for us to run
task_list = create_list(self.tasks, all_tasks) task_list = create_list(self.tasks, all_tasks)
# Output the tasklist # Output the tasklist
@ -118,18 +119,39 @@ def create_list(taskset, all_tasks):
return sorted_tasks return sorted_tasks
def get_all_tasks(modules): def get_all_tasks(loaded_modules):
"""Gets a list of all task classes in the package """Gets a list of all task classes in the package
:return: A list of all tasks in the package :return: A list of all tasks in the package
:rtype: list :rtype: list
""" """
import pkgutil
import os.path import os.path
# Get generators that return all classes in a module import bootstrapvz
generators = [] bootstrapvz_root = os.path.dirname(bootstrapvz.__file__)
for module in modules: module_paths = set([(os.path.join(bootstrapvz_root, 'common/tasks'), 'bootstrapvz.common.tasks.')])
for module in loaded_modules:
module_path = os.path.dirname(module.__file__) module_path = os.path.dirname(module.__file__)
module_prefix = module.__name__ + '.' module_prefix = module.__name__ + '.'
module_paths.add((module_path, module_prefix))
providers = os.path.join(os.path.dirname(bootstrapvz.__file__), 'providers')
for module_loader, module_name, ispkg in pkgutil.iter_modules([providers, 'bootstrapvz.providers']):
module_path = os.path.join(module_loader.path, module_name)
# The prefix param seems to do nothing, so we prefix the module name ourselves
module_prefix = 'bootstrapvz.providers.{}.'.format(module_name)
module_paths.add((module_path, module_prefix))
plugins = os.path.join(os.path.dirname(bootstrapvz.__file__), 'plugins')
for module_loader, module_name, ispkg in pkgutil.iter_modules([plugins, 'bootstrapvz.plugins']):
module_path = os.path.join(module_loader.path, module_name)
module_prefix = 'bootstrapvz.plugins.{}.'.format(module_name)
module_paths.add((module_path, module_prefix))
# Get generators that return all classes in a module
generators = []
for (module_path, module_prefix) in module_paths:
generators.append(get_all_classes(module_path, module_prefix)) generators.append(get_all_classes(module_path, module_prefix))
import itertools import itertools
classes = itertools.chain(*generators) classes = itertools.chain(*generators)