blob: bff4f988fbc50d708e3cfb4f4da0f59de1ed71b9 [file] [log] [blame]
Yilin Yang19da6932019-12-10 13:39:28 +08001#!/usr/bin/env python3
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
Tammo Spalink9a96b8a2012-04-03 11:10:41 +08008"""Google Factory Tool.
9
You-Cheng Syu461ec032017-03-06 15:56:58 +080010This tool is intended to be used on factory assembly lines. It
Tammo Spalink9a96b8a2012-04-03 11:10:41 +080011provides all of the Google required test functionality and must be run
12on each device as part of the assembly process.
13"""
14
Yilin Yang71e39412019-09-24 09:26:46 +080015from __future__ import print_function
16
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
Peter Shihfdf17682017-05-26 11:38:39 +080022from tempfile import gettempdir
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080023import threading
Hung-Te Lin6bd16472012-06-20 16:26:47 +080024import time
Yilin Yange02d5722019-10-23 11:07:36 +080025import xmlrpc.client
Peter Shihfdf17682017-05-26 11:38:39 +080026
Wei-Han Chen0a3320e2016-04-23 01:32:07 +080027from cros.factory.gooftool.common import ExecFactoryPar
Hung-Te Lin0e0f9362015-11-18 18:18:05 +080028from cros.factory.gooftool.common import Shell
Peter Shihfdf17682017-05-26 11:38:39 +080029from cros.factory.gooftool.core import Gooftool
30from cros.factory.gooftool import crosfw
Peter Shihfdf17682017-05-26 11:38:39 +080031from cros.factory.gooftool import report_upload
Yong Hong65bda312018-12-13 20:05:58 +080032from cros.factory.gooftool import vpd
Hung-Te Lin604e0c22015-11-24 15:17:07 +080033from cros.factory.hwid.v3 import hwid_utils
Yong Hong863d3262017-10-30 16:23:34 +080034from cros.factory.probe.functions import chromeos_firmware
Wei-Han Chen2ebb92d2016-01-12 14:51:41 +080035from cros.factory.test.env import paths
Peter Shihfdf17682017-05-26 11:38:39 +080036from cros.factory.test import event_log
Wei-Han Chenaff56232016-04-16 09:17:59 +080037from cros.factory.test.rules import phase
Hung-Te Lin3f096842016-01-13 17:37:06 +080038from cros.factory.test.rules.privacy import FilterDict
Philip Chen6ada02c2019-11-04 19:41:54 +000039from cros.factory.test import state
Peter Shihfdf17682017-05-26 11:38:39 +080040from cros.factory.utils import argparse_utils
Hung-Te Lin03bf7ab2016-06-16 17:26:19 +080041from cros.factory.utils.argparse_utils import CmdArg
Hung-Te Lin03bf7ab2016-06-16 17:26:19 +080042from cros.factory.utils.argparse_utils import ParseCmdline
Wei-Han Chenb34bdff2019-09-26 13:07:50 +080043from cros.factory.utils.argparse_utils import VERBOSITY_CMD_ARG
Peter Shihfdf17682017-05-26 11:38:39 +080044from cros.factory.utils.debug_utils import SetupLogging
Jon Salz40b9f822014-07-25 16:39:55 +080045from cros.factory.utils import file_utils
Peter Shih67c7c0f2018-02-26 11:23:59 +080046from cros.factory.utils.process_utils import Spawn
Wei-Han Chena5c01a02016-04-23 19:27:19 +080047from cros.factory.utils import sys_utils
Chun-Ta Lin53cbbd52016-06-08 21:42:19 +080048from cros.factory.utils import time_utils
Joel Kitchingd3bc2662014-12-16 16:03:32 -080049from cros.factory.utils.type_utils import Error
Tammo Spalink86a61c62012-05-25 15:10:35 +080050
Tammo Spalink5c699832012-07-03 17:50:39 +080051
Tammo Spalink5c699832012-07-03 17:50:39 +080052# TODO(tammo): Replace calls to sys.exit with raise Exit, and maybe
53# treat that specially (as a smoot exit, as opposed to the more
54# verbose output for generic Error).
55
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080056_global_gooftool = None
57_gooftool_lock = threading.Lock()
Philip Chen04fb90b2019-11-06 12:10:33 -080058_has_fpmcu = None
Tammo Spalink5c699832012-07-03 17:50:39 +080059
Hung-Te Lin56b18402015-01-16 14:52:30 +080060
Ricky Lianga70a1202013-03-15 15:03:17 +080061def GetGooftool(options):
Peter Shihfdf17682017-05-26 11:38:39 +080062 global _global_gooftool # pylint: disable=global-statement
Ricky Lianga70a1202013-03-15 15:03:17 +080063
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080064 if _global_gooftool is None:
65 with _gooftool_lock:
Shen-En Shihc5d15d62017-08-04 13:02:59 +080066 if _global_gooftool is None:
67 project = getattr(options, 'project', None)
68 hwdb_path = getattr(options, 'hwdb_path', None)
69 _global_gooftool = Gooftool(hwid_version=3, project=project,
70 hwdb_path=hwdb_path)
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080071
72 return _global_gooftool
Ricky Lianga70a1202013-03-15 15:03:17 +080073
Philip Chen04fb90b2019-11-06 12:10:33 -080074def HasFpmcu():
75 global _has_fpmcu # pylint: disable=global-statement
76
77 if _has_fpmcu is None:
78 FPMCU_PATH = '/dev/cros_fp'
79 has_fpmcu_path = os.path.exists(FPMCU_PATH)
80 has_cros_config_fpmcu = False
Philip Chencf6642b2019-12-02 19:38:59 -080081 cros_config_output = Shell(['cros_config', '/fingerprint', 'board'])
82 if cros_config_output.success and cros_config_output.stdout:
Philip Chen04fb90b2019-11-06 12:10:33 -080083 has_cros_config_fpmcu = True
84
85 if has_fpmcu_path is False and has_cros_config_fpmcu is True:
86 raise Error('FPMCU found in cros_config but missing in %s.' % FPMCU_PATH)
Fei Shao0e4e2c62020-06-23 18:22:26 +080087 if has_fpmcu_path is True and has_cros_config_fpmcu is False:
Philip Chen04fb90b2019-11-06 12:10:33 -080088 raise Error('FPMCU found in %s but missing in cros_config.' % FPMCU_PATH)
89
90 _has_fpmcu = has_fpmcu_path
91
92 return _has_fpmcu
Hung-Te Lin56b18402015-01-16 14:52:30 +080093
Ting Shen18a06382016-08-30 16:18:21 +080094def Command(cmd_name, *args, **kwargs):
You-Cheng Syu8fc2a602017-12-22 17:05:05 +080095 """Decorator for commands in gooftool.
Ting Shen18a06382016-08-30 16:18:21 +080096
97 This is similar to argparse_utils.Command, but all gooftool commands
98 can be waived during `gooftool finalize` or `gooftool verify` using
Wei-Han Chen60c5d332017-01-05 17:15:10 +080099 --waive_list or --skip_list option.
Ting Shen18a06382016-08-30 16:18:21 +0800100 """
101 def Decorate(fun):
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800102 def CommandWithWaiveSkipCheck(options):
Ting Shen18a06382016-08-30 16:18:21 +0800103 waive_list = vars(options).get('waive_list', [])
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800104 skip_list = vars(options).get('skip_list', [])
105 if phase.GetPhase() >= phase.PVT_DOGFOOD and (
106 waive_list != [] or skip_list != []):
Ting Shen18a06382016-08-30 16:18:21 +0800107 raise Error(
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800108 'waive_list and skip_list should be empty for phase %s' %
109 phase.GetPhase())
Ting Shen18a06382016-08-30 16:18:21 +0800110
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800111 if cmd_name not in skip_list:
112 try:
113 fun(options)
114 except Exception as e:
115 if cmd_name in waive_list:
116 logging.exception(e)
117 else:
118 raise
Ting Shen18a06382016-08-30 16:18:21 +0800119
120 return argparse_utils.Command(cmd_name, *args, **kwargs)(
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800121 CommandWithWaiveSkipCheck)
Ting Shen18a06382016-08-30 16:18:21 +0800122 return Decorate
123
124
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800125@Command('write_hwid',
126 CmdArg('hwid', metavar='HWID', help='HWID string'))
Andy Chengc92e6f92012-11-20 16:55:53 +0800127def WriteHWID(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800128 """Write specified HWID value into the system BB."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800129
Tammo Spalink95c43732012-07-25 15:57:14 -0700130 logging.info('writing hwid string %r', options.hwid)
Ricky Lianga70a1202013-03-15 15:03:17 +0800131 GetGooftool(options).WriteHWID(options.hwid)
Andy Cheng0465d132013-03-20 12:12:06 +0800132 event_log.Log('write_hwid', hwid=options.hwid)
Yilin Yang71e39412019-09-24 09:26:46 +0800133 print('Wrote HWID: %r' % options.hwid)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800134
135
Yong Hongc3765412017-12-26 23:12:15 +0800136@Command('read_hwid')
137def ReadHWID(options):
138 """Read the HWID string from GBB."""
139
140 logging.info('reading the hwid string')
Yilin Yang71e39412019-09-24 09:26:46 +0800141 print(GetGooftool(options).ReadHWID())
Yong Hongc3765412017-12-26 23:12:15 +0800142
143
Yong Hong5408f652017-07-11 19:20:25 +0800144_project_cmd_arg = CmdArg(
145 '--project', metavar='PROJECT',
146 default=None, help='Project name to test.')
Ricky Liang53390232013-03-08 15:37:57 +0800147
Tammo Spalink8fab5312012-05-28 18:33:30 +0800148_hwdb_path_cmd_arg = CmdArg(
149 '--hwdb_path', metavar='PATH',
Yong Hong5c6dcd52017-12-27 11:05:01 +0800150 default=hwid_utils.GetDefaultDataPath(),
Tammo Spalink8fab5312012-05-28 18:33:30 +0800151 help='Path to the HWID database.')
152
Tammo Spalink95c43732012-07-25 15:57:14 -0700153_hwid_status_list_cmd_arg = CmdArg(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800154 '--status', nargs='*', default=['supported'],
155 help='allow only HWIDs with these status values')
Tammo Spalink95c43732012-07-25 15:57:14 -0700156
Jon Salzce124fb2012-10-02 17:42:03 +0800157_probe_results_cmd_arg = CmdArg(
Yong Hong55050c12018-02-27 18:19:47 +0800158 '--probe_results', metavar='RESULTS.json',
159 help=('Output from "hwid probe" (used instead of probing this system).'))
Jon Salzce124fb2012-10-02 17:42:03 +0800160
Ricky Liang53390232013-03-08 15:37:57 +0800161_device_info_cmd_arg = CmdArg(
Ricky Liangf89f73a2013-03-19 05:00:24 +0800162 '--device_info', metavar='DEVICE_INFO.yaml', default=None,
You-Cheng Syu8fc2a602017-12-22 17:05:05 +0800163 help='A dict of device info to use instead of fetching from shopfloor '
Ricky Liang53390232013-03-08 15:37:57 +0800164 'server.')
165
Jon Salzce124fb2012-10-02 17:42:03 +0800166_hwid_cmd_arg = CmdArg(
167 '--hwid', metavar='HWID',
Ricky Lianga70a1202013-03-15 15:03:17 +0800168 help='HWID to verify (instead of the currently set HWID of this system).')
Jon Salzce124fb2012-10-02 17:42:03 +0800169
Yong Hong68a0e0d2017-12-20 19:06:54 +0800170_hwid_run_vpd_cmd_arg = CmdArg(
171 '--hwid-run-vpd', action='store_true',
172 help=('Specify the hwid utility to obtain the vpd data by running the '
173 '`vpd` commandline tool.'))
174
175_hwid_vpd_data_file_cmd_arg = CmdArg(
176 '--hwid-vpd-data-file', metavar='FILE.json', type=str, default=None,
177 help=('Specify the hwid utility to obtain the vpd data from the specified '
178 'file.'))
179
Bernie Thompson3c11c872013-07-22 18:22:45 -0700180_rma_mode_cmd_arg = CmdArg(
181 '--rma_mode', action='store_true',
182 help='Enable RMA mode, do not check for deprecated components.')
Tammo Spalink95c43732012-07-25 15:57:14 -0700183
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800184_cros_core_cmd_arg = CmdArg(
185 '--cros_core', action='store_true',
186 help='Finalize for ChromeOS Core devices (may add or remove few test '
Hung-Te Lin53c49402017-07-26 13:10:58 +0800187 'items. For example, registration codes or firmware bitmap '
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800188 'locale settings).')
189
Pin-Yen Lin215b7542020-05-05 09:45:37 +0800190_has_ec_pubkey_cmd_arg = CmdArg(
191 '--has_ec_pubkey', action='store_true', default=None,
192 help='The device has EC public key for EFS and need to run VerifyECKey.')
Yilun Lin599833f2017-12-22 14:07:46 +0800193
bowgotsai13820f42015-09-10 23:18:04 +0800194_enforced_release_channels_cmd_arg = CmdArg(
195 '--enforced_release_channels', nargs='*', default=None,
196 help='Enforced release image channels.')
197
Yilun Lin34f54802017-11-16 11:58:25 +0800198_ec_pubkey_path_cmd_arg = CmdArg(
199 '--ec_pubkey_path',
200 default=None,
201 help='Path to public key in vb2 format. Verify EC key with pubkey file.')
202
203_ec_pubkey_hash_cmd_arg = CmdArg(
204 '--ec_pubkey_hash',
205 default=None,
206 help='A string for public key hash. Verify EC key with the given hash.')
207
Hung-Te Lincdb96522016-04-15 16:51:10 +0800208_release_rootfs_cmd_arg = CmdArg(
209 '--release_rootfs', help='Location of release image rootfs partition.')
210
211_firmware_path_cmd_arg = CmdArg(
212 '--firmware_path', help='Location of firmware image partition.')
Ricky Liang43b879b2014-02-24 11:36:55 +0800213
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800214_shopfloor_url_args_cmd_arg = CmdArg(
215 '--shopfloor_url',
Earl Ou51182222016-09-09 12:16:48 +0800216 help='Shopfloor server url to be informed when wiping is done. '
217 'After wiping, a XML-RPC request will be sent to the '
218 'given url to indicate the completion of wiping.')
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800219
220_station_ip_cmd_arg = CmdArg(
221 '--station_ip',
222 help='IP of remote station')
223
224_station_port_cmd_arg = CmdArg(
225 '--station_port',
226 help='Port on remote station')
227
228_wipe_finish_token_cmd_arg = CmdArg(
229 '--wipe_finish_token',
230 help='Required token when notifying station after wipe finished')
231
Wei-Han Chenf3924112019-02-25 14:52:58 +0800232_keep_developer_mode_flag_after_clobber_state_cmd_arg = CmdArg(
233 # The argument name is super long because you should never use it by
234 # yourself when using command line tools.
235 '--keep_developer_mode_flag_after_clobber_state',
236 action='store_true', default=None,
237 help='After clobber-state, do not delete .developer_mode')
238
Ting Shen18a06382016-08-30 16:18:21 +0800239_waive_list_cmd_arg = CmdArg(
240 '--waive_list', nargs='*', default=[], metavar='SUBCMD',
You-Cheng Syu8fc2a602017-12-22 17:05:05 +0800241 help='A list of waived checks, separated by whitespace. '
242 'Each item should be a sub-command of gooftool. '
Ting Shen18a06382016-08-30 16:18:21 +0800243 'e.g. "gooftool verify --waive_list verify_tpm clear_gbb_flags".')
244
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800245_skip_list_cmd_arg = CmdArg(
246 '--skip_list', nargs='*', default=[], metavar='SUBCMD',
You-Cheng Syu8fc2a602017-12-22 17:05:05 +0800247 help='A list of skipped checks, separated by whitespace. '
248 'Each item should be a sub-command of gooftool. '
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800249 'e.g. "gooftool verify --skip_list verify_tpm clear_gbb_flags".')
250
Meng-Huan Yu7a4f0f52020-01-07 20:11:01 +0800251_test_umount_cmd_arg = CmdArg(
252 '--test_umount', action='store_true',
253 help='(For testing only) Only umount rootfs and stateful partition '
254 'instead of running full wiping and cutoff process.')
255
Wei-Han Cheneb4f9a22018-03-09 14:52:23 +0800256_rlz_embargo_end_date_offset_cmd_arg = CmdArg(
Kevin Line4c64de2019-11-22 15:28:34 +0800257 '--embargo_offset', type=int, default=7, choices=list(range(7, 15)),
Wei-Han Cheneb4f9a22018-03-09 14:52:23 +0800258 help='Change the offset of embargo end date, cannot less than 7 days or '
259 'more than 14 days.')
260
Marco Chena681b2e2018-08-31 11:41:41 +0800261_no_ectool_cmd_arg = CmdArg(
262 '--no_ectool', action='store_false', dest='has_ectool',
263 help='There is no ectool utility so tests rely on ectool should be '
264 'skipped.')
Tammo Spalink8fab5312012-05-28 18:33:30 +0800265
chuntsenaf1232f2019-03-20 15:45:54 +0800266_no_generate_mfg_date_cmd_arg = CmdArg(
267 '--no_generate_mfg_date', action='store_false', dest='generate_mfg_date',
268 help='Do not generate manufacturing date nor write mfg_date into VPD.')
269
270
Yilun Lin34f54802017-11-16 11:58:25 +0800271@Command(
272 'verify_ec_key',
273 _ec_pubkey_path_cmd_arg,
274 _ec_pubkey_hash_cmd_arg)
275def VerifyECKey(options):
276 """Verify EC key."""
277 return GetGooftool(options).VerifyECKey(
278 options.ec_pubkey_path, options.ec_pubkey_hash)
279
280
Hung-Te Line1d80f62016-03-31 14:58:13 +0800281@Command('verify_keys',
Hung-Te Lincdb96522016-04-15 16:51:10 +0800282 _release_rootfs_cmd_arg,
283 _firmware_path_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800284def VerifyKeys(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800285 """Verify keys in firmware and SSD match."""
Hung-Te Line1d80f62016-03-31 14:58:13 +0800286 return GetGooftool(options).VerifyKeys(
Hung-Te Lincdb96522016-04-15 16:51:10 +0800287 options.release_rootfs, options.firmware_path)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800288
289
290@Command('set_fw_bitmap_locale')
Peter Shihfdf17682017-05-26 11:38:39 +0800291def SetFirmwareBitmapLocale(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800292 """Use VPD locale value to set firmware bitmap default language."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800293
Ricky Lianga70a1202013-03-15 15:03:17 +0800294 (index, locale) = GetGooftool(options).SetFirmwareBitmapLocale()
Andy Cheng2582d292012-12-04 17:38:28 +0800295 logging.info('Firmware bitmap initial locale set to %d (%s).',
296 index, locale)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800297
298
Hung-Te Line1d80f62016-03-31 14:58:13 +0800299@Command('verify_system_time',
Wei-Han Chen2790d2e2019-01-18 21:13:40 +0800300 _release_rootfs_cmd_arg,
301 _rma_mode_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800302def VerifySystemTime(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800303 """Verify system time is later than release filesystem creation time."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800304
Wei-Han Chen2790d2e2019-01-18 21:13:40 +0800305 return GetGooftool(options).VerifySystemTime(options.release_rootfs,
306 rma_mode=options.rma_mode)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800307
308
Hung-Te Line1d80f62016-03-31 14:58:13 +0800309@Command('verify_rootfs',
Hung-Te Lincdb96522016-04-15 16:51:10 +0800310 _release_rootfs_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800311def VerifyRootFs(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800312 """Verify rootfs on SSD is valid by checking hash."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800313
Hung-Te Line1d80f62016-03-31 14:58:13 +0800314 return GetGooftool(options).VerifyRootFs(options.release_rootfs)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800315
Hung-Te Lin56b18402015-01-16 14:52:30 +0800316
Cheng-Yi Chiang676b5292013-06-18 12:05:33 +0800317@Command('verify_tpm')
Peter Shihfdf17682017-05-26 11:38:39 +0800318def VerifyTPM(options):
Cheng-Yi Chiang676b5292013-06-18 12:05:33 +0800319 """Verify TPM is cleared."""
320
321 return GetGooftool(options).VerifyTPM()
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800322
Hung-Te Lin56b18402015-01-16 14:52:30 +0800323
Hung-Te Lindd708d42014-07-11 17:05:01 +0800324@Command('verify_me_locked')
Peter Shihfdf17682017-05-26 11:38:39 +0800325def VerifyManagementEngineLocked(options):
You-Cheng Syu461ec032017-03-06 15:56:58 +0800326 """Verify Management Engine is locked."""
Hung-Te Lindd708d42014-07-11 17:05:01 +0800327
328 return GetGooftool(options).VerifyManagementEngineLocked()
329
Hung-Te Lin56b18402015-01-16 14:52:30 +0800330
Marco Chena681b2e2018-08-31 11:41:41 +0800331@Command('verify_switch_wp',
332 _no_ectool_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800333def VerifyWPSwitch(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800334 """Verify hardware write protection switch is enabled."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800335
Marco Chena681b2e2018-08-31 11:41:41 +0800336 GetGooftool(options).VerifyWPSwitch(options.has_ectool)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800337
338
Hung-Te Lin53c49402017-07-26 13:10:58 +0800339@Command('verify_vpd')
340def VerifyVPD(options):
341 """Verify that VPD values are properly set.
Jon Salzadd90d32014-04-29 16:16:27 +0800342
Hung-Te Lin53c49402017-07-26 13:10:58 +0800343 Check if mandatory fields are set, and deprecated fields don't exist.
Jon Salzadd90d32014-04-29 16:16:27 +0800344 """
Hung-Te Lin53c49402017-07-26 13:10:58 +0800345 return GetGooftool(options).VerifyVPD()
Jon Salzadd90d32014-04-29 16:16:27 +0800346
347
bowgotsai13820f42015-09-10 23:18:04 +0800348@Command('verify_release_channel',
349 _enforced_release_channels_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800350def VerifyReleaseChannel(options):
bowgotsai529139c2015-05-30 01:39:49 +0800351 """Verify that release image channel is correct.
352
353 ChromeOS has four channels: canary, dev, beta and stable.
354 The last three channels support image auto-updates, checks
355 that release image channel is one of them.
356 """
bowgotsai13820f42015-09-10 23:18:04 +0800357 return GetGooftool(options).VerifyReleaseChannel(
358 options.enforced_release_channels)
bowgotsai529139c2015-05-30 01:39:49 +0800359
360
Wei-Han Chen0de7cfd2020-01-03 16:49:20 +0800361@Command('verify_cros_config')
362def VerifyCrosConfig(options):
363 """Verify entries in cros config make sense."""
364 return GetGooftool(options).VerifyCrosConfig()
365
366
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800367@Command('write_protect')
Peter Shihfdf17682017-05-26 11:38:39 +0800368def EnableFwWp(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800369 """Enable then verify firmware write protection."""
Peter Shihfdf17682017-05-26 11:38:39 +0800370 del options # Unused.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800371
Yong Hongdad230a2017-08-30 22:25:19 +0800372 def WriteProtect(fw):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800373 """Calculate protection size, then invoke flashrom.
374
Yong Hongdad230a2017-08-30 22:25:19 +0800375 The region (offset and size) to write protect may be different per chipset
376 and firmware layout, so we have to read the WP_RO section from FMAP to
377 decide that.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800378 """
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800379 wp_section = 'WP_RO'
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800380
Yong Hongdad230a2017-08-30 22:25:19 +0800381 fmap_image = fw.GetFirmwareImage(
382 sections=(['FMAP'] if fw.target == crosfw.TARGET_MAIN else None))
383 if not fmap_image.has_section(wp_section):
384 raise Error('Could not find %s firmware section: %s' %
385 (fw.target.upper(), wp_section))
386
387 section_data = fw.GetFirmwareImage(
388 sections=[wp_section]).get_section_area(wp_section)
Peter Shihe6afab32018-09-11 17:16:48 +0800389 ro_offset, ro_size = section_data[0:2]
Yong Hongdad230a2017-08-30 22:25:19 +0800390
391 logging.debug('write protecting %s [off=%x size=%x]', fw.target.upper(),
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800392 ro_offset, ro_size)
Yong Hongdad230a2017-08-30 22:25:19 +0800393 crosfw.Flashrom(fw.target).EnableWriteProtection(ro_offset, ro_size)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800394
Philip Chendbb06202019-11-05 17:24:26 -0800395 if HasFpmcu():
396 # TODO(b/143991572): Implement enable_fpmcu_write_protection in gooftool.
397 cmd = os.path.join(
398 paths.FACTORY_DIR, 'sh', 'enable_fpmcu_write_protection.sh')
399 cmd_result = Shell(cmd)
400 if not cmd_result.success:
401 raise Error(
402 'Failed to enable FPMCU write protection, stdout=%r, stderr=%r' %
403 (cmd_result.stdout, cmd_result.stderr))
404
Yong Hongdad230a2017-08-30 22:25:19 +0800405 WriteProtect(crosfw.LoadMainFirmware())
Andy Cheng0465d132013-03-20 12:12:06 +0800406 event_log.Log('wp', fw='main')
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800407
Fei Shao21be8242020-04-13 16:57:51 +0800408 # Some EC (mostly PD) does not support "RO_NOW". Instead they will only set
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800409 # "RO_AT_BOOT" when you request to enable RO (These platforms consider
410 # --wp-range with right range identical to --wp-enable), and requires a
411 # 'ectool reboot_ec RO at-shutdown; reboot' to let the RO take effect.
Hung-Te Lin0d10b562016-12-28 10:58:07 +0800412 # After reboot, "flashrom -p host --wp-status" will return protected range.
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800413 # If you don't reboot, returned range will be (0, 0), and running command
414 # "ectool flashprotect" will not have RO_NOW.
Fei Shao21be8242020-04-13 16:57:51 +0800415 # generic_common.test_list.json provides "EnableECWriteProtect" test group
416 # which can be run individually before finalization. Try that out if you're
417 # having trouble enabling RO_NOW flag.
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800418
Yong Hongdad230a2017-08-30 22:25:19 +0800419 for fw in [crosfw.LoadEcFirmware(), crosfw.LoadPDFirmware()]:
420 if fw.GetChipId() is None:
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800421 logging.warning('%s not write protected (seems there is no %s flash).',
Yong Hongdad230a2017-08-30 22:25:19 +0800422 fw.target.upper(), fw.target.upper())
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800423 continue
Yong Hongdad230a2017-08-30 22:25:19 +0800424 WriteProtect(fw)
425 event_log.Log('wp', fw=fw.target)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800426
427
428@Command('clear_gbb_flags')
Peter Shihfdf17682017-05-26 11:38:39 +0800429def ClearGBBFlags(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800430 """Zero out the GBB flags, in preparation for transition to release state.
431
432 No GBB flags are set in release/shipping state, but they are useful
Hung-Te Lin879cff42017-06-19 12:46:37 +0800433 for factory/development. See "futility gbb --flags" for details.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800434 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800435
Ricky Lianga70a1202013-03-15 15:03:17 +0800436 GetGooftool(options).ClearGBBFlags()
Andy Cheng0465d132013-03-20 12:12:06 +0800437 event_log.Log('clear_gbb_flags')
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800438
439
Jon Salzaa3a30e2013-05-15 15:56:28 +0800440@Command('clear_factory_vpd_entries')
Peter Shihfdf17682017-05-26 11:38:39 +0800441def ClearFactoryVPDEntries(options):
Jon Salzaa3a30e2013-05-15 15:56:28 +0800442 """Clears factory.* items in the RW VPD."""
443 entries = GetGooftool(options).ClearFactoryVPDEntries()
444 event_log.Log('clear_factory_vpd_entries', entries=FilterDict(entries))
445
446
Mattias Nisslercca761b2015-04-15 21:53:04 +0200447@Command('generate_stable_device_secret')
Peter Shihfdf17682017-05-26 11:38:39 +0800448def GenerateStableDeviceSecret(options):
You-Cheng Syu461ec032017-03-06 15:56:58 +0800449 """Generates a fresh stable device secret and stores it in the RO VPD."""
Mattias Nisslercca761b2015-04-15 21:53:04 +0200450 GetGooftool(options).GenerateStableDeviceSecret()
451 event_log.Log('generate_stable_device_secret')
452
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800453
Stimim Chenda9e62c2020-05-14 15:43:18 +0800454@Command('cr50_set_sn_bits_and_board_id',
455 _rma_mode_cmd_arg)
Yves Arrouyeb49b31e2019-03-06 21:51:52 -0800456def Cr50SetSnBitsAndBoardId(options):
Wei-Han Chen66357592020-01-14 15:15:37 +0800457 """Deprecated: use Cr50WriteFlashInfo instead."""
458 logging.warning('This function is renamed to Cr50WriteFlashInfo')
459 Cr50WriteFlashInfo(options)
460
461
Stimim Chen60f7bb22020-04-07 21:02:47 +0800462@Command('cr50_write_flash_info',
Stimim Chenda9e62c2020-05-14 15:43:18 +0800463 _rma_mode_cmd_arg,
Stimim Chen60f7bb22020-04-07 21:02:47 +0800464 CmdArg('--expect_zero_touch', action='store_true',
465 help='zero touch feature is expected, the command will fail '
466 'immediately if required dependencies are not found.'))
Wei-Han Chen66357592020-01-14 15:15:37 +0800467def Cr50WriteFlashInfo(options):
Yves Arrouyeb49b31e2019-03-06 21:51:52 -0800468 """Set the serial number bits, board id and flags on the Cr50 chip."""
Stimim Chen60f7bb22020-04-07 21:02:47 +0800469 # The '--expect_zero_touch' argument is for testing purpose, therefore, the
470 # argument can only be specified by directly using `cr50_write_flash_info`
471 # subcommand. And the `expect_zero_touch` attribute won't exist when this
472 # function is invoked by other subcommands, e.g. `finalize`.
473 expect_zero_touch = getattr(options, 'expect_zero_touch', False)
Stimim Chenda9e62c2020-05-14 15:43:18 +0800474 GetGooftool(options).Cr50WriteFlashInfo(expect_zero_touch, options.rma_mode)
Wei-Han Chen66357592020-01-14 15:15:37 +0800475 event_log.Log('cr50_write_flash_info')
476
477
478@Command('cr50_write_whitelabel_flags')
479def Cr50WriteWhitelabelFlags(options):
480 GetGooftool(options).Cr50WriteWhitelabelFlags()
481 event_log.Log('cr50_write_whitelabel_flags')
Shen-En Shihd078a7c2017-08-04 13:33:49 +0800482
483
Marco Chen20c885d2018-10-04 17:22:03 +0800484@Command('cr50_disable_factory_mode')
Marco Chen44a666d2018-07-13 21:01:50 +0800485def Cr50DisableFactoryMode(options):
Cheng-Han Yang08333af2017-12-18 17:22:38 +0800486 """Reset Cr50 state back to default state after RMA."""
Marco Chen44a666d2018-07-13 21:01:50 +0800487 return GetGooftool(options).Cr50DisableFactoryMode()
Cheng-Han Yang08333af2017-12-18 17:22:38 +0800488
489
Earl Ou564a7872016-10-05 10:22:00 +0800490@Command('enable_release_partition',
491 CmdArg('--release_rootfs',
492 help=('path to the release rootfs device. If not specified, '
493 'the default (5th) partition will be used.')))
494def EnableReleasePartition(options):
495 """Enables a release image partition on the disk."""
496 GetGooftool(options).EnableReleasePartition(options.release_rootfs)
497
498
Shun-Hsing Oucdc64e12015-01-14 22:07:33 +0800499@Command('wipe_in_place',
500 CmdArg('--fast', action='store_true',
Shun-Hsing Ou8d3c40a2015-10-08 18:16:08 +0800501 help='use non-secure but faster wipe method.'),
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800502 _shopfloor_url_args_cmd_arg,
503 _station_ip_cmd_arg,
504 _station_port_cmd_arg,
Meng-Huan Yu7a4f0f52020-01-07 20:11:01 +0800505 _wipe_finish_token_cmd_arg,
506 _test_umount_cmd_arg)
Shun-Hsing Oucdc64e12015-01-14 22:07:33 +0800507def WipeInPlace(options):
508 """Start factory wipe directly without reboot."""
509
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800510 GetGooftool(options).WipeInPlace(options.fast,
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800511 options.shopfloor_url,
512 options.station_ip,
513 options.station_port,
Meng-Huan Yu7a4f0f52020-01-07 20:11:01 +0800514 options.wipe_finish_token,
515 options.test_umount)
Mattias Nisslercca761b2015-04-15 21:53:04 +0200516
Wei-Han Chen7dc6d132016-04-06 11:11:53 +0800517@Command('wipe_init',
Wei-Han Chen0a3320e2016-04-23 01:32:07 +0800518 CmdArg('--wipe_args', help='arguments for clobber-state'),
519 CmdArg('--state_dev', help='path to stateful partition device'),
520 CmdArg('--root_disk', help='path to primary device'),
521 CmdArg('--old_root', help='path to old root'),
Wei-Han Chen0a3320e2016-04-23 01:32:07 +0800522 _shopfloor_url_args_cmd_arg,
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800523 _release_rootfs_cmd_arg,
524 _station_ip_cmd_arg,
525 _station_port_cmd_arg,
Wei-Han Chenf3924112019-02-25 14:52:58 +0800526 _wipe_finish_token_cmd_arg,
Meng-Huan Yu7a4f0f52020-01-07 20:11:01 +0800527 _keep_developer_mode_flag_after_clobber_state_cmd_arg,
528 _test_umount_cmd_arg)
Wei-Han Chen7dc6d132016-04-06 11:11:53 +0800529def WipeInit(options):
Wei-Han Chenf3924112019-02-25 14:52:58 +0800530 GetGooftool(options).WipeInit(
531 options.wipe_args,
532 options.shopfloor_url,
533 options.state_dev,
534 options.release_rootfs,
535 options.root_disk,
536 options.old_root,
537 options.station_ip,
538 options.station_port,
539 options.wipe_finish_token,
Meng-Huan Yu7a4f0f52020-01-07 20:11:01 +0800540 options.keep_developer_mode_flag_after_clobber_state,
541 options.test_umount)
Wei-Han Chen7dc6d132016-04-06 11:11:53 +0800542
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800543@Command('verify',
Hung-Te Lin6d827542012-07-19 11:50:41 +0800544 CmdArg('--no_write_protect', action='store_true',
545 help='Do not check write protection switch state.'),
Tammo Spalink95c43732012-07-25 15:57:14 -0700546 _hwid_status_list_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800547 _hwdb_path_cmd_arg,
Yong Hong5408f652017-07-11 19:20:25 +0800548 _project_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800549 _probe_results_cmd_arg,
Cheng-Yi Chiang406ad912013-11-14 16:51:33 +0800550 _hwid_cmd_arg,
Yong Hong68a0e0d2017-12-20 19:06:54 +0800551 _hwid_run_vpd_cmd_arg,
552 _hwid_vpd_data_file_cmd_arg,
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800553 _rma_mode_cmd_arg,
bowgotsai13820f42015-09-10 23:18:04 +0800554 _cros_core_cmd_arg,
Pin-Yen Lin215b7542020-05-05 09:45:37 +0800555 _has_ec_pubkey_cmd_arg,
Yilun Lin34f54802017-11-16 11:58:25 +0800556 _ec_pubkey_path_cmd_arg,
557 _ec_pubkey_hash_cmd_arg,
Hung-Te Lincdb96522016-04-15 16:51:10 +0800558 _release_rootfs_cmd_arg,
559 _firmware_path_cmd_arg,
Ting Shen18a06382016-08-30 16:18:21 +0800560 _enforced_release_channels_cmd_arg,
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800561 _waive_list_cmd_arg,
Marco Chena681b2e2018-08-31 11:41:41 +0800562 _skip_list_cmd_arg,
563 _no_ectool_cmd_arg)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800564def Verify(options):
565 """Verifies if whole factory process is ready for finalization.
566
567 This routine performs all the necessary checks to make sure the
568 device is ready to be finalized, but does not modify state. These
569 checks include dev switch, firmware write protection switch, hwid,
570 system time, keys, and root file system.
571 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800572
Hung-Te Lin6d827542012-07-19 11:50:41 +0800573 if not options.no_write_protect:
Ricky Lianga70a1202013-03-15 15:03:17 +0800574 VerifyWPSwitch(options)
Hung-Te Lindd708d42014-07-11 17:05:01 +0800575 VerifyManagementEngineLocked(options)
Ting Shen129fa6f2016-09-02 12:22:24 +0800576 VerifyHWID(options)
Ricky Lianga70a1202013-03-15 15:03:17 +0800577 VerifySystemTime(options)
Pin-Yen Lin215b7542020-05-05 09:45:37 +0800578 if options.has_ec_pubkey:
Yilun Lin599833f2017-12-22 14:07:46 +0800579 VerifyECKey(options)
Ricky Lianga70a1202013-03-15 15:03:17 +0800580 VerifyKeys(options)
581 VerifyRootFs(options)
Cheng-Yi Chiang676b5292013-06-18 12:05:33 +0800582 VerifyTPM(options)
Hung-Te Lin53c49402017-07-26 13:10:58 +0800583 VerifyVPD(options)
bowgotsai529139c2015-05-30 01:39:49 +0800584 VerifyReleaseChannel(options)
Wei-Han Chen0de7cfd2020-01-03 16:49:20 +0800585 VerifyCrosConfig(options)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800586
Hung-Te Lin56b18402015-01-16 14:52:30 +0800587
Jon Salzfe9036f2014-01-16 14:11:23 +0800588@Command('untar_stateful_files')
Hung-Te Lin388bce22014-06-03 19:56:40 +0800589def UntarStatefulFiles(unused_options):
Jon Salzfe9036f2014-01-16 14:11:23 +0800590 """Untars stateful files from stateful_files.tar.xz on stateful partition.
591
592 If that file does not exist (which should only be R30 and earlier),
593 this is a no-op.
594 """
Hung-Te Lin2333f3f2016-08-24 17:56:48 +0800595 # Path to stateful partition on device.
596 device_stateful_path = '/mnt/stateful_partition'
597 tar_file = os.path.join(device_stateful_path, 'stateful_files.tar.xz')
Jon Salzfe9036f2014-01-16 14:11:23 +0800598 if os.path.exists(tar_file):
Hung-Te Lin2333f3f2016-08-24 17:56:48 +0800599 Spawn(['tar', 'xf', tar_file], cwd=device_stateful_path,
Jon Salzfe9036f2014-01-16 14:11:23 +0800600 log=True, check_call=True)
601 else:
602 logging.warning('No stateful files at %s', tar_file)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800603
Jon Salz40b9f822014-07-25 16:39:55 +0800604
605@Command('log_source_hashes')
Peter Shihfdf17682017-05-26 11:38:39 +0800606def LogSourceHashes(options):
Jon Salz40b9f822014-07-25 16:39:55 +0800607 """Logs hashes of source files in the factory toolkit."""
Peter Shihfdf17682017-05-26 11:38:39 +0800608 del options # Unused.
Jon Salze60307f2014-08-05 16:20:00 +0800609 # WARNING: The following line is necessary to validate the integrity
610 # of the factory software. Do not remove or modify it.
611 #
612 # 警告:此行会验证工厂软件的完整性,禁止删除或修改。
Wei-Han Chena5c01a02016-04-23 19:27:19 +0800613 factory_par = sys_utils.GetRunningFactoryPythonArchivePath()
614 if factory_par:
615 event_log.Log(
616 'source_hashes',
617 **file_utils.HashPythonArchive(factory_par))
618 else:
619 event_log.Log(
620 'source_hashes',
Peter Shihad166772017-05-31 11:36:17 +0800621 **file_utils.HashSourceTree(os.path.join(paths.FACTORY_DIR, 'py')))
Jon Salz40b9f822014-07-25 16:39:55 +0800622
623
Tammo Spalink86a61c62012-05-25 15:10:35 +0800624@Command('log_system_details')
Peter Shihfdf17682017-05-26 11:38:39 +0800625def LogSystemDetails(options):
Tammo Spalink86a61c62012-05-25 15:10:35 +0800626 """Write miscellaneous system details to the event log."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800627
Ricky Liang43b879b2014-02-24 11:36:55 +0800628 event_log.Log('system_details', **GetGooftool(options).GetSystemDetails())
Tammo Spalink86a61c62012-05-25 15:10:35 +0800629
630
Jon Salza88b83b2013-05-27 20:00:35 +0800631def CreateReportArchiveBlob(*args, **kwargs):
632 """Creates a report archive and returns it as a blob.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800633
Jon Salza88b83b2013-05-27 20:00:35 +0800634 Args:
635 See CreateReportArchive.
Andy Cheng7a76cb82012-11-19 18:08:19 +0800636
Jon Salza88b83b2013-05-27 20:00:35 +0800637 Returns:
Yilin Yange02d5722019-10-23 11:07:36 +0800638 An xmlrpc.client.Binary object containing a .tar.xz file.
Jon Salza88b83b2013-05-27 20:00:35 +0800639 """
Wei-Han Chen47416612016-09-14 17:41:52 +0800640 report_archive = CreateReportArchive(*args, **kwargs)
641 try:
Yilin Yangf6994c22019-12-09 16:17:21 +0800642 return xmlrpc.client.Binary(
643 file_utils.ReadFile(report_archive, encoding=None))
Wei-Han Chen47416612016-09-14 17:41:52 +0800644 finally:
645 os.unlink(report_archive)
Jon Salza88b83b2013-05-27 20:00:35 +0800646
647
648def CreateReportArchive(device_sn=None, add_file=None):
649 """Creates a report archive in a temporary directory.
650
651 Args:
652 device_sn: The device serial number (optional).
653 add_file: A list of files to add (optional).
654
655 Returns:
656 Path to the archive.
657 """
Philip Chen6ada02c2019-11-04 19:41:54 +0000658 # Flush Testlog data to DATA_TESTLOG_DIR before creating a report archive.
659 result, reason = state.GetInstance().FlushTestlog(
660 uplink=False, local=True, timeout=10)
661 if not result:
662 logging.warning('Failed to flush testlog data: %s', reason)
663
Hung-Te Lin6bd16472012-06-20 16:26:47 +0800664 def NormalizeAsFileName(token):
665 return re.sub(r'\W+', '', token).strip()
Jon Salza88b83b2013-05-27 20:00:35 +0800666
667 target_name = '%s%s.tar.xz' % (
668 time.strftime('%Y%m%dT%H%M%SZ',
669 time.gmtime()),
Hung-Te Lin56b18402015-01-16 14:52:30 +0800670 ('' if device_sn is None else
671 '_' + NormalizeAsFileName(device_sn)))
Tammo Spalink86a61c62012-05-25 15:10:35 +0800672 target_path = os.path.join(gettempdir(), target_name)
Jon Salza88b83b2013-05-27 20:00:35 +0800673
Tammo Spalink86a61c62012-05-25 15:10:35 +0800674 # Intentionally ignoring dotfiles in EVENT_LOG_DIR.
Pi-Hsun Shih1f569a72019-12-26 11:23:56 +0800675 tar_cmd = 'cd %s ; tar cJf %s * -C /' % (event_log.EVENT_LOG_DIR, target_path)
Jongpil Jung23355a92019-12-31 14:38:29 +0900676 tar_files = [paths.FACTORY_LOG_PATH, paths.DATA_TESTLOG_DIR]
677 if add_file:
678 tar_files = tar_files + add_file
Pi-Hsun Shih1f569a72019-12-26 11:23:56 +0800679 for f in tar_files:
680 # Require absolute paths since we use -C / to change current directory to
681 # root.
682 if not f.startswith('/'):
683 raise Error('Not an absolute path: %s' % f)
684 if not os.path.exists(f):
685 raise Error('File does not exist: %s' % f)
686 tar_cmd += ' %s' % pipes.quote(f[1:])
Tammo Spalink86a61c62012-05-25 15:10:35 +0800687 cmd_result = Shell(tar_cmd)
Jon Salzff88c022012-11-03 12:19:58 +0800688
Hung-Te Lin3756c432020-01-16 11:30:46 +0800689 if cmd_result.status == 1:
690 # tar returns 1 when some files were changed during archiving,
691 # but that is expected for log files so should ignore such failure
692 # if the archive looks good.
Pi-Hsun Shih1f569a72019-12-26 11:23:56 +0800693 Spawn(['tar', 'tJf', target_path], check_call=True, log=True,
Jon Salzff88c022012-11-03 12:19:58 +0800694 ignore_stdout=True)
695 elif not cmd_result.success:
Tammo Spalink86a61c62012-05-25 15:10:35 +0800696 raise Error('unable to tar event logs, cmd %r failed, stderr: %r' %
697 (tar_cmd, cmd_result.stderr))
Jon Salzff88c022012-11-03 12:19:58 +0800698
Jon Salza88b83b2013-05-27 20:00:35 +0800699 return target_path
700
701_upload_method_cmd_arg = CmdArg(
702 '--upload_method', metavar='METHOD:PARAM',
703 help=('How to perform the upload. METHOD should be one of '
Kevin Line4c64de2019-11-22 15:28:34 +0800704 '{ftp, shopfloor, ftps, cpfe, smb}.'))
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800705_upload_max_retry_times_arg = CmdArg(
706 '--upload_max_retry_times', type=int, default=0,
707 help='Number of tries to upload. 0 to retry infinitely.')
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800708_upload_retry_interval_arg = CmdArg(
709 '--upload_retry_interval', type=int, default=None,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800710 help='Retry interval in seconds.')
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800711_upload_allow_fail_arg = CmdArg(
712 '--upload_allow_fail', action='store_true',
713 help='Continue finalize if report upload fails.')
Jon Salza88b83b2013-05-27 20:00:35 +0800714_add_file_cmd_arg = CmdArg(
715 '--add_file', metavar='FILE', action='append',
716 help='Extra file to include in report (must be an absolute path)')
717
Hung-Te Lin56b18402015-01-16 14:52:30 +0800718
Jon Salza88b83b2013-05-27 20:00:35 +0800719@Command('upload_report',
720 _upload_method_cmd_arg,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800721 _upload_max_retry_times_arg,
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800722 _upload_retry_interval_arg,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800723 _upload_allow_fail_arg,
Jon Salza88b83b2013-05-27 20:00:35 +0800724 _add_file_cmd_arg)
725def UploadReport(options):
726 """Create a report containing key device details."""
Yong Hong65bda312018-12-13 20:05:58 +0800727 ro_vpd = vpd.VPDTool().GetAllData(partition=vpd.VPD_READONLY_PARTITION_NAME)
Jon Salza88b83b2013-05-27 20:00:35 +0800728 device_sn = ro_vpd.get('serial_number', None)
729 if device_sn is None:
730 logging.warning('RO_VPD missing device serial number')
Chun-Ta Lin53cbbd52016-06-08 21:42:19 +0800731 device_sn = 'MISSING_SN_' + time_utils.TimedUUID()
chuntsena6da2be2019-08-14 17:11:55 +0800732 target_path = CreateReportArchive(device_sn, options.add_file)
Jon Salza88b83b2013-05-27 20:00:35 +0800733
Tammo Spalink86a61c62012-05-25 15:10:35 +0800734 if options.upload_method is None or options.upload_method == 'none':
735 logging.warning('REPORT UPLOAD SKIPPED (report left at %s)', target_path)
736 return
737 method, param = options.upload_method.split(':', 1)
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800738
739 if options.upload_retry_interval is not None:
740 retry_interval = options.upload_retry_interval
741 else:
742 retry_interval = report_upload.DEFAULT_RETRY_INTERVAL
743
Tammo Spalink86a61c62012-05-25 15:10:35 +0800744 if method == 'shopfloor':
You-Cheng Syuf0f4be12017-12-05 16:33:53 +0800745 report_upload.ShopFloorUpload(
746 target_path, param,
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800747 'GRT' if options.command_name == 'finalize' else None,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800748 max_retry_times=options.upload_max_retry_times,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800749 retry_interval=retry_interval,
750 allow_fail=options.upload_allow_fail)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800751 elif method == 'ftp':
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800752 report_upload.FtpUpload(target_path, 'ftp:' + param,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800753 max_retry_times=options.upload_max_retry_times,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800754 retry_interval=retry_interval,
755 allow_fail=options.upload_allow_fail)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800756 elif method == 'ftps':
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800757 report_upload.CurlUrlUpload(target_path, '--ftp-ssl-reqd ftp:%s' % param,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800758 max_retry_times=options.upload_max_retry_times,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800759 retry_interval=retry_interval,
760 allow_fail=options.upload_allow_fail)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800761 elif method == 'cpfe':
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800762 report_upload.CpfeUpload(target_path, pipes.quote(param),
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800763 max_retry_times=options.upload_max_retry_times,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800764 retry_interval=retry_interval,
765 allow_fail=options.upload_allow_fail)
Kevin Line4c64de2019-11-22 15:28:34 +0800766 elif method == 'smb':
767 # param should be in form: <dest_path>.
768 report_upload.SmbUpload(target_path, 'smb:' + param,
769 max_retry_times=options.upload_max_retry_times,
770 retry_interval=retry_interval,
771 allow_fail=options.upload_allow_fail)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800772 else:
Peter Shihbf6f22b2018-02-26 14:05:28 +0800773 raise Error('unknown report upload method %r' % method)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800774
775
776@Command('finalize',
Hung-Te Lin6d827542012-07-19 11:50:41 +0800777 CmdArg('--no_write_protect', action='store_true',
778 help='Do not enable firmware write protection.'),
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800779 CmdArg('--fast', action='store_true',
780 help='use non-secure but faster wipe method.'),
Yong Hongb2926bd2018-10-12 14:11:14 +0800781 _no_ectool_cmd_arg,
Shun-Hsing Oudb407d62015-11-11 11:03:59 +0800782 _shopfloor_url_args_cmd_arg,
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800783 _hwdb_path_cmd_arg,
Tammo Spalink95c43732012-07-25 15:57:14 -0700784 _hwid_status_list_cmd_arg,
Jon Salz65266432012-07-30 19:02:49 +0800785 _upload_method_cmd_arg,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800786 _upload_max_retry_times_arg,
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800787 _upload_retry_interval_arg,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800788 _upload_allow_fail_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800789 _add_file_cmd_arg,
790 _probe_results_cmd_arg,
Cheng-Yi Chiang406ad912013-11-14 16:51:33 +0800791 _hwid_cmd_arg,
Yong Hong68a0e0d2017-12-20 19:06:54 +0800792 _hwid_run_vpd_cmd_arg,
793 _hwid_vpd_data_file_cmd_arg,
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800794 _rma_mode_cmd_arg,
bowgotsai13820f42015-09-10 23:18:04 +0800795 _cros_core_cmd_arg,
Pin-Yen Lin215b7542020-05-05 09:45:37 +0800796 _has_ec_pubkey_cmd_arg,
Yilun Lin34f54802017-11-16 11:58:25 +0800797 _ec_pubkey_path_cmd_arg,
798 _ec_pubkey_hash_cmd_arg,
Hung-Te Lincdb96522016-04-15 16:51:10 +0800799 _release_rootfs_cmd_arg,
800 _firmware_path_cmd_arg,
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800801 _enforced_release_channels_cmd_arg,
802 _station_ip_cmd_arg,
803 _station_port_cmd_arg,
Ting Shen18a06382016-08-30 16:18:21 +0800804 _wipe_finish_token_cmd_arg,
Wei-Han Cheneb4f9a22018-03-09 14:52:23 +0800805 _rlz_embargo_end_date_offset_cmd_arg,
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800806 _waive_list_cmd_arg,
chuntsenaf1232f2019-03-20 15:45:54 +0800807 _skip_list_cmd_arg,
Philip Chen04fb90b2019-11-06 12:10:33 -0800808 _no_generate_mfg_date_cmd_arg)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800809def Finalize(options):
810 """Verify system readiness and trigger transition into release state.
811
Jon Salzaa3a30e2013-05-15 15:56:28 +0800812 This routine does the following:
813 - Verifies system state (see verify command)
Jon Salzfe9036f2014-01-16 14:11:23 +0800814 - Untars stateful_files.tar.xz, if it exists, in the stateful partition, to
815 initialize files such as the CRX cache
Jon Salzaa3a30e2013-05-15 15:56:28 +0800816 - Modifies firmware bitmaps to match locale
817 - Clears all factory-friendly flags from the GBB
818 - Removes factory-specific entries from RW_VPD (factory.*)
819 - Enables firmware write protection (cannot rollback after this)
Marco Chenecee04f2019-02-15 22:24:24 +0800820 - Initialize Fpmcu entropy
Jon Salzaa3a30e2013-05-15 15:56:28 +0800821 - Uploads system logs & reports
Earl Ou51182222016-09-09 12:16:48 +0800822 - Wipes the testing kernel, rootfs, and stateful partition
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800823 """
Wei-Han Cheneb4f9a22018-03-09 14:52:23 +0800824 if not options.rma_mode:
825 # Write VPD values related to RLZ ping into VPD.
826 GetGooftool(options).WriteVPDForRLZPing(options.embargo_offset)
chuntsenaf1232f2019-03-20 15:45:54 +0800827 if options.generate_mfg_date:
828 GetGooftool(options).WriteVPDForMFGDate()
Wei-Han Chen66357592020-01-14 15:15:37 +0800829 Cr50WriteFlashInfo(options)
Marco Chen44a666d2018-07-13 21:01:50 +0800830 Cr50DisableFactoryMode(options)
Marco Chen9d0631c2018-08-31 10:52:44 +0800831 Verify(options)
Jon Salz40b9f822014-07-25 16:39:55 +0800832 LogSourceHashes(options)
Jon Salzfe9036f2014-01-16 14:11:23 +0800833 UntarStatefulFiles(options)
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800834 if options.cros_core:
835 logging.info('SetFirmwareBitmapLocale is skipped for ChromeOS Core device.')
836 else:
837 SetFirmwareBitmapLocale(options)
Jon Salzaa3a30e2013-05-15 15:56:28 +0800838 ClearFactoryVPDEntries(options)
Mattias Nisslercca761b2015-04-15 21:53:04 +0200839 GenerateStableDeviceSecret(options)
Shen-En Shih3e079b22017-09-11 05:43:09 -0700840 ClearGBBFlags(options)
Hung-Te Lin6d827542012-07-19 11:50:41 +0800841 if options.no_write_protect:
Pi-Hsun Shih1f569a72019-12-26 11:23:56 +0800842 logging.warning('WARNING: Firmware Write Protection is SKIPPED.')
Andy Cheng0465d132013-03-20 12:12:06 +0800843 event_log.Log('wp', fw='both', status='skipped')
Hung-Te Lin6d827542012-07-19 11:50:41 +0800844 else:
Wei-Han Chenba21f512016-10-14 18:52:33 +0800845 EnableFwWp(options)
Marco Chenecee04f2019-02-15 22:24:24 +0800846 FpmcuInitializeEntropy(options)
Jon Salza0f58e02012-05-29 19:33:39 +0800847 LogSystemDetails(options)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800848 UploadReport(options)
Earl Ou51182222016-09-09 12:16:48 +0800849
850 event_log.Log('wipe_in_place')
851 wipe_args = []
Earl Ou51182222016-09-09 12:16:48 +0800852 if options.shopfloor_url:
853 wipe_args += ['--shopfloor_url', options.shopfloor_url]
854 if options.fast:
855 wipe_args += ['--fast']
856 if options.station_ip:
857 wipe_args += ['--station_ip', options.station_ip]
858 if options.station_port:
859 wipe_args += ['--station_port', options.station_port]
860 if options.wipe_finish_token:
861 wipe_args += ['--wipe_finish_token', options.wipe_finish_token]
862 ExecFactoryPar('gooftool', 'wipe_in_place', *wipe_args)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800863
864
Ting Shen129fa6f2016-09-02 12:22:24 +0800865@Command('verify_hwid',
866 _probe_results_cmd_arg,
867 _hwdb_path_cmd_arg,
868 _hwid_cmd_arg,
Yong Hong68a0e0d2017-12-20 19:06:54 +0800869 _hwid_run_vpd_cmd_arg,
870 _hwid_vpd_data_file_cmd_arg,
Ting Shen129fa6f2016-09-02 12:22:24 +0800871 _rma_mode_cmd_arg)
872def VerifyHWID(options):
Ricky Liangc662be32013-12-24 11:50:23 +0800873 """A simple wrapper that calls out to HWID utils to verify version 3 HWID.
Ricky Liang53390232013-03-08 15:37:57 +0800874
Ricky Liangc662be32013-12-24 11:50:23 +0800875 This is mainly for Gooftool to verify v3 HWID during finalize. For testing
876 and development purposes, please use `hwid` command.
Ricky Liang53390232013-03-08 15:37:57 +0800877 """
Yong Hongada8e0e2018-01-04 16:36:21 +0800878 database = GetGooftool(options).db
Yong Hong68a0e0d2017-12-20 19:06:54 +0800879
Yong Hongada8e0e2018-01-04 16:36:21 +0800880 encoded_string = options.hwid or GetGooftool(options).ReadHWID()
881
882 probed_results = hwid_utils.GetProbedResults(infile=options.probe_results)
Yong Hong2c39bf22018-01-24 22:24:11 +0800883 device_info = hwid_utils.GetDeviceInfo()
Yong Hong65bda312018-12-13 20:05:58 +0800884 vpd_data = hwid_utils.GetVPDData(run_vpd=options.hwid_run_vpd,
885 infile=options.hwid_vpd_data_file)
Ricky Liang53390232013-03-08 15:37:57 +0800886
Hung-Te Lin11052952015-03-18 13:48:59 +0800887 event_log.Log('probed_results', probed_results=FilterDict(probed_results))
Yong Hong65bda312018-12-13 20:05:58 +0800888 event_log.Log('vpd', vpd=FilterDict(vpd_data))
Ricky Liang53390232013-03-08 15:37:57 +0800889
Yong Hong2c39bf22018-01-24 22:24:11 +0800890 hwid_utils.VerifyHWID(database, encoded_string, probed_results,
Yong Hong65bda312018-12-13 20:05:58 +0800891 device_info, vpd_data, options.rma_mode)
Ricky Liang53390232013-03-08 15:37:57 +0800892
Ricky Liangc662be32013-12-24 11:50:23 +0800893 event_log.Log('verified_hwid', hwid=encoded_string)
Ricky Liang53390232013-03-08 15:37:57 +0800894
895
henryhsu44d793a2013-07-20 00:07:38 +0800896@Command('get_firmware_hash',
Marco Chence70b132018-05-03 23:43:39 +0800897 CmdArg('--file', required=True, metavar='FILE', help='Firmware File.'))
henryhsu44d793a2013-07-20 00:07:38 +0800898def GetFirmwareHash(options):
henryhsuf6f835c2013-07-20 20:49:25 +0800899 """Get firmware hash from a file"""
henryhsu44d793a2013-07-20 00:07:38 +0800900 if os.path.exists(options.file):
Cheng-Han Yang2c668ae2018-04-18 22:31:07 +0800901 value_dict = chromeos_firmware.CalculateFirmwareHashes(options.file)
Yilin Yang879fbda2020-05-14 13:52:30 +0800902 for key, value in value_dict.items():
Yilin Yang71e39412019-09-24 09:26:46 +0800903 print(' %s: %s' % (key, value))
henryhsu44d793a2013-07-20 00:07:38 +0800904 else:
905 raise Error('File does not exist: %s' % options.file)
906
henryhsuf6f835c2013-07-20 20:49:25 +0800907
Philip Chen04fb90b2019-11-06 12:10:33 -0800908@Command('fpmcu_initialize_entropy')
Marco Chenecee04f2019-02-15 22:24:24 +0800909def FpmcuInitializeEntropy(options):
910 """Initialze entropy of FPMCU."""
Philip Chen04fb90b2019-11-06 12:10:33 -0800911
912 if HasFpmcu():
Marco Chenecee04f2019-02-15 22:24:24 +0800913 GetGooftool(options).FpmcuInitializeEntropy()
Philip Chen04fb90b2019-11-06 12:10:33 -0800914 else:
915 logging.info('No FPS on this board.')
Marco Chenecee04f2019-02-15 22:24:24 +0800916
917
Peter Shihfdf17682017-05-26 11:38:39 +0800918def main():
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800919 """Run sub-command specified by the command line args."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800920
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800921 options = ParseCmdline(
Ting Shen129fa6f2016-09-02 12:22:24 +0800922 'Perform Google required factory tests.',
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800923 CmdArg('-l', '--log', metavar='PATH',
924 help='Write logs to this file.'),
Jon Salza4bea382012-10-29 13:00:34 +0800925 CmdArg('--suppress-event-logs', action='store_true',
926 help='Suppress event logging.'),
Wei-Han Chenaff56232016-04-16 09:17:59 +0800927 CmdArg('--phase', default=None,
928 help=('override phase for phase checking (defaults to the current '
929 'as returned by the "factory phase" command)')),
Wei-Han Chenb34bdff2019-09-26 13:07:50 +0800930 VERBOSITY_CMD_ARG)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800931 SetupLogging(options.verbosity, options.log)
Andy Cheng0465d132013-03-20 12:12:06 +0800932 event_log.SetGlobalLoggerDefaultPrefix('gooftool')
933 event_log.GetGlobalLogger().suppress = options.suppress_event_logs
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800934 logging.debug('gooftool options: %s', repr(options))
Wei-Han Chenaff56232016-04-16 09:17:59 +0800935
936 phase.OverridePhase(options.phase)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800937 try:
938 logging.debug('GOOFTOOL command %r', options.command_name)
939 options.command(options)
940 logging.info('GOOFTOOL command %r SUCCESS', options.command_name)
Peter Shih6674ecf2018-03-29 14:04:57 +0800941 except Error as e:
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800942 logging.exception(e)
943 sys.exit('GOOFTOOL command %r ERROR: %s' % (options.command_name, e))
Peter Shih6674ecf2018-03-29 14:04:57 +0800944 except Exception as e:
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800945 logging.exception(e)
946 sys.exit('UNCAUGHT RUNTIME EXCEPTION %s' % e)
947
948
949if __name__ == '__main__':
Peter Shihfdf17682017-05-26 11:38:39 +0800950 main()