blob: 4b4d9ea5ac38b1752b1f42d94bef60d1c6b5281f [file] [log] [blame]
Jack Rosenthal543bb062020-06-05 15:30:09 -06001#!/usr/bin/env python3
2# Copyright 2020 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6# This file uses 2-space indentations.
7# pylint: disable=bad-indentation
8
9# This is contrib-quality code: not all functions/classes are
10# documented.
11# pylint: disable=missing-function-docstring
12# pylint: disable=missing-class-docstring
13# pylint: disable=class-missing-docstring
14
15# Classes make heavy-use of setattr to dynamically set the attributes
16# on an object. Disable this check which gets confused very
17# frequently.
18# pylint: disable=no-member
19
20"""Utility script to auto-convert a pre-unibuild board to unibuild."""
21
22import argparse
23import datetime
24import json
25import os
26import pathlib
27import re
28import shlex
29import subprocess
30import sys
31import tempfile
32# pylint: disable=import-error
33import yaml
34# pylint: enable=import-error
35
36
37make_defaults_search_and_destroy_re = re.compile(
38 r'(?:^\s*)*(?:^\s*#.*\s*)*^\s*USE="\s*\$\{?USE\}?\s*-unibuild\s*"\s*$',
39 re.MULTILINE)
40
41
42def log(message):
43 print('[{}] {}'.format(datetime.datetime.now(), message), file=sys.stderr)
44
45
46def prepend_all_lines(text, prepend):
47 return ''.join(
48 '{}{}\n'.format(prepend, line)
49 for line in text.splitlines())
50
51
52def gen_cros_copyright(line_comment='# '):
53 return prepend_all_lines(
54 """Copyright {} The Chromium OS Authors. All rights reserved.
55Use of this source code is coverned by a BSD-style license that can be
56found in the LICENSE file.""".format(datetime.datetime.now().strftime('%Y')),
57 line_comment)
58
59
60def yaml_str_representer(dumper, data):
61 style = None
62 tag = 'tag:yaml.org,2002:str'
63 if '\n' in data:
64 style = '|'
65 return dumper.represent_scalar(tag, data, style)
66
67
68yaml.add_representer(str, yaml_str_representer)
69
70
71def format_yaml(config):
72 conf_str = yaml.dump(config, indent=2, default_flow_style=False)
73 out = gen_cros_copyright()
74 out += """
75# This board only supports a single config, defined below, as it is a
76# migrated pre-unibuild device.
77device-config: &device_config\n"""
78 out += prepend_all_lines(conf_str, ' ')
79 out += """
80# Required dunder for chromeos-config to support a single device.
81chromeos:
82 devices:
83 - skus:
84 - config: *device_config\n"""
85 return out
86
87
88def generate_vpackage(depends):
89 return gen_cros_copyright() + """
90EAPI=7
91
92# cros_workon applies only to ebuild and files directory. Use the
93# canonical empty project.
94CROS_WORKON_PROJECT="chromiumos/infra/build/empty-project"
95CROS_WORKON_LOCALNAME="../platform/empty-project"
96
97inherit cros-workon
98
99DESCRIPTION="ChromeOS Unibuild Config virtual package"
100HOMEPAGE="https://chromium.googlesource.com/chromiumos/platform2/+/master/chromeos-config/README.md"
101
102LICENSE="BSD-Google"
103SLOT="0"
104KEYWORDS="~*"
105
106DEPEND="%(depends)s"
107RDEPEND="${DEPEND}"
108""" % {
109 'depends':
110 (''.join('\n\t{}'.format(d) for d in depends) + '\n')
111 if len(depends) > 1 else
112 ''.join(depends)}
113
114
115def generate_bsp_ebuild(private=False):
116 return gen_cros_copyright() + """
117EAPI=7
118
119# cros_workon applies only to ebuild and files directory. Use the
120# canonical empty project.
121CROS_WORKON_PROJECT="chromiumos/infra/build/empty-project"
122CROS_WORKON_LOCALNAME="../platform/empty-project"
123
124inherit cros-workon cros-unibuild
125
126DESCRIPTION="ChromeOS model configuration"
127HOMEPAGE="https://chromium.googlesource.com/chromiumos/platform2/+/master/chromeos-config/README.md"
128
129LICENSE="BSD-Google"
130SLOT="0"
131KEYWORDS="~*"
132
133src_install() {
134\tinstall%(maybe_private)s_model_files
135}
136""" % {'maybe_private': '_private' if private else ''}
137
138
139def generate_firmware_ebuild(board_name):
140 return gen_cros_copyright() + """
141# Change this version number when any change is made to model.yaml
142# in order to trigger an auto-revbump is required.
143# VERSION=REVBUMP-0.0.1
144
145EAPI=7
146CROS_WORKON_COMMIT=""
147CROS_WORKON_TREE=""
148CROS_WORKON_LOCALNAME="platform/firmware"
149CROS_WORKON_PROJECT="chromiumos/platform/firmware"
150CROS_BOARDS=( %(board_name)s )
151
152inherit cros-workon cros-firmware cros-unibuild
153
154DESCRIPTION="Chrome OS Firmware (%(board_name)s)"
155HOMEPAGE="http://src.chromium.org"
156LICENSE="BSD-Google"
157SLOT="0"
158KEYWORDS="~*"
159
160RDEPEND=""
161
162# Unified Builds firmware URL's are read from:
163# chromeos-base/chromeos-config-bsp-private/files/model.yaml
164# in this repository. Those config files output the SRC_URI's used by Portage.
165#
166# Update the model.yaml, then run this command from the
167# src/platform/dev/contrib directory:
168#
169# ./cros_update_firmware --board=%(board_name)s
170#
171# Verify the changes by running:
172# /build/%(board_name)s/usr/sbin/chromeos-firmwareupdate --manifest
173#
174# If this works then you can create a CL with your changes, which should include
175# the files:
176# chromeos-base/chromeos-config-bsp-private/files/model.yaml
177# chromeos-base/chromeos-firmware-%(board_name)s/Manifest
178# chromeos-base/chromeos-firmware-%(board_name)s/files/srcuris
179# chromeos-base/chromeos-firmware-%(board_name)s/chromeos-firmware-%(board_name)s-9999.ebuild
180cros-firmware_setup_source
181""" % {'board_name': board_name}
182
183
184def find_file(searchdir, name):
185 results = []
186 for root, _, files in os.walk(searchdir):
187 if name in files:
188 results.append(pathlib.Path(root) / name)
189 return results
190
191
192def find_one_file(searchdir, name):
193 results = find_file(searchdir, name)
194 assert len(results) == 1
195 return results.pop()
196
197
198def sh_getvar(script, varname):
199 script = script + ('\necho "${%s}"\n' % varname)
200 with tempfile.NamedTemporaryFile('w') as f:
201 f.write(script)
202 f.flush()
203 res = subprocess.run(['sh', f.name], stdout=subprocess.PIPE,
204 check=True, encoding='utf-8')
205 return res.stdout.strip() or None
206
207
208def write_file(fullpath, file_contents):
209 os.makedirs(fullpath.parent, exist_ok=True)
210 log('Writing {}...'.format(fullpath))
211 with open(fullpath, 'w') as f:
212 f.write(file_contents)
213
214
215def generate_make_defaults(contents):
216 contents = make_defaults_search_and_destroy_re.sub('', contents)
217 contents += """
218# Enable chromeos-config.
219USE="${USE} unibuild"
220"""
221 return contents
222
223
224class CrosConfig:
225 def __init__(self, public_yaml_raw, private_yaml_raw):
226 with tempfile.NamedTemporaryFile(mode='w', delete=False) as merged_tempfile, \
227 tempfile.NamedTemporaryFile(mode='w') as public_yaml_tempfile, \
228 tempfile.NamedTemporaryFile(mode='w') as private_yaml_tempfile:
229 public_yaml_tempfile.write(public_yaml_raw)
230 public_yaml_tempfile.flush()
231
232 private_yaml_tempfile.write(private_yaml_raw)
233 private_yaml_tempfile.flush()
234
235 log('Merging and validating config schema...')
236 subprocess.run(['cros_config_schema', '-o', merged_tempfile.name,
237 '-m', public_yaml_tempfile.name,
238 private_yaml_tempfile.name], check=True)
239 self.merged_yaml = merged_tempfile.name
240
241 def run_host_command(self, *args):
242 return subprocess.run(['cros_config_host', '-c', self.merged_yaml]
243 + list(args),
244 check=True, encoding='utf-8',
245 stdout=subprocess.PIPE).stdout
246
247
248class BoardOverlays:
249 FIRMWARE_ATTRS = [
250 ('CROS_FIRMWARE_MAIN_IMAGE', 'bcs_main_ro'),
251 ('CROS_FIRMWARE_MAIN_RW_IMAGE', 'bcs_main_rw'),
252 ('CROS_FIRMWARE_EC_IMAGE', 'bcs_ec'),
253 ('CROS_FIRMWARE_PD_IMAGE', 'bcs_pd'),
254 ]
255
256 MAKE_DEFAULTS_ATTRS = [
257 ('EC_FIRMWARE', 'ec_firmwares'),
258 ('PD_FIRMWARE', 'pd_firmwares'),
259 ('EC_FIRMWARE_EXTRA', 'ec_firmware_extras'),
260 ('FPMCU_FIRMWARE', 'fpmcu_firmware'),
261 ('USE', 'use_flags'),
262 ]
263
264 def __init__(self, board_name, checkout, mosys_platform):
265 self.board_name = board_name
266 self.mosys_platform = mosys_platform
267 self.public_overlay = (checkout / 'src' / 'overlays'
268 / f'overlay-{board_name}')
269 log('Public overlay path: {}'.format(self.public_overlay))
270 self.private_overlay = (checkout / 'src' / 'private-overlays'
271 / f'overlay-{board_name}-private')
272 log('Private overlay path: {}'.format(self.private_overlay))
273
274 assert self.public_overlay.is_dir()
275 assert self.private_overlay.is_dir()
276
277 # Find the firmware ebuild
278 self.firmware_ebuild_path = find_one_file(
279 self.private_overlay, f'chromeos-firmware-{board_name}-9999.ebuild')
280 log('Firmware ebuild path: {}'.format(self.firmware_ebuild_path))
281
282 # Read the firmware attrs from it
283 for _, attr in self.FIRMWARE_ATTRS:
284 setattr(self, attr, None)
285
286 with open(self.firmware_ebuild_path) as f:
287 for line in f:
288 if '#' in line:
289 line, _, _ = line.partition('#')
290 line = line.strip()
291
292 for var, attr in self.FIRMWARE_ATTRS:
293 if line.startswith('{}='.format(var)):
294 _, _, value = line.partition('=')
295 value = value.replace('"', '').replace("'", '')
296 setattr(self, attr, value)
297
298 # Find make.defaults files
299 self.public_make_defaults_file = (
300 self.public_overlay / 'profiles' / 'base' / 'make.defaults')
301 self.private_make_defaults_file = (
302 self.private_overlay / 'profiles' / 'base' / 'make.defaults')
303
304 with open(self.public_make_defaults_file) as f:
305 self.public_make_defaults = f.read()
306 with open(self.private_make_defaults_file) as f:
307 self.private_make_defaults = f.read()
308
309 for var, attr in self.MAKE_DEFAULTS_ATTRS:
310 setattr(self, attr, set())
311 for script in (self.public_make_defaults, self.private_make_defaults):
312 value = sh_getvar(script, var)
313 if value:
314 for v in value.split():
315 getattr(self, attr).add(v)
316
317 if 'whiskers' in self.ec_firmware_extras:
318 self.ec_firmware_extras.remove('whiskers')
319 self.detachable_base_build_target = 'whiskers'
320 else:
321 self.detachable_base_build_target = None
322
323 self.ec_build_target = ' '.join(self.ec_firmwares) or None
324 self.ec_extras_build_target = sorted(list(self.ec_firmware_extras
325 | self.pd_firmwares)) or None
326
327 def write_file(self, overlay_flags, path, file_contents):
328 dirs = []
329 if overlay_flags & M_PUBLIC:
330 dirs += [self.public_overlay]
331 if overlay_flags & M_PRIVATE:
332 dirs += [self.private_overlay]
333 for d in dirs:
334 write_file(d / path, file_contents)
335
336
337class Dut:
338 def __init__(self, hostname, checkout, port=22):
339 self.ssh_hostname = hostname
340
341 id_source = checkout / 'chromite' / 'ssh_keys' / 'testing_rsa'
342 with open(id_source, 'rb') as f:
343 id_contents = f.read()
344
345 with tempfile.NamedTemporaryFile(mode='wb', delete=False) as tmpfile:
346 tmpfile.write(id_contents)
347 self.ssh_identity = tmpfile.name
348
349 with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
350 self.ssh_known_hosts_file = tmpfile.name
351
352 self.ssh_port = port
353
354 # Check connectivity.
355 log('Checking SSH connectivity to DUT...')
356 self.run_command(['/bin/true'])
357
358 # Linter is unaware that we set check=True in kwargs.
359 # pylint: disable=subprocess-run-check
360 def run_command(self, argv, *args, **kwargs):
361 kwargs.setdefault('check', True)
362 kwargs.setdefault('stdout', subprocess.PIPE)
363 kwargs.setdefault('encoding', 'utf-8')
364 quoted_argv = [shlex.quote(arg) for arg in argv]
365 return subprocess.run(['ssh',
366 '-p', '{}'.format(self.ssh_port),
367 '-i', self.ssh_identity,
368 '-o', 'UserKnownHostsFile={}'.format(
369 self.ssh_known_hosts_file),
370 '-o', 'StrictHostKeyChecking=no',
371 '-o', 'CheckHostIP=no',
372 '-o', 'ConnectTimeout=10',
373 'root@{}'.format(self.ssh_hostname)] + quoted_argv,
374 *args, **kwargs)
375 # pylint: enable=subprocess-run-check
376
377
378class DeviceConfig:
379 ATTRS = {
380 'brand_code': ['mosys', 'platform', 'brand'],
381 'model': ['mosys', 'platform', 'model'],
382 'lsb_release': ['cat', '/etc/lsb-release'],
383 'smbios_name': ['cat', '/sys/class/dmi/id/product_name'],
384 'fdt_compatible_raw': ['cat', '/proc/device-tree/compatible'],
385 'arc_build_props': ['cat', '/usr/share/arc/properties/build.prop'],
386 'mosys_psu_type': ['mosys', 'psu', 'type'],
387 'whitelabel_tag': ['vpd_get_value', 'whitelabel_tag'],
388 'customization_id': ['vpd_get_value', 'customization_id'],
389 'cras_config_dir': ['sh', '/etc/cras/get_device_config_dir'],
390 'internal_ucm_suffix': ['sh', '/etc/cras/get_internal_ucm_suffix'],
391 # disgusting, but whatever...
392 'powerd_raw':
393 ['python3', '-c',
394 'import os;'
395 'import json;'
396 'print(json.dumps('
397 '{f.replace("_", "-"): open("/usr/share/power_manager/board_specific/"+f).read().rstrip()'
398 ' for f in os.listdir("/usr/share/power_manager/board_specific")}))'],
399 }
400
401 @classmethod
402 def from_dut(cls, dut):
403 slf = cls()
404 for attr, cmd in cls.ATTRS.items():
405 try:
406 log('Running {!r} on DUT...'.format(cmd))
407 res = dut.run_command(cmd)
408 except subprocess.CalledProcessError:
409 setattr(slf, attr, None)
410 else:
411 setattr(slf, attr, res.stdout.strip())
412 return slf
413
414 def __str__(self):
415 return 'DeviceConfig({})'.format(
416 ', '.join('{}={!r}'.format(attr, getattr(self, attr))
417 for attr in self.ATTRS))
418
419 def lsb_val(self, name, default=None):
420 for item in self.lsb_release.splitlines():
421 k, _, v = item.partition('=')
422 if k == name:
423 return v
424 return default
425
426 def arc_build_prop(self, name, default=None):
427 for line in self.arc_build_props.splitlines():
428 if '#' in line:
429 line, _, _ = line.partition('#')
430 line = line.strip()
431 if line.startswith('{}='.format(name)):
432 _, _, val = line.partition('=')
433 return val
434 return default
435
436
437def genconf_first_api_level(_, overlay):
438 if overlay.board_name in ('atlas', 'nocturne'):
439 return '28'
440 return '25'
441
442
443def genconf_dt_compatible_match(device, overlay):
444 if not device.fdt_compatible_raw:
445 return None
446 compatible_strings = device.fdt_compatible_raw.strip('\x00').split('\x00')
447 compatible_strings.sort(key=lambda s: (s.startswith('google'),
448 'rev' not in s,
449 'sku' not in s,
450 overlay.board_name in s,
451 -len(s)))
452 return compatible_strings[-1]
453
454
455def genconf_psu_type(device, _):
456 if device.mosys_psu_type:
457 return device.mosys_psu_type
458 devicetype = device.lsb_val('DEVICETYPE')
459 if devicetype == 'CHROMEBOOK':
460 return 'battery'
461 if devicetype in ('CHROMEBIT', 'CHROMEBASE', 'CHROMEBOX'):
462 return 'AC_only'
463 return None
464
465
466def genconf_fp_board(_, overlay):
467 if overlay.fpmcu_firmware:
468 return ' '.join(overlay.fpmcu_firmware)
469 return None
470
471
472def genconf_fp_type(_, overlay):
473 if 'fp_on_power_button' in overlay.use_flags:
474 return 'on-power-button'
475 if overlay.fpmcu_firmware:
476 return 'stand-alone'
477 return None
478
479
480def genconf_fp_location(_, overlay):
481 if overlay.board_name == 'nocturne':
482 return 'power-button-top-left'
483 return None
484
485
486def genconf_signature_id(device, _):
487 if device.whitelabel_tag:
488 return device.whitelabel_tag.upper()
489 if device.customization_id:
490 return device.customization_id.upper().partition('-')[0]
491 return device.model
492
493
494def genconf_cras_config_dir(device, _):
495 prefix = '/etc/cras/'
496 if device.cras_config_dir and device.cras_config_dir.startswith(prefix):
497 return device.cras_config_dir[len(prefix):]
498 if device.cras_config_dir:
499 return '../../{}'.format(device.cras_config_dir)
500 return None
501
502
503def genconf_powerd_settings(device, overlay):
504 if not device.powerd_raw:
505 d = {}
506 else:
507 d = json.loads(device.powerd_raw)
508 if 'mosys_eventlog' in overlay.use_flags:
509 d['mosys-eventlog'] = '1'
510 return d
511
512
513M_PUBLIC = (1 << 0)
514M_PRIVATE = (1 << 1)
515
516
517genconf_schema = {
518 'name': (M_PUBLIC | M_PRIVATE, lambda d, _: d.model),
519 'brand-code': (M_PUBLIC, lambda d, _: d.brand_code),
520 'arc': {
521 'build-properties': {
522 'device': (M_PRIVATE, lambda d, _:
523 d.arc_build_prop('ro.product.device')),
524 'marketing-name': (M_PRIVATE, lambda d, _:
525 d.arc_build_prop('ro.product.model')),
526 'oem': (M_PRIVATE,
527 lambda d, _: d.arc_build_prop('ro.product.brand')),
528 'first-api-level': (M_PRIVATE, genconf_first_api_level),
529 'metrics-tag': (M_PRIVATE,
530 lambda d, _: d.arc_build_prop('ro.product.board')),
531 'product': (M_PRIVATE, lambda d, _:
532 d.arc_build_prop('ro.product.name')),
533 },
534 },
535 'audio': {
536 'main': {
537 'cras-config-dir': (M_PUBLIC, genconf_cras_config_dir),
538 'ucm-suffix': (M_PUBLIC, lambda d, _: d.internal_ucm_suffix),
539 },
540 },
541 'fingerprint': {
542 'board': (M_PUBLIC, genconf_fp_board),
543 'fingerprint-sensor-type': (M_PUBLIC, genconf_fp_type),
544 'sensor-location': (M_PUBLIC, genconf_fp_location),
545 },
546 'firmware': {
547 'image-name': (M_PUBLIC, lambda d, _: d.model),
548 'name': (M_PRIVATE, lambda d, _: d.model),
549 'bcs-overlay': (M_PRIVATE, lambda _, b:
550 f'overlay-{b.board_name}-private'),
551 'ec-ro-image': (M_PRIVATE, lambda _, b: b.bcs_ec),
552 'pd-ro-image': (M_PRIVATE, lambda _, b: b.bcs_pd),
553 'main-ro-image': (M_PRIVATE, lambda _, b: b.bcs_main_ro),
554 'main-rw-image': (M_PRIVATE, lambda _, b: b.bcs_main_rw),
555 'build-targets': {
556 'base': (M_PUBLIC, lambda _, b: b.detachable_base_build_target),
557 'coreboot': (M_PUBLIC, lambda _, b: b.board_name),
558 'depthcharge': (M_PUBLIC, lambda _, b: b.board_name),
559 'ec': (M_PUBLIC, lambda _, b: b.ec_build_target),
560 'ec_extras': (M_PUBLIC, lambda _, b: b.ec_extras_build_target),
561 },
562 },
563 'firmware-signing': {
564 'key-id': (M_PRIVATE, lambda d, _: d.model.upper()),
565 'signature-id': (M_PRIVATE, genconf_signature_id),
566 },
567 'hardware-properties': {
568 'psu-type': (M_PUBLIC, genconf_psu_type),
569 },
570 'identity': {
571 'platform-name': (M_PUBLIC, lambda _, b: b.mosys_platform),
572 'smbios-name-match': (M_PUBLIC | M_PRIVATE, lambda d, _: d.smbios_name),
573 'device-tree-compatible-match': (M_PUBLIC | M_PRIVATE,
574 genconf_dt_compatible_match),
575 },
576 'power': (M_PUBLIC, genconf_powerd_settings),
577}
578
579
580def genconf(schema, device_conf, overlay_conf):
581
582 def qualifies_as_value(v):
583 return v is not None and v != {}
584
585 if isinstance(schema, dict):
586 pub, priv = {}, {}
587 for k, v in schema.items():
588 pub_r, priv_r = genconf(v, device_conf, overlay_conf)
589 if qualifies_as_value(pub_r):
590 pub[k] = pub_r
591 if qualifies_as_value(priv_r):
592 priv[k] = priv_r
593 return pub, priv
594
595 if isinstance(schema, tuple):
596 pub, priv = None, None
597 flags, func = schema
598 value = func(device_conf, overlay_conf)
599 if flags & M_PUBLIC:
600 pub = value
601 if flags & M_PRIVATE:
602 priv = value
603 return pub, priv
604
605
606def validate_gs_uri(uri):
607 log('Validating {}...'.format(uri))
608 subprocess.run(['gsutil', 'stat', uri], check=True, stdout=subprocess.DEVNULL)
609
610
611def parse_opts(argv):
612 parser = argparse.ArgumentParser()
613 parser.add_argument('--cros-checkout',
614 type=pathlib.Path,
615 default=pathlib.Path(os.getenv('HOME')) / 'trunk',
616 help='Location of the ChromeOS checkout')
617 parser.add_argument('--dut', '-d',
618 type=str,
619 required=True,
620 help='Hostname of DUT to use for querying and testing.')
621 parser.add_argument('--dut-ssh-port', type=int, default=22,
622 help='SSH port to use on the dut.')
623 parser.add_argument('--board', '-b',
624 type=str,
625 required=True,
626 help='Board name to convert.')
627 parser.add_argument('--mosys-platform', type=str, required=True)
628 parser.add_argument('--dry-run',
629 action='store_true',
630 default=False,
631 help='Dry run')
632 return parser.parse_args(argv)
633
634
635def main(argv):
636 opts = parse_opts(argv)
637
638 overlays = BoardOverlays(opts.board, opts.cros_checkout, opts.mosys_platform)
639 dut = Dut(opts.dut, opts.cros_checkout, port=opts.dut_ssh_port)
640
641 log('Loading configuration from DUT...')
642 dut_config = DeviceConfig.from_dut(dut)
643 log('Got configuration: {}'.format(dut_config))
644
645 assert dut_config.lsb_val('CHROMEOS_RELEASE_BOARD') == opts.board
646 assert dut_config.lsb_val('CHROMEOS_RELEASE_UNIBUILD', '0') != '1'
647
648 log('Generating chromeos-config values...')
649 public_config, private_config = genconf(genconf_schema, dut_config, overlays)
650
651 public_config_yaml = format_yaml(public_config)
652 private_config_yaml = format_yaml(private_config)
653 log('Got public config: \n{}'.format(public_config_yaml))
654 log('Got private config: \n{}'.format(private_config_yaml))
655
656 log('Generating ebuilds...')
657
658 public_vpackage = generate_vpackage(('chromeos-base/chromeos-config-bsp', ))
659 private_vpackage = generate_vpackage(
660 ('chromeos-base/chromeos-config-bsp',
661 'chromeos-base/chromeos-config-bsp-private'))
662 log('Got public vpackage: \n{}'.format(public_vpackage))
663 log('Got private vpackage: \n{}'.format(private_vpackage))
664
665 public_bsp_ebuild = generate_bsp_ebuild()
666 private_bsp_ebuild = generate_bsp_ebuild(private=True)
667 log('Got public bsp_ebuild: \n{}'.format(public_bsp_ebuild))
668 log('Got private bsp_ebuild: \n{}'.format(private_bsp_ebuild))
669
670 firmware_ebuild = generate_firmware_ebuild(opts.board)
671 log('Got firmware ebuild: \n{}'.format(firmware_ebuild))
672
673 public_make_defaults = generate_make_defaults(overlays.public_make_defaults)
674 log('Got public make defaults: \n{}'.format(public_make_defaults))
675 private_make_defaults = generate_make_defaults(overlays.private_make_defaults)
676 log('Got private make defaults: \n{}'.format(private_make_defaults))
677
678 cros_config = CrosConfig(public_config_yaml, private_config_yaml)
679 firmware_srcuris = cros_config.run_host_command('get-firmware-uris')
680 log('Got firmware URIs: {}'.format(firmware_srcuris))
681
682 log('Validating firmware srcuris...')
683 for uri in firmware_srcuris.split():
684 validate_gs_uri(uri)
685
686 firmware_srcuris_path = (overlays.firmware_ebuild_path.parent
687 / 'files' / 'srcuris')
688
689 if opts.dry_run:
690 return
691
692 overlays.write_file(
693 M_PUBLIC, 'chromeos-base/chromeos-config-bsp/files/model.yaml',
694 public_config_yaml)
695 overlays.write_file(
696 M_PRIVATE, 'chromeos-base/chromeos-config-bsp-private/files/model.yaml',
697 private_config_yaml)
698 overlays.write_file(
699 M_PUBLIC, 'virtual/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
700 public_vpackage)
701 overlays.write_file(
702 M_PRIVATE, 'virtual/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
703 private_vpackage)
704 overlays.write_file(
705 M_PUBLIC,
706 'chromeos-base/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
707 public_bsp_ebuild)
708 overlays.write_file(
709 M_PRIVATE,
710 'chromeos-base/chromeos-config-bsp-private/chromeos-config-bsp-private-9999.ebuild',
711 private_bsp_ebuild)
712 write_file(overlays.firmware_ebuild_path, firmware_ebuild)
713 write_file(firmware_srcuris_path, firmware_srcuris)
714 write_file(overlays.public_make_defaults_file, public_make_defaults)
715 write_file(overlays.private_make_defaults_file, private_make_defaults)
716
717
718if __name__ == '__main__':
719 main(sys.argv[1:])