| #!/usr/bin/env python2 |
| # -*- coding: utf-8 -*- |
| # Copyright 2018 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Switcher for chromeos localbuild bisecting.""" |
| |
| from __future__ import print_function |
| import argparse |
| import logging |
| import os |
| |
| from bisect_kit import cli |
| from bisect_kit import codechange |
| from bisect_kit import common |
| from bisect_kit import configure |
| from bisect_kit import cros_util |
| from bisect_kit import repo_util |
| from bisect_kit import util |
| |
| logger = logging.getLogger(__name__) |
| |
| |
| def create_argument_parser(): |
| parser = argparse.ArgumentParser() |
| common.add_common_arguments(parser) |
| parser.add_argument( |
| 'dut', |
| nargs='?', |
| type=cli.argtype_notempty, |
| metavar='DUT', |
| default=configure.get('DUT', ''), |
| help='DUT address') |
| parser.add_argument( |
| 'rev', |
| nargs='?', |
| type=cli.argtype_notempty, |
| metavar='INTRA_REV', |
| default=configure.get('INTRA_REV', ''), |
| help='ChromeOS local build version string, in format short version, ' |
| 'full version, or "full,full+N"') |
| parser.add_argument( |
| '--board', |
| metavar='BOARD', |
| default=configure.get('BOARD', ''), |
| help='ChromeOS board name') |
| parser.add_argument( |
| '--chromeos_root', |
| type=cli.argtype_dir_path, |
| metavar='CHROMEOS_ROOT', |
| default=configure.get('CHROMEOS_ROOT', ''), |
| help='ChromeOS tree root (default: %(default)s)') |
| parser.add_argument( |
| '--chromeos_mirror', |
| type=cli.argtype_dir_path, |
| default=configure.get('CHROMEOS_MIRROR', ''), |
| help='ChromeOS repo mirror path') |
| parser.add_argument( |
| '--clobber-stateful', |
| action='store_true', |
| help='Clobber stateful partition when performing update') |
| parser.add_argument( |
| '--no-disable-rootfs-verification', |
| dest='disable_rootfs_verification', |
| action='store_false', |
| help="Don't disable rootfs verification after update is completed") |
| parser.add_argument( |
| '--nobuild', |
| action='store_true', |
| help='Sync source code only; do not build; imply --nodeploy') |
| parser.add_argument( |
| '--nodeploy', action='store_true', help='Do not deploy after build') |
| return parser |
| |
| |
| def mark_as_stable(opts): |
| cmd = ['chromite/bin/cros_list_overlays', '--all'] |
| output = util.check_output(*cmd, cwd=opts.chromeos_root) |
| overlays = ':'.join(output.splitlines()) |
| |
| cmd = [ |
| 'chromite/bin/cros_mark_as_stable', |
| '-b', opts.board, |
| '-o', overlays, |
| '--debug', |
| '--all', |
| 'commit', |
| ] # yapf: disable |
| util.check_call(*cmd, cwd=opts.chromeos_root) |
| |
| |
| def cleanup(opts): |
| logger.info('clean up previous result of "mark as stable"') |
| repo_util.abandon(opts.chromeos_root, 'stabilizing_branch') |
| |
| |
| def build(opts): |
| # create chroot if necessary |
| if (not os.path.exists(os.path.join(opts.chromeos_root, 'chroot')) and |
| not os.path.exists(os.path.join(opts.chromeos_root, 'chroot.img'))): |
| util.check_output( |
| 'chromite/bin/cros_sdk', '--create', cwd=opts.chromeos_root) |
| |
| logger.info('mark as stable') |
| mark_as_stable(opts) |
| |
| logger.info('build image') |
| return cros_util.build_image(opts.chromeos_root, opts.board, opts.rev) |
| |
| |
| def switch(opts): |
| cleanup(opts) |
| |
| logger.info('switch source code') |
| config = dict( |
| board=opts.board, |
| chromeos_root=opts.chromeos_root, |
| chromeos_mirror=opts.chromeos_mirror) |
| spec_manager = cros_util.ChromeOSSpecManager(config) |
| cache = repo_util.RepoMirror(opts.chromeos_mirror) |
| code_manager = codechange.CodeManager(opts.chromeos_root, spec_manager, cache) |
| code_manager.switch(opts.rev) |
| |
| if opts.nobuild: |
| return |
| |
| try: |
| image_path = build(opts) |
| except cros_util.NeedRecreateChrootException as e: |
| logger.warning('recreate chroot and retry again, reason: %s', e) |
| util.check_output( |
| 'chromite/bin/cros_sdk', '--delete', cwd=opts.chromeos_root) |
| image_path = build(opts) |
| |
| if opts.nodeploy: |
| return |
| |
| cros_util.cros_flash( |
| opts.chromeos_root, |
| opts.dut, |
| opts.board, |
| image_path, |
| clobber_stateful=opts.clobber_stateful, |
| disable_rootfs_verification=opts.disable_rootfs_verification, |
| run_inside_chroot=True) |
| |
| |
| def main(args=None): |
| common.init() |
| parser = create_argument_parser() |
| opts = parser.parse_args(args) |
| common.config_logging(opts) |
| |
| assert opts.nodeploy or cros_util.is_dut(opts.dut) |
| if not opts.board: |
| opts.board = cros_util.query_dut_board(opts.dut) |
| |
| if cros_util.is_cros_short_version(opts.rev): |
| opts.rev = cros_util.version_to_full(opts.board, opts.rev) |
| |
| switch(opts) |
| |
| |
| if __name__ == '__main__': |
| main() |