def setup_login(self, hostname, username, password=None): """ Setup login on VM. :param hostname: the hostname. :param username: the username. :param password: the password. """ if not self.logged: self.remote = Remote(hostname, username, password) # pylint: disable=W0201 res = self.remote.uptime() if res.succeeded: self.logged = True else: self.logged = False
def setup_login(self, hostname, username, password=None): """ Setup login on VM. :param hostname: the hostname. :param username: the username. :param password: the password. """ if not self.logged: self.remote = Remote(hostname, username, password) res = self.remote.uptime() if res.succeeded: self.logged = True else: self.logged = False
class VM: """ The Virtual Machine handler class. """ def __init__(self, hypervisor, domain): """ Creates an instance of VM class. :param hypervisor: an instance of :class:`Hypervisor`. :param domain: an instance of :class:`libvirt.virDomain`. """ self.hypervisor = hypervisor self.domain = domain self.logged = False self.snapshot = None def __str__(self): return "%s('%s', '%s')" % (self.__class__.__name__, self.hypervisor.uri, self.domain.name()) @property def is_active(self): """ Property to check if VM is active. :return: if VM is active. :rtype: Boolean """ return bool(self.domain.isActive()) @property def name(self): """ Property with the name of VM. :return: the name of VM. """ return self.domain.name() @property def state(self): """ Property with the state of VM. :return: current state name. """ states = ['No state', 'Running', 'Blocked', 'Paused', 'Shutting down', 'Shutoff', 'Crashed'] return states[self.domain.info()[0]] def start(self): """ Start VM. """ if self.is_active is False: self.domain.create() def suspend(self): """ Suspend VM. """ if self.is_active: self.domain.suspend() def resume(self): """ Resume VM. """ if self.is_active: self.domain.resume() def reboot(self): """ Reboot VM. """ if self.is_active: self.domain.reboot() def shutdown(self): """ Shutdown VM. """ if self.is_active: self.domain.shutdown() def reset(self): """ Reset VM. """ if self.is_active: self.domain.reset() def stop(self): """ Stop VM. """ if self.is_active: self.domain.destroy() def _system_checkpoint_xml(self, name=None, description=None): def create_element(doc, tag, text): el = doc.createElement(tag) txt = doc.createTextNode(text) el.appendChild(txt) return el doc = minidom.Document() root = doc.createElement('domainsnapshot') doc.appendChild(root) if name is not None: root.appendChild(create_element(doc, 'name', name)) if description is None: description = 'Avocado Test Runner' root.appendChild(create_element(doc, 'description', description)) return doc.toxml() @property def snapshots(self): return self.domain.snapshotListNames() def create_snapshot(self, name=None): """ Creates a snapshot of kind 'system checkpoint'. """ xml = self._system_checkpoint_xml(name) self.snapshot = self.domain.snapshotCreateXML(xml) return self.snapshot def revert_snapshot(self): """ Revert to previous snapshot. """ if self.snapshot is not None: self.domain.revertToSnapshot(self.snapshot) def delete_snapshot(self): """ Delete the current snapshot. """ if self.snapshot is not None: self.snapshot.delete() self.snapshot = None def restore_snapshot(self): """ Revert to previous snapshot and delete the snapshot point. """ self.revert_snapshot() self.delete_snapshot() def setup_login(self, hostname, username, password=None): """ Setup login on VM. :param hostname: the hostname. :param username: the username. :param password: the password. """ if not self.logged: self.remote = Remote(hostname, username, password) # pylint: disable=W0201 res = self.remote.uptime() if res.succeeded: self.logged = True else: self.logged = False def ip_address(self, timeout=30): """ Returns the domain IP address consulting qemu-guest-agent through libvirt. :returns: either the IP address or None if not found :rtype: str or None """ timelimit = time.time() + timeout while True: try: ip = self._get_ip_from_libvirt_agent() if ip is not None: return ip except libvirt.libvirtError as exception: # Qemu guest agent takes time to be ready, but # libvirt raises an exception here if it's not. # Let's be nice and wait for the guest agent, if # that's the problem. errno = libvirt.VIR_ERR_AGENT_UNRESPONSIVE if exception.get_error_code() == errno: pass else: return None if time.time() > timelimit: return None time.sleep(1) def _get_ip_from_libvirt_agent(self): """ Retrieves from libvirt/qemu-guest-agent the first IPv4 non-loopback IP from the first non-loopback device. Libvirt response example: {'ens3': {'addrs': [{'addr': '192.168.122.4', 'prefix': 24, 'type': 0}, {'addr': 'fe80::5054:ff:fe0c:9c9b', 'prefix': 64, 'type': 1}], 'hwaddr': '52:54:00:0c:9c:9b'}, 'lo': {'addrs': [{'addr': '127.0.0.1', 'prefix': 8, 'type': 0}, {'addr': '::1', 'prefix': 128, 'type': 1}], 'hwaddr': '00:00:00:00:00:00'}} :return: either the IP address or None if not found. """ querytype = libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT ipversion = libvirt.VIR_IP_ADDR_TYPE_IPV4 ifaces = self.domain.interfaceAddresses(querytype) for _, data in ifaces.items(): if data['addrs'] and data['hwaddr'] != '00:00:00:00:00:00': ip_addr = data['addrs'][0]['addr'] ip_type = data['addrs'][0]['type'] if ip_type == ipversion and not ip_addr.startswith('127.'): return ip_addr return None
class VM(object): """ The Virtual Machine handler class. """ def __init__(self, hypervisor, domain): """ Creates an instance of VM class. :param hypervisor: an instance of :class:`Hypervisor`. :param domain: an instance of :class:`libvirt.virDomain`. """ self.hypervisor = hypervisor self.domain = domain self.logged = False self.snapshot = None def __str__(self): return "%s('%s', '%s')" % (self.__class__.__name__, self.hypervisor.uri, self.domain.name()) @property def is_active(self): """ Property to check if VM is active. :return: if VM is active. :rtype: Boolean """ return bool(self.domain.isActive()) @property def name(self): """ Property with the name of VM. :return: the name of VM. """ return self.domain.name() @property def state(self): """ Property with the state of VM. :return: current state name. """ states = ['No state', 'Running', 'Blocked', 'Paused', 'Shutting down', 'Shutoff', 'Crashed'] return states[self.domain.info()[0]] def start(self): """ Start VM. """ if self.is_active is False: self.domain.create() def suspend(self): """ Suspend VM. """ if self.is_active: self.domain.suspend() def resume(self): """ Resume VM. """ if self.is_active: self.domain.resume() def reboot(self): """ Reboot VM. """ if self.is_active: self.domain.reboot() def shutdown(self): """ Shutdown VM. """ if self.is_active: self.domain.shutdown() def reset(self): """ Reset VM. """ if self.is_active: self.domain.reset() def stop(self): """ Stop VM. """ if self.is_active: self.domain.destroy() def _system_checkpoint_xml(self, name=None, description=None): def create_element(doc, tag, text): el = doc.createElement(tag) txt = doc.createTextNode(text) el.appendChild(txt) return el doc = minidom.Document() root = doc.createElement('domainsnapshot') doc.appendChild(root) if name is not None: root.appendChild(create_element(doc, 'name', name)) if description is None: description = 'Avocado Test Runner' root.appendChild(create_element(doc, 'description', description)) return doc.toxml() @property def snapshots(self): return self.domain.snapshotListNames() def create_snapshot(self, name=None): """ Creates a snapshot of kind 'system checkpoint'. """ xml = self._system_checkpoint_xml(name) self.snapshot = self.domain.snapshotCreateXML(xml) return self.snapshot def revert_snapshot(self): """ Revert to previous snapshot. """ if self.snapshot is not None: self.domain.revertToSnapshot(self.snapshot) def delete_snapshot(self): """ Delete the current snapshot. """ if self.snapshot is not None: self.snapshot.delete() self.snapshot = None def restore_snapshot(self): """ Revert to previous snapshot and delete the snapshot point. """ self.revert_snapshot() self.delete_snapshot() def setup_login(self, hostname, username, password=None): """ Setup login on VM. :param hostname: the hostname. :param username: the username. :param password: the password. """ if not self.logged: self.remote = Remote(hostname, username, password) res = self.remote.uptime() if res.succeeded: self.logged = True else: self.logged = False def ip_address(self, timeout=30): """ Returns the domain IP address consulting qemu-guest-agent through libvirt. :returns: either the IP address or None if not found :rtype: str or None """ timelimit = time.time() + timeout while True: try: ip = self._get_ip_from_libvirt_agent() if ip is not None: return ip except libvirt.libvirtError as exception: # Qemu guest agent takes time to be ready, but # libvirt raises an exception here if it's not. # Let's be nice and wait for the guest agent, if # that's the problem. errno = libvirt.VIR_ERR_AGENT_UNRESPONSIVE if exception.get_error_code() == errno: pass else: return None if time.time() > timelimit: return None time.sleep(1) def _get_ip_from_libvirt_agent(self): """ Retrieves from libvirt/qemu-guest-agent the first IPv4 non-loopback IP from the first non-loopback device. Libvirt response example: {'ens3': {'addrs': [{'addr': '192.168.122.4', 'prefix': 24, 'type': 0}, {'addr': 'fe80::5054:ff:fe0c:9c9b', 'prefix': 64, 'type': 1}], 'hwaddr': '52:54:00:0c:9c:9b'}, 'lo': {'addrs': [{'addr': '127.0.0.1', 'prefix': 8, 'type': 0}, {'addr': '::1', 'prefix': 128, 'type': 1}], 'hwaddr': '00:00:00:00:00:00'}} :return: either the IP address or None if not found. """ querytype = libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT ipversion = libvirt.VIR_IP_ADDR_TYPE_IPV4 ifaces = self.domain.interfaceAddresses(querytype) for iface, data in iteritems(ifaces): if data['addrs'] and data['hwaddr'] != '00:00:00:00:00:00': ip_addr = data['addrs'][0]['addr'] ip_type = data['addrs'][0]['type'] if ip_type == ipversion and not ip_addr.startswith('127.'): return ip_addr return None