def provision(vm, compute_node=None, vt=None, steps=None, ret=None, output=True): '''provision a vm compute_node where to act vt virtual type vm vm to spawn steps list or comma separated list of steps Default:: ['spawn', 'hostsfile', 'sshkeys', 'grains', 'initial_setup', 'initial_highstate'] :: mastersalt-run -lall mc_cloud_vm.provision foo.domain.tld ''' func_name = 'mc_cloud_vm.provision {0}'.format(vm) __salt__['mc_api.time_log']('start {0}'.format(func_name)) vt = __salt__['mc_cloud_vm.get_vt'](vm, vt) compute_node = __salt__['mc_cloud_vm.get_compute_node'](vm, compute_node) vt = __salt__['mc_cloud_vm.get_vt'](vm, vt) if isinstance(steps, basestring): steps = steps.split(',') if steps is None: steps = ['register_configuration_on_cn', 'spawn', 'register_configuration', 'preprovision', # 'sshkeys', # 'hostsfile', # 'grains', # 'markers', 'initial_setup', 'initial_highstate'] if ret is None: ret = result() for step in steps: cret = __salt__['mc_cloud_vm.step'](vm, step, compute_node=compute_node, vt=vt, output=False) merge_results(ret, cret) if ret['result']: ret['comment'] += green( '{0}/{1}/{2} deployed\n').format(compute_node, vt, vm) else: ret['comment'] += red( '{0}/{1}/{2} failed to deploy\n').format(compute_node, vt, vm) salt_output(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret
def register_configurations(only=None, only_vms=None, skip=None, skip_vms=None, refresh=False, ret=None, output=True): '''Parse all reachable compute nodes and vms and regenerate the local configuration registries concerning cloud deployment''' func_name = 'mc_compute_node.register_configurations' __salt__['mc_api.time_log']('start {0}'.format(func_name)) only, _, skip, __ = ( __salt__['mc_cloud_controller.gather_only_skip']( only=only, skip=skip)) if ret is None: ret = result() if refresh: cli('saltutil.refresh_pillar') settings = cli('mc_cloud_compute_node.settings') configuration = ret['changes'].setdefault('cns_configured', []) configuration_error = ret['changes'].setdefault('cns_in_error', []) targets = [a for a in settings['targets']] # targets += ['foo', 'bar'] targets = filter_compute_nodes(targets, skip, only) hosts_to_configure_vms = [] for idx, compute_node in enumerate(targets): cret = result() try: if not cli('test.ping', salt_target=compute_node): raise FailedStepError('not reachable') register_configuration(compute_node, ret=cret, output=False) check_point(cret, __opts__, output=output) if compute_node not in hosts_to_configure_vms: hosts_to_configure_vms.append(compute_node) except FailedStepError: cret['result'] = False except Exception, exc: trace = traceback.format_exc() cret = {'result': False, 'output': 'unknown error on {0}\n{1}'.format(compute_node, exc), 'comment': 'unknown error on {0}\n'.format(compute_node), 'trace': trace} if cret['result']: if compute_node not in configuration: configuration.append(compute_node) # if everything is well, wipe the unseful output cret['output'] = '' cret['trace'] = '' else: ret['result'] = False if compute_node not in configuration_error: configuration_error.append(compute_node) cret.pop('result', False) merge_results(ret, cret)
def post_provision_compute_nodes(skip=None, only=None, output=True, refresh=False, ret=None): '''post provision all compute nodes ''' func_name = 'mc_compute_node.post_provision_compute_nodes' __salt__['mc_api.time_log']('start {0}'.format(func_name)) only, _, skip, __ = ( __salt__['mc_cloud_controller.gather_only_skip']( only=only, skip=skip)) if ret is None: ret = result() if refresh: cli('saltutil.refresh_pillar') settings = cli('mc_cloud_compute_node.settings') provision = ret['changes'].setdefault('postp_cns_provisionned', []) provision_error = ret['changes'].setdefault('postp_cns_in_error', []) targets = [a for a in settings['targets']] #targets += ['foo', 'bar'] targets = filter_compute_nodes(targets, skip, only) for idx, compute_node in enumerate(targets): cret = result() try: post_deploy(compute_node, ret=cret, output=False) #if idx == 1: # raise FailedStepError('foo') #elif idx > 0: # raise Exception('bar') except FailedStepError: cret['result'] = False except Exception, exc: trace = traceback.format_exc() cret = {'result': False, 'output': 'unknown error on {0}\n{1}'.format(compute_node, exc), 'comment': 'unknown error on {0}\n'.format(compute_node), 'trace': trace} if cret['result']: if compute_node not in provision: provision.append(compute_node) # if everything is well, wipe the unseful output cret['output'] = '' cret['trace'] = '' else: ret['result'] = False if compute_node not in provision_error: provision_error.append(compute_node) cret.pop('result', False) merge_results(ret, cret)
def sync_images(target, output=True, ret=None): '''sync images on target''' func_name = 'mc_cloud_lxc.sync_images {0}'.format( target) __salt__['mc_api.time_log']('start {0}'.format(func_name)) if ret is None: ret = result() iret = __salt__['mc_lxc.sync_images'](only=[target]) if iret['result']: ret['comment'] += yellow( 'LXC: images synchronnised on {0}\n'.format(target)) else: merge_results(ret, iret) ret['comment'] += yellow( 'LXC: images failed to synchronnise on {0}\n'.format(target)) salt_output(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret
def post_provision(vm, compute_node=None, vt=None, ret=None, output=True): '''post provision a vm compute_node where to act vt virtual type vm vm to spawn steps list or comma separated list of steps Default:: ['ping', 'post_provision_hook'] :: mastersalt-run -lall mc_cloud_vm.post_provision foo.domain.tld ''' func_name = 'mc_cloud_vm.post_provision {0}'.format(vm) __salt__['mc_api.time_log']('start {0}'.format(func_name)) if ret is None: ret = result() vt = __salt__['mc_cloud_vm.get_vt'](vm, vt) compute_node = __salt__['mc_cloud_vm.get_compute_node'](vm, compute_node) for step in ['ping', 'post_provision_hook']: cret = __salt__['mc_cloud_vm.step'](vm, step, compute_node=compute_node, vt=vt, output=False) merge_results(ret, cret) if ret['result']: ret['comment'] += green( '{0}/{1}/{2} deployed\n').format(compute_node, vt, vm) else: ret['comment'] += red( '{0}/{1}/{2} failed to deploy\n').format(compute_node, vt, vm) salt_output(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret
def run_vt_hook(hook_name, ret=None, target=None, vts=None, output=True, *args, **kwargs): '''Run an hook for a special vt on a controller, or a compute node or a vm''' func_name = ( 'mc_cloud_controller.run_vt_hook ' '{0} {1}').format(hook_name, target) __salt__['mc_api.time_log']('start {0}'.format(func_name)) if target: kwargs['target'] = target if ret is None: ret = result() if not vts: if not target: settings = cli('mc_cloud_controller.settings') vts = settings['vts'] else: settings = cli('mc_cloud_compute_node.settings') vts = settings['targets'][target]['virt_types'] if isinstance(vts, basestring): vts = [vts] for vt in vts: vid_ = 'mc_cloud_{0}.{1}'.format(vt, hook_name) if vid_ in __salt__: ret['comment'] += ( green('\n --> ') + blue(vid_) + green(' hook\n') ) kwargs['output'] = False cret = __salt__[vid_](*args, **kwargs) merge_results(ret, cret) check_point(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret
def vm_spawn(vm, compute_node=None, vt='lxc', ret=None, output=True, force=False): '''spawn the vm :: mastersalt-run -lall mc_cloud_lxc.vm_spawn foo.domain.tld ''' func_name = 'mc_cloud_lxc.vm_spawn {0}'.format(vm) __salt__['mc_api.time_log']('start {0}'.format(func_name)) if not ret: ret = result() compute_node = __salt__['mc_cloud_vm.get_compute_node'](vm, compute_node) reg = cli('mc_macros.get_local_registry', 'mc_cloud_lxc_containers') provisioned_containers = reg.setdefault('provisioned_containers', OrderedDict()) containers = provisioned_containers.setdefault(compute_node, []) reg = __salt__['mc_cloud_vm.lazy_register_configuration_on_cn']( vm, compute_node) pillar = __salt__['mc_cloud_vm.vm_sls_pillar'](compute_node, vm) target = compute_node data = pillar['vtVmData'] cloudSettings = pillar['cloudSettings'] profile = data.get( 'profile', 'ms-{0}-dir-sratch'.format(target)) profile_data = { 'target': target, 'dnsservers': data.get("dnsservers", ["8.8.8.8", "4.4.4.4"]), 'minion': { 'master': data['master'], 'master_port': data['master_port'], } } for var in ["from_container", "snapshot", "image", "additional_ips", "gateway", "bridge", "mac", "lxc_conf_unset", "ssh_gateway", "ssh_gateway_user", "ssh_gateway_port", "ssh_gateway_key", "ip", "netmask", "size", "backing", "vgname", "script", "lvname", "script_args", "dnsserver", "ssh_username", "password", "lxc_conf"]: val = data.get(var) if val: if var in ['script_args']: if '--salt-cloud-dir' not in val: val = '{0} {1}'.format( val, '--salt-cloud-dir {0}') profile_data[var] = val marker = "{cloudSettings[prefix]}/pki/master/minions/{vm}".format( cloudSettings=cloudSettings, vm=vm) lret = cli('cmd.run_all', 'test -e {0}'.format(marker)) lret['retcode'] = 1 # verify if VM is already reachable if already marked as provisioned # this add a 10 seconds overhead upon VM creation # but enable us from crashing a vm that was loosed from local # registry and where reprovisionning can be harmful # As we are pinguing it, we are managing it, we will not # enforce spawning here ! try: ping = False if vm in containers: ping = cli('test.ping', salt_timeout=10, salt_target=vm) except Exception: ping = False if force or (lret['retcode'] and not ping): try: # XXX: Code to use with salt-cloud # cret = __salt__['cloud.profile']( # profile, [vm], vm_overrides=profile_data) # if vm not in cret: # cret['result'] = False # cret = cret[vm]['runner_return'] # XXX: using the lxc runner which is now faster and nicer. cret = __salt__['lxc.cloud_init']( [vm], host=compute_node, **profile_data) if not cret['result']: # convert to regular dict for pformat errors = dict(cret.pop('errors', {})) hosts = {} for h in errors: hosts[h] = dict(errors[h]) cret['errors'] = hosts ret['trace'] += 'FAILURE ON LXC {0}:\n{1}\n'.format( vm, pformat(dict(cret))) merge_results(ret, cret) ret['result'] = False else: ret['comment'] += '{0} provisioned\n'.format(vm) except Exception, ex: ret['trace'] += '{0}\n'.format(traceback.format_exc()) ret['result'] = False ret['comment'] += red(ex.message)
def post_provision_vms(compute_node, skip=None, only=None, ret=None, output=True, refresh=False): '''post provision all or selected compute node vms :: mastersalt-run -lall mc_cloud_vm.post_provision_vms host1.domain.tld mastersalt-run -lall mc_cloud_vm.post_provision_vms host1.domain.tld only=['foo.domain.tld'] mastersalt-run -lall mc_cloud_vm.post_provision_vms host1.domain.tld skip=['foo2.domain.tld'] ''' func_name = 'mc_cloud_vm.post_provision_vms' __salt__['mc_api.time_log']('start {0}'.format(func_name)) if ret is None: ret = result() _, only, __, skip = ( __salt__['mc_cloud_controller.gather_only_skip']( only_vms=only, skip_vms=skip)) if refresh: cli('saltutil.refresh_pillar') settings = cli('mc_cloud_compute_node.settings') gerror = ret['changes'].setdefault('postp_vms_provisionned', {}) gprov = ret['changes'].setdefault('postp_vms_in_error', {}) provisionned = gprov.setdefault(compute_node, []) provision_error = gerror.setdefault(compute_node, []) vms = settings['targets'].get(compute_node, {'virt_types': [], 'vms': {}}) vms = filter_vms(compute_node, vms['vms'], skip, only) kvms = [a for a in vms] kvms.sort() for idx, vm in enumerate(kvms): vt = vms[vm] cret = result() try: #if idx == 1: # raise FailedStepError('foo') #elif idx > 0: # raise Exception('bar') cret = post_provision(vm, compute_node=compute_node, vt=vt, ret=cret, output=False) except FailedStepError: cret['result'] = False except Exception, exc: trace = traceback.format_exc() cret = {'result': False, 'output': 'unknown error on {0}/{2}\n{1}'.format( compute_node, exc, vm), 'comment': 'unknown error on {0}/{1}\n'.format( compute_node, vm), 'trace': trace} if cret['result']: if vm not in provisionned: provisionned.append(vm) # if everything is well, wipe the unseful output cret['output'] = '' cret['trace'] = '' else: ret['result'] = False if vm not in provision_error: provision_error.append(vm) cret.pop('result', False) merge_results(ret, cret)
if cret['result']: if vm not in configured: configured.append(vm) # if everything is well, wipe the unseful output cret['output'] = '' cret['trace'] = '' else: ret['result'] = False for k in ['trace', 'comment']: if k in cret: val = ret.setdefault(k, '') val += cret[k] if vm not in configuration_error: configuration_error.append(vm) cret.pop('result', False) merge_results(ret, cret) if len(configuration_error): ret['comment'] += red('There were errors while configuring ' 'vms nodes {0}\n'.format(configuration_error)) else: if ret['result']: ret['trace'] = '' ret['comment'] += green('All vms were configured\n') salt_output(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret def provision_vms(compute_node, skip=None, only=None, ret=None, output=True, refresh=False):
def orchestrate(skip=None, skip_vms=None, only=None, only_vms=None, no_dns_conf=False, no_configure=False, no_saltify=False, no_provision=False, no_vms=False, no_compute_node_provision=False, no_post_provision=False, no_vms_post_provision=False, output=True, refresh=True, ret=None): '''install controller, compute node, vms & run postdeploy no_configure skip configuring the cloud controller skip list of compute nodes to skip skip_vms list of vm to skip only explicit list of compute nodes to deploy only_vms explicit list of vm to deploy no_provision skip compute node & vm provision no_compute_node_provision skip configuration of compute nodes no_vms do not provision vms no_post_provision do not post provision compute nodes no_vms_post_provision do not post provision vms ''' func_name = 'mc_cloud_controller.orchestrate' __salt__['mc_api.time_log']('start {0}'.format(func_name)) only, only_vms, skip, skip_vms = ( __salt__['mc_cloud_controller.gather_only_skip']( only=only, only_vms=only_vms, skip=skip, skip_vms=skip_vms)) if ret is None: ret = result() if refresh: cli('saltutil.refresh_pillar') cret = result() try: # only deploy base configuration if we did not set # a specific saltify/computenode/vm switch if not no_dns_conf: dns_conf(output=False, ret=cret) check_point(cret, __opts__, output=output) del cret['result'] merge_results(ret, cret) if not no_configure: cret = result() # test that all hosts resolve else # for the dns migration deploy(output=False, ret=cret) check_point(cret, __opts__, output=output) del cret['result'] merge_results(ret, cret) if not no_saltify: cret = result() __salt__['mc_cloud_saltify.orchestrate']( only=only, skip=skip, ret=cret, output=False, refresh=False) del cret['result'] merge_results(ret, cret) cn_in_error = cret['changes'].get('saltified_errors', []) if not no_provision: if not skip: skip = [] skip += cn_in_error cret = result() __salt__['mc_cloud_compute_node.orchestrate']( skip=skip, skip_vms=skip_vms, only=only, only_vms=only_vms, no_provision=no_provision, no_compute_node_provision=no_compute_node_provision, no_post_provision=no_post_provision, no_vms_post_provision=no_vms_post_provision, no_vms=no_vms, refresh=False, output=False, ret=cret) del cret['result'] merge_results(ret, cret) cn_in_error = cret['changes'].get('provision_error', []) except FailedStepError: merge_results(ret, cret) trace = traceback.format_exc() ret['output'] += '\n{0}'.format(trace) salt_output(ret, __opts__, output=output) raise salt_output(ret, __opts__, output=output) __salt__['mc_api.time_log']('end {0}'.format(func_name)) return ret