blob: 339eaa039de4cf046361056435fe7df119a18bef [file] [log] [blame]
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08001#!/usr/bin/python
Jon Salze60307f2014-08-05 16:20:00 +08002# -*- coding: utf-8 -*-
3# Copyright 2014 The Chromium OS Authors. All rights reserved.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08004# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
Jon Salze60307f2014-08-05 16:20:00 +08007# pylint: disable=E1101
8
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08009"""Google Factory Tool.
10
11This tool is indended to be used on factory assembly lines. It
12provides all of the Google required test functionality and must be run
13on each device as part of the assembly process.
14"""
15
Ricky Liang5b4568d2013-04-23 17:15:23 +080016import collections
Tammo Spalink9a96b8a2012-04-03 11:10:41 +080017import logging
18import os
Jon Salz65266432012-07-30 19:02:49 +080019import pipes
Tammo Spalink9a96b8a2012-04-03 11:10:41 +080020import re
21import sys
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080022import threading
Hung-Te Lin6bd16472012-06-20 16:26:47 +080023import time
Jon Salza88b83b2013-05-27 20:00:35 +080024import xmlrpclib
Ricky Liang7905f272013-03-16 01:57:10 +080025import yaml
Tammo Spalink9a96b8a2012-04-03 11:10:41 +080026
Andy Cheng2582d292012-12-04 17:38:28 +080027from tempfile import gettempdir
Tammo Spalink86a61c62012-05-25 15:10:35 +080028
Tammo Spalinka40293e2012-07-04 14:58:56 +080029import factory_common # pylint: disable=W0611
Tammo Spalink9a96b8a2012-04-03 11:10:41 +080030
Ricky Liang53390232013-03-08 15:37:57 +080031from cros.factory.gooftool import crosfw
Tammo Spalink01e11722012-07-24 10:17:54 -070032from cros.factory.gooftool import report_upload
Hung-Te Lin84c77fa2016-03-02 17:43:30 +080033from cros.factory.gooftool.core import Gooftool
Hung-Te Lin0e0f9362015-11-18 18:18:05 +080034from cros.factory.gooftool.common import Shell
Andy Cheng8ece7382012-08-22 16:25:42 +080035from cros.factory.gooftool.probe import Probe, PROBEABLE_COMPONENT_CLASSES
Jon Salz0f8a6842012-09-25 11:28:22 +080036from cros.factory.gooftool.probe import ReadRoVpd, ReadRwVpd
henryhsu44d793a2013-07-20 00:07:38 +080037from cros.factory.gooftool.probe import CalculateFirmwareHashes
Jon Salz193d7c62013-03-07 13:40:19 +080038from cros.factory.gooftool.vpd_data import KNOWN_VPD_FIELD_DATA
Tammo Spalinka40293e2012-07-04 14:58:56 +080039from cros.factory.hacked_argparse import CmdArg, Command, ParseCmdline
40from cros.factory.hacked_argparse import verbosity_cmd_arg
Hung-Te Lin604e0c22015-11-24 15:17:07 +080041from cros.factory.hwid.v2 import hwid_tool
42from cros.factory.hwid.v2.yaml_datastore import YamlWrite
43from cros.factory.hwid.v3 import common
44from cros.factory.hwid.v3 import hwid_utils
Hung-Te Lin91492a12014-11-25 18:56:30 +080045from cros.factory.test import event_log
Wei-Han Chen2ebb92d2016-01-12 14:51:41 +080046from cros.factory.test.env import paths
Wei-Han Chenaff56232016-04-16 09:17:59 +080047from cros.factory.test.rules import phase
Hung-Te Lin3f096842016-01-13 17:37:06 +080048from cros.factory.test.rules.privacy import FilterDict
Jon Salz40b9f822014-07-25 16:39:55 +080049from cros.factory.utils import file_utils
Hung-Te Lin0e0f9362015-11-18 18:18:05 +080050from cros.factory.utils.debug_utils import SetupLogging
Jon Salzff88c022012-11-03 12:19:58 +080051from cros.factory.utils.process_utils import Spawn
Joel Kitchingd3bc2662014-12-16 16:03:32 -080052from cros.factory.utils.type_utils import Error
Tammo Spalink86a61c62012-05-25 15:10:35 +080053
Tammo Spalink5c699832012-07-03 17:50:39 +080054
Tammo Spalink5c699832012-07-03 17:50:39 +080055# TODO(tammo): Replace calls to sys.exit with raise Exit, and maybe
56# treat that specially (as a smoot exit, as opposed to the more
57# verbose output for generic Error).
58
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080059_global_gooftool = None
60_gooftool_lock = threading.Lock()
Tammo Spalink5c699832012-07-03 17:50:39 +080061
Hung-Te Lin56b18402015-01-16 14:52:30 +080062
Ricky Lianga70a1202013-03-15 15:03:17 +080063def GetGooftool(options):
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080064 global _global_gooftool # pylint: disable=W0603
Ricky Lianga70a1202013-03-15 15:03:17 +080065
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080066 if _global_gooftool is None:
67 with _gooftool_lock:
Ricky Liang43b879b2014-02-24 11:36:55 +080068 hwid_version = getattr(options, 'hwid_version', 3)
69 if hwid_version == 2:
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080070 hwdb_path = getattr(options, 'hwdb_path', None)
71 component_db = (
72 hwid_tool.HardwareDb(options.hwdb_path).comp_db if hwdb_path
73 else None)
74 _global_gooftool = Gooftool(hwid_version=2, component_db=component_db)
Ricky Liang43b879b2014-02-24 11:36:55 +080075 elif hwid_version == 3:
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080076 board = getattr(options, 'board', None)
77 hwdb_path = getattr(options, 'hwdb_path', None)
78 _global_gooftool = Gooftool(hwid_version=3, board=board,
79 hwdb_path=hwdb_path)
80 else:
81 raise Error, 'Invalid HWID version: %r' % options.hwid_version
82
83 return _global_gooftool
Ricky Lianga70a1202013-03-15 15:03:17 +080084
Hung-Te Lin56b18402015-01-16 14:52:30 +080085
Tammo Spalink9a96b8a2012-04-03 11:10:41 +080086@Command('write_hwid',
87 CmdArg('hwid', metavar='HWID', help='HWID string'))
Andy Chengc92e6f92012-11-20 16:55:53 +080088def WriteHWID(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +080089 """Write specified HWID value into the system BB."""
Andy Cheng7a76cb82012-11-19 18:08:19 +080090
Tammo Spalink95c43732012-07-25 15:57:14 -070091 logging.info('writing hwid string %r', options.hwid)
Ricky Lianga70a1202013-03-15 15:03:17 +080092 GetGooftool(options).WriteHWID(options.hwid)
Andy Cheng0465d132013-03-20 12:12:06 +080093 event_log.Log('write_hwid', hwid=options.hwid)
Tammo Spalink95c43732012-07-25 15:57:14 -070094 print 'Wrote HWID: %r' % options.hwid
Tammo Spalink9a96b8a2012-04-03 11:10:41 +080095
96
Ricky Liang53390232013-03-08 15:37:57 +080097_board_cmd_arg = CmdArg(
98 '--board', metavar='BOARD',
99 default=None, help='Board name to test.')
100
Tammo Spalink8fab5312012-05-28 18:33:30 +0800101_hwdb_path_cmd_arg = CmdArg(
102 '--hwdb_path', metavar='PATH',
Ricky Liangeede7922013-06-19 10:18:41 +0800103 default=common.DEFAULT_HWID_DATA_PATH,
Tammo Spalink8fab5312012-05-28 18:33:30 +0800104 help='Path to the HWID database.')
105
Tammo Spalink95c43732012-07-25 15:57:14 -0700106_hwid_status_list_cmd_arg = CmdArg(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800107 '--status', nargs='*', default=['supported'],
108 help='allow only HWIDs with these status values')
Tammo Spalink95c43732012-07-25 15:57:14 -0700109
Jon Salzce124fb2012-10-02 17:42:03 +0800110_probe_results_cmd_arg = CmdArg(
111 '--probe_results', metavar='RESULTS.yaml',
Ricky Liangc662be32013-12-24 11:50:23 +0800112 help=('Output from "gooftool probe --include_vpd" (used instead of '
Jon Salzce124fb2012-10-02 17:42:03 +0800113 'probing this system).'))
114
Ricky Liang53390232013-03-08 15:37:57 +0800115_device_info_cmd_arg = CmdArg(
Ricky Liangf89f73a2013-03-19 05:00:24 +0800116 '--device_info', metavar='DEVICE_INFO.yaml', default=None,
Ricky Liang53390232013-03-08 15:37:57 +0800117 help='A dict of device info to use instead of fetching from shopfllor '
118 'server.')
119
Jon Salzce124fb2012-10-02 17:42:03 +0800120_hwid_cmd_arg = CmdArg(
121 '--hwid', metavar='HWID',
Ricky Lianga70a1202013-03-15 15:03:17 +0800122 help='HWID to verify (instead of the currently set HWID of this system).')
Jon Salzce124fb2012-10-02 17:42:03 +0800123
Bernie Thompson3c11c872013-07-22 18:22:45 -0700124_rma_mode_cmd_arg = CmdArg(
125 '--rma_mode', action='store_true',
126 help='Enable RMA mode, do not check for deprecated components.')
Tammo Spalink95c43732012-07-25 15:57:14 -0700127
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800128_cros_core_cmd_arg = CmdArg(
129 '--cros_core', action='store_true',
130 help='Finalize for ChromeOS Core devices (may add or remove few test '
131 'items. For example, branding verification or firmware bitmap '
132 'locale settings).')
133
Ricky Liang43b879b2014-02-24 11:36:55 +0800134_hwid_version_cmd_arg = CmdArg(
135 '-i', '--hwid-version', default=3, choices=(2, 3), type=int,
136 help='Version of HWID to operate on. (default: %(default)s)')
137
bowgotsai13820f42015-09-10 23:18:04 +0800138_enforced_release_channels_cmd_arg = CmdArg(
139 '--enforced_release_channels', nargs='*', default=None,
140 help='Enforced release image channels.')
141
Hung-Te Lincdb96522016-04-15 16:51:10 +0800142_release_rootfs_cmd_arg = CmdArg(
143 '--release_rootfs', help='Location of release image rootfs partition.')
144
145_firmware_path_cmd_arg = CmdArg(
146 '--firmware_path', help='Location of firmware image partition.')
Ricky Liang43b879b2014-02-24 11:36:55 +0800147
Tammo Spalink95c43732012-07-25 15:57:14 -0700148@Command('best_match_hwids',
Tammo Spalink8fab5312012-05-28 18:33:30 +0800149 _hwdb_path_cmd_arg,
150 CmdArg('-b', '--board', metavar='BOARD',
Tammo Spalink95c43732012-07-25 15:57:14 -0700151 help='optional BOARD name, needed only if data is present '
152 'for more than one'),
Tammo Spalink8fab5312012-05-28 18:33:30 +0800153 CmdArg('--bom', metavar='BOM', help='BOM name'),
154 CmdArg('--variant', metavar='VARIANT', help='VARIANT code'),
Tammo Spalink5c699832012-07-03 17:50:39 +0800155 CmdArg('--optimistic', action='store_true',
156 help='do not probe; assume singletons match'),
Tammo Spalink95c43732012-07-25 15:57:14 -0700157 CmdArg('--comps', nargs='*', default=[],
158 help='list of canonical component names'),
159 CmdArg('--missing', nargs='*', default=[],
160 help='list component classes to be assumed missing'),
Tammo Spalink5c699832012-07-03 17:50:39 +0800161 CmdArg('--status', nargs='*', default=['supported'],
Tammo Spalink95c43732012-07-25 15:57:14 -0700162 help='consider only HWIDs within this list of status values'))
163def BestMatchHwids(options):
Ricky Liangc662be32013-12-24 11:50:23 +0800164 """Determine a list of possible HWIDs using provided args and probing.
Tammo Spalink8fab5312012-05-28 18:33:30 +0800165
166 VOLATILE can always be determined by probing. To get a unique
167 result, VARIANT must be specified for all cases where the matching
168 BOM has more than one associated variant code, otherwise all HWID
169 variants will be returned. Both VARIANT and BOM information can
Tammo Spalink95c43732012-07-25 15:57:14 -0700170 alternatively be specified using the --stdin_comps argument, which
171 allows specifying a list of canonical names (one per line) on stdin,
172 one per line. Based on what is known from BOM and stdin_comps,
173 determine a list of components to probe for, and use those probe
174 results to resolve a list of matching HWIDs. If no boms,
175 components, or variant codes are specified, then a list of all HWIDs
Andy Cheng8ece7382012-08-22 16:25:42 +0800176 that match probeable components will be returned.
Tammo Spalink8fab5312012-05-28 18:33:30 +0800177
178 Returns (on stdout): A list of HWIDs that match the available probe
179 results and argument contraints, one per line.
Tammo Spalink70b48a52012-08-08 16:54:51 -0700180
181 Example:
182
183 // Three ways to specify a keyboard (assuming it is a variant component)
184 gooftool best_match_hwids --missing keyboard
185 gooftool best_match_hwids --variant A or
186 gooftool best_match_hwids --comps us_kbd
Tammo Spalink8fab5312012-05-28 18:33:30 +0800187 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800188
Tammo Spalink5c699832012-07-03 17:50:39 +0800189 map(hwid_tool.Validate.Status, options.status)
Tammo Spalink95c43732012-07-25 15:57:14 -0700190 hw_db = hwid_tool.HardwareDb(options.hwdb_path)
Tammo Spalink5c699832012-07-03 17:50:39 +0800191 comp_db = hw_db.comp_db
Tammo Spalink3a7e9022012-06-27 14:08:40 +0800192 device = hw_db.GetDevice(options.board)
Tammo Spalink5c699832012-07-03 17:50:39 +0800193 component_spec = hwid_tool.ComponentSpec.New()
Tammo Spalink8fab5312012-05-28 18:33:30 +0800194 if options.bom:
Tammo Spalink5c699832012-07-03 17:50:39 +0800195 device.BomExists(options.bom)
Tammo Spalink01e11722012-07-24 10:17:54 -0700196 component_spec = hwid_tool.CombineComponentSpecs(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800197 component_spec, device.boms[options.bom].primary)
Tammo Spalink8fab5312012-05-28 18:33:30 +0800198 if options.variant:
Tammo Spalink5c699832012-07-03 17:50:39 +0800199 device.VariantExists(options.variant)
200 variant_spec = device.variants[options.variant]
Tammo Spalink01e11722012-07-24 10:17:54 -0700201 if hwid_tool.ComponentSpecsConflict(component_spec, variant_spec):
Tammo Spalink95c43732012-07-25 15:57:14 -0700202 sys.exit('ERROR: multiple specifications for these components:\n%s'
Tammo Spalink394e4492012-08-01 10:20:30 -0700203 % YamlWrite(sorted(
204 hwid_tool.ComponentSpecClasses(component_spec) &
205 hwid_tool.ComponentSpecClasses(variant_spec))))
Tammo Spalink01e11722012-07-24 10:17:54 -0700206 component_spec = hwid_tool.CombineComponentSpecs(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800207 component_spec, variant_spec)
Tammo Spalink95c43732012-07-25 15:57:14 -0700208 if options.comps or options.missing:
209 map(comp_db.CompExists, options.comps)
210 map(comp_db.CompClassExists, options.missing)
211 extra_comp_spec = comp_db.CreateComponentSpec(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800212 components=options.comps,
213 missing=options.missing)
Tammo Spalink95c43732012-07-25 15:57:14 -0700214 print 'cmdline asserted components:\n%s' % extra_comp_spec.Encode()
215 if hwid_tool.ComponentSpecsConflict(component_spec, extra_comp_spec):
216 sys.exit('ERROR: multiple specifications for these components:\n%s'
Tammo Spalink394e4492012-08-01 10:20:30 -0700217 % YamlWrite(sorted(
218 hwid_tool.ComponentSpecClasses(component_spec) &
219 hwid_tool.ComponentSpecClasses(extra_comp_spec))))
Tammo Spalink95c43732012-07-25 15:57:14 -0700220 component_spec = hwid_tool.CombineComponentSpecs(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800221 component_spec, extra_comp_spec)
Tammo Spalink01e11722012-07-24 10:17:54 -0700222 spec_classes = hwid_tool.ComponentSpecClasses(component_spec)
Tammo Spalink95c43732012-07-25 15:57:14 -0700223 missing_classes = set(comp_db.all_comp_classes) - spec_classes
Tammo Spalink5c699832012-07-03 17:50:39 +0800224 if missing_classes and not options.optimistic:
Andy Cheng8ece7382012-08-22 16:25:42 +0800225 non_probeable_missing = missing_classes - PROBEABLE_COMPONENT_CLASSES
226 if non_probeable_missing:
Tammo Spalink95c43732012-07-25 15:57:14 -0700227 sys.exit('FAILURE: these classes are necessary, were not specified '
Tammo Spalink70b48a52012-08-08 16:54:51 -0700228 'as inputs, and cannot be probed for:\n%s'
229 'This problem can often be addressed by specifying all of '
230 'the missing components on the command line (see the command '
Andy Cheng8ece7382012-08-22 16:25:42 +0800231 'help).' % YamlWrite(list(non_probeable_missing)))
Tammo Spalink95c43732012-07-25 15:57:14 -0700232 print 'probing for missing classes:'
233 print YamlWrite(list(missing_classes))
234 probe_results = Probe(target_comp_classes=list(missing_classes),
235 probe_volatile=False, probe_initial_config=False)
236 cooked_components = comp_db.MatchComponentProbeValues(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800237 probe_results.found_probe_value_map)
Tammo Spalink95c43732012-07-25 15:57:14 -0700238 if cooked_components.unmatched:
239 sys.exit('ERROR: some probed components are unrecognized:\n%s'
240 % YamlWrite(cooked_components.unmatched))
241 probed_comp_spec = comp_db.CreateComponentSpec(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800242 components=cooked_components.matched,
243 missing=probe_results.missing_component_classes)
Tammo Spalink95c43732012-07-25 15:57:14 -0700244 component_spec = hwid_tool.CombineComponentSpecs(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800245 component_spec, probed_comp_spec)
Tammo Spalink95c43732012-07-25 15:57:14 -0700246 print YamlWrite({'component data used for matching': {
Hung-Te Lin56b18402015-01-16 14:52:30 +0800247 'missing component classes': component_spec.classes_missing,
248 'found components': component_spec.components}})
Tammo Spalink95c43732012-07-25 15:57:14 -0700249 component_data = hwid_tool.ComponentData(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800250 extant_components=hwid_tool.ComponentSpecCompClassMap(
251 component_spec).keys(),
252 classes_missing=component_spec.classes_missing)
Tammo Spalink95c43732012-07-25 15:57:14 -0700253 match_tree = device.BuildMatchTree(component_data)
254 if not match_tree:
255 sys.exit('FAILURE: NO matching BOMs found')
256 print 'potential BOMs/VARIANTs:'
257 potential_variants = set()
258 potential_volatiles = set()
259 for bom_name, variant_tree in match_tree.items():
260 print ' BOM: %-8s VARIANTS: %s' % (
Hung-Te Lin56b18402015-01-16 14:52:30 +0800261 bom_name, ', '.join(sorted(variant_tree)))
Tammo Spalink95c43732012-07-25 15:57:14 -0700262 for variant_code in variant_tree:
263 potential_variants.add(variant_code)
264 for volatile_code in device.volatiles:
265 status = device.GetHwidStatus(bom_name, variant_code, volatile_code)
266 if status in options.status:
267 potential_volatiles.add(volatile_code)
268 print ''
269 if len(potential_variants) == 0:
270 sys.exit('FAILURE: no matching VARIANTs found')
271 if len(potential_volatiles) == 0:
272 sys.exit('FAILURE: no VOLATILEs found for potential matching BOMs/VARIANTS '
273 '(with specified status)')
Tammo Spalink394e4492012-08-01 10:20:30 -0700274 if (options.optimistic and
275 len(match_tree) == 1 and
276 len(potential_variants) == 1 and
277 len(potential_volatiles) == 1):
278 print ('MATCHING HWID: %s' % device.FmtHwid(match_tree.keys().pop(),
279 potential_variants.pop(),
280 potential_volatiles.pop()))
Tammo Spalink5c699832012-07-03 17:50:39 +0800281 return
Tammo Spalink95c43732012-07-25 15:57:14 -0700282 print ('probing VOLATILEs to resolve potential matches: %s\n' %
283 ', '.join(sorted(potential_volatiles)))
284 vol_probe_results = Probe(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800285 target_comp_classes=[],
286 probe_volatile=True,
287 probe_initial_config=False)
Tammo Spalink95c43732012-07-25 15:57:14 -0700288 cooked_volatiles = device.MatchVolatileValues(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800289 vol_probe_results.found_volatile_values)
Tammo Spalink95c43732012-07-25 15:57:14 -0700290 match_tree = device.BuildMatchTree(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800291 component_data, cooked_volatiles.matched_tags)
Tammo Spalink95c43732012-07-25 15:57:14 -0700292 matched_hwids = device.GetMatchTreeHwids(match_tree)
293 if matched_hwids:
294 for hwid in matched_hwids:
Ricky Liang02f3bd72012-09-21 14:33:01 +0800295 if matched_hwids[hwid] in options.status:
296 print 'MATCHING HWID: %s' % hwid
Tammo Spalink95c43732012-07-25 15:57:14 -0700297 return
298 print 'exact HWID matching failed, but the following BOMs match: %s' % (
Hung-Te Lin56b18402015-01-16 14:52:30 +0800299 ', '.join(sorted(match_tree)))
Tammo Spalink95c43732012-07-25 15:57:14 -0700300 if options.optimistic and len(match_tree) == 1:
301 bom_name = set(match_tree).pop()
Tammo Spalink5c699832012-07-03 17:50:39 +0800302 bom = device.boms[bom_name]
Tammo Spalink95c43732012-07-25 15:57:14 -0700303 variant_matches = match_tree[bom_name]
Tammo Spalink5c699832012-07-03 17:50:39 +0800304 if len(variant_matches) == 1:
305 var_code = set(variant_matches).pop()
306 elif len(bom.variants) == 1:
307 var_code = set(bom.variants).pop()
308 else:
Tammo Spalink95c43732012-07-25 15:57:14 -0700309 sys.exit('FAILURE: NO matching HWIDs found; optimistic matching failed '
310 'because there were too many variants to choose from for BOM %r'
311 % bom_name)
312 hwids = [device.FmtHwid(bom_name, var_code, vol_code)
313 for vol_code in device.volatiles
314 if device.GetHwidStatus(bom_name, var_code, vol_code)
315 in options.status]
316 for hwid in hwids:
317 print 'MATCHING HWID: %s' % hwid
Tammo Spalink5c699832012-07-03 17:50:39 +0800318 return
319 else:
Tammo Spalink95c43732012-07-25 15:57:14 -0700320 print ('optimistic matching not attempted because either it was '
321 'not requested, or because the number of BOMs was <> 1\n')
322 sys.exit('FAILURE: NO matching HWIDs found')
Tammo Spalink8fab5312012-05-28 18:33:30 +0800323
324
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800325@Command('probe',
326 CmdArg('--comps', nargs='*',
327 help='List of keys from the component_db registry.'),
Ricky Liangb30da672013-06-14 12:36:34 +0800328 CmdArg('--fast_fw_probe', action='store_true',
329 help='Do a fast probe for EC and main firmware versions only. '
330 'This implies --no_vol and --no_ic.'),
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800331 CmdArg('--no_vol', action='store_true',
332 help='Do not probe volatile data.'),
333 CmdArg('--no_ic', action='store_true',
Jon Salz0f8a6842012-09-25 11:28:22 +0800334 help='Do not probe initial_config data.'),
335 CmdArg('--include_vpd', action='store_true',
336 help='Include VPD data in volatiles.'))
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800337def RunProbe(options):
338 """Print yaml-formatted breakdown of probed device properties."""
Ricky Lianga70a1202013-03-15 15:03:17 +0800339 print GetGooftool(options).Probe(
340 target_comp_classes=options.comps,
Ricky Liangb30da672013-06-14 12:36:34 +0800341 fast_fw_probe=options.fast_fw_probe,
Ricky Lianga70a1202013-03-15 15:03:17 +0800342 probe_volatile=not options.no_vol,
343 probe_initial_config=not options.no_ic,
344 probe_vpd=options.include_vpd).Encode()
Ricky Liang53390232013-03-08 15:37:57 +0800345
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800346
Tammo Spalink214caf42012-05-28 10:45:00 +0800347@Command('verify_components',
348 _hwdb_path_cmd_arg,
Tammo Spalink5c699832012-07-03 17:50:39 +0800349 CmdArg('target_comps', nargs='*'))
Tammo Spalink214caf42012-05-28 10:45:00 +0800350def VerifyComponents(options):
Andy Cheng8ece7382012-08-22 16:25:42 +0800351 """Verify that probeable components all match entries in the component_db.
Tammo Spalink214caf42012-05-28 10:45:00 +0800352
Tammo Spalink5c699832012-07-03 17:50:39 +0800353 Probe for each component class in the target_comps and verify
Tammo Spalink214caf42012-05-28 10:45:00 +0800354 that a corresponding match exists in the component_db -- make sure
355 that these components are present, that they have been approved, but
356 do not check against any specific BOM/HWID configurations.
357 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800358
Andy Chengc531e2f2012-10-15 19:09:17 +0800359 try:
Ricky Lianga70a1202013-03-15 15:03:17 +0800360 result = GetGooftool(options).VerifyComponents(
Andy Chengc531e2f2012-10-15 19:09:17 +0800361 options.target_comps)
362 except ValueError, e:
363 sys.exit(e)
364
Ricky Liang53390232013-03-08 15:37:57 +0800365 PrintVerifyComponentsResults(result)
366
367
368def PrintVerifyComponentsResults(result):
369 """Prints out the results of VerifyComponents method call.
370
371 Groups the results into two groups: 'matches' and 'errors', and prints out
372 their values.
373 """
Andy Chengc531e2f2012-10-15 19:09:17 +0800374 # group by matches and errors
Tammo Spalink214caf42012-05-28 10:45:00 +0800375 matches = []
Andy Chengc531e2f2012-10-15 19:09:17 +0800376 errors = []
377 for result_list in result.values():
378 for component_name, _, error in result_list:
379 if component_name:
380 matches.append(component_name)
Tammo Spalink214caf42012-05-28 10:45:00 +0800381 else:
Andy Chengc531e2f2012-10-15 19:09:17 +0800382 errors.append(error)
383
Andy Cheng228a8c92012-08-27 10:53:57 +0800384 if matches:
385 print 'found probeable components:\n %s' % '\n '.join(matches)
Tammo Spalink214caf42012-05-28 10:45:00 +0800386 if errors:
Andy Cheng228a8c92012-08-27 10:53:57 +0800387 print '\nerrors:\n %s' % '\n '.join(errors)
388 sys.exit('\ncomponent verification FAILURE')
Tammo Spalink214caf42012-05-28 10:45:00 +0800389 else:
Hung-Te Lin56b18402015-01-16 14:52:30 +0800390 print '\ncomponent verification SUCCESS'
Tammo Spalink214caf42012-05-28 10:45:00 +0800391
392
Ricky Liang43b879b2014-02-24 11:36:55 +0800393@Command('verify_hwid_v2',
Tammo Spalink95c43732012-07-25 15:57:14 -0700394 _hwid_status_list_cmd_arg,
Jon Salz0f8a6842012-09-25 11:28:22 +0800395 _hwdb_path_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800396 _probe_results_cmd_arg,
397 _hwid_cmd_arg)
Ricky Liang43b879b2014-02-24 11:36:55 +0800398def VerifyHWIDv2(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800399 """Verify system HWID properties match probed device properties.
400
401 First probe components, volatile and initial_config parameters for
402 the DUT. Then use the available device data to produce a list of
403 candidate HWIDs. Then verify the HWID from the DUT is present in
404 that list. Then verify that the DUT initial config values match
405 those specified for its HWID. Finally, verify that VPD contains all
406 the necessary fields as specified by the board data, and when
407 possible verify that values are legitimate.
408 """
Ricky Liangf7857c12012-09-17 13:34:41 +0800409 def VerifyVpd(ro_vpd_keys, rw_vpd_keys):
Tammo Spalink5c699832012-07-03 17:50:39 +0800410 for key in ro_vpd_keys:
411 if key not in ro_vpd:
Ricky Liangf7857c12012-09-17 13:34:41 +0800412 sys.exit('Missing required RO VPD field: %s' % key)
Tammo Spalink01e11722012-07-24 10:17:54 -0700413 known_valid_values = KNOWN_VPD_FIELD_DATA.get(key, None)
Tammo Spalink5c699832012-07-03 17:50:39 +0800414 value = ro_vpd[key]
Ricky Liangf7857c12012-09-17 13:34:41 +0800415 if (known_valid_values is not None) and (value not in known_valid_values):
416 sys.exit('Invalid RO VPD entry : key %r, value %r' % (key, value))
Ricky Liangf7857c12012-09-17 13:34:41 +0800417 for key in rw_vpd_keys:
418 if key not in rw_vpd:
419 sys.exit('Missing required RW VPD field: %s' % key)
420 known_valid_values = KNOWN_VPD_FIELD_DATA.get(key, None)
421 value = rw_vpd[key]
422 if (known_valid_values is not None) and (value not in known_valid_values):
423 sys.exit('Invalid RW VPD entry : key %r, value %r' % (key, value))
Andy Cheng0465d132013-03-20 12:12:06 +0800424 event_log.Log('vpd', ro_vpd=FilterDict(ro_vpd), rw_vpd=FilterDict(rw_vpd))
Tammo Spalink5c699832012-07-03 17:50:39 +0800425 map(hwid_tool.Validate.Status, options.status)
Jon Salz0f8a6842012-09-25 11:28:22 +0800426
Jon Salz0f8a6842012-09-25 11:28:22 +0800427 if options.hwid:
428 hwid_str = options.hwid
429 else:
Hung-Te Lin74346d72016-01-07 22:16:57 +0800430 main_fw_file = crosfw.LoadMainFirmware().GetFileName()
Jon Salz0f8a6842012-09-25 11:28:22 +0800431 gbb_result = Shell('gbb_utility -g --hwid %s' % main_fw_file).stdout
432 hwid_str = re.findall(r'hardware_id:(.*)', gbb_result)[0].strip()
Tammo Spalink95c43732012-07-25 15:57:14 -0700433 hwid = hwid_tool.ParseHwid(hwid_str)
Tammo Spalink5c699832012-07-03 17:50:39 +0800434 hw_db = hwid_tool.HardwareDb(options.hwdb_path)
Jon Salz0f8a6842012-09-25 11:28:22 +0800435 print 'Verifying HWID: %r\n' % hwid.hwid
Tammo Spalink95c43732012-07-25 15:57:14 -0700436 device = hw_db.GetDevice(hwid.board)
437 hwid_status = device.GetHwidStatus(hwid.bom, hwid.variant, hwid.volatile)
438 if hwid_status not in options.status:
Tammo Spalink5c699832012-07-03 17:50:39 +0800439 sys.exit('HWID status must be one of [%s], found %r' %
Hung-Te Lin4f5beb12012-08-20 14:48:06 +0800440 (', '.join(options.status), hwid_status))
Jon Salz0f8a6842012-09-25 11:28:22 +0800441 if options.probe_results:
442 # Pull in probe results (including VPD data) from the given file
443 # rather than probing the current system.
444 probe_results = hwid_tool.ProbeResults.Decode(
445 open(options.probe_results).read())
446 ro_vpd = {}
447 rw_vpd = {}
448 for k, v in probe_results.found_volatile_values.items():
Hung-Te Lin56b18402015-01-16 14:52:30 +0800449 match = re.match(r'^vpd\.(ro|rw)\.(\w+)$', k)
Jon Salz0f8a6842012-09-25 11:28:22 +0800450 if match:
451 del probe_results.found_volatile_values[k]
452 (ro_vpd if match.group(1) == 'ro' else rw_vpd)[match.group(2)] = v
453 else:
454 probe_results = Probe()
Hung-Te Lin74346d72016-01-07 22:16:57 +0800455 ro_vpd = ReadRoVpd()
456 rw_vpd = ReadRwVpd()
Tammo Spalink95c43732012-07-25 15:57:14 -0700457 cooked_components = hw_db.comp_db.MatchComponentProbeValues(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800458 probe_results.found_probe_value_map)
Tammo Spalink95c43732012-07-25 15:57:14 -0700459 cooked_volatiles = device.MatchVolatileValues(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800460 probe_results.found_volatile_values)
Tammo Spalink95c43732012-07-25 15:57:14 -0700461 cooked_initial_configs = device.MatchInitialConfigValues(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800462 probe_results.initial_configs)
Tammo Spalink95c43732012-07-25 15:57:14 -0700463 component_data = hwid_tool.ComponentData(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800464 extant_components=cooked_components.matched,
465 classes_missing=probe_results.missing_component_classes)
Tammo Spalink95c43732012-07-25 15:57:14 -0700466 match_tree = device.BuildMatchTree(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800467 component_data, cooked_volatiles.matched_tags)
Tammo Spalink95c43732012-07-25 15:57:14 -0700468 matched_hwids = device.GetMatchTreeHwids(match_tree)
469 print 'HWID status: %s\n' % hwid_status
470 print 'probed system components:'
471 print YamlWrite(cooked_components.__dict__)
472 print 'missing component classes:'
473 print YamlWrite(probe_results.missing_component_classes)
474 print 'probed volatiles:'
475 print YamlWrite(cooked_volatiles.__dict__)
476 print 'probed initial_configs:'
477 print YamlWrite(cooked_initial_configs)
478 print 'hwid match tree:'
479 print YamlWrite(match_tree)
Andy Cheng0465d132013-03-20 12:12:06 +0800480 event_log.Log(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800481 'probe',
482 found_components=cooked_components.__dict__,
483 missing_component_classes=probe_results.missing_component_classes,
484 volatiles=cooked_volatiles.__dict__,
485 initial_configs=cooked_initial_configs)
Tammo Spalink95c43732012-07-25 15:57:14 -0700486 if hwid.hwid not in matched_hwids:
Tammo Spalink5c699832012-07-03 17:50:39 +0800487 err_msg = 'HWID verification FAILED.\n'
Tammo Spalink95c43732012-07-25 15:57:14 -0700488 if cooked_components.unmatched:
Tammo Spalink5c699832012-07-03 17:50:39 +0800489 sys.exit(err_msg + 'some components could not be indentified:\n%s' %
Tammo Spalink95c43732012-07-25 15:57:14 -0700490 YamlWrite(cooked_components.unmatched))
491 if not match_tree:
Tammo Spalink5c699832012-07-03 17:50:39 +0800492 sys.exit(err_msg + 'no matching boms were found for components:\n%s' %
Tammo Spalink95c43732012-07-25 15:57:14 -0700493 component_data.Encode())
494 if hwid.bom not in match_tree:
Tammo Spalink5c699832012-07-03 17:50:39 +0800495 sys.exit(err_msg + 'matching boms [%s] do not include target bom %r' %
Tammo Spalink95c43732012-07-25 15:57:14 -0700496 (', '.join(sorted(match_tree)), hwid.bom))
497 err_msg += 'target bom %r matches components' % hwid.bom
498 if hwid.bom not in device.IntersectBomsAndInitialConfigs(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800499 cooked_initial_configs):
Tammo Spalink5c699832012-07-03 17:50:39 +0800500 sys.exit(err_msg + ', but failed initial config verification')
Tammo Spalink95c43732012-07-25 15:57:14 -0700501 matched_variants = match_tree.get(hwid.bom, {})
502 if hwid.variant not in matched_variants:
Tammo Spalink5c699832012-07-03 17:50:39 +0800503 sys.exit(err_msg + ', but target variant_code %r did not match' %
Tammo Spalink95c43732012-07-25 15:57:14 -0700504 hwid.variant)
505 matched_volatiles = matched_variants.get(hwid.variant, {})
506 if hwid.volatile not in matched_volatiles:
Tammo Spalink5c699832012-07-03 17:50:39 +0800507 sys.exit(err_msg + ', but target volatile_code %r did not match' %
Tammo Spalink95c43732012-07-25 15:57:14 -0700508 hwid.volatile)
509 found_status = matched_volatiles.get(hwid.volatile, None)
Tammo Spalink5c699832012-07-03 17:50:39 +0800510 sys.exit(err_msg + ', but hwid status %r was unacceptable' % found_status)
Ricky Liangf7857c12012-09-17 13:34:41 +0800511 VerifyVpd(device.vpd_ro_fields, device.vpd_rw_fields)
Andy Cheng0465d132013-03-20 12:12:06 +0800512 event_log.Log('verified_hwid', hwid=hwid)
Tammo Spalink95c43732012-07-25 15:57:14 -0700513 print 'Verification SUCCESS!'
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800514
515
Hung-Te Line1d80f62016-03-31 14:58:13 +0800516@Command('verify_keys',
Hung-Te Lincdb96522016-04-15 16:51:10 +0800517 _release_rootfs_cmd_arg,
518 _firmware_path_cmd_arg)
Tammo Spalink01e11722012-07-24 10:17:54 -0700519def VerifyKeys(options): # pylint: disable=W0613
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800520 """Verify keys in firmware and SSD match."""
Hung-Te Line1d80f62016-03-31 14:58:13 +0800521 return GetGooftool(options).VerifyKeys(
Hung-Te Lincdb96522016-04-15 16:51:10 +0800522 options.release_rootfs, options.firmware_path)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800523
524
525@Command('set_fw_bitmap_locale')
Tammo Spalink01e11722012-07-24 10:17:54 -0700526def SetFirmwareBitmapLocale(options): # pylint: disable=W0613
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800527 """Use VPD locale value to set firmware bitmap default language."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800528
Ricky Lianga70a1202013-03-15 15:03:17 +0800529 (index, locale) = GetGooftool(options).SetFirmwareBitmapLocale()
Andy Cheng2582d292012-12-04 17:38:28 +0800530 logging.info('Firmware bitmap initial locale set to %d (%s).',
531 index, locale)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800532
533
Hung-Te Line1d80f62016-03-31 14:58:13 +0800534@Command('verify_system_time',
Hung-Te Lincdb96522016-04-15 16:51:10 +0800535 _release_rootfs_cmd_arg)
Tammo Spalink01e11722012-07-24 10:17:54 -0700536def VerifySystemTime(options): # pylint: disable=W0613
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800537 """Verify system time is later than release filesystem creation time."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800538
Hung-Te Lincdb96522016-04-15 16:51:10 +0800539 return GetGooftool(options).VerifySystemTime(options.release_rootfs)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800540
541
Hung-Te Line1d80f62016-03-31 14:58:13 +0800542@Command('verify_rootfs',
Hung-Te Lincdb96522016-04-15 16:51:10 +0800543 _release_rootfs_cmd_arg)
Tammo Spalink01e11722012-07-24 10:17:54 -0700544def VerifyRootFs(options): # pylint: disable=W0613
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800545 """Verify rootfs on SSD is valid by checking hash."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800546
Hung-Te Line1d80f62016-03-31 14:58:13 +0800547 return GetGooftool(options).VerifyRootFs(options.release_rootfs)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800548
Hung-Te Lin56b18402015-01-16 14:52:30 +0800549
Cheng-Yi Chiang676b5292013-06-18 12:05:33 +0800550@Command('verify_tpm')
551def VerifyTPM(options): # pylint: disable=W0613
552 """Verify TPM is cleared."""
553
554 return GetGooftool(options).VerifyTPM()
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800555
Hung-Te Lin56b18402015-01-16 14:52:30 +0800556
Hung-Te Lindd708d42014-07-11 17:05:01 +0800557@Command('verify_me_locked')
558def VerifyManagementEngineLocked(options): # pylint: disable=W0613
559 """Verify Managment Engine is locked."""
560
561 return GetGooftool(options).VerifyManagementEngineLocked()
562
Hung-Te Lin56b18402015-01-16 14:52:30 +0800563
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800564@Command('verify_switch_wp')
Andy Chengc92e6f92012-11-20 16:55:53 +0800565def VerifyWPSwitch(options): # pylint: disable=W0613
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800566 """Verify hardware write protection switch is enabled."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800567
Ricky Lianga70a1202013-03-15 15:03:17 +0800568 GetGooftool(options).VerifyWPSwitch()
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800569
570
571@Command('verify_switch_dev')
Tammo Spalink01e11722012-07-24 10:17:54 -0700572def VerifyDevSwitch(options): # pylint: disable=W0613
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800573 """Verify developer switch is disabled."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800574
Ricky Lianga70a1202013-03-15 15:03:17 +0800575 if GetGooftool(options).CheckDevSwitchForDisabling():
Hung-Te Lind7d34722012-07-26 16:48:35 +0800576 logging.warn('VerifyDevSwitch: No physical switch.')
Andy Cheng0465d132013-03-20 12:12:06 +0800577 event_log.Log('switch_dev', type='virtual switch')
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800578
579
Jon Salzadd90d32014-04-29 16:16:27 +0800580@Command('verify_branding')
581def VerifyBranding(options): # pylint: disable=W0613
582 """Verify that branding fields are properly set.
583
584 customization_id, if set in the RO VPD, must be of the correct format.
585
586 rlz_brand_code must be set either in the RO VPD or OEM partition, and must
587 be of the correct format.
588 """
589 return GetGooftool(options).VerifyBranding()
590
591
bowgotsai13820f42015-09-10 23:18:04 +0800592@Command('verify_release_channel',
593 _enforced_release_channels_cmd_arg)
bowgotsai529139c2015-05-30 01:39:49 +0800594def VerifyReleaseChannel(options): # pylint: disable=W0613
595 """Verify that release image channel is correct.
596
597 ChromeOS has four channels: canary, dev, beta and stable.
598 The last three channels support image auto-updates, checks
599 that release image channel is one of them.
600 """
bowgotsai13820f42015-09-10 23:18:04 +0800601 return GetGooftool(options).VerifyReleaseChannel(
602 options.enforced_release_channels)
bowgotsai529139c2015-05-30 01:39:49 +0800603
604
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800605@Command('write_protect')
Tammo Spalink01e11722012-07-24 10:17:54 -0700606def EnableFwWp(options): # pylint: disable=W0613
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800607 """Enable then verify firmware write protection."""
608
Hung-Te Linb21c6682012-08-01 13:53:57 +0800609 def CalculateLegacyRange(fw_type, length, section_data,
610 section_name):
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800611 ro_size = length / 2
612 ro_a = int(section_data[0] / ro_size)
613 ro_b = int((section_data[0] + section_data[1] - 1) / ro_size)
614 if ro_a != ro_b:
Hung-Te Lin56b18402015-01-16 14:52:30 +0800615 raise Error('%s firmware section %s has illegal size' %
Hung-Te Linb21c6682012-08-01 13:53:57 +0800616 (fw_type, section_name))
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800617 ro_offset = ro_a * ro_size
618 return (ro_offset, ro_size)
619
620 def WriteProtect(fw_file_path, fw_type, legacy_section):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800621 """Calculate protection size, then invoke flashrom.
622
623 Our supported chips only allow write protecting half their total
624 size, so we parition the flash chipset space accordingly.
625 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800626
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800627 raw_image = open(fw_file_path, 'rb').read()
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800628 wp_section = 'WP_RO'
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800629 image = crosfw.FirmwareImage(raw_image)
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800630 if image.has_section(wp_section):
631 section_data = image.get_section_area(wp_section)
632 ro_offset = section_data[0]
633 ro_size = section_data[1]
634 elif image.has_section(legacy_section):
635 section_data = image.get_section_area(legacy_section)
636 (ro_offset, ro_size) = CalculateLegacyRange(
Hung-Te Linb21c6682012-08-01 13:53:57 +0800637 fw_type, len(raw_image), section_data, legacy_section)
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800638 else:
639 raise Error('could not find %s firmware section %s or %s' %
640 (fw_type, wp_section, legacy_section))
641
642 logging.debug('write protecting %s [off=%x size=%x]', fw_type,
643 ro_offset, ro_size)
644 crosfw.Flashrom(fw_type).EnableWriteProtection(ro_offset, ro_size)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800645
646 WriteProtect(crosfw.LoadMainFirmware().GetFileName(), 'main', 'RO_SECTION')
Andy Cheng0465d132013-03-20 12:12:06 +0800647 event_log.Log('wp', fw='main')
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800648 ec_fw_file = crosfw.LoadEcFirmware().GetFileName()
649 if ec_fw_file is not None:
650 WriteProtect(ec_fw_file, 'ec', 'EC_RO')
Andy Cheng0465d132013-03-20 12:12:06 +0800651 event_log.Log('wp', fw='ec')
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800652 else:
653 logging.warning('EC not write protected (seems there is no EC flash).')
654
655
656@Command('clear_gbb_flags')
Andy Chengc92e6f92012-11-20 16:55:53 +0800657def ClearGBBFlags(options): # pylint: disable=W0613
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800658 """Zero out the GBB flags, in preparation for transition to release state.
659
660 No GBB flags are set in release/shipping state, but they are useful
661 for factory/development. See "gbb_utility --flags" for details.
662 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800663
Ricky Lianga70a1202013-03-15 15:03:17 +0800664 GetGooftool(options).ClearGBBFlags()
Andy Cheng0465d132013-03-20 12:12:06 +0800665 event_log.Log('clear_gbb_flags')
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800666
667
Jon Salzaa3a30e2013-05-15 15:56:28 +0800668@Command('clear_factory_vpd_entries')
669def ClearFactoryVPDEntries(options): # pylint: disable=W0613
670 """Clears factory.* items in the RW VPD."""
671 entries = GetGooftool(options).ClearFactoryVPDEntries()
672 event_log.Log('clear_factory_vpd_entries', entries=FilterDict(entries))
673
674
Mattias Nisslercca761b2015-04-15 21:53:04 +0200675@Command('generate_stable_device_secret')
676def GenerateStableDeviceSecret(options): # pylint: disable=W0613
677 """Generates a a fresh stable device secret and stores it in the RO VPD."""
678 GetGooftool(options).GenerateStableDeviceSecret()
679 event_log.Log('generate_stable_device_secret')
680
Shun-Hsing Ou8d3c40a2015-10-08 18:16:08 +0800681_cutoff_args_cmd_arg = CmdArg(
682 '--cutoff_args',
683 help='Battery cutoff arguments to be passed to battery_cutoff.sh '
684 'after wiping. Should be the following format: '
685 '[--method shutdown|reboot|battery_cutoff|battery_cutoff_at_shutdown] '
686 '[--check-ac connect_ac|remove_ac] '
687 '[--min-battery-percent <minimum battery percentage>] '
688 '[--max-battery-percent <maximum battery percentage>] '
689 '[--min-battery-voltage <minimum battery voltage>] '
690 '[--max-battery-voltage <maximum battery voltage>]')
Shun-Hsing Oudb407d62015-11-11 11:03:59 +0800691_shopfloor_url_args_cmd_arg = CmdArg(
692 '--shopfloor_url',
693 help='Shopfloor server url to be informed when in-place wipe is done. '
694 'After in-place wipe, a XML-RPC request will be sent to the '
695 'given url to indicate the completion of wipe.')
Shun-Hsing Oucdc64e12015-01-14 22:07:33 +0800696@Command('wipe_in_place',
697 CmdArg('--fast', action='store_true',
Shun-Hsing Ou8d3c40a2015-10-08 18:16:08 +0800698 help='use non-secure but faster wipe method.'),
Shun-Hsing Oudb407d62015-11-11 11:03:59 +0800699 _cutoff_args_cmd_arg,
700 _shopfloor_url_args_cmd_arg)
Shun-Hsing Oucdc64e12015-01-14 22:07:33 +0800701def WipeInPlace(options):
702 """Start factory wipe directly without reboot."""
703
Shun-Hsing Oudb407d62015-11-11 11:03:59 +0800704 GetGooftool(options).WipeInPlace(options.fast, options.cutoff_args,
705 options.shopfloor_url)
Mattias Nisslercca761b2015-04-15 21:53:04 +0200706
Wei-Han Chen7dc6d132016-04-06 11:11:53 +0800707@Command('wipe_init',
708 CmdArg('--wipe_file', help='path to the wipe args file'))
709def WipeInit(options):
710 GetGooftool(options).WipeInit(options.args_file)
711
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800712@Command('prepare_wipe',
713 CmdArg('--fast', action='store_true',
714 help='use non-secure but faster wipe method.'))
715def PrepareWipe(options):
716 """Prepare system for transition to release state in next reboot."""
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800717
Ricky Lianga70a1202013-03-15 15:03:17 +0800718 GetGooftool(options).PrepareWipe(options.fast)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800719
Hung-Te Lin56b18402015-01-16 14:52:30 +0800720
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800721@Command('verify',
Hung-Te Lin6d827542012-07-19 11:50:41 +0800722 CmdArg('--no_write_protect', action='store_true',
723 help='Do not check write protection switch state.'),
Ricky Liang43b879b2014-02-24 11:36:55 +0800724 _hwid_version_cmd_arg,
Tammo Spalink95c43732012-07-25 15:57:14 -0700725 _hwid_status_list_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800726 _hwdb_path_cmd_arg,
Ricky Lianga70a1202013-03-15 15:03:17 +0800727 _board_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800728 _probe_results_cmd_arg,
Cheng-Yi Chiang406ad912013-11-14 16:51:33 +0800729 _hwid_cmd_arg,
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800730 _rma_mode_cmd_arg,
bowgotsai13820f42015-09-10 23:18:04 +0800731 _cros_core_cmd_arg,
Hung-Te Lincdb96522016-04-15 16:51:10 +0800732 _release_rootfs_cmd_arg,
733 _firmware_path_cmd_arg,
bowgotsai13820f42015-09-10 23:18:04 +0800734 _enforced_release_channels_cmd_arg)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800735def Verify(options):
736 """Verifies if whole factory process is ready for finalization.
737
738 This routine performs all the necessary checks to make sure the
739 device is ready to be finalized, but does not modify state. These
740 checks include dev switch, firmware write protection switch, hwid,
741 system time, keys, and root file system.
742 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800743
Hung-Te Lin6d827542012-07-19 11:50:41 +0800744 if not options.no_write_protect:
Ricky Lianga70a1202013-03-15 15:03:17 +0800745 VerifyWPSwitch(options)
Hung-Te Lindd708d42014-07-11 17:05:01 +0800746 VerifyManagementEngineLocked(options)
Ricky Lianga70a1202013-03-15 15:03:17 +0800747 VerifyDevSwitch(options)
748 if options.hwid_version == 2:
Ricky Liang43b879b2014-02-24 11:36:55 +0800749 VerifyHWIDv2(options)
Ricky Lianga70a1202013-03-15 15:03:17 +0800750 elif options.hwid_version == 3:
Ricky Liangc662be32013-12-24 11:50:23 +0800751 VerifyHWIDv3(options)
Ricky Lianga70a1202013-03-15 15:03:17 +0800752 else:
753 raise Error, 'Invalid HWID version: %r' % options.hwid_version
754 VerifySystemTime(options)
755 VerifyKeys(options)
756 VerifyRootFs(options)
Cheng-Yi Chiang676b5292013-06-18 12:05:33 +0800757 VerifyTPM(options)
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800758 if options.cros_core:
759 logging.info('VerifyBranding is skipped for ChromeOS Core device.')
760 else:
761 VerifyBranding(options)
bowgotsai529139c2015-05-30 01:39:49 +0800762 VerifyReleaseChannel(options)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800763
Hung-Te Lin56b18402015-01-16 14:52:30 +0800764
Jon Salzfe9036f2014-01-16 14:11:23 +0800765@Command('untar_stateful_files')
Hung-Te Lin388bce22014-06-03 19:56:40 +0800766def UntarStatefulFiles(unused_options):
Jon Salzfe9036f2014-01-16 14:11:23 +0800767 """Untars stateful files from stateful_files.tar.xz on stateful partition.
768
769 If that file does not exist (which should only be R30 and earlier),
770 this is a no-op.
771 """
Wei-Han Chen2ebb92d2016-01-12 14:51:41 +0800772 tar_file = os.path.join(paths.DEVICE_STATEFUL_PATH, 'stateful_files.tar.xz')
Jon Salzfe9036f2014-01-16 14:11:23 +0800773 if os.path.exists(tar_file):
Wei-Han Chen2ebb92d2016-01-12 14:51:41 +0800774 Spawn(['tar', 'xf', tar_file], cwd=paths.DEVICE_STATEFUL_PATH,
Jon Salzfe9036f2014-01-16 14:11:23 +0800775 log=True, check_call=True)
776 else:
777 logging.warning('No stateful files at %s', tar_file)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800778
Jon Salz40b9f822014-07-25 16:39:55 +0800779
780@Command('log_source_hashes')
781def LogSourceHashes(options): # pylint: disable=W0613
782 """Logs hashes of source files in the factory toolkit."""
Jon Salze60307f2014-08-05 16:20:00 +0800783 # WARNING: The following line is necessary to validate the integrity
784 # of the factory software. Do not remove or modify it.
785 #
786 # 警告:此行会验证工厂软件的完整性,禁止删除或修改。
Jon Salz40b9f822014-07-25 16:39:55 +0800787 event_log.Log(
788 'source_hashes',
Wei-Han Chen2ebb92d2016-01-12 14:51:41 +0800789 **file_utils.HashSourceTree(os.path.join(paths.FACTORY_PATH, 'py')))
Jon Salz40b9f822014-07-25 16:39:55 +0800790
791
Tammo Spalink86a61c62012-05-25 15:10:35 +0800792@Command('log_system_details')
Tammo Spalink01e11722012-07-24 10:17:54 -0700793def LogSystemDetails(options): # pylint: disable=W0613
Tammo Spalink86a61c62012-05-25 15:10:35 +0800794 """Write miscellaneous system details to the event log."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800795
Ricky Liang43b879b2014-02-24 11:36:55 +0800796 event_log.Log('system_details', **GetGooftool(options).GetSystemDetails())
Tammo Spalink86a61c62012-05-25 15:10:35 +0800797
798
Jon Salza88b83b2013-05-27 20:00:35 +0800799def CreateReportArchiveBlob(*args, **kwargs):
800 """Creates a report archive and returns it as a blob.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800801
Jon Salza88b83b2013-05-27 20:00:35 +0800802 Args:
803 See CreateReportArchive.
Andy Cheng7a76cb82012-11-19 18:08:19 +0800804
Jon Salza88b83b2013-05-27 20:00:35 +0800805 Returns:
806 An xmlrpclib.Binary object containing a .tar.xz file.
807 """
808 with open(CreateReportArchive(*args, **kwargs)) as f:
809 return xmlrpclib.Binary(f.read())
810
811
812def CreateReportArchive(device_sn=None, add_file=None):
813 """Creates a report archive in a temporary directory.
814
815 Args:
816 device_sn: The device serial number (optional).
817 add_file: A list of files to add (optional).
818
819 Returns:
820 Path to the archive.
821 """
Hung-Te Lin6bd16472012-06-20 16:26:47 +0800822 def NormalizeAsFileName(token):
823 return re.sub(r'\W+', '', token).strip()
Jon Salza88b83b2013-05-27 20:00:35 +0800824
825 target_name = '%s%s.tar.xz' % (
826 time.strftime('%Y%m%dT%H%M%SZ',
827 time.gmtime()),
Hung-Te Lin56b18402015-01-16 14:52:30 +0800828 ('' if device_sn is None else
829 '_' + NormalizeAsFileName(device_sn)))
Tammo Spalink86a61c62012-05-25 15:10:35 +0800830 target_path = os.path.join(gettempdir(), target_name)
Jon Salza88b83b2013-05-27 20:00:35 +0800831
Tammo Spalink86a61c62012-05-25 15:10:35 +0800832 # Intentionally ignoring dotfiles in EVENT_LOG_DIR.
Andy Cheng0465d132013-03-20 12:12:06 +0800833 tar_cmd = 'cd %s ; tar cJf %s *' % (event_log.EVENT_LOG_DIR, target_path)
Joel Kitching4b1b6c02016-05-10 14:34:30 +0800834 tar_cmd += ' --add-file %s' % paths.GetFactoryLogPath()
Jon Salza88b83b2013-05-27 20:00:35 +0800835 if add_file:
836 for f in add_file:
Jon Salz65266432012-07-30 19:02:49 +0800837 # Require absolute paths since the tar command may change the
838 # directory.
839 if not f.startswith('/'):
840 raise Error('Not an absolute path: %s' % f)
841 if not os.path.exists(f):
842 raise Error('File does not exist: %s' % f)
843 tar_cmd += ' --add-file %s' % pipes.quote(f)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800844 cmd_result = Shell(tar_cmd)
Jon Salzff88c022012-11-03 12:19:58 +0800845
846 if ((cmd_result.status == 1) and
847 all((x == '' or
848 'file changed as we read it' in x or
849 "Removing leading `/' from member names" in x)
850 for x in cmd_result.stderr.split('\n'))):
851 # That's OK. Make sure it's valid though.
Vic Yang85199e72013-01-28 14:33:11 +0800852 Spawn(['tar', 'tfJ', target_path], check_call=True, log=True,
Jon Salzff88c022012-11-03 12:19:58 +0800853 ignore_stdout=True)
854 elif not cmd_result.success:
Tammo Spalink86a61c62012-05-25 15:10:35 +0800855 raise Error('unable to tar event logs, cmd %r failed, stderr: %r' %
856 (tar_cmd, cmd_result.stderr))
Jon Salzff88c022012-11-03 12:19:58 +0800857
Jon Salza88b83b2013-05-27 20:00:35 +0800858 return target_path
859
860_upload_method_cmd_arg = CmdArg(
861 '--upload_method', metavar='METHOD:PARAM',
862 help=('How to perform the upload. METHOD should be one of '
863 '{ftp, shopfloor, ftps, cpfe}.'))
864_add_file_cmd_arg = CmdArg(
865 '--add_file', metavar='FILE', action='append',
866 help='Extra file to include in report (must be an absolute path)')
867
Hung-Te Lin56b18402015-01-16 14:52:30 +0800868
Jon Salza88b83b2013-05-27 20:00:35 +0800869@Command('upload_report',
870 _upload_method_cmd_arg,
871 _add_file_cmd_arg)
872def UploadReport(options):
873 """Create a report containing key device details."""
Hung-Te Lin74346d72016-01-07 22:16:57 +0800874 ro_vpd = ReadRoVpd()
Jon Salza88b83b2013-05-27 20:00:35 +0800875 device_sn = ro_vpd.get('serial_number', None)
876 if device_sn is None:
877 logging.warning('RO_VPD missing device serial number')
878 device_sn = 'MISSING_SN_' + event_log.TimedUuid()
879 target_path = CreateReportArchive(device_sn)
880
Tammo Spalink86a61c62012-05-25 15:10:35 +0800881 if options.upload_method is None or options.upload_method == 'none':
882 logging.warning('REPORT UPLOAD SKIPPED (report left at %s)', target_path)
883 return
884 method, param = options.upload_method.split(':', 1)
885 if method == 'shopfloor':
886 report_upload.ShopFloorUpload(target_path, param)
887 elif method == 'ftp':
Jay Kim360c1dd2012-06-25 10:58:11 -0700888 report_upload.FtpUpload(target_path, 'ftp:' + param)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800889 elif method == 'ftps':
890 report_upload.CurlUrlUpload(target_path, '--ftp-ssl-reqd ftp:%s' % param)
891 elif method == 'cpfe':
Shawn Nematbakhsh3404a092013-01-28 16:49:09 -0800892 report_upload.CpfeUpload(target_path, pipes.quote(param))
Tammo Spalink86a61c62012-05-25 15:10:35 +0800893 else:
894 raise Error('unknown report upload method %r', method)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800895
896
897@Command('finalize',
Hung-Te Lin6d827542012-07-19 11:50:41 +0800898 CmdArg('--no_write_protect', action='store_true',
899 help='Do not enable firmware write protection.'),
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800900 CmdArg('--fast', action='store_true',
901 help='use non-secure but faster wipe method.'),
Shun-Hsing Oucdc64e12015-01-14 22:07:33 +0800902 CmdArg('--wipe_in_place', action='store_true',
903 help='Start factory wiping in place without reboot.'),
Shun-Hsing Ou8d3c40a2015-10-08 18:16:08 +0800904 _cutoff_args_cmd_arg,
Shun-Hsing Oudb407d62015-11-11 11:03:59 +0800905 _shopfloor_url_args_cmd_arg,
Ricky Liang43b879b2014-02-24 11:36:55 +0800906 _hwid_version_cmd_arg,
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800907 _hwdb_path_cmd_arg,
Tammo Spalink95c43732012-07-25 15:57:14 -0700908 _hwid_status_list_cmd_arg,
Jon Salz65266432012-07-30 19:02:49 +0800909 _upload_method_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800910 _add_file_cmd_arg,
Ricky Lianga70a1202013-03-15 15:03:17 +0800911 _board_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800912 _probe_results_cmd_arg,
Cheng-Yi Chiang406ad912013-11-14 16:51:33 +0800913 _hwid_cmd_arg,
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800914 _rma_mode_cmd_arg,
bowgotsai13820f42015-09-10 23:18:04 +0800915 _cros_core_cmd_arg,
Hung-Te Lincdb96522016-04-15 16:51:10 +0800916 _release_rootfs_cmd_arg,
917 _firmware_path_cmd_arg,
bowgotsai13820f42015-09-10 23:18:04 +0800918 _enforced_release_channels_cmd_arg)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800919def Finalize(options):
920 """Verify system readiness and trigger transition into release state.
921
Jon Salzaa3a30e2013-05-15 15:56:28 +0800922 This routine does the following:
923 - Verifies system state (see verify command)
Jon Salzfe9036f2014-01-16 14:11:23 +0800924 - Untars stateful_files.tar.xz, if it exists, in the stateful partition, to
925 initialize files such as the CRX cache
Jon Salzaa3a30e2013-05-15 15:56:28 +0800926 - Modifies firmware bitmaps to match locale
927 - Clears all factory-friendly flags from the GBB
928 - Removes factory-specific entries from RW_VPD (factory.*)
929 - Enables firmware write protection (cannot rollback after this)
930 - Uploads system logs & reports
931 - Sets the necessary boot flags to cause wipe of the factory image on the
932 next boot.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800933 """
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800934 Verify(options)
Jon Salz40b9f822014-07-25 16:39:55 +0800935 LogSourceHashes(options)
Jon Salzfe9036f2014-01-16 14:11:23 +0800936 UntarStatefulFiles(options)
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800937 if options.cros_core:
938 logging.info('SetFirmwareBitmapLocale is skipped for ChromeOS Core device.')
939 else:
940 SetFirmwareBitmapLocale(options)
Ricky Lianga70a1202013-03-15 15:03:17 +0800941 ClearGBBFlags(options)
Jon Salzaa3a30e2013-05-15 15:56:28 +0800942 ClearFactoryVPDEntries(options)
Mattias Nisslercca761b2015-04-15 21:53:04 +0200943 GenerateStableDeviceSecret(options)
Hung-Te Lin6d827542012-07-19 11:50:41 +0800944 if options.no_write_protect:
945 logging.warn('WARNING: Firmware Write Protection is SKIPPED.')
Andy Cheng0465d132013-03-20 12:12:06 +0800946 event_log.Log('wp', fw='both', status='skipped')
Hung-Te Lin6d827542012-07-19 11:50:41 +0800947 else:
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800948 EnableFwWp({})
Jon Salza0f58e02012-05-29 19:33:39 +0800949 LogSystemDetails(options)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800950 UploadReport(options)
Shun-Hsing Oucdc64e12015-01-14 22:07:33 +0800951 if options.wipe_in_place:
952 event_log.Log('wipe_in_place')
953 WipeInPlace(options)
954 else:
955 PrepareWipe(options)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800956
957
Ricky Liangc662be32013-12-24 11:50:23 +0800958def VerifyHWIDv3(options):
959 """A simple wrapper that calls out to HWID utils to verify version 3 HWID.
Ricky Liang53390232013-03-08 15:37:57 +0800960
Ricky Liangc662be32013-12-24 11:50:23 +0800961 This is mainly for Gooftool to verify v3 HWID during finalize. For testing
962 and development purposes, please use `hwid` command.
Ricky Liang53390232013-03-08 15:37:57 +0800963 """
Ricky Liangc662be32013-12-24 11:50:23 +0800964 db = GetGooftool(options).db
965 encoded_string = options.hwid or hwid_utils.GetHWIDString()
Ricky Liang7905f272013-03-16 01:57:10 +0800966 if options.probe_results:
Ricky Liangc662be32013-12-24 11:50:23 +0800967 probed_results = yaml.load(open(options.probe_results).read())
Ricky Liang7905f272013-03-16 01:57:10 +0800968 else:
Ricky Liangc662be32013-12-24 11:50:23 +0800969 probed_results = yaml.load(Probe(probe_vpd=True).Encode())
970 vpd = hwid_utils.GetVPD(probed_results)
Ricky Liang53390232013-03-08 15:37:57 +0800971
Hung-Te Lin11052952015-03-18 13:48:59 +0800972 event_log.Log('probed_results', probed_results=FilterDict(probed_results))
973 event_log.Log('vpd', vpd=FilterDict(vpd))
Ricky Liang53390232013-03-08 15:37:57 +0800974
Ricky Liangc662be32013-12-24 11:50:23 +0800975 hwid_utils.VerifyHWID(db, encoded_string, probed_results, vpd,
Hung-Te Lin56b18402015-01-16 14:52:30 +0800976 rma_mode=options.rma_mode)
Ricky Liang53390232013-03-08 15:37:57 +0800977
Ricky Liangc662be32013-12-24 11:50:23 +0800978 event_log.Log('verified_hwid', hwid=encoded_string)
Ricky Liang53390232013-03-08 15:37:57 +0800979
980
Ricky Liang59611a62013-06-11 13:47:33 +0800981def ParseDecodedHWID(hwid):
982 """Parse the HWID object into a more compact dict.
983
984 Args:
985 hwid: A decoded HWID object.
986
987 Returns:
988 A dict containing the board name, the binary string, and the list of
989 components.
990 """
991 results = {}
992 results['board'] = hwid.database.board
993 results['binary_string'] = hwid.binary_string
994 results['components'] = collections.defaultdict(list)
995 components = hwid.bom.components
996 for comp_cls in sorted(components):
997 for (comp_name, probed_values, _) in sorted(components[comp_cls]):
998 if not probed_values:
999 db_components = hwid.database.components
1000 probed_values = db_components.GetComponentAttributes(
1001 comp_cls, comp_name).get('values')
1002 results['components'][comp_cls].append(
1003 {comp_name: probed_values if probed_values else None})
1004 # Convert defaultdict to dict.
1005 results['components'] = dict(results['components'])
1006 return results
1007
1008
henryhsu44d793a2013-07-20 00:07:38 +08001009@Command('get_firmware_hash',
1010 CmdArg('--file', metavar='FILE', help='Firmware File.'))
1011def GetFirmwareHash(options):
henryhsuf6f835c2013-07-20 20:49:25 +08001012 """Get firmware hash from a file"""
henryhsu44d793a2013-07-20 00:07:38 +08001013 if os.path.exists(options.file):
1014 hashes = CalculateFirmwareHashes(options.file)
1015 for section, value_dict in hashes.iteritems():
Hung-Te Lin56b18402015-01-16 14:52:30 +08001016 print '%s:' % section
henryhsu44d793a2013-07-20 00:07:38 +08001017 for key, value in value_dict.iteritems():
Hung-Te Lin56b18402015-01-16 14:52:30 +08001018 print ' %s: %s' % (key, value)
henryhsu44d793a2013-07-20 00:07:38 +08001019 else:
1020 raise Error('File does not exist: %s' % options.file)
1021
henryhsuf6f835c2013-07-20 20:49:25 +08001022
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08001023def Main():
1024 """Run sub-command specified by the command line args."""
Andy Cheng7a76cb82012-11-19 18:08:19 +08001025
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08001026 options = ParseCmdline(
Ricky Liangc662be32013-12-24 11:50:23 +08001027 ('Perform Google required factory tests. All the HWID-related functions '
1028 'provided here are mainly for the deprecated HWID v2. To access HWID '
1029 'v3-related utilities, please use `hwid` command.'),
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08001030 CmdArg('-l', '--log', metavar='PATH',
1031 help='Write logs to this file.'),
Jon Salza4bea382012-10-29 13:00:34 +08001032 CmdArg('--suppress-event-logs', action='store_true',
1033 help='Suppress event logging.'),
Wei-Han Chenaff56232016-04-16 09:17:59 +08001034 CmdArg('--phase', default=None,
1035 help=('override phase for phase checking (defaults to the current '
1036 'as returned by the "factory phase" command)')),
Tammo Spalink8fab5312012-05-28 18:33:30 +08001037 verbosity_cmd_arg)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08001038 SetupLogging(options.verbosity, options.log)
Andy Cheng0465d132013-03-20 12:12:06 +08001039 event_log.SetGlobalLoggerDefaultPrefix('gooftool')
1040 event_log.GetGlobalLogger().suppress = options.suppress_event_logs
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08001041 logging.debug('gooftool options: %s', repr(options))
Wei-Han Chenaff56232016-04-16 09:17:59 +08001042
1043 phase.OverridePhase(options.phase)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08001044 try:
1045 logging.debug('GOOFTOOL command %r', options.command_name)
1046 options.command(options)
1047 logging.info('GOOFTOOL command %r SUCCESS', options.command_name)
1048 except Error, e:
1049 logging.exception(e)
1050 sys.exit('GOOFTOOL command %r ERROR: %s' % (options.command_name, e))
1051 except Exception, e:
1052 logging.exception(e)
1053 sys.exit('UNCAUGHT RUNTIME EXCEPTION %s' % e)
1054
1055
1056if __name__ == '__main__':
1057 Main()