1# 2# Copyright (C) 2016 Intel Corporation 3# 4# SPDX-License-Identifier: MIT 5# 6 7import os 8import sys 9import signal 10import time 11import glob 12import subprocess 13from collections import defaultdict 14 15from .ssh import OESSHTarget 16from oeqa.utils.qemurunner import QemuRunner 17from oeqa.utils.dump import MonitorDumper 18from oeqa.utils.dump import TargetDumper 19 20supported_fstypes = ['ext3', 'ext4', 'cpio.gz', 'wic'] 21 22class OEQemuTarget(OESSHTarget): 23 def __init__(self, logger, server_ip, timeout=300, user='root', 24 port=None, machine='', rootfs='', kernel='', kvm=False, slirp=False, 25 dump_dir='', dump_host_cmds='', display='', bootlog='', 26 tmpdir='', dir_image='', boottime=60, serial_ports=2, 27 boot_patterns = defaultdict(str), ovmf=False, tmpfsdir=None, **kwargs): 28 29 super(OEQemuTarget, self).__init__(logger, None, server_ip, timeout, 30 user, port) 31 32 self.server_ip = server_ip 33 self.server_port = 0 34 self.machine = machine 35 self.rootfs = rootfs 36 self.kernel = kernel 37 self.kvm = kvm 38 self.ovmf = ovmf 39 self.use_slirp = slirp 40 self.boot_patterns = boot_patterns 41 self.dump_dir = dump_dir 42 self.bootlog = bootlog 43 44 self.runner = QemuRunner(machine=machine, rootfs=rootfs, tmpdir=tmpdir, 45 deploy_dir_image=dir_image, display=display, 46 logfile=bootlog, boottime=boottime, 47 use_kvm=kvm, use_slirp=slirp, dump_dir=dump_dir, 48 dump_host_cmds=dump_host_cmds, logger=logger, 49 serial_ports=serial_ports, boot_patterns = boot_patterns, 50 use_ovmf=ovmf, tmpfsdir=tmpfsdir) 51 dump_monitor_cmds = kwargs.get("testimage_dump_monitor") 52 self.monitor_dumper = MonitorDumper(dump_monitor_cmds, dump_dir, self.runner) 53 if self.monitor_dumper: 54 self.monitor_dumper.create_dir("qmp") 55 56 dump_target_cmds = kwargs.get("testimage_dump_target") 57 self.target_dumper = TargetDumper(dump_target_cmds, dump_dir, self.runner) 58 self.target_dumper.create_dir("qemu") 59 60 def start(self, params=None, extra_bootparams=None, runqemuparams=''): 61 if self.use_slirp and not self.server_ip: 62 self.logger.error("Could not start qemu with slirp without server ip - provide 'TEST_SERVER_IP'") 63 raise RuntimeError("FAILED to start qemu - check the task log and the boot log") 64 if self.runner.start(params, extra_bootparams=extra_bootparams, runqemuparams=runqemuparams): 65 self.ip = self.runner.ip 66 if self.use_slirp: 67 target_ip_port = self.runner.ip.split(':') 68 if len(target_ip_port) == 2: 69 target_ip = target_ip_port[0] 70 port = target_ip_port[1] 71 self.ip = target_ip 72 self.ssh = self.ssh + ['-p', port] 73 self.scp = self.scp + ['-P', port] 74 else: 75 self.logger.error("Could not get host machine port to connect qemu with slirp, ssh will not be " 76 "able to connect to qemu with slirp") 77 if self.runner.server_ip: 78 self.server_ip = self.runner.server_ip 79 else: 80 self.stop() 81 # Display the first 20 lines of top and 82 # last 20 lines of the bootlog when the 83 # target is not being booted up. 84 topfile = glob.glob(self.dump_dir + "/*_qemu/host_*_top") 85 msg = "\n\n===== start: snippet =====\n\n" 86 for f in topfile: 87 msg += "file: %s\n\n" % f 88 with open(f) as tf: 89 for x in range(20): 90 msg += next(tf) 91 msg += "\n\n===== end: snippet =====\n\n" 92 blcmd = ["tail", "-20", self.bootlog] 93 msg += "===== start: snippet =====\n\n" 94 try: 95 out = subprocess.check_output(blcmd, stderr=subprocess.STDOUT, timeout=1).decode('utf-8') 96 msg += "file: %s\n\n" % self.bootlog 97 msg += out 98 except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError) as err: 99 msg += "Error running command: %s\n%s\n" % (blcmd, err) 100 msg += "\n\n===== end: snippet =====\n" 101 102 raise RuntimeError("FAILED to start qemu - check the task log and the boot log %s" % (msg)) 103 104 def stop(self): 105 self.runner.stop() 106