Пример #1
0
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
Пример #2
0
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)
Пример #3
0
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)
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
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)
Пример #8
0
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)
Пример #9
0
        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):
Пример #10
0
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