def start(self): """ Starts this VM. """ self.uuid = virsh.domuuid(self.name, uri=self.connect_uri) # Pull in mac addresses from libvirt guest definition for index, nic in enumerate(self.virtnet): try: mac = self.get_virsh_mac_address(index) if not nic.has_key('mac'): logging.debug("Updating nic %d with mac %s on vm %s" % (index, mac, self.name)) nic.mac = mac elif nic.mac != mac: logging.warning("Requested mac %s doesn't match mac %s " "as defined for vm %s" % (nic.mac, mac, self.name)) #TODO: Checkout/Set nic_model, nettype, netdst also except virt_vm.VMMACAddressMissingError: logging.warning("Nic %d requested by test but not defined for" " vm %s" % (index, self.name)) if virsh.start(self.name, uri=self.connect_uri): # Wait for the domain to be created has_started = utils_misc.wait_for(func=self.is_alive, timeout=60, text=("waiting for domain %s " "to start" % self.name)) if has_started is None: raise virt_vm.VMStartError(self.name, "libvirt domain not " "active after start") self.uuid = virsh.domuuid(self.name, uri=self.connect_uri) else: raise virt_vm.VMStartError(self.name, "libvirt domain failed " "to start")
def start(self): """ Starts this VM. """ self.uuid = virsh.domuuid(self.name, uri=self.connect_uri) # Pull in mac addresses from libvirt guest definition for index, nic in enumerate(self.virtnet): try: mac = self.get_virsh_mac_address(index) if not nic.has_key("mac"): logging.debug("Updating nic %d with mac %s on vm %s" % (index, mac, self.name)) nic.mac = mac elif nic.mac != mac: logging.warning( "Requested mac %s doesn't match mac %s " "as defined for vm %s" % (nic.mac, mac, self.name) ) # TODO: Checkout/Set nic_model, nettype, netdst also except virt_vm.VMMACAddressMissingError: logging.warning("Nic %d requested by test but not defined for" " vm %s" % (index, self.name)) if virsh.start(self.name, uri=self.connect_uri): # Wait for the domain to be created has_started = utils_misc.wait_for( func=self.is_alive, timeout=60, text=("waiting for domain %s " "to start" % self.name) ) if has_started is None: raise virt_vm.VMStartError(self.name, "libvirt domain not " "active after start") self.uuid = virsh.domuuid(self.name, uri=self.connect_uri) else: raise virt_vm.VMStartError(self.name, "libvirt domain failed " "to start")
def get_uuid(self): """ Return VM's UUID. """ uuid = virsh.domuuid(self.name, uri=self.connect_uri) # only overwrite it if it's not set if self.uuid is None: self.uuid = uuid return self.uuid
def create(self, name=None, params=None, root_dir=None, timeout=5.0, migration_mode=None, mac_source=None): """ Start the VM by running a qemu command. All parameters are optional. If name, params or root_dir are not supplied, the respective values stored as class attributes are used. @param name: The name of the object @param params: A dict containing VM params @param root_dir: Base directory for relative filenames @param migration_mode: If supplied, start VM for incoming migration using this protocol (either 'tcp', 'unix' or 'exec') @param migration_exec_cmd: Command to embed in '-incoming "exec: ..."' (e.g. 'gzip -c -d filename') if migration_mode is 'exec' @param mac_source: A VM object from which to copy MAC addresses. If not specified, new addresses will be generated. @raise VMCreateError: If qemu terminates unexpectedly @raise VMKVMInitError: If KVM initialization fails @raise VMHugePageError: If hugepage initialization fails @raise VMImageMissingError: If a CD image is missing @raise VMHashMismatchError: If a CD image hash has doesn't match the expected hash @raise VMBadPATypeError: If an unsupported PCI assignment type is requested @raise VMPAError: If no PCI assignable devices could be assigned """ error.context("creating '%s'" % self.name) self.destroy(free_mac_addresses=False) if name is not None: self.name = name if params is not None: self.params = params if root_dir is not None: self.root_dir = root_dir name = self.name params = self.params root_dir = self.root_dir # Verify the md5sum of the ISO images for cdrom in params.objects("cdroms"): if params.get("medium") == "import": break cdrom_params = params.object_params(cdrom) iso = cdrom_params.get("cdrom") if ( (self.driver_type == "xen") and (params.get("hvm_or_pv") == "pv") and (os.path.basename(iso) == "ks.iso") ): continue if iso: iso = utils_misc.get_path(data_dir.get_data_dir(), iso) if not os.path.exists(iso): raise virt_vm.VMImageMissingError(iso) compare = False if cdrom_params.get("md5sum_1m"): logging.debug("Comparing expected MD5 sum with MD5 sum of " "first MB of ISO file...") actual_hash = utils.hash_file(iso, 1048576, method="md5") expected_hash = cdrom_params.get("md5sum_1m") compare = True elif cdrom_params.get("md5sum"): logging.debug("Comparing expected MD5 sum with MD5 sum of " "ISO file...") actual_hash = utils.hash_file(iso, method="md5") expected_hash = cdrom_params.get("md5sum") compare = True elif cdrom_params.get("sha1sum"): logging.debug("Comparing expected SHA1 sum with SHA1 sum " "of ISO file...") actual_hash = utils.hash_file(iso, method="sha1") expected_hash = cdrom_params.get("sha1sum") compare = True if compare: if actual_hash == expected_hash: logging.debug("Hashes match") else: raise virt_vm.VMHashMismatchError(actual_hash, expected_hash) # Make sure the following code is not executed by more than one thread # at the same time lockfile = open("/tmp/libvirt-autotest-vm-create.lock", "w+") fcntl.lockf(lockfile, fcntl.LOCK_EX) try: # Handle port redirections redir_names = params.objects("redirs") host_ports = utils_misc.find_free_ports(5000, 6000, len(redir_names)) self.redirs = {} for i in range(len(redir_names)): redir_params = params.object_params(redir_names[i]) guest_port = int(redir_params.get("guest_port")) self.redirs[guest_port] = host_ports[i] # Find available PCI devices self.pci_devices = [] for device in params.objects("pci_devices"): self.pci_devices.append(device) # Find available VNC port, if needed if params.get("display") == "vnc": if params.get("vnc_autoport") == "yes": self.vnc_port = None self.vnc_autoport = True else: self.vnc_port = utils_misc.find_free_port(5900, 6100) self.vnc_autoport = False # Find available spice port, if needed if params.get("spice"): self.spice_port = utils_misc.find_free_port(8000, 8100) # Find random UUID if specified 'uuid = random' in config file if params.get("uuid") == "random": f = open("/proc/sys/kernel/random/uuid") self.uuid = f.read().strip() f.close() # Generate or copy MAC addresses for all NICs for nic in self.virtnet: nic_params = dict(nic) if mac_source: # Will raise exception if source doesn't # have cooresponding nic logging.debug("Copying mac for nic %s from VM %s" % (nic.nic_name, mac_source.nam)) nic_params["mac"] = mac_source.get_mac_address(nic.nic_name) # make_create_command() calls vm.add_nic (i.e. on a copy) nic = self.add_nic(**nic_params) logging.debug("VM.create activating nic %s" % nic) self.activate_nic(nic.nic_name) # Make qemu command install_command = self.make_create_command() logging.info("Running libvirt command (reformatted):") for item in install_command.replace(" -", " \n -").splitlines(): logging.info("%s", item) utils.run(install_command, verbose=False) # Wait for the domain to be created utils_misc.wait_for(func=self.is_alive, timeout=60, text=("waiting for domain %s to start" % self.name)) self.uuid = virsh.domuuid(self.name, uri=self.connect_uri) # Establish a session with the serial console if self.only_pty == True: self.serial_console = aexpect.ShellSession( "virsh console %s" % self.name, auto_close=False, output_func=utils_misc.log_line, output_params=("serial-%s.log" % name,), ) else: self.serial_console = aexpect.ShellSession( "tail -f %s" % self.get_serial_console_filename(), auto_close=False, output_func=utils_misc.log_line, output_params=("serial-%s.log" % name,), ) finally: fcntl.lockf(lockfile, fcntl.LOCK_UN) lockfile.close()
def create(self, name=None, params=None, root_dir=None, timeout=5.0, migration_mode=None, mac_source=None): """ Start the VM by running a qemu command. All parameters are optional. If name, params or root_dir are not supplied, the respective values stored as class attributes are used. @param name: The name of the object @param params: A dict containing VM params @param root_dir: Base directory for relative filenames @param migration_mode: If supplied, start VM for incoming migration using this protocol (either 'tcp', 'unix' or 'exec') @param migration_exec_cmd: Command to embed in '-incoming "exec: ..."' (e.g. 'gzip -c -d filename') if migration_mode is 'exec' @param mac_source: A VM object from which to copy MAC addresses. If not specified, new addresses will be generated. @raise VMCreateError: If qemu terminates unexpectedly @raise VMKVMInitError: If KVM initialization fails @raise VMHugePageError: If hugepage initialization fails @raise VMImageMissingError: If a CD image is missing @raise VMHashMismatchError: If a CD image hash has doesn't match the expected hash @raise VMBadPATypeError: If an unsupported PCI assignment type is requested @raise VMPAError: If no PCI assignable devices could be assigned """ error.context("creating '%s'" % self.name) self.destroy(free_mac_addresses=False) if name is not None: self.name = name if params is not None: self.params = params if root_dir is not None: self.root_dir = root_dir name = self.name params = self.params root_dir = self.root_dir # Verify the md5sum of the ISO images for cdrom in params.objects("cdroms"): if params.get("medium") == "import": break cdrom_params = params.object_params(cdrom) iso = cdrom_params.get("cdrom") if ((self.driver_type == 'xen') and (params.get('hvm_or_pv') == 'pv') and (os.path.basename(iso) == 'ks.iso')): continue if iso: iso = utils_misc.get_path(data_dir.get_data_dir(), iso) if not os.path.exists(iso): raise virt_vm.VMImageMissingError(iso) compare = False if cdrom_params.get("md5sum_1m"): logging.debug("Comparing expected MD5 sum with MD5 sum of " "first MB of ISO file...") actual_hash = utils.hash_file(iso, 1048576, method="md5") expected_hash = cdrom_params.get("md5sum_1m") compare = True elif cdrom_params.get("md5sum"): logging.debug("Comparing expected MD5 sum with MD5 sum of " "ISO file...") actual_hash = utils.hash_file(iso, method="md5") expected_hash = cdrom_params.get("md5sum") compare = True elif cdrom_params.get("sha1sum"): logging.debug("Comparing expected SHA1 sum with SHA1 sum " "of ISO file...") actual_hash = utils.hash_file(iso, method="sha1") expected_hash = cdrom_params.get("sha1sum") compare = True if compare: if actual_hash == expected_hash: logging.debug("Hashes match") else: raise virt_vm.VMHashMismatchError(actual_hash, expected_hash) # Make sure the following code is not executed by more than one thread # at the same time lockfile = open("/tmp/libvirt-autotest-vm-create.lock", "w+") fcntl.lockf(lockfile, fcntl.LOCK_EX) try: # Handle port redirections redir_names = params.objects("redirs") host_ports = utils_misc.find_free_ports(5000, 6000, len(redir_names)) self.redirs = {} for i in range(len(redir_names)): redir_params = params.object_params(redir_names[i]) guest_port = int(redir_params.get("guest_port")) self.redirs[guest_port] = host_ports[i] # Find available PCI devices self.pci_devices = [] for device in params.objects("pci_devices"): self.pci_devices.append(device) # Find available VNC port, if needed if params.get("display") == "vnc": if params.get("vnc_autoport") == "yes": self.vnc_port = None self.vnc_autoport = True else: self.vnc_port = utils_misc.find_free_port(5900, 6100) self.vnc_autoport = False # Find available spice port, if needed if params.get("spice"): self.spice_port = utils_misc.find_free_port(8000, 8100) # Find random UUID if specified 'uuid = random' in config file if params.get("uuid") == "random": f = open("/proc/sys/kernel/random/uuid") self.uuid = f.read().strip() f.close() # Generate or copy MAC addresses for all NICs for nic in self.virtnet: nic_params = dict(nic) if mac_source: # Will raise exception if source doesn't # have cooresponding nic logging.debug("Copying mac for nic %s from VM %s" % (nic.nic_name, mac_source.nam)) nic_params['mac'] = mac_source.get_mac_address(nic.nic_name) # make_create_command() calls vm.add_nic (i.e. on a copy) nic = self.add_nic(**nic_params) logging.debug('VM.create activating nic %s' % nic) self.activate_nic(nic.nic_name) # Make qemu command install_command = self.make_create_command() logging.info("Running libvirt command (reformatted):") for item in install_command.replace(" -", " \n -").splitlines(): logging.info("%s", item) utils.run(install_command, verbose=False) # Wait for the domain to be created utils_misc.wait_for(func=self.is_alive, timeout=60, text=("waiting for domain %s to start" % self.name)) self.uuid = virsh.domuuid(self.name, uri=self.connect_uri) # Establish a session with the serial console if self.only_pty == True: self.serial_console = aexpect.ShellSession( "virsh console %s" % self.name, auto_close=False, output_func=utils_misc.log_line, output_params=("serial-%s.log" % name,)) else: self.serial_console = aexpect.ShellSession( "tail -f %s" % self.get_serial_console_filename(), auto_close=False, output_func=utils_misc.log_line, output_params=("serial-%s.log" % name,)) finally: fcntl.lockf(lockfile, fcntl.LOCK_UN) lockfile.close()
def get_uuid(self): """ Return VM's UUID. """ return virsh.domuuid(self.name, uri=self.connect_uri)