通过python-libvirt管理KVM虚拟机 代码实现

   2023-02-10 学习力0
核心提示:初步代码 [python] view plain copy span style="font-size:18px;"''''' Work with virtual machines managed by libvirt     :depends: libvirt Python module '''  # Special Thanks to Michael Dehann, many of the conce

初步代码

 

[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('\n')  
  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 = '\n'.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>  
 
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 云计算中的OpenStack和KVM到底是什么
    云计算中的OpenStack和KVM到底是什么
    OpenStack是一个开放源代码云计算平台 openstack是云管理平台,其本身并不提供虚拟化功能,真正的虚拟化能力是由底层的hypervisor(如KVM、Qemu、Xen等)提供。 以下内容真的的背了一遍又一遍的内容,openstart组件介绍Nova:Nova是OpenStack的主要计算引擎,
    03-08
  • KVM 虚拟机联网方式:NAT 和 Bridge
    KVM 客户机网络连接有两种方式:用户网络(User Networking):让虚拟机访问主机、互联网或本地网络上的资源的简单方法,但是不能从网络或其他的客户机访问客户机,性能上也需要大的调整。NAT方式。虚拟网桥(Virtual Bridge):这种方式要比用户网络复杂一些
    03-08
  • 如何在 CentOS 7 / RHEL 7 终端服务器上安装 KVM
    如何在 CentOS 7 / RHEL 7 终端服务器上安装 KV
    如何在 CnetOS 7 或 RHEL 7(Red Hat 企业版 Linux)服务器上安装和配置 KVM(基于内核的虚拟机)?如何在 CentOS 7 上设置 KVM 并使用云镜像 / cloud-init 来安装客户虚拟机?基于内核的虚拟机(KVM)是 CentOS 或 RHEL 7 的虚拟化软件。KVM 可以将你的服务
    03-08
  • kvm虚拟机扩容系统盘 虚拟机扩容c盘
    kvm虚拟机扩容系统盘 虚拟机扩容c盘
     一,宿主机扩容虚拟机系统盘环境文件系统CentOS 7XFS1.1查看虚拟机(以下操作在宿主机上)[root@office-prd-kvm-01 ~]# virsh list 4 office-com-ldap-01 running1.2查看虚拟机系统盘[root@office-prd-kvm-01 ~]# virsh domblklist office-com-ldap-01 目标 源
    03-08
  • kvm虚拟化介绍 kvm开源虚拟化系统
  • Linux中KVM桥接的配置
    Linux中KVM桥接的配置
    1. 原理1.1 说明在安装一个拥有虚拟化功能的Linux操作系统(此处以CentOS为例),一般我们有两种方法:1.在光盘安装的时候安装好虚拟化包或者PXE服务器上配置好虚拟化包2.手动在没有安装虚拟化组件的系统中安装虚拟化组件1.2 目的 如果我们搭建的环境是必须使
    02-10
  • kvm学习笔记(一,基础概念) kvm 原理
    kvm学习笔记(一,基础概念) kvm 原理
    前言   阿里云的云主机,采用的kvm,今天就花了点时间研究了下。一、安装官方文档参考:http://www.linux-kvm.org/page/HOWTO二、快速建立一个基于vnc的虚拟机安装 桥接网卡命令创建虚拟机 virt-install \#--network bridge:br0如果主机网卡不是桥接模式
    02-10
  • KVM 内存虚拟化
    KVM 内存虚拟化
    内存虚拟化的概念    除了 CPU 虚拟化,另一个关键是内存虚拟化,通过内存虚拟化共享物理系统内存,动态分配给虚拟机。虚拟机的内存虚拟化很象现在的操作系统支持的虚拟内存方式,应用程序看到邻近的内存地址空间,这个地址空间无需和下面的物理机器内存直
    02-10
  • 在Ubuntu1804中通过KVM创建bridge型的网络虚拟机
    在Ubuntu1804中通过KVM创建bridge型的网络虚拟
    桥接网络可以运行在宿主机上的虚拟机使用和宿主机同网段的IP,并且可以从外部直接访问到虚拟机。目前企业中大部分场景都是使用桥接网络第一步:首先在宿主机上创建桥接网卡,如下:Ubuntu1804创建桥接网卡 1 # cat/etc/netplan/01-netcfg.yaml 23 # This file
    02-10
  • kvm初体验之八:调整vm的vcpu, memory, disk大
    TD P { margin-bottom: 0 }P { margin-bottom: 0.08in }假设host上创建的vm的名字为vm1。1. 查看vm1的domain information[root@tang*** thm]# virsh dominfo vm1 Id: 10Name: vm1UUID: e2597379-5cc5-4ffa-0531-a073a81c5811OS Type: hvmState: runningCPU(s)
    02-10
点击排行