初步代码

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

通过python-libvirt管理KVM虚拟机 代码实现的更多相关文章

  1. 使用 libvirt创建和管理KVM虚拟机

      1. libvirt介绍    Libvirt是一个软件集合,便于使用者管理虚拟机和其他虚拟化功能,比如存储和网络接口管理等等.Libvirt概括起来包括一个API库.一个 daemon(libv ...

  2. 管理KVM虚拟机(二)

    管理KVM虚拟机 工具:libvirt 官网:http://libvirt.org/ 介绍:Libvirt 库是一种实现 Linux 虚拟化功能的 Linux® API,它支持各种虚拟机监控程序,包括 ...

  3. 关于Linux虚拟化技术KVM的科普 科普二(KVM虚拟机代码揭秘)

    代码分析文章<KVM虚拟机代码揭秘--QEMU代码结构分析>.<KVM虚拟机代码揭秘--中断虚拟化>.<KVM虚拟机代码揭秘--设备IO虚拟化>.<KVM虚拟 ...

  4. Linux 中使用 virsh 管理 KVM 虚拟机 (转)

    术语 虚拟化指的是:在相同的物理(硬件)系统上,同时运行多个操作系统,且这几个系统相互隔离的可能性,而那个硬件在虚拟化架构中被称作宿主机(host).虚拟机监视器(也被称为虚拟机管理程序(hyperv ...

  5. 使用Wok管理kvm虚拟机

    [Centos7.4] !!!测试环境我们首关闭防火墙和selinux [root@localhost ~]# systemctl stop firewalld [root@localhost ~]# ...

  6. 使用libvirt管理KVM(一)

    一. 安装和配置libvirt,源码下载http://www.qemu-project.org/download/#source. 二. 从包和源码包进行安装libvirt. 1. 在ubuntu系统 ...

  7. 安装libvirt管理套件(C/S架构模式,用户管理kvm虚拟机)

    # 1:安装程序包 yum install -y libvirt virt-manager virt-viewer virt-install qemu-kvm   # 2:启动libvirtd守护进程 ...

  8. 使用cockpit管理kvm虚拟机

    在Centos8.2主机上部署kvm,使用cockpit管理 首先检测cpu是否支持虚拟化 [root@localhost ~]# cat /proc/cpuinfo | grep vmx flags ...

  9. 通过python-libvirt管理KVM虚拟机 源码

    版本:0.9.13 libvirt库可真是大,先看看该版本里面都有哪些类和方法,验证过的方法我会用O开头,|开头的标示还没亲自验证过. <span style="font-size:1 ...

随机推荐

  1. arping 帮助——翻译

    [root@localhost ~]# arping --helparping: invalid option -- '-'Usage: arping [-fqbDUAV] [-c count] [- ...

  2. windows Maven3.0 服务器配置搭建

    搭建nexus私服,原因很简单,不必多说,本文重点说下最新版的Maven 3.0.x系列的安装步骤. 最新版的网上中文资料很少,参考后都没成功.最后在官网的英文资料中得到答案,成功搞定. 1.确定我们 ...

  3. SAP升级ECC6.0 引起的一个事故

    上个月底,公司的SAP系统升级到了ECC6,在升级时,我们进行了所有关联系统的集成测试,当时没有发现什么问题. 过了2周,需要从SAP下载对账单了,这个时候问题出现了,很多分公司的数据下载失败.和SA ...

  4. win7怎么快速截取图片

    点击开始--运行或者winkey + r 键直接进入运行. 2 在输入框输入snippingtool,点击确定. 3 这就找到截图工具,如图. END 方法/步骤2   进入c盘--Windows-- ...

  5. easyui-linkbutton 设置和获取text文本

    <a id="butTransagt"  href="#" class="easyui-linkbutton"  icon=" ...

  6. 豆瓣上9分以上的IT书籍-编程技术篇

    在豆瓣上9分以上的IT书籍-编程语言篇中,收集了很多优秀的编程语言书籍,也得到了不少读者的喜欢.不过也有一些读者留言说某某书为什么没有,一种是因为某些书并不算讲某种编程语言的,一种是由于豆瓣9分以上这 ...

  7. C++的坑真的多吗?

    先说明一下,我不希望本文变成语言争论贴.希望下面的文章能让我们客观理性地了解C++这个语言.(另,我觉得技术争论不要停留在非黑即白的二元价值观上,这样争论无非就是比谁的嗓门大,比哪一方的观点强,毫无价 ...

  8. ext2文件系统 - mke2fs

      上一遍博文的重点其实将ext2整体的组织框架,我们知道了ext2文件系统由块组组成,每个块组里面的组织形式.我们甚至直接把超级块和组描述符里面的内容,用十六进制形式展现了出来.这篇博文主要讲述如何 ...

  9. tableView的用法具体解释

    1 tableView的类型   1.1 UITableViewStylePlain  没有区头 不显区头     向上滑动区头不会移动到屏幕外面 ' 1.2 UITableViewStyleGrou ...

  10. C#中关于DataGridView行和列的背景色-前景色设置

    关于DataGridView行和列的背景色-前景色设置 1.设定DataGridView全部单元格的Style  DataGridView内所有单元格的Style变更,可以使用DataGridView ...