def _get_domain_ips_and_macs(
            domain: libvirt.virDomain) -> Tuple[List[str], List[str]]:
        interfaces_sources = [
            # getting all DHCP leases IPs
            libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE,
            # getting static IPs via ARP
            libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP,
        ]

        interfaces = {}
        for addresses_source in interfaces_sources:
            try:
                interfaces.update(
                    **domain.interfaceAddresses(addresses_source))
            except libvirt.libvirtError:
                log.exception(
                    "Got an error while updating domain's network addresses")

        ips = []
        macs = []
        log.debug(f"Host {domain.name()} interfaces are {interfaces}")
        if interfaces:
            for (_, val) in interfaces.items():
                if val["addrs"]:
                    for addr in val["addrs"]:
                        ips.append(addr["addr"])
                        macs.append(val["hwaddr"])
        if ips:
            log.info("Host %s ips are %s", domain.name(), ips)
        if macs:
            log.info("Host %s macs are %s", domain.name(), macs)
        return ips, macs
Exemple #2
0
def snapshot_domain(dom: libvirt.virDomain, tmpDir: str, disks: dict, wantedDisks: list):
    printNoNL("Creating temporary snapshot. ")

    xml_snapshot = ET.Element(SNAPSHOT_XML_ROOT)
    xml_disks = ET.SubElement(xml_snapshot, SNAPSHOT_XML_DISK_LIST)
    
    for disk in disks.values():
        params = dict()
        params[SNAPSHOT_XML_DISK_NAME] = disk["name"]
        if disk["name"] in wantedDisks:
            xml_disk = ET.SubElement(xml_disks, SNAPSHOT_XML_DISK, **params)
            new_snapshot_path = tmpDir + '/' + disk["name"] + '.qcow2'
            #Make sure file has correct owner and permissions.
            f = open(new_snapshot_path, "w+")
            f.close()
            os.chmod(new_snapshot_path, 0o664)
            source_params = dict()
            source_params[SNAPSHOT_XML_SOURCE_FILE] = new_snapshot_path
            ET.SubElement(xml_disk, SNAPSHOT_XML_SOURCE, **source_params)
        else:
            params[SNAPSHOT_XML_DISK_SNAPSHOT] = "no"
            xml_disk = ET.SubElement(xml_disks, SNAPSHOT_XML_DISK, **params)
    
    xml_string = ET.tostring(xml_snapshot).decode('UTF-8')
    dom.snapshotCreateXML(xml_string, flags = libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA | libvirt. VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY | libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC)
    print("Done.")
Exemple #3
0
def revert_snapshot_for_disk(dom: libvirt.virDomain, disk:str):
    printNoNL(" Block committing " + disk + ".")
    dom.blockCommit(disk, None, None, flags=libvirt.VIR_DOMAIN_BLOCK_COMMIT_SHALLOW | libvirt.VIR_DOMAIN_BLOCK_COMMIT_ACTIVE)
    while True:
        info = dom.blockJobInfo(disk)
        cur = info["cur"]
        end = info["end"]
        if cur >= end:
            break
        message = ('\r Block committing ' + disk + ': {:.2%}' + SPACE_PADDING).format(cur/end)
        printNoNL(message)
    printNoNL("\r Block committing " + disk + ": Finishing." + SPACE_PADDING)
    dom.blockJobAbort(disk, flags=libvirt.VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT)
    print("\r Block committing " + disk + ". Done." + SPACE_PADDING)
Exemple #4
0
def storage_allocated_gb(domain: libvirt.virDomain):
    capacity = 0
    for device in storage_devices(domain):
        capacity += domain.blockInfo(device)[0]
    return round(
        capacity / 1024**3, 2
    )  # convert bytes to gb and round to 2 digits precision after the decimal point.
Exemple #5
0
def mac_from_vm(vm: libvirt.virDomain = None) -> str:
    """
    Parses the vm's XML to return just the mac address as a string
    """
    doc = minidom.parseString(vm.XMLDesc())
    interfaces = doc.getElementsByTagName('mac')
    return interfaces[0].getAttribute('address')
Exemple #6
0
def storage_used_gb(domain: libvirt.virDomain):
    allocation = 0
    for device in storage_devices(domain):
        allocation += domain.blockInfo(device)[1]
    return round(
        allocation / 1024**3, 2
    )  # convert bytes to gb and round to 2 digits precision after the decimal point.
Exemple #7
0
def backup_vm_def(dom: libvirt.virDomain, tar:tarfileProg.TarFile):
    printNoNL("Writing backup of vm definition. ")
    _, xmlFile_path = tempfile.mkstemp(suffix=".xml", prefix="backup_vm_def_")
    xmlFile = open(xmlFile_path, 'w')
    xmlFile.write(dom.XMLDesc())
    xmlFile.close()
    tar.add(xmlFile_path, arcname=os.path.join(backup_name,"vm-def.xml"))
    os.remove(xmlFile_path)
    print("Done.")
Exemple #8
0
def hostname(domain: libvirt.virDomain):
    try:
        with suppress_stderr():
            hostname = domain.hostname()
        return hostname
    except libvirt.libvirtError:
        macs = []
        ifaces = domain.interfaceAddresses(
            libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)
        for (_, val) in ifaces.items():
            if val["hwaddr"]:
                macs.append(val["hwaddr"])
        conn = domain.connect()
        for network in conn.listAllNetworks(
                libvirt.VIR_CONNECT_LIST_NETWORKS_ACTIVE):
            for lease in network.DHCPLeases():
                for mac in macs:
                    if lease["mac"] == mac:
                        return lease["hostname"]
Exemple #9
0
def ip_addresses(domain: libvirt.virDomain):
    ips = []
    ifaces = domain.interfaceAddresses(
        libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)
    for (_, val) in ifaces.items():
        if val["addrs"]:
            for ipaddr in val["addrs"]:
                if (ipaddr["type"] == libvirt.VIR_IP_ADDR_TYPE_IPV4
                        or ipaddr["type"] == libvirt.VIR_IP_ADDR_TYPE_IPV6):
                    ips.append(ipaddr["addr"])
    return ips
Exemple #10
0
def domain_address(domain: libvirt.virDomain) -> str:
    interfaces = domain.interfaceAddresses(
        libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)

    for iface in interfaces.values():
        if isinstance(iface, dict) and 'addrs' in iface:
            for address in iface['addrs']:
                if 'addr' in address:
                    return address['addr']

    raise RuntimeError("No IP address found for the given domain")
Exemple #11
0
def domain_vnc_server(domain: libvirt.virDomain) -> str:
    etree = ElementTree.fromstring(domain.XMLDesc())

    vnc = etree.find('.//graphics[@type="vnc"]')
    if vnc is None:
        raise RuntimeError("No VNC connection found for the given domain")

    if 'socket' in vnc.keys():
        return vnc.get('socket')
    elif {'listen', 'port'} <= set(vnc.keys()):
        return '::'.join((vnc.get('listen'), vnc.get('port')))
    else:
        raise RuntimeError("No valid VNC connection found for the given domain")
Exemple #12
0
def libvirt_screenshot(domain: libvirt.virDomain) -> BytesIO:
    """Takes a screenshot of the vnc connection of the guest.
    The resulting image file will be in Portable Pixmap format (PPM).

    """
    def handler(_, buff, file_handler):
        file_handler.write(buff)

    string = BytesIO()
    stream = domain.connect().newStream(0)

    try:
        domain.screenshot(stream, 0, 0)
        stream.recvAll(handler, string)
    except Exception as error:
        stream.abort()

        raise RuntimeError("Unable to take screenshot") from error
    else:
        stream.finish()

    return string
Exemple #13
0
    def _status_code(self, domain:libvirt.virDomain):
        '''
        获取虚拟机的当前状态码

        :param domain: 虚拟机实例
        :return:
            success: state_code:int

        :raise VirtError()
        '''
        try:
            info = domain.info()
            return info[0]
        except libvirt.libvirtError as e:
            raise VirtError(err=e)
Exemple #14
0
    def status_code(domain: libvirt.virDomain):
        """
        获取虚拟机的当前状态码

        :param domain: 虚拟机实例
        :return:
            success: state_code:int

        :raise VirtError()
        """
        try:
            info = domain.info()
            return info[0]
        except libvirt.libvirtError as e:
            raise wrap_error(err=e)
def print_dom_ifaces(dom: libvirt.virDomain) -> None:
    ifaces = dom.interfaceAddresses(
        libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)
    if ifaces is None:
        print("Failed to get domain interfaces")
        exit(0)

    print(" {0:10} {1:20} {2:12} {3}".format("Interface", "MAC address",
                                             "Protocol", "Address"))

    for (name, val) in ifaces.items():
        if val['addrs']:
            for addr in val['addrs']:
                print(" {0:10} {1:19} {2:12} {3}/{4}".format(
                    name, val['hwaddr'], IPTYPE[addr['type']], addr['addr'],
                    addr['prefix']))
        else:
            print(" {0:10} {1:19} {2:12} {3}".format(name, val['hwaddr'],
                                                     "N/A", "N/A"))
Exemple #16
0
    def start_domain(self, domain: libvirt.virDomain):
        """
        开机启动一个虚拟机

        :return:
            success: True
            failed: False

        :raise VirtError()
        """
        if self.domain_is_running(domain):
            return True

        try:
            res = domain.create()
            if res == 0:
                return True
            return False
        except libvirt.libvirtError as e:
            raise wrap_error(err=e, msg=f'启动虚拟机失败,{str(e)}')
Exemple #17
0
    def shutdown_domain(self, domain: libvirt.virDomain):
        """
        关机

        :return:
            success: True
            failed: False

        :raise VirtError()
        """
        if not self.domain_is_running(domain):
            return True

        try:
            res = domain.shutdown()
            if res == 0:
                return True
            return False
        except libvirt.libvirtError as e:
            raise wrap_error(err=e, msg=f'关闭虚拟机失败, {str(e)}')
Exemple #18
0
    def power_off_domain(self, domain: libvirt.virDomain):
        """
        关闭电源

        :return:
            success: True
            failed: False

        :raise VirtError()
        """
        if not self.domain_is_running(domain):
            return True

        res = domain.destroy()
        try:
            if res == 0:
                return True
            return False
        except libvirt.libvirtError as e:
            raise wrap_error(err=e, msg=f'关闭虚拟机电源失败, {str(e)}')
Exemple #19
0
def myDomainEventDeviceRemovalFailedCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, dev: str, opaque: _T) -> None:
    print("myDomainEventDeviceRemovalFailedCallback: Domain %s(%s) failed to remove device: %s" % (
        dom.name(), dom.ID(), dev))
Exemple #20
0
def myDomainEventJobCompletedCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, params: Dict[str, Any], opaque: _T) -> None:
    print("myDomainEventJobCompletedCallback: Domain %s(%s) %s" % (
        dom.name(), dom.ID(), params))
Exemple #21
0
def myDomainEventMigrationIteration(conn: libvirt.virConnect, dom: libvirt.virDomain, iteration: int, opaque: _T) -> None:
    print("myDomainEventMigrationIteration: Domain %s(%s) started migration iteration %d" % (
        dom.name(), dom.ID(), iteration))
Exemple #22
0
def myDomainEventDeviceAddedCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, dev: str, opaque: _T) -> None:
    print("myDomainEventDeviceAddedCallback: Domain %s(%s) device added: %s" % (
        dom.name(), dom.ID(), dev))
Exemple #23
0
def myDomainEventAgentLifecycleCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, state: int, reason: int, opaque: _T) -> None:
    print("myDomainEventAgentLifecycleCallback: Domain %s(%s) %s %s" % (
        dom.name(), dom.ID(), AGENT_STATES[state], AGENT_REASONS[reason]))
Exemple #24
0
def myDomainEventBlockJob2Callback(conn: libvirt.virConnect, dom: libvirt.virDomain, disk: str, type: int, status: int, opaque: _T) -> None:
    print("myDomainEventBlockJob2Callback: Domain %s(%s) %s on disk %s %s" % (
        dom.name(), dom.ID(), BLOCK_JOB_TYPES[type], disk, BLOCK_JOB_STATUS[status]))
Exemple #25
0
def myDomainEventMemoryFailureCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, recipient: int, action: int, flags: int, opaque: _T) -> None:
    print("myDomainEventMemoryFailureCallback: Domain %s(%s) memory failure recipient %d action %d flags %d" % (
        dom.name(), dom.ID(), recipient, action, flags))
Exemple #26
0
def myDomainEventMetadataChangeCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, mtype: int, nsuri: str, opaque: _T) -> None:
    print("myDomainEventMetadataChangeCallback: Domain %s(%s) changed metadata mtype=%d nsuri=%s" % (
        dom.name(), dom.ID(), mtype, nsuri))
 def __init__(self, libvirt_domain: libvirt.virDomain):
     self.libvirt_domain = libvirt_domain
     self.name = libvirt_domain.name()
     self.libvirt_snapshot = None
Exemple #28
0
def myDomainEventBlockThresholdCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, dev: str, path: str, threshold: int, excess: int, opaque: _T) -> None:
    print("myDomainEventBlockThresholdCallback: Domain %s(%s) block device %s(%s) threshold %d exceeded by %d" % (
        dom.name(), dom.ID(), dev, path, threshold, excess))
Exemple #29
0
def myDomainEventBalloonChangeCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, actual: int, opaque: _T) -> None:
    print("myDomainEventBalloonChangeCallback: Domain %s(%s) %d" % (
        dom.name(), dom.ID(), actual))
Exemple #30
0
 def __init__(self, libvirt_domain: libvirt.virDomain):
     self.libvirt_domain = libvirt_domain
     self.name = libvirt_domain.name()
     self.libvirt_snapshot = None
Exemple #31
0
def myDomainEventPMSuspendDiskCallback(conn: libvirt.virConnect, dom: libvirt.virDomain, reason: int, opaque: _T) -> None:
    print("myDomainEventPMSuspendDiskCallback: Domain %s(%s) system pmsuspend_disk" % (
        dom.name(), dom.ID()))