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"]
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')
def test_0_put(self): self.assertIsNotNone(save_node_info(self.node.name, self.node))
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)