def add_nic(self, **params): """ Add new or setup existing NIC with optional model type and mac address @param: **params: Additional NIC parameters to set. @param: nic_name: Name for device @param: mac: Optional MAC address, None to randomly generate. @param: ip: Optional IP address to register in address_cache @return: Dict with new NIC's info. """ if not params.has_key('nic_name'): params['nic_name'] = virt_utils.generate_random_id() nic_name = params['nic_name'] if nic_name in self.virtnet.nic_name_list(): self.virtnet[nic_name].update(**params) else: self.virtnet.append(params) nic = self.virtnet[nic_name] if not nic.has_key('mac'): # generate random mac logging.debug("Generating random mac address for nic") self.virtnet.generate_mac_address(nic_name) # mac of '' or invaid format results in not setting a mac if nic.has_key('ip') and nic.has_key('mac'): if not self.address_cache.has_key(nic.mac): logging.debug("(address cache) Adding static " "cache entry: %s ---> %s" % (nic.mac, nic.ip)) else: logging.debug("(address cache) Updating static " "cache entry from: %s ---> %s" " to: %s ---> %s" % (nic.mac, self.address_cache[nic.mac], nic.mac, nic.ip)) self.address_cache[nic.mac] = nic.ip return nic
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"): cdrom_params = params.object_params(cdrom) iso = cdrom_params.get("cdrom") if iso: iso = virt_utils.get_path(root_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 = virt_utils.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] # Generate netdev/device IDs for all NICs self.netdev_id = [] self.device_id = [] for nic in params.objects("nics"): self.netdev_id.append(virt_utils.generate_random_id()) self.device_id.append(virt_utils.generate_random_id()) # 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": self.vnc_port = virt_utils.find_free_port(5900, 6100) # Find available spice port, if needed if params.get("spice"): self.spice_port = virt_utils.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 num_nics = len(params.objects("nics")) for vlan in range(num_nics): nic_name = params.objects("nics")[vlan] nic_params = params.object_params(nic_name) mac = (nic_params.get("nic_mac") or mac_source and mac_source.get_mac_address(vlan)) if mac: virt_utils.set_mac_address(self.instance, vlan, mac) else: virt_utils.generate_mac_address(self.instance, vlan) # Make qemu command install_command = self.__make_libvirt_command() logging.info("Running libvirt command:\n%s", install_command) utils.run(install_command, verbose=False) # Wait for the domain to be created virt_utils.wait_for(func=self.is_alive, timeout=60, text=("waiting for domain %s to start" % self.name)) # Establish a session with the serial console -- requires a version # of netcat that supports -U self.serial_console = aexpect.ShellSession( "nc -U %s" % self.get_serial_console_filename(), auto_close=False, output_func=virt_utils.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"): cdrom_params = params.object_params(cdrom) iso = cdrom_params.get("cdrom") if ((self.driver_type == self.LIBVIRT_XEN) and (params.get('hvm_or_pv') == 'pv') and (os.path.basename(iso) == 'ks.iso')): continue if iso: iso = virt_utils.get_path(root_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 = virt_utils.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] # Generate netdev/device IDs for all NICs self.netdev_id = [] self.device_id = [] for nic in params.objects("nics"): self.netdev_id.append(virt_utils.generate_random_id()) self.device_id.append(virt_utils.generate_random_id()) # 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": self.vnc_port = virt_utils.find_free_port(5900, 6100) # Find available spice port, if needed if params.get("spice"): self.spice_port = virt_utils.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 num_nics = len(params.objects("nics")) for vlan in range(num_nics): nic_name = params.objects("nics")[vlan] nic_params = params.object_params(nic_name) mac = (nic_params.get("nic_mac") or mac_source and mac_source.get_mac_address(vlan)) if mac: virt_utils.set_mac_address(self.instance, vlan, mac) else: virt_utils.generate_mac_address(self.instance, vlan) # Make qemu command install_command = self.__make_libvirt_command() logging.info("Running libvirt command:\n%s", install_command) utils.run(install_command, verbose=False) # Wait for the domain to be created virt_utils.wait_for(func=self.is_alive, timeout=60, text=("waiting for domain %s to start" % self.name)) # Establish a session with the serial console -- requires a version # of netcat that supports -U self.serial_console = aexpect.ShellSession( "nc -U %s" % self.get_serial_console_filename(), auto_close=False, output_func=virt_utils.log_line, output_params=("serial-%s.log" % name, )) finally: fcntl.lockf(lockfile, fcntl.LOCK_UN) lockfile.close()