diff --git a/contrib/cros_unibuild_convert.py b/contrib/cros_unibuild_convert.py
new file mode 100755
index 0000000..4b4d9ea
--- /dev/null
+++ b/contrib/cros_unibuild_convert.py
@@ -0,0 +1,719 @@
+#!/usr/bin/env python3
+# Copyright 2020 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.
+
+# This file uses 2-space indentations.
+# pylint: disable=bad-indentation
+
+# This is contrib-quality code: not all functions/classes are
+# documented.
+# pylint: disable=missing-function-docstring
+# pylint: disable=missing-class-docstring
+# pylint: disable=class-missing-docstring
+
+# Classes make heavy-use of setattr to dynamically set the attributes
+# on an object.  Disable this check which gets confused very
+# frequently.
+# pylint: disable=no-member
+
+"""Utility script to auto-convert a pre-unibuild board to unibuild."""
+
+import argparse
+import datetime
+import json
+import os
+import pathlib
+import re
+import shlex
+import subprocess
+import sys
+import tempfile
+# pylint: disable=import-error
+import yaml
+# pylint: enable=import-error
+
+
+make_defaults_search_and_destroy_re = re.compile(
+    r'(?:^\s*)*(?:^\s*#.*\s*)*^\s*USE="\s*\$\{?USE\}?\s*-unibuild\s*"\s*$',
+    re.MULTILINE)
+
+
+def log(message):
+  print('[{}] {}'.format(datetime.datetime.now(), message), file=sys.stderr)
+
+
+def prepend_all_lines(text, prepend):
+  return ''.join(
+      '{}{}\n'.format(prepend, line)
+      for line in text.splitlines())
+
+
+def gen_cros_copyright(line_comment='# '):
+  return prepend_all_lines(
+      """Copyright {} The Chromium OS Authors. All rights reserved.
+Use of this source code is coverned by a BSD-style license that can be
+found in the LICENSE file.""".format(datetime.datetime.now().strftime('%Y')),
+      line_comment)
+
+
+def yaml_str_representer(dumper, data):
+  style = None
+  tag = 'tag:yaml.org,2002:str'
+  if '\n' in data:
+    style = '|'
+  return dumper.represent_scalar(tag, data, style)
+
+
+yaml.add_representer(str, yaml_str_representer)
+
+
+def format_yaml(config):
+  conf_str = yaml.dump(config, indent=2, default_flow_style=False)
+  out = gen_cros_copyright()
+  out += """
+# This board only supports a single config, defined below, as it is a
+# migrated pre-unibuild device.
+device-config: &device_config\n"""
+  out += prepend_all_lines(conf_str, '  ')
+  out += """
+# Required dunder for chromeos-config to support a single device.
+chromeos:
+  devices:
+    - skus:
+        - config: *device_config\n"""
+  return out
+
+
+def generate_vpackage(depends):
+  return gen_cros_copyright() + """
+EAPI=7
+
+# cros_workon applies only to ebuild and files directory. Use the
+# canonical empty project.
+CROS_WORKON_PROJECT="chromiumos/infra/build/empty-project"
+CROS_WORKON_LOCALNAME="../platform/empty-project"
+
+inherit cros-workon
+
+DESCRIPTION="ChromeOS Unibuild Config virtual package"
+HOMEPAGE="https://chromium.googlesource.com/chromiumos/platform2/+/master/chromeos-config/README.md"
+
+LICENSE="BSD-Google"
+SLOT="0"
+KEYWORDS="~*"
+
+DEPEND="%(depends)s"
+RDEPEND="${DEPEND}"
+""" % {
+    'depends':
+    (''.join('\n\t{}'.format(d) for d in depends) + '\n')
+    if len(depends) > 1 else
+    ''.join(depends)}
+
+
+def generate_bsp_ebuild(private=False):
+  return gen_cros_copyright() + """
+EAPI=7
+
+# cros_workon applies only to ebuild and files directory. Use the
+# canonical empty project.
+CROS_WORKON_PROJECT="chromiumos/infra/build/empty-project"
+CROS_WORKON_LOCALNAME="../platform/empty-project"
+
+inherit cros-workon cros-unibuild
+
+DESCRIPTION="ChromeOS model configuration"
+HOMEPAGE="https://chromium.googlesource.com/chromiumos/platform2/+/master/chromeos-config/README.md"
+
+LICENSE="BSD-Google"
+SLOT="0"
+KEYWORDS="~*"
+
+src_install() {
+\tinstall%(maybe_private)s_model_files
+}
+""" % {'maybe_private': '_private' if private else ''}
+
+
+def generate_firmware_ebuild(board_name):
+  return gen_cros_copyright() + """
+# Change this version number when any change is made to model.yaml
+# in order to trigger an auto-revbump is required.
+# VERSION=REVBUMP-0.0.1
+
+EAPI=7
+CROS_WORKON_COMMIT=""
+CROS_WORKON_TREE=""
+CROS_WORKON_LOCALNAME="platform/firmware"
+CROS_WORKON_PROJECT="chromiumos/platform/firmware"
+CROS_BOARDS=( %(board_name)s )
+
+inherit cros-workon cros-firmware cros-unibuild
+
+DESCRIPTION="Chrome OS Firmware (%(board_name)s)"
+HOMEPAGE="http://src.chromium.org"
+LICENSE="BSD-Google"
+SLOT="0"
+KEYWORDS="~*"
+
+RDEPEND=""
+
+# Unified Builds firmware URL's are read from:
+#   chromeos-base/chromeos-config-bsp-private/files/model.yaml
+# in this repository. Those config files output the SRC_URI's used by Portage.
+#
+# Update the model.yaml, then run this command from the
+# src/platform/dev/contrib directory:
+#
+#   ./cros_update_firmware --board=%(board_name)s
+#
+# Verify the changes by running:
+#   /build/%(board_name)s/usr/sbin/chromeos-firmwareupdate --manifest
+#
+# If this works then you can create a CL with your changes, which should include
+# the files:
+# chromeos-base/chromeos-config-bsp-private/files/model.yaml
+# chromeos-base/chromeos-firmware-%(board_name)s/Manifest
+# chromeos-base/chromeos-firmware-%(board_name)s/files/srcuris
+# chromeos-base/chromeos-firmware-%(board_name)s/chromeos-firmware-%(board_name)s-9999.ebuild
+cros-firmware_setup_source
+""" % {'board_name': board_name}
+
+
+def find_file(searchdir, name):
+  results = []
+  for root, _, files in os.walk(searchdir):
+    if name in files:
+      results.append(pathlib.Path(root) / name)
+  return results
+
+
+def find_one_file(searchdir, name):
+  results = find_file(searchdir, name)
+  assert len(results) == 1
+  return results.pop()
+
+
+def sh_getvar(script, varname):
+  script = script + ('\necho "${%s}"\n' % varname)
+  with tempfile.NamedTemporaryFile('w') as f:
+    f.write(script)
+    f.flush()
+    res = subprocess.run(['sh', f.name], stdout=subprocess.PIPE,
+                         check=True, encoding='utf-8')
+  return res.stdout.strip() or None
+
+
+def write_file(fullpath, file_contents):
+  os.makedirs(fullpath.parent, exist_ok=True)
+  log('Writing {}...'.format(fullpath))
+  with open(fullpath, 'w') as f:
+    f.write(file_contents)
+
+
+def generate_make_defaults(contents):
+  contents = make_defaults_search_and_destroy_re.sub('', contents)
+  contents += """
+# Enable chromeos-config.
+USE="${USE} unibuild"
+"""
+  return contents
+
+
+class CrosConfig:
+  def __init__(self, public_yaml_raw, private_yaml_raw):
+    with tempfile.NamedTemporaryFile(mode='w', delete=False) as merged_tempfile, \
+         tempfile.NamedTemporaryFile(mode='w') as public_yaml_tempfile, \
+         tempfile.NamedTemporaryFile(mode='w') as private_yaml_tempfile:
+      public_yaml_tempfile.write(public_yaml_raw)
+      public_yaml_tempfile.flush()
+
+      private_yaml_tempfile.write(private_yaml_raw)
+      private_yaml_tempfile.flush()
+
+      log('Merging and validating config schema...')
+      subprocess.run(['cros_config_schema', '-o', merged_tempfile.name,
+                      '-m', public_yaml_tempfile.name,
+                      private_yaml_tempfile.name], check=True)
+      self.merged_yaml = merged_tempfile.name
+
+  def run_host_command(self, *args):
+    return subprocess.run(['cros_config_host', '-c', self.merged_yaml]
+                          + list(args),
+                          check=True, encoding='utf-8',
+                          stdout=subprocess.PIPE).stdout
+
+
+class BoardOverlays:
+  FIRMWARE_ATTRS = [
+      ('CROS_FIRMWARE_MAIN_IMAGE', 'bcs_main_ro'),
+      ('CROS_FIRMWARE_MAIN_RW_IMAGE', 'bcs_main_rw'),
+      ('CROS_FIRMWARE_EC_IMAGE', 'bcs_ec'),
+      ('CROS_FIRMWARE_PD_IMAGE', 'bcs_pd'),
+  ]
+
+  MAKE_DEFAULTS_ATTRS = [
+      ('EC_FIRMWARE', 'ec_firmwares'),
+      ('PD_FIRMWARE', 'pd_firmwares'),
+      ('EC_FIRMWARE_EXTRA', 'ec_firmware_extras'),
+      ('FPMCU_FIRMWARE', 'fpmcu_firmware'),
+      ('USE', 'use_flags'),
+  ]
+
+  def __init__(self, board_name, checkout, mosys_platform):
+    self.board_name = board_name
+    self.mosys_platform = mosys_platform
+    self.public_overlay = (checkout / 'src' / 'overlays'
+                           / f'overlay-{board_name}')
+    log('Public overlay path: {}'.format(self.public_overlay))
+    self.private_overlay = (checkout / 'src' / 'private-overlays'
+                            / f'overlay-{board_name}-private')
+    log('Private overlay path: {}'.format(self.private_overlay))
+
+    assert self.public_overlay.is_dir()
+    assert self.private_overlay.is_dir()
+
+    # Find the firmware ebuild
+    self.firmware_ebuild_path = find_one_file(
+        self.private_overlay, f'chromeos-firmware-{board_name}-9999.ebuild')
+    log('Firmware ebuild path: {}'.format(self.firmware_ebuild_path))
+
+    # Read the firmware attrs from it
+    for _, attr in self.FIRMWARE_ATTRS:
+      setattr(self, attr, None)
+
+    with open(self.firmware_ebuild_path) as f:
+      for line in f:
+        if '#' in line:
+          line, _, _ = line.partition('#')
+        line = line.strip()
+
+        for var, attr in self.FIRMWARE_ATTRS:
+          if line.startswith('{}='.format(var)):
+            _, _, value = line.partition('=')
+            value = value.replace('"', '').replace("'", '')
+            setattr(self, attr, value)
+
+    # Find make.defaults files
+    self.public_make_defaults_file = (
+        self.public_overlay / 'profiles' / 'base' / 'make.defaults')
+    self.private_make_defaults_file = (
+        self.private_overlay / 'profiles' / 'base' / 'make.defaults')
+
+    with open(self.public_make_defaults_file) as f:
+      self.public_make_defaults = f.read()
+    with open(self.private_make_defaults_file) as f:
+      self.private_make_defaults = f.read()
+
+    for var, attr in self.MAKE_DEFAULTS_ATTRS:
+      setattr(self, attr, set())
+      for script in (self.public_make_defaults, self.private_make_defaults):
+        value = sh_getvar(script, var)
+        if value:
+          for v in value.split():
+            getattr(self, attr).add(v)
+
+    if 'whiskers' in self.ec_firmware_extras:
+      self.ec_firmware_extras.remove('whiskers')
+      self.detachable_base_build_target = 'whiskers'
+    else:
+      self.detachable_base_build_target = None
+
+    self.ec_build_target = ' '.join(self.ec_firmwares) or None
+    self.ec_extras_build_target = sorted(list(self.ec_firmware_extras
+                                              | self.pd_firmwares)) or None
+
+  def write_file(self, overlay_flags, path, file_contents):
+    dirs = []
+    if overlay_flags & M_PUBLIC:
+      dirs += [self.public_overlay]
+    if overlay_flags & M_PRIVATE:
+      dirs += [self.private_overlay]
+    for d in dirs:
+      write_file(d / path, file_contents)
+
+
+class Dut:
+  def __init__(self, hostname, checkout, port=22):
+    self.ssh_hostname = hostname
+
+    id_source = checkout / 'chromite' / 'ssh_keys' / 'testing_rsa'
+    with open(id_source, 'rb') as f:
+      id_contents = f.read()
+
+    with tempfile.NamedTemporaryFile(mode='wb', delete=False) as tmpfile:
+      tmpfile.write(id_contents)
+      self.ssh_identity = tmpfile.name
+
+    with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
+      self.ssh_known_hosts_file = tmpfile.name
+
+    self.ssh_port = port
+
+    # Check connectivity.
+    log('Checking SSH connectivity to DUT...')
+    self.run_command(['/bin/true'])
+
+  # Linter is unaware that we set check=True in kwargs.
+  # pylint: disable=subprocess-run-check
+  def run_command(self, argv, *args, **kwargs):
+    kwargs.setdefault('check', True)
+    kwargs.setdefault('stdout', subprocess.PIPE)
+    kwargs.setdefault('encoding', 'utf-8')
+    quoted_argv = [shlex.quote(arg) for arg in argv]
+    return subprocess.run(['ssh',
+                           '-p', '{}'.format(self.ssh_port),
+                           '-i', self.ssh_identity,
+                           '-o', 'UserKnownHostsFile={}'.format(
+                               self.ssh_known_hosts_file),
+                           '-o', 'StrictHostKeyChecking=no',
+                           '-o', 'CheckHostIP=no',
+                           '-o', 'ConnectTimeout=10',
+                           'root@{}'.format(self.ssh_hostname)] + quoted_argv,
+                          *args, **kwargs)
+  # pylint: enable=subprocess-run-check
+
+
+class DeviceConfig:
+  ATTRS = {
+      'brand_code': ['mosys', 'platform', 'brand'],
+      'model': ['mosys', 'platform', 'model'],
+      'lsb_release': ['cat', '/etc/lsb-release'],
+      'smbios_name': ['cat', '/sys/class/dmi/id/product_name'],
+      'fdt_compatible_raw': ['cat', '/proc/device-tree/compatible'],
+      'arc_build_props': ['cat', '/usr/share/arc/properties/build.prop'],
+      'mosys_psu_type': ['mosys', 'psu', 'type'],
+      'whitelabel_tag': ['vpd_get_value', 'whitelabel_tag'],
+      'customization_id': ['vpd_get_value', 'customization_id'],
+      'cras_config_dir': ['sh', '/etc/cras/get_device_config_dir'],
+      'internal_ucm_suffix': ['sh', '/etc/cras/get_internal_ucm_suffix'],
+      # disgusting, but whatever...
+      'powerd_raw':
+      ['python3', '-c',
+       'import os;'
+       'import json;'
+       'print(json.dumps('
+       '{f.replace("_", "-"): open("/usr/share/power_manager/board_specific/"+f).read().rstrip()'
+       ' for f in os.listdir("/usr/share/power_manager/board_specific")}))'],
+  }
+
+  @classmethod
+  def from_dut(cls, dut):
+    slf = cls()
+    for attr, cmd in cls.ATTRS.items():
+      try:
+        log('Running {!r} on DUT...'.format(cmd))
+        res = dut.run_command(cmd)
+      except subprocess.CalledProcessError:
+        setattr(slf, attr, None)
+      else:
+        setattr(slf, attr, res.stdout.strip())
+    return slf
+
+  def __str__(self):
+    return 'DeviceConfig({})'.format(
+        ', '.join('{}={!r}'.format(attr, getattr(self, attr))
+                  for attr in self.ATTRS))
+
+  def lsb_val(self, name, default=None):
+    for item in self.lsb_release.splitlines():
+      k, _, v = item.partition('=')
+      if k == name:
+        return v
+    return default
+
+  def arc_build_prop(self, name, default=None):
+    for line in self.arc_build_props.splitlines():
+      if '#' in line:
+        line, _, _ = line.partition('#')
+      line = line.strip()
+      if line.startswith('{}='.format(name)):
+        _, _, val = line.partition('=')
+        return val
+    return default
+
+
+def genconf_first_api_level(_, overlay):
+  if overlay.board_name in ('atlas', 'nocturne'):
+    return '28'
+  return '25'
+
+
+def genconf_dt_compatible_match(device, overlay):
+  if not device.fdt_compatible_raw:
+    return None
+  compatible_strings = device.fdt_compatible_raw.strip('\x00').split('\x00')
+  compatible_strings.sort(key=lambda s: (s.startswith('google'),
+                                         'rev' not in s,
+                                         'sku' not in s,
+                                         overlay.board_name in s,
+                                         -len(s)))
+  return compatible_strings[-1]
+
+
+def genconf_psu_type(device, _):
+  if device.mosys_psu_type:
+    return device.mosys_psu_type
+  devicetype = device.lsb_val('DEVICETYPE')
+  if devicetype == 'CHROMEBOOK':
+    return 'battery'
+  if devicetype in ('CHROMEBIT', 'CHROMEBASE', 'CHROMEBOX'):
+    return 'AC_only'
+  return None
+
+
+def genconf_fp_board(_, overlay):
+  if overlay.fpmcu_firmware:
+    return ' '.join(overlay.fpmcu_firmware)
+  return None
+
+
+def genconf_fp_type(_, overlay):
+  if 'fp_on_power_button' in overlay.use_flags:
+    return 'on-power-button'
+  if overlay.fpmcu_firmware:
+    return 'stand-alone'
+  return None
+
+
+def genconf_fp_location(_, overlay):
+  if overlay.board_name == 'nocturne':
+    return 'power-button-top-left'
+  return None
+
+
+def genconf_signature_id(device, _):
+  if device.whitelabel_tag:
+    return device.whitelabel_tag.upper()
+  if device.customization_id:
+    return device.customization_id.upper().partition('-')[0]
+  return device.model
+
+
+def genconf_cras_config_dir(device, _):
+  prefix = '/etc/cras/'
+  if device.cras_config_dir and device.cras_config_dir.startswith(prefix):
+    return device.cras_config_dir[len(prefix):]
+  if device.cras_config_dir:
+    return '../../{}'.format(device.cras_config_dir)
+  return None
+
+
+def genconf_powerd_settings(device, overlay):
+  if not device.powerd_raw:
+    d = {}
+  else:
+    d = json.loads(device.powerd_raw)
+  if 'mosys_eventlog' in overlay.use_flags:
+    d['mosys-eventlog'] = '1'
+  return d
+
+
+M_PUBLIC = (1 << 0)
+M_PRIVATE = (1 << 1)
+
+
+genconf_schema = {
+    'name': (M_PUBLIC | M_PRIVATE, lambda d, _: d.model),
+    'brand-code': (M_PUBLIC, lambda d, _: d.brand_code),
+    'arc': {
+        'build-properties': {
+            'device': (M_PRIVATE, lambda d, _:
+                       d.arc_build_prop('ro.product.device')),
+            'marketing-name': (M_PRIVATE, lambda d, _:
+                               d.arc_build_prop('ro.product.model')),
+            'oem': (M_PRIVATE,
+                    lambda d, _: d.arc_build_prop('ro.product.brand')),
+            'first-api-level': (M_PRIVATE, genconf_first_api_level),
+            'metrics-tag': (M_PRIVATE,
+                            lambda d, _: d.arc_build_prop('ro.product.board')),
+            'product': (M_PRIVATE, lambda d, _:
+                        d.arc_build_prop('ro.product.name')),
+        },
+    },
+    'audio': {
+        'main': {
+            'cras-config-dir': (M_PUBLIC, genconf_cras_config_dir),
+            'ucm-suffix': (M_PUBLIC, lambda d, _: d.internal_ucm_suffix),
+        },
+    },
+    'fingerprint': {
+        'board': (M_PUBLIC, genconf_fp_board),
+        'fingerprint-sensor-type': (M_PUBLIC, genconf_fp_type),
+        'sensor-location': (M_PUBLIC, genconf_fp_location),
+    },
+    'firmware': {
+        'image-name': (M_PUBLIC, lambda d, _: d.model),
+        'name': (M_PRIVATE, lambda d, _: d.model),
+        'bcs-overlay': (M_PRIVATE, lambda _, b:
+                        f'overlay-{b.board_name}-private'),
+        'ec-ro-image': (M_PRIVATE, lambda _, b: b.bcs_ec),
+        'pd-ro-image': (M_PRIVATE, lambda _, b: b.bcs_pd),
+        'main-ro-image': (M_PRIVATE, lambda _, b: b.bcs_main_ro),
+        'main-rw-image': (M_PRIVATE, lambda _, b: b.bcs_main_rw),
+        'build-targets': {
+            'base': (M_PUBLIC, lambda _, b: b.detachable_base_build_target),
+            'coreboot': (M_PUBLIC, lambda _, b: b.board_name),
+            'depthcharge': (M_PUBLIC, lambda _, b: b.board_name),
+            'ec': (M_PUBLIC, lambda _, b: b.ec_build_target),
+            'ec_extras': (M_PUBLIC, lambda _, b: b.ec_extras_build_target),
+        },
+    },
+    'firmware-signing': {
+        'key-id': (M_PRIVATE, lambda d, _: d.model.upper()),
+        'signature-id': (M_PRIVATE, genconf_signature_id),
+    },
+    'hardware-properties': {
+        'psu-type': (M_PUBLIC, genconf_psu_type),
+    },
+    'identity': {
+        'platform-name': (M_PUBLIC, lambda _, b: b.mosys_platform),
+        'smbios-name-match': (M_PUBLIC | M_PRIVATE, lambda d, _: d.smbios_name),
+        'device-tree-compatible-match': (M_PUBLIC | M_PRIVATE,
+                                         genconf_dt_compatible_match),
+    },
+    'power': (M_PUBLIC, genconf_powerd_settings),
+}
+
+
+def genconf(schema, device_conf, overlay_conf):
+
+  def qualifies_as_value(v):
+    return v is not None and v != {}
+
+  if isinstance(schema, dict):
+    pub, priv = {}, {}
+    for k, v in schema.items():
+      pub_r, priv_r = genconf(v, device_conf, overlay_conf)
+      if qualifies_as_value(pub_r):
+        pub[k] = pub_r
+      if qualifies_as_value(priv_r):
+        priv[k] = priv_r
+    return pub, priv
+
+  if isinstance(schema, tuple):
+    pub, priv = None, None
+    flags, func = schema
+    value = func(device_conf, overlay_conf)
+    if flags & M_PUBLIC:
+      pub = value
+    if flags & M_PRIVATE:
+      priv = value
+    return pub, priv
+
+
+def validate_gs_uri(uri):
+  log('Validating {}...'.format(uri))
+  subprocess.run(['gsutil', 'stat', uri], check=True, stdout=subprocess.DEVNULL)
+
+
+def parse_opts(argv):
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--cros-checkout',
+                      type=pathlib.Path,
+                      default=pathlib.Path(os.getenv('HOME')) / 'trunk',
+                      help='Location of the ChromeOS checkout')
+  parser.add_argument('--dut', '-d',
+                      type=str,
+                      required=True,
+                      help='Hostname of DUT to use for querying and testing.')
+  parser.add_argument('--dut-ssh-port', type=int, default=22,
+                      help='SSH port to use on the dut.')
+  parser.add_argument('--board', '-b',
+                      type=str,
+                      required=True,
+                      help='Board name to convert.')
+  parser.add_argument('--mosys-platform', type=str, required=True)
+  parser.add_argument('--dry-run',
+                      action='store_true',
+                      default=False,
+                      help='Dry run')
+  return parser.parse_args(argv)
+
+
+def main(argv):
+  opts = parse_opts(argv)
+
+  overlays = BoardOverlays(opts.board, opts.cros_checkout, opts.mosys_platform)
+  dut = Dut(opts.dut, opts.cros_checkout, port=opts.dut_ssh_port)
+
+  log('Loading configuration from DUT...')
+  dut_config = DeviceConfig.from_dut(dut)
+  log('Got configuration: {}'.format(dut_config))
+
+  assert dut_config.lsb_val('CHROMEOS_RELEASE_BOARD') == opts.board
+  assert dut_config.lsb_val('CHROMEOS_RELEASE_UNIBUILD', '0') != '1'
+
+  log('Generating chromeos-config values...')
+  public_config, private_config = genconf(genconf_schema, dut_config, overlays)
+
+  public_config_yaml = format_yaml(public_config)
+  private_config_yaml = format_yaml(private_config)
+  log('Got public config: \n{}'.format(public_config_yaml))
+  log('Got private config: \n{}'.format(private_config_yaml))
+
+  log('Generating ebuilds...')
+
+  public_vpackage = generate_vpackage(('chromeos-base/chromeos-config-bsp', ))
+  private_vpackage = generate_vpackage(
+      ('chromeos-base/chromeos-config-bsp',
+       'chromeos-base/chromeos-config-bsp-private'))
+  log('Got public vpackage: \n{}'.format(public_vpackage))
+  log('Got private vpackage: \n{}'.format(private_vpackage))
+
+  public_bsp_ebuild = generate_bsp_ebuild()
+  private_bsp_ebuild = generate_bsp_ebuild(private=True)
+  log('Got public bsp_ebuild: \n{}'.format(public_bsp_ebuild))
+  log('Got private bsp_ebuild: \n{}'.format(private_bsp_ebuild))
+
+  firmware_ebuild = generate_firmware_ebuild(opts.board)
+  log('Got firmware ebuild: \n{}'.format(firmware_ebuild))
+
+  public_make_defaults = generate_make_defaults(overlays.public_make_defaults)
+  log('Got public make defaults: \n{}'.format(public_make_defaults))
+  private_make_defaults = generate_make_defaults(overlays.private_make_defaults)
+  log('Got private make defaults: \n{}'.format(private_make_defaults))
+
+  cros_config = CrosConfig(public_config_yaml, private_config_yaml)
+  firmware_srcuris = cros_config.run_host_command('get-firmware-uris')
+  log('Got firmware URIs: {}'.format(firmware_srcuris))
+
+  log('Validating firmware srcuris...')
+  for uri in firmware_srcuris.split():
+    validate_gs_uri(uri)
+
+  firmware_srcuris_path = (overlays.firmware_ebuild_path.parent
+                           / 'files' / 'srcuris')
+
+  if opts.dry_run:
+    return
+
+  overlays.write_file(
+      M_PUBLIC, 'chromeos-base/chromeos-config-bsp/files/model.yaml',
+      public_config_yaml)
+  overlays.write_file(
+      M_PRIVATE, 'chromeos-base/chromeos-config-bsp-private/files/model.yaml',
+      private_config_yaml)
+  overlays.write_file(
+      M_PUBLIC, 'virtual/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
+      public_vpackage)
+  overlays.write_file(
+      M_PRIVATE, 'virtual/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
+      private_vpackage)
+  overlays.write_file(
+      M_PUBLIC,
+      'chromeos-base/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
+      public_bsp_ebuild)
+  overlays.write_file(
+      M_PRIVATE,
+      'chromeos-base/chromeos-config-bsp-private/chromeos-config-bsp-private-9999.ebuild',
+      private_bsp_ebuild)
+  write_file(overlays.firmware_ebuild_path, firmware_ebuild)
+  write_file(firmware_srcuris_path, firmware_srcuris)
+  write_file(overlays.public_make_defaults_file, public_make_defaults)
+  write_file(overlays.private_make_defaults_file, private_make_defaults)
+
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
