blob: 969d1a13e867459dcf909f9e0c700ecf304c2332 [file] [log] [blame]
Mike Frysinger63bb3c72019-09-01 15:16:26 -04001#!/usr/bin/env python2
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
Jon Salza88b83b2013-05-27 20:00:35 +080025import xmlrpclib
Peter Shihfdf17682017-05-26 11:38:39 +080026
Peter Shihfdf17682017-05-26 11:38:39 +080027import factory_common # pylint: disable=unused-import
Wei-Han Chen0a3320e2016-04-23 01:32:07 +080028from cros.factory.gooftool.common import ExecFactoryPar
Hung-Te Lin0e0f9362015-11-18 18:18:05 +080029from cros.factory.gooftool.common import Shell
Peter Shihfdf17682017-05-26 11:38:39 +080030from cros.factory.gooftool.core import Gooftool
31from cros.factory.gooftool import crosfw
Peter Shihfdf17682017-05-26 11:38:39 +080032from cros.factory.gooftool import report_upload
Yong Hong65bda312018-12-13 20:05:58 +080033from cros.factory.gooftool import vpd
Hung-Te Lin604e0c22015-11-24 15:17:07 +080034from cros.factory.hwid.v3 import hwid_utils
Yong Hong863d3262017-10-30 16:23:34 +080035from cros.factory.probe.functions import chromeos_firmware
Wei-Han Chen2ebb92d2016-01-12 14:51:41 +080036from cros.factory.test.env import paths
Peter Shihfdf17682017-05-26 11:38:39 +080037from cros.factory.test import event_log
Wei-Han Chenaff56232016-04-16 09:17:59 +080038from cros.factory.test.rules import phase
Hung-Te Lin3f096842016-01-13 17:37:06 +080039from cros.factory.test.rules.privacy import FilterDict
chuntsen2b43cc22019-07-18 15:26:16 +080040from cros.factory.test import state
Peter Shihfdf17682017-05-26 11:38:39 +080041from cros.factory.utils import argparse_utils
Hung-Te Lin03bf7ab2016-06-16 17:26:19 +080042from cros.factory.utils.argparse_utils import CmdArg
Hung-Te Lin03bf7ab2016-06-16 17:26:19 +080043from cros.factory.utils.argparse_utils import ParseCmdline
Wei-Han Chenb34bdff2019-09-26 13:07:50 +080044from cros.factory.utils.argparse_utils import VERBOSITY_CMD_ARG
Peter Shihfdf17682017-05-26 11:38:39 +080045from cros.factory.utils.debug_utils import SetupLogging
Jon Salz40b9f822014-07-25 16:39:55 +080046from cros.factory.utils import file_utils
Peter Shih67c7c0f2018-02-26 11:23:59 +080047from cros.factory.utils.process_utils import Spawn
Wei-Han Chena5c01a02016-04-23 19:27:19 +080048from cros.factory.utils import sys_utils
Chun-Ta Lin53cbbd52016-06-08 21:42:19 +080049from cros.factory.utils import time_utils
Joel Kitchingd3bc2662014-12-16 16:03:32 -080050from cros.factory.utils.type_utils import Error
Tammo Spalink86a61c62012-05-25 15:10:35 +080051
Tammo Spalink5c699832012-07-03 17:50:39 +080052
Tammo Spalink5c699832012-07-03 17:50:39 +080053# TODO(tammo): Replace calls to sys.exit with raise Exit, and maybe
54# treat that specially (as a smoot exit, as opposed to the more
55# verbose output for generic Error).
56
Cheng-Yi Chiang9fc121c2014-01-27 11:23:22 +080057_global_gooftool = None
58_gooftool_lock = threading.Lock()
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
Hung-Te Lin56b18402015-01-16 14:52:30 +080074
Ting Shen18a06382016-08-30 16:18:21 +080075def Command(cmd_name, *args, **kwargs):
You-Cheng Syu8fc2a602017-12-22 17:05:05 +080076 """Decorator for commands in gooftool.
Ting Shen18a06382016-08-30 16:18:21 +080077
78 This is similar to argparse_utils.Command, but all gooftool commands
79 can be waived during `gooftool finalize` or `gooftool verify` using
Wei-Han Chen60c5d332017-01-05 17:15:10 +080080 --waive_list or --skip_list option.
Ting Shen18a06382016-08-30 16:18:21 +080081 """
82 def Decorate(fun):
Wei-Han Chen60c5d332017-01-05 17:15:10 +080083 def CommandWithWaiveSkipCheck(options):
Ting Shen18a06382016-08-30 16:18:21 +080084 waive_list = vars(options).get('waive_list', [])
Wei-Han Chen60c5d332017-01-05 17:15:10 +080085 skip_list = vars(options).get('skip_list', [])
86 if phase.GetPhase() >= phase.PVT_DOGFOOD and (
87 waive_list != [] or skip_list != []):
Ting Shen18a06382016-08-30 16:18:21 +080088 raise Error(
Wei-Han Chen60c5d332017-01-05 17:15:10 +080089 'waive_list and skip_list should be empty for phase %s' %
90 phase.GetPhase())
Ting Shen18a06382016-08-30 16:18:21 +080091
Wei-Han Chen60c5d332017-01-05 17:15:10 +080092 if cmd_name not in skip_list:
93 try:
94 fun(options)
95 except Exception as e:
96 if cmd_name in waive_list:
97 logging.exception(e)
98 else:
99 raise
Ting Shen18a06382016-08-30 16:18:21 +0800100
101 return argparse_utils.Command(cmd_name, *args, **kwargs)(
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800102 CommandWithWaiveSkipCheck)
Ting Shen18a06382016-08-30 16:18:21 +0800103 return Decorate
104
105
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800106@Command('write_hwid',
107 CmdArg('hwid', metavar='HWID', help='HWID string'))
Andy Chengc92e6f92012-11-20 16:55:53 +0800108def WriteHWID(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800109 """Write specified HWID value into the system BB."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800110
Tammo Spalink95c43732012-07-25 15:57:14 -0700111 logging.info('writing hwid string %r', options.hwid)
Ricky Lianga70a1202013-03-15 15:03:17 +0800112 GetGooftool(options).WriteHWID(options.hwid)
Andy Cheng0465d132013-03-20 12:12:06 +0800113 event_log.Log('write_hwid', hwid=options.hwid)
Yilin Yang71e39412019-09-24 09:26:46 +0800114 print('Wrote HWID: %r' % options.hwid)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800115
116
Yong Hongc3765412017-12-26 23:12:15 +0800117@Command('read_hwid')
118def ReadHWID(options):
119 """Read the HWID string from GBB."""
120
121 logging.info('reading the hwid string')
Yilin Yang71e39412019-09-24 09:26:46 +0800122 print(GetGooftool(options).ReadHWID())
Yong Hongc3765412017-12-26 23:12:15 +0800123
124
Yong Hong5408f652017-07-11 19:20:25 +0800125_project_cmd_arg = CmdArg(
126 '--project', metavar='PROJECT',
127 default=None, help='Project name to test.')
Ricky Liang53390232013-03-08 15:37:57 +0800128
Tammo Spalink8fab5312012-05-28 18:33:30 +0800129_hwdb_path_cmd_arg = CmdArg(
130 '--hwdb_path', metavar='PATH',
Yong Hong5c6dcd52017-12-27 11:05:01 +0800131 default=hwid_utils.GetDefaultDataPath(),
Tammo Spalink8fab5312012-05-28 18:33:30 +0800132 help='Path to the HWID database.')
133
Tammo Spalink95c43732012-07-25 15:57:14 -0700134_hwid_status_list_cmd_arg = CmdArg(
Hung-Te Lin56b18402015-01-16 14:52:30 +0800135 '--status', nargs='*', default=['supported'],
136 help='allow only HWIDs with these status values')
Tammo Spalink95c43732012-07-25 15:57:14 -0700137
Jon Salzce124fb2012-10-02 17:42:03 +0800138_probe_results_cmd_arg = CmdArg(
Yong Hong55050c12018-02-27 18:19:47 +0800139 '--probe_results', metavar='RESULTS.json',
140 help=('Output from "hwid probe" (used instead of probing this system).'))
Jon Salzce124fb2012-10-02 17:42:03 +0800141
Ricky Liang53390232013-03-08 15:37:57 +0800142_device_info_cmd_arg = CmdArg(
Ricky Liangf89f73a2013-03-19 05:00:24 +0800143 '--device_info', metavar='DEVICE_INFO.yaml', default=None,
You-Cheng Syu8fc2a602017-12-22 17:05:05 +0800144 help='A dict of device info to use instead of fetching from shopfloor '
Ricky Liang53390232013-03-08 15:37:57 +0800145 'server.')
146
Jon Salzce124fb2012-10-02 17:42:03 +0800147_hwid_cmd_arg = CmdArg(
148 '--hwid', metavar='HWID',
Ricky Lianga70a1202013-03-15 15:03:17 +0800149 help='HWID to verify (instead of the currently set HWID of this system).')
Jon Salzce124fb2012-10-02 17:42:03 +0800150
Yong Hong68a0e0d2017-12-20 19:06:54 +0800151_hwid_run_vpd_cmd_arg = CmdArg(
152 '--hwid-run-vpd', action='store_true',
153 help=('Specify the hwid utility to obtain the vpd data by running the '
154 '`vpd` commandline tool.'))
155
156_hwid_vpd_data_file_cmd_arg = CmdArg(
157 '--hwid-vpd-data-file', metavar='FILE.json', type=str, default=None,
158 help=('Specify the hwid utility to obtain the vpd data from the specified '
159 'file.'))
160
Bernie Thompson3c11c872013-07-22 18:22:45 -0700161_rma_mode_cmd_arg = CmdArg(
162 '--rma_mode', action='store_true',
163 help='Enable RMA mode, do not check for deprecated components.')
Tammo Spalink95c43732012-07-25 15:57:14 -0700164
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800165_cros_core_cmd_arg = CmdArg(
166 '--cros_core', action='store_true',
167 help='Finalize for ChromeOS Core devices (may add or remove few test '
Hung-Te Lin53c49402017-07-26 13:10:58 +0800168 'items. For example, registration codes or firmware bitmap '
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800169 'locale settings).')
170
Yilun Lin599833f2017-12-22 14:07:46 +0800171_chromebox_cmd_arg = CmdArg(
172 '--chromebox', action='store_true', default=None,
173 help='Finalize for ChromeBox devices (may add or remove few test '
174 'items. For example, VerifyECKey).')
175
bowgotsai13820f42015-09-10 23:18:04 +0800176_enforced_release_channels_cmd_arg = CmdArg(
177 '--enforced_release_channels', nargs='*', default=None,
178 help='Enforced release image channels.')
179
Yilun Lin34f54802017-11-16 11:58:25 +0800180_ec_pubkey_path_cmd_arg = CmdArg(
181 '--ec_pubkey_path',
182 default=None,
183 help='Path to public key in vb2 format. Verify EC key with pubkey file.')
184
185_ec_pubkey_hash_cmd_arg = CmdArg(
186 '--ec_pubkey_hash',
187 default=None,
188 help='A string for public key hash. Verify EC key with the given hash.')
189
Hung-Te Lincdb96522016-04-15 16:51:10 +0800190_release_rootfs_cmd_arg = CmdArg(
191 '--release_rootfs', help='Location of release image rootfs partition.')
192
193_firmware_path_cmd_arg = CmdArg(
194 '--firmware_path', help='Location of firmware image partition.')
Ricky Liang43b879b2014-02-24 11:36:55 +0800195
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800196_shopfloor_url_args_cmd_arg = CmdArg(
197 '--shopfloor_url',
Earl Ou51182222016-09-09 12:16:48 +0800198 help='Shopfloor server url to be informed when wiping is done. '
199 'After wiping, a XML-RPC request will be sent to the '
200 'given url to indicate the completion of wiping.')
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800201
202_station_ip_cmd_arg = CmdArg(
203 '--station_ip',
204 help='IP of remote station')
205
206_station_port_cmd_arg = CmdArg(
207 '--station_port',
208 help='Port on remote station')
209
210_wipe_finish_token_cmd_arg = CmdArg(
211 '--wipe_finish_token',
212 help='Required token when notifying station after wipe finished')
213
Wei-Han Chenf3924112019-02-25 14:52:58 +0800214_keep_developer_mode_flag_after_clobber_state_cmd_arg = CmdArg(
215 # The argument name is super long because you should never use it by
216 # yourself when using command line tools.
217 '--keep_developer_mode_flag_after_clobber_state',
218 action='store_true', default=None,
219 help='After clobber-state, do not delete .developer_mode')
220
Ting Shen18a06382016-08-30 16:18:21 +0800221_waive_list_cmd_arg = CmdArg(
222 '--waive_list', nargs='*', default=[], metavar='SUBCMD',
You-Cheng Syu8fc2a602017-12-22 17:05:05 +0800223 help='A list of waived checks, separated by whitespace. '
224 'Each item should be a sub-command of gooftool. '
Ting Shen18a06382016-08-30 16:18:21 +0800225 'e.g. "gooftool verify --waive_list verify_tpm clear_gbb_flags".')
226
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800227_skip_list_cmd_arg = CmdArg(
228 '--skip_list', nargs='*', default=[], metavar='SUBCMD',
You-Cheng Syu8fc2a602017-12-22 17:05:05 +0800229 help='A list of skipped checks, separated by whitespace. '
230 'Each item should be a sub-command of gooftool. '
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800231 'e.g. "gooftool verify --skip_list verify_tpm clear_gbb_flags".')
232
Wei-Han Cheneb4f9a22018-03-09 14:52:23 +0800233_rlz_embargo_end_date_offset_cmd_arg = CmdArg(
234 '--embargo_offset', type=int, default=7, choices=xrange(7, 15),
235 help='Change the offset of embargo end date, cannot less than 7 days or '
236 'more than 14 days.')
237
Marco Chena681b2e2018-08-31 11:41:41 +0800238_no_ectool_cmd_arg = CmdArg(
239 '--no_ectool', action='store_false', dest='has_ectool',
240 help='There is no ectool utility so tests rely on ectool should be '
241 'skipped.')
Tammo Spalink8fab5312012-05-28 18:33:30 +0800242
chuntsenaf1232f2019-03-20 15:45:54 +0800243_no_generate_mfg_date_cmd_arg = CmdArg(
244 '--no_generate_mfg_date', action='store_false', dest='generate_mfg_date',
245 help='Do not generate manufacturing date nor write mfg_date into VPD.')
246
247
Yilun Lin34f54802017-11-16 11:58:25 +0800248@Command(
249 'verify_ec_key',
250 _ec_pubkey_path_cmd_arg,
251 _ec_pubkey_hash_cmd_arg)
252def VerifyECKey(options):
253 """Verify EC key."""
254 return GetGooftool(options).VerifyECKey(
255 options.ec_pubkey_path, options.ec_pubkey_hash)
256
257
Hung-Te Line1d80f62016-03-31 14:58:13 +0800258@Command('verify_keys',
Hung-Te Lincdb96522016-04-15 16:51:10 +0800259 _release_rootfs_cmd_arg,
260 _firmware_path_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800261def VerifyKeys(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800262 """Verify keys in firmware and SSD match."""
Hung-Te Line1d80f62016-03-31 14:58:13 +0800263 return GetGooftool(options).VerifyKeys(
Hung-Te Lincdb96522016-04-15 16:51:10 +0800264 options.release_rootfs, options.firmware_path)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800265
266
267@Command('set_fw_bitmap_locale')
Peter Shihfdf17682017-05-26 11:38:39 +0800268def SetFirmwareBitmapLocale(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800269 """Use VPD locale value to set firmware bitmap default language."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800270
Ricky Lianga70a1202013-03-15 15:03:17 +0800271 (index, locale) = GetGooftool(options).SetFirmwareBitmapLocale()
Andy Cheng2582d292012-12-04 17:38:28 +0800272 logging.info('Firmware bitmap initial locale set to %d (%s).',
273 index, locale)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800274
275
Hung-Te Line1d80f62016-03-31 14:58:13 +0800276@Command('verify_system_time',
Wei-Han Chen2790d2e2019-01-18 21:13:40 +0800277 _release_rootfs_cmd_arg,
278 _rma_mode_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800279def VerifySystemTime(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800280 """Verify system time is later than release filesystem creation time."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800281
Wei-Han Chen2790d2e2019-01-18 21:13:40 +0800282 return GetGooftool(options).VerifySystemTime(options.release_rootfs,
283 rma_mode=options.rma_mode)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800284
285
Hung-Te Line1d80f62016-03-31 14:58:13 +0800286@Command('verify_rootfs',
Hung-Te Lincdb96522016-04-15 16:51:10 +0800287 _release_rootfs_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800288def VerifyRootFs(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800289 """Verify rootfs on SSD is valid by checking hash."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800290
Hung-Te Line1d80f62016-03-31 14:58:13 +0800291 return GetGooftool(options).VerifyRootFs(options.release_rootfs)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800292
Hung-Te Lin56b18402015-01-16 14:52:30 +0800293
Cheng-Yi Chiang676b5292013-06-18 12:05:33 +0800294@Command('verify_tpm')
Peter Shihfdf17682017-05-26 11:38:39 +0800295def VerifyTPM(options):
Cheng-Yi Chiang676b5292013-06-18 12:05:33 +0800296 """Verify TPM is cleared."""
297
298 return GetGooftool(options).VerifyTPM()
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800299
Hung-Te Lin56b18402015-01-16 14:52:30 +0800300
Hung-Te Lindd708d42014-07-11 17:05:01 +0800301@Command('verify_me_locked')
Peter Shihfdf17682017-05-26 11:38:39 +0800302def VerifyManagementEngineLocked(options):
You-Cheng Syu461ec032017-03-06 15:56:58 +0800303 """Verify Management Engine is locked."""
Hung-Te Lindd708d42014-07-11 17:05:01 +0800304
305 return GetGooftool(options).VerifyManagementEngineLocked()
306
Hung-Te Lin56b18402015-01-16 14:52:30 +0800307
Marco Chena681b2e2018-08-31 11:41:41 +0800308@Command('verify_switch_wp',
309 _no_ectool_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800310def VerifyWPSwitch(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800311 """Verify hardware write protection switch is enabled."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800312
Marco Chena681b2e2018-08-31 11:41:41 +0800313 GetGooftool(options).VerifyWPSwitch(options.has_ectool)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800314
315
Hung-Te Lin53c49402017-07-26 13:10:58 +0800316@Command('verify_vpd')
317def VerifyVPD(options):
318 """Verify that VPD values are properly set.
Jon Salzadd90d32014-04-29 16:16:27 +0800319
Hung-Te Lin53c49402017-07-26 13:10:58 +0800320 Check if mandatory fields are set, and deprecated fields don't exist.
Jon Salzadd90d32014-04-29 16:16:27 +0800321 """
Hung-Te Lin53c49402017-07-26 13:10:58 +0800322 return GetGooftool(options).VerifyVPD()
Jon Salzadd90d32014-04-29 16:16:27 +0800323
324
bowgotsai13820f42015-09-10 23:18:04 +0800325@Command('verify_release_channel',
326 _enforced_release_channels_cmd_arg)
Peter Shihfdf17682017-05-26 11:38:39 +0800327def VerifyReleaseChannel(options):
bowgotsai529139c2015-05-30 01:39:49 +0800328 """Verify that release image channel is correct.
329
330 ChromeOS has four channels: canary, dev, beta and stable.
331 The last three channels support image auto-updates, checks
332 that release image channel is one of them.
333 """
bowgotsai13820f42015-09-10 23:18:04 +0800334 return GetGooftool(options).VerifyReleaseChannel(
335 options.enforced_release_channels)
bowgotsai529139c2015-05-30 01:39:49 +0800336
337
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800338@Command('write_protect')
Peter Shihfdf17682017-05-26 11:38:39 +0800339def EnableFwWp(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800340 """Enable then verify firmware write protection."""
Peter Shihfdf17682017-05-26 11:38:39 +0800341 del options # Unused.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800342
Yong Hongdad230a2017-08-30 22:25:19 +0800343 def WriteProtect(fw):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800344 """Calculate protection size, then invoke flashrom.
345
Yong Hongdad230a2017-08-30 22:25:19 +0800346 The region (offset and size) to write protect may be different per chipset
347 and firmware layout, so we have to read the WP_RO section from FMAP to
348 decide that.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800349 """
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800350 wp_section = 'WP_RO'
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800351
Yong Hongdad230a2017-08-30 22:25:19 +0800352 fmap_image = fw.GetFirmwareImage(
353 sections=(['FMAP'] if fw.target == crosfw.TARGET_MAIN else None))
354 if not fmap_image.has_section(wp_section):
355 raise Error('Could not find %s firmware section: %s' %
356 (fw.target.upper(), wp_section))
357
358 section_data = fw.GetFirmwareImage(
359 sections=[wp_section]).get_section_area(wp_section)
Peter Shihe6afab32018-09-11 17:16:48 +0800360 ro_offset, ro_size = section_data[0:2]
Yong Hongdad230a2017-08-30 22:25:19 +0800361
362 logging.debug('write protecting %s [off=%x size=%x]', fw.target.upper(),
Hung-Te Lin7ea39e82012-07-31 18:39:33 +0800363 ro_offset, ro_size)
Yong Hongdad230a2017-08-30 22:25:19 +0800364 crosfw.Flashrom(fw.target).EnableWriteProtection(ro_offset, ro_size)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800365
Yong Hongdad230a2017-08-30 22:25:19 +0800366 WriteProtect(crosfw.LoadMainFirmware())
Andy Cheng0465d132013-03-20 12:12:06 +0800367 event_log.Log('wp', fw='main')
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800368
369 # Some EC (mostly PD) does not support "RO NOW". Instead they will only set
370 # "RO_AT_BOOT" when you request to enable RO (These platforms consider
371 # --wp-range with right range identical to --wp-enable), and requires a
372 # 'ectool reboot_ec RO at-shutdown; reboot' to let the RO take effect.
Hung-Te Lin0d10b562016-12-28 10:58:07 +0800373 # After reboot, "flashrom -p host --wp-status" will return protected range.
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800374 # If you don't reboot, returned range will be (0, 0), and running command
375 # "ectool flashprotect" will not have RO_NOW.
376
Yong Hongdad230a2017-08-30 22:25:19 +0800377 for fw in [crosfw.LoadEcFirmware(), crosfw.LoadPDFirmware()]:
378 if fw.GetChipId() is None:
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800379 logging.warning('%s not write protected (seems there is no %s flash).',
Yong Hongdad230a2017-08-30 22:25:19 +0800380 fw.target.upper(), fw.target.upper())
Hung-Te Lind3b124c2016-10-20 22:22:31 +0800381 continue
Yong Hongdad230a2017-08-30 22:25:19 +0800382 WriteProtect(fw)
383 event_log.Log('wp', fw=fw.target)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800384
385
386@Command('clear_gbb_flags')
Peter Shihfdf17682017-05-26 11:38:39 +0800387def ClearGBBFlags(options):
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800388 """Zero out the GBB flags, in preparation for transition to release state.
389
390 No GBB flags are set in release/shipping state, but they are useful
Hung-Te Lin879cff42017-06-19 12:46:37 +0800391 for factory/development. See "futility gbb --flags" for details.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800392 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800393
Ricky Lianga70a1202013-03-15 15:03:17 +0800394 GetGooftool(options).ClearGBBFlags()
Andy Cheng0465d132013-03-20 12:12:06 +0800395 event_log.Log('clear_gbb_flags')
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800396
397
Jon Salzaa3a30e2013-05-15 15:56:28 +0800398@Command('clear_factory_vpd_entries')
Peter Shihfdf17682017-05-26 11:38:39 +0800399def ClearFactoryVPDEntries(options):
Jon Salzaa3a30e2013-05-15 15:56:28 +0800400 """Clears factory.* items in the RW VPD."""
401 entries = GetGooftool(options).ClearFactoryVPDEntries()
402 event_log.Log('clear_factory_vpd_entries', entries=FilterDict(entries))
403
404
Mattias Nisslercca761b2015-04-15 21:53:04 +0200405@Command('generate_stable_device_secret')
Peter Shihfdf17682017-05-26 11:38:39 +0800406def GenerateStableDeviceSecret(options):
You-Cheng Syu461ec032017-03-06 15:56:58 +0800407 """Generates a fresh stable device secret and stores it in the RO VPD."""
Mattias Nisslercca761b2015-04-15 21:53:04 +0200408 GetGooftool(options).GenerateStableDeviceSecret()
409 event_log.Log('generate_stable_device_secret')
410
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800411
Yves Arrouyeb49b31e2019-03-06 21:51:52 -0800412@Command('cr50_set_sn_bits_and_board_id')
413def Cr50SetSnBitsAndBoardId(options):
414 """Set the serial number bits, board id and flags on the Cr50 chip."""
415 GetGooftool(options).Cr50SetSnBitsAndBoardId()
416 event_log.Log('cr50_set_sn_bits_and_board_id')
Shen-En Shihd078a7c2017-08-04 13:33:49 +0800417
418
Marco Chen20c885d2018-10-04 17:22:03 +0800419@Command('cr50_disable_factory_mode')
Marco Chen44a666d2018-07-13 21:01:50 +0800420def Cr50DisableFactoryMode(options):
Cheng-Han Yang08333af2017-12-18 17:22:38 +0800421 """Reset Cr50 state back to default state after RMA."""
Marco Chen44a666d2018-07-13 21:01:50 +0800422 return GetGooftool(options).Cr50DisableFactoryMode()
Cheng-Han Yang08333af2017-12-18 17:22:38 +0800423
424
Earl Ou564a7872016-10-05 10:22:00 +0800425@Command('enable_release_partition',
426 CmdArg('--release_rootfs',
427 help=('path to the release rootfs device. If not specified, '
428 'the default (5th) partition will be used.')))
429def EnableReleasePartition(options):
430 """Enables a release image partition on the disk."""
431 GetGooftool(options).EnableReleasePartition(options.release_rootfs)
432
433
Shun-Hsing Oucdc64e12015-01-14 22:07:33 +0800434@Command('wipe_in_place',
435 CmdArg('--fast', action='store_true',
Shun-Hsing Ou8d3c40a2015-10-08 18:16:08 +0800436 help='use non-secure but faster wipe method.'),
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800437 _shopfloor_url_args_cmd_arg,
438 _station_ip_cmd_arg,
439 _station_port_cmd_arg,
440 _wipe_finish_token_cmd_arg)
Shun-Hsing Oucdc64e12015-01-14 22:07:33 +0800441def WipeInPlace(options):
442 """Start factory wipe directly without reboot."""
443
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800444 GetGooftool(options).WipeInPlace(options.fast,
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800445 options.shopfloor_url,
446 options.station_ip,
447 options.station_port,
448 options.wipe_finish_token)
Mattias Nisslercca761b2015-04-15 21:53:04 +0200449
Wei-Han Chen7dc6d132016-04-06 11:11:53 +0800450@Command('wipe_init',
Wei-Han Chen0a3320e2016-04-23 01:32:07 +0800451 CmdArg('--wipe_args', help='arguments for clobber-state'),
452 CmdArg('--state_dev', help='path to stateful partition device'),
453 CmdArg('--root_disk', help='path to primary device'),
454 CmdArg('--old_root', help='path to old root'),
Wei-Han Chen0a3320e2016-04-23 01:32:07 +0800455 _shopfloor_url_args_cmd_arg,
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800456 _release_rootfs_cmd_arg,
457 _station_ip_cmd_arg,
458 _station_port_cmd_arg,
Wei-Han Chenf3924112019-02-25 14:52:58 +0800459 _wipe_finish_token_cmd_arg,
460 _keep_developer_mode_flag_after_clobber_state_cmd_arg)
Wei-Han Chen7dc6d132016-04-06 11:11:53 +0800461def WipeInit(options):
Wei-Han Chenf3924112019-02-25 14:52:58 +0800462 GetGooftool(options).WipeInit(
463 options.wipe_args,
464 options.shopfloor_url,
465 options.state_dev,
466 options.release_rootfs,
467 options.root_disk,
468 options.old_root,
469 options.station_ip,
470 options.station_port,
471 options.wipe_finish_token,
472 options.keep_developer_mode_flag_after_clobber_state)
Wei-Han Chen7dc6d132016-04-06 11:11:53 +0800473
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800474@Command('verify',
Hung-Te Lin6d827542012-07-19 11:50:41 +0800475 CmdArg('--no_write_protect', action='store_true',
476 help='Do not check write protection switch state.'),
Tammo Spalink95c43732012-07-25 15:57:14 -0700477 _hwid_status_list_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800478 _hwdb_path_cmd_arg,
Yong Hong5408f652017-07-11 19:20:25 +0800479 _project_cmd_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800480 _probe_results_cmd_arg,
Cheng-Yi Chiang406ad912013-11-14 16:51:33 +0800481 _hwid_cmd_arg,
Yong Hong68a0e0d2017-12-20 19:06:54 +0800482 _hwid_run_vpd_cmd_arg,
483 _hwid_vpd_data_file_cmd_arg,
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800484 _rma_mode_cmd_arg,
bowgotsai13820f42015-09-10 23:18:04 +0800485 _cros_core_cmd_arg,
Yilun Lin599833f2017-12-22 14:07:46 +0800486 _chromebox_cmd_arg,
Yilun Lin34f54802017-11-16 11:58:25 +0800487 _ec_pubkey_path_cmd_arg,
488 _ec_pubkey_hash_cmd_arg,
Hung-Te Lincdb96522016-04-15 16:51:10 +0800489 _release_rootfs_cmd_arg,
490 _firmware_path_cmd_arg,
Ting Shen18a06382016-08-30 16:18:21 +0800491 _enforced_release_channels_cmd_arg,
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800492 _waive_list_cmd_arg,
Marco Chena681b2e2018-08-31 11:41:41 +0800493 _skip_list_cmd_arg,
494 _no_ectool_cmd_arg)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800495def Verify(options):
496 """Verifies if whole factory process is ready for finalization.
497
498 This routine performs all the necessary checks to make sure the
499 device is ready to be finalized, but does not modify state. These
500 checks include dev switch, firmware write protection switch, hwid,
501 system time, keys, and root file system.
502 """
Andy Cheng7a76cb82012-11-19 18:08:19 +0800503
Hung-Te Lin6d827542012-07-19 11:50:41 +0800504 if not options.no_write_protect:
Ricky Lianga70a1202013-03-15 15:03:17 +0800505 VerifyWPSwitch(options)
Hung-Te Lindd708d42014-07-11 17:05:01 +0800506 VerifyManagementEngineLocked(options)
Ting Shen129fa6f2016-09-02 12:22:24 +0800507 VerifyHWID(options)
Ricky Lianga70a1202013-03-15 15:03:17 +0800508 VerifySystemTime(options)
Yilun Lin599833f2017-12-22 14:07:46 +0800509 if options.chromebox:
510 VerifyECKey(options)
Ricky Lianga70a1202013-03-15 15:03:17 +0800511 VerifyKeys(options)
512 VerifyRootFs(options)
Cheng-Yi Chiang676b5292013-06-18 12:05:33 +0800513 VerifyTPM(options)
Hung-Te Lin53c49402017-07-26 13:10:58 +0800514 VerifyVPD(options)
bowgotsai529139c2015-05-30 01:39:49 +0800515 VerifyReleaseChannel(options)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800516
Hung-Te Lin56b18402015-01-16 14:52:30 +0800517
Jon Salzfe9036f2014-01-16 14:11:23 +0800518@Command('untar_stateful_files')
Hung-Te Lin388bce22014-06-03 19:56:40 +0800519def UntarStatefulFiles(unused_options):
Jon Salzfe9036f2014-01-16 14:11:23 +0800520 """Untars stateful files from stateful_files.tar.xz on stateful partition.
521
522 If that file does not exist (which should only be R30 and earlier),
523 this is a no-op.
524 """
Hung-Te Lin2333f3f2016-08-24 17:56:48 +0800525 # Path to stateful partition on device.
526 device_stateful_path = '/mnt/stateful_partition'
527 tar_file = os.path.join(device_stateful_path, 'stateful_files.tar.xz')
Jon Salzfe9036f2014-01-16 14:11:23 +0800528 if os.path.exists(tar_file):
Hung-Te Lin2333f3f2016-08-24 17:56:48 +0800529 Spawn(['tar', 'xf', tar_file], cwd=device_stateful_path,
Jon Salzfe9036f2014-01-16 14:11:23 +0800530 log=True, check_call=True)
531 else:
532 logging.warning('No stateful files at %s', tar_file)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800533
Jon Salz40b9f822014-07-25 16:39:55 +0800534
535@Command('log_source_hashes')
Peter Shihfdf17682017-05-26 11:38:39 +0800536def LogSourceHashes(options):
Jon Salz40b9f822014-07-25 16:39:55 +0800537 """Logs hashes of source files in the factory toolkit."""
Peter Shihfdf17682017-05-26 11:38:39 +0800538 del options # Unused.
Jon Salze60307f2014-08-05 16:20:00 +0800539 # WARNING: The following line is necessary to validate the integrity
540 # of the factory software. Do not remove or modify it.
541 #
542 # 警告:此行会验证工厂软件的完整性,禁止删除或修改。
Wei-Han Chena5c01a02016-04-23 19:27:19 +0800543 factory_par = sys_utils.GetRunningFactoryPythonArchivePath()
544 if factory_par:
545 event_log.Log(
546 'source_hashes',
547 **file_utils.HashPythonArchive(factory_par))
548 else:
549 event_log.Log(
550 'source_hashes',
Peter Shihad166772017-05-31 11:36:17 +0800551 **file_utils.HashSourceTree(os.path.join(paths.FACTORY_DIR, 'py')))
Jon Salz40b9f822014-07-25 16:39:55 +0800552
553
Tammo Spalink86a61c62012-05-25 15:10:35 +0800554@Command('log_system_details')
Peter Shihfdf17682017-05-26 11:38:39 +0800555def LogSystemDetails(options):
Tammo Spalink86a61c62012-05-25 15:10:35 +0800556 """Write miscellaneous system details to the event log."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800557
Ricky Liang43b879b2014-02-24 11:36:55 +0800558 event_log.Log('system_details', **GetGooftool(options).GetSystemDetails())
Tammo Spalink86a61c62012-05-25 15:10:35 +0800559
560
Jon Salza88b83b2013-05-27 20:00:35 +0800561def CreateReportArchiveBlob(*args, **kwargs):
562 """Creates a report archive and returns it as a blob.
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800563
Jon Salza88b83b2013-05-27 20:00:35 +0800564 Args:
565 See CreateReportArchive.
Andy Cheng7a76cb82012-11-19 18:08:19 +0800566
Jon Salza88b83b2013-05-27 20:00:35 +0800567 Returns:
568 An xmlrpclib.Binary object containing a .tar.xz file.
569 """
Wei-Han Chen47416612016-09-14 17:41:52 +0800570 report_archive = CreateReportArchive(*args, **kwargs)
571 try:
You-Cheng Syuf0f4be12017-12-05 16:33:53 +0800572 return xmlrpclib.Binary(file_utils.ReadFile(report_archive))
Wei-Han Chen47416612016-09-14 17:41:52 +0800573 finally:
574 os.unlink(report_archive)
Jon Salza88b83b2013-05-27 20:00:35 +0800575
576
577def CreateReportArchive(device_sn=None, add_file=None):
578 """Creates a report archive in a temporary directory.
579
580 Args:
581 device_sn: The device serial number (optional).
582 add_file: A list of files to add (optional).
583
584 Returns:
585 Path to the archive.
586 """
chuntsen2b43cc22019-07-18 15:26:16 +0800587 # Flush Testlog data to DATA_TESTLOG_DIR before creating a report archive.
588 result, reason = state.GetInstance().FlushTestlog(
589 uplink=False, local=True, timeout=10)
590 if not result:
591 logging.warning('Failed to flush testlog data: %s', reason)
592
Hung-Te Lin6bd16472012-06-20 16:26:47 +0800593 def NormalizeAsFileName(token):
594 return re.sub(r'\W+', '', token).strip()
Jon Salza88b83b2013-05-27 20:00:35 +0800595
596 target_name = '%s%s.tar.xz' % (
597 time.strftime('%Y%m%dT%H%M%SZ',
598 time.gmtime()),
Hung-Te Lin56b18402015-01-16 14:52:30 +0800599 ('' if device_sn is None else
600 '_' + NormalizeAsFileName(device_sn)))
Tammo Spalink86a61c62012-05-25 15:10:35 +0800601 target_path = os.path.join(gettempdir(), target_name)
Jon Salza88b83b2013-05-27 20:00:35 +0800602
Tammo Spalink86a61c62012-05-25 15:10:35 +0800603 # Intentionally ignoring dotfiles in EVENT_LOG_DIR.
Andy Cheng0465d132013-03-20 12:12:06 +0800604 tar_cmd = 'cd %s ; tar cJf %s *' % (event_log.EVENT_LOG_DIR, target_path)
Peter Shihb4e49352017-05-25 17:35:11 +0800605 tar_cmd += ' %s' % paths.FACTORY_LOG_PATH
chuntsen2b43cc22019-07-18 15:26:16 +0800606 tar_cmd += ' %s' % paths.DATA_TESTLOG_DIR
Jon Salza88b83b2013-05-27 20:00:35 +0800607 if add_file:
608 for f in add_file:
Jon Salz65266432012-07-30 19:02:49 +0800609 # Require absolute paths since the tar command may change the
610 # directory.
611 if not f.startswith('/'):
612 raise Error('Not an absolute path: %s' % f)
613 if not os.path.exists(f):
614 raise Error('File does not exist: %s' % f)
Wei-Han Chen4b755022017-01-04 10:51:52 +0800615 tar_cmd += ' %s' % pipes.quote(f)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800616 cmd_result = Shell(tar_cmd)
Jon Salzff88c022012-11-03 12:19:58 +0800617
618 if ((cmd_result.status == 1) and
619 all((x == '' or
620 'file changed as we read it' in x or
621 "Removing leading `/' from member names" in x)
622 for x in cmd_result.stderr.split('\n'))):
623 # That's OK. Make sure it's valid though.
Vic Yang85199e72013-01-28 14:33:11 +0800624 Spawn(['tar', 'tfJ', target_path], check_call=True, log=True,
Jon Salzff88c022012-11-03 12:19:58 +0800625 ignore_stdout=True)
626 elif not cmd_result.success:
Tammo Spalink86a61c62012-05-25 15:10:35 +0800627 raise Error('unable to tar event logs, cmd %r failed, stderr: %r' %
628 (tar_cmd, cmd_result.stderr))
Jon Salzff88c022012-11-03 12:19:58 +0800629
Jon Salza88b83b2013-05-27 20:00:35 +0800630 return target_path
631
632_upload_method_cmd_arg = CmdArg(
633 '--upload_method', metavar='METHOD:PARAM',
634 help=('How to perform the upload. METHOD should be one of '
635 '{ftp, shopfloor, ftps, cpfe}.'))
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800636_upload_max_retry_times_arg = CmdArg(
637 '--upload_max_retry_times', type=int, default=0,
638 help='Number of tries to upload. 0 to retry infinitely.')
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800639_upload_retry_interval_arg = CmdArg(
640 '--upload_retry_interval', type=int, default=None,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800641 help='Retry interval in seconds.')
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800642_upload_allow_fail_arg = CmdArg(
643 '--upload_allow_fail', action='store_true',
644 help='Continue finalize if report upload fails.')
Jon Salza88b83b2013-05-27 20:00:35 +0800645_add_file_cmd_arg = CmdArg(
646 '--add_file', metavar='FILE', action='append',
647 help='Extra file to include in report (must be an absolute path)')
648
Hung-Te Lin56b18402015-01-16 14:52:30 +0800649
Jon Salza88b83b2013-05-27 20:00:35 +0800650@Command('upload_report',
651 _upload_method_cmd_arg,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800652 _upload_max_retry_times_arg,
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800653 _upload_retry_interval_arg,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800654 _upload_allow_fail_arg,
Jon Salza88b83b2013-05-27 20:00:35 +0800655 _add_file_cmd_arg)
656def UploadReport(options):
657 """Create a report containing key device details."""
Yong Hong65bda312018-12-13 20:05:58 +0800658 ro_vpd = vpd.VPDTool().GetAllData(partition=vpd.VPD_READONLY_PARTITION_NAME)
Jon Salza88b83b2013-05-27 20:00:35 +0800659 device_sn = ro_vpd.get('serial_number', None)
660 if device_sn is None:
661 logging.warning('RO_VPD missing device serial number')
Chun-Ta Lin53cbbd52016-06-08 21:42:19 +0800662 device_sn = 'MISSING_SN_' + time_utils.TimedUUID()
chuntsena6da2be2019-08-14 17:11:55 +0800663 target_path = CreateReportArchive(device_sn, options.add_file)
Jon Salza88b83b2013-05-27 20:00:35 +0800664
Tammo Spalink86a61c62012-05-25 15:10:35 +0800665 if options.upload_method is None or options.upload_method == 'none':
666 logging.warning('REPORT UPLOAD SKIPPED (report left at %s)', target_path)
667 return
668 method, param = options.upload_method.split(':', 1)
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800669
670 if options.upload_retry_interval is not None:
671 retry_interval = options.upload_retry_interval
672 else:
673 retry_interval = report_upload.DEFAULT_RETRY_INTERVAL
674
Tammo Spalink86a61c62012-05-25 15:10:35 +0800675 if method == 'shopfloor':
You-Cheng Syuf0f4be12017-12-05 16:33:53 +0800676 report_upload.ShopFloorUpload(
677 target_path, param,
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800678 'GRT' if options.command_name == 'finalize' else None,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800679 max_retry_times=options.upload_max_retry_times,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800680 retry_interval=retry_interval,
681 allow_fail=options.upload_allow_fail)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800682 elif method == 'ftp':
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800683 report_upload.FtpUpload(target_path, 'ftp:' + param,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800684 max_retry_times=options.upload_max_retry_times,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800685 retry_interval=retry_interval,
686 allow_fail=options.upload_allow_fail)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800687 elif method == 'ftps':
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800688 report_upload.CurlUrlUpload(target_path, '--ftp-ssl-reqd ftp:%s' % param,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800689 max_retry_times=options.upload_max_retry_times,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800690 retry_interval=retry_interval,
691 allow_fail=options.upload_allow_fail)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800692 elif method == 'cpfe':
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800693 report_upload.CpfeUpload(target_path, pipes.quote(param),
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800694 max_retry_times=options.upload_max_retry_times,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800695 retry_interval=retry_interval,
696 allow_fail=options.upload_allow_fail)
Tammo Spalink86a61c62012-05-25 15:10:35 +0800697 else:
Peter Shihbf6f22b2018-02-26 14:05:28 +0800698 raise Error('unknown report upload method %r' % method)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800699
700
701@Command('finalize',
Hung-Te Lin6d827542012-07-19 11:50:41 +0800702 CmdArg('--no_write_protect', action='store_true',
703 help='Do not enable firmware write protection.'),
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800704 CmdArg('--fast', action='store_true',
705 help='use non-secure but faster wipe method.'),
Yong Hongb2926bd2018-10-12 14:11:14 +0800706 _no_ectool_cmd_arg,
Shun-Hsing Oudb407d62015-11-11 11:03:59 +0800707 _shopfloor_url_args_cmd_arg,
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800708 _hwdb_path_cmd_arg,
Tammo Spalink95c43732012-07-25 15:57:14 -0700709 _hwid_status_list_cmd_arg,
Jon Salz65266432012-07-30 19:02:49 +0800710 _upload_method_cmd_arg,
Cheng-Han Yang31a3bd92018-08-23 19:04:04 +0800711 _upload_max_retry_times_arg,
Cheng-Han Yang3d4b0c02018-08-23 18:24:14 +0800712 _upload_retry_interval_arg,
Cheng-Han Yangc1697e22018-08-24 15:22:39 +0800713 _upload_allow_fail_arg,
Jon Salzce124fb2012-10-02 17:42:03 +0800714 _add_file_cmd_arg,
715 _probe_results_cmd_arg,
Cheng-Yi Chiang406ad912013-11-14 16:51:33 +0800716 _hwid_cmd_arg,
Yong Hong68a0e0d2017-12-20 19:06:54 +0800717 _hwid_run_vpd_cmd_arg,
718 _hwid_vpd_data_file_cmd_arg,
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800719 _rma_mode_cmd_arg,
bowgotsai13820f42015-09-10 23:18:04 +0800720 _cros_core_cmd_arg,
Yilun Lin599833f2017-12-22 14:07:46 +0800721 _chromebox_cmd_arg,
Yilun Lin34f54802017-11-16 11:58:25 +0800722 _ec_pubkey_path_cmd_arg,
723 _ec_pubkey_hash_cmd_arg,
Hung-Te Lincdb96522016-04-15 16:51:10 +0800724 _release_rootfs_cmd_arg,
725 _firmware_path_cmd_arg,
Wei-Han Chenbe1355a2016-04-24 19:31:03 +0800726 _enforced_release_channels_cmd_arg,
727 _station_ip_cmd_arg,
728 _station_port_cmd_arg,
Ting Shen18a06382016-08-30 16:18:21 +0800729 _wipe_finish_token_cmd_arg,
Wei-Han Cheneb4f9a22018-03-09 14:52:23 +0800730 _rlz_embargo_end_date_offset_cmd_arg,
Wei-Han Chen60c5d332017-01-05 17:15:10 +0800731 _waive_list_cmd_arg,
chuntsenaf1232f2019-03-20 15:45:54 +0800732 _skip_list_cmd_arg,
733 _no_generate_mfg_date_cmd_arg)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800734def Finalize(options):
735 """Verify system readiness and trigger transition into release state.
736
Jon Salzaa3a30e2013-05-15 15:56:28 +0800737 This routine does the following:
738 - Verifies system state (see verify command)
Jon Salzfe9036f2014-01-16 14:11:23 +0800739 - Untars stateful_files.tar.xz, if it exists, in the stateful partition, to
740 initialize files such as the CRX cache
Jon Salzaa3a30e2013-05-15 15:56:28 +0800741 - Modifies firmware bitmaps to match locale
742 - Clears all factory-friendly flags from the GBB
743 - Removes factory-specific entries from RW_VPD (factory.*)
744 - Enables firmware write protection (cannot rollback after this)
745 - Uploads system logs & reports
Earl Ou51182222016-09-09 12:16:48 +0800746 - Wipes the testing kernel, rootfs, and stateful partition
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800747 """
Wei-Han Cheneb4f9a22018-03-09 14:52:23 +0800748 if not options.rma_mode:
749 # Write VPD values related to RLZ ping into VPD.
750 GetGooftool(options).WriteVPDForRLZPing(options.embargo_offset)
chuntsenaf1232f2019-03-20 15:45:54 +0800751 if options.generate_mfg_date:
752 GetGooftool(options).WriteVPDForMFGDate()
Yves Arrouyeb49b31e2019-03-06 21:51:52 -0800753 Cr50SetSnBitsAndBoardId(options)
Marco Chen44a666d2018-07-13 21:01:50 +0800754 Cr50DisableFactoryMode(options)
Marco Chen9d0631c2018-08-31 10:52:44 +0800755 Verify(options)
Jon Salz40b9f822014-07-25 16:39:55 +0800756 LogSourceHashes(options)
Jon Salzfe9036f2014-01-16 14:11:23 +0800757 UntarStatefulFiles(options)
Chih-Yu Huang714dbc42015-07-21 16:42:16 +0800758 if options.cros_core:
759 logging.info('SetFirmwareBitmapLocale is skipped for ChromeOS Core device.')
760 else:
761 SetFirmwareBitmapLocale(options)
Jon Salzaa3a30e2013-05-15 15:56:28 +0800762 ClearFactoryVPDEntries(options)
Mattias Nisslercca761b2015-04-15 21:53:04 +0200763 GenerateStableDeviceSecret(options)
Shen-En Shih3e079b22017-09-11 05:43:09 -0700764 ClearGBBFlags(options)
Hung-Te Lin6d827542012-07-19 11:50:41 +0800765 if options.no_write_protect:
766 logging.warn('WARNING: Firmware Write Protection is SKIPPED.')
Andy Cheng0465d132013-03-20 12:12:06 +0800767 event_log.Log('wp', fw='both', status='skipped')
Hung-Te Lin6d827542012-07-19 11:50:41 +0800768 else:
Wei-Han Chenba21f512016-10-14 18:52:33 +0800769 EnableFwWp(options)
Jon Salza0f58e02012-05-29 19:33:39 +0800770 LogSystemDetails(options)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800771 UploadReport(options)
Earl Ou51182222016-09-09 12:16:48 +0800772
773 event_log.Log('wipe_in_place')
774 wipe_args = []
Earl Ou51182222016-09-09 12:16:48 +0800775 if options.shopfloor_url:
776 wipe_args += ['--shopfloor_url', options.shopfloor_url]
777 if options.fast:
778 wipe_args += ['--fast']
779 if options.station_ip:
780 wipe_args += ['--station_ip', options.station_ip]
781 if options.station_port:
782 wipe_args += ['--station_port', options.station_port]
783 if options.wipe_finish_token:
784 wipe_args += ['--wipe_finish_token', options.wipe_finish_token]
785 ExecFactoryPar('gooftool', 'wipe_in_place', *wipe_args)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800786
787
Ting Shen129fa6f2016-09-02 12:22:24 +0800788@Command('verify_hwid',
789 _probe_results_cmd_arg,
790 _hwdb_path_cmd_arg,
791 _hwid_cmd_arg,
Yong Hong68a0e0d2017-12-20 19:06:54 +0800792 _hwid_run_vpd_cmd_arg,
793 _hwid_vpd_data_file_cmd_arg,
Ting Shen129fa6f2016-09-02 12:22:24 +0800794 _rma_mode_cmd_arg)
795def VerifyHWID(options):
Ricky Liangc662be32013-12-24 11:50:23 +0800796 """A simple wrapper that calls out to HWID utils to verify version 3 HWID.
Ricky Liang53390232013-03-08 15:37:57 +0800797
Ricky Liangc662be32013-12-24 11:50:23 +0800798 This is mainly for Gooftool to verify v3 HWID during finalize. For testing
799 and development purposes, please use `hwid` command.
Ricky Liang53390232013-03-08 15:37:57 +0800800 """
Yong Hongada8e0e2018-01-04 16:36:21 +0800801 database = GetGooftool(options).db
Yong Hong68a0e0d2017-12-20 19:06:54 +0800802
Yong Hongada8e0e2018-01-04 16:36:21 +0800803 encoded_string = options.hwid or GetGooftool(options).ReadHWID()
804
805 probed_results = hwid_utils.GetProbedResults(infile=options.probe_results)
Yong Hong2c39bf22018-01-24 22:24:11 +0800806 device_info = hwid_utils.GetDeviceInfo()
Yong Hong65bda312018-12-13 20:05:58 +0800807 vpd_data = hwid_utils.GetVPDData(run_vpd=options.hwid_run_vpd,
808 infile=options.hwid_vpd_data_file)
Ricky Liang53390232013-03-08 15:37:57 +0800809
Hung-Te Lin11052952015-03-18 13:48:59 +0800810 event_log.Log('probed_results', probed_results=FilterDict(probed_results))
Yong Hong65bda312018-12-13 20:05:58 +0800811 event_log.Log('vpd', vpd=FilterDict(vpd_data))
Ricky Liang53390232013-03-08 15:37:57 +0800812
Yong Hong2c39bf22018-01-24 22:24:11 +0800813 hwid_utils.VerifyHWID(database, encoded_string, probed_results,
Yong Hong65bda312018-12-13 20:05:58 +0800814 device_info, vpd_data, options.rma_mode)
Ricky Liang53390232013-03-08 15:37:57 +0800815
Ricky Liangc662be32013-12-24 11:50:23 +0800816 event_log.Log('verified_hwid', hwid=encoded_string)
Ricky Liang53390232013-03-08 15:37:57 +0800817
818
henryhsu44d793a2013-07-20 00:07:38 +0800819@Command('get_firmware_hash',
Marco Chence70b132018-05-03 23:43:39 +0800820 CmdArg('--file', required=True, metavar='FILE', help='Firmware File.'))
henryhsu44d793a2013-07-20 00:07:38 +0800821def GetFirmwareHash(options):
henryhsuf6f835c2013-07-20 20:49:25 +0800822 """Get firmware hash from a file"""
henryhsu44d793a2013-07-20 00:07:38 +0800823 if os.path.exists(options.file):
Cheng-Han Yang2c668ae2018-04-18 22:31:07 +0800824 value_dict = chromeos_firmware.CalculateFirmwareHashes(options.file)
825 for key, value in value_dict.iteritems():
Yilin Yang71e39412019-09-24 09:26:46 +0800826 print(' %s: %s' % (key, value))
henryhsu44d793a2013-07-20 00:07:38 +0800827 else:
828 raise Error('File does not exist: %s' % options.file)
829
henryhsuf6f835c2013-07-20 20:49:25 +0800830
Peter Shihfdf17682017-05-26 11:38:39 +0800831def main():
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800832 """Run sub-command specified by the command line args."""
Andy Cheng7a76cb82012-11-19 18:08:19 +0800833
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800834 options = ParseCmdline(
Ting Shen129fa6f2016-09-02 12:22:24 +0800835 'Perform Google required factory tests.',
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800836 CmdArg('-l', '--log', metavar='PATH',
837 help='Write logs to this file.'),
Jon Salza4bea382012-10-29 13:00:34 +0800838 CmdArg('--suppress-event-logs', action='store_true',
839 help='Suppress event logging.'),
Wei-Han Chenaff56232016-04-16 09:17:59 +0800840 CmdArg('--phase', default=None,
841 help=('override phase for phase checking (defaults to the current '
842 'as returned by the "factory phase" command)')),
Wei-Han Chenb34bdff2019-09-26 13:07:50 +0800843 VERBOSITY_CMD_ARG)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800844 SetupLogging(options.verbosity, options.log)
Andy Cheng0465d132013-03-20 12:12:06 +0800845 event_log.SetGlobalLoggerDefaultPrefix('gooftool')
846 event_log.GetGlobalLogger().suppress = options.suppress_event_logs
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800847 logging.debug('gooftool options: %s', repr(options))
Wei-Han Chenaff56232016-04-16 09:17:59 +0800848
849 phase.OverridePhase(options.phase)
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800850 try:
851 logging.debug('GOOFTOOL command %r', options.command_name)
852 options.command(options)
853 logging.info('GOOFTOOL command %r SUCCESS', options.command_name)
Peter Shih6674ecf2018-03-29 14:04:57 +0800854 except Error as e:
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800855 logging.exception(e)
856 sys.exit('GOOFTOOL command %r ERROR: %s' % (options.command_name, e))
Peter Shih6674ecf2018-03-29 14:04:57 +0800857 except Exception as e:
Tammo Spalink9a96b8a2012-04-03 11:10:41 +0800858 logging.exception(e)
859 sys.exit('UNCAUGHT RUNTIME EXCEPTION %s' % e)
860
861
862if __name__ == '__main__':
Peter Shihfdf17682017-05-26 11:38:39 +0800863 main()