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