def add_to_cluster(self, cluster, res):
        """Specification:
        0. Search and handle `master` tag in `cluster_name`
        1. Imports `cluster_name`, seeks and sets (`install` xor `setup`) and (serve` or `start`) callables
        2. Installs `cluster_name`
        3. Serves `cluster_name`
        """
        if self.is_comment_cluster(cluster):
            return

        if cluster["type"] == "fabric":
            from .drivers.OffFabric import OffFabric

            offregisterC = OffFabric
        elif cluster["type"] == "ansible":
            from .drivers.OffAnsible import OffAnsible

            offregisterC = OffAnsible
        else:
            raise NotImplementedError("{}".format(cluster["type"]))

        offregister = offregisterC(self.env, self.node, self.node_name,
                                   self.dns_name)
        add_cluster_ret = offregister.prepare_cluster_obj(cluster, res)
        offregister.run_tasks(**add_cluster_ret._asdict())
        # offregister.run_tasks(cluster_path, cluster_type, res, tag, args, kwargs)
        save_node_info(
            self.node_name,
            node_to_dict(self.node),
            folder=add_cluster_ret.cluster_path,
            marshall=json,
        )
    def run_tasks(self, cluster_path, cluster_type, cluster_args,
                  cluster_kwargs, res, tag):
        for idx, step in enumerate(self.func_names):
            kw_args = (
                cluster_kwargs.copy()
            )  # Only allow mutations on cluster_kwargs.cache [between task runs]
            kw_args["cache"] = cluster_kwargs["cache"]  # ref
            t = time()
            exec_output = execute(getattr(self.fab, step), *cluster_args,
                                  **kw_args)[self.dns_name]

            if idx == 0:
                if self.dns_name not in res:
                    res[self.dns_name] = {
                        cluster_path: OrderedDict({step: {
                            t: exec_output
                        }})
                    }
                if tag == "master":
                    save_node_info("master", [self.node_name],
                                   folder=cluster_type,
                                   marshall=json)

            if cluster_path not in res[self.dns_name]:
                res[self.dns_name][cluster_path] = OrderedDict(
                    {step: OrderedDict({t: exec_output})})
            elif step not in res[self.dns_name][cluster_path]:
                res[self.dns_name][cluster_path][step] = OrderedDict(
                    {t: exec_output})
            else:
                res[self.dns_name][cluster_path][step][t] = exec_output

            if (res[self.dns_name][cluster_path][step]
                    and "_merge" in res[self.dns_name][cluster_path][step]):
                merge = res[self.dns_name][cluster_path][step].pop("_merge")
                self.merge_steps(merge, res)

            if "_merge" in cluster_kwargs["cache"]:
                merge = cluster_kwargs["cache"].pop("_merge")
                self.merge_steps(merge, res)

            if "offregister_fab_utils" in res[self.dns_name]:
                del res[self.dns_name]["offregister_fab_utils"]
Exemple #3
0
    def attempt_provision(self, create_or_deploy='create', prefer_provider=None, prefer_image=None):
        if ping_port() is not True:
            raise EnvironmentError('etcd server not up')

        if prefer_provider:
            self.strategy.strategy['provider']['options'] = (next(
                ifilter(
                    lambda obj: obj.keys()[0] == prefer_provider,
                    self.strategy.strategy['provider']['options']
                )
            ),)
            '''
            # Prefer syntax
            self.strategy.strategy['provider']['options'].insert(
                0, self.strategy.strategy['provider']['options'].pop(
                    next(
                        ifilter(
                            lambda (idx, obj): obj.keys()[0] == prefer_provider,
                            enumerate(self.strategy.strategy['provider']['options'])
                        )
                    )[0]
                )
            )
            '''
        for i in xrange(len(self.strategy.strategy['provider']['options'])):  # Threshold
            logger.info('Attempting to create node "{node_name}" on: {provider}'.format(
                node_name=self.strategy.get_node_name(), provider=self.provider_dict['provider']['name']
            ))
            self.provision(create_or_deploy)

            if self.node:
                save_node_info(self.node_name, node_to_dict(self.node), marshall=json)
                return self.node
            self.restrategise()

        raise LibcloudError('Failed to provision node')
Exemple #4
0
 def test_0_put(self):
     self.assertIsNotNone(save_node_info(self.node.name, self.node))
Exemple #5
0
    def add_to_cluster(self, cluster, res):
        """ Specification:
          0. Search and handle `master` tag in `cluster_name`
          1. Imports `cluster_name`, seeks and sets (`install` xor `setup`) and (serve` or `start`) callables
          2. Installs `cluster_name`
          3. Serves `cluster_name`
        """
        args = cluster['args'] if 'args' in cluster else tuple()

        kwargs = update_d({
            'domain': self.dns_name,
            'node_name': self.node_name,
            'public_ipv4': self.node.public_ips[-1],
            'cache': {},
            'cluster_name': cluster.get('cluster_name')
        }, cluster['kwargs'] if 'kwargs' in cluster else {})
        cluster_type = cluster['module'].replace('-', '_')
        cluster_path = '/'.join(ifilter(None, (cluster_type, kwargs['cluster_name'])))
        kwargs.update(cluster_path=cluster_path)

        if ':' in cluster_type:
            cluster_type, _, tag = cluster_type.rpartition(':')
            del _
        else:
            tag = None

        kwargs.update(tag=tag)

        if tag == 'master':
            kwargs.update(master=True)
        if hasattr(self.node, 'private_ips') and len(self.node.private_ips):
            kwargs.update(private_ipv4=self.node.private_ips[-1])

        guessed_os = self.guess_os()

        # import `cluster_type`
        try:
            setattr(self, 'fab', getattr(__import__(cluster_type, globals(), locals(), [guessed_os], -1), guessed_os))
        except AttributeError as e:
            if e.message != "'module' object has no attribute '{os}'".format(os=guessed_os):
                raise
            raise ImportError('Cannot `import {os} from {cluster_type}`'.format(os=guessed_os,
                                                                                cluster_type=cluster_type))
        fab_dir = dir(self.fab)
        # Sort functions like so: `step0`, `step1`
        func_names = sorted(
            (j for j in fab_dir if not j.startswith('_') and str.isdigit(j[-1])),
            key=lambda s: int(''.join(takewhile(str.isdigit, s[::-1]))[::-1] or -1)
        )
        if 'run_cmds' in cluster:
            mapping = {'>=': operator.ge, '<': operator.lt,
                       '>': operator.gt, '<=': operator.le}  # TODO: There must be a full list somewhere!

            def dict_type(run_cmds, func_names):
                op = mapping[run_cmds['op']]
                return [func_name for func_name in func_names
                        if op(int(''.join(takewhile(str.isdigit, func_name[::-1]))[::-1]),
                              int(run_cmds['val']))]

            run_cmds_type = type(cluster['run_cmds'])
            if 'exclude' in cluster['run_cmds']:
                func_names = tuple(ifilter(lambda func: func not in cluster['run_cmds']['exclude'], func_names))
            func_names = dict_type(cluster['run_cmds'], func_names)

            '''{
                DictType: dict_type(cluster['run_cmds'], func_names)
            }.get(run_cmds_type, raise_f(NotImplementedError, '{!s} unexpected for run_cmds'.format(run_cmds_type)))'''

        if not func_names:
            try:
                get_attr = lambda a, b: a if hasattr(self.fab, a) else b if hasattr(self.fab, b) else raise_f(
                    AttributeError, '`{a}` nor `{b}`'.format(a=a, b=b))
                func_names = (
                    get_attr('install', 'setup'),
                    get_attr('serve', 'start')
                )
            except AttributeError as e:
                logger.error('{e} found in {cluster_type}'.format(e=e, cluster_type=cluster_type))
                raise AttributeError(
                    'Function names in {cluster_type} must end in a number'.format(cluster_type=cluster_type)
                )  # 'must'!

            logger.warn('Deprecation: Function names in {cluster_type} should end in a number'.format(
                cluster_type=cluster_type)
            )

        self.handle_deprecations(func_names)

        for idx, step in enumerate(func_names):
            exec_output = execute(getattr(self.fab, step), *args, **kwargs)[self.dns_name]

            if idx == 0:
                res[self.dns_name] = {cluster_path: {step: exec_output}}
                if tag == 'master':
                    save_node_info('master', [self.node_name], folder=cluster_type, marshall=json)
            else:
                res[self.dns_name][cluster_path][step] = exec_output

        save_node_info(self.node_name, node_to_dict(self.node), folder=cluster_path, marshall=json)