blob: 154be8f67d2cdac1040c858e88cfe0d1ed255337 [file] [log] [blame]
#!/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()