blob: daa925a8f0f5af995e87d584bf3a963c6b0f5be5 [file] [log] [blame]
jadmanski1c5e3a12008-08-15 23:08:20 +00001import os, sys, subprocess
2
jadmanskia2db9412008-08-22 21:47:24 +00003from autotest_lib.client.common_lib import utils, error
4from autotest_lib.server import utils as server_utils
jadmanski1c5e3a12008-08-15 23:08:20 +00005from autotest_lib.server.hosts import site_host
6
7
8class SerialHost(site_host.SiteHost):
jadmanskia2db9412008-08-22 21:47:24 +00009 DEFAULT_REBOOT_TIMEOUT = site_host.SiteHost.DEFAULT_REBOOT_TIMEOUT
10
jadmanski1c5e3a12008-08-15 23:08:20 +000011 def __init__(self, conmux_server=None, conmux_attach=None,
jadmanskic533bd12008-09-03 20:48:51 +000012 console_log="console.log", *args, **dargs):
jadmanski1c5e3a12008-08-15 23:08:20 +000013 super(SerialHost, self).__init__(*args, **dargs)
14
jadmanskic533bd12008-09-03 20:48:51 +000015 self.__logger = None
16 self.__console_log = console_log
17
jadmanski1c5e3a12008-08-15 23:08:20 +000018 self.conmux_server = conmux_server
jadmanskia2db9412008-08-22 21:47:24 +000019 self.conmux_attach = self._get_conmux_attach(conmux_attach)
jadmanski1c5e3a12008-08-15 23:08:20 +000020
jadmanski1c5e3a12008-08-15 23:08:20 +000021
jadmanskia2db9412008-08-22 21:47:24 +000022 @classmethod
23 def _get_conmux_attach(cls, conmux_attach=None):
24 if conmux_attach:
25 return conmux_attach
26
27 # assume we're using the conmux-attach provided with autotest
28 server_dir = server_utils.get_server_dir()
29 path = os.path.join(server_dir, "..", "conmux", "conmux-attach")
30 path = os.path.abspath(path)
31 return path
32
33
34 @staticmethod
35 def _get_conmux_hostname(hostname, conmux_server):
36 if conmux_server:
37 return "%s/%s" % (conmux_server, hostname)
jadmanski1c5e3a12008-08-15 23:08:20 +000038 else:
jadmanskia2db9412008-08-22 21:47:24 +000039 return hostname
40
41
42 def get_conmux_hostname(self):
43 return self._get_conmux_hostname(self.hostname, self.conmux_server)
44
45
46 @classmethod
47 def host_is_supported(cls, hostname, conmux_server=None,
48 conmux_attach=None):
49 """ Returns a boolean indicating if the remote host with "hostname"
50 supports use as a SerialHost """
51 conmux_attach = cls._get_conmux_attach(conmux_attach)
52 conmux_hostname = cls._get_conmux_hostname(hostname, conmux_server)
53 cmd = "%s %s echo 2> /dev/null" % (conmux_attach, conmux_hostname)
jadmanski74394b62008-08-25 19:24:45 +000054 result = utils.run(cmd, ignore_status=True)
jadmanskia2db9412008-08-22 21:47:24 +000055 return result.exit_status == 0
jadmanski1c5e3a12008-08-15 23:08:20 +000056
57
jadmanskic533bd12008-09-03 20:48:51 +000058 def start_loggers(self):
59 super(SerialHost, self).start_loggers()
60
61 if self.__console_log == None:
jadmanski1c5e3a12008-08-15 23:08:20 +000062 return
jadmanskic533bd12008-09-03 20:48:51 +000063
jadmanski1c5e3a12008-08-15 23:08:20 +000064 if not self.conmux_attach or not os.path.exists(self.conmux_attach):
65 return
66
67 r, w = os.pipe()
68 script_path = os.path.join(self.serverdir,
69 'warning_monitor.py')
jadmanskia2db9412008-08-22 21:47:24 +000070 cmd = [self.conmux_attach, self.get_conmux_hostname(),
jadmanski1c5e3a12008-08-15 23:08:20 +000071 '%s %s %s %d' % (sys.executable, script_path,
jadmanskic533bd12008-09-03 20:48:51 +000072 self.__console_log, w)]
jadmanski1c5e3a12008-08-15 23:08:20 +000073
jadmanskic533bd12008-09-03 20:48:51 +000074 self.__warning_stream = os.fdopen(r, 'r', 0)
jadmanski1c5e3a12008-08-15 23:08:20 +000075 if self.job:
jadmanskic533bd12008-09-03 20:48:51 +000076 self.job.warning_loggers.add(self.__warning_stream)
77
78 stdout = stderr = open(os.devnull, 'w')
79 self.__logger = subprocess.Popen(cmd, stdout=stdout, stderr=stderr)
jadmanski1c5e3a12008-08-15 23:08:20 +000080 os.close(w)
81
82
jadmanskic533bd12008-09-03 20:48:51 +000083 def stop_loggers(self):
84 super(SerialHost, self).stop_loggers()
85
86 if self.__logger:
87 utils.nuke_subprocess(self.__logger)
88 self.__logger = None
jadmanski1c5e3a12008-08-15 23:08:20 +000089 if self.job:
jadmanskic533bd12008-09-03 20:48:51 +000090 self.job.warning_loggers.discard(self.__warning_stream)
91 self.__warning_stream.close()
jadmanski1c5e3a12008-08-15 23:08:20 +000092
93
94 def run_conmux(self, cmd):
95 """
96 Send a command to the conmux session
97 """
98 if not self.conmux_attach or not os.path.exists(self.conmux_attach):
99 return False
100 cmd = '%s %s echo %s 2> /dev/null' % (self.conmux_attach,
jadmanskia2db9412008-08-22 21:47:24 +0000101 self.get_conmux_hostname(),
jadmanski1c5e3a12008-08-15 23:08:20 +0000102 cmd)
103 result = utils.system(cmd, ignore_status=True)
104 return result == 0
jadmanskia2db9412008-08-22 21:47:24 +0000105
106
107 def hardreset(self, timeout=DEFAULT_REBOOT_TIMEOUT, wait=True,
108 conmux_command='hardreset'):
109 """
110 Reach out and slap the box in the power switch.
111 Args:
112 conmux_command: The command to run via the conmux interface
113 timeout: timelimit in seconds before the machine is
114 considered unreachable
115 wait: Whether or not to wait for the machine to reboot
116
117 """
118 conmux_command = "'~$%s'" % conmux_command
119 def reboot():
120 if not self.run_conmux(conmux_command):
121 self.record("ABORT", None, "reboot.start",
122 "hard reset unavailable")
123 raise error.AutoservUnsupportedError(
124 'Hard reset unavailable')
125 self.record("GOOD", None, "reboot.start", "hard reset")
126 if wait:
127 self.wait_for_restart(timeout)
128
129 if wait:
130 self.log_reboot(reboot)
131 else:
132 reboot()