blob: d1c237238c593b7353d5980b36b4ab99a9c1680f [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2021 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.
import argparse
import json
import subprocess
import sys
from chromite.lib.cros_build_lib import IsInsideChroot
user_conf = '/etc/make.conf.user'
conf_line = 'source ${ROOT}/etc/make.conf.binhost'
def run_prechecks():
if not IsInsideChroot():
print('This script must be run inside the CrOS chroot')
sys.exit(1)
with open(user_conf, 'r') as f:
for line in f.read().split('\n'):
if line == conf_line:
break
else:
print(f'Add "{conf_line}" to {user_conf} and rerun')
sys.exit(1)
def write_binhost(board, s):
subprocess.run(
['sudo', 'tee', f'/build/{board}/etc/make.conf.binhost'],
input=s.encode(), check=True)
def is_internal():
url = subprocess.run(
['git', 'config', '--get', 'remote.origin.url'],
stdout=subprocess.PIPE,
cwd='/mnt/host/source/.repo/manifests/',
check=True).stdout.decode().strip()
if 'chrome-internal.googlesource.com/chromeos/manifest-internal' in url:
return True
if 'chromium.googlesource.com/chromiumos/manifest' in url:
return False
print(f'Unknown manifest source {url}')
sys.exit(1)
def get_current_snapshot():
return subprocess.run(
['git', 'rev-parse', 'HEAD'],
stdout=subprocess.PIPE,
cwd='/mnt/host/source/.repo/manifests/',
check=True).stdout.decode().strip()
def internal_to_external_snapshot(rev):
return subprocess.run(
['git', 'footers', '--key', 'Cr-External-Snapshot', rev],
stdout=subprocess.PIPE,
cwd='/mnt/host/source/.repo/manifests/',
check=True).stdout.decode().strip()
def run_query(query):
query_str = json.dumps(query)
return subprocess.run(
['bb', 'ls', '-json', '-fields', 'output', '-predicate', query_str],
stdout=subprocess.PIPE,
check=True).stdout.decode()
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=f"""Find up-to-date binary package sources
Chrome OS tries to speed up builds by using binary packages taken from
CI builds. However, the configuration file that controls which build
these packages are taken from is itself a part of the git repo, which
means it is effectivly always out of date. See crbug.com/1073565 for
more details.
This script tries to solve this by looking up a CI build which matches
the currently checked out manifest snapshot. Only exact matches are
used, so this is most useful if you sync to the "stable" manifest
branch. If you haven't used this script before, you must add the line
{conf_line}
to the file {user_conf} in your chroot. This script also
relies on the buildbucket CLI tool. If you haven't previously used it,
you will need to run "bb auth-login".""")
parser.add_argument('board', type=str, help='The board to configure')
args = parser.parse_args()
run_prechecks()
query = {
'builder': {
'project': 'chromeos',
'bucket': 'postsubmit',
'builder': f'{args.board}-postsubmit',
},
'tags': [{
'key': 'snapshot',
'value': get_current_snapshot(),
}],
'status': 'SUCCESS',
}
bb_ret = run_query(query)
# Some postsubmit builders use the external manifest, so if we
# didn't find anything and we were using the internal manifest,
# try using the external one instead.
if not bb_ret.strip() and is_internal():
query['tags'][0]['value'] = (
internal_to_external_snapshot(query['tags'][0]['value']))
bb_ret = run_query(query)
# If we still didn't find anything, give up.
if not bb_ret.strip():
print('Failed to find an exact postsubmit match')
# Clear the config file so builds will fallback to the
# PORTAGE_BINHOST it would normally use.
write_binhost(args.board, '')
sys.exit(1)
bb_ret = json.loads(bb_ret)
uri = bb_ret['output']['properties']['prebuilts_uri']
write_binhost(args.board, f'PORTAGE_BINHOST={uri}\n')
if __name__ == '__main__':
main()