Set which CPUs a VCPU can use.

    CLI Example:

    .. code-block:: bash

        salt 'foo' virt.vcpu_pin domU-id 2 1
        salt 'foo' virt.vcpu_pin domU-id 2 2-6

def vcpu_pin(vm_, vcpu, cpus):
    '''
    Set which CPUs a VCPU can use.

    CLI Example:

    .. code-block:: bash

        salt 'foo' virt.vcpu_pin domU-id 2 1
        salt 'foo' virt.vcpu_pin domU-id 2 2-6
    '''
    with _get_xapi_session() as xapi:

        vm_uuid = _get_label_uuid(xapi, 'VM', vm_)
        if vm_uuid is False:
            return False

        # from xm's main
        def cpu_make_map(cpulist):
            cpus = []
            for c in cpulist.split(','):
                if c == '':
                    continue
                if '-' in c:
                    (x, y) = c.split('-')
                    for i in range(int(x), int(y) + 1):
                        cpus.append(int(i))
                else:
                    # remove this element from the list
                    if c[0] == '^':
                        cpus = [x for x in cpus if x != int(c[1:])]
                    else:
                        cpus.append(int(c))
            cpus.sort()
            return ','.join(map(str, cpus))

        if cpus == 'all':
            cpumap = cpu_make_map('0-63')
        else:
            cpumap = cpu_make_map('{0}'.format(cpus))

        try:
            xapi.VM.add_to_VCPUs_params_live(vm_uuid,
                                             'cpumap{0}'.format(vcpu), cpumap)
            return True
        # VM.add_to_VCPUs_params_live() implementation in xend 4.1+ has
        # a bug which makes the client call fail.
        # That code is accurate for all others XenAPI implementations, but
        # for that particular one, fallback to xm / xl instead.
        except Exception:
            return __salt__['cmd.run'](
                    '{0} vcpu-pin {1} {2} {3}'.format(_get_xtool(), vm_, vcpu, cpus),
                    python_shell=False)