blob: 3871ceccbf76436a32184c625c3af1e8b9ce8a70 [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
jadmanskif6562912008-10-21 17:59:01 +000011 def _initialize(self, conmux_server=None, conmux_attach=None,
12 console_log="console.log", *args, **dargs):
13 super(SerialHost, self)._initialize(*args, **dargs)
jadmanski1c5e3a12008-08-15 23:08:20 +000014
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
mblighd876f452008-12-03 15:09:17 +000061 if self.__console_log is 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()
jadmanski79777f62008-09-09 22:31:38 +000068 script_path = os.path.join(self.monitordir, 'console.py')
jadmanskia2db9412008-08-22 21:47:24 +000069 cmd = [self.conmux_attach, self.get_conmux_hostname(),
jadmanski1c5e3a12008-08-15 23:08:20 +000070 '%s %s %s %d' % (sys.executable, script_path,
jadmanskic533bd12008-09-03 20:48:51 +000071 self.__console_log, w)]
jadmanski1c5e3a12008-08-15 23:08:20 +000072
jadmanskic533bd12008-09-03 20:48:51 +000073 self.__warning_stream = os.fdopen(r, 'r', 0)
jadmanski1c5e3a12008-08-15 23:08:20 +000074 if self.job:
jadmanskic533bd12008-09-03 20:48:51 +000075 self.job.warning_loggers.add(self.__warning_stream)
76
77 stdout = stderr = open(os.devnull, 'w')
78 self.__logger = subprocess.Popen(cmd, stdout=stdout, stderr=stderr)
jadmanski1c5e3a12008-08-15 23:08:20 +000079 os.close(w)
80
81
jadmanskic533bd12008-09-03 20:48:51 +000082 def stop_loggers(self):
83 super(SerialHost, self).stop_loggers()
84
85 if self.__logger:
86 utils.nuke_subprocess(self.__logger)
87 self.__logger = None
jadmanski1c5e3a12008-08-15 23:08:20 +000088 if self.job:
jadmanskic533bd12008-09-03 20:48:51 +000089 self.job.warning_loggers.discard(self.__warning_stream)
90 self.__warning_stream.close()
jadmanski1c5e3a12008-08-15 23:08:20 +000091
92
93 def run_conmux(self, cmd):
94 """
95 Send a command to the conmux session
96 """
97 if not self.conmux_attach or not os.path.exists(self.conmux_attach):
98 return False
99 cmd = '%s %s echo %s 2> /dev/null' % (self.conmux_attach,
jadmanskia2db9412008-08-22 21:47:24 +0000100 self.get_conmux_hostname(),
jadmanski1c5e3a12008-08-15 23:08:20 +0000101 cmd)
102 result = utils.system(cmd, ignore_status=True)
103 return result == 0
jadmanskia2db9412008-08-22 21:47:24 +0000104
105
106 def hardreset(self, timeout=DEFAULT_REBOOT_TIMEOUT, wait=True,
107 conmux_command='hardreset'):
108 """
109 Reach out and slap the box in the power switch.
110 Args:
111 conmux_command: The command to run via the conmux interface
112 timeout: timelimit in seconds before the machine is
113 considered unreachable
114 wait: Whether or not to wait for the machine to reboot
115
116 """
117 conmux_command = "'~$%s'" % conmux_command
118 def reboot():
119 if not self.run_conmux(conmux_command):
120 self.record("ABORT", None, "reboot.start",
121 "hard reset unavailable")
122 raise error.AutoservUnsupportedError(
123 'Hard reset unavailable')
124 self.record("GOOD", None, "reboot.start", "hard reset")
125 if wait:
126 self.wait_for_restart(timeout)
127
128 if wait:
129 self.log_reboot(reboot)
130 else:
131 reboot()