• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6import socket
7
8import common
9from autotest_lib.client.common_lib import hosts
10from autotest_lib.server import utils
11
12
13def require_servo(host):
14    """Require a DUT to have a working servo for a repair action."""
15    if not host.servo:
16        raise hosts.AutoservRepairError(
17                '%s has no working servo.' % host.hostname, 'no_working_servo')
18
19
20class SshVerifier(hosts.Verifier):
21    """
22    Verifier to test a host's accessibility via `ssh`.
23
24    This verifier checks whether a given host is reachable over `ssh`.
25    In the event of failure, it distinguishes one of three distinct
26    conditions:
27      * The host can't be found with a DNS lookup.
28      * The host doesn't answer to ping.
29      * The host answers to ping, but not to ssh.
30    """
31
32    def verify(self, host):
33        if host.is_up():
34            return
35        msg = 'No answer to ssh from %s'
36        try:
37            socket.gethostbyname(host.hostname)
38        except Exception as e:
39            logging.exception('DNS lookup failure')
40            msg = 'Unable to look up %%s in DNS: %s' % e
41        else:
42            if utils.ping(host.hostname, tries=1, deadline=1) != 0:
43                msg = 'No answer to ping from %s'
44        raise hosts.AutoservVerifyError(msg % host.hostname)
45
46
47    @property
48    def description(self):
49        return 'host is available via ssh'
50
51
52class LegacyHostVerifier(hosts.Verifier):
53    """
54    Ask a Host instance to perform its own verification.
55
56    This class exists as a temporary legacy during refactoring to
57    provide access to code that hasn't yet been rewritten to use the new
58    repair and verify framework.
59    """
60
61    def verify(self, host):
62        host.verify_software()
63        host.verify_hardware()
64
65
66    @property
67    def description(self):
68        return 'Legacy host verification checks'
69
70
71class RebootRepair(hosts.RepairAction):
72    """Repair a target device by rebooting it."""
73
74    def repair(self, host):
75        host.reboot()
76
77
78    @property
79    def description(self):
80        return 'Reboot the host'
81
82
83class RPMCycleRepair(hosts.RepairAction):
84    """
85    Cycle AC power using the RPM infrastructure.
86
87    This is meant to catch two distinct kinds of failure:
88      * If the target has no battery (that is, a chromebox), power
89        cycling it may force it back on.
90      * If the target has a batter that is discharging or even fully
91        drained, power cycling will leave power on, enabling other
92        repair procedures.
93    """
94
95    def repair(self, host):
96        if not host.has_power():
97            raise hosts.AutoservRepairError(
98                    '%s has no RPM connection.' % host.hostname,
99                    'no_working_rpm')
100        host.power_cycle()
101        if not host.wait_up(timeout=host.BOOT_TIMEOUT):
102            raise hosts.AutoservRepairError(
103                    '%s is still offline after powercycling' %
104                    host.hostname, 'failed_to_boot_after_rpm_power_cycle')
105
106
107    @property
108    def description(self):
109        return 'Power cycle the host with RPM'
110