blob: e56cc16ab6a3a5becfd8338b6a987f6f9b82ddcb [file] [log] [blame]
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -07001# Copyright (c) 2011 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
5"""Exposes the FAFTClient interface over XMLRPC.
6
7It launches a XMLRPC server and exposes the interface of FAFTClient object.
8The FAFTClient object aggreates some useful functions of exisintg SAFT
9libraries.
10"""
11
Tom Wai-Hong Tam0e680af2011-10-26 14:32:55 +080012import functools
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070013import sys
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070014from optparse import OptionParser
15from SimpleXMLRPCServer import SimpleXMLRPCServer
16
17# Import libraries from SAFT.
Tom Wai-Hong Tamc1576b72011-11-08 11:36:16 +080018sys.path.append('/usr/local/sbin/firmware/saft')
Tom Wai-Hong Tam48958832011-12-30 10:16:57 +080019import cgpt_state
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070020import chromeos_interface
21import flashrom_handler
22import kernel_handler
23import saft_flashrom_util
24import tpm_handler
25
26
Tom Wai-Hong Tam0e680af2011-10-26 14:32:55 +080027def allow_multiple_section_input(image_operator):
28 @functools.wraps(image_operator)
29 def wrapper(self, section):
30 if type(section) in (tuple, list):
31 for sec in section:
32 image_operator(self, sec)
33 else:
34 image_operator(self, section)
35 return wrapper
36
37
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070038class FAFTClient(object):
39 """A class of FAFT client which aggregates some useful functions of SAFT.
40
41 This class can be exposed via a XMLRPC server such that its functions can
42 be accessed remotely.
43
44 Attributes:
45 _chromeos_interface: An object to encapsulate OS services functions.
46 _flashrom_handler: An object to automate flashrom testing.
47 _kernel_handler: An object to provide kernel related actions.
48 _tpm_handler: An object to control TPM device.
49 """
50
51 def __init__(self):
52 """Initialize the data attributes of this class."""
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070053 # TODO(waihong): Move the explicit object.init() methods to the
54 # objects' constructors (ChromeOSInterface, FlashromHandler,
55 # KernelHandler, and TpmHandler).
56 self._chromeos_interface = chromeos_interface.ChromeOSInterface(False)
Tom Wai-Hong Tam48958832011-12-30 10:16:57 +080057 # We keep the state of FAFT test in a permanent directory over reboots.
58 self._chromeos_interface.init(state_dir='/var/tmp/faft',
59 log_file='/tmp/faft_log.txt')
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070060
61 self._flashrom_handler = flashrom_handler.FlashromHandler()
62 self._flashrom_handler.init(saft_flashrom_util,
63 self._chromeos_interface)
64 self._flashrom_handler.new_image()
65
66 self._kernel_handler = kernel_handler.KernelHandler()
67 self._kernel_handler.init(self._chromeos_interface)
68
69 self._tpm_handler = tpm_handler.TpmHandler()
70 self._tpm_handler.init(self._chromeos_interface)
71
Tom Wai-Hong Tam48958832011-12-30 10:16:57 +080072 self._cgpt_state = cgpt_state.CgptState(
73 'AUTO', self._chromeos_interface, self.get_root_dev())
74
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070075
Tom Wai-Hong Tame8f291a2011-12-08 22:03:53 +080076 def _dispatch(self, method, params):
77 """This _dispatch method handles string conversion especially.
78
79 Since we turn off allow_dotted_names option. So any string conversion,
80 like str(FAFTClient.method), i.e. FAFTClient.method.__str__, failed
81 via XML RPC call.
82 """
83 is_str = method.endswith('.__str__')
84 if is_str:
85 method = method.rsplit('.', 1)[0]
86 try:
87 func = getattr(self, method)
88 except AttributeError:
89 raise Exception('method "%s" is not supported' % method)
90 else:
91 if is_str:
92 return str(func)
93 else:
94 return func(*params)
95
96
Tom Wai-Hong Tambea57b32011-09-02 18:27:47 +080097 def is_available(self):
98 """Function for polling the RPC server availability.
99
100 Returns:
101 Always True.
102 """
103 return True
104
105
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700106 def run_shell_command(self, command):
107 """Run shell command.
108
109 Args:
110 command: A shell command to be run.
111 """
112 self._chromeos_interface.log('Requesting run shell command')
113 self._chromeos_interface.run_shell_command(command)
114
115
116 def run_shell_command_get_output(self, command):
117 """Run shell command and get its console output.
118
119 Args:
120 command: A shell command to be run.
121
122 Returns:
123 A list of strings stripped of the newline characters.
124 """
125 self._chromeos_interface.log(
126 'Requesting run shell command and get its console output')
127 return self._chromeos_interface.run_shell_command_get_output(command)
128
129
130 def software_reboot(self):
131 """Request software reboot."""
132 self._chromeos_interface.log('Requesting software reboot')
133 self._chromeos_interface.run_shell_command('reboot')
134
135
Tom Wai-Hong Tam678ab152011-12-14 15:27:24 +0800136 def get_platform_name(self):
137 """Get the platform name of the current system.
138
139 Returns:
140 A string of the platform name.
141 """
142 self._chromeos_interface.log('Requesting get platform name')
143 return self._chromeos_interface.run_shell_command_get_output(
144 'mosys platform name')[0]
145
146
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700147 def get_crossystem_value(self, key):
148 """Get crossystem value of the requested key.
149
150 Args:
151 key: A crossystem key.
152
153 Returns:
154 A string of the requested crossystem value.
155 """
156 self._chromeos_interface.log('Requesting get crossystem value')
157 return self._chromeos_interface.run_shell_command_get_output(
158 'crossystem %s' % key)[0]
159
160
Tom Wai-Hong Tamcfda61f2011-11-02 17:41:01 +0800161 def get_root_dev(self):
162 """Get the name of root device without partition number.
163
164 Returns:
165 A string of the root device without partition number.
166 """
167 self._chromeos_interface.log('Requesting get root device')
168 return self._chromeos_interface.get_root_dev()
169
170
171 def get_root_part(self):
172 """Get the name of root device with partition number.
173
174 Returns:
175 A string of the root device with partition number.
176 """
177 self._chromeos_interface.log('Requesting get root part')
178 return self._chromeos_interface.get_root_part()
179
180
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700181 def set_try_fw_b(self):
182 """Set 'Try Frimware B' flag in crossystem."""
183 self._chromeos_interface.log('Requesting restart with firmware B')
184 self._chromeos_interface.cs.fwb_tries = 1
185
186
Tom Wai-Hong Tam76c75072011-10-25 18:00:12 +0800187 def request_recovery_boot(self):
188 """Request running in recovery mode on the restart."""
189 self._chromeos_interface.log('Requesting restart in recovery mode')
190 self._chromeos_interface.cs.request_recovery()
191
192
Tom Wai-Hong Tam8c9eed62011-12-28 15:05:05 +0800193 def get_gbb_flags(self):
194 """Get the GBB flags.
195
196 Returns:
197 An integer of the GBB flags.
198 """
199 self._chromeos_interface.log('Getting GBB flags')
200 return self._flashrom_handler.get_gbb_flags()
201
202
Tom Wai-Hong Tam81f70002011-12-13 12:29:46 +0800203 def get_firmware_flags(self, section):
204 """Get the preamble flags of a firmware section.
205
206 Args:
207 section: A firmware section, either 'a' or 'b'.
208
209 Returns:
210 An integer of the preamble flags.
211 """
212 self._chromeos_interface.log('Getting preamble flags of firmware %s' %
213 section)
214 return self._flashrom_handler.get_section_flags(section)
215
216
Tom Wai-Hong Tam0e680af2011-10-26 14:32:55 +0800217 @allow_multiple_section_input
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700218 def corrupt_firmware(self, section):
Tom Wai-Hong Tam9aea8212011-12-12 15:08:45 +0800219 """Corrupt the requested firmware section signature.
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700220
221 Args:
222 section: A firmware section, either 'a' or 'b'.
223 """
Tom Wai-Hong Tam9aea8212011-12-12 15:08:45 +0800224 self._chromeos_interface.log('Corrupting firmware signature %s' %
225 section)
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700226 self._flashrom_handler.corrupt_firmware(section)
227
228
Tom Wai-Hong Tam0e680af2011-10-26 14:32:55 +0800229 @allow_multiple_section_input
Tom Wai-Hong Tam81f70002011-12-13 12:29:46 +0800230 def corrupt_firmware_body(self, section):
231 """Corrupt the requested firmware section body.
232
233 Args:
234 section: A firmware section, either 'a' or 'b'.
235 """
236 self._chromeos_interface.log('Corrupting firmware body %s' %
237 section)
238 self._flashrom_handler.corrupt_firmware_body(section)
239
240
241 @allow_multiple_section_input
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700242 def restore_firmware(self, section):
Tom Wai-Hong Tam9aea8212011-12-12 15:08:45 +0800243 """Restore the previously corrupted firmware section signature.
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700244
245 Args:
246 section: A firmware section, either 'a' or 'b'.
247 """
Tom Wai-Hong Tam9aea8212011-12-12 15:08:45 +0800248 self._chromeos_interface.log('Restoring firmware signature %s' %
249 section)
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700250 self._flashrom_handler.restore_firmware(section)
251
252
Tom Wai-Hong Tamcfda61f2011-11-02 17:41:01 +0800253 @allow_multiple_section_input
Tom Wai-Hong Tam81f70002011-12-13 12:29:46 +0800254 def restore_firmware_body(self, section):
255 """Restore the previously corrupted firmware section body.
256
257 Args:
258 section: A firmware section, either 'a' or 'b'.
259 """
260 self._chromeos_interface.log('Restoring firmware body %s' %
261 section)
262 self._flashrom_handler.restore_firmware_body(section)
263
264
265 @allow_multiple_section_input
Tom Wai-Hong Tamcfda61f2011-11-02 17:41:01 +0800266 def corrupt_kernel(self, section):
267 """Corrupt the requested kernel section.
268
269 Args:
270 section: A kernel section, either 'a' or 'b'.
271 """
272 self._chromeos_interface.log('Corrupting kernel %s' % section)
273 self._kernel_handler.corrupt_kernel(section)
274
275
276 @allow_multiple_section_input
277 def restore_kernel(self, section):
278 """Restore the requested kernel section (previously corrupted).
279
280 Args:
281 section: A kernel section, either 'a' or 'b'.
282 """
283 self._chromeos_interface.log('restoring kernel %s' % section)
284 self._kernel_handler.restore_kernel(section)
285
286
Tom Wai-Hong Tam48958832011-12-30 10:16:57 +0800287 def run_cgpt_test_loop(self):
288 """Run the CgptState test loop. The tst logic is handled in the client.
289
290 Returns:
291 0: there are more cgpt tests to execute.
292 1: no more CgptState test, finished.
293 """
294 return self._cgpt_state.test_loop()
295
296
297 def set_cgpt_test_step(self, step):
298 """Set the CgptState test step.
299
300 Args:
301 step: A test step number.
302 """
303 self._cgpt_state.set_step(step)
304
305
306 def get_cgpt_test_step(self):
307 """Get the CgptState test step.
308
309 Returns:
310 A test step number.
311 """
312 return self._cgpt_state.get_step()
313
314
Tom Wai-Hong Tambea57b32011-09-02 18:27:47 +0800315 def cleanup(self):
316 """Cleanup for the RPC server. Currently nothing."""
317 pass
318
319
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700320def main():
321 parser = OptionParser(usage='Usage: %prog [options]')
322 parser.add_option('--port', type='int', dest='port', default=9990,
323 help='port number of XMLRPC server')
324 (options, args) = parser.parse_args()
325
326 faft_client = FAFTClient()
327
328 # Launch the XMLRPC server to provide FAFTClient commands.
Tom Wai-Hong Tam4a257e52011-11-12 08:36:22 +0800329 server = SimpleXMLRPCServer(('localhost', options.port), allow_none=True,
330 logRequests=False)
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700331 server.register_introspection_functions()
332 server.register_instance(faft_client)
333 print 'XMLRPC Server: Serving FAFTClient on port %s' % options.port
334 server.serve_forever()
335
336
337if __name__ == '__main__':
338 main()