blob: 8cad7f7bc816d2a54808e34f91e600abc4a36117 [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 os
14import sys
15import tempfile
16from optparse import OptionParser
17from SimpleXMLRPCServer import SimpleXMLRPCServer
18
19# Import libraries from SAFT.
Tom Wai-Hong Tamc1576b72011-11-08 11:36:16 +080020sys.path.append('/usr/local/sbin/firmware/saft')
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070021import chromeos_interface
22import flashrom_handler
23import kernel_handler
24import saft_flashrom_util
25import tpm_handler
26
27
Tom Wai-Hong Tam0e680af2011-10-26 14:32:55 +080028def allow_multiple_section_input(image_operator):
29 @functools.wraps(image_operator)
30 def wrapper(self, section):
31 if type(section) in (tuple, list):
32 for sec in section:
33 image_operator(self, sec)
34 else:
35 image_operator(self, section)
36 return wrapper
37
38
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -070039class FAFTClient(object):
40 """A class of FAFT client which aggregates some useful functions of SAFT.
41
42 This class can be exposed via a XMLRPC server such that its functions can
43 be accessed remotely.
44
45 Attributes:
46 _chromeos_interface: An object to encapsulate OS services functions.
47 _flashrom_handler: An object to automate flashrom testing.
48 _kernel_handler: An object to provide kernel related actions.
49 _tpm_handler: An object to control TPM device.
50 """
51
52 def __init__(self):
53 """Initialize the data attributes of this class."""
54 tmp_dir = tempfile.mkdtemp()
55
56 # TODO(waihong): Move the explicit object.init() methods to the
57 # objects' constructors (ChromeOSInterface, FlashromHandler,
58 # KernelHandler, and TpmHandler).
59 self._chromeos_interface = chromeos_interface.ChromeOSInterface(False)
60 self._chromeos_interface.init(tmp_dir)
61
62 self._flashrom_handler = flashrom_handler.FlashromHandler()
63 self._flashrom_handler.init(saft_flashrom_util,
64 self._chromeos_interface)
65 self._flashrom_handler.new_image()
66
67 self._kernel_handler = kernel_handler.KernelHandler()
68 self._kernel_handler.init(self._chromeos_interface)
69
70 self._tpm_handler = tpm_handler.TpmHandler()
71 self._tpm_handler.init(self._chromeos_interface)
72
73
Tom Wai-Hong Tame8f291a2011-12-08 22:03:53 +080074 def _dispatch(self, method, params):
75 """This _dispatch method handles string conversion especially.
76
77 Since we turn off allow_dotted_names option. So any string conversion,
78 like str(FAFTClient.method), i.e. FAFTClient.method.__str__, failed
79 via XML RPC call.
80 """
81 is_str = method.endswith('.__str__')
82 if is_str:
83 method = method.rsplit('.', 1)[0]
84 try:
85 func = getattr(self, method)
86 except AttributeError:
87 raise Exception('method "%s" is not supported' % method)
88 else:
89 if is_str:
90 return str(func)
91 else:
92 return func(*params)
93
94
Tom Wai-Hong Tambea57b32011-09-02 18:27:47 +080095 def is_available(self):
96 """Function for polling the RPC server availability.
97
98 Returns:
99 Always True.
100 """
101 return True
102
103
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700104 def run_shell_command(self, command):
105 """Run shell command.
106
107 Args:
108 command: A shell command to be run.
109 """
110 self._chromeos_interface.log('Requesting run shell command')
111 self._chromeos_interface.run_shell_command(command)
112
113
114 def run_shell_command_get_output(self, command):
115 """Run shell command and get its console output.
116
117 Args:
118 command: A shell command to be run.
119
120 Returns:
121 A list of strings stripped of the newline characters.
122 """
123 self._chromeos_interface.log(
124 'Requesting run shell command and get its console output')
125 return self._chromeos_interface.run_shell_command_get_output(command)
126
127
128 def software_reboot(self):
129 """Request software reboot."""
130 self._chromeos_interface.log('Requesting software reboot')
131 self._chromeos_interface.run_shell_command('reboot')
132
133
Tom Wai-Hong Tam678ab152011-12-14 15:27:24 +0800134 def get_platform_name(self):
135 """Get the platform name of the current system.
136
137 Returns:
138 A string of the platform name.
139 """
140 self._chromeos_interface.log('Requesting get platform name')
141 return self._chromeos_interface.run_shell_command_get_output(
142 'mosys platform name')[0]
143
144
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700145 def get_crossystem_value(self, key):
146 """Get crossystem value of the requested key.
147
148 Args:
149 key: A crossystem key.
150
151 Returns:
152 A string of the requested crossystem value.
153 """
154 self._chromeos_interface.log('Requesting get crossystem value')
155 return self._chromeos_interface.run_shell_command_get_output(
156 'crossystem %s' % key)[0]
157
158
Tom Wai-Hong Tamcfda61f2011-11-02 17:41:01 +0800159 def get_root_dev(self):
160 """Get the name of root device without partition number.
161
162 Returns:
163 A string of the root device without partition number.
164 """
165 self._chromeos_interface.log('Requesting get root device')
166 return self._chromeos_interface.get_root_dev()
167
168
169 def get_root_part(self):
170 """Get the name of root device with partition number.
171
172 Returns:
173 A string of the root device with partition number.
174 """
175 self._chromeos_interface.log('Requesting get root part')
176 return self._chromeos_interface.get_root_part()
177
178
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700179 def set_try_fw_b(self):
180 """Set 'Try Frimware B' flag in crossystem."""
181 self._chromeos_interface.log('Requesting restart with firmware B')
182 self._chromeos_interface.cs.fwb_tries = 1
183
184
Tom Wai-Hong Tam76c75072011-10-25 18:00:12 +0800185 def request_recovery_boot(self):
186 """Request running in recovery mode on the restart."""
187 self._chromeos_interface.log('Requesting restart in recovery mode')
188 self._chromeos_interface.cs.request_recovery()
189
190
Tom Wai-Hong Tam8c9eed62011-12-28 15:05:05 +0800191 def get_gbb_flags(self):
192 """Get the GBB flags.
193
194 Returns:
195 An integer of the GBB flags.
196 """
197 self._chromeos_interface.log('Getting GBB flags')
198 return self._flashrom_handler.get_gbb_flags()
199
200
Tom Wai-Hong Tam81f70002011-12-13 12:29:46 +0800201 def get_firmware_flags(self, section):
202 """Get the preamble flags of a firmware section.
203
204 Args:
205 section: A firmware section, either 'a' or 'b'.
206
207 Returns:
208 An integer of the preamble flags.
209 """
210 self._chromeos_interface.log('Getting preamble flags of firmware %s' %
211 section)
212 return self._flashrom_handler.get_section_flags(section)
213
214
Tom Wai-Hong Tam0e680af2011-10-26 14:32:55 +0800215 @allow_multiple_section_input
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700216 def corrupt_firmware(self, section):
Tom Wai-Hong Tam9aea8212011-12-12 15:08:45 +0800217 """Corrupt the requested firmware section signature.
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700218
219 Args:
220 section: A firmware section, either 'a' or 'b'.
221 """
Tom Wai-Hong Tam9aea8212011-12-12 15:08:45 +0800222 self._chromeos_interface.log('Corrupting firmware signature %s' %
223 section)
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700224 self._flashrom_handler.corrupt_firmware(section)
225
226
Tom Wai-Hong Tam0e680af2011-10-26 14:32:55 +0800227 @allow_multiple_section_input
Tom Wai-Hong Tam81f70002011-12-13 12:29:46 +0800228 def corrupt_firmware_body(self, section):
229 """Corrupt the requested firmware section body.
230
231 Args:
232 section: A firmware section, either 'a' or 'b'.
233 """
234 self._chromeos_interface.log('Corrupting firmware body %s' %
235 section)
236 self._flashrom_handler.corrupt_firmware_body(section)
237
238
239 @allow_multiple_section_input
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700240 def restore_firmware(self, section):
Tom Wai-Hong Tam9aea8212011-12-12 15:08:45 +0800241 """Restore the previously corrupted firmware section signature.
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700242
243 Args:
244 section: A firmware section, either 'a' or 'b'.
245 """
Tom Wai-Hong Tam9aea8212011-12-12 15:08:45 +0800246 self._chromeos_interface.log('Restoring firmware signature %s' %
247 section)
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700248 self._flashrom_handler.restore_firmware(section)
249
250
Tom Wai-Hong Tamcfda61f2011-11-02 17:41:01 +0800251 @allow_multiple_section_input
Tom Wai-Hong Tam81f70002011-12-13 12:29:46 +0800252 def restore_firmware_body(self, section):
253 """Restore the previously corrupted firmware section body.
254
255 Args:
256 section: A firmware section, either 'a' or 'b'.
257 """
258 self._chromeos_interface.log('Restoring firmware body %s' %
259 section)
260 self._flashrom_handler.restore_firmware_body(section)
261
262
263 @allow_multiple_section_input
Tom Wai-Hong Tamcfda61f2011-11-02 17:41:01 +0800264 def corrupt_kernel(self, section):
265 """Corrupt the requested kernel section.
266
267 Args:
268 section: A kernel section, either 'a' or 'b'.
269 """
270 self._chromeos_interface.log('Corrupting kernel %s' % section)
271 self._kernel_handler.corrupt_kernel(section)
272
273
274 @allow_multiple_section_input
275 def restore_kernel(self, section):
276 """Restore the requested kernel section (previously corrupted).
277
278 Args:
279 section: A kernel section, either 'a' or 'b'.
280 """
281 self._chromeos_interface.log('restoring kernel %s' % section)
282 self._kernel_handler.restore_kernel(section)
283
284
Tom Wai-Hong Tambea57b32011-09-02 18:27:47 +0800285 def cleanup(self):
286 """Cleanup for the RPC server. Currently nothing."""
287 pass
288
289
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700290def main():
291 parser = OptionParser(usage='Usage: %prog [options]')
292 parser.add_option('--port', type='int', dest='port', default=9990,
293 help='port number of XMLRPC server')
294 (options, args) = parser.parse_args()
295
296 faft_client = FAFTClient()
297
298 # Launch the XMLRPC server to provide FAFTClient commands.
Tom Wai-Hong Tam4a257e52011-11-12 08:36:22 +0800299 server = SimpleXMLRPCServer(('localhost', options.port), allow_none=True,
300 logRequests=False)
Tom Wai-Hong Tamb8a58ef2011-10-11 23:53:10 -0700301 server.register_introspection_functions()
302 server.register_instance(faft_client)
303 print 'XMLRPC Server: Serving FAFTClient on port %s' % options.port
304 server.serve_forever()
305
306
307if __name__ == '__main__':
308 main()