def __init__(self, debug=False, vcpus=None): self._guest = None self._tmpdir = os.path.realpath( tempfile.mkdtemp(prefix="vm-test-", suffix=".tmp", dir=".")) atexit.register(shutil.rmtree, self._tmpdir) self._ssh_key_file = os.path.join(self._tmpdir, "id_rsa") open(self._ssh_key_file, "w").write(SSH_KEY) subprocess.check_call(["chmod", "600", self._ssh_key_file]) self._ssh_pub_key_file = os.path.join(self._tmpdir, "id_rsa.pub") open(self._ssh_pub_key_file, "w").write(SSH_PUB_KEY) self.debug = debug self._stderr = sys.stderr self._devnull = open(os.devnull, "w") if self.debug: self._stdout = sys.stdout else: self._stdout = self._devnull self._args = [ \ "-nodefaults", "-m", "4G", "-cpu", "max", "-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22" + (",ipv6=no" if not self.ipv6 else ""), "-device", "virtio-net-pci,netdev=vnet", "-vnc", "127.0.0.1:0,to=20"] if vcpus and vcpus > 1: self._args += ["-smp", "%d" % vcpus] if kvm_available(self.arch): self._args += ["-enable-kvm"] else: logging.info("KVM not available, not using -enable-kvm") self._data_args = []
def test_virtio_vga_virgl(self): """ :avocado: tags=arch:x86_64 :avocado: tags=device:virtio-vga """ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash") # FIXME: should check presence of virtio, virgl etc if not kvm_available(self.arch, self.qemu_bin): self.cancel(KVM_NOT_AVAILABLE) kernel_path = self.fetch_asset(self.KERNEL_URL) initrd_path = self.fetch_asset(self.INITRD_URL) self.vm.set_console() self.vm.add_args("-cpu", "host") self.vm.add_args("-m", "2G") self.vm.add_args("-machine", "pc,accel=kvm") self.vm.add_args("-device", "virtio-vga,virgl=on") self.vm.add_args("-display", "egl-headless") self.vm.add_args( "-kernel", kernel_path, "-initrd", initrd_path, "-append", kernel_command_line, ) self.vm.launch() self.wait_for_console_pattern("as init process") exec_command_and_wait_for_pattern(self, "/usr/sbin/modprobe virtio_gpu", "") self.wait_for_console_pattern("features: +virgl +edid")
def setUp(self): vmlinuz = self.params.get('vmlinuz') if vmlinuz is None: self.cancel('vmlinuz parameter not set; you must point it to a ' 'Linux kernel binary to test (to run this test with ' \ 'the on-image kernel, set it to an empty string)') self.seed = self.params.get('seed') atwd = os.getenv('AVOCADO_TEST_WORKDIR') self.ssh_key = os.path.join(atwd, 'id_ed25519') self.run(('ssh-keygen', '-t', 'ed25519', '-f', self.ssh_key)) pubkey = open(self.ssh_key + '.pub').read() super(VirtiofsSubmountsTest, self).setUp(pubkey) if len(vmlinuz) > 0: self.vm.add_args('-kernel', vmlinuz, '-append', 'console=ttyS0 root=/dev/sda1') # Allow us to connect to SSH self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22', '-device', 'e1000,netdev=vnet') if not kvm_available(self.arch, self.qemu_bin): self.cancel(KVM_NOT_AVAILABLE) self.vm.add_args('-accel', 'kvm')
def test_pc_q35_kvm(self): """ :avocado: tags=machine:q35 :avocado: tags=accel:kvm """ if not kvm_available(self.arch, self.qemu_bin): self.cancel(KVM_NOT_AVAILABLE) self.vm.add_args("-accel", "kvm") self.launch_and_wait()
def test_virt_kvm(self): """ :avocado: tags=accel:kvm :avocado: tags=cpu:host """ if not kvm_available(self.arch, self.qemu_bin): self.cancel(KVM_NOT_AVAILABLE) self.vm.add_args("-accel", "kvm") self.vm.add_args("-cpu", "host") self.vm.add_args("-machine", "virt,gic-version=2") self.add_common_args() self.launch_and_wait()
def get_default_jobs(): if multiprocessing.cpu_count() > 1: if kvm_available(vmcls.arch): return multiprocessing.cpu_count() // 2 elif os.uname().machine == "x86_64" and \ vmcls.arch in ["aarch64", "x86_64", "i386"]: # MTTCG is available on these arches and we can allow # more cores. but only up to a reasonable limit. User # can always override these limits with --jobs. return min(multiprocessing.cpu_count() // 2, 8) else: return 1
def wait_boot(self, wait_string=None): """Wait for the standard string we expect on completion of a normal boot. The user can also choose to override with an alternate string to wait for.""" if wait_string is None: if self.login_prompt is None: raise Exception("self.login_prompt not defined") wait_string = self.login_prompt # Intentionally bump up the default timeout under TCG, # since the console wait below takes longer. timeout = self.socket_timeout if not kvm_available(self.arch): timeout *= 8 self.console_init(timeout=timeout) self.console_wait(wait_string)
def wait_ssh(self, wait_root=False, seconds=300, cmd="exit 0"): # Allow more time for VM to boot under TCG. if not kvm_available(self.arch): seconds *= self.tcg_ssh_timeout_multiplier starttime = datetime.datetime.now() endtime = starttime + datetime.timedelta(seconds=seconds) cmd_success = False while datetime.datetime.now() < endtime: if wait_root and self.ssh_root(cmd) == 0: cmd_success = True break elif self.ssh(cmd) == 0: cmd_success = True break seconds = (endtime - datetime.datetime.now()).total_seconds() logging.debug("%ds before timeout", seconds) time.sleep(1) if not cmd_success: raise Exception("Timeout while waiting for guest ssh")
def aarch_get_config_defaults(vmcls): """Set the defaults for current version of QEMU.""" config = CURRENT_CONFIG args = basevm.parse_args(vmcls) qemu_path = basevm.get_qemu_path(vmcls.arch, args.build_path) qemu_version = basevm.get_qemu_version(qemu_path) if qemu_version < QEMU_AARCH64_MIN_VERSION: error = "\nThis major version of QEMU {} is to old for aarch64 VMs.\n"\ "The major version must be at least {}.\n"\ "To continue with the current build of QEMU, "\ "please restart with QEMU_LOCAL=1 .\n" print(error.format(qemu_version, QEMU_AARCH64_MIN_VERSION)) exit(1) if qemu_version == QEMU_AARCH64_MIN_VERSION: # We have an older version of QEMU, # set the config values for backwards compatibility. if kvm_available('aarch64'): config.update(DEFAULT_CONFIG['kvm']) else: config.update(DEFAULT_CONFIG['tcg']) return config
def get_default_jobs(): if kvm_available(vmcls.arch): return multiprocessing.cpu_count() // 2 else: return 1
def test_vhost_user_vga_virgl(self): """ :avocado: tags=arch:x86_64 :avocado: tags=device:vhost-user-vga """ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash") # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc if not kvm_available(self.arch, self.qemu_bin): self.cancel(KVM_NOT_AVAILABLE) vug = pick_default_vug_bin() if not vug: self.cancel("Could not find vhost-user-gpu") kernel_path = self.fetch_asset(self.KERNEL_URL) initrd_path = self.fetch_asset(self.INITRD_URL) # Create socketpair to connect proxy and remote processes qemu_sock, vug_sock = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM) os.set_inheritable(qemu_sock.fileno(), True) os.set_inheritable(vug_sock.fileno(), True) self._vug_log_path = os.path.join(self.vm._test_dir, "vhost-user-gpu.log") self._vug_log_file = open(self._vug_log_path, "wb") print(self._vug_log_path) vugp = subprocess.Popen( [vug, "--virgl", "--fd=%d" % vug_sock.fileno()], stdin=subprocess.DEVNULL, stdout=self._vug_log_file, stderr=subprocess.STDOUT, shell=False, close_fds=False, ) self.vm.set_console() self.vm.add_args("-cpu", "host") self.vm.add_args("-m", "2G") self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G") self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm") self.vm.add_args("-chardev", "socket,id=vug,fd=%d" % qemu_sock.fileno()) self.vm.add_args("-device", "vhost-user-vga,chardev=vug") self.vm.add_args("-display", "egl-headless") self.vm.add_args( "-kernel", kernel_path, "-initrd", initrd_path, "-append", kernel_command_line, ) self.vm.launch() self.wait_for_console_pattern("as init process") exec_command_and_wait_for_pattern(self, "/usr/sbin/modprobe virtio_gpu", "") self.wait_for_console_pattern("features: +virgl -edid") self.vm.shutdown() qemu_sock.close() vugp.terminate() vugp.wait()
def __init__(self, args, config=None): self._guest = None self._genisoimage = args.genisoimage self._build_path = args.build_path self._efi_aarch64 = args.efi_aarch64 # Allow input config to override defaults. self._config = DEFAULT_CONFIG.copy() if config != None: self._config.update(config) self.validate_ssh_keys() self._tmpdir = os.path.realpath( tempfile.mkdtemp(prefix="vm-test-", suffix=".tmp", dir=".")) atexit.register(shutil.rmtree, self._tmpdir) # Copy the key files to a temporary directory. # Also chmod the key file to agree with ssh requirements. self._config['ssh_key'] = \ open(self._config['ssh_key_file']).read().rstrip() self._config['ssh_pub_key'] = \ open(self._config['ssh_pub_key_file']).read().rstrip() self._ssh_tmp_key_file = os.path.join(self._tmpdir, "id_rsa") open(self._ssh_tmp_key_file, "w").write(self._config['ssh_key']) subprocess.check_call(["chmod", "600", self._ssh_tmp_key_file]) self._ssh_tmp_pub_key_file = os.path.join(self._tmpdir, "id_rsa.pub") open(self._ssh_tmp_pub_key_file, "w").write(self._config['ssh_pub_key']) self.debug = args.debug self._console_log_path = None if args.log_console: self._console_log_path = \ os.path.join(os.path.expanduser("~/.cache/qemu-vm"), "{}.install.log".format(self.name)) self._stderr = sys.stderr self._devnull = open(os.devnull, "w") if self.debug: self._stdout = sys.stdout else: self._stdout = self._devnull netdev = "user,id=vnet,hostfwd=:127.0.0.1:{}-:22" self._args = [ \ "-nodefaults", "-m", self._config['memory'], "-cpu", self._config['cpu'], "-netdev", netdev.format(self._config['ssh_port']) + (",ipv6=no" if not self.ipv6 else "") + (",dns=" + self._config['dns'] if self._config['dns'] else ""), "-device", "virtio-net-pci,netdev=vnet", "-vnc", "127.0.0.1:0,to=20"] if args.jobs and args.jobs > 1: self._args += ["-smp", "%d" % args.jobs] if kvm_available(self.arch): self._args += ["-enable-kvm"] else: logging.info("KVM not available, not using -enable-kvm") self._data_args = [] if self._config['qemu_args'] != None: qemu_args = self._config['qemu_args'] qemu_args = qemu_args.replace('\n', ' ').replace('\r', '') # shlex groups quoted arguments together # we need this to keep the quoted args together for when # the QEMU command is issued later. args = shlex.split(qemu_args) self._config['extra_args'] = [] for arg in args: if arg: # Preserve quotes around arguments. # shlex above takes them out, so add them in. if " " in arg: arg = '"{}"'.format(arg) self._config['extra_args'].append(arg)