def conns(self): if self.hosts_online is None: if libvirt.getVersion() < 9004: # libvirt support for no_verify was introduced in 0.9.4 procs = [] for hostport in self.hosts.iterkeys(): host, _, port = hostport.partition(':') args = ["/usr/bin/ssh", "-oBatchMode=yes", "-oStrictHostKeyChecking=no", "-p{0}".format(port), "root@{0}".format(host), "uptime"] procs.append(subprocess.Popen(args)) [proc.wait() for proc in procs] self.hosts_online = [] def lv_connect(host, priority, weight): try: conn = PoniLVConn(host, keyfile=self.ssh_key, priority=priority, weight=weight) conn.connect() self.hosts_online.append(conn) except (LVPError, libvirt.libvirtError) as ex: self.log.warn("Connection to %r failed: %r", conn.uri, ex) tasks = util.TaskPool() for host, (priority, weight) in self.hosts.iteritems(): tasks.apply_async(lv_connect, [host, priority, weight]) tasks.wait_all() if not self.hosts_online: raise LVPError("No VM hosts available") return list(self.hosts_online)
def has_mem_hotplug_support(conn): ''' A memory device can be hot-plugged or hot-unplugged since libvirt version 1.2.14. ''' # Libvirt < 1.2.14 does not support memory devices, so firstly, check # its version, then try to attach a device. These steps avoid errors # with Libvirt 'test' driver for KVM version = 1000000*1 + 1000*2 + 14 if libvirt.getVersion() < version: return False with RollbackContext() as rollback: FeatureTests.disable_libvirt_error_logging() rollback.prependDefer(FeatureTests.enable_libvirt_error_logging) conn_type = conn.getType().lower() domain_type = 'test' if conn_type == 'test' else 'kvm' arch = 'i686' if conn_type == 'test' else platform.machine() arch = 'ppc64' if arch == 'ppc64le' else arch dom = conn.defineXML(MAXMEM_VM_XML % {'name': FEATURETEST_VM_NAME, 'domain': domain_type, 'arch': arch}) rollback.prependDefer(dom.undefine) try: dom.attachDeviceFlags(DEV_MEM_XML, libvirt.VIR_DOMAIN_MEM_CONFIG) return True except libvirt.libvirtError: return False
def _version_check(self): """Check if libvirt release supports snapshots. @return: True or false. """ if libvirt.getVersion() >= 8000: return True else: return False
def local_libvirt_version(): """ Lookup the local libvirt library version, but cache the value since it never changes. """ key = "__virtinst_cached_getVersion" if not hasattr(libvirt, key): setattr(libvirt, key, libvirt.getVersion()) return getattr(libvirt, key)
def libvirt_version(self): """ Return the version of the libvirt """ if not self._libvirt_version: libvirtnumber = libvirt.getVersion() self._libvirt_version = {"major": libvirtnumber / 1000000, "minor": libvirtnumber / 1000, "release": libvirtnumber % 1000} return self._libvirt_version
def setup_libvirt(): import libvirt # Check libvirt version assert(libvirt.getVersion() >= 9008) # 0.9.8 # Squash redundant reporting of libvirt errors to stderr. This modifies # global state, since the Python bindings don't provide a way to do this # per-connection. libvirt.registerErrorHandler(lambda _ctx, _error: None, None)
def setup_libvirt(): import libvirt # Check libvirt version assert (libvirt.getVersion() >= 9008) # 0.9.8 # Squash redundant reporting of libvirt errors to stderr. This modifies # global state, since the Python bindings don't provide a way to do this # per-connection. libvirt.registerErrorHandler(lambda _ctx, _error: None, None)
def __virtual__(): """ Only load if libvirt python binding is present """ if libvirt is None: msg = "libvirt module not found" elif libvirt.getVersion() < 1000000: msg = "libvirt >= 1.0.0 required" else: msg = "" return not bool(msg), msg
def __virtual__(): ''' Only load if libvirt python binding is present ''' if libvirt is None: msg = 'libvirt module not found' elif libvirt.getVersion() < 1000000: msg = 'libvirt >= 1.0.0 required' else: msg = '' return not bool(msg), msg
def libvirt_version(self): """ Return the version of the libvirt """ if not self._libvirt_version: libvirtnumber = libvirt.getVersion() self._libvirt_version = { "major": libvirtnumber / 1000000, "minor": libvirtnumber / 1000, "release": libvirtnumber % 1000 } return self._libvirt_version
def main(): parser = argparse.ArgumentParser() parser.add_argument('vm_name', help='Name of the virtual machine') args = parser.parse_args() vm_name = args.vm_name if libvirt.getVersion() >= 1002006: newest_dhcp_lease = get_vir_network_dhcp_lease(vm_name) else: newest_dhcp_lease = get_dnsmasq_dhcp_lease(vm_name) print(newest_dhcp_lease)
def check_libvirt_python_bindings(hostname, username, trd_party_dir): ''' TBD ''' try: _status = 100 _fmsg = "An error has occurred, but no error message was captured" _msg = "Checking libvirt python bindings version....." import libvirt _version = str(libvirt.getVersion()).strip() del libvirt _msg += compare_versions('9003', _version) _status = 0 except ImportError, e: _status = 7282
def check_libvirt_python_bindings(hostname, username, trd_party_dir) : ''' TBD ''' try: _status = 100 _fmsg = "An error has occurred, but no error message was captured" _msg = "Checking libvirt python bindings version....." import libvirt _version = str(libvirt.getVersion()).strip() del libvirt _msg += compare_versions('9003', _version) _status = 0 except ImportError, e: _status = 7282
def conns(self): if self.hosts_online is None: if libvirt.getVersion() < 9004: # libvirt support for no_verify was introduced in 0.9.4 procs = [] for hostport in self.hosts.iterkeys(): host, _, port = hostport.partition(':') args = ["/usr/bin/ssh", "-oBatchMode=yes", "-oStrictHostKeyChecking=no", "-p{0}".format(port), "root@{0}".format(host), "uptime"] procs.append(subprocess.Popen(args)) [proc.wait() for proc in procs] self.hosts_online = [] for host, (priority, weight) in self.hosts.iteritems(): try: conn = PoniLVConn(host, keyfile=self.ssh_key, priority=priority, weight=weight) conn.connect() self.hosts_online.append(conn) except libvirt.libvirtError, ex: self.log.warn("Connection to %r failed: %r", conn.uri, ex)
class TestLibvirtDomain(unittest.TestCase): def setUp(self): self.conn = libvirt.open("test:///default") self.dom = self.conn.lookupByName("test") def tearDown(self): self.dom = None self.conn = None def testDomainSchedParams(self): params = self.dom.schedulerParameters() self.assertEqual(len(params), 1) self.assertTrue("weight" in params) params["weight"] = 100 self.dom.setSchedulerParameters(params) @unittest.skipIf(libvirt.getVersion() == 4000000, "test driver screenshot broken in 4.0.0") def testScreenshot(self): stream = self.conn.newStream() ss = self.dom.screenshot(stream, 0, 0)
def conns(self): if self.hosts_online is None: if libvirt.getVersion() < 9004: # libvirt support for no_verify was introduced in 0.9.4 procs = [] for hostport in self.hosts.iterkeys(): host, _, port = hostport.partition(':') args = [ "/usr/bin/ssh", "-oBatchMode=yes", "-oStrictHostKeyChecking=no", "-p{0}".format(port), "root@{0}".format(host), "uptime" ] procs.append(subprocess.Popen(args)) [proc.wait() for proc in procs] self.hosts_online = [] def lv_connect(host, priority, weight): try: conn = PoniLVConn(host, hypervisor=self.hypervisor, keyfile=self.ssh_key, priority=priority, weight=weight) conn.connect() self.hosts_online.append(conn) except (LVPError, libvirt.libvirtError) as ex: self.log.warn("Connection to %r failed: %r", conn.uri, ex) tasks = util.TaskPool() for host, (priority, weight) in self.hosts.iteritems(): tasks.apply_async(lv_connect, [host, priority, weight]) tasks.wait_all() if not self.hosts_online: raise LVPError("No VM hosts available") return list(self.hosts_online)
def impl(): return "LibVirt-" + libvirt.getVersion()
import docopt import sys import os.path import ClusterShell from clara import utils # Version 10.2.9 is Debian Jessie # earlier versions might work but are not tested. # Debian Squeeze is not OK though try: import libvirt except ImportError: utils.clara_exit("LibVirt Missing, needs version >= 10.2.9.") libvirt_version = libvirt.getVersion() if libvirt_version < 1002009: utils.clara_exit( "LibVirt too old (%d.%d.%d), needs version >= 10.2.9." % (libvirt_version / 1000000, (libvirt_version % 1000000) / 1000, libvirt_version % 1000)) from clara.virt.conf.virtconf import VirtConf from clara.virt.libvirt.nodegroup import NodeGroup from clara.virt.exceptions import VirtConfigurationException def do_list(conf, show_hosts=False, show_volumes=False, host_name=None): vm_line = "VM:{0:16} State:{1:12} Host:{2:16}" host_line = " Host:{0:16} HostState:{1:16}" vol_line = " Volume:{0:32} Pool:{1:16} Capacity:{2:12}"
assert dev.type_id == "vfio_ap-passthrough" def testPCIMdev(): conn = utils.URIs.open_testdriver_cached() devname = "mdev_4b20d080_1b54_4048_85b3_a6a62d165c01" dev = _nodeDevFromName(conn, devname) assert dev.name == devname assert dev.parent == "pci_0000_06_00_0" assert dev.device_type == "mdev" assert dev.type_id == "nvidia-11" assert dev.get_mdev_uuid() == "4b20d080-1b54-4048-85b3-a6a62d165c01" # libvirt <7.3.0 doesn't support <uuid> in the mdev node device xml @pytest.mark.skipif(libvirt.getVersion() < 7003000, reason="libvirt version doesn't support new mdev format") def testPCIMdevNewFormat(): conn = utils.URIs.open_testdriver_cached() devname = "mdev_35ceae7f_eea5_4f28_b7f3_7b12a3e62d3c_0000_06_00_0" dev = _nodeDevFromName(conn, devname) assert dev.name == devname assert dev.parent == "pci_0000_06_00_0" assert dev.device_type == "mdev" assert dev.type_id == "nvidia-11" assert dev.get_mdev_uuid() == "35ceae7f-eea5-4f28-b7f3-7b12a3e62d3c" # NodeDevice 2 Device XML tests def testNodeDev2USB1(): conn = utils.URIs.open_testdriver_cached()
import zope.interface except ImportError: print >>sys.stderr, "\n%sCannot locate the zope.interface package." % ERR print >>sys.stderr, "\nThis should be included in the workspace-control lib/ directory. That directory should be loaded as part of the program's PYTHONPATH." problem_count += 1 try: import libvirt except: print >>sys.stderr, "\n%sCannot locate the libvirt Python bindings package." % ERR print >>sys.stderr, "\nOn some Linux distributions, this is only included when you install libvirt\n when you have previously installed the 'python-dev' package." print >>sys.stderr, "\nSee your distribution documentation." problem_count += 1 try: libvirtsion = libvirt.getVersion() libvirtsion = int(libvirtsion) if libvirtsion < 7000: print >>sys.stderr, "\nWarning: low libvirt version, compatibility is not understood" except: print >>sys.stderr, "\nProblem getting libvirt version?" problem_count += 1 try: from workspacecontrol.api.exceptions import * except: print >>sys.stderr, "\n%sCannot locate the 'workspacecontrol' Python package." % ERR print >>sys.stderr, "\nIf you installed this from the directions, please contact the mailing list.." problem_count += 1 if problem_count:
import uuid from wsgiref.handlers import format_date_time as format_rfc1123_date from ...domain import DomainXML from ...package import Package from ...util import ErrorBuffer, ensure_dir, get_cache_dir from .. import Controller, MachineExecutionError, MachineStateError, Statistic from .monitor import (ChunkMapMonitor, LineStreamMonitor, LoadProgressMonitor, StatMonitor) from .virtevent import LibvirtEventImpl from .vmnetfs import VMNetFS, NS as VMNETFS_NS _log = logging.getLogger(__name__) # Check libvirt version assert(libvirt.getVersion() >= 9008) # 0.9.8 # Squash redundant reporting of libvirt errors to stderr. This modifies # global state, since the Python bindings don't provide a way to do this # per-connection. libvirt.registerErrorHandler(lambda _ctx, _error: None, None) # Enable libvirt event reporting. Also modifies global state. LibvirtEventImpl().register() class _ReferencedObject(object): # pylint doesn't understand named tuples # pylint: disable=E1103 def __init__(self, label, info, username=None, password=None, chunk_size=131072):
def getLibvirtVer(): return libvirt.getVersion()
import zope.interface except ImportError: print >> sys.stderr, "\n%sCannot locate the zope.interface package." % ERR print >> sys.stderr, "\nThis should be included in the workspace-control lib/ directory. That directory should be loaded as part of the program's PYTHONPATH." problem_count += 1 try: import libvirt except: print >> sys.stderr, "\n%sCannot locate the libvirt Python bindings package." % ERR print >> sys.stderr, "\nOn some Linux distributions, this is only included when you install libvirt\n when you have previously installed the 'python-dev' package." print >> sys.stderr, "\nSee your distribution documentation." problem_count += 1 try: libvirtsion = libvirt.getVersion() libvirtsion = int(libvirtsion) if libvirtsion < 7000: print >> sys.stderr, "\nWarning: low libvirt version, compatibility is not understood" except: print >> sys.stderr, "\nProblem getting libvirt version?" problem_count += 1 try: from workspacecontrol.api.exceptions import * except: print >> sys.stderr, "\n%sCannot locate the 'workspacecontrol' Python package." % ERR print >> sys.stderr, "\nIf you installed this from the directions, please contact the mailing list.." problem_count += 1 if problem_count:
pass logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d def deleteSnapshot(vm, name): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d ######### INITIALIZATION ######### hypervisor = "vbox" conn = None if hypervisor == "vbox": conn = libvirt.open('vbox:///session') if conn == None: logger.fatal("Failed to open connection to the hypervisor") sys.exit(1) logger.info("Using LibVirt %s and Hypervisor: %s. VMs found: %s" % (libvirt.getVersion(), hypervisor, conn.listDefinedDomains()))
# We don't know which it will be, so just set them all: domainname = opt[1] volumepath = opt[1] poolname = opt[1] elif opt[0] == "-2": socket = opt[1] elif opt[0] == "-i": interface = opt[1] elif opt[0] == "-d": disk = opt[1] elif opt[0] == "-v": verbose = 1 elif opt[0] == "-r": humanreadable = 1 version = libvirt.getVersion() # needed to know what features we support #conn=libvirt.openReadOnly('qemu+ssh://test8virt3/') #conn=libvirt.openReadOnly('remote://test8virt3/') #conn=libvirt.openReadOnly('qemu://test8virt3/system') # See: http://libvirt.org/uri.html # And: http://libvirt.org/remote.html if connecttype == 'qemu+ssh://': conn = libvirt.openReadOnly(connecttype + username + '@' + hostname + '/system' + '?socket=' + socket) elif connecttype == 'qemu://': # untested conn = libvirt.openReadOnly(connecttype + hostname + '/system' + '?socket=' + socket) elif connecttype == 'esx://': # partially implemented. (not all stats work) if version < 7000:
def _local_lib_ver(): return libvirt.getVersion()
def _get_root(self): root = ElementTree.Element('domain', type='kvm') ElementTree.SubElement(root, 'name').text = self.name ElementTree.SubElement(root, 'memory', unit='MiB').text = str(self.memory) ElementTree.SubElement(root, 'currentMemory', unit='MiB').text = str(self.memory) ElementTree.SubElement(root, 'vcpu', placement='static').text = str(self.vcpus) os_element = ElementTree.SubElement(root, 'os') ElementTree.SubElement(os_element, 'type', arch='x86_64').text = 'hvm' ElementTree.SubElement(os_element, 'boot', dev='hd') feature_element = ElementTree.SubElement(root, 'features') ElementTree.SubElement(feature_element, 'acpi') ElementTree.SubElement(feature_element, 'apic') #cpu_element = ElementTree.SubElement(root, 'cpu', mode='host-model') #ElementTree.SubElement(cpu_element, 'model', fallback='allow') cpu_element = ElementTree.SubElement(root, 'cpu', mode='custom') ElementTree.SubElement(cpu_element, 'model', fallback='allow').text = 'Haswell-noTSX' devices = ElementTree.SubElement(root, 'devices') # Add the HDD. Default. Should this be modularized like any other # devices? disk = ElementTree.SubElement(devices, 'disk', type='file', device='disk') ElementTree.SubElement(disk, 'driver', name='qemu', type='qcow2') ElementTree.SubElement(disk, 'source', file=self.disk_file) ElementTree.SubElement(disk, 'target', dev='vda', bus='virtio') # Some basic serial console devices serial_element = ElementTree.SubElement(devices, 'serial') ElementTree.SubElement(serial_element, 'target', port='0') console_element = ElementTree.SubElement(devices, 'console') ElementTree.SubElement(console_element, 'target', type='serial', port='0') graphics_element = ElementTree.SubElement(devices, 'graphics', type='vnc', port='-1', autoport='yes', listen='0.0.0.0') ElementTree.SubElement(graphics_element, 'listen', type='address', address='0.0.0.0') video_element = ElementTree.SubElement(root, 'video') ElementTree.SubElement(video_element, 'model', type='cirrus') # Add the qemu guest agent, only if the libvirt version is higher than # 1.0.6 which does not require source path channel = ElementTree.SubElement(devices, 'channel', type='unix') if libvirt.getVersion() < 1000006: ElementTree.SubElement(channel, 'source', mode='bind', path='/var/lib/libvirt/qemu/%s.agent' % self.name) else: ElementTree.SubElement(channel, 'source', mode='bind') ElementTree.SubElement(channel, 'target', type='virtio', name='org.qemu.guest_agent.0') for device_element in self.device_list: devices.append(device_element) return root
#!/usr/bin/env python # # Cloudlet Infrastructure for Mobile Computing # # Author: Kiryong Ha <*****@*****.**> # # Copyright (C) 2011-2013 Carnegie Mellon University # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import libvirt assert (libvirt.getVersion() >= 9004) # 0.9.4
def restoreSnapshot(vm, name): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d def deleteSnapshot(vm, name): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d ######### INITIALIZATION ######### hypervisor = "vbox" conn = None if hypervisor == "vbox": conn = libvirt.open('vbox:///session') if conn == None: logger.fatal("Failed to open connection to the hypervisor") sys.exit(1) logger.info("Using LibVirt %s and Hypervisor: %s. VMs found: %s" % (libvirt.getVersion(), hypervisor, conn.listDefinedDomains()))
def supports_spice(): return libvirt.getVersion() >= 8006
def main(): if os.geteuid() == 0: print("Do not run as root!") sys.exit(1) parser = argparse.ArgumentParser( description='Run a CLIP OS VM in a libvirt based testbed.') parser.add_argument('product', metavar='name', help='Product name') parser.add_argument('version', metavar='version', help='Product version') args = parser.parse_args() product_name = args.product product_version = args.version libvirt_template = os.path.join(repo_root_path(), "testbed", "qemu", "clipos-qemu.xml") spawn_virtmanager = False ovmf_code = os.path.join(repo_root_path(), "out", product_name, product_version, "efiboot", "bundle", "qemu-ovmf", "OVMF_CODE.fd") ovmf_vars_template = os.path.join(repo_root_path(), "out", product_name, product_version, "efiboot", "bundle", "qemu-ovmf", "OVMF_VARS.fd") qcow2_image = os.path.join(repo_root_path(), "run", "virtual_machines", "main.qcow2") # Name used for libvirt domain. This name must not include any '+' sign as # when doing TPM emulation, libvirt passes the guest name to swtpm, which # then uses it as a CN, for which '+' signs have a special meaning. name = "{name}-testbed_{name}-qemu".format(name=product_name).replace( '+', '--') # Look for qemu-system-x86_64 emulator = "qemu-system-x86_64" emulator_binpath = shutil.which(emulator) if not emulator_binpath: print("[!] Could not find {!r} emulator!") sys.exit(1) # Get a connection handle to the system libvirt daemon: conn = libvirt.open('qemu:///system') if not conn: print("[!] Could not connect to the system libvirt daemon!") sys.exit(1) # Destroy existing domain with the same name for domain in conn.listAllDomains(): if domain.name() == name: if domain.isActive(): domain.destroy() domain.undefineFlags( libvirt.VIR_DOMAIN_UNDEFINE_MANAGED_SAVE | libvirt.VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA | libvirt.VIR_DOMAIN_UNDEFINE_NVRAM) # The runtime working directory: the location where the containers bundles # will be created and managed (to put it differently, this is our # /var/lib/docker...). working_dir = os.path.join(repo_root_path(), "run/virtual_machines", name) if os.path.exists(working_dir): # obliterate directory unconditionnally as we may already have # destroyed the associated libvirt domain shutil.rmtree(working_dir) os.makedirs(working_dir) workdir_ovmf_code = os.path.join(working_dir, "OVMF_code.fd") workdir_ovmf_vars_template = os.path.join(working_dir, "OVMF_vars_template.fd") workdir_ovmf_vars = os.path.join(working_dir, "OVMF_vars.fd") try: shutil.copy(ovmf_code, workdir_ovmf_code) except: print("[!] Could not copy '{}' to workdir!".format(ovmf_code)) sys.exit(1) try: shutil.copy(ovmf_vars_template, workdir_ovmf_vars_template) except: print("[!] Could not copy '{}' to workdir!".format(ovmf_vars_template)) sys.exit(1) workdir_qcow2_image = os.path.join(working_dir, "main.qcow2") try: subprocess.run([ "qemu-img", "create", "-f", "qcow2", "-b", qcow2_image, "-F", "qcow2", "-q", workdir_qcow2_image ], check=True) except: print("[!] Could not create backing image for '{}' in workdir!".format( qcow2_image)) sys.exit(1) # Do we have a TPM emulator installed? (i.e. is swtpm in $PATH?) is_swtpm_present = bool(shutil.which('swtpm')) tpm_support_xmlhunk = "<tpm model='tpm-tis'><backend type='emulator' version='2.0'></backend></tpm>" # We require libvirt >= 4.5.0 to get swtpm working, check the current # libvirt version: _int_libvirt_version = libvirt.getVersion() # According to libvirt docs, getVersion() returns the libvirt version # as an integer x where x = 1000000*major + 1000*minor + release. # Compare versions with a more Pythonic way (tuples): libvirt_version = ( (_int_libvirt_version // 1000000), # major ((_int_libvirt_version // 1000) % 1000), # minor (_int_libvirt_version % 1000), # release ) libvirt_version_supports_swtpm = bool(libvirt_version >= (4, 5, 0)) is_swtpm_usable = is_swtpm_present and libvirt_version_supports_swtpm if not is_swtpm_usable: if not is_swtpm_present: print( """[!] swtpm (libtpms-based TPM emulator) could not be found in PATH but is required by libvirt for the TPM emulation.""") if not libvirt_version_supports_swtpm: print("""[!] Your libvirt version is too old to support swtpm (libtpms-based TPM emulator): libvirt 4.5.0 at least is required but your libvirt version is currently {libvirt_version}.""".format(libvirt_version=".".join( [str(i) for i in libvirt_version]), )) print("""[!] TPM cannot be emulated: falling back to launch a libvirt virtual machine without any emulated TPM.""") # Generate domain XML with open(libvirt_template, 'r') as xmlfile: xmlcontents = xmlfile.read() xmltpl = Template(xmlcontents) xmldomain = xmltpl.substitute( domain_name=name, ovmf_firmware_code_filepath=workdir_ovmf_code, ovmf_firmware_vars_filepath=workdir_ovmf_vars, ovmf_firmware_vars_template_filepath=workdir_ovmf_vars_template, qemu_x86_64_binpath=emulator_binpath, qcow2_main_disk_image_filepath=workdir_qcow2_image, tpm_support=(tpm_support_xmlhunk if is_swtpm_usable else ""), ) # Debug: # workdir_domain_xml = os.path.join(working_dir, "domain.xml") # with open(workdir_domain_xml, "w+") as xmlfile: # xmlfile.write(xmldomain) libvirt_domain = conn.defineXML(xmldomain) if not libvirt_domain: print("[!] Could define libvirt domain!") sys.exit(1) # Start the domain libvirt_domain.create() print("") if spawn_virtmanager: print( "[*] Spawning graphical virtual machine manager (\"virt-manager\")..." ) virt_manager_binpath = shutil.which("virt-manager") if not virt_manager_binpath: print("[!] Could not find virt-manager in PATH!") # virt-manager is expected to fork into background, i.e. the small # timeout subprocess.run([ virt_manager_binpath, "--connect", "qemu:///system", "--show-domain-console", name ], timeout=2, check=True) else: print("[*] Retrieve the virtual machine IP address with:") print("$ virsh --connect qemu:///system domifaddr {name}".format( name=name)) print("") print("[*] Connect locally via SSH with:") print("$ ssh -i cache/{product}/{version}/qemu/bundle/ssh_root \\". format(product=product_name, version=product_version)) print( " -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \\" ) print(" root@<domain_ip>") print("") try: print("[*] Interrupt the virtual machine with Control+C (SIGINT).\n" + "[*] Note: this will kill the virtual machine.") signal.pause() except KeyboardInterrupt: print("[*] Stopping virtual machine") for domain in conn.listAllDomains(): if domain.name() == name: if domain.isActive(): domain.destroy() break
def _populate_libvirt_domain_working_dir(self, working_dir: str) -> None: """Populate a given directory to be used as a working directory for the libvirt domain. This is made in order not to mess with the file serving to create the virtual machine (such as the main disk image or the UEFI vars file) and to ensure that all the changes that libvirt can bring to the underlying files of the virtualized environment are contained within this working directory. :param working_dir: the directory where the required files for the libvirt domain will be deployed and where libvirt will work """ if not os.path.exists(working_dir): os.makedirs(working_dir) workdir_qcow2_image = os.path.join(working_dir, "main_disk.qcow2") try: shutil.copy(self.qcow2_main_disk_image, workdir_qcow2_image) except: raise VirtualizedEnvironmentError(line( """The specified QCOW2 image file ({!r}) for the virtual machine main disk could not be copied into the virtual machine working directory. Cannot create the virtualized environment.""").format(self.qcow2_main_disk_image)) workdir_ovmf_code = os.path.join(working_dir, "OVMF_code.fd") try: shutil.copy(self.ovmf_firmware_code_filepath, workdir_ovmf_code) except: raise VirtualizedEnvironmentError(line( """The specified OVMF firmware code file ({!r}) could not be copied into the virtual machine working directory. Cannot create the virtualized environment.""") .format(self.ovmf_firmware_code_filepath)) workdir_ovmf_vars_template = os.path.join(working_dir, "OVMF_vars_template.fd") try: shutil.copy(self.ovmf_firmware_vars_template_filepath, workdir_ovmf_vars_template) except: raise VirtualizedEnvironmentError(line( """The specified OVMF firmware UEFI variables template file ({!r}) could not be copied into the virtual machine working directory. Cannot create the virtualized environment.""") .format(self.ovmf_firmware_vars_template_filepath)) # prepare the path to receive the OVMF UEFI vars file to be created # from the OVMF UEFI vars template file automatically by libvirt at the # first start of the domain workdir_ovmf_vars = os.path.join(working_dir, "OVMF_vars.fd") # create the libvirt domain and network XML files for the VM definition with open(self.libvirt_network_xml_template, 'r') as xmlfile: xmlcontents = xmlfile.read() xmltpl = Template(xmlcontents) try: external_iface = guess_external_netiface_name() except VirtualizedEnvironmentError: external_iface = 'nonguessable' network_name = self.name xmlnetwork = xmltpl.substitute( name=network_name, external_iface=external_iface, ) workdir_network_xml = os.path.join(working_dir, "network.xml") with open(workdir_network_xml, "w+") as xmlfile: xmlfile.write(xmlnetwork) # Do we have a TPM emulator installed? (i.e. is swtpm in $PATH?) is_swtpm_present = bool(shutil.which('swtpm')) tpm_support_xmlhunk = "<tpm model='tpm-tis'><backend type='emulator' version='2.0'></backend></tpm>" # We require libvirt >= 4.5.0 to get swtpm working, check the current # libvirt version: _int_libvirt_version = libvirt.getVersion() # According to libvirt docs, getVersion() returns the libvirt version # as an integer x where x = 1000000*major + 1000*minor + release. # Compare versions with a more Pythonic way (tuples): libvirt_version = ( (_int_libvirt_version // 1000000), # major ((_int_libvirt_version // 1000) % 1000), # minor (_int_libvirt_version % 1000), # release ) libvirt_version_supports_swtpm = bool(libvirt_version >= (4, 5, 0)) is_swtpm_usable = is_swtpm_present and libvirt_version_supports_swtpm if not is_swtpm_usable: if not is_swtpm_present: log.warn(line( """swtpm (libtpms-based TPM emulator) could not be found in PATH but is required by libvirt for the TPM emulation.""" )) if not libvirt_version_supports_swtpm: log.warn(line( """Your libvirt version is too old to support swtpm (libtpms-based TPM emulator): libvirt 4.5.0 at least is required but your libvirt version is currently {libvirt_version}.""" ).format( libvirt_version=".".join([str(i) for i in libvirt_version]), )) log.warn(line( """TPM cannot be emulated: falling back to launch a libvirt virtual machine without any emulated TPM.""")) with open(self.libvirt_domain_xml_template, 'r') as xmlfile: xmlcontents = xmlfile.read() xmltpl = Template(xmlcontents) xmldomain = xmltpl.substitute( domain_name=self.name, ovmf_firmware_code_filepath=workdir_ovmf_code, ovmf_firmware_vars_filepath=workdir_ovmf_vars, ovmf_firmware_vars_template_filepath=workdir_ovmf_vars_template, qemu_x86_64_binpath=self.emulator_binpath, qcow2_main_disk_image_filepath=workdir_qcow2_image, network_name=network_name, tpm_support=(tpm_support_xmlhunk if is_swtpm_usable else ""), ) workdir_domain_xml = os.path.join(working_dir, "domain.xml") with open(workdir_domain_xml, "w+") as xmlfile: xmlfile.write(xmldomain)
import atexit import logging import sys import threading import traceback try: from urlparse import urlparse except: from urllib.parse import urlparse log = logging.getLogger(__name__) HAS_LIBVIRT_PY = False try: import libvirt if libvirt.getVersion() >= 1000000: HAS_LIBVIRT_PY = True else: log.error('libvirt >= 1.0.0 required') except: pass # Import salt libs import salt.utils.event __virtualname__ = 'libvirt_events' def __virtual__(): ''' Only load if libvirt python binding is present
# We don't know which it will be, so just set them all: domainname = opt[1] volumepath = opt[1] poolname = opt[1] elif opt[0] == "-2": socket = opt[1] elif opt[0] == "-i": interface = opt[1] elif opt[0] == "-d": disk = opt[1] elif opt[0] == "-v": verbose = 1 elif opt[0] == "-r": humanreadable = 1 version = libvirt.getVersion() # needed to know what features we support #conn=libvirt.openReadOnly('qemu+ssh://test8virt3/') #conn=libvirt.openReadOnly('remote://test8virt3/') #conn=libvirt.openReadOnly('qemu://test8virt3/system') # See: http://libvirt.org/uri.html # And: http://libvirt.org/remote.html if connecttype == 'qemu+ssh://': conn=libvirt.openReadOnly(connecttype+username+'@'+hostname+'/system'+'?socket='+socket) elif connecttype == 'qemu://': # untested conn=libvirt.openReadOnly(connecttype+hostname+'/system'+'?socket='+socket) elif connecttype == 'esx://': # partially implemented. (not all stats work) if version < 7000: print "The ESX connect type only works correctly in libvirt 0.7.0 and newer with ESX compiled in" help(1)
def initialize(): LibvirtMonitor.virEventLoopPureStart() logging.info('Libvirt version installed: %d' %(libvirt.getVersion())) vc = libvirt.open(None) #XXX: maybe could it be xen:/// but callbacks will only be registered for XEN domain vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, LifeCycleEventCallbacks, None)
import libvirt # https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventType LIBVIRT_VERSION = libvirt.getVersion() vir_domain_event_type = { libvirt.VIR_DOMAIN_EVENT_DEFINED: 'VIR_DOMAIN_EVENT_DEFINED', libvirt.VIR_DOMAIN_EVENT_UNDEFINED: 'VIR_DOMAIN_EVENT_UNDEFINED', libvirt.VIR_DOMAIN_EVENT_STARTED: 'VIR_DOMAIN_EVENT_STARTED', libvirt.VIR_DOMAIN_EVENT_SUSPENDED: 'VIR_DOMAIN_EVENT_SUSPENDED', libvirt.VIR_DOMAIN_EVENT_RESUMED: 'VIR_DOMAIN_EVENT_RESUMED', libvirt.VIR_DOMAIN_EVENT_STOPPED: 'VIR_DOMAIN_EVENT_STOPPED', libvirt.VIR_DOMAIN_EVENT_SHUTDOWN: 'VIR_DOMAIN_EVENT_SHUTDOWN', # The following are commented as not define for libvirt-python, # but are defined in libvirt c module # libvirt.VIR_DOMAIN_EVENT_LAST: 'VIR_DOMAIN_EVENT_LAST' } def event_type_to_str(virtDomEventType): '''Returns str format of domain event type. Returns None for failures/unknown event types ''' return vir_domain_event_type.get(virtDomEventType) virDomainEventDefinedDetailType = { libvirt.VIR_DOMAIN_EVENT_DEFINED_ADDED: 'VIR_DOMAIN_EVENT_DEFINED_ADDED: Newly created config file', libvirt.VIR_DOMAIN_EVENT_DEFINED_UPDATED: