zoukankan      html  css  js  c++  java
  • 通过python-libvirt管理KVM虚拟机 代码实现

    初步代码

    [python] view plain copy
     
    1. <span style="font-size:18px;">''''' 
    2. Work with virtual machines managed by libvirt 
    3.     
    4. :depends: libvirt Python module 
    5. '''  
    6. # Special Thanks to Michael Dehann, many of the concepts, and a few structures  
    7. # of his in the virt func module have been used  
    8.      
    9. # Import python libs  
    10. import os  
    11. import re  
    12. import shutil  
    13. import subprocess  
    14. from xml.dom import minidom  
    15.      
    16. # Import third party libs  
    17. try:  
    18.     import libvirt  
    19.     HAS_LIBVIRT = True  
    20. except ImportError:  
    21.     HAS_LIBVIRT = False  
    22. import yaml  
    23.      
    24. # Import salt libs  
    25. import salt.utils  
    26. from salt._compat import StringIO as _StringIO  
    27. from salt.exceptions import CommandExecutionError  
    28.      
    29.      
    30. VIRT_STATE_NAME_MAP = {0: 'running',  
    31.                        1: 'running',  
    32.                        2: 'running',  
    33.                        3: 'paused',  
    34.                        4: 'shutdown',  
    35.                        5: 'shutdown',  
    36.                        6: 'crashed'}  
    37.      
    38.      
    39. def __virtual__():  
    40.     if not HAS_LIBVIRT:  
    41.         return False  
    42.     return 'virt'  
    43.      
    44.      
    45. def __get_conn():  
    46.     ''''' 
    47.     Detects what type of dom this node is and attempts to connect to the 
    48.     correct hypervisor via libvirt. 
    49.     '''  
    50.     # This has only been tested on kvm and xen, it needs to be expanded to  
    51.     # support all vm layers supported by libvirt  
    52.     try:  
    53.         conn = libvirt.open('qemu:///system')  
    54.     except Exception:  
    55.         raise CommandExecutionError(  
    56.             'Sorry, {0} failed to open a connection to the hypervisor '  
    57.             'software'.format(  
    58.                 __grains__['fqdn']  
    59.             )  
    60.         )  
    61.     return conn  
    62.      
    63.      
    64. def _get_dom(vm_):  
    65.     ''''' 
    66.     Return a domain object for the named vm 
    67.     '''  
    68.     conn = __get_conn()  
    69.     if vm_ not in list_vms():  
    70.         raise CommandExecutionError('The specified vm is not present')  
    71.     return conn.lookupByName(vm_)  
    72.      
    73.      
    74. def _libvirt_creds():  
    75.     ''''' 
    76.     Returns the user and group that the disk images should be owned by 
    77.     '''  
    78.     g_cmd = 'grep ^s*group /etc/libvirt/qemu.conf'  
    79.     u_cmd = 'grep ^s*user /etc/libvirt/qemu.conf'  
    80.     try:  
    81.         group = subprocess.Popen(g_cmd,  
    82.             shell=True,  
    83.             stdout=subprocess.PIPE).communicate()[0].split('"''"')[1] 
    84.     except IndexError: 
    85.         group = 'root' 
    86.     try: 
    87.         user = subprocess.Popen(u_cmd, 
    88.             shell=True, 
    89.             stdout=subprocess.PIPE).communicate()[0].split('"')[1]  
    90.     except IndexError:  
    91.         user = 'root'  
    92.     return {'user': user, 'group': group}  
    93.      
    94. def _get_migrate_command():  
    95.     ''''' 
    96.     Returns the command shared by the differnt migration types 
    97.     '''  
    98.     return 'virsh migrate --live --persistent --undefinesource '  
    99.      
    100. def _get_target(target, ssh):  
    101.     proto = 'qemu'  
    102.     if ssh:  
    103.         proto += '+ssh'  
    104.     return ' %s://%s/%s' %(proto, target, 'system')  
    105.      
    106. def list_vms():  
    107.     ''''' 
    108.     Return a list of virtual machine names on the minion 
    109.     
    110.     CLI Example:: 
    111.     
    112.         salt '*' virt.list_vms 
    113.     '''  
    114.     vms = []  
    115.     vms.extend(list_active_vms())  
    116.     vms.extend(list_inactive_vms())  
    117.     return vms  
    118.      
    119.      
    120. def list_active_vms():  
    121.     ''''' 
    122.     Return a list of names for active virtual machine on the minion 
    123.     
    124.     CLI Example:: 
    125.     
    126.         salt '*' virt.list_active_vms 
    127.     '''  
    128.     conn = __get_conn()  
    129.     vms = []  
    130.     for id_ in conn.listDomainsID():  
    131.         vms.append(conn.lookupByID(id_).name())  
    132.     return vms  
    133.      
    134.      
    135. def list_inactive_vms():  
    136.     ''''' 
    137.     Return a list of names for inactive virtual machine on the minion 
    138.     
    139.     CLI Example:: 
    140.     
    141.         salt '*' virt.list_inactive_vms 
    142.     '''  
    143.     conn = __get_conn()  
    144.     vms = []  
    145.     for id_ in conn.listDefinedDomains():  
    146.         vms.append(id_)  
    147.     return vms  
    148.      
    149.      
    150. def vm_info(vm_=None):  
    151.     ''''' 
    152.     Return detailed information about the vms on this hyper in a 
    153.     list of dicts:: 
    154.     
    155.         [ 
    156.             'your-vm': { 
    157.                 'cpu': <int>, 
    158.                 'maxMem': <int>, 
    159.                 'mem': <int>, 
    160.                 'state': '<state>', 
    161.                 'cputime' <int> 
    162.                 }, 
    163.             ... 
    164.             ] 
    165.     
    166.     If you pass a VM name in as an argument then it will return info 
    167.     for just the named VM, otherwise it will return all VMs. 
    168.     
    169.     CLI Example:: 
    170.     
    171.         salt '*' virt.vm_info 
    172.     '''  
    173.     def _info(vm_):  
    174.         dom = _get_dom(vm_)  
    175.         raw = dom.info()  
    176.         return {'cpu': raw[3],  
    177.                 'cputime': int(raw[4]),  
    178.                 'disks': get_disks(vm_),  
    179.                 'graphics': get_graphics(vm_),  
    180.                 'nics': get_nics(vm_),  
    181.                 'maxMem': int(raw[1]),  
    182.                 'mem': int(raw[2]),  
    183.                 'state': VIRT_STATE_NAME_MAP.get(raw[0], 'unknown')}  
    184.     info = {}  
    185.     if vm_:  
    186.         info[vm_] = _info(vm_)  
    187.     else:  
    188.         for vm_ in list_vms():  
    189.             info[vm_] = _info(vm_)  
    190.     return info  
    191.      
    192.      
    193. def vm_state(vm_=None):  
    194.     ''''' 
    195.     Return list of all the vms and their state. 
    196.     
    197.     If you pass a VM name in as an argument then it will return info 
    198.     for just the named VM, otherwise it will return all VMs. 
    199.     
    200.     CLI Example:: 
    201.     
    202.         salt '*' virt.vm_state <vm name> 
    203.     '''  
    204.     def _info(vm_):  
    205.         state = ''  
    206.         dom = _get_dom(vm_)  
    207.         raw = dom.info()  
    208.         state = VIRT_STATE_NAME_MAP.get(raw[0], 'unknown')  
    209.         return state  
    210.     info = {}  
    211.     if vm_:  
    212.         info[vm_] = _info(vm_)  
    213.     else:  
    214.         for vm_ in list_vms():  
    215.             info[vm_] = _info(vm_)  
    216.     return info  
    217.      
    218.      
    219. def node_info():  
    220.     ''''' 
    221.     Return a dict with information about this node 
    222.     
    223.     CLI Example:: 
    224.     
    225.         salt '*' virt.node_info 
    226.     '''  
    227.     conn = __get_conn()  
    228.     raw = conn.getInfo()  
    229.     info = {'cpucores': raw[6],  
    230.             'cpumhz': raw[3],  
    231.             'cpumodel': str(raw[0]),  
    232.             'cpus': raw[2],  
    233.             'cputhreads': raw[7],  
    234.             'numanodes': raw[4],  
    235.             'phymemory': raw[1],  
    236.             'sockets': raw[5]}  
    237.     return info  
    238.      
    239.      
    240. def get_nics(vm_):  
    241.     ''''' 
    242.     Return info about the network interfaces of a named vm 
    243.     
    244.     CLI Example:: 
    245.     
    246.         salt '*' virt.get_nics <vm name> 
    247.     '''  
    248.     nics = {}  
    249.     doc = minidom.parse(_StringIO(get_xml(vm_)))  
    250.     for node in doc.getElementsByTagName('devices'):  
    251.         i_nodes = node.getElementsByTagName('interface')  
    252.         for i_node in i_nodes:  
    253.             nic = {}  
    254.             nic['type'] = i_node.getAttribute('type')  
    255.             for v_node in i_node.getElementsByTagName('*'):  
    256.                 if v_node.tagName == 'mac':  
    257.                     nic['mac'] = v_node.getAttribute('address')  
    258.                 if v_node.tagName == 'model':  
    259.                     nic['model'] = v_node.getAttribute('type')  
    260.                 if v_node.tagName == 'target':  
    261.                     nic['target'] = v_node.getAttribute('dev')  
    262.                 # driver, source, and match can all have optional attributes  
    263.                 if re.match('(driver|source|address)', v_node.tagName):  
    264.                     temp = {}  
    265.                     for key in v_node.attributes.keys():  
    266.                         temp[key] = v_node.getAttribute(key)  
    267.                     nic[str(v_node.tagName)] = temp  
    268.                 # virtualport needs to be handled separately, to pick up the  
    269.                 # type attribute of the virtualport itself  
    270.                 if v_node.tagName == 'virtualport':  
    271.                     temp = {}  
    272.                     temp['type'] = v_node.getAttribute('type')  
    273.                     for key in v_node.attributes.keys():  
    274.                         temp[key] = v_node.getAttribute(key)  
    275.                     nic['virtualport'] = temp  
    276.             if 'mac' not in nic:  
    277.                 continue  
    278.             nics[nic['mac']] = nic  
    279.     return nics  
    280.      
    281.      
    282. def get_macs(vm_):  
    283.     ''''' 
    284.     Return a list off MAC addresses from the named vm 
    285.     
    286.     CLI Example:: 
    287.     
    288.         salt '*' virt.get_macs <vm name> 
    289.     '''  
    290.     macs = []  
    291.     doc = minidom.parse(_StringIO(get_xml(vm_)))  
    292.     for node in doc.getElementsByTagName('devices'):  
    293.         i_nodes = node.getElementsByTagName('interface')  
    294.         for i_node in i_nodes:  
    295.             for v_node in i_node.getElementsByTagName('mac'):  
    296.                 macs.append(v_node.getAttribute('address'))  
    297.     return macs  
    298.      
    299.      
    300. def get_graphics(vm_):  
    301.     ''''' 
    302.     Returns the information on vnc for a given vm 
    303.     
    304.     CLI Example:: 
    305.     
    306.         salt '*' virt.get_graphics <vm name> 
    307.     '''  
    308.     out = {'autoport': 'None',  
    309.            'keymap': 'None',  
    310.            'listen': 'None',  
    311.            'port': 'None',  
    312.            'type': 'vnc'}  
    313.     xml = get_xml(vm_)  
    314.     ssock = _StringIO(xml)  
    315.     doc = minidom.parse(ssock)  
    316.     for node in doc.getElementsByTagName('domain'):  
    317.         g_nodes = node.getElementsByTagName('graphics')  
    318.         for g_node in g_nodes:  
    319.             for key in g_node.attributes.keys():  
    320.                 out[key] = g_node.getAttribute(key)  
    321.     return out  
    322.      
    323.      
    324. def get_disks(vm_):  
    325.     ''''' 
    326.     Return the disks of a named vm 
    327.     
    328.     CLI Example:: 
    329.     
    330.         salt '*' virt.get_disks <vm name> 
    331.     '''  
    332.     disks = {}  
    333.     doc = minidom.parse(_StringIO(get_xml(vm_)))  
    334.     for elem in doc.getElementsByTagName('disk'):  
    335.         sources = elem.getElementsByTagName('source')  
    336.         targets = elem.getElementsByTagName('target')  
    337.         if len(sources) > 0:  
    338.             source = sources[0]  
    339.         else:  
    340.             continue  
    341.         if len(targets) > 0:  
    342.             target = targets[0]  
    343.         else:  
    344.             continue  
    345.         if target.hasAttribute('dev'):  
    346.             qemu_target = ''  
    347.             if source.hasAttribute('file'):  
    348.                 qemu_target = source.getAttribute('file')  
    349.             elif source.hasAttribute('dev'):  
    350.                 qemu_target = source.getAttribute('dev')  
    351.             elif source.hasAttribute('protocol') and   
    352.                     source.hasAttribute('name'): # For rbd network  
    353.                 qemu_target = '%s:%s' %(  
    354.                         source.getAttribute('protocol'),  
    355.                         source.getAttribute('name'))  
    356.             if qemu_target:  
    357.                 disks[target.getAttribute('dev')] = {  
    358.                     'file': qemu_target}  
    359.     for dev in disks:  
    360.         try:  
    361.             output = []  
    362.             qemu_output = subprocess.Popen(['qemu-img', 'info',  
    363.                 disks[dev]['file']],  
    364.                 shell=False,  
    365.                 stdout=subprocess.PIPE).communicate()[0]  
    366.             snapshots = False  
    367.             columns = None  
    368.             lines = qemu_output.strip().split(' ')  
    369.             for line in lines:  
    370.                 if line.startswith('Snapshot list:'):  
    371.                     snapshots = True  
    372.                     continue  
    373.                 elif snapshots:  
    374.                     if line.startswith('ID'):  # Do not parse table headers  
    375.                         line = line.replace('VM SIZE', 'VMSIZE')  
    376.                         line = line.replace('VM CLOCK', 'TIME VMCLOCK')  
    377.                         columns = re.split('s+', line)  
    378.                         columns = [c.lower() for c in columns]  
    379.                         output.append('snapshots:')  
    380.                         continue  
    381.                     fields = re.split('s+', line)  
    382.                     for i, field in enumerate(fields):  
    383.                         sep = ' '  
    384.                         if i == 0:  
    385.                             sep = '-'  
    386.                         output.append(  
    387.                             '{0} {1}: "{2}"'.format(  
    388.                                 sep, columns[i], field  
    389.                             )  
    390.                         )  
    391.                     continue  
    392.                 output.append(line)  
    393.             output = ' '.join(output)  
    394.             disks[dev].update(yaml.safe_load(output))  
    395.         except TypeError:  
    396.             disks[dev].update(yaml.safe_load('image: Does not exist'))  
    397.     return disks  
    398.      
    399.      
    400. def setmem(vm_, memory, config=False):  
    401.     ''''' 
    402.     Changes the amount of memory allocated to VM. The VM must be shutdown 
    403.     for this to work. 
    404.     
    405.     memory is to be specified in MB 
    406.     If config is True then we ask libvirt to modify the config as well 
    407.     
    408.     CLI Example:: 
    409.     
    410.         salt '*' virt.setmem myvm 768 
    411.     '''  
    412.     if vm_state(vm_) != 'shutdown':  
    413.         return False  
    414.      
    415.     dom = _get_dom(vm_)  
    416.      
    417.     # libvirt has a funny bitwise system for the flags in that the flag  
    418.     # to affect the "current" setting is 0, which means that to set the  
    419.     # current setting we have to call it a second time with just 0 set  
    420.     flags = libvirt.VIR_DOMAIN_MEM_MAXIMUM  
    421.     if config:  
    422.         flags = flags | libvirt.VIR_DOMAIN_AFFECT_CONFIG  
    423.      
    424.     ret1 = dom.setMemoryFlags(memory * 1024, flags)  
    425.     ret2 = dom.setMemoryFlags(memory * 1024, libvirt.VIR_DOMAIN_AFFECT_CURRENT)  
    426.      
    427.     # return True if both calls succeeded  
    428.     return ret1 == ret2 == 0  
    429.      
    430.      
    431. def setvcpus(vm_, vcpus, config=False):  
    432.     ''''' 
    433.     Changes the amount of vcpus allocated to VM. The VM must be shutdown 
    434.     for this to work. 
    435.     
    436.     vcpus is an int representing the number to be assigned 
    437.     If config is True then we ask libvirt to modify the config as well 
    438.     
    439.     CLI Example:: 
    440.     
    441.         salt '*' virt.setvcpus myvm 2 
    442.     '''  
    443.     if vm_state(vm_) != 'shutdown':  
    444.         return False  
    445.      
    446.     dom = _get_dom(vm_)  
    447.      
    448.     # see notes in setmem  
    449.     flags = libvirt.VIR_DOMAIN_VCPU_MAXIMUM  
    450.     if config:  
    451.         flags = flags | libvirt.VIR_DOMAIN_AFFECT_CONFIG  
    452.      
    453.     ret1 = dom.setVcpusFlags(vcpus, flags)  
    454.     ret2 = dom.setVcpusFlags(vcpus, libvirt.VIR_DOMAIN_AFFECT_CURRENT)  
    455.      
    456.     return ret1 == ret2 == 0  
    457.      
    458.      
    459. def freemem():  
    460.     ''''' 
    461.     Return an int representing the amount of memory that has not been given 
    462.     to virtual machines on this node 
    463.     
    464.     CLI Example:: 
    465.     
    466.         salt '*' virt.freemem 
    467.     '''  
    468.     conn = __get_conn()  
    469.     mem = conn.getInfo()[1]  
    470.     # Take off just enough to sustain the hypervisor  
    471.     mem -= 256  
    472.     for vm_ in list_vms():  
    473.         dom = _get_dom(vm_)  
    474.         if dom.ID() > 0:  
    475.             mem -= dom.info()[2] / 1024  
    476.     return mem  
    477.      
    478.      
    479. def freecpu():  
    480.     ''''' 
    481.     Return an int representing the number of unallocated cpus on this 
    482.     hypervisor 
    483.     
    484.     CLI Example:: 
    485.     
    486.         salt '*' virt.freecpu 
    487.     '''  
    488.     conn = __get_conn()  
    489.     cpus = conn.getInfo()[2]  
    490.     for vm_ in list_vms():  
    491.         dom = _get_dom(vm_)  
    492.         if dom.ID() > 0:  
    493.             cpus -= dom.info()[3]  
    494.     return cpus  
    495.      
    496.      
    497. def full_info():  
    498.     ''''' 
    499.     Return the node_info, vm_info and freemem 
    500.     
    501.     CLI Example:: 
    502.     
    503.         salt '*' virt.full_info 
    504.     '''  
    505.     return {'freecpu': freecpu(),  
    506.             'freemem': freemem(),  
    507.             'node_info': node_info(),  
    508.             'vm_info': vm_info()}  
    509.      
    510.      
    511. def get_xml(vm_):  
    512.     ''''' 
    513.     Returns the xml for a given vm 
    514.     
    515.     CLI Example:: 
    516.     
    517.         salt '*' virt.get_xml <vm name> 
    518.     '''  
    519.     dom = _get_dom(vm_)  
    520.     return dom.XMLDesc(0)  
    521.      
    522.      
    523. def shutdown(vm_):  
    524.     ''''' 
    525.     Send a soft shutdown signal to the named vm 
    526.     
    527.     CLI Example:: 
    528.     
    529.         salt '*' virt.shutdown <vm name> 
    530.     '''  
    531.     dom = _get_dom(vm_)  
    532.     return dom.shutdown() == 0  
    533.      
    534.      
    535. def pause(vm_):  
    536.     ''''' 
    537.     Pause the named vm 
    538.     
    539.     CLI Example:: 
    540.     
    541.         salt '*' virt.pause <vm name> 
    542.     '''  
    543.     dom = _get_dom(vm_)  
    544.     return dom.suspend() == 0  
    545.      
    546.      
    547. def resume(vm_):  
    548.     ''''' 
    549.     Resume the named vm 
    550.     
    551.     CLI Example:: 
    552.     
    553.         salt '*' virt.resume <vm name> 
    554.     '''  
    555.     dom = _get_dom(vm_)  
    556.     return dom.resume() == 0  
    557.      
    558.      
    559. def create(vm_):  
    560.     ''''' 
    561.     Start a defined domain 
    562.     
    563.     CLI Example:: 
    564.     
    565.         salt '*' virt.create <vm name> 
    566.     '''  
    567.     dom = _get_dom(vm_)  
    568.     return dom.create() == 0  
    569.      
    570.      
    571. def start(vm_):  
    572.     ''''' 
    573.     Alias for the obscurely named 'create' function 
    574.     
    575.     CLI Example:: 
    576.     
    577.         salt '*' virt.start <vm name> 
    578.     '''  
    579.     return create(vm_)  
    580.      
    581.      
    582. def reboot(vm_):  
    583.     ''''' 
    584.     Reboot a domain via ACPI request 
    585.     
    586.     CLI Example:: 
    587.     
    588.         salt '*' virt.reboot <vm name> 
    589.     '''  
    590.     dom = _get_dom(vm_)  
    591.      
    592.     # reboot has a few modes of operation, passing 0 in means the  
    593.     # hypervisor will pick the best method for rebooting  
    594.     return dom.reboot(0) == 0  
    595.      
    596.      
    597. def reset(vm_):  
    598.     ''''' 
    599.     Reset a VM by emulating the reset button on a physical machine 
    600.     
    601.     CLI Example:: 
    602.     
    603.         salt '*' virt.reset <vm name> 
    604.     '''  
    605.     dom = _get_dom(vm_)  
    606.      
    607.     # reset takes a flag, like reboot, but it is not yet used  
    608.     # so we just pass in 0  
    609.     # see: http://libvirt.org/html/libvirt-libvirt.html#virDomainReset  
    610.     return dom.reset(0) == 0  
    611.      
    612.      
    613. def ctrl_alt_del(vm_):  
    614.     ''''' 
    615.     Sends CTRL+ALT+DEL to a VM 
    616.     
    617.     CLI Example:: 
    618.     
    619.         salt '*' virt.ctrl_alt_del <vm name> 
    620.     '''  
    621.     dom = _get_dom(vm_)  
    622.     return dom.sendKey(0, 0, [29, 56, 111], 3, 0) == 0  
    623.      
    624.      
    625. def create_xml_str(xml):  
    626.     ''''' 
    627.     Start a domain based on the xml passed to the function 
    628.     
    629.     CLI Example:: 
    630.     
    631.         salt '*' virt.create_xml_str <xml in string format> 
    632.     '''  
    633.     conn = __get_conn()  
    634.     return conn.createXML(xml, 0) is not None  
    635.      
    636.      
    637. def create_xml_path(path):  
    638.     ''''' 
    639.     Start a defined domain 
    640.     
    641.     CLI Example:: 
    642.     
    643.         salt '*' virt.create_xml_path <path to xml file on the node> 
    644.     '''  
    645.     if not os.path.isfile(path):  
    646.         return False  
    647.     return create_xml_str(salt.utils.fopen(path, 'r').read())  
    648.      
    649.      
    650. def define_xml_str(xml):  
    651.     ''''' 
    652.     Define a domain based on the xml passed to the function 
    653.     
    654.     CLI Example:: 
    655.     
    656.         salt '*' virt.define_xml_str <xml in string format> 
    657.     '''  
    658.     conn = __get_conn()  
    659.     return conn.defineXML(xml) is not None  
    660.      
    661. def migrate_non_shared(vm_, target, ssh=False):  
    662.     ''''' 
    663.     Attempt to execute non-shared storage "all" migration 
    664.     
    665.     CLI Example:: 
    666.     
    667.         salt '*' virt.migrate_non_shared <vm name> <target hypervisor> 
    668.     '''  
    669.     cmd = _get_migrate_command() + ' --copy-storage-all ' + vm_  
    670.         + _get_target(target, ssh)  
    671.      
    672.     return subprocess.Popen(cmd,  
    673.             shell=True,  
    674.             stdout=subprocess.PIPE).communicate()[0]  
    675.      
    676.      
    677. def migrate_non_shared_inc(vm_, target, ssh=False):  
    678.     ''''' 
    679.     Attempt to execute non-shared storage "all" migration 
    680.     
    681.     CLI Example:: 
    682.     
    683.         salt '*' virt.migrate_non_shared_inc <vm name> <target hypervisor> 
    684.     '''  
    685.     cmd = _get_migrate_command() + ' --copy-storage-inc ' + vm_  
    686.         + _get_target(target, ssh)  
    687.      
    688.     return subprocess.Popen(cmd,  
    689.             shell=True,  
    690.             stdout=subprocess.PIPE).communicate()[0]  
    691.      
    692.      
    693. def migrate(vm_, target, ssh=False):  
    694.     ''''' 
    695.     Shared storage migration 
    696.     
    697.     CLI Example:: 
    698.     
    699.         salt '*' virt.migrate <vm name> <target hypervisor> 
    700.     '''  
    701.     cmd = _get_migrate_command() + ' ' + vm_  
    702.         + _get_target(target, ssh)  
    703.      
    704.     return subprocess.Popen(cmd,  
    705.             shell=True,  
    706.             stdout=subprocess.PIPE).communicate()[0]  
    707.      
    708. def seed_non_shared_migrate(disks, force=False):  
    709.     ''''' 
    710.     Non shared migration requires that the disks be present on the migration 
    711.     destination, pass the disks information via this function, to the 
    712.     migration destination before executing the migration. 
    713.     
    714.     CLI Example:: 
    715.     
    716.         salt '*' virt.seed_non_shared_migrate <disks> 
    717.     '''  
    718.     for _, data in disks.items():  
    719.         fn_ = data['file']  
    720.         form = data['file format']  
    721.         size = data['virtual size'].split()[1][1:]  
    722.         if os.path.isfile(fn_) and not force:  
    723.             # the target exists, check to see if is is compatible  
    724.             pre = yaml.safe_load(subprocess.Popen('qemu-img info arch',  
    725.                 shell=True,  
    726.                 stdout=subprocess.PIPE).communicate()[0])  
    727.             if not pre['file format'] == data['file format']  
    728.                     and not pre['virtual size'] == data['virtual size']:  
    729.                 return False  
    730.         if not os.path.isdir(os.path.dirname(fn_)):  
    731.             os.makedirs(os.path.dirname(fn_))  
    732.         if os.path.isfile(fn_):  
    733.             os.remove(fn_)  
    734.         cmd = 'qemu-img create -f ' + form + ' ' + fn_ + ' ' + size  
    735.         subprocess.call(cmd, shell=True)  
    736.         creds = _libvirt_creds()  
    737.         cmd = 'chown ' + creds['user'] + ':' + creds['group'] + ' ' + fn_  
    738.         subprocess.call(cmd, shell=True)  
    739.     return True  
    740.      
    741.      
    742. def set_autostart(vm_, state='on'):  
    743.     ''''' 
    744.     Set the autostart flag on a VM so that the VM will start with the host 
    745.     system on reboot. 
    746.     
    747.     CLI Example:: 
    748.     
    749.         salt "*" virt.set_autostart <vm name> <on | off> 
    750.     '''  
    751.      
    752.     dom = _get_dom(vm_)  
    753.      
    754.     if state == 'on':  
    755.         return dom.setAutostart(1) == 0  
    756.      
    757.     elif state == 'off':  
    758.         return dom.setAutostart(0) == 0  
    759.      
    760.     else:  
    761.         # return False if state is set to something other then on or off  
    762.         return False  
    763.      
    764.      
    765. def destroy(vm_):  
    766.     ''''' 
    767.     Hard power down the virtual machine, this is equivalent to pulling the 
    768.     power 
    769.     
    770.     CLI Example:: 
    771.     
    772.         salt '*' virt.destroy <vm name> 
    773.     '''  
    774.     dom = _get_dom(vm_)  
    775.     return dom.destroy() == 0  
    776.      
    777.      
    778. def undefine(vm_):  
    779.     ''''' 
    780.     Remove a defined vm, this does not purge the virtual machine image, and 
    781.     this only works if the vm is powered down 
    782.     
    783.     CLI Example:: 
    784.     
    785.         salt '*' virt.undefine <vm name> 
    786.     '''  
    787.     dom = _get_dom(vm_)  
    788.     return dom.undefine() == 0  
    789.      
    790.      
    791. def purge(vm_, dirs=False):  
    792.     ''''' 
    793.     Recursively destroy and delete a virtual machine, pass True for dir's to 
    794.     also delete the directories containing the virtual machine disk images - 
    795.     USE WITH EXTREME CAUTION! 
    796.     
    797.     CLI Example:: 
    798.     
    799.         salt '*' virt.purge <vm name> 
    800.     '''  
    801.     disks = get_disks(vm_)  
    802.     if not destroy(vm_):  
    803.         return False  
    804.     directories = set()  
    805.     for disk in disks:  
    806.         os.remove(disks[disk]['file'])  
    807.         directories.add(os.path.dirname(disks[disk]['file']))  
    808.     if dirs:  
    809.         for dir_ in directories:  
    810.             shutil.rmtree(dir_)  
    811.     return True  
    812.      
    813.      
    814. def virt_type():  
    815.     ''''' 
    816.     Returns the virtual machine type as a string 
    817.     
    818.     CLI Example:: 
    819.     
    820.         salt '*' virt.virt_type 
    821.     '''  
    822.     return __grains__['virtual']  
    823.      
    824.      
    825. def is_kvm_hyper():  
    826.     ''''' 
    827.     Returns a bool whether or not this node is a KVM hypervisor 
    828.     
    829.     CLI Example:: 
    830.     
    831.         salt '*' virt.is_kvm_hyper 
    832.     '''  
    833.     if __grains__['virtual'] != 'physical':  
    834.         return False  
    835.     try:  
    836.         if 'kvm_' not in salt.utils.fopen('/proc/modules').read():  
    837.             return False  
    838.     except IOError:  
    839.         # No /proc/modules? Are we on Windows? Or Solaris?  
    840.         return False  
    841.     return 'libvirtd' in __salt__['cmd.run'](__grains__['ps'])  
    842.      
    843.      
    844. def is_xen_hyper():  
    845.     ''''' 
    846.     Returns a bool whether or not this node is a XEN hypervisor 
    847.     
    848.     CLI Example:: 
    849.     
    850.         salt '*' virt.is_xen_hyper 
    851.     '''  
    852.     try:  
    853.         if __grains__['virtual_subtype'] != 'Xen Dom0':  
    854.             return False  
    855.     except KeyError:  
    856.         # virtual_subtype isn't set everywhere.  
    857.         return False  
    858.     try:  
    859.         if 'xen_' not in salt.utils.fopen('/proc/modules').read():  
    860.             return False  
    861.     except IOError:  
    862.         # No /proc/modules? Are we on Windows? Or Solaris?  
    863.         return False  
    864.     return 'libvirtd' in __salt__['cmd.run'](__grains__['ps'])  
    865.      
    866.      
    867. def is_hyper():  
    868.     ''''' 
    869.     Returns a bool whether or not this node is a hypervisor of any kind 
    870.     
    871.     CLI Example:: 
    872.     
    873.         salt '*' virt.is_hyper 
    874.     '''  
    875.     return is_xen_hyper() or is_kvm_hyper()  
    876.      
    877. def vm_cputime(vm_=None):  
    878.     ''''' 
    879.     Return cputime used by the vms on this hyper in a 
    880.     list of dicts:: 
    881.     
    882.         [ 
    883.             'your-vm': { 
    884.                 'cputime' <int> 
    885.                 'cputime_percent' <int> 
    886.                 }, 
    887.             ... 
    888.             ] 
    889.     
    890.     If you pass a VM name in as an argument then it will return info 
    891.     for just the named VM, otherwise it will return all VMs. 
    892.     
    893.     CLI Example:: 
    894.     
    895.         salt '*' virt.vm_cputime 
    896.     '''  
    897.     host_cpus = __get_conn().getInfo()[2]  
    898.     def _info(vm_):  
    899.         dom = _get_dom(vm_)  
    900.         raw = dom.info()  
    901.         vcpus = int(raw[3])  
    902.         cputime = int(raw[4])  
    903.         cputime_percent = 0  
    904.         if cputime:  
    905.             # Divide by vcpus to always return a number between 0 and 100  
    906.             cputime_percent = (1.0e-7 * cputime / host_cpus) / vcpus  
    907.         return {  
    908.                 'cputime': int(raw[4]),  
    909.                 'cputime_percent': int('%.0f' %cputime_percent)  
    910.                }  
    911.     info = {}  
    912.     if vm_:  
    913.         info[vm_] = _info(vm_)  
    914.     else:  
    915.         for vm_ in list_vms():  
    916.             info[vm_] = _info(vm_)  
    917.     return info  
    918.      
    919. def vm_netstats(vm_=None):  
    920.     ''''' 
    921.     Return combined network counters used by the vms on this hyper in a 
    922.     list of dicts:: 
    923.     
    924.         [ 
    925.             'your-vm': { 
    926.                 'rx_bytes'   : 0, 
    927.                 'rx_packets' : 0, 
    928.                 'rx_errs'    : 0, 
    929.                 'rx_drop'    : 0, 
    930.                 'tx_bytes'   : 0, 
    931.                 'tx_packets' : 0, 
    932.                 'tx_errs'    : 0, 
    933.                 'tx_drop'    : 0 
    934.                 }, 
    935.             ... 
    936.             ] 
    937.     
    938.     If you pass a VM name in as an argument then it will return info 
    939.     for just the named VM, otherwise it will return all VMs. 
    940.     
    941.     CLI Example:: 
    942.     
    943.         salt '*' virt.vm_netstats 
    944.     '''  
    945.     def _info(vm_):  
    946.         dom = _get_dom(vm_)  
    947.         nics = get_nics(vm_)  
    948.         ret = {  
    949.                 'rx_bytes'   : 0,  
    950.                 'rx_packets' : 0,  
    951.                 'rx_errs'    : 0,  
    952.                 'rx_drop'    : 0,  
    953.                 'tx_bytes'   : 0,  
    954.                 'tx_packets' : 0,  
    955.                 'tx_errs'    : 0,  
    956.                 'tx_drop'    : 0  
    957.                }  
    958.         for mac, attrs in nics.items():  
    959.             if 'target' in attrs:  
    960.                 dev = attrs['target']  
    961.                 stats = dom.interfaceStats(dev)  
    962.                 ret['rx_bytes'] += stats[0]  
    963.                 ret['rx_packets'] += stats[1]  
    964.                 ret['rx_errs'] += stats[2]  
    965.                 ret['rx_drop'] += stats[3]  
    966.                 ret['tx_bytes'] += stats[4]  
    967.                 ret['tx_packets'] += stats[5]  
    968.                 ret['tx_errs'] += stats[6]  
    969.                 ret['tx_drop'] += stats[7]  
    970.      
    971.         return ret  
    972.     info = {}  
    973.     if vm_:  
    974.         info[vm_] = _info(vm_)  
    975.     else:  
    976.         for vm_ in list_vms():  
    977.             info[vm_] = _info(vm_)  
    978.     return info  
    979.      
    980. def vm_diskstats(vm_=None):  
    981.     ''''' 
    982.     Return disk usage counters used by the vms on this hyper in a 
    983.     list of dicts:: 
    984.     
    985.         [ 
    986.             'your-vm': { 
    987.                 'rd_req'   : 0, 
    988.                 'rd_bytes' : 0, 
    989.                 'wr_req'   : 0, 
    990.                 'wr_bytes' : 0, 
    991.                 'errs'     : 0 
    992.                 }, 
    993.             ... 
    994.             ] 
    995.     
    996.     If you pass a VM name in as an argument then it will return info 
    997.     for just the named VM, otherwise it will return all VMs. 
    998.     
    999.     CLI Example:: 
    1000.     
    1001.         salt '*' virt.vm_blockstats 
    1002.     '''  
    1003.     def get_disk_devs(vm_):  
    1004.         doc = minidom.parse(_StringIO(get_xml(vm_)))  
    1005.         disks = []  
    1006.         for elem in doc.getElementsByTagName('disk'):  
    1007.             targets = elem.getElementsByTagName('target')  
    1008.             target = targets[0]  
    1009.             disks.append(target.getAttribute('dev'))  
    1010.         return disks  
    1011.      
    1012.     def _info(vm_):  
    1013.         dom = _get_dom(vm_)  
    1014.         # Do not use get_disks, since it uses qemu-img and is very slow  
    1015.         # and unsuitable for any sort of real time statistics  
    1016.         disks = get_disk_devs(vm_)  
    1017.         ret = {  
    1018.                 'rd_req'   : 0,  
    1019.                 'rd_bytes' : 0,  
    1020.                 'wr_req'   : 0,  
    1021.                 'wr_bytes' : 0,  
    1022.                 'errs'     : 0  
    1023.                }  
    1024.         for disk in disks:  
    1025.             stats = dom.blockStats(disk)  
    1026.             ret['rd_req']   += stats[0]  
    1027.             ret['rd_bytes'] += stats[1]  
    1028.             ret['wr_req']   += stats[2]  
    1029.             ret['wr_bytes'] += stats[3]  
    1030.             ret['errs']     += stats[4]  
    1031.      
    1032.         return ret  
    1033.     info = {}  
    1034.     if vm_:  
    1035.         info[vm_] = _info(vm_)  
    1036.     else:  
    1037.         # Can not run function blockStats on inactive VMs  
    1038.         for vm_ in list_active_vms():  
    1039.             info[vm_] = _info(vm_)  
    1040.     return info  
    1041. </span>  
     
  • 相关阅读:
    [MacOS]修改Wifi默认共享网段
    [CentOS7]升级OpenSSL至1.1.1
    [Linux]checking for libevent support... configure: error: Unable to use libevent (libevent check failed)
    [CentOS7]team模式切换
    HDU 5416 CBR and tree
    CodeForces 374D Inna and Sequence
    HDU 5981 Guess the number
    题目清单
    HDU 5510 Bazinga
    KMP & AC自动机
  • 原文地址:https://www.cnblogs.com/zknublx/p/9200563.html
Copyright © 2011-2022 走看看