From patchwork Fri Mar 2 00:34:10 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael-Doyle Hudson X-Patchwork-Id: 7041 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id E97E92447B for ; Fri, 2 Mar 2012 00:34:14 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 89422A1813A for ; Fri, 2 Mar 2012 00:34:14 +0000 (UTC) Received: by iage36 with SMTP id e36so2075793iag.11 for ; Thu, 01 Mar 2012 16:34:14 -0800 (PST) Received: from mr.google.com ([10.50.89.201]) by 10.50.89.201 with SMTP id bq9mr6678494igb.55.1330648454034 (num_hops = 1); Thu, 01 Mar 2012 16:34:14 -0800 (PST) Received: by 10.50.89.201 with SMTP id bq9mr5484930igb.55.1330648453988; Thu, 01 Mar 2012 16:34:13 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.53.18 with SMTP id k18csp31138ibg; Thu, 1 Mar 2012 16:34:12 -0800 (PST) Received: by 10.180.80.35 with SMTP id o3mr203823wix.5.1330648451710; Thu, 01 Mar 2012 16:34:11 -0800 (PST) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id x24si2926359weq.120.2012.03.01.16.34.10 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 01 Mar 2012 16:34:11 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1S3GRm-000058-G5 for ; Fri, 02 Mar 2012 00:34:10 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 70AC1E14CA for ; Fri, 2 Mar 2012 00:34:10 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: lava-dispatcher X-Launchpad-Branch: ~linaro-validation/lava-dispatcher/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 237 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-validation/lava-dispatcher/trunk] Rev 237: remove the connection abstraction which did not work very well Message-Id: <20120302003410.25698.99511.launchpad@ackee.canonical.com> Date: Fri, 02 Mar 2012 00:34:10 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="14886"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 67e5e8043656b427d24d0be2ed09842f5bbc133d X-Gm-Message-State: ALoCoQmxc/+tF8UQa6kZ02dT0DoVvpaoIDKL8QiPKyq0CiwnzSrBGhRzP08au9RYGVLlWq63P6gq Merge authors: Michael Hudson-Doyle (mwhudson) Related merge proposals: https://code.launchpad.net/~mwhudson/lava-dispatcher/kill-connection/+merge/95278 proposed by: Michael Hudson-Doyle (mwhudson) review: Approve - Paul Larson (pwlars) ------------------------------------------------------------ revno: 237 [merge] committer: Michael Hudson-Doyle branch nick: trunk timestamp: Fri 2012-03-02 13:32:27 +1300 message: remove the connection abstraction which did not work very well removed: lava_dispatcher/connection.py modified: lava_dispatcher/client/base.py lava_dispatcher/client/master.py lava_dispatcher/client/qemu.py lava_dispatcher/utils.py --- lp:lava-dispatcher https://code.launchpad.net/~linaro-validation/lava-dispatcher/trunk You are subscribed to branch lp:lava-dispatcher. To unsubscribe from this branch go to https://code.launchpad.net/~linaro-validation/lava-dispatcher/trunk/+edit-subscription === modified file 'lava_dispatcher/client/base.py' --- lava_dispatcher/client/base.py 2012-02-20 00:41:31 +0000 +++ lava_dispatcher/client/base.py 2012-02-29 02:17:16 +0000 @@ -26,7 +26,6 @@ import time from cStringIO import StringIO import traceback -from lava_dispatcher.utils import string_to_list import logging @@ -292,11 +291,6 @@ return self.device_option("TESTER_STR") @property - def boot_cmds(self): - uboot_str = self.device_option("boot_cmds") - return string_to_list(uboot_str) - - @property def device_type(self): return self.device_option("device_type") @@ -391,7 +385,7 @@ """ logging.info("Boot the test image") - self.proc._boot(self.boot_cmds) + self._boot_linaro_image() self.in_test_shell(300) # set PS1 to include return value of last command # Details: system PS1 is set in /etc/bash.bashrc and user PS1 is set in @@ -412,7 +406,7 @@ def boot_linaro_android_image(self): """Reboot the system to the test android image.""" - self.proc._boot(string_to_list(self.config.get('boot_cmds_android'))) + self._boot_linaro_android_image() self.in_test_shell(timeout=900) self.proc.sendline("export PS1=\"root@linaro: \"") === modified file 'lava_dispatcher/client/master.py' --- lava_dispatcher/client/master.py 2012-02-29 01:33:14 +0000 +++ lava_dispatcher/client/master.py 2012-02-29 02:32:27 +0000 @@ -22,17 +22,21 @@ import contextlib import logging import os -import pexpect +import re import shutil import subprocess from tempfile import mkdtemp import time import traceback +import pexpect + from lava_dispatcher.utils import ( download, download_with_cache, + logging_spawn, logging_system, + string_to_list, ) from lava_dispatcher.client.base import ( CommandRunner, @@ -45,9 +49,6 @@ generate_image, image_partition_mounted, ) -from lava_dispatcher.connection import ( - LavaConmuxConnection, - ) def _extract_partition(image, partno, tarfile): @@ -256,7 +257,11 @@ def __init__(self, context, config): super(LavaMasterImageClient, self).__init__(context, config) - self.proc = LavaConmuxConnection(config, self.sio) + cmd = self.device_option("connection_command") + proc = logging_spawn(cmd, timeout=1200, logfile=self.sio) + #serial can be slow, races do funny things if you don't increase delay + proc.delaybeforesend=1 + self.proc = proc @property def master_str(self): @@ -441,13 +446,13 @@ reboot the system, and check that we are in a master shell """ logging.info("Boot the system master image") - self.proc.soft_reboot() + self.soft_reboot() try: self.proc.expect("Starting kernel") self._in_master_shell(300) except: logging.exception("in_master_shell failed") - self.proc.hard_reboot() + self.hard_reboot() self._in_master_shell(300) self.proc.sendline('export PS1="$PS1 [rc=$(echo \$?)]: "') self.proc.expect(self.master_str, timeout=10, lava_no_logging=1) @@ -595,7 +600,7 @@ [self.master_str, pexpect.TIMEOUT], timeout=timeout, lava_no_logging=1) if match_id == 1: raise OperationFailed - + @contextlib.contextmanager def _master_session(self): """A session that can be used to run commands in the master image. @@ -609,3 +614,46 @@ except OperationFailed: self.boot_master_image() yield MasterCommandRunner(self) + + def soft_reboot(self): + logging.info("Perform soft reboot the system") + cmd = self.device_option("soft_boot_cmd") + if cmd != "": + self.proc.sendline(cmd) + else: + self.proc.sendline("reboot") + # set soft reboot timeout 120s, or do a hard reset + id = self.proc.expect( + ['Restarting system.', 'The system is going down for reboot NOW', + 'Will now restart', pexpect.TIMEOUT], timeout=120) + if id not in [0, 1, 2]: + self.hard_reboot() + + def hard_reboot(self): + logging.info("Perform hard reset on the system") + self.proc.send("~$") + self.proc.sendline("hardreset") + + def _enter_uboot(self): + self.proc.expect("Hit any key to stop autoboot") + self.proc.sendline("") + + def _boot_linaro_image(self): + self._boot(string_to_list(self.config.get('boot_cmds'))) + + def _boot_linaro_android_image(self): + self._boot(string_to_list(self.config.get('boot_cmds_android'))) + + def _boot(self, boot_cmds): + self.soft_reboot() + try: + self._enter_uboot() + except: + logging.exception("_enter_uboot failed") + self.hard_reboot() + self._enter_uboot() + self.proc.sendline(boot_cmds[0]) + bootloader_prompt = re.escape(self.device_option('bootloader_prompt')) + for line in range(1, len(boot_cmds)): + self.proc.expect(bootloader_prompt, timeout=300) + self.proc.sendline(boot_cmds[line]) === modified file 'lava_dispatcher/client/qemu.py' --- lava_dispatcher/client/qemu.py 2012-02-26 20:45:59 +0000 +++ lava_dispatcher/client/qemu.py 2012-02-29 22:38:07 +0000 @@ -33,6 +33,7 @@ image_partition_mounted, ) from lava_dispatcher.utils import ( + logging_spawn, logging_system, ) @@ -106,7 +107,8 @@ self.device_option('qemu_machine_type'), self._lava_image) logging.info('launching qemu with command %r' % qemu_cmd) - self.proc = pexpect.spawn(qemu_cmd, logfile=self.sio, timeout=None) + self.proc = logging_spawn( + qemu_cmd, logfile=self.sio, timeout=None) self.proc.expect(self.tester_str, timeout=300) # set PS1 to include return value of last command self.proc.sendline('export PS1="$PS1 [rc=$(echo \$?)]: "') === removed file 'lava_dispatcher/connection.py' --- lava_dispatcher/connection.py 2012-01-26 10:20:09 +0000 +++ lava_dispatcher/connection.py 1970-01-01 00:00:00 +0000 @@ -1,128 +0,0 @@ -# Copyright (C) 2011 Linaro Limited -# -# Author: Michael Hudson-Doyle -# -# This file is part of LAVA Dispatcher. -# -# LAVA Dispatcher is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# LAVA Dispatcher is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along -# with this program; if not, see . - -import logging -import pexpect -import re - - -class LavaConnection(object): - - def __init__(self, device_config, sio): - self.device_config = device_config - self.proc = self._make_connection(sio) - - def _make_connection(self, sio): - raise NotImplementedError(self._make_connection) - - def device_option(self, option_name): - return self.device_config.get(option_name) - - def device_option_int(self, option_name): - return self.device_config.getint(option_name) - - - # pexpect-like interface. - - def sendline(self, *args, **kw): - logging.debug("sendline : %s" %args[0]) - return self.proc.sendline(*args, **kw) - - def send(self, *args, **kw): - logging.debug("sendline : %s" %args[0]) - return self.proc.send(*args, **kw) - - def expect(self, *args, **kw): - # some expect should not be logged because it is so much noise. - if kw.has_key('lava_no_logging'): - del kw['lava_no_logging'] - return self.proc.expect(*args, **kw) - - if (kw.has_key('timeout')): - timeout = kw['timeout'] - else: - timeout = self.proc.timeout - - if len(args) == 1: - logging.debug("expect (%d): '%s'" %(timeout, args[0])) - else: - logging.debug("expect (%d): '%s'" %(timeout, str(args))) - - return self.proc.expect(*args, **kw) - - def sendcontrol(self, *args, **kw): - return self.proc.sendcontrol(*args, **kw) - - @property - def match(self): - return self.proc.match - - - # Extra bits. - - def _enter_uboot(self): - self.expect("Hit any key to stop autoboot") - self.sendline("") - - def soft_reboot(self): - logging.info("Perform soft reboot the system") - cmd = self.device_option("soft_boot_cmd") - if cmd != "": - self.sendline(cmd) - else: - self.sendline("reboot") - # set soft reboot timeout 120s, or do a hard reset - id = self.expect( - ['Restarting system.', 'The system is going down for reboot NOW', - 'Will now restart', pexpect.TIMEOUT], timeout=120) - if id not in [0,1,2]: - self.hard_reboot() - - def hard_reboot(self): - raise NotImplementedError(self.hard_reboot) - - -class LavaConmuxConnection(LavaConnection): - - def _make_connection(self, sio): - cmd = self.device_option("connection_command") - proc = pexpect.spawn(cmd, timeout=1200, logfile=sio) - #serial can be slow, races do funny things if you don't increase delay - proc.delaybeforesend=1 - return proc - - def hard_reboot(self): - logging.info("Perform hard reset on the system") - self.proc.send("~$") - self.proc.sendline("hardreset") - - def _boot(self, boot_cmds): - self.soft_reboot() - try: - self._enter_uboot() - except: - logging.exception("_enter_uboot failed") - self.hard_reboot() - self._enter_uboot() - self.sendline(boot_cmds[0]) - bootloader_prompt = re.escape(self.device_option('bootloader_prompt')) - for line in range(1, len(boot_cmds)): - self.expect(bootloader_prompt, timeout=300) - self.sendline(boot_cmds[line]) === modified file 'lava_dispatcher/utils.py' --- lava_dispatcher/utils.py 2012-02-28 03:19:36 +0000 +++ lava_dispatcher/utils.py 2012-02-29 02:44:17 +0000 @@ -26,6 +26,9 @@ import urlparse from shlex import shlex +import pexpect + + def download(url, path="", verbose_failure=1): urlpath = urlparse.urlsplit(url).path filename = os.path.basename(urlpath) @@ -93,3 +96,31 @@ logging.debug("Executing on host : '%r'"%cmd) return os.system(cmd) + +class logging_spawn(pexpect.spawn): + + def sendline(self, *args, **kw): + logging.debug("sendline : %s" %args[0]) + return super(logging_spawn, self).sendline(*args, **kw) + + def send(self, *args, **kw): + logging.debug("send : %s" %args[0]) + return super(logging_spawn, self).send(*args, **kw) + + def expect(self, *args, **kw): + # some expect should not be logged because it is so much noise. + if kw.has_key('lava_no_logging'): + del kw['lava_no_logging'] + return self.expect(*args, **kw) + + if (kw.has_key('timeout')): + timeout = kw['timeout'] + else: + timeout = self.timeout + + if len(args) == 1: + logging.debug("expect (%d): '%s'" %(timeout, args[0])) + else: + logging.debug("expect (%d): '%s'" %(timeout, str(args))) + + return super(logging_spawn, self).expect(*args, **kw)