Kuang-che Wu | 875c89a | 2020-01-08 14:30:55 +0800 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Kuang-che Wu | 6e4beca | 2018-06-27 17:45:02 +0800 | [diff] [blame] | 2 | # -*- coding: utf-8 -*- |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 3 | # Copyright 2018 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 localbuild bisecting.""" |
| 7 | |
| 8 | from __future__ import print_function |
| 9 | import argparse |
| 10 | import logging |
Kuang-che Wu | 9890ce8 | 2018-07-07 15:14:10 +0800 | [diff] [blame] | 11 | import os |
Kuang-che Wu | 4427814 | 2019-03-04 11:33:57 +0800 | [diff] [blame] | 12 | import sys |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 13 | |
| 14 | from bisect_kit import cli |
Kuang-che Wu | e4bae0b | 2018-07-19 12:10:14 +0800 | [diff] [blame] | 15 | from bisect_kit import codechange |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 16 | from bisect_kit import common |
| 17 | from bisect_kit import configure |
Kuang-che Wu | 414d67f | 2019-05-28 11:28:57 +0800 | [diff] [blame] | 18 | from bisect_kit import cros_lab_util |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 19 | from bisect_kit import cros_util |
Kuang-che Wu | 0ebbf7c | 2019-08-28 18:19:19 +0800 | [diff] [blame] | 20 | from bisect_kit import errors |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 21 | from bisect_kit import repo_util |
| 22 | from bisect_kit import util |
| 23 | |
| 24 | logger = logging.getLogger(__name__) |
| 25 | |
| 26 | |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 27 | def add_build_and_deploy_arguments(parser_group): |
| 28 | parser_group.add_argument( |
| 29 | '--goma_chromeos_dir', |
| 30 | type=cli.argtype_dir_path, |
| 31 | default=configure.get('GOMA_CHROMEOS_DIR'), |
| 32 | help='Goma-chromeos installed directory to mount into the Chrome OS ' |
| 33 | 'chroot') |
| 34 | parser_group.add_argument( |
| 35 | '--clobber-stateful', |
| 36 | '--clobber_stateful', |
| 37 | action='store_true', |
| 38 | help='Clobber stateful partition when performing update') |
| 39 | parser_group.add_argument( |
| 40 | '--no-disable-rootfs-verification', |
| 41 | '--no_disable_rootfs_verification', |
| 42 | dest='disable_rootfs_verification', |
| 43 | action='store_false', |
| 44 | help="Don't disable rootfs verification after update is completed") |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 45 | parser_group.add_argument( |
| 46 | '--no-mark-as-stable', |
| 47 | '--no_mark_as_stable', |
| 48 | dest='mark_as_stable', |
| 49 | action='store_false', |
| 50 | help="Don't mark repo stable") |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 51 | |
| 52 | |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 53 | def create_argument_parser(): |
Kuang-che Wu | d2d6e41 | 2021-01-28 16:26:41 +0800 | [diff] [blame] | 54 | parents = [common.common_argument_parser, common.session_optional_parser] |
| 55 | parser = argparse.ArgumentParser(parents=parents) |
Kuang-che Wu | fe1e88a | 2019-09-10 21:52:25 +0800 | [diff] [blame] | 56 | cli.patching_argparser_exit(parser) |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 57 | parser.add_argument( |
Kuang-che Wu | 0ebbf7c | 2019-08-28 18:19:19 +0800 | [diff] [blame] | 58 | '--dut', |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 59 | type=cli.argtype_notempty, |
| 60 | metavar='DUT', |
Kuang-che Wu | 0ebbf7c | 2019-08-28 18:19:19 +0800 | [diff] [blame] | 61 | default=configure.get('DUT'), |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 62 | help='DUT address') |
| 63 | parser.add_argument( |
| 64 | 'rev', |
| 65 | nargs='?', |
| 66 | type=cli.argtype_notempty, |
Kuang-che Wu | 99e808f | 2019-06-26 12:17:32 +0800 | [diff] [blame] | 67 | metavar='CROS_VERSION', |
| 68 | default=configure.get('CROS_VERSION', ''), |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 69 | help='ChromeOS local build version string, in format short version, ' |
| 70 | 'full version, or "full,full+N"') |
| 71 | parser.add_argument( |
| 72 | '--board', |
| 73 | metavar='BOARD', |
| 74 | default=configure.get('BOARD', ''), |
| 75 | help='ChromeOS board name') |
| 76 | parser.add_argument( |
Kuang-che Wu | c95fc15 | 2018-06-28 18:13:22 +0800 | [diff] [blame] | 77 | '--chromeos_root', |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 78 | type=cli.argtype_dir_path, |
Kuang-che Wu | c95fc15 | 2018-06-28 18:13:22 +0800 | [diff] [blame] | 79 | metavar='CHROMEOS_ROOT', |
| 80 | default=configure.get('CHROMEOS_ROOT', ''), |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 81 | help='ChromeOS tree root (default: %(default)s)') |
| 82 | parser.add_argument( |
Kuang-che Wu | d8fc957 | 2018-10-03 21:00:41 +0800 | [diff] [blame] | 83 | '--chromeos_mirror', |
Kuang-che Wu | e4bae0b | 2018-07-19 12:10:14 +0800 | [diff] [blame] | 84 | type=cli.argtype_dir_path, |
Kuang-che Wu | d8fc957 | 2018-10-03 21:00:41 +0800 | [diff] [blame] | 85 | default=configure.get('CHROMEOS_MIRROR', ''), |
Kuang-che Wu | e4bae0b | 2018-07-19 12:10:14 +0800 | [diff] [blame] | 86 | help='ChromeOS repo mirror path') |
| 87 | parser.add_argument( |
Kuang-che Wu | 85b61f0 | 2020-03-11 17:41:46 +0800 | [diff] [blame] | 88 | '--skip_sync_code', |
| 89 | action='store_true', |
| 90 | help='Skip the step syncing source code') |
| 91 | parser.add_argument( |
Kuang-che Wu | a2fe988 | 2018-09-05 17:16:31 +0800 | [diff] [blame] | 92 | '--nobuild', |
| 93 | action='store_true', |
Kuang-che Wu | 85b61f0 | 2020-03-11 17:41:46 +0800 | [diff] [blame] | 94 | help='Stop after source code sync; do not build; imply --noimage') |
Kuang-che Wu | 7f82c6f | 2019-08-12 14:29:28 +0800 | [diff] [blame] | 95 | parser.add_argument( |
| 96 | '--noimage', |
| 97 | action='store_true', |
| 98 | help='Build packages only; do not build image; imply --nodeploy') |
Kuang-che Wu | a2fe988 | 2018-09-05 17:16:31 +0800 | [diff] [blame] | 99 | parser.add_argument( |
| 100 | '--nodeploy', action='store_true', help='Do not deploy after build') |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 101 | |
| 102 | group = parser.add_argument_group(title='Build and deploy options') |
| 103 | add_build_and_deploy_arguments(group) |
| 104 | |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 105 | return parser |
| 106 | |
| 107 | |
| 108 | def mark_as_stable(opts): |
Kuang-che Wu | b7fb243 | 2019-04-02 18:03:25 +0800 | [diff] [blame] | 109 | overlays = util.check_output( |
| 110 | 'chromite/bin/cros_list_overlays', '--all', |
| 111 | cwd=opts.chromeos_root).splitlines() |
| 112 | |
| 113 | # Get overlays listed in manifest file. |
| 114 | known_projects = [] |
Kuang-che Wu | 3d04eda | 2019-09-05 23:56:40 +0800 | [diff] [blame] | 115 | for path in repo_util.list_projects(opts.chromeos_root): |
Kuang-che Wu | b7fb243 | 2019-04-02 18:03:25 +0800 | [diff] [blame] | 116 | known_projects.append( |
| 117 | os.path.realpath(os.path.join(opts.chromeos_root, path))) |
| 118 | logger.debug('known_projects %s', known_projects) |
| 119 | |
| 120 | # Skip recent added overlays. |
| 121 | # cros_mark_as_stable expects all overlays is recorded in manifest file |
| 122 | # but we haven't synthesized manifest files for each intra versions yet. |
| 123 | # TODO(kcwu): synthesize manifest file |
| 124 | for overlay in list(overlays): |
| 125 | if 'private-overlays/' in overlay and overlay not in known_projects: |
| 126 | logger.warning( |
| 127 | 'bisect-kit cannot handle recently added overlay %s yet; ignore', |
| 128 | overlay) |
| 129 | overlays.remove(overlay) |
| 130 | continue |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 131 | |
| 132 | cmd = [ |
| 133 | 'chromite/bin/cros_mark_as_stable', |
| 134 | '-b', opts.board, |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 135 | '--list_revisions', |
Kuang-che Wu | b7fb243 | 2019-04-02 18:03:25 +0800 | [diff] [blame] | 136 | '--overlays', ':'.join(overlays), |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 137 | '--debug', |
| 138 | '--all', |
| 139 | 'commit', |
| 140 | ] # yapf: disable |
Kuang-che Wu | c95fc15 | 2018-06-28 18:13:22 +0800 | [diff] [blame] | 141 | util.check_call(*cmd, cwd=opts.chromeos_root) |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 142 | |
| 143 | |
| 144 | def cleanup(opts): |
Kuang-che Wu | b9bc49a | 2021-01-27 16:27:51 +0800 | [diff] [blame] | 145 | logger.info('clean up leftover in the source tree from the last build') |
Kuang-che Wu | 3d04eda | 2019-09-05 23:56:40 +0800 | [diff] [blame] | 146 | repo_util.cleanup_unexpected_files(opts.chromeos_root) |
| 147 | |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 148 | logger.info('clean up previous result of "mark as stable"') |
Kuang-che Wu | c95fc15 | 2018-06-28 18:13:22 +0800 | [diff] [blame] | 149 | repo_util.abandon(opts.chromeos_root, 'stabilizing_branch') |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 150 | |
| 151 | |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 152 | def _build_packages(opts): |
| 153 | logger.info('build packages') |
| 154 | |
| 155 | # chrome_root is only defined if called from chrome's switcher. |
| 156 | # This means using chromeos build_packages flow to build chrome during chrome |
| 157 | # bisection. |
| 158 | chrome_root = getattr(opts, 'chrome_root', None) |
| 159 | |
| 160 | if not opts.goma_chromeos_dir: |
Kuang-che Wu | 0eb2fca | 2020-03-17 12:28:43 +0800 | [diff] [blame] | 161 | default_goma_chromeos_dir = os.path.expanduser('~/goma') |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 162 | if os.path.exists(default_goma_chromeos_dir): |
| 163 | logger.debug('found %s available, use goma automatically', |
| 164 | default_goma_chromeos_dir) |
| 165 | opts.goma_chromeos_dir = default_goma_chromeos_dir |
| 166 | |
| 167 | cros_util.build_packages( |
| 168 | opts.chromeos_root, |
| 169 | opts.board, |
| 170 | chrome_root=chrome_root, |
| 171 | goma_dir=opts.goma_chromeos_dir, |
| 172 | afdo_use=True) |
| 173 | |
| 174 | |
| 175 | def build(opts, do_mark_as_stable=True): |
Kuang-che Wu | 28980b2 | 2019-07-31 19:51:45 +0800 | [diff] [blame] | 176 | # Used many times in this function, shorten it. |
| 177 | chromeos_root = opts.chromeos_root |
| 178 | |
Kuang-che Wu | ad5ac7b | 2020-02-20 19:02:52 +0800 | [diff] [blame] | 179 | # create and hotfix chroot if necessary |
| 180 | cros_util.prepare_chroot(chromeos_root) |
Kuang-che Wu | 9890ce8 | 2018-07-07 15:14:10 +0800 | [diff] [blame] | 181 | |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 182 | if do_mark_as_stable: |
| 183 | logger.info('mark as stable') |
| 184 | mark_as_stable(opts) |
Kuang-che Wu | 9890ce8 | 2018-07-07 15:14:10 +0800 | [diff] [blame] | 185 | |
Kuang-che Wu | 7f82c6f | 2019-08-12 14:29:28 +0800 | [diff] [blame] | 186 | if opts.noimage: |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 187 | _build_packages(opts) |
Kuang-che Wu | 7f82c6f | 2019-08-12 14:29:28 +0800 | [diff] [blame] | 188 | return None |
| 189 | |
Kuang-che Wu | af91710 | 2020-04-10 18:03:22 +0800 | [diff] [blame] | 190 | cached_name = 'bisect-%s' % util.escape_rev(opts.rev) |
Kuang-che Wu | 28980b2 | 2019-07-31 19:51:45 +0800 | [diff] [blame] | 191 | image_folder = os.path.join(cros_util.cached_images_dir, opts.board, |
| 192 | cached_name) |
| 193 | image_path = os.path.join(image_folder, cros_util.test_image_filename) |
| 194 | |
| 195 | # If the given version is already built, reuse it. |
Jae Hoon Kim | 25474b7 | 2021-04-12 18:56:15 -0700 | [diff] [blame] | 196 | chromeos_root_image_folder = os.path.join(chromeos_root, image_folder) |
| 197 | chromeos_root_image_path = os.path.join(chromeos_root, image_path) |
| 198 | if not os.path.exists(chromeos_root_image_path): |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 199 | _build_packages(opts) |
Kuang-che Wu | 28980b2 | 2019-07-31 19:51:45 +0800 | [diff] [blame] | 200 | built_image_folder = cros_util.build_image(chromeos_root, opts.board) |
Jae Hoon Kim | 25474b7 | 2021-04-12 18:56:15 -0700 | [diff] [blame] | 201 | os.makedirs(os.path.dirname(chromeos_root_image_folder), exist_ok=True) |
| 202 | if os.path.exists(chromeos_root_image_folder): |
| 203 | os.unlink(chromeos_root_image_folder) |
| 204 | # Create a relative symlink, so the condition actually only comes in here if |
| 205 | # the image folder is actually missing. |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 206 | os.symlink( |
| 207 | os.path.join('../../..', built_image_folder), |
| 208 | chromeos_root_image_folder) |
Kuang-che Wu | 28980b2 | 2019-07-31 19:51:45 +0800 | [diff] [blame] | 209 | |
Kuang-che Wu | 28980b2 | 2019-07-31 19:51:45 +0800 | [diff] [blame] | 210 | return image_path |
Kuang-che Wu | 9890ce8 | 2018-07-07 15:14:10 +0800 | [diff] [blame] | 211 | |
| 212 | |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 213 | def build_and_deploy(opts): |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 214 | try: |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 215 | image_path = build(opts, do_mark_as_stable=opts.mark_as_stable) |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 216 | except cros_util.NeedRecreateChrootException as e: |
| 217 | logger.warning('recreate chroot and retry again, reason: %s', e) |
| 218 | util.check_output( |
| 219 | 'chromite/bin/cros_sdk', '--delete', cwd=opts.chromeos_root) |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 220 | image_path = build(opts, do_mark_as_stable=opts.mark_as_stable) |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 221 | |
| 222 | if opts.noimage or opts.nodeploy: |
| 223 | return 0 |
| 224 | |
Kuang-che Wu | 721e890 | 2021-03-19 12:18:53 +0800 | [diff] [blame] | 225 | image_info = cros_util.ImageInfo() |
| 226 | image_info[cros_util.ImageType.DISK_IMAGE] = image_path |
| 227 | |
| 228 | if cros_util.provision_image_with_retry( |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 229 | opts.chromeos_root, |
| 230 | opts.dut, |
| 231 | opts.board, |
Kuang-che Wu | 721e890 | 2021-03-19 12:18:53 +0800 | [diff] [blame] | 232 | image_info, |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 233 | clobber_stateful=opts.clobber_stateful, |
| 234 | disable_rootfs_verification=opts.disable_rootfs_verification, |
Kuang-che Wu | 2ac9a92 | 2020-09-03 16:50:12 +0800 | [diff] [blame] | 235 | repair_callback=cros_lab_util.repair, |
| 236 | force_reboot_callback=cros_lab_util.reboot_via_servo): |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 237 | return 0 |
| 238 | return 1 |
| 239 | |
| 240 | |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 241 | def switch(opts): |
| 242 | cleanup(opts) |
| 243 | |
Kuang-che Wu | 85b61f0 | 2020-03-11 17:41:46 +0800 | [diff] [blame] | 244 | if not opts.skip_sync_code: |
| 245 | logger.info('switch source code') |
| 246 | config = dict( |
| 247 | board=opts.board, |
| 248 | chromeos_root=opts.chromeos_root, |
| 249 | chromeos_mirror=opts.chromeos_mirror) |
| 250 | spec_manager = cros_util.ChromeOSSpecManager(config) |
| 251 | cache = repo_util.RepoMirror(opts.chromeos_mirror) |
| 252 | code_manager = codechange.CodeManager(opts.chromeos_root, spec_manager, |
| 253 | cache) |
| 254 | code_manager.switch(opts.rev) |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 255 | |
Kuang-che Wu | a2fe988 | 2018-09-05 17:16:31 +0800 | [diff] [blame] | 256 | if opts.nobuild: |
Kuang-che Wu | 414d67f | 2019-05-28 11:28:57 +0800 | [diff] [blame] | 257 | return 0 |
Kuang-che Wu | a2fe988 | 2018-09-05 17:16:31 +0800 | [diff] [blame] | 258 | |
Kuang-che Wu | a9a20bb | 2019-09-05 22:24:04 +0800 | [diff] [blame] | 259 | return build_and_deploy(opts) |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 260 | |
| 261 | |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 262 | def parse_args(args): |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 263 | parser = create_argument_parser() |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 264 | return parser.parse_args(args) |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 265 | |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 266 | |
| 267 | def inner_main(opts): |
Kuang-che Wu | 99e808f | 2019-06-26 12:17:32 +0800 | [diff] [blame] | 268 | # --nobuild imply --nodeploy |
| 269 | if opts.nobuild: |
| 270 | opts.nodeploy = True |
| 271 | |
Kuang-che Wu | 85b61f0 | 2020-03-11 17:41:46 +0800 | [diff] [blame] | 272 | if opts.skip_sync_code and opts.nobuild: |
| 273 | raise errors.ArgumentError('--skip_sync_code and --nobuild', |
| 274 | 'nothing to do') |
Kuang-che Wu | 0ebbf7c | 2019-08-28 18:19:19 +0800 | [diff] [blame] | 275 | if not opts.dut: |
| 276 | if not opts.nodeploy: |
| 277 | raise errors.ArgumentError('--dut', |
| 278 | 'DUT can be omitted only if --nodeploy') |
| 279 | if not opts.board: |
| 280 | raise errors.ArgumentError('--board', |
| 281 | 'board must be specified if no --dut') |
Kuang-che Wu | 4427814 | 2019-03-04 11:33:57 +0800 | [diff] [blame] | 282 | if not opts.nodeploy: |
| 283 | if not cros_util.is_good_dut(opts.dut): |
Kuang-che Wu | 414d67f | 2019-05-28 11:28:57 +0800 | [diff] [blame] | 284 | logger.fatal('%r is not a good DUT', opts.dut) |
| 285 | if not cros_lab_util.repair(opts.dut): |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 286 | return cli.EXIT_CODE_FATAL |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 287 | if not opts.board: |
| 288 | opts.board = cros_util.query_dut_board(opts.dut) |
| 289 | |
| 290 | if cros_util.is_cros_short_version(opts.rev): |
| 291 | opts.rev = cros_util.version_to_full(opts.board, opts.rev) |
| 292 | |
Kuang-che Wu | 721e890 | 2021-03-19 12:18:53 +0800 | [diff] [blame] | 293 | cros_util.prepare_chroot(opts.chromeos_root) |
| 294 | |
Kuang-che Wu | 414d67f | 2019-05-28 11:28:57 +0800 | [diff] [blame] | 295 | try: |
| 296 | returncode = switch(opts) |
| 297 | except Exception: |
| 298 | logger.exception('switch failed') |
| 299 | returncode = 1 |
| 300 | |
Kuang-che Wu | 5f445bf | 2019-06-04 19:36:44 +0800 | [diff] [blame] | 301 | if not opts.nodeploy: |
| 302 | # No matter switching succeeded or not, DUT must be in good state. |
| 303 | # switch() already tried repairing if possible, no repair here. |
| 304 | if not cros_util.is_good_dut(opts.dut): |
| 305 | logger.fatal('%r is not a good DUT', opts.dut) |
| 306 | returncode = cli.EXIT_CODE_FATAL |
Kuang-che Wu | 414d67f | 2019-05-28 11:28:57 +0800 | [diff] [blame] | 307 | logger.info('done') |
Jae Hoon Kim | 7cbf64e | 2021-04-16 10:06:32 -0700 | [diff] [blame] | 308 | return returncode |
| 309 | |
| 310 | |
| 311 | @cli.fatal_error_handler |
| 312 | def main(args=None): |
| 313 | common.init() |
| 314 | opts = parse_args(args) |
| 315 | common.config_logging(opts) |
| 316 | sys.exit(inner_main(opts)) |
Kuang-che Wu | bfc4a64 | 2018-04-19 11:54:08 +0800 | [diff] [blame] | 317 | |
| 318 | |
| 319 | if __name__ == '__main__': |
| 320 | main() |