From c9f67455db59a17b9ee6b01d6d6117d4dc14e99b Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Nov 07 2018 14:00:40 +0000 Subject: inventory: Include log output when VM fails to boot When the VM fails to boot, include PTY log output in the failure message. This allows us to easily diagnose the problem without looking through all the artifacts. --- diff --git a/inventory/standard-inventory-qcow2 b/inventory/standard-inventory-qcow2 index 7bb55ea..3f3563d 100755 --- a/inventory/standard-inventory-qcow2 +++ b/inventory/standard-inventory-qcow2 @@ -342,7 +342,7 @@ def start_qemu(image, cloudinit, portrange=(2222, 5555)): logger.info("qemu-kvm is running with VNC server. PID: {}".format(qemu_proc.pid)) logger.info("netstat -ltpn4 | grep {0} # to find VNC server port".format(qemu_proc.pid)) - return qemu_proc, port + return qemu_proc, port, log_guest def inv_host(image): @@ -383,9 +383,10 @@ def inv_host(image): proc = None # for failure detection cpe = None # for exception scoping + log = None for _ in range(0, 5): try: - proc, port = start_qemu(image, cloudinit) + proc, port, log = start_qemu(image, cloudinit) break except subprocess.CalledProcessError as cpe: time.sleep(1) @@ -424,7 +425,7 @@ def inv_host(image): (pid, _) = os.waitpid(proc.pid, os.WNOHANG) if pid != 0: - raise RuntimeError("qemu failed to launch qcow2 image: {0}".format(image)) + raise RuntimeError("qemu failed to launch VM for qcow2 image: {0}".format(image)) subprocess.check_call(ping, stdout=null, stderr=null) break except subprocess.CalledProcessError: @@ -435,7 +436,14 @@ def inv_host(image): os.kill(proc.pid, signal.SIGTERM) except OSError: pass - raise RuntimeError("could not access launched qcow2 image: {0}".format(image)) + # Read the last lines of the log + try: + with open(log) as f: + data = f.readlines() + output = "\nLast lines of {0}:\n".format(os.path.basename(log)) + "".join(data[-10:]) + except OSError: + output = "" + raise RuntimeError("Could not access VM launched from qcow2 image: {0}{1}".format(image, output)) # Process of our parent ppid = os.getppid() @@ -526,7 +534,9 @@ if __name__ == '__main__': try: main(sys.argv) ret = 0 + except RuntimeError as ex: + logger.error("{0}".format(ex)) except Exception: # Backtrace stack goes to log file. If TEST_DEBUG == 1, it goes to stderr too. - logger.info("Fatal error in provision script.", exc_info=True) + logger.error("Fatal error in provision script.", exc_info=True) sys.exit(ret)