From patchwork Tue Mar 10 18:25:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430069 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 708D713A4 for ; Tue, 10 Mar 2020 18:29:03 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4628620727 for ; Tue, 10 Mar 2020 18:29:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="DYmmx94q" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4628620727 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38394 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjck-0000Bz-Gq for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:29:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43923) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjb4-0004xJ-Tt for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjb2-00022b-Kv for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:17 -0400 Received: from mail-pg1-x541.google.com ([2607:f8b0:4864:20::541]:39718) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjb2-00020n-F1 for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:16 -0400 Received: by mail-pg1-x541.google.com with SMTP id s2so6681695pgv.6 for ; Tue, 10 Mar 2020 11:27:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gBa/eZgenJryGWjkA8q6oRG/FDhBu8JGwHX1oWSrDEI=; b=DYmmx94qb8D05NaSaEY1Bq3iYKyYtEGvuyJE8AGczrBiN85W/yVdvUq9mgfELxAgub BWZTd1ZVLcZUkmmleaDa2A0RB6aTGqNL0zBHxqrR4f2N1bPeDdGObbQMQaz5T+Jl47aN gjFnmryC6Q6jmMPHF6zVeVL5OoJjCPnBsEV0Hq+7AfhDqBLZ54fsyy1SwrNwxndrl8+U ndWN8vNOwO66wbKcr+T4ixPjUebsVIqVKKBFov0C+QRF5Rz3PT6LMjZqN1HHLWxuTJbB d0C/cJ8g6t0lSF9Sn51xSGgfg5vXkaMElXpbHYw+HKn6AFyyX/p57J+dXtmp6CTcOD5E bXAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=gBa/eZgenJryGWjkA8q6oRG/FDhBu8JGwHX1oWSrDEI=; b=ArIG2A3yi8Di9hf7Ti74GEtnkTX6DpuERlZUc+Fgi74VOrH7icjnT1L23m336m1DrT Z15L96XFIbOQfT8VKODThxb11AgvIx6hn71zn036s644NFW9euXom0tr+5ZiPkH7mUWW vdIWRkD1e/hVW3vuqkC2lVKvbhoWqL33zwG7LDv6ZIviJG7S02E4+TKyfnxw0GT6tCIV WQKCL4l9qkpAQZYyVQPjfbXRPRHAe4Qnflf21R4bqtgkRivMdhdsUR1BztoyO2K04h0G ShCJaQaLTrl/lsdzLpbTm5MeKX4qttz5POyb/oleDgigMrhB4Ko6/d4K1l91jIRzGi+D gtUw== X-Gm-Message-State: ANhLgQ2VcvDaYNHrlrMqKM+ssQO2fhguIvS9P6O516joMqGwxUBnUbRa gyGEfnSt9z+AX/WYDz52KGGBQNk0eUk= X-Google-Smtp-Source: ADFU+vuUvscJG8gx7WCLvW6mz+AybyvnIVDW/ar6iy53aFartoKQPEL200HGOn/xsI8wo4W8o26lAw== X-Received: by 2002:a63:a35a:: with SMTP id v26mr23060473pgn.40.1583864835169; Tue, 10 Mar 2020 11:27:15 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:14 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 01/10] tests/vm: Add validation of target Date: Tue, 10 Mar 2020 14:25:27 -0400 Message-Id: <20200310182536.11137-2-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::541 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This validation is now useful since some targets may not be valid if their dependencies are not installed. Instead of allowing the scripts to fail with missing dependencies we will fail earlier with a helpful error message. Signed-off-by: Robert Foley --- tests/vm/Makefile.include | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index 1bf9693d19..835e3f3549 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -2,7 +2,7 @@ .PHONY: vm-build-all vm-clean-all -IMAGES := freebsd netbsd openbsd centos fedora +IMAGES := freebsd netbsd openbsd fedora ifneq ($(GENISOIMAGE),) IMAGES += ubuntu.i386 centos endif @@ -49,9 +49,20 @@ vm-build-all: $(addprefix vm-build-, $(IMAGES)) vm-clean-all: rm -f $(IMAGE_FILES) +# Validate the target since some targets will not +# be valid if their software dependencies are not installed. +define validate_target + @echo $(1) | grep $(2) || \ + (echo "Invalid target ($(2))"; \ + echo "Valid Targets are: $(1)"; \ + echo "See make vm-help for more information."; \ + exit 1;) +endef + $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \ $(SRC_PATH)/tests/vm/basevm.py \ $(SRC_PATH)/tests/vm/Makefile.include + $(call validate_target,${IMAGES},$*) @mkdir -p $(IMAGES_DIR) $(call quiet-command, \ $(PYTHON) $< \ @@ -64,6 +75,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \ # Build in VM $(IMAGE) vm-build-%: $(IMAGES_DIR)/%.img + $(call validate_target,${IMAGES},$*) $(call quiet-command, \ $(PYTHON) $(SRC_PATH)/tests/vm/$* \ $(if $(V)$(DEBUG), --debug) \ @@ -79,6 +91,7 @@ vm-build-%: $(IMAGES_DIR)/%.img " VM-BUILD $*") vm-boot-serial-%: $(IMAGES_DIR)/%.img + $(call validate_target,${IMAGES},$*) qemu-system-x86_64 -enable-kvm -m 4G -smp 2 -nographic \ -drive if=none,id=vblk,cache=writeback,file="$<" \ -netdev user,id=vnet \ @@ -87,6 +100,7 @@ vm-boot-serial-%: $(IMAGES_DIR)/%.img || true vm-boot-ssh-%: $(IMAGES_DIR)/%.img + $(call validate_target,${IMAGES},$*) $(call quiet-command, \ $(PYTHON) $(SRC_PATH)/tests/vm/$* \ $(if $(J),--jobs $(J)) \ From patchwork Tue Mar 10 18:25:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430065 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E0CE292A for ; Tue, 10 Mar 2020 18:28:27 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A6C5520727 for ; Tue, 10 Mar 2020 18:28:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="RCcuNTbK" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A6C5520727 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38378 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjcA-0006rx-Rw for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:28:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43970) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjb6-00050J-Th for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjb4-000270-TL for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:20 -0400 Received: from mail-pg1-x52f.google.com ([2607:f8b0:4864:20::52f]:41073) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjb4-00024Z-Md for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:18 -0400 Received: by mail-pg1-x52f.google.com with SMTP id b1so6678235pgm.8 for ; Tue, 10 Mar 2020 11:27:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=urnRDvlr6Rggb1UPjGmbmXEKKyEMUtTeol/j0/zSato=; b=RCcuNTbKkEF8d51ktWx+1uLP7yHYTTTnKL9Ly9g7+h98POD6d6oorAGroR/IXe6mb5 0qjoDyxEoubcDQUxAnJ2LrhT/XFtl1AFoh5J+82zhzl2SP9K/btyhnJHVqQO57qKJGiT qVCbJhS5LUzvUk87Og0d1fPWC0hUN72WxrJIc1v3N5aV8hqaMWK0HeR4pUdzg1TDQOJd ggz7PJg+s/fXe3G/Wjl8VHa4u25vLK4NEa8K5PkSL0EkFCn5/eh8A3vmtUWzkEk+pU04 Px66pEl4iBPKlxKSETwSvndIaRtj9nSmKmoJA6i00B0VN6OTA5QCuX6eTD/WCVWMNVLN Pvew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=urnRDvlr6Rggb1UPjGmbmXEKKyEMUtTeol/j0/zSato=; b=Y92rgblEs6+11U/JSYr+rnyDkfU8UYWHJsKy7+cnebxWKMopKFPvE2IkOZPpotysdK mM0j0MSh9ee1oHc4p1fprmAiKrYXth0RaR08Wt41iUs4eqS0lbFH67qIqUCgeQYHxvlL ZIjJzsDKgMPDT4TaCRq8oFJ0/viveGkENjt2/QxAny0bm9R4yZCJdmBWYoIqnYXYI/jK wOVKt+C7cbT/MCXw7pMCRsgEoNedwFXUW9DYq3AjltIdLIf6snEkfP28d4KT8MBNYB32 51ov7UN/lsMdidlSnOZ40r4usUZ5hvdTCC6LWMvi8fIGbEnAY64ic/XS+w8BFKSavq3q JRmw== X-Gm-Message-State: ANhLgQ0ZdGDN6PxZkbZ4FAzBBR2aEb6EeTohbQpyOTSxAH/QyH+jZrip 7yWUnQxa1agq9YFcbY7sMN1AMBAe7yk= X-Google-Smtp-Source: ADFU+vtNNvfFLw0JyyeaIIVOYHdbhn6O9Po1MrZwaCbEN2kiKvXCYAnCb3DJn1Z1cbZ6UBmVl7No+g== X-Received: by 2002:a62:1b51:: with SMTP id b78mr16415587pfb.23.1583864837102; Tue, 10 Mar 2020 11:27:17 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:16 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 02/10] tests/vm: Add configuration to basevm.py Date: Tue, 10 Mar 2020 14:25:28 -0400 Message-Id: <20200310182536.11137-3-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::52f X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Added use of a configuration to tests/vm/basevm.py. The configuration provides parameters used to configure a VM. This allows for providing alternate configurations to the VM being created/launched. cpu, machine, memory, and NUMA configuration are all examples of configuration which we might want to vary on the VM being created or launched. This will for example allow for creating an aarch64 vm. Signed-off-by: Robert Foley --- tests/vm/basevm.py | 143 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 112 insertions(+), 31 deletions(-) diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 8400b0e07f..97c6f625c9 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -30,15 +30,39 @@ import shutil import multiprocessing import traceback -SSH_KEY = open(os.path.join(os.path.dirname(__file__), - "..", "keys", "id_rsa")).read() -SSH_PUB_KEY = open(os.path.join(os.path.dirname(__file__), - "..", "keys", "id_rsa.pub")).read() - +SSH_KEY_FILE = os.path.join(os.path.dirname(__file__), + "..", "keys", "id_rsa") +SSH_PUB_KEY_FILE = os.path.join(os.path.dirname(__file__), + "..", "keys", "id_rsa.pub") + +# This is the standard configuration. +# Any or all of these can be overridden by +# passing in a config argument to the VM constructor. +DEFAULT_CONFIG = { + 'cpu' : "max", + 'machine' : 'pc', + 'guest_user' : "qemu", + 'guest_pass' : "qemupass", + 'root_pass' : "qemupass", + 'ssh_key_file' : SSH_KEY_FILE, + 'ssh_pub_key_file': SSH_PUB_KEY_FILE, + 'memory' : "4G", + 'extra_args' : [], + 'qemu_args' : "", + 'dns' : "", + 'ssh_port' : 0, + 'install_cmds' : "", + 'boot_dev_type' : "block", + 'ssh_timeout' : 1, +} +BOOT_DEVICE = { + 'block' : "-drive file={},if=none,id=drive0,cache=writeback "\ + "-device virtio-blk,drive=drive0,bootindex=0", + 'scsi' : "-device virtio-scsi-device,id=scsi "\ + "-drive file={},format=raw,if=none,id=hd0 "\ + "-device scsi-hd,drive=hd0,bootindex=0", +} class BaseVM(object): - GUEST_USER = "qemu" - GUEST_PASS = "qemupass" - ROOT_PASS = "qemupass" envvars = [ "https_proxy", @@ -61,19 +85,30 @@ class BaseVM(object): # 4 is arbitrary, but greater than 2, # since we found we need to wait more than twice as long. tcg_ssh_timeout_multiplier = 4 - def __init__(self, debug=False, vcpus=None): + def __init__(self, debug=False, vcpus=None, config=None): self._guest = None + # 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) - - 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) + # 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 = debug self._stderr = sys.stderr @@ -82,11 +117,14 @@ class BaseVM(object): self._stdout = sys.stdout else: self._stdout = self._devnull + netdev = "user,id=vnet,hostfwd=:127.0.0.1:{}-:22" 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 ""), + "-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 vcpus and vcpus > 1: @@ -97,6 +135,45 @@ class BaseVM(object): 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','') + # Remove any empty strings from list. + self._config['extra_args'] = [x for x in qemu_args.split(' ') if x] + + def validate_ssh_keys(self): + """Check to see if the ssh key files exist.""" + if 'ssh_key_file' not in self._config or\ + not os.path.exists(self._config['ssh_key_file']): + raise Exception("ssh key file not found.") + if 'ssh_pub_key_file' not in self._config or\ + not os.path.exists(self._config['ssh_pub_key_file']): + raise Exception("ssh pub key file not found.") + + 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 __getattr__(self, name): + # Support direct access to config by key. + # for example, access self._config['cpu'] by self.cpu + if name.lower() in self._config.keys(): + return self._config[name.lower()] + return object.__getattribute__(self, name) + def _download_with_cache(self, url, sha256sum=None, sha512sum=None): def check_sha256sum(fname): if not sha256sum: @@ -128,8 +205,9 @@ class BaseVM(object): "-t", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=" + os.devnull, - "-o", "ConnectTimeout=1", - "-p", self.ssh_port, "-i", self._ssh_key_file] + "-o", + "ConnectTimeout={}".format(self._config["ssh_timeout"]), + "-p", self.ssh_port, "-i", self._ssh_tmp_key_file] # If not in debug mode, set ssh to quiet mode to # avoid printing the results of commands. if not self.debug: @@ -178,15 +256,15 @@ class BaseVM(object): "virtio-blk,drive=%s,serial=%s,bootindex=1" % (name, name)] def boot(self, img, extra_args=[]): - args = self._args + [ - "-device", "VGA", - "-drive", "file=%s,if=none,id=drive0,cache=writeback" % img, - "-device", "virtio-blk,drive=drive0,bootindex=0"] - args += self._data_args + extra_args + boot_dev = BOOT_DEVICE[self._config['boot_dev_type']] + boot_params = boot_dev.format(img) + args = self._args + boot_params.split(' ') + args += self._data_args + extra_args + self._config['extra_args'] + args += ["-device", "VGA"] logging.debug("QEMU args: %s", " ".join(args)) qemu_bin = os.environ.get("QEMU", "qemu-system-" + self.arch) guest = QEMUMachine(binary=qemu_bin, args=args) - guest.set_machine('pc') + guest.set_machine(self._config['machine']) guest.set_console() try: guest.launch() @@ -294,7 +372,8 @@ class BaseVM(object): self.console_send(command) def console_ssh_init(self, prompt, user, pw): - sshkey_cmd = "echo '%s' > .ssh/authorized_keys\n" % SSH_PUB_KEY.rstrip() + sshkey_cmd = "echo '%s' > .ssh/authorized_keys\n" \ + % self._config['ssh_pub_key'].rstrip() self.console_wait_send("login:", "%s\n" % user) self.console_wait_send("Password:", "%s\n" % pw) self.console_wait_send(prompt, "mkdir .ssh\n") @@ -422,15 +501,17 @@ def parse_args(vmcls): parser.disable_interspersed_args() return parser.parse_args() -def main(vmcls): +def main(vmcls, config=None): try: + if config == None: + config = {} args, argv = parse_args(vmcls) if not argv and not args.build_qemu and not args.build_image: print("Nothing to do?") return 1 logging.basicConfig(level=(logging.DEBUG if args.debug else logging.WARN)) - vm = vmcls(debug=args.debug, vcpus=args.jobs) + vm = vmcls(debug=args.debug, vcpus=args.jobs, config=config) if args.build_image: if os.path.exists(args.image) and not args.force: sys.stderr.writelines(["Image file exists: %s\n" % args.image, From patchwork Tue Mar 10 18:25:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430067 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AE4081731 for ; Tue, 10 Mar 2020 18:28:30 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 737E4208C3 for ; Tue, 10 Mar 2020 18:28:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="eZTAZwh7" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 737E4208C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38382 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjcD-0006yr-Ll for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:28:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44029) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjb9-00054P-JK for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjb7-0002Db-NN for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:23 -0400 Received: from mail-pf1-x444.google.com ([2607:f8b0:4864:20::444]:36581) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjb7-0002AQ-EA for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:21 -0400 Received: by mail-pf1-x444.google.com with SMTP id i13so6892012pfe.3 for ; Tue, 10 Mar 2020 11:27:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5KvGN43ndQQIILfqo4BWtywWGNWXjXBH37QMXubCTbI=; b=eZTAZwh7FULoRtPJgajtvL5Zp8z4LlDq3nWd3zFn+NP+ZXBj0FGmcXMBa56WBrEW9m u7ap9IMIk2d/Xd4YHc4fYg40aiMxpS9OmPOiCFFBLRFP+FaiinCpYdwDl/HCNbdug08Z a/Vi6umoQ3Kv4byBWVzHESdZ3W7P4JZr0265uLz9T+YNooo5iYinrfZsweddmMpK4RSI +oNUX05fSFno5cL+l7ozzLmsnqUp8tbkyZ1Ezkt859lvv17cwp4JIrcShyrK1Yc3+Ha2 gVu1amD8r/ghE+W3E1gpIOch7r3cNpQ8sTUg+tbclmtQSXwmHMzorDgIv9uiDvaJeoix pUdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5KvGN43ndQQIILfqo4BWtywWGNWXjXBH37QMXubCTbI=; b=U0lc6JadGCBN4BY1bTDb3RFNAzpHNj6d1bVdFzAXUGwRNjxGE9o1FvjORVj4fl4AKx U/eu9DXr2ohBNeIhZmECXIT0q2shIZiVwUTS49CdO7S6gkWkHFPudH/6qDjqPTZO2EbD coUSataI9iwBBSOZ/Zpqa0tVqaWytLVdbe/q95Tm5B6aVXH/V/IiHIcIWwxF5OXoFM8+ gVpttnlkAly00D1KOVbnpaxKkI+I3RXs1JPMFY/C0oVCgEIUVHsNoqOX5C9brZyoe8Dx tuzXa6KuJtXurM+8I7tWnhZ5HT+0i9MA2BF93r/aIQJD18KfJfexFyuEZIbBV23XtAvA HHbw== X-Gm-Message-State: ANhLgQ3R4jE4bW3xQZx9ayj23qqMslnpQ+Z4uZGC3EwY6ff8w24VJIQ1 qYw0DC8zmGKagJfpIcdsKG9Xm1qR2ss= X-Google-Smtp-Source: ADFU+vusEZZsaLlrg6wCgY/fk9FlutGr326R6OnZ34NpBwyx0vQRYx1vbQ7FVUw5CBvim2cZI4Qr1A== X-Received: by 2002:a63:3fce:: with SMTP id m197mr21481730pga.38.1583864839226; Tue, 10 Mar 2020 11:27:19 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:18 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 03/10] tests/vm: Added configuration file support Date: Tue, 10 Mar 2020 14:25:29 -0400 Message-Id: <20200310182536.11137-4-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::444 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Changes to tests/vm/basevm.py to allow accepting a configuration file as a parameter. Allows for specifying VM options such as cpu, machine, memory, and arbitrary qemu arguments for specifying options such as NUMA configuration. Also added an example conf_example_aarch64.yml and conf_example_x86.yml. Signed-off-by: Robert Foley --- configure | 9 ++++++ tests/vm/Makefile.include | 6 ++++ tests/vm/basevm.py | 40 +++++++++++++++++++++++- tests/vm/conf_example_aarch64.yml | 51 +++++++++++++++++++++++++++++++ tests/vm/conf_example_x86.yml | 50 ++++++++++++++++++++++++++++++ 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 tests/vm/conf_example_aarch64.yml create mode 100644 tests/vm/conf_example_x86.yml diff --git a/configure b/configure index cbf864bff1..2d49ae7446 100755 --- a/configure +++ b/configure @@ -947,6 +947,13 @@ do fi done +# Check for existence of python3 yaml, needed to +# import yaml config files into vm-build. +python_yaml="no" +if $(python3 -c "import yaml" 2> /dev/null); then + python_yaml="yes" +fi + : ${smbd=${SMBD-/usr/sbin/smbd}} # Default objcc to clang if available, otherwise use CC @@ -6579,6 +6586,7 @@ if test "$docs" != "no"; then echo "sphinx-build $sphinx_build" fi echo "genisoimage $genisoimage" +echo "python_yaml $python_yaml" echo "slirp support $slirp $(echo_version $slirp $slirp_version)" if test "$slirp" != "no" ; then echo "smbd $smbd" @@ -7629,6 +7637,7 @@ echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak echo "PYTHON=$python" >> $config_host_mak echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak echo "GENISOIMAGE=$genisoimage" >> $config_host_mak +echo "PYTHON_YAML=$python_yaml" >> $config_host_mak echo "CC=$cc" >> $config_host_mak if $iasl -h > /dev/null 2>&1; then echo "IASL=$iasl" >> $config_host_mak diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index 835e3f3549..9916e6d050 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -43,6 +43,12 @@ endif @echo " V=1 - Enable verbose ouput on host and guest commands" @echo " QEMU=/path/to/qemu - Change path to QEMU binary" @echo " QEMU_IMG=/path/to/qemu-img - Change path to qemu-img tool" +ifeq ($(PYTHON_YAML),yes) + @echo " QEMU_CONFIG=/path/conf.yml - Change path to VM configuration .yml file." +else + @echo " (install python3-yaml to enable support for yaml file to configure a VM.)" +endif + @echo " See conf_example_*.yml for file format details." vm-build-all: $(addprefix vm-build-, $(IMAGES)) diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 97c6f625c9..dd545d3d1d 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -461,9 +461,43 @@ class BaseVM(object): cwd=cidir, stdin=self._devnull, stdout=self._stdout, stderr=self._stdout) - return os.path.join(cidir, "cloud-init.iso") +def parse_config(config, args): + """ Parse yaml config and populate our config structure. + The yaml config allows the user to override the + defaults for VM parameters. In many cases these + defaults can be overridden without rebuilding the VM.""" + if args.config: + config_file = args.config + elif 'QEMU_CONFIG' in os.environ: + config_file = os.environ['QEMU_CONFIG'] + else: + return config + if not os.path.exists(config_file): + raise Exception("config file {} does not exist".format(config_file)) + # We gracefully handle importing the yaml module + # since it might not be installed. + # If we are here it means the user supplied a .yml file, + # so if the yaml module is not installed we will exit with error. + try: + import yaml + except ImportError: + print("The python3-yaml package is needed "\ + "to support config.yaml files") + # Instead of raising an exception we exit to avoid + # a raft of messy (expected) errors to stdout. + exit(1) + with open(config_file) as f: + yaml_dict = yaml.safe_load(f) + + if 'qemu-conf' in yaml_dict: + config.update(yaml_dict['qemu-conf']) + else: + raise Exception("config file {} is not valid"\ + " missing qemu-conf".format(config_file)) + return config + def parse_args(vmcls): def get_default_jobs(): @@ -498,6 +532,9 @@ def parse_args(vmcls): help="Interactively run command") parser.add_option("--snapshot", "-s", action="store_true", help="run tests with a snapshot") + parser.add_option("--config", "-c", default=None, + help="Provide config yaml for configuration. "\ + "See config_example.yaml for example.") parser.disable_interspersed_args() return parser.parse_args() @@ -509,6 +546,7 @@ def main(vmcls, config=None): if not argv and not args.build_qemu and not args.build_image: print("Nothing to do?") return 1 + config = parse_config(config, args) logging.basicConfig(level=(logging.DEBUG if args.debug else logging.WARN)) vm = vmcls(debug=args.debug, vcpus=args.jobs, config=config) diff --git a/tests/vm/conf_example_aarch64.yml b/tests/vm/conf_example_aarch64.yml new file mode 100644 index 0000000000..9d44ae356f --- /dev/null +++ b/tests/vm/conf_example_aarch64.yml @@ -0,0 +1,51 @@ +# +# Example yaml for use by any of the scripts in tests/vm. +# Can be provided as an environment variable QEMU_CONFIG +# +qemu-conf: + + # If any of the below are not provided, we will just use the qemu defaults. + + # Login username and password(has to be sudo enabled) + guest_user: qemu + guest_pass: "qemupass" + + # Password for root user can be different from guest. + root_pass: "qemupass" + + # If one key is provided, both must be provided. + #ssh_key: /complete/path/of/your/keyfile/id_rsa + #ssh_pub_key: /complete/path/of/your/keyfile/id_rsa.pub + + cpu: max + machine: virt,gic-version=max + memory: 16G + + # The below is a example for how to configure NUMA topology with + # 4 NUMA nodes and 2 different NUMA distances. + qemu_args: "-smp cpus=16,sockets=2,cores=8 + -numa node,cpus=0-3,nodeid=0 -numa node,cpus=4-7,nodeid=1 + -numa node,cpus=8-11,nodeid=2 -numa node,cpus=12-15,nodeid=3 + -numa dist,src=0,dst=1,val=15 -numa dist,src=2,dst=3,val=15 + -numa dist,src=0,dst=2,val=20 -numa dist,src=0,dst=3,val=20 + -numa dist,src=1,dst=2,val=20 -numa dist,src=1,dst=3,val=20" + + # By default we do not set the DNS. + # You override the defaults by setting the below. + #dns: 1.234.567.89 + + # By default we will use a "block" device, but + # you can also boot from a "scsi" device. + # Just keep in mind your scripts might need to change + # As you will have /dev/sda instead of /dev/vda (for block device) + boot_dev_type: "block" + + # By default the ssh port is not fixed. + # A fixed ssh port makes it easier for automated tests. + #ssh_port: 5555 + + # To install a different set of packages, provide a command to issue + #install_cmds: "apt-get update ; apt-get build-dep -y qemu" + + # Or to skip the install entirely, just provide "" + #install_cmds: "" diff --git a/tests/vm/conf_example_x86.yml b/tests/vm/conf_example_x86.yml new file mode 100644 index 0000000000..78d3f5830f --- /dev/null +++ b/tests/vm/conf_example_x86.yml @@ -0,0 +1,50 @@ +# +# Example yaml for use by any of the x86 based scripts in tests/vm. +# Can be provided as an environment variable QEMU_CONFIG +# +qemu-conf: + + # If any of the below are not provided, we will just use the qemu defaults. + + # Login username and password(has to be sudo enabled) + guest_user: "qemu" + guest_pass: "qemupass" + + # Password for root user can be different from guest. + root_pass: "qemupass" + + # Provide default ssh keys of current user. + # You need to edit the below for your user. + #ssh_key_file: /home//.ssh/id_rsa + #ssh_pub_key_file: /home//.ssh/id_rsa.pub + + cpu: max + machine: pc + memory: 8G + + # The below is a example for how to configure NUMA topology with + # 4 NUMA nodes and 2 different NUMA distances. + qemu_args: "-smp cpus=8,sockets=2,cores=4 + -object memory-backend-ram,size=4G,policy=bind,host-nodes=0,id=ram-node0 + -object memory-backend-ram,size=4G,policy=bind,host-nodes=0,id=ram-node1 + -object memory-backend-ram,size=4G,policy=bind,host-nodes=1,id=ram-node2 + -object memory-backend-ram,size=4G,policy=bind,host-nodes=1,id=ram-node3 + -numa node,cpus=0-1,nodeid=0 -numa node,cpus=2-3,nodeid=1 + -numa node,cpus=4-5,nodeid=2 -numa node,cpus=6-7,nodeid=3 + -numa dist,src=0,dst=1,val=15 -numa dist,src=2,dst=3,val=15 + -numa dist,src=0,dst=2,val=20 -numa dist,src=0,dst=3,val=20 + -numa dist,src=1,dst=2,val=20 -numa dist,src=1,dst=3,val=20" + + # By default we do not set the DNS. + # You override the defaults by setting the below. + #dns: "1.234.567.89" + + # By default we will use a "block" device, but + # you can also boot from a "scsi" device. + # Just keep in mind your scripts might need to change + # As you will have /dev/sda instead of /dev/vda (for block device) + boot_dev_type: "block" + + # By default the ssh port is not fixed. + # A fixed ssh port makes it easier for automated tests. + ssh_port: 5555 From patchwork Tue Mar 10 18:25:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430079 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5BE6F14BC for ; Tue, 10 Mar 2020 18:31:34 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 30F17208C3 for ; Tue, 10 Mar 2020 18:31:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="NOhbJSeY" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 30F17208C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38456 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjfB-0003es-7a for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:31:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44038) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjb9-00054w-W5 for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjb8-0002HJ-MI for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:23 -0400 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]:36398) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjb8-0002Eg-Fr for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:22 -0400 Received: by mail-pg1-x543.google.com with SMTP id c7so958957pgw.3 for ; Tue, 10 Mar 2020 11:27:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WeELFgz4oE5nux7AxNZv/xikqWNx8/F92UvlX1CD9Nw=; b=NOhbJSeYycDhZ/5wHfxLKcS+XSyAFakB3Mq8DYYWVQ1g90/zHsQFn6xHsl2ma5jk15 B5Rm7GrgzcZZ7Xfu+4pWrVsWSeHdLaY1GkkxqiK4s7FK4NUMssyzY9Ear+lDgtAvzk/p kVUGY0XocfTx+IMWLuTeQcLOazOTNr33H0h1IHN1kQbLfmm2pvsla+0vBPKKBpfDriIn DGMY6gI8OsBViv5tFEqqRkvz+smF+CIsZP1bsbm+HrEMWBcBUCfdVd4Nt7P7IqFZvb4M xUljSBuwkekMAWieggxGCxuI0089sYFEaBAtj64VbLMSWvfdIzPbnaiC2qsDb/Pp6mk3 +N3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WeELFgz4oE5nux7AxNZv/xikqWNx8/F92UvlX1CD9Nw=; b=Mv7KGYmypoD3YxgKf5MqKfEUTlHWcqC8fTUsZX3J8wTLnTUpaalBtidlTCl6W+kuIX C+Et0spH/oFOvenj5TLerRkU/9WOUNAq5/2ssAgrWNl2JHFvltu4Ih05/auea36XuT58 9pR5FWIpjtXfEBxl4PLIYDqyi06ke7h8QURJNtT9WyS4zLGTD7EFAU79aB1Br5l64E+L zVHDoMstGPwLSRgYXcT1CQMOEI2Hjm8R4csvV0RclgUq3PKANsck17kKC+xxP219NYHr dZBZ5fUl+gVQlHaMITAorICihXcNFETHUfbdgXBbPRI8ft9kXgn3phrg9scKAhUMd4UK 4F9A== X-Gm-Message-State: ANhLgQ3u/XWNgaW7ViuAigMNWGMCSBWiC3ridEuWSJ91NEbTr4PTo9C0 TJnj1oqpNRMGxBB3F/5mTLfxUlLqIrQ= X-Google-Smtp-Source: ADFU+vsMdyoFvm6TAaoAN4gMxkCDSQr1U6SJkGA/alRrvvdFdYaxqlg9WWvbwmJy/3YeIGYdCG/SOA== X-Received: by 2002:a62:8144:: with SMTP id t65mr14872364pfd.188.1583864841164; Tue, 10 Mar 2020 11:27:21 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:20 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 04/10] tests/vm: add --boot-console switch Date: Tue, 10 Mar 2020 14:25:30 -0400 Message-Id: <20200310182536.11137-5-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::543 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Added ability to view console during boot via --boot-console switch to basevm.py. This helps debug issues that occur during the boot sequence. Also added a new special variable to vm-build: BOOT_CONSOLE=1 will cause this new --boot-console switch to be set. Signed-off-by: Robert Foley --- tests/vm/Makefile.include | 4 ++++ tests/vm/basevm.py | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index 9916e6d050..8879fdd185 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -40,6 +40,7 @@ endif @echo ' EXTRA_CONFIGURE_OPTS="..."' @echo " J=[0..9]* - Override the -jN parameter for make commands" @echo " DEBUG=1 - Enable verbose output on host and interactive debugging" + @echo " BOOT_CONSOLE=1 - Show the console output at boot time. " @echo " V=1 - Enable verbose ouput on host and guest commands" @echo " QEMU=/path/to/qemu - Change path to QEMU binary" @echo " QEMU_IMG=/path/to/qemu-img - Change path to qemu-img tool" @@ -73,6 +74,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \ $(call quiet-command, \ $(PYTHON) $< \ $(if $(V)$(DEBUG), --debug) \ + $(if $(BOOT_CONSOLE),--boot-console) \ --image "$@" \ --force \ --build-image $@, \ @@ -88,6 +90,7 @@ vm-build-%: $(IMAGES_DIR)/%.img $(if $(DEBUG), --interactive) \ $(if $(J),--jobs $(J)) \ $(if $(V),--verbose) \ + $(if $(BOOT_CONSOLE),--boot-console) \ --image "$<" \ $(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \ --snapshot \ @@ -110,6 +113,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img $(call quiet-command, \ $(PYTHON) $(SRC_PATH)/tests/vm/$* \ $(if $(J),--jobs $(J)) \ + $(if $(BOOT_CONSOLE),--boot-console) \ --image "$<" \ --interactive \ false, \ diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index dd545d3d1d..aab3d98edf 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -85,8 +85,10 @@ class BaseVM(object): # 4 is arbitrary, but greater than 2, # since we found we need to wait more than twice as long. tcg_ssh_timeout_multiplier = 4 - def __init__(self, debug=False, vcpus=None, config=None): + def __init__(self, debug=False, vcpus=None, config=None, + boot_console=None): self._guest = None + self._boot_console = boot_console # Allow input config to override defaults. self._config = DEFAULT_CONFIG.copy() if config != None: @@ -535,6 +537,8 @@ def parse_args(vmcls): parser.add_option("--config", "-c", default=None, help="Provide config yaml for configuration. "\ "See config_example.yaml for example.") + parser.add_option("--boot-console", action="store_true", + help="Show console during boot. ") parser.disable_interspersed_args() return parser.parse_args() @@ -549,7 +553,8 @@ def main(vmcls, config=None): config = parse_config(config, args) logging.basicConfig(level=(logging.DEBUG if args.debug else logging.WARN)) - vm = vmcls(debug=args.debug, vcpus=args.jobs, config=config) + vm = vmcls(debug=args.debug, vcpus=args.jobs, config=config, + boot_console=args.boot_console) if args.build_image: if os.path.exists(args.image) and not args.force: sys.stderr.writelines(["Image file exists: %s\n" % args.image, @@ -569,6 +574,8 @@ def main(vmcls, config=None): if args.snapshot: img += ",snapshot=on" vm.boot(img) + if vm._boot_console: + vm.wait_boot() vm.wait_ssh() except Exception as e: if isinstance(e, SystemExit) and e.code == 0: From patchwork Tue Mar 10 18:25:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430077 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AAF8513A4 for ; Tue, 10 Mar 2020 18:30:10 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8095820727 for ; Tue, 10 Mar 2020 18:30:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="nhgeH7hj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8095820727 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38432 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjdp-0002Bu-JL for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:30:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44089) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjbC-00059Z-9t for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjbA-0002K5-Lt for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:26 -0400 Received: from mail-pl1-x636.google.com ([2607:f8b0:4864:20::636]:44072) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjbA-0002JD-Ed for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:24 -0400 Received: by mail-pl1-x636.google.com with SMTP id d9so5759982plo.11 for ; Tue, 10 Mar 2020 11:27:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=HLPZo5Mpt6bAz3JUox4H09RNNnYNOYLGWSUwOHKTkfk=; b=nhgeH7hj8awtNO+dk6hC1fkavg9rbHK1wpaPCQhW2FL/smqdrTFVcqWRocUHagJ1av i397EiICMzUzw2J3sXj+BBEOgumxWeiYf0Jc55F9TFica2R/BOcM7aEXroD5lCSn2USs 741XYX+/vRh7ryHaXx/VwSMoNTD/L0z8ErILfOH70OXGcqnV9jE2cIStAbaFrwBqHA4q Ia2fZStMilfYF9lADhwWFSbHNYXosyv05+khX3Qg27FLNaYtLKMiCvV7Hc39e9w7IgPd tnXFGP7Kkl8yQBUyHrH1YDLemkBqiRwEV3Pn/mjVYLzk0AAMX57gFGhGAn7Rv2+cvb2l 1Ngg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=HLPZo5Mpt6bAz3JUox4H09RNNnYNOYLGWSUwOHKTkfk=; b=VmAYD+H5ViUcbq9dW+kESFrez/B7QRNs9i/zyAPYk70EGCQeiIAZjy9KhJ747bVfD7 E36zeg+M5sovLcrRARil9EZf45c2AMYqPtsNL+2uaW9GrAkYy+gQBoAsefXqCdTnrD1d F6pYBR+aRsUW/TTwxhiPyIMi7yB+frPhJpqNNPqBzXY8onaACaBSTxYXR6i40dkio3RP YFQ5gT1UQeC8dX54gAICfEVqrEMPpxuK3XT9ie4sEJn7H1mtCziD7LeeHeCLSBD8/o1I GesVX98SquiRT2Sr5g6T0yXzbrSYimg7TXGqI4cOfOTolRKSLyZdAsajfpGcoRNCoojH sufQ== X-Gm-Message-State: ANhLgQ0np3yZXkZj2PjiJjOBecoyl3s6l4WlVVcop3Ihf212If8OgXKN Mse1xytLRk9w8RZkZHlOA71hDt+1qkc= X-Google-Smtp-Source: ADFU+vuHCrkcA4IkavGjjpe/fqbzJGDrqNrlJdq4ophD0EAXR0Oo2rnpM8xFMu9X4m/DeOlBunFpoA== X-Received: by 2002:a17:90a:8c8a:: with SMTP id b10mr3081593pjo.51.1583864843050; Tue, 10 Mar 2020 11:27:23 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:22 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 05/10] tests/vm: Add ability to select QEMU from current build. Date: Tue, 10 Mar 2020 14:25:31 -0400 Message-Id: <20200310182536.11137-6-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::636 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Added a new special variable QEMU_LOCAL=1, which will indicate to take the QEMU binary from the current build. Signed-off-by: Robert Foley --- tests/vm/Makefile.include | 4 ++++ tests/vm/basevm.py | 28 ++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index 8879fdd185..9986e4ae9a 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -42,6 +42,7 @@ endif @echo " DEBUG=1 - Enable verbose output on host and interactive debugging" @echo " BOOT_CONSOLE=1 - Show the console output at boot time. " @echo " V=1 - Enable verbose ouput on host and guest commands" + @echo " QEMU_LOCAL=1 - Use QEMU binary local to this build." @echo " QEMU=/path/to/qemu - Change path to QEMU binary" @echo " QEMU_IMG=/path/to/qemu-img - Change path to qemu-img tool" ifeq ($(PYTHON_YAML),yes) @@ -75,6 +76,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \ $(PYTHON) $< \ $(if $(V)$(DEBUG), --debug) \ $(if $(BOOT_CONSOLE),--boot-console) \ + --build-path $(BUILD_DIR)\ --image "$@" \ --force \ --build-image $@, \ @@ -91,6 +93,7 @@ vm-build-%: $(IMAGES_DIR)/%.img $(if $(J),--jobs $(J)) \ $(if $(V),--verbose) \ $(if $(BOOT_CONSOLE),--boot-console) \ + --build-path $(BUILD_DIR)\ --image "$<" \ $(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \ --snapshot \ @@ -114,6 +117,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img $(PYTHON) $(SRC_PATH)/tests/vm/$* \ $(if $(J),--jobs $(J)) \ $(if $(BOOT_CONSOLE),--boot-console) \ + --build-path $(BUILD_DIR)\ --image "$<" \ --interactive \ false, \ diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index aab3d98edf..3562a33ffa 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -86,8 +86,9 @@ class BaseVM(object): # since we found we need to wait more than twice as long. tcg_ssh_timeout_multiplier = 4 def __init__(self, debug=False, vcpus=None, config=None, - boot_console=None): + boot_console=False, build_path=None): self._guest = None + self._build_path = build_path self._boot_console = boot_console # Allow input config to override defaults. self._config = DEFAULT_CONFIG.copy() @@ -264,8 +265,8 @@ class BaseVM(object): args += self._data_args + extra_args + self._config['extra_args'] args += ["-device", "VGA"] logging.debug("QEMU args: %s", " ".join(args)) - qemu_bin = os.environ.get("QEMU", "qemu-system-" + self.arch) - guest = QEMUMachine(binary=qemu_bin, args=args) + qemu_path = get_qemu_path(self.arch, self._build_path) + guest = QEMUMachine(binary=qemu_path, args=args) guest.set_machine(self._config['machine']) guest.set_console() try: @@ -465,6 +466,22 @@ class BaseVM(object): stderr=self._stdout) return os.path.join(cidir, "cloud-init.iso") +def get_qemu_path(arch, build_path=None): + """Fetch the path to the qemu binary.""" + qemu_local = os.environ.get("QEMU_LOCAL", 0) + # If QEMU environment variable set, it takes precedence + if "QEMU" in os.environ: + qemu_path = os.environ["QEMU"] + elif qemu_local: + if not build_path: + raise Exception("--build-path option required with QEMU_LOCAL") + qemu_path = os.path.join(build_path, arch + "-softmmu") + qemu_path = os.path.join(qemu_path, "qemu-system-" + arch) + else: + # Default is to use system path for qemu. + qemu_path = "qemu-system-" + arch + return qemu_path + def parse_config(config, args): """ Parse yaml config and populate our config structure. The yaml config allows the user to override the @@ -539,6 +556,8 @@ def parse_args(vmcls): "See config_example.yaml for example.") parser.add_option("--boot-console", action="store_true", help="Show console during boot. ") + parser.add_option("--build-path", default=None, + help="Path of build directory. ") parser.disable_interspersed_args() return parser.parse_args() @@ -554,7 +573,8 @@ def main(vmcls, config=None): logging.basicConfig(level=(logging.DEBUG if args.debug else logging.WARN)) vm = vmcls(debug=args.debug, vcpus=args.jobs, config=config, - boot_console=args.boot_console) + boot_console=args.boot_console, + build_path=args.build_path) if args.build_image: if os.path.exists(args.image) and not args.force: sys.stderr.writelines(["Image file exists: %s\n" % args.image, From patchwork Tue Mar 10 18:25:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430075 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 59E9813A4 for ; Tue, 10 Mar 2020 18:29:36 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3006720727 for ; Tue, 10 Mar 2020 18:29:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="vhO0VdIY" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3006720727 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38412 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjdH-000145-CK for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:29:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44118) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjbD-0005CJ-BY for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjbC-0002MI-AG for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:27 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]:32864) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjbC-0002LF-3o for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:26 -0400 Received: by mail-pl1-x62b.google.com with SMTP id ay11so5778032plb.0 for ; Tue, 10 Mar 2020 11:27:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8MBax5bvqnGFn59+X+0C/P+ZVgi3X2sGtV0kV14mTCU=; b=vhO0VdIYJSFchp3fKcitkAFupc8J8UfcV3mfm6YJ50fYh4rVAmPY+FuaTCjR0u2KSS JGT6+AXUhPUFaqzWRf3Wpn0zYIC1k2DzLBjdQ8kfx4xI4Hbor21wF7dU70pmoorwlo0k Yiv6TmIpWH3fV3A+4BV1ZyyrS4Ugo2d4UPGN50gLFyNJD2KwVI4taNqoNHm6nPg1s9z+ fNJYk3dMCk1tpOIywr2GfCOCt4pEO0SNACV894NKNWaWvKTl+lcF3XsIeUVcEfBs4iGo 9y9peRgxqKIRBnP/vxLZTyH7eIWi9L82Hjd/XZqO33DjAWMJz7ImVNH8HnJvR5nzDVd0 RkhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8MBax5bvqnGFn59+X+0C/P+ZVgi3X2sGtV0kV14mTCU=; b=Pee3Beb/mCVIkZW1GczPMOAK4be96Rfs0KQjcs0Rbox20K9iefvCuOdCveylnEEW9h YCKitf2odQRTwq5nJfgF21G9UoCEKrq0EpZjhr4vOf/IPWAQlQ5kNBvdWAIMn8tctqcS Uy2K9pTUxRIxGZ1bmOP/cgwY3QN4/UHqHe2/cK/dM5Eo2H7Gvo/aiTbrl/iU7cOXSaCk 5ICG1mbKciCdc9uiuIV1uGorgFxH7kX6XEJrfDtCoO8Wgk2iDutyH/GR8OueLp81qnMT B2q0c5sXU6XS54DW5jS0gMjSV15GCzAMTqPXJCL9SFmX76NGO4rzIKr3o0VEE4MQLMo8 00sA== X-Gm-Message-State: ANhLgQ0Ug/0rFES5whsSVVWQyshaaC0LuoR+MYbWBCNBaSLZrIEm52vH Wp1lXddiw0TwIkeOMSFc/I20BABz6jQ= X-Google-Smtp-Source: ADFU+vvHAc0zQJ9KGH5qD0sR9j51rX4f6LTF7zdEERCfzkaTlqe335EZ0r66p+0OZ+qk3XGNC5lBFQ== X-Received: by 2002:a17:902:bf0b:: with SMTP id bi11mr10282373plb.245.1583864844846; Tue, 10 Mar 2020 11:27:24 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:24 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 06/10] tests/vm: allow wait_ssh() to specify command Date: Tue, 10 Mar 2020 14:25:32 -0400 Message-Id: <20200310182536.11137-7-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::62b X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This allows for waiting for completion of arbitrary commands. Signed-off-by: Robert Foley --- tests/vm/basevm.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 3562a33ffa..305b839000 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -394,24 +394,24 @@ class BaseVM(object): def print_step(self, text): sys.stderr.write("### %s ...\n" % text) - def wait_ssh(self, wait_root=False, seconds=300): + 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) - guest_up = False + cmd_success = False while datetime.datetime.now() < endtime: - if wait_root and self.ssh_root("exit 0") == 0: - guest_up = True + if wait_root and self.ssh_root(cmd) == 0: + cmd_success = True break - elif self.ssh("exit 0") == 0: - guest_up = True + 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 guest_up: + if not cmd_success: raise Exception("Timeout while waiting for guest ssh") def shutdown(self): From patchwork Tue Mar 10 18:25:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430083 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3353C13A4 for ; Tue, 10 Mar 2020 18:34:32 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EBBB620727 for ; Tue, 10 Mar 2020 18:34:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="J2/u+Ky3" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EBBB620727 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38518 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBji3-0007kJ-62 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:34:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44195) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjbH-0005LO-2y for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjbE-0002Rp-Vf for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:30 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:56091) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjbE-0002QT-N5 for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:28 -0400 Received: by mail-pj1-x102e.google.com with SMTP id a18so772380pjs.5 for ; Tue, 10 Mar 2020 11:27:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nWF11s9Z1ALG93i18OLFSQWlbYgwHdvSRO5TIhznGmk=; b=J2/u+Ky35YmF0akB2H6gOWNooOKqi57qkPny3F5SrKSZ59POOsGOc82Xda6IUxPmxB gj+RckA/AqfyDdy8C1HQiMMgNmrTfJHIq7wE5fuDuTw2+pjOPQ6csbIi83BlQDpt5yGJ kr2Zip/dBmKwPW3QqD1KZU5YCKM+mhielL18Xa5hddHrS07iO/AgXG/8hnMwOeFkVBLX fgKX7V/AEJk8++h9oOF8MUnXW/OzmtrSD1lwPCPER9i6fKApQfnQrPQYjNhozbxoDQd5 Rgp59YVwI/PY4CC/pwjnO1jk9Y5ANlqauCdmIyoq3pbwQF4TgMJ04YzboE0umCprHefA RWYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nWF11s9Z1ALG93i18OLFSQWlbYgwHdvSRO5TIhznGmk=; b=C0TaChanx9PNQHbuZvmYmq1fHmDeqloacx8gQq1uINckKL4XuvlZ61RMUc3cd3T493 y+6OpRLBpSDDsGmXGINmbT1zWBy3eijh8pCVuaFCPkLA5yZchZt1VKDz9Uw+ASAn10RP JJXm7ZIj+zFvD1ulxPrrrUSWDiFyVzN9hEz5yNjse08xPi612o4TeF9IeooE7vAIWKfa Vbi+wTDjjOqyg4i3nStIoo7y3kd7AcLRGebaNKv8xYJ+QwKQryeQeY3O7BwOShN5Ymt3 gGcx8LNhIy+VzA30d+rmMsUjYNFNkyKp/3dbRi62ESoC+po4aBNpFDFHS+grVcgWm4Ps G+zQ== X-Gm-Message-State: ANhLgQ1NIIpnC9jPesfMKJQ3yXUnmXYsHWndPSwR8LGvusssenw/xTJv 6jdjTIOYU899G3N3F0ls987ato9XN/A= X-Google-Smtp-Source: ADFU+vsljjNBnKWIlkNj7kgPq47hBnXD9guFG416YtZsHR8n/xUEKpcLWUplCgCBux4vNrDRxFREmw== X-Received: by 2002:a17:902:b40f:: with SMTP id x15mr22629912plr.82.1583864846698; Tue, 10 Mar 2020 11:27:26 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:26 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 07/10] tests/vm: Added a new script for ubuntu.aarch64. Date: Tue, 10 Mar 2020 14:25:33 -0400 Message-Id: <20200310182536.11137-8-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::102e X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" ubuntu.aarch64 provides a script to create an Ubuntu 18.04 VM. Another new file is also added aarch64vm.py, which is a module with common methods used by aarch64 VMs, such as how to create the flash images. Signed-off-by: Robert Foley --- configure | 16 ++++++ tests/vm/Makefile.include | 8 +++ tests/vm/aarch64vm.py | 100 ++++++++++++++++++++++++++++++++ tests/vm/basevm.py | 8 +++ tests/vm/ubuntu.aarch64 | 117 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 249 insertions(+) create mode 100644 tests/vm/aarch64vm.py create mode 100755 tests/vm/ubuntu.aarch64 diff --git a/configure b/configure index 2d49ae7446..21044008ea 100755 --- a/configure +++ b/configure @@ -947,6 +947,20 @@ do fi done +# Check for files needed by aarch64 VMs. +# Allow user to override the path for efi also. +qemu_efi_aarch64= +for fd in $QEMU_EFI_PATH /usr/share/qemu-efi-aarch64/QEMU_EFI.fd +do + if has $fd + then + if [ -f $fd ]; then + qemu_efi_aarch64=$fd + fi + break + fi +done + # Check for existence of python3 yaml, needed to # import yaml config files into vm-build. python_yaml="no" @@ -6586,6 +6600,7 @@ if test "$docs" != "no"; then echo "sphinx-build $sphinx_build" fi echo "genisoimage $genisoimage" +echo "qemu_efi_aarch64 $qemu_efi_aarch64" echo "python_yaml $python_yaml" echo "slirp support $slirp $(echo_version $slirp $slirp_version)" if test "$slirp" != "no" ; then @@ -7637,6 +7652,7 @@ echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak echo "PYTHON=$python" >> $config_host_mak echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak echo "GENISOIMAGE=$genisoimage" >> $config_host_mak +echo "QEMU_EFI_AARCH64=$qemu_efi_aarch64" >> $config_host_mak echo "PYTHON_YAML=$python_yaml" >> $config_host_mak echo "CC=$cc" >> $config_host_mak if $iasl -h > /dev/null 2>&1; then diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index 9986e4ae9a..db8bee66a5 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -5,6 +5,9 @@ IMAGES := freebsd netbsd openbsd fedora ifneq ($(GENISOIMAGE),) IMAGES += ubuntu.i386 centos +ifneq ($(QEMU_EFI_AARCH64),) +IMAGES += ubuntu.aarch64 +endif endif IMAGES_DIR := $(HOME)/.cache/qemu-vm/images @@ -23,6 +26,11 @@ vm-help vm-test: ifneq ($(GENISOIMAGE),) @echo " vm-build-centos - Build QEMU in CentOS VM, with Docker" @echo " vm-build-ubuntu.i386 - Build QEMU in ubuntu i386 VM" +ifneq ($(QEMU_EFI_AARCH64),) + @echo " vm-build-ubuntu.aarch64 - Build QEMU in ubuntu aarch64 VM" +else + @echo " (install qemu-efi-aarch64 to build centos/ubuntu aarch64 images.)" +endif else @echo " (install genisoimage to build centos/ubuntu images)" endif diff --git a/tests/vm/aarch64vm.py b/tests/vm/aarch64vm.py new file mode 100644 index 0000000000..646dc975f2 --- /dev/null +++ b/tests/vm/aarch64vm.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# +# VM testing aarch64 library +# +# Copyright 2020 Linaro +# +# Authors: +# Robert Foley +# +# This code is licensed under the GPL version 2 or later. See +# the COPYING file in the top-level directory. +# +import os +import sys +import subprocess +import basevm +from qemu.accel import kvm_available + +# This is the config needed for current version of QEMU. +# This works for both kvm and tcg. +CURRENT_CONFIG = { + 'cpu' : "max", + 'machine' : "virt,gic-version=max", +} + +# The minimum minor version of QEMU we will support with aarch64 VMs is 3. +# QEMU versions less than 3 have various issues running these VMs. +QEMU_AARCH64_MIN_VERSION = 3 + +# The DEFAULT_CONFIG will default to a version of +# parameters that works for backwards compatibility. +DEFAULT_CONFIG = {'kvm' : {'cpu' : "host", + 'machine' : "virt,gic-version=host"}, + 'tcg' : {'cpu' : "cortex-a57", + 'machine' : "virt"}, +} + +def get_config_defaults(vmcls, default_config): + """Fetch the configuration defaults for this VM, + taking into consideration the defaults for + aarch64 first, followed by the defaults for this VM.""" + config = default_config + config.update(aarch_get_config_defaults(vmcls)) + return config + +def aarch_get_config_defaults(vmcls): + """Set the defaults for current version of QEMU.""" + config = CURRENT_CONFIG + args, argv = 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 create_flash_images(flash_dir="./"): + """Creates the appropriate pflash files + for an aarch64 VM.""" + flash0_path = get_flash_path(flash_dir, "flash0") + flash1_path = get_flash_path(flash_dir, "flash1") + subprocess.check_call(["dd", "if=/dev/zero", "of={}".format(flash0_path), + "bs=1M", "count=64"]) + # A reliable way to get the QEMU EFI image is via an installed package. + efi_img = "/usr/share/qemu-efi-aarch64/QEMU_EFI.fd" + if not os.path.exists(efi_img): + sys.stderr.write("*** {} is missing\n".format(efi_img)) + sys.stderr.write("*** please install qemu-efi-aarch64 package\n") + exit(3) + subprocess.check_call(["dd", "if={}".format(efi_img), + "of={}".format(flash0_path), + "conv=notrunc"]) + subprocess.check_call(["dd", "if=/dev/zero", + "of={}".format(flash1_path), + "bs=1M", "count=64"]) + +def get_pflash_args(flash_dir="./"): + """Returns a string that can be used to + boot qemu using the appropriate pflash files + for aarch64.""" + flash0_path = get_flash_path(flash_dir, "flash0") + flash1_path = get_flash_path(flash_dir, "flash1") + pflash_args_str = "-drive file={},format=raw,if=pflash "\ + "-drive file={},format=raw,if=pflash" + pflash_args = pflash_args_str.format(flash0_path, flash1_path) + return pflash_args.split(" ") + +def get_flash_path(flash_dir, name): + return os.path.join(flash_dir, "{}.img".format(name)) diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 305b839000..a0727d7058 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -482,6 +482,14 @@ def get_qemu_path(arch, build_path=None): qemu_path = "qemu-system-" + arch return qemu_path +def get_qemu_version(qemu_path): + """Get the version number from the current QEMU, + and return the major number.""" + output = subprocess.check_output([qemu_path, '--version']) + version_line = output.decode("utf-8") + version_num = re.split(' |\(', version_line)[3].split('.')[0] + return int(version_num) + def parse_config(config, args): """ Parse yaml config and populate our config structure. The yaml config allows the user to override the diff --git a/tests/vm/ubuntu.aarch64 b/tests/vm/ubuntu.aarch64 new file mode 100755 index 0000000000..0413971d33 --- /dev/null +++ b/tests/vm/ubuntu.aarch64 @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +# +# Ubuntu aarch64 image +# +# Copyright 2020 Linaro +# +# Authors: +# Robert Foley +# Originally based on ubuntu.i386 Fam Zheng +# +# This code is licensed under the GPL version 2 or later. See +# the COPYING file in the top-level directory. +# + +import os +import sys +import subprocess +import basevm +from qemu.accel import kvm_available +import time +import aarch64vm + +DEFAULT_CONFIG = { + 'cpu' : "cortex-a57", + 'machine' : "virt,gic-version=3", + 'install_cmds' : "apt-get update,"\ + "apt-get build-dep -y qemu,"\ + "apt-get install -y libfdt-dev flex bison", + # We increase beyond the default time since during boot + # it can take some time (many seconds) to log into the VM + # especially using softmmu. + 'ssh_timeout' : 60, +} + +class UbuntuAarch64VM(basevm.BaseVM): + name = "ubuntu.aarch64" + arch = "aarch64" + image_name = "ubuntu-18.04-server-cloudimg-arm64.img" + image_link = "https://cloud-images.ubuntu.com/releases/18.04/release/" + image_name + login_prompt = "ubuntu-aarch64-guest login:" + BUILD_SCRIPT = """ + set -e; + cd $(mktemp -d); + sudo chmod a+r /dev/vdb; + tar --checkpoint=.10 -xf /dev/vdb; + ./configure {configure_opts}; + make --output-sync {target} -j{jobs} {verbose}; + """ + def boot(self, img, extra_args=None): + aarch64vm.create_flash_images(self._tmpdir) + default_args = aarch64vm.get_pflash_args(self._tmpdir) + if extra_args: + extra_args.extend(default_args) + else: + extra_args = default_args + # We always add these performance tweaks + # because without them, we boot so slowly that we + # can time out finding the boot efi device. + if '-smp' not in extra_args and \ + '-smp' not in self._config['extra_args'] and \ + '-smp' not in self._args: + # Only add if not already there to give caller option to change it. + extra_args.extend(["-smp", "8"]) + + # We have overridden boot() since aarch64 has additional parameters. + # Call down to the base class method. + super(UbuntuAarch64VM, self).boot(img, extra_args=extra_args) + + def build_image(self, img): + os_img = self._download_with_cache(self.image_link) + img_tmp = img + ".tmp" + subprocess.check_call(["cp", "-f", os_img, img_tmp]) + subprocess.check_call(["qemu-img", "resize", img_tmp, "+50G"]) + ci_img = self.gen_cloud_init_iso() + + self.boot(img_tmp, extra_args = ["-cdrom", ci_img]) + if self._boot_console: + self.wait_boot() + # First command we issue is fix for slow ssh login. + self.wait_ssh(wait_root=True, + cmd="chmod -x /etc/update-motd.d/*") + # Wait for cloud init to finish + self.wait_ssh(wait_root=True, + cmd="ls /var/lib/cloud/instance/boot-finished") + self.ssh_root("touch /etc/cloud/cloud-init.disabled") + # Disable auto upgrades. + # We want to keep the VM system state stable. + self.ssh_root('sed -ie \'s/"1"/"0"/g\' /etc/apt/apt.conf.d/20auto-upgrades') + # If the user chooses *not* to do the second phase, + # then we will jump right to the graceful shutdown + if self._config['install_cmds'] != "": + self.ssh_root("sync") + # Shutdown and then boot it again. + # Allows us to know for sure it is booting (not shutting down) + # before we call wait_ssh(). + self.graceful_shutdown() + self.boot(img_tmp) + if self._boot_console: + self.wait_boot() + self.wait_ssh(wait_root=True) + self.wait_ssh(wait_root=True, cmd="locale") + # The previous update sometimes doesn't survive a reboot, so do it again + self.ssh_root("sed -ie s/^#\ deb-src/deb-src/g /etc/apt/sources.list") + + # Issue the install commands. + # This can be overriden by the user in the config .yml. + install_cmds = self._config['install_cmds'].split(',') + for cmd in install_cmds: + self.ssh_root(cmd) + self.graceful_shutdown() + self.wait() + os.rename(img_tmp, img) + return 0 + +if __name__ == "__main__": + defaults = aarch64vm.get_config_defaults(UbuntuAarch64VM, DEFAULT_CONFIG) + sys.exit(basevm.main(UbuntuAarch64VM, defaults)) From patchwork Tue Mar 10 18:25:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430129 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 62F5913A4 for ; Tue, 10 Mar 2020 18:36:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 286F220727 for ; Tue, 10 Mar 2020 18:36:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="oGHqxWAX" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 286F220727 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38566 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjjf-0002hA-Cg for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:36:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44245) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjbJ-0005RH-FO for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjbH-0002V6-2t for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:33 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]:50875) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjbG-0002Tg-MN for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:31 -0400 Received: by mail-pj1-x102d.google.com with SMTP id u10so781407pjy.0 for ; Tue, 10 Mar 2020 11:27:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TQQ7Ghv7WzXH77WZM2n6MIWyZg+mWPnPLpAbH2ZM5iU=; b=oGHqxWAXOBN+kgYUU9rDmJcP6PXpDhJSRO1m2d3h16F3M2Jg5R1WrwMYqmYzDTcoyL iqbZcw+xN7lseI8YH5vsdHNdzHQ4BIWMzbAa67wYDjc0kWtCFbpWx/VIW441PBJZwA+f 7BwdM8Udimm/5+iyvSiDJugNeZjz08eo42+aM6n/D7vS7q8dIahkOLCR7JT5Jce4h2dK HHk7CY/JrokUZmfduLRhq2epjKGeD3VEoTeUggWfDJzWDWpzUfvAU1JHVpw2HwRUay0D nLj3eWEqeUeO1U1UE3ONmCbCYwIRZiP2Lj5kPNQJ6NjDcWtkIx3iDfcaaS/8gQ59Sb61 LC7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TQQ7Ghv7WzXH77WZM2n6MIWyZg+mWPnPLpAbH2ZM5iU=; b=nctM3fR/LRFjcyZE7ZTK0ibmn/arHSKqTuH5EQzQvFXHdxbRKlSFdGy8PtTU1r1IDK vxNrZDQOlNhPeah3NF7edyBd3Ty6aKuygITftjqvmi304vc5GZRCsyQ+++fm6z4Jp7f4 38BFGoHR8jO+nB98PErf+6ykLKOgtRjcoR+IDOcVwGpSDU3Y6KEyNeACqPGqfDaZ80S/ QrBXpvet3ZlnKGI0PYcSXhHrjbfMFn/Sjhlzr37m99qzqvHMbDOeznjyBDk3gNlx5T4O 8w1e+etvaIDFXq/D/vFfRkuU7QwqfTKBCg5xLEwgYl31Z+cfnJ+SbD/WHKwe0A0pTSj4 recA== X-Gm-Message-State: ANhLgQ2SLSYpvXs19cx/U9u4dS50vEkFOqeTMeYP4C2Xfg7IfOFtWOUX rmQdCuVR3HuJ8gsUUeghYLbMiR35I1Q= X-Google-Smtp-Source: ADFU+vtZzjrpdn+/KXJfGYuImQQid+eYJJ7hrAV2vpt5ZdY4F1U7pffsa2BzLvi7GjSODQlOutUaZg== X-Received: by 2002:a17:90a:252b:: with SMTP id j40mr2965451pje.189.1583864848894; Tue, 10 Mar 2020 11:27:28 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:27 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 08/10] tests/vm: Added a new script for centos.aarch64. Date: Tue, 10 Mar 2020 14:25:34 -0400 Message-Id: <20200310182536.11137-9-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::102d X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" centos.aarch64 creates a CentOS 8 image. Also added a new kickstart script used to build the centos.aarch64 image. Signed-off-by: Robert Foley --- tests/vm/Makefile.include | 3 +- tests/vm/centos-8-aarch64.ks | 51 ++++++++ tests/vm/centos.aarch64 | 226 +++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 tests/vm/centos-8-aarch64.ks create mode 100755 tests/vm/centos.aarch64 diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index db8bee66a5..75868d3b37 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -6,7 +6,7 @@ IMAGES := freebsd netbsd openbsd fedora ifneq ($(GENISOIMAGE),) IMAGES += ubuntu.i386 centos ifneq ($(QEMU_EFI_AARCH64),) -IMAGES += ubuntu.aarch64 +IMAGES += ubuntu.aarch64 centos.aarch64 endif endif @@ -28,6 +28,7 @@ ifneq ($(GENISOIMAGE),) @echo " vm-build-ubuntu.i386 - Build QEMU in ubuntu i386 VM" ifneq ($(QEMU_EFI_AARCH64),) @echo " vm-build-ubuntu.aarch64 - Build QEMU in ubuntu aarch64 VM" + @echo " vm-build-centos.aarch64 - Build QEMU in CentOS aarch64 VM" else @echo " (install qemu-efi-aarch64 to build centos/ubuntu aarch64 images.)" endif diff --git a/tests/vm/centos-8-aarch64.ks b/tests/vm/centos-8-aarch64.ks new file mode 100644 index 0000000000..fd6ebe4d49 --- /dev/null +++ b/tests/vm/centos-8-aarch64.ks @@ -0,0 +1,51 @@ +# CentOS aarch64 image kickstart file. +# This file is used by the CentOS installer to +# script the generation of the image. +# +# Copyright 2020 Linaro +# +ignoredisk --only-use=vda +# System bootloader configuration +bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=vda +autopart --type=plain +# Partition clearing information +clearpart --linux --initlabel --drives=vda +# Use text mode install +text +repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream +# Use CDROM installation media +cdrom +# Keyboard layouts +keyboard --vckeymap=us --xlayouts='' +# System language +lang en_US.UTF-8 + +# Network information +network --bootproto=dhcp --device=enp0s1 --onboot=off --ipv6=auto --no-activate +network --hostname=localhost.localdomain +# Run the Setup Agent on first boot +firstboot --enable +# Do not configure the X Window System +skipx +# System services +services --enabled="chronyd" +# System timezone +timezone America/New_York --isUtc + +# Shutdown after installation is complete. +shutdown + +%packages +@^server-product-environment +kexec-tools + +%end + +%addon com_redhat_kdump --enable --reserve-mb='auto' + +%end +%anaconda +pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty +pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok +pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty +%end diff --git a/tests/vm/centos.aarch64 b/tests/vm/centos.aarch64 new file mode 100755 index 0000000000..f2aa79e02d --- /dev/null +++ b/tests/vm/centos.aarch64 @@ -0,0 +1,226 @@ +#!/usr/bin/env python3 +# +# Centos aarch64 image +# +# Copyright 2020 Linaro +# +# Authors: +# Robert Foley +# Originally based on ubuntu.aarch64 +# +# This code is licensed under the GPL version 2 or later. See +# the COPYING file in the top-level directory. +# + +import os +import sys +import subprocess +import basevm +import time +import traceback +import aarch64vm + +DEFAULT_CONFIG = { + 'cpu' : "max", + 'machine' : "virt,gic-version=max", + 'install_cmds' : "yum install -y make git python3 gcc gcc-c++ flex bison, "\ + "yum install -y glib2-devel pixman-devel zlib-devel, "\ + "yum install -y perl-Test-Harness, "\ + "sudo dnf config-manager "\ + "--add-repo=https://download.docker.com/linux/centos/docker-ce.repo,"\ + "sudo dnf install --nobest -y docker-ce.aarch64,"\ + "systemctl enable docker", + # We increase beyond the default time since during boot + # it can take some time (many seconds) to log into the VM. + 'ssh_timeout' : 60, +} + +class CentosAarch64VM(basevm.BaseVM): + name = "centos.aarch64" + arch = "aarch64" + login_prompt = "localhost login:" + prompt = '[root@localhost ~]#' + image_name = "CentOS-8-aarch64-1905-dvd1.iso" + image_link = "http://mirrors.usc.edu/pub/linux/distributions/centos/8.0.1905/isos/aarch64/" + image_link += image_name + BUILD_SCRIPT = """ + set -e; + cd $(mktemp -d); + sudo chmod a+r /dev/vdb; + tar --checkpoint=.10 -xf /dev/vdb; + ./configure {configure_opts}; + make --output-sync {target} -j{jobs} {verbose}; + """ + def set_key_perm(self): + """Set permissions properly on certain files to allow + ssh access.""" + self.console_wait_send(self.prompt, + "/usr/sbin/restorecon -R -v /root/.ssh\n") + self.console_wait_send(self.prompt, + "/usr/sbin/restorecon -R -v "\ + "/home/{}/.ssh\n".format(self._config["guest_user"])) + + def create_kickstart(self): + """Generate the kickstart file used to generate the centos image.""" + # Start with the template for the kickstart. + ks_file = "../tests/vm/centos-8-aarch64.ks" + subprocess.check_call("cp {} ./ks.cfg".format(ks_file), shell=True) + # Append the ssh keys to the kickstart file + # as the post processing phase of installation. + with open("ks.cfg", "a") as f: + # Add in the root pw and guest user. + rootpw = "rootpw --plaintext {}\n" + f.write(rootpw.format(self._config["root_pass"])) + add_user = "user --groups=wheel --name={} "\ + "--password={} --plaintext\n" + f.write(add_user.format(self._config["guest_user"], + self._config["guest_pass"])) + # Add the ssh keys. + f.write("%post --log=/root/ks-post.log\n") + f.write("mkdir -p /root/.ssh\n") + addkey = 'echo "{}" >> /root/.ssh/authorized_keys\n' + addkey_cmd = addkey.format(self._config["ssh_pub_key"]) + f.write(addkey_cmd) + f.write('mkdir -p /home/{}/.ssh\n'.format(self._config["guest_user"])) + addkey = 'echo "{}" >> /home/{}/.ssh/authorized_keys\n' + addkey_cmd = addkey.format(self._config["ssh_pub_key"], + self._config["guest_user"]) + f.write(addkey_cmd) + f.write("%end\n") + # Take our kickstart file and create an .iso from it. + # The .iso will be provided to qemu as we boot + # from the install dvd. + # Anaconda will recognize the label "OEMDRV" and will + # start the automated installation. + gen_iso_img = 'genisoimage -output ks.iso -volid "OEMDRV" ks.cfg' + subprocess.check_call(gen_iso_img, shell=True) + + def wait_for_shutdown(self): + """We wait for qemu to shutdown the VM and exit. + While this happens we display the console view + for easier debugging.""" + # The image creation is essentially done, + # so whether or not the wait is successful we want to + # wait for qemu to exit (the self.wait()) before we return. + try: + self.console_wait("reboot: Power down") + except Exception as e: + sys.stderr.write("Exception hit\n") + if isinstance(e, SystemExit) and e.code == 0: + return 0 + traceback.print_exc() + finally: + self.wait() + + def build_base_image(self, dest_img): + """Run through the centos installer to create + a base image with name dest_img.""" + # We create the temp image, and only rename + # to destination when we are done. + img = dest_img + ".tmp" + # Create an empty image. + # We will provide this as the install destination. + qemu_img_create = "qemu-img create {} 50G".format(img) + subprocess.check_call(qemu_img_create, shell=True) + + # Create our kickstart file to be fed to the installer. + self.create_kickstart() + # Boot the install dvd with the params as our ks.iso + os_img = self._download_with_cache(self.image_link) + dvd_iso = "centos-8-dvd.iso" + subprocess.check_call(["cp", "-f", os_img, dvd_iso]) + extra_args = "-cdrom ks.iso" + extra_args += " -drive file={},if=none,id=drive1,cache=writeback" + extra_args += " -device virtio-blk,drive=drive1,bootindex=1" + extra_args = extra_args.format(dvd_iso).split(" ") + self.boot(img, extra_args=extra_args) + self.console_wait_send("change the selection", "\n") + # We seem to need to hit esc (chr(27)) twice to abort the + # media check, which takes a long time. + # Waiting a bit seems to be more reliable before hitting esc. + self.console_wait("Checking") + time.sleep(5) + self.console_wait_send("Checking", chr(27)) + time.sleep(5) + self.console_wait_send("Checking", chr(27)) + print("Found Checking") + # Give sufficient time for the installer to create the image. + self.console_init(timeout=7200) + self.wait_for_shutdown() + os.rename(img, dest_img) + print("Done with base image build: {}".format(dest_img)) + + def check_create_base_img(self, img_base, img_dest): + """Create a base image using the installer. + We will use the base image if it exists. + This helps cut down on install time in case we + need to restart image creation, + since the base image creation can take a long time.""" + if not os.path.exists(img_base): + print("Generate new base image: {}".format(img_base)) + self.build_base_image(img_base); + else: + print("Use existing base image: {}".format(img_base)) + # Save a copy of the base image and copy it to dest. + # which we will use going forward. + subprocess.check_call(["cp", img_base, img_dest]) + + def boot(self, img, extra_args=None): + aarch64vm.create_flash_images(self._tmpdir) + default_args = aarch64vm.get_pflash_args(self._tmpdir) + if extra_args: + extra_args.extend(default_args) + else: + extra_args = default_args + # We always add these performance tweaks + # because without them, we boot so slowly that we + # can time out finding the boot efi device. + if '-smp' not in extra_args and \ + '-smp' not in self._config['extra_args'] and \ + '-smp' not in self._args: + # Only add if not already there to give caller option to change it. + extra_args.extend(["-smp", "8"]) + # We have overridden boot() since aarch64 has additional parameters. + # Call down to the base class method. + super(CentosAarch64VM, self).boot(img, extra_args=extra_args) + + def build_image(self, img): + img_tmp = img + ".tmp" + self.check_create_base_img(img + ".base", img_tmp) + + # Boot the new image for the first time to finish installation. + self.boot(img_tmp) + self.console_init() + self.console_wait_send(self.login_prompt, "root\n") + self.console_wait_send("Password:", + "{}\n".format(self._config["root_pass"])) + + self.set_key_perm() + self.console_wait_send(self.prompt, "rpm -q centos-release\n") + enable_adapter = "sed -i 's/ONBOOT=no/ONBOOT=yes/g'" \ + " /etc/sysconfig/network-scripts/ifcfg-enp0s1\n" + self.console_wait_send(self.prompt, enable_adapter) + self.console_wait_send(self.prompt, "ifup enp0s1\n") + self.console_wait_send(self.prompt, + 'echo "qemu ALL=(ALL) NOPASSWD:ALL" | '\ + 'sudo tee /etc/sudoers.d/qemu\n') + self.console_wait(self.prompt) + + # Rest of the commands we issue through ssh. + self.wait_ssh(wait_root=True) + + # If the user chooses *not* to do the second phase, + # then we will jump right to the graceful shutdown + if self._config['install_cmds'] != "": + install_cmds = self._config['install_cmds'].split(',') + for cmd in install_cmds: + self.ssh_root(cmd) + self.ssh_root("poweroff") + self.wait_for_shutdown() + os.rename(img_tmp, img) + print("image creation complete: {}".format(img)) + return 0 + +if __name__ == "__main__": + defaults = aarch64vm.get_config_defaults(CentosAarch64VM, DEFAULT_CONFIG) + sys.exit(basevm.main(CentosAarch64VM, defaults)) From patchwork Tue Mar 10 18:25:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430081 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 960C413A4 for ; Tue, 10 Mar 2020 18:32:58 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5BD9D20727 for ; Tue, 10 Mar 2020 18:32:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="Rx+f8aH+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5BD9D20727 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38490 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjgX-0005QG-Jo for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:32:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44264) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjbK-0005Uc-F3 for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjbI-0002Xc-Kf for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:34 -0400 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]:41789) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjbI-0002WG-Cd for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:32 -0400 Received: by mail-pf1-x442.google.com with SMTP id z65so6876960pfz.8 for ; Tue, 10 Mar 2020 11:27:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Zu55w57Oui8Xur6dOmzXIZRXCZIx7GGCMyc1jtFJeG4=; b=Rx+f8aH+7jwAESyrt1hwQiP9aqLBc4bZ0RAjZxZCNM3poy90MG6VZNMc139sxt/sbQ QpNfZgNXXXqDn+XkSLGbFIQopQ5KabYHrMDbkJRZzu8CHgNmgdwQRHSMY0Sl3mUL5CQu 7nd230J278psW3IB6J8GF08Xb+lZRsxU4uSGYpNwNgMH+7fOcPvcelfAXJYnBAwhI1An pazo6l8FPV9S8ItdCGaGHJ/Xi/jrlNz1We8LPlTdQDFXoP0vPactipBKwu6ofOnZiae7 uiDaMEaydvJXj7Ja4dnU3DKzFAD7mG83Q/L2msInRhtfpQjXNlGtyHSkYbNfanXp8Q0b Vgnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Zu55w57Oui8Xur6dOmzXIZRXCZIx7GGCMyc1jtFJeG4=; b=j5XeJlBtj5FJVG7fnW4MDwNSRbcuXU86E+2UWvzWNjxPx8goOBnZHb1OjQsEzuzv6p I4bPPNz4SdmEl+wDtmJsgmzzQKm/cuYblYvyHYf8q6p+nNjcP8aBQUGJCaIQvSAWcS6d jPyrzupG4e261ur2m/TRdVQENYnQBehFUgZNX8/knFdJ51fdnWUYxbeg3EOTvn397VlE 2rxYcYJCaEYry39qkNBUXikopGzl5jYjtQmSc3Jiqy99fryEiRcrgro9hGBj8+35kB9I iyE4wA78VziVY/4YVI7oBjktfJ6jxe/HQIFgmG7uHF1UcO9UWxBFVTnaXSM6eAu4eecd pSlw== X-Gm-Message-State: ANhLgQ08No81pRSrBhr82r0ugPQ1ZIn4seCQe50PIIN2Xc/eE4tQWgHN UMF1TpP6FM3MIV3I4WSrr+qsz4USvPg= X-Google-Smtp-Source: ADFU+vvjDe17yEhqzJetrz4ikwGLO/iZNROEoy5/McdqUiI1OXzi4JGCJ+x2/EfB2B2y0w6M7t91ZQ== X-Received: by 2002:a63:a062:: with SMTP id u34mr22851996pgn.286.1583864850804; Tue, 10 Mar 2020 11:27:30 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:30 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 09/10] tests/vm: change scripts to use self._config Date: Tue, 10 Mar 2020 14:25:35 -0400 Message-Id: <20200310182536.11137-10-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::442 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This change converts existing scripts to using for example self.ROOT_PASS, to self._config['root_pass']. We made similar changes for GUEST_USER, and GUEST_PASS. This allows us also to remove the change in basevm.py, which adds __getattr__ for backwards compatibility. Signed-off-by: Robert Foley --- tests/vm/basevm.py | 11 ++--------- tests/vm/fedora | 17 +++++++++-------- tests/vm/freebsd | 16 ++++++++-------- tests/vm/netbsd | 19 ++++++++++--------- tests/vm/openbsd | 17 +++++++++-------- 5 files changed, 38 insertions(+), 42 deletions(-) diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index a0727d7058..bd4a1f9639 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -170,13 +170,6 @@ class BaseVM(object): self.console_init(timeout=timeout) self.console_wait(wait_string) - def __getattr__(self, name): - # Support direct access to config by key. - # for example, access self._config['cpu'] by self.cpu - if name.lower() in self._config.keys(): - return self._config[name.lower()] - return object.__getattribute__(self, name) - def _download_with_cache(self, url, sha256sum=None, sha512sum=None): def check_sha256sum(fname): if not sha256sum: @@ -226,13 +219,13 @@ class BaseVM(object): return r def ssh(self, *cmd): - return self._ssh_do(self.GUEST_USER, cmd, False) + return self._ssh_do(self._config["guest_user"], cmd, False) def ssh_root(self, *cmd): return self._ssh_do("root", cmd, False) def ssh_check(self, *cmd): - self._ssh_do(self.GUEST_USER, cmd, True) + self._ssh_do(self._config["guest_user"], cmd, True) def ssh_root_check(self, *cmd): self._ssh_do("root", cmd, True) diff --git a/tests/vm/fedora b/tests/vm/fedora index 4843b4175e..6a7023eb71 100755 --- a/tests/vm/fedora +++ b/tests/vm/fedora @@ -108,20 +108,20 @@ class FedoraVM(basevm.BaseVM): self.console_wait_send("7) [!] Root password", "7\n") self.console_wait("Password:") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait("Password (confirm):") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait_send("8) [ ] User creation", "8\n") self.console_wait_send("1) [ ] Create user", "1\n") self.console_wait_send("3) User name", "3\n") - self.console_wait_send("ENTER:", "%s\n" % self.GUEST_USER) + self.console_wait_send("ENTER:", "%s\n" % self._config["guest_user"]) self.console_wait_send("4) [ ] Use password", "4\n") self.console_wait_send("5) Password", "5\n") self.console_wait("Password:") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait("Password (confirm):") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait_send("7) Groups", "c\n") while True: @@ -139,7 +139,7 @@ class FedoraVM(basevm.BaseVM): if good: break time.sleep(10) - self.console_send("r\n" % self.GUEST_PASS) + self.console_send("r\n" % self._config["guest_pass"]) self.console_wait_send("'b' to begin install", "b\n") @@ -150,12 +150,13 @@ class FedoraVM(basevm.BaseVM): # setup qemu user prompt = " ~]$" - self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) + self.console_ssh_init(prompt, self._config["guest_user"], + self._config["guest_pass"]) self.console_wait_send(prompt, "exit\n") # setup root user prompt = " ~]#" - self.console_ssh_init(prompt, "root", self.ROOT_PASS) + self.console_ssh_init(prompt, "root", self._config["root_pass"]) self.console_sshd_config(prompt) # setup virtio-blk #1 (tarfile) diff --git a/tests/vm/freebsd b/tests/vm/freebsd index 86770878b6..43f14f102d 100755 --- a/tests/vm/freebsd +++ b/tests/vm/freebsd @@ -113,9 +113,9 @@ class FreeBSDVM(basevm.BaseVM): # post-install configuration self.console_wait("New Password:") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait("Retype New Password:") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait_send("Network Configuration", "\n") self.console_wait_send("IPv4", "y") @@ -134,9 +134,9 @@ class FreeBSDVM(basevm.BaseVM): # qemu user self.console_wait_send("Add User Accounts", "y") self.console_wait("Username") - self.console_send("%s\n" % self.GUEST_USER) + self.console_send("%s\n" % self._config["guest_user"]) self.console_wait("Full name") - self.console_send("%s\n" % self.GUEST_USER) + self.console_send("%s\n" % self._config["guest_user"]) self.console_wait_send("Uid", "\n") self.console_wait_send("Login group", "\n") self.console_wait_send("Login group", "\n") @@ -148,9 +148,9 @@ class FreeBSDVM(basevm.BaseVM): self.console_wait_send("Use an empty password", "\n") self.console_wait_send("Use a random password", "\n") self.console_wait("Enter password:") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait("Enter password again:") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait_send("Lock out", "\n") self.console_wait_send("OK", "yes\n") self.console_wait_send("Add another user", "no\n") @@ -164,12 +164,12 @@ class FreeBSDVM(basevm.BaseVM): # setup qemu user prompt = "$" - self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) + self.console_ssh_init(prompt, self._config["guest_user"], self._config["guest_pass"]) self.console_wait_send(prompt, "exit\n") # setup root user prompt = "root@freebsd:~ #" - self.console_ssh_init(prompt, "root", self.ROOT_PASS) + self.console_ssh_init(prompt, "root", self._config["root_pass"]) self.console_sshd_config(prompt) # setup serial console diff --git a/tests/vm/netbsd b/tests/vm/netbsd index 55590f4601..e953fcd161 100755 --- a/tests/vm/netbsd +++ b/tests/vm/netbsd @@ -131,24 +131,24 @@ class NetBSDVM(basevm.BaseVM): self.console_wait_send("d: Change root password", "d\n") self.console_wait_send("a: Yes", "a\n") self.console_wait("New password:") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait("New password:") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait("Retype new password:") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait_send("o: Add a user", "o\n") self.console_wait("username") - self.console_send("%s\n" % self.GUEST_USER) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait("to group wheel") self.console_wait_send("a: Yes", "a\n") self.console_wait_send("a: /bin/sh", "a\n") self.console_wait("New password:") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait("New password:") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait("Retype new password:") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait_send("a: Configure network", "a\n") self.console_wait_send("a: vioif0", "a\n") @@ -181,12 +181,13 @@ class NetBSDVM(basevm.BaseVM): # setup qemu user prompt = "localhost$" - self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) + self.console_ssh_init(prompt, self._config["guest_user"], + self._config["guest_pass"]) self.console_wait_send(prompt, "exit\n") # setup root user prompt = "localhost#" - self.console_ssh_init(prompt, "root", self.ROOT_PASS) + self.console_ssh_init(prompt, "root", self._config["root_pass"]) self.console_sshd_config(prompt) # setup virtio-blk #1 (tarfile) diff --git a/tests/vm/openbsd b/tests/vm/openbsd index ab6abbedab..445ea78516 100755 --- a/tests/vm/openbsd +++ b/tests/vm/openbsd @@ -98,9 +98,9 @@ class OpenBSDVM(basevm.BaseVM): self.console_wait_send("Which network interface", "done\n") self.console_wait_send("DNS domain name", "localnet\n") self.console_wait("Password for root account") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait("Password for root account") - self.console_send("%s\n" % self.ROOT_PASS) + self.console_send("%s\n" % self._config["root_pass"]) self.console_wait_send("Start sshd(8)", "yes\n") self.console_wait_send("X Window System", "\n") self.console_wait_send("xenodm", "\n") @@ -108,13 +108,13 @@ class OpenBSDVM(basevm.BaseVM): self.console_wait_send("Which speed", "\n") self.console_wait("Setup a user") - self.console_send("%s\n" % self.GUEST_USER) + self.console_send("%s\n" % self._config["guest_user"]) self.console_wait("Full name") - self.console_send("%s\n" % self.GUEST_USER) + self.console_send("%s\n" % self._config["guest_user"]) self.console_wait("Password") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait("Password") - self.console_send("%s\n" % self.GUEST_PASS) + self.console_send("%s\n" % self._config["guest_pass"]) self.console_wait_send("Allow root ssh login", "yes\n") self.console_wait_send("timezone", "UTC\n") @@ -135,12 +135,13 @@ class OpenBSDVM(basevm.BaseVM): # setup qemu user prompt = "$" - self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS) + self.console_ssh_init(prompt, self._config["guest_user"], + self._config["guest_pass"]) self.console_wait_send(prompt, "exit\n") # setup root user prompt = "openbsd#" - self.console_ssh_init(prompt, "root", self.ROOT_PASS) + self.console_ssh_init(prompt, "root", self._config["root_pass"]) self.console_sshd_config(prompt) # setup virtio-blk #1 (tarfile) From patchwork Tue Mar 10 18:25:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foley X-Patchwork-Id: 11430131 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DD5C41731 for ; Tue, 10 Mar 2020 18:37:22 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A308C227BF for ; Tue, 10 Mar 2020 18:37:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="XXaqgeHs" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A308C227BF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:38594 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjkn-0004J8-PE for patchwork-qemu-devel@patchwork.kernel.org; Tue, 10 Mar 2020 14:37:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44305) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBjbM-0005cj-OH for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBjbK-0002Zm-FW for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:36 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]:53722) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jBjbK-0002Yr-6N for qemu-devel@nongnu.org; Tue, 10 Mar 2020 14:27:34 -0400 Received: by mail-pj1-x102c.google.com with SMTP id l36so777433pjb.3 for ; Tue, 10 Mar 2020 11:27:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WguiU1MpCfikMD0tIg2PmMZ5FyB6ak1jQimxWfvBjhM=; b=XXaqgeHsQ6TTpUb1LJjXFiM7cdPqq4158BfYtItZ2bOAXmJuKq4GbMB0aRFQtukL6k 79dhgUfUO4oKgex4ztcLwBCZ73Cwy3d6TNJFOzJ/2F5kpIiGWBuH34jcOd5vBz3dNQbx HL5aZIlqXxAEPqWTh41bWicF7vqmIktR0rrC/rhSbvJt9o33Ulkyzpsbl+W9krFRYlZi CQGLDBYGt/QDk94TPqvRu3q8lwa4fYiP4U81PKQIhGgEx3BM03IRZxk/oDClcCyHvJWF Qd6iI4hd/JCbT2OydnvSl4oTOJ/qV23oE6PfEbx4XrVbN5d49qpGZOPVJl0HfFyXoqPE uf+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WguiU1MpCfikMD0tIg2PmMZ5FyB6ak1jQimxWfvBjhM=; b=Gf9PV+dMJkZ2o1qPAIhgdnd3qj+dZmX86Oeo2nYBOPhYAzO9kWiDVXECPW2mvGKjLi yk6KX+EfA4354Dw4FnOqx1d+RkN9pGhzaJ0gucGxGz5pgEmVsePAYPo2BsX/JR10Gcq6 12RbpQCRmxg2dg3iFymzEXsG/WQ2lF+RSm4ibTkqO2tA9jfxMRR9yAJikZGO9pqa8AmX o3Nq3H4GcG4YjuARpoDsbXsxp4j8z2keODYtgrGsYxCzII86hZzAEDtomIsreHrvglON xp6VmS1vnURF1F5UBo84Z6sM7ar8MHcLechpeAXO+4OqC6pdmDT3M4Zkoj7rdfUt52I3 FeHg== X-Gm-Message-State: ANhLgQ3Kg8DXeAzDyxUgsugH16P7zI5yt1eaGgHALHuQ/pqPMGf0uiCe zE7Efcfw5BXQloquexQfxjTq7WVlKjw= X-Google-Smtp-Source: ADFU+vtahLjHVyKSEEKT16QUT4Jt+vcG9Z+xx6YAfFHPfphyCnnge+6jYQMbDWkevdfci0l38qO6Xg== X-Received: by 2002:a17:902:d915:: with SMTP id c21mr11813164plz.239.1583864852545; Tue, 10 Mar 2020 11:27:32 -0700 (PDT) Received: from Rfoley-MA01.usrd.futurewei.com ([12.111.81.71]) by smtp.gmail.com with ESMTPSA id p1sm8730692pfq.114.2020.03.10.11.27.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2020 11:27:31 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v3 10/10] tests/vm: Add workaround to consume console Date: Tue, 10 Mar 2020 14:25:36 -0400 Message-Id: <20200310182536.11137-11-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200310182536.11137-1-robert.foley@linaro.org> References: <20200310182536.11137-1-robert.foley@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::102c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: philmd@redhat.com, alex.bennee@linaro.org, robert.foley@linaro.org, peter.puhov@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The ConsoleSocket object provides a socket interface which will consume all arriving characters on the socket, but will provide those chars via recv() as would a regular socket. This is a workaround we found was needed since there is a known issue where QEMU will hang waiting for console characters to be consumed. We also add the option of logging the console to a file. Signed-off-by: Robert Foley --- python/qemu/console_socket.py | 162 ++++++++++++++++++++++++++++++++++ python/qemu/machine.py | 12 ++- tests/vm/Makefile.include | 4 + tests/vm/basevm.py | 23 ++++- 4 files changed, 193 insertions(+), 8 deletions(-) create mode 100644 python/qemu/console_socket.py diff --git a/python/qemu/console_socket.py b/python/qemu/console_socket.py new file mode 100644 index 0000000000..a1f74e60ac --- /dev/null +++ b/python/qemu/console_socket.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# +# This python module implements a ConsoleSocket object which is +# designed always drain the socket itself, and place +# the bytes into a in memory buffer for later processing. +# +# Optionally a file path can be passed in and we will also +# dump the characters to this file for debug. +# +# Copyright 2020 Linaro +# +# Authors: +# Robert Foley +# +# This code is licensed under the GPL version 2 or later. See +# the COPYING file in the top-level directory. +# +import asyncore +import socket +import threading +import io +import os +import sys +from collections import deque +import time +import traceback + +class ConsoleSocket(asyncore.dispatcher): + + def __init__(self, address, file=None): + self._recv_timeout_sec = 300 + self._buffer = deque() + self._asyncore_thread = None + self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self._sock.connect(address) + self._logfile = None + if file: + self._logfile = open(file, "w") + asyncore.dispatcher.__init__(self, sock=self._sock) + self._thread_start() + self._open = True + + def _thread_start(self): + """Kick off a thread to wait on the asyncore.loop""" + if self._asyncore_thread is not None: + return + self._asyncore_thread = threading.Thread(target=asyncore.loop, + kwargs={'timeout':1}) + self._asyncore_thread.daemon = True + self._asyncore_thread.start() + + def handle_close(self): + """redirect close to base class""" + # Call the base class close, but not self.close() since + # handle_close() occurs in the context of the thread which + # self.close() attempts to join. + asyncore.dispatcher.close(self) + + def close(self): + """Close the base object and wait for the thread to terminate""" + if self._open: + self._open = False + asyncore.dispatcher.close(self) + if self._asyncore_thread is not None: + thread, self._asyncore_thread = self._asyncore_thread, None + thread.join() + if self._logfile: + self._logfile.close() + self._logfile = None + + def handle_read(self): + """process arriving characters into in memory _buffer""" + try: + data = asyncore.dispatcher.recv(self, 1) + # latin1 is needed since there are some chars + # we are receiving that cannot be encoded to utf-8 + # such as 0xe2, 0x80, 0xA6. + string = data.decode("latin1") + except: + print("Exception seen.") + traceback.print_exc() + return + if self._logfile: + self._logfile.write("{}".format(string)) + self._logfile.flush() + for c in string: + self._buffer.append(c) + + def recv(self, n=1): + """Return chars from in memory buffer""" + start_time = time.time() + while len(self._buffer) < n: + time.sleep(0.1) + elapsed_sec = time.time() - start_time + if elapsed_sec > self._recv_timeout_sec: + raise socket.timeout + chars = ''.join([self._buffer.popleft() for i in range(n)]) + # We choose to use latin1 to remain consistent with + # handle_read() and give back the same data as the user would + # receive if they were reading directly from the + # socket w/o our intervention. + return chars.encode("latin1") + + def set_blocking(self): + """Maintain compatibility with socket API""" + pass + + def settimeout(self, seconds): + """Set current timeout on recv""" + self._recv_timeout_sec = seconds + +class ByteBuffer(deque): + """Simple in memory buffer with read/write interface""" + def write(self, bytes): + for i in bytes: + self.append(i) + def read(self, n): + return ''.join([self.popleft() for i in range(n)]) + +if __name__ == '__main__': + # Brief test to exercise the above code. + # The ConsoleSocket will ship some data to the server, + # the server will echo it back and the client will echo what it received. + + # First remove the socket. + address = "./test_console_socket" + if os.path.exists(address): + os.unlink(address) + + # Create the server side. + server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + server_socket.bind(address) + server_socket.listen(1) + + # Create the object we are trying to test. + console_socket = ConsoleSocket(address, file="./logfile.txt") + + # Generate some data and ship it over the socket. + send_data = "" + for i in range(10): + send_data += "this is a test message {}\n".format(i) + console_socket.send(send_data.encode('latin1')) + connection, client_address = server_socket.accept() + + # Process the data on the server and ship it back. + data = connection.recv(len(send_data)) + print("server received: {}".format(data)) + print("server: sending data back to the client") + connection.sendall(data) + + # Client receives teh bytes and displays them. + print("client: receiving bytes") + bytes = console_socket.recv(len(data)) + recv_data = bytes.decode('latin1') + print("client received: {}".format(recv_data)) + assert(recv_data == send_data) + # Close console connection first, then close server. + console_socket.close() + connection.close() + server_socket.close() + print("test successful.") + diff --git a/python/qemu/machine.py b/python/qemu/machine.py index 183d8f3d38..6a4a5c2845 100644 --- a/python/qemu/machine.py +++ b/python/qemu/machine.py @@ -24,6 +24,7 @@ import subprocess import shutil import socket import tempfile +from qemu.console_socket import ConsoleSocket from . import qmp @@ -71,7 +72,8 @@ class QEMUMachine(object): def __init__(self, binary, args=None, wrapper=None, name=None, test_dir="/var/tmp", monitor_address=None, - socket_scm_helper=None, sock_dir=None): + socket_scm_helper=None, sock_dir=None, + console_log=None): ''' Initialize a QEMUMachine @@ -82,6 +84,8 @@ class QEMUMachine(object): @param test_dir: where to create socket and log file @param monitor_address: address for QMP monitor @param socket_scm_helper: helper program, required for send_fd_scm() + @param sock_dir: where to create socket (overrides test_dir for sock) + @param console_log: (optional) path to console log file @note: Qemu process is not started until launch() is used. ''' if args is None: @@ -118,6 +122,7 @@ class QEMUMachine(object): self._console_address = None self._console_socket = None self._remove_files = [] + self._console_log_path = console_log # just in case logging wasn't configured by the main script: logging.basicConfig() @@ -566,7 +571,6 @@ class QEMUMachine(object): Returns a socket connected to the console """ if self._console_socket is None: - self._console_socket = socket.socket(socket.AF_UNIX, - socket.SOCK_STREAM) - self._console_socket.connect(self._console_address) + self._console_socket = ConsoleSocket(self._console_address, + file=self._console_log_path) return self._console_socket diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index 75868d3b37..71595d2d25 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -50,6 +50,7 @@ endif @echo " J=[0..9]* - Override the -jN parameter for make commands" @echo " DEBUG=1 - Enable verbose output on host and interactive debugging" @echo " BOOT_CONSOLE=1 - Show the console output at boot time. " + @echo " LOG_CONSOLE=1 - Log console to file in: ~/.cache/qemu-vm " @echo " V=1 - Enable verbose ouput on host and guest commands" @echo " QEMU_LOCAL=1 - Use QEMU binary local to this build." @echo " QEMU=/path/to/qemu - Change path to QEMU binary" @@ -85,6 +86,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \ $(PYTHON) $< \ $(if $(V)$(DEBUG), --debug) \ $(if $(BOOT_CONSOLE),--boot-console) \ + $(if $(LOG_CONSOLE),--log-console) \ --build-path $(BUILD_DIR)\ --image "$@" \ --force \ @@ -102,6 +104,7 @@ vm-build-%: $(IMAGES_DIR)/%.img $(if $(J),--jobs $(J)) \ $(if $(V),--verbose) \ $(if $(BOOT_CONSOLE),--boot-console) \ + $(if $(LOG_CONSOLE),--log-console) \ --build-path $(BUILD_DIR)\ --image "$<" \ $(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \ @@ -126,6 +129,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img $(PYTHON) $(SRC_PATH)/tests/vm/$* \ $(if $(J),--jobs $(J)) \ $(if $(BOOT_CONSOLE),--boot-console) \ + $(if $(LOG_CONSOLE),--log-console) \ --build-path $(BUILD_DIR)\ --image "$<" \ --interactive \ diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index bd4a1f9639..998c5d54c1 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -81,12 +81,14 @@ class BaseVM(object): poweroff = "poweroff" # enable IPv6 networking ipv6 = True + # This is the timeout on the wait for console bytes. + socket_timeout = 120 # Scale up some timeouts under TCG. # 4 is arbitrary, but greater than 2, # since we found we need to wait more than twice as long. tcg_ssh_timeout_multiplier = 4 def __init__(self, debug=False, vcpus=None, config=None, - boot_console=False, build_path=None): + boot_console=False, build_path=None, log_console=False): self._guest = None self._build_path = build_path self._boot_console = boot_console @@ -113,6 +115,11 @@ class BaseVM(object): open(self._ssh_tmp_pub_key_file, "w").write(self._config['ssh_pub_key']) + self._console_log_path = None + if log_console: + self._console_log_path = \ + os.path.join(os.path.expanduser("~/.cache/qemu-vm"), + "{}.install.log".format(self.name)) self.debug = debug self._stderr = sys.stderr self._devnull = open(os.devnull, "w") @@ -259,7 +266,8 @@ class BaseVM(object): args += ["-device", "VGA"] logging.debug("QEMU args: %s", " ".join(args)) qemu_path = get_qemu_path(self.arch, self._build_path) - guest = QEMUMachine(binary=qemu_path, args=args) + guest = QEMUMachine(binary=qemu_path, args=args, + console_log=self._console_log_path) guest.set_machine(self._config['machine']) guest.set_console() try: @@ -273,6 +281,8 @@ class BaseVM(object): raise atexit.register(self.shutdown) self._guest = guest + # Init console so we can start consuming the chars. + self.console_init() usernet_info = guest.qmp("human-monitor-command", command_line="info usernet") self.ssh_port = None @@ -284,7 +294,9 @@ class BaseVM(object): raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \ usernet_info) - def console_init(self, timeout = 120): + def console_init(self, timeout = None): + if timeout == None: + timeout = self.socket_timeout vm = self._guest vm.console_socket.settimeout(timeout) @@ -559,6 +571,8 @@ def parse_args(vmcls): help="Show console during boot. ") parser.add_option("--build-path", default=None, help="Path of build directory. ") + parser.add_option("--log-console", action="store_true", + help="Log console to file.") parser.disable_interspersed_args() return parser.parse_args() @@ -575,7 +589,8 @@ def main(vmcls, config=None): else logging.WARN)) vm = vmcls(debug=args.debug, vcpus=args.jobs, config=config, boot_console=args.boot_console, - build_path=args.build_path) + build_path=args.build_path, + log_console=args.log_console) if args.build_image: if os.path.exists(args.image) and not args.force: sys.stderr.writelines(["Image file exists: %s\n" % args.image,