blob: c4547abd102f8ea381be58d139f4996bb8e43c47 [file] [log] [blame]
Kuang-che Wu875c89a2020-01-08 14:30:55 +08001#!/usr/bin/env python3
Kuang-che Wu6e4beca2018-06-27 17:45:02 +08002# -*- coding: utf-8 -*-
Kuang-che Wu2ea804f2017-11-28 17:11:41 +08003# Copyright 2017 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6"""Switcher for ChromeOS prebuilt"""
7
8from __future__ import print_function
9import argparse
10import logging
11import os
Kuang-che Wu44278142019-03-04 11:33:57 +080012import sys
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080013
14from bisect_kit import cli
15from bisect_kit import common
16from bisect_kit import configure
Kuang-che Wu414d67f2019-05-28 11:28:57 +080017from bisect_kit import cros_lab_util
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080018from bisect_kit import cros_util
19
20logger = logging.getLogger(__name__)
21
22
23def create_argument_parser():
Kuang-che Wud2d6e412021-01-28 16:26:41 +080024 parents = [common.common_argument_parser, common.session_optional_parser]
25 parser = argparse.ArgumentParser(description=__doc__, parents=parents)
Kuang-che Wufe1e88a2019-09-10 21:52:25 +080026 cli.patching_argparser_exit(parser)
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080027 parser.add_argument(
Kuang-che Wu0ebbf7c2019-08-28 18:19:19 +080028 '--dut',
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080029 type=cli.argtype_notempty,
30 metavar='DUT',
31 default=configure.get('DUT', ''))
32 parser.add_argument(
33 'version',
34 nargs='?',
35 type=cros_util.argtype_cros_version,
36 metavar='CROS_VERSION',
37 default=configure.get('CROS_VERSION', ''),
38 help='ChromeOS version number, short (10162.0.0) or full (R64-10162.0.0)')
39 parser.add_argument(
40 '--board',
41 metavar='BOARD',
42 default=configure.get('BOARD', ''),
43 help='ChromeOS board name')
44 parser.add_argument(
45 '--clobber-stateful',
Kuang-che Wu86fbde52019-01-18 15:41:00 +080046 '--clobber_stateful',
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080047 action='store_true',
48 help='Clobber stateful partition when performing update')
49 parser.add_argument(
50 '--no-disable-rootfs-verification',
Kuang-che Wu86fbde52019-01-18 15:41:00 +080051 '--no_disable_rootfs_verification',
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080052 dest='disable_rootfs_verification',
53 action='store_false',
54 help="Don't disable rootfs verification after update is completed")
55 parser.add_argument(
56 '--default_chromeos_root',
57 type=cli.argtype_dir_path,
58 default=configure.get('DEFAULT_CHROMEOS_ROOT',
Kuang-che Wu927231f2018-07-24 14:21:56 +080059 os.path.expanduser('~/chromiumos')),
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080060 help='Default chromeos tree to run "cros flash" (default: %(default)s)')
61
62 return parser
63
64
Kuang-che Wu414d67f2019-05-28 11:28:57 +080065def switch(opts):
66 # TODO(kcwu): clear cache of cros flash
Kuang-che Wu721e8902021-03-19 12:18:53 +080067 image_info = cros_util.search_image(opts.board, opts.version)
68 if not image_info:
69 logger.error('no images available for %s %s', opts.board, opts.version)
70 return cli.EXIT_CODE_FATAL
Kuang-che Wu414d67f2019-05-28 11:28:57 +080071
Kuang-che Wu721e8902021-03-19 12:18:53 +080072 if cros_util.provision_image_with_retry(
Kuang-che Wu414d67f2019-05-28 11:28:57 +080073 opts.default_chromeos_root,
74 opts.dut,
75 opts.board,
Kuang-che Wu721e8902021-03-19 12:18:53 +080076 image_info,
Kuang-che Wu414d67f2019-05-28 11:28:57 +080077 version=opts.version,
78 clobber_stateful=opts.clobber_stateful,
79 disable_rootfs_verification=opts.disable_rootfs_verification,
Kuang-che Wu2ac9a922020-09-03 16:50:12 +080080 repair_callback=cros_lab_util.repair,
81 force_reboot_callback=cros_lab_util.reboot_via_servo):
Kuang-che Wu414d67f2019-05-28 11:28:57 +080082 return 0
83 return 1
84
85
Jae Hoon Kim7cbf64e2021-04-16 10:06:32 -070086def parse_args(args):
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080087 parser = create_argument_parser()
Jae Hoon Kim7cbf64e2021-04-16 10:06:32 -070088 return parser.parse_args(args)
Kuang-che Wu2ea804f2017-11-28 17:11:41 +080089
Jae Hoon Kim7cbf64e2021-04-16 10:06:32 -070090
91def inner_main(opts):
Kuang-che Wu44278142019-03-04 11:33:57 +080092 if not cros_util.is_good_dut(opts.dut):
93 logger.error('%r is not a good DUT', opts.dut)
Kuang-che Wu414d67f2019-05-28 11:28:57 +080094 if not cros_lab_util.repair(opts.dut):
Jae Hoon Kim7cbf64e2021-04-16 10:06:32 -070095 return cli.EXIT_CODE_FATAL
Kuang-che Wu414d67f2019-05-28 11:28:57 +080096 if not opts.board:
97 opts.board = cros_util.query_dut_board(opts.dut)
98
Kuang-che Wu721e8902021-03-19 12:18:53 +080099 cros_util.prepare_chroot(opts.default_chromeos_root)
100
Kuang-che Wu414d67f2019-05-28 11:28:57 +0800101 try:
102 returncode = switch(opts)
103 except Exception:
104 logger.exception('switch failed')
105 returncode = 1
106
107 # No matter switching succeeded or not, DUT must be in good state.
108 # switch() already tried repairing if possible, no repair here.
109 if not cros_util.is_good_dut(opts.dut):
110 logger.fatal('%r is not a good DUT', opts.dut)
111 returncode = cli.EXIT_CODE_FATAL
112 logger.info('done')
Jae Hoon Kim7cbf64e2021-04-16 10:06:32 -0700113 return returncode
114
115
116@cli.fatal_error_handler
117def main(args=None):
118 common.init()
119 opts = parse_args(args)
120 common.config_logging(opts)
121 sys.exit(inner_main(opts))
Kuang-che Wu2ea804f2017-11-28 17:11:41 +0800122
123
124if __name__ == '__main__':
125 main()