All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Fam Zheng" <fam@euphon.net>, "Ed Maste" <emaste@freebsd.org>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Kamil Rytarowski" <kamil@netbsd.org>,
	"Gerd Hoffmann" <kraxel@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>,
	"Li-Wen Hsu" <lwhsu@freebsd.org>,
	"Brad Smith" <brad@comstyle.com>
Subject: [Qemu-devel] [PATCH v4 06/11] tests/vm: serial console support helpers
Date: Mon, 17 Jun 2019 06:38:53 +0200	[thread overview]
Message-ID: <20190617043858.8290-7-kraxel@redhat.com> (raw)
In-Reply-To: <20190617043858.8290-1-kraxel@redhat.com>

Add a bunch of helpers to talk to the guest using the
serial console.

Also drop the hard-coded -serial parameter for the vm
so QEMUMachine.set_console() actually works.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
---
 tests/vm/basevm.py | 86 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 3 deletions(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index f27178f3c7c2..592a3447735f 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -2,10 +2,11 @@
 #
 # VM testing base class
 #
-# Copyright 2017 Red Hat Inc.
+# Copyright 2017-2019 Red Hat Inc.
 #
 # Authors:
 #  Fam Zheng <famz@redhat.com>
+#  Gerd Hoffmann <kraxel@redhat.com>
 #
 # This code is licensed under the GPL version 2 or later.  See
 # the COPYING file in the top-level directory.
@@ -13,7 +14,9 @@
 
 from __future__ import print_function
 import os
+import re
 import sys
+import socket
 import logging
 import time
 import datetime
@@ -79,8 +82,7 @@ class BaseVM(object):
             "-cpu", "max",
             "-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22",
             "-device", "virtio-net-pci,netdev=vnet",
-            "-vnc", "127.0.0.1:0,to=20",
-            "-serial", "file:%s" % os.path.join(self._tmpdir, "serial.out")]
+            "-vnc", "127.0.0.1:0,to=20"]
         if vcpus and vcpus > 1:
             self._args += ["-smp", "%d" % vcpus]
         if kvm_available(self.arch):
@@ -162,6 +164,8 @@ class BaseVM(object):
         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_console()
         try:
             guest.launch()
         except:
@@ -184,6 +188,82 @@ class BaseVM(object):
             raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
                             usernet_info)
 
+    def console_init(self, timeout = 120):
+        vm = self._guest
+        vm.console_socket.settimeout(timeout)
+
+    def console_log(self, text):
+        for line in re.split("[\r\n]", text):
+            # filter out terminal escape sequences
+            line = re.sub("\x1b\[[0-9;?]*[a-zA-Z]", "", line)
+            line = re.sub("\x1b\([0-9;?]*[a-zA-Z]", "", line)
+            # replace unprintable chars
+            line = re.sub("\x1b", "<esc>", line)
+            line = re.sub("[\x00-\x1f]", ".", line)
+            line = re.sub("[\x80-\xff]", ".", line)
+            if line == "":
+                continue
+            # log console line
+            sys.stderr.write("con recv: %s\n" % line)
+
+    def console_wait(self, expect):
+        vm = self._guest
+        output = ""
+        while True:
+            try:
+                chars = vm.console_socket.recv(1)
+            except socket.timeout:
+                sys.stderr.write("console: *** read timeout ***\n")
+                sys.stderr.write("console: waiting for: '%s'\n" % expect)
+                sys.stderr.write("console: line buffer:\n")
+                sys.stderr.write("\n")
+                self.console_log(output.rstrip())
+                sys.stderr.write("\n")
+                raise
+            output += chars.decode("latin1")
+            if expect in output:
+                break
+            if "\r" in output or "\n" in output:
+                lines = re.split("[\r\n]", output)
+                output = lines.pop()
+                if self.debug:
+                    self.console_log("\n".join(lines))
+        if self.debug:
+            self.console_log(output)
+
+    def console_send(self, command):
+        vm = self._guest
+        if self.debug:
+            logline = re.sub("\n", "<enter>", command)
+            logline = re.sub("[\x00-\x1f]", ".", logline)
+            sys.stderr.write("con send: %s\n" % logline)
+        for char in list(command):
+            vm.console_socket.send(char.encode("utf-8"))
+            time.sleep(0.01)
+
+    def console_wait_send(self, wait, command):
+        self.console_wait(wait)
+        self.console_send(command)
+
+    def console_ssh_init(self, prompt, user, pw):
+        sshkey_cmd = "echo '%s' > .ssh/authorized_keys\n" % 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")
+        self.console_wait_send(prompt,      sshkey_cmd)
+        self.console_wait_send(prompt,      "chmod 755 .ssh\n")
+        self.console_wait_send(prompt,      "chmod 644 .ssh/authorized_keys\n")
+
+    def console_sshd_config(self, prompt):
+        self.console_wait(prompt)
+        self.console_send("echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config\n")
+        for var in self.envvars:
+            self.console_wait(prompt)
+            self.console_send("echo 'AcceptEnv %s' >> /etc/ssh/sshd_config\n" % var)
+
+    def print_step(self, text):
+        sys.stderr.write("### %s ...\n" % text)
+
     def wait_ssh(self, seconds=300):
         starttime = datetime.datetime.now()
         endtime = starttime + datetime.timedelta(seconds=seconds)
-- 
2.18.1



  parent reply	other threads:[~2019-06-17  4:48 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-17  4:38 [Qemu-devel] [PATCH v4 00/11] tests/vm: serial console autoinstall, misc fixes Gerd Hoffmann
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 01/11] tests/vm: send proxy environment variables over ssh Gerd Hoffmann
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 02/11] tests/vm: use ssh with pty unconditionally Gerd Hoffmann
2019-06-17 16:09   ` Philippe Mathieu-Daudé
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 03/11] tests/vm: run test builds on snapshot Gerd Hoffmann
2019-06-17 16:15   ` Philippe Mathieu-Daudé
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 04/11] tests/vm: proper guest shutdown Gerd Hoffmann
2019-06-17 16:09   ` Philippe Mathieu-Daudé
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 05/11] tests/vm: add vm-boot-{ssh, serial}-<guest> targets Gerd Hoffmann
2019-06-17 16:11   ` Philippe Mathieu-Daudé
2019-06-17  4:38 ` Gerd Hoffmann [this message]
2019-06-17 16:12   ` [Qemu-devel] [PATCH v4 06/11] tests/vm: serial console support helpers Philippe Mathieu-Daudé
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 07/11] tests/vm: openbsd autoinstall, using serial console Gerd Hoffmann
2019-06-17 16:12   ` Philippe Mathieu-Daudé
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 08/11] tests/vm: freebsd " Gerd Hoffmann
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 09/11] tests/vm: netbsd " Gerd Hoffmann
2019-06-17 16:13   ` Philippe Mathieu-Daudé
2019-07-05 10:24   ` Alex Bennée
2019-07-05 10:43     ` Kamil Rytarowski
2019-07-05 10:47       ` Philippe Mathieu-Daudé
2019-07-05 10:49         ` Kamil Rytarowski
2019-07-05 10:52       ` Peter Maydell
2019-07-05 11:05         ` Daniel P. Berrangé
2019-07-05 11:10         ` Alex Bennée
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 10/11] tests/vm: fedora " Gerd Hoffmann
2019-06-17 16:13   ` Philippe Mathieu-Daudé
2019-06-17  4:38 ` [Qemu-devel] [PATCH v4 11/11] tests/vm: ubuntu.i386: apt proxy setup Gerd Hoffmann
2019-06-17  9:21 ` [Qemu-devel] [PATCH v4 00/11] tests/vm: serial console autoinstall, misc fixes Alex Bennée
2019-06-17 15:44 ` Alex Bennée

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190617043858.8290-7-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=brad@comstyle.com \
    --cc=emaste@freebsd.org \
    --cc=fam@euphon.net \
    --cc=kamil@netbsd.org \
    --cc=lwhsu@freebsd.org \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.