gooftool: Remove hwid v2 functions, add command verify_hwid for v3.
As discussed in CL:377579, we would like to add verify_hwid_v3 as a
command to make it waivable.
1. Remove hwid v2 related functions, gooftool only supports hwid v3 now.
2. Add VerifyHWIDv3 as a command: 'verify_hwid'.
BUG=None
TEST=Run `gooftool verify` and `gooftool verify_hwid`
CQ-DEPEND=CL:377579
Change-Id: Ia9509dea05fef0c8df6521a5c3b02aaadc74f847
Reviewed-on: https://chromium-review.googlesource.com/380420
Commit-Ready: Ting Shen <phoenixshen@chromium.org>
Tested-by: Ting Shen <phoenixshen@chromium.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
diff --git a/py/gooftool/commands.py b/py/gooftool/commands.py
index aadcee7..0da0653 100755
--- a/py/gooftool/commands.py
+++ b/py/gooftool/commands.py
@@ -33,12 +33,9 @@
from cros.factory.gooftool.core import Gooftool
from cros.factory.gooftool.common import ExecFactoryPar
from cros.factory.gooftool.common import Shell
-from cros.factory.gooftool.probe import Probe, PROBEABLE_COMPONENT_CLASSES
-from cros.factory.gooftool.probe import ReadRoVpd, ReadRwVpd
+from cros.factory.gooftool.probe import Probe
+from cros.factory.gooftool.probe import ReadRoVpd
from cros.factory.gooftool.probe import CalculateFirmwareHashes
-from cros.factory.gooftool.vpd_data import KNOWN_VPD_FIELD_DATA
-from cros.factory.hwid.v2 import hwid_tool
-from cros.factory.hwid.v2.yaml_datastore import YamlWrite
from cros.factory.hwid.v3 import common
from cros.factory.hwid.v3 import hwid_utils
from cros.factory.test import event_log
@@ -70,20 +67,10 @@
if _global_gooftool is None:
with _gooftool_lock:
- hwid_version = getattr(options, 'hwid_version', 3)
- if hwid_version == 2:
- hwdb_path = getattr(options, 'hwdb_path', None)
- component_db = (
- hwid_tool.HardwareDb(options.hwdb_path).comp_db if hwdb_path
- else None)
- _global_gooftool = Gooftool(hwid_version=2, component_db=component_db)
- elif hwid_version == 3:
- board = getattr(options, 'board', None)
- hwdb_path = getattr(options, 'hwdb_path', None)
- _global_gooftool = Gooftool(hwid_version=3, board=board,
- hwdb_path=hwdb_path)
- else:
- raise Error, 'Invalid HWID version: %r' % options.hwid_version
+ board = getattr(options, 'board', None)
+ hwdb_path = getattr(options, 'hwdb_path', None)
+ _global_gooftool = Gooftool(hwid_version=3, board=board,
+ hwdb_path=hwdb_path)
return _global_gooftool
@@ -163,10 +150,6 @@
'items. For example, branding verification or firmware bitmap '
'locale settings).')
-_hwid_version_cmd_arg = CmdArg(
- '-i', '--hwid-version', default=3, choices=(2, 3), type=int,
- help='Version of HWID to operate on. (default: %(default)s)')
-
_enforced_release_channels_cmd_arg = CmdArg(
'--enforced_release_channels', nargs='*', default=None,
help='Enforced release image channels.')
@@ -212,182 +195,6 @@
'Each item should be a sub-command of gooftool.'
'e.g. "gooftool verify --waive_list verify_tpm clear_gbb_flags".')
-@Command('best_match_hwids',
- _hwdb_path_cmd_arg,
- CmdArg('-b', '--board', metavar='BOARD',
- help='optional BOARD name, needed only if data is present '
- 'for more than one'),
- CmdArg('--bom', metavar='BOM', help='BOM name'),
- CmdArg('--variant', metavar='VARIANT', help='VARIANT code'),
- CmdArg('--optimistic', action='store_true',
- help='do not probe; assume singletons match'),
- CmdArg('--comps', nargs='*', default=[],
- help='list of canonical component names'),
- CmdArg('--missing', nargs='*', default=[],
- help='list component classes to be assumed missing'),
- CmdArg('--status', nargs='*', default=['supported'],
- help='consider only HWIDs within this list of status values'))
-def BestMatchHwids(options):
- """Determine a list of possible HWIDs using provided args and probing.
-
- VOLATILE can always be determined by probing. To get a unique
- result, VARIANT must be specified for all cases where the matching
- BOM has more than one associated variant code, otherwise all HWID
- variants will be returned. Both VARIANT and BOM information can
- alternatively be specified using the --stdin_comps argument, which
- allows specifying a list of canonical names (one per line) on stdin,
- one per line. Based on what is known from BOM and stdin_comps,
- determine a list of components to probe for, and use those probe
- results to resolve a list of matching HWIDs. If no boms,
- components, or variant codes are specified, then a list of all HWIDs
- that match probeable components will be returned.
-
- Returns (on stdout): A list of HWIDs that match the available probe
- results and argument contraints, one per line.
-
- Example:
-
- // Three ways to specify a keyboard (assuming it is a variant component)
- gooftool best_match_hwids --missing keyboard
- gooftool best_match_hwids --variant A or
- gooftool best_match_hwids --comps us_kbd
- """
-
- map(hwid_tool.Validate.Status, options.status)
- hw_db = hwid_tool.HardwareDb(options.hwdb_path)
- comp_db = hw_db.comp_db
- device = hw_db.GetDevice(options.board)
- component_spec = hwid_tool.ComponentSpec.New()
- if options.bom:
- device.BomExists(options.bom)
- component_spec = hwid_tool.CombineComponentSpecs(
- component_spec, device.boms[options.bom].primary)
- if options.variant:
- device.VariantExists(options.variant)
- variant_spec = device.variants[options.variant]
- if hwid_tool.ComponentSpecsConflict(component_spec, variant_spec):
- sys.exit('ERROR: multiple specifications for these components:\n%s'
- % YamlWrite(sorted(
- hwid_tool.ComponentSpecClasses(component_spec) &
- hwid_tool.ComponentSpecClasses(variant_spec))))
- component_spec = hwid_tool.CombineComponentSpecs(
- component_spec, variant_spec)
- if options.comps or options.missing:
- map(comp_db.CompExists, options.comps)
- map(comp_db.CompClassExists, options.missing)
- extra_comp_spec = comp_db.CreateComponentSpec(
- components=options.comps,
- missing=options.missing)
- print 'cmdline asserted components:\n%s' % extra_comp_spec.Encode()
- if hwid_tool.ComponentSpecsConflict(component_spec, extra_comp_spec):
- sys.exit('ERROR: multiple specifications for these components:\n%s'
- % YamlWrite(sorted(
- hwid_tool.ComponentSpecClasses(component_spec) &
- hwid_tool.ComponentSpecClasses(extra_comp_spec))))
- component_spec = hwid_tool.CombineComponentSpecs(
- component_spec, extra_comp_spec)
- spec_classes = hwid_tool.ComponentSpecClasses(component_spec)
- missing_classes = set(comp_db.all_comp_classes) - spec_classes
- if missing_classes and not options.optimistic:
- non_probeable_missing = missing_classes - PROBEABLE_COMPONENT_CLASSES
- if non_probeable_missing:
- sys.exit('FAILURE: these classes are necessary, were not specified '
- 'as inputs, and cannot be probed for:\n%s'
- 'This problem can often be addressed by specifying all of '
- 'the missing components on the command line (see the command '
- 'help).' % YamlWrite(list(non_probeable_missing)))
- print 'probing for missing classes:'
- print YamlWrite(list(missing_classes))
- probe_results = Probe(target_comp_classes=list(missing_classes),
- probe_volatile=False, probe_initial_config=False)
- cooked_components = comp_db.MatchComponentProbeValues(
- probe_results.found_probe_value_map)
- if cooked_components.unmatched:
- sys.exit('ERROR: some probed components are unrecognized:\n%s'
- % YamlWrite(cooked_components.unmatched))
- probed_comp_spec = comp_db.CreateComponentSpec(
- components=cooked_components.matched,
- missing=probe_results.missing_component_classes)
- component_spec = hwid_tool.CombineComponentSpecs(
- component_spec, probed_comp_spec)
- print YamlWrite({'component data used for matching': {
- 'missing component classes': component_spec.classes_missing,
- 'found components': component_spec.components}})
- component_data = hwid_tool.ComponentData(
- extant_components=hwid_tool.ComponentSpecCompClassMap(
- component_spec).keys(),
- classes_missing=component_spec.classes_missing)
- match_tree = device.BuildMatchTree(component_data)
- if not match_tree:
- sys.exit('FAILURE: NO matching BOMs found')
- print 'potential BOMs/VARIANTs:'
- potential_variants = set()
- potential_volatiles = set()
- for bom_name, variant_tree in match_tree.items():
- print ' BOM: %-8s VARIANTS: %s' % (
- bom_name, ', '.join(sorted(variant_tree)))
- for variant_code in variant_tree:
- potential_variants.add(variant_code)
- for volatile_code in device.volatiles:
- status = device.GetHwidStatus(bom_name, variant_code, volatile_code)
- if status in options.status:
- potential_volatiles.add(volatile_code)
- print ''
- if len(potential_variants) == 0:
- sys.exit('FAILURE: no matching VARIANTs found')
- if len(potential_volatiles) == 0:
- sys.exit('FAILURE: no VOLATILEs found for potential matching BOMs/VARIANTS '
- '(with specified status)')
- if (options.optimistic and
- len(match_tree) == 1 and
- len(potential_variants) == 1 and
- len(potential_volatiles) == 1):
- print ('MATCHING HWID: %s' % device.FmtHwid(match_tree.keys().pop(),
- potential_variants.pop(),
- potential_volatiles.pop()))
- return
- print ('probing VOLATILEs to resolve potential matches: %s\n' %
- ', '.join(sorted(potential_volatiles)))
- vol_probe_results = Probe(
- target_comp_classes=[],
- probe_volatile=True,
- probe_initial_config=False)
- cooked_volatiles = device.MatchVolatileValues(
- vol_probe_results.found_volatile_values)
- match_tree = device.BuildMatchTree(
- component_data, cooked_volatiles.matched_tags)
- matched_hwids = device.GetMatchTreeHwids(match_tree)
- if matched_hwids:
- for hwid in matched_hwids:
- if matched_hwids[hwid] in options.status:
- print 'MATCHING HWID: %s' % hwid
- return
- print 'exact HWID matching failed, but the following BOMs match: %s' % (
- ', '.join(sorted(match_tree)))
- if options.optimistic and len(match_tree) == 1:
- bom_name = set(match_tree).pop()
- bom = device.boms[bom_name]
- variant_matches = match_tree[bom_name]
- if len(variant_matches) == 1:
- var_code = set(variant_matches).pop()
- elif len(bom.variants) == 1:
- var_code = set(bom.variants).pop()
- else:
- sys.exit('FAILURE: NO matching HWIDs found; optimistic matching failed '
- 'because there were too many variants to choose from for BOM %r'
- % bom_name)
- hwids = [device.FmtHwid(bom_name, var_code, vol_code)
- for vol_code in device.volatiles
- if device.GetHwidStatus(bom_name, var_code, vol_code)
- in options.status]
- for hwid in hwids:
- print 'MATCHING HWID: %s' % hwid
- return
- else:
- print ('optimistic matching not attempted because either it was '
- 'not requested, or because the number of BOMs was <> 1\n')
- sys.exit('FAILURE: NO matching HWIDs found')
-
@Command('probe',
CmdArg('--comps', nargs='*',
@@ -457,129 +264,6 @@
print '\ncomponent verification SUCCESS'
-@Command('verify_hwid_v2',
- _hwid_status_list_cmd_arg,
- _hwdb_path_cmd_arg,
- _probe_results_cmd_arg,
- _hwid_cmd_arg)
-def VerifyHWIDv2(options):
- """Verify system HWID properties match probed device properties.
-
- First probe components, volatile and initial_config parameters for
- the DUT. Then use the available device data to produce a list of
- candidate HWIDs. Then verify the HWID from the DUT is present in
- that list. Then verify that the DUT initial config values match
- those specified for its HWID. Finally, verify that VPD contains all
- the necessary fields as specified by the board data, and when
- possible verify that values are legitimate.
- """
- def VerifyVpd(ro_vpd_keys, rw_vpd_keys):
- for key in ro_vpd_keys:
- if key not in ro_vpd:
- sys.exit('Missing required RO VPD field: %s' % key)
- known_valid_values = KNOWN_VPD_FIELD_DATA.get(key, None)
- value = ro_vpd[key]
- if (known_valid_values is not None) and (value not in known_valid_values):
- sys.exit('Invalid RO VPD entry : key %r, value %r' % (key, value))
- for key in rw_vpd_keys:
- if key not in rw_vpd:
- sys.exit('Missing required RW VPD field: %s' % key)
- known_valid_values = KNOWN_VPD_FIELD_DATA.get(key, None)
- value = rw_vpd[key]
- if (known_valid_values is not None) and (value not in known_valid_values):
- sys.exit('Invalid RW VPD entry : key %r, value %r' % (key, value))
- event_log.Log('vpd', ro_vpd=FilterDict(ro_vpd), rw_vpd=FilterDict(rw_vpd))
- map(hwid_tool.Validate.Status, options.status)
-
- if options.hwid:
- hwid_str = options.hwid
- else:
- main_fw_file = crosfw.LoadMainFirmware().GetFileName()
- gbb_result = Shell('gbb_utility -g --hwid %s' % main_fw_file).stdout
- hwid_str = re.findall(r'hardware_id:(.*)', gbb_result)[0].strip()
- hwid = hwid_tool.ParseHwid(hwid_str)
- hw_db = hwid_tool.HardwareDb(options.hwdb_path)
- print 'Verifying HWID: %r\n' % hwid.hwid
- device = hw_db.GetDevice(hwid.board)
- hwid_status = device.GetHwidStatus(hwid.bom, hwid.variant, hwid.volatile)
- if hwid_status not in options.status:
- sys.exit('HWID status must be one of [%s], found %r' %
- (', '.join(options.status), hwid_status))
- if options.probe_results:
- # Pull in probe results (including VPD data) from the given file
- # rather than probing the current system.
- probe_results = hwid_tool.ProbeResults.Decode(
- open(options.probe_results).read())
- ro_vpd = {}
- rw_vpd = {}
- for k, v in probe_results.found_volatile_values.items():
- match = re.match(r'^vpd\.(ro|rw)\.(\w+)$', k)
- if match:
- del probe_results.found_volatile_values[k]
- (ro_vpd if match.group(1) == 'ro' else rw_vpd)[match.group(2)] = v
- else:
- probe_results = Probe()
- ro_vpd = ReadRoVpd()
- rw_vpd = ReadRwVpd()
- cooked_components = hw_db.comp_db.MatchComponentProbeValues(
- probe_results.found_probe_value_map)
- cooked_volatiles = device.MatchVolatileValues(
- probe_results.found_volatile_values)
- cooked_initial_configs = device.MatchInitialConfigValues(
- probe_results.initial_configs)
- component_data = hwid_tool.ComponentData(
- extant_components=cooked_components.matched,
- classes_missing=probe_results.missing_component_classes)
- match_tree = device.BuildMatchTree(
- component_data, cooked_volatiles.matched_tags)
- matched_hwids = device.GetMatchTreeHwids(match_tree)
- print 'HWID status: %s\n' % hwid_status
- print 'probed system components:'
- print YamlWrite(cooked_components.__dict__)
- print 'missing component classes:'
- print YamlWrite(probe_results.missing_component_classes)
- print 'probed volatiles:'
- print YamlWrite(cooked_volatiles.__dict__)
- print 'probed initial_configs:'
- print YamlWrite(cooked_initial_configs)
- print 'hwid match tree:'
- print YamlWrite(match_tree)
- event_log.Log(
- 'probe',
- found_components=cooked_components.__dict__,
- missing_component_classes=probe_results.missing_component_classes,
- volatiles=cooked_volatiles.__dict__,
- initial_configs=cooked_initial_configs)
- if hwid.hwid not in matched_hwids:
- err_msg = 'HWID verification FAILED.\n'
- if cooked_components.unmatched:
- sys.exit(err_msg + 'some components could not be indentified:\n%s' %
- YamlWrite(cooked_components.unmatched))
- if not match_tree:
- sys.exit(err_msg + 'no matching boms were found for components:\n%s' %
- component_data.Encode())
- if hwid.bom not in match_tree:
- sys.exit(err_msg + 'matching boms [%s] do not include target bom %r' %
- (', '.join(sorted(match_tree)), hwid.bom))
- err_msg += 'target bom %r matches components' % hwid.bom
- if hwid.bom not in device.IntersectBomsAndInitialConfigs(
- cooked_initial_configs):
- sys.exit(err_msg + ', but failed initial config verification')
- matched_variants = match_tree.get(hwid.bom, {})
- if hwid.variant not in matched_variants:
- sys.exit(err_msg + ', but target variant_code %r did not match' %
- hwid.variant)
- matched_volatiles = matched_variants.get(hwid.variant, {})
- if hwid.volatile not in matched_volatiles:
- sys.exit(err_msg + ', but target volatile_code %r did not match' %
- hwid.volatile)
- found_status = matched_volatiles.get(hwid.volatile, None)
- sys.exit(err_msg + ', but hwid status %r was unacceptable' % found_status)
- VerifyVpd(device.vpd_ro_fields, device.vpd_rw_fields)
- event_log.Log('verified_hwid', hwid=hwid)
- print 'Verification SUCCESS!'
-
-
@Command('verify_keys',
_release_rootfs_cmd_arg,
_firmware_path_cmd_arg)
@@ -799,7 +483,6 @@
@Command('verify',
CmdArg('--no_write_protect', action='store_true',
help='Do not check write protection switch state.'),
- _hwid_version_cmd_arg,
_hwid_status_list_cmd_arg,
_hwdb_path_cmd_arg,
_board_cmd_arg,
@@ -824,12 +507,7 @@
VerifyWPSwitch(options)
VerifyManagementEngineLocked(options)
VerifyDevSwitch(options)
- if options.hwid_version == 2:
- VerifyHWIDv2(options)
- elif options.hwid_version == 3:
- VerifyHWIDv3(options)
- else:
- raise Error, 'Invalid HWID version: %r' % options.hwid_version
+ VerifyHWID(options)
VerifySystemTime(options)
VerifyKeys(options)
VerifyRootFs(options)
@@ -990,7 +668,6 @@
help='Start factory wiping in place without reboot.'),
_cutoff_args_cmd_arg,
_shopfloor_url_args_cmd_arg,
- _hwid_version_cmd_arg,
_hwdb_path_cmd_arg,
_hwid_status_list_cmd_arg,
_upload_method_cmd_arg,
@@ -1060,7 +737,12 @@
PrepareWipe(options)
-def VerifyHWIDv3(options):
+@Command('verify_hwid',
+ _probe_results_cmd_arg,
+ _hwdb_path_cmd_arg,
+ _hwid_cmd_arg,
+ _rma_mode_cmd_arg)
+def VerifyHWID(options):
"""A simple wrapper that calls out to HWID utils to verify version 3 HWID.
This is mainly for Gooftool to verify v3 HWID during finalize. For testing
@@ -1129,9 +811,7 @@
"""Run sub-command specified by the command line args."""
options = ParseCmdline(
- ('Perform Google required factory tests. All the HWID-related functions '
- 'provided here are mainly for the deprecated HWID v2. To access HWID '
- 'v3-related utilities, please use `hwid` command.'),
+ 'Perform Google required factory tests.',
CmdArg('-l', '--log', metavar='PATH',
help='Write logs to this file.'),
CmdArg('--suppress-event-logs', action='store_true',