blob: db9fbac66965031f4d7cffaa4fa197ef6563247f [file] [log] [blame] [view]
# ChromeOS Project Configuration
[TOC]
## Overview
This repo contains schema definitions and utilities for configuring ChromeOS
hardware and software. Other repos will use this repo to generate config
payloads to drive ChromeOS builds, manufacturing, etc.
The config payloads are [Protocol Buffers](https://developers.google.com/protocol-buffers)
which are generated via [Starlark](https://docs.bazel.build/versions/master/skylark/language.html).
A basic understanding of protobuf and Starlark is required to manage these
configs.
## Project Setup for Partners
### Syncing Private Repos
**Googlers should have the project and program config repos as part of the
internal-manifest checkout and should not run these steps.**
Partners will do a public checkout and then add
config repos for the projects and programs they are working on.
1. Before beginning verify that you have appropriate permissions to work with
the project. This will usually mean having membership in the partner domain
account that is configured for your project. Inquire with your local
representative or Google contact if you need more information about the
partner domain accounts configured for your project.
1. Follow the [Chromium OS Quick Start Guide](http://www.chromium.org/chromium-os/quick-start-guide)
through to the end of the "Get the Source" section. This guide walks you
through installing prerequisites and syncing the public Chromium OS source
code into a `$SOURCE_REPO` directory. This step pulls down a lot of code and
could take up to an hour.
1. Verify the name of your `$PROGRAM` and `$PROJECT` with your local representative
or Google contact.
1. Run the following command to sync your `$PROGRAM` and `$PROJECT` from within your
chromiumos checkout in the `$SOURCE_REPO/src/config` directory:
```
./setup_project.sh --program=$PROGRAM --project=$PROJECT
```
This command will execute a number of steps including checking out your
program and project and other related repositories, symlinking a local
manifest, and finally doing a full chromiumos sync.
### Syncing to a specific ChromeOS version (buildspec)
**Googlers have access to full private buildspecs and should not run these
steps.**
Partners only have access to public buildspecs, which do not include information
about private partner-specific projects. Infrastructure now exists to create
a project-specific buildspec from a local_manifest.xml file. The following
workflow explains how to include said project-specific buildspecs in a public
ChromeOS checkout, so that partners can properly sync to a specific ChromeOS
version.
1. Make sure that you and your project(s) are enrolled in this program (a
Google contact will need to set this up for you.)
1. Choose the buildspec you'd like to sync to, e.g. `full/buildspecs/92/13963.2.0.xml`. You can list available buildspecs by running `gsutil ls -R gs://chromiumos-manifest-versions/`.
1. [Instructions for setting up `gsutil`](https://cloud.google.com/storage/docs/gsutil_install)
1. Provided the project in question has been enrolled by your Googler contact, project-specific buildspecs are automatically created for enrolled projects for new build versions (at up to a 12 hour delay). If you'd like to sync to an older buildspec (or one that has not yet been created):
1. run ```bb add chromeos/partner-access/project-buildspec -p 'projects=["{your project}/{your program}"]' -p buildspec={your buildspec}```, e.g. ```bb add chromeos/partner-access/project-buildspec -p 'projects=["brya/brya"]' -p buildspec=buildspecs/96/14268.0.0.xml```.
1. Follow the link that `bb add` prints and verify that the run has successfully completed.
1. Run the following commands:
1. `export BUILDSPEC={your buildspec}`, e.g. `export BUILDSPEC=buildspecs/92/13963.2.0.xml`.
1. `export PROJECT={your project}`, e.g. `export PROJECT=galaxy`.
1. `export PROGRAM={your program}`, e.g. `export PROGRAM=milkyway`.
1. `export CHECKOUT={path to your checkout}`, e.g. `export CHECKOUT=~/my_checkout`.
1. ```(mkdir -p $CHECKOUT && cd $CHECKOUT && repo init -u gs://chromiumos-manifest-versions/$BUILDSPEC --standalone-manifest)```
1. ```./setup_project.sh --checkout=$CHECKOUT --program=$PROGRAM --project=$PROJECT --buildspec=$BUILDSPEC```
1. If you do not already have `setup_project.sh` available in an existing ChromeOS checkout, you can download it [here](https://chromium.googlesource.com/chromiumos/config/+/refs/heads/main/setup_project.sh).
1. ```cd $CHECKOUT && repo sync --force-sync -j12 --nmu``` (`--nmu` is a temporary workaround to a known bug, this will be resolved shortly.)
Run `./setup_project.sh -h` for a full list of options/arguments, e.g. `--chipset`, `--all_projects`, and `--other-repos`.
#### Googler Workflows:
1. Enrolling a new partner:
1. (Temporary, as of 08/26/21): The setup_project app has not yet been verified. Add users as Test Users on the setup_project OAuth configuration page [screenshot](https://screenshot.googleplex.com/A4g7m4gaUeYB2Di).
1. In order for a partner to kick off a project-buildspec build via bb add, they need to be added to [cria/project-chromeos-partner-access](https://chrome-infra-auth.appspot.com/auth/groups/project-chromeos-partner-access). If you want to add a google or mdb group, you need to export the group to CRIA by cutting a CL ([example](https://critique-ng.corp.google.com/cl/386477578)).
1. Enrolling a new project:
1. Enroll the appropriate projects in automatic buildspec creation by adding them to the `project_buildspecs` property of `manifest-doctor` ([example](crrev.com/i/4081090)).
1. (Temporary, as of 08/26/21): Create a program bucket: From the root of a chromiumos checkout, run ```./src/config/sbin/create_partner_repo --run createprogrambuckets --program {your program}```.
1. For now, you need to manually set the "Storage Object Viewer" permission for the appropriate groups ([example](https://screenshot.googleplex.com/63ioviutNRiebL2)).
#### See Also
* [go/per-project-buildspecs](http://go/per-project-buildspecs)
* [go/cros-partner-buildspec-sync](http://go/cros-partner-buildspec-sync)
### Configuring the Chroot
**As of 6/8/2020, profiles have not been set up for all projects. Please check with your Google representative on the status of your project.**
Portage profiles are used to build ChromeOS with configuration from a single
project repo. The profile can be set with `setup_board`:
```
(cr) $ setup_board --board=$PROGRAM --profile=$PROJECT
```
After the profile is set, `build_packages` can be called normally:
```
(cr) ~/trunk/src/scripts $ ./build_packages --board=$PROGRAM
```
Note that if no profile is set, the default `base` profile will use
configuration from all projects in the program.
#### Notes
- The above profiles work by setting Portage `USE` flags which affect the
`CROS_WORKON_PROJECT`s that are chosen. Any subset of projects can be chosen
with these `USE` flags, e.g.
```
(cr) $ USE="project_a project_b" emerge ...
```
- The `project_all` `USE` flag is a convenience to use all projects.
If you got to this point without an error you are set up to start working on
your project.
## Adding Utilities to Your `PATH`
The `$SOURCE_REPO/src/config/bin` directory contains utilties for working with
your project. Add the directory to the end of your `PATH`. You will probably
want to add this configuration in your `~/.bashrc` file or other appropriate
location so you don't have to repeatedly set the `PATH`:
```
export PATH=$PATH:$SOURCE_REPO/src/config/bin
```
## Working with Projects for Partners
After setting up your project you'll want to note the location of several
important repositories within the checkout:
* `src/config`: The repository that contains this README.md file. This repository
contains the higher level framework including protocol buffer definitions,
configuration language constructs, constraint checking code, and binaries
for performing tasks.
* `src/program/$PROGRAM`: The repository that defines the program of your
project. This repository defines the constraints that your project follows
and config constructs that are shared across projects in the program.
* `src/project/$PROGRAM/$PROJECT`: The repository that defines your project.
This repository defines your project design under the constraints of the
program it belongs to.
Partners will rarely propose changes to `src/config` and occasionally propose
changes to `src/program/$PROGRAM`. The bulk of a partner's work will occur in
in `src/project/$PROGRAM/$PROJECT`.
## Making Configuration Changes for your Project
Configuration changes are made to a project by adjusting the
[Starlark](https://docs.bazel.build/versions/master/skylark/language.html)
configuration definition in
`$SOURCE_REPO/src/project/$PROGRAM/$PROJECT/config.star` and then running the
`gen_config` script (added to the `PATH` above). An example session updating
project configuration follows:
```
cd $SOURCE_REPO/src/project/$PROGRAM/$PROJECT/
$EDITOR config.star
# Adjust contents of config.star and save.
gen_config config.star
```
Note that many `config.star` files are executable, with the shebang
`#!/usr/bin/env gen_config`. Thus `./config.star` can be used as a shortcut for
`gen_config config.star` if `gen_config` is on `PATH`.
This will cause the generation of payloads and config files that can be found
at:
* `$SOURCE_REPO/src/project/$PROGRAM/$PROJECT/generated/config.jsonproto`
* `$SOURCE_REPO/src/project/$PROGRAM/$PROJECT/generated/project/sw_build_config/platform/chromeos-config/generated/project-config.json`
`config.jsonproto` is a file containing the config protobuf
[encoded as JSON](https://developers.google.com/protocol-buffers/docs/proto3#json).
`project-config.json` is the config in the [legacy YAML schema](https://chromium.git.corp.google.com/chromiumos/platform2/+/HEAD/chromeos-config/README.md#Config-Schema)
and is present for backwards-compatibility.
Before uploading the changes for review you should check to see if your
changes pass constraint checks. You can do that by running the `check_config`
script from within your project's root directory:
```
cd $SOURCE_REPO/src/project/$PROGRAM/$PROJECT/
check_config
```
If your changes pass the contraint checks you are ready to submit your
CL. To submit the changes the user first commits the files and then submits
them to commit queue (CQ):
```
git add .
git commit
# Add commit message with BUG= and TEST= directives
repo upload .
```
This will result in a reviewable CL in
[gerrit](https://chrome-internal-review.googlesource.com/). The exact URL
for your CL will be output when the CL is uploaded. The CL will need to be
approved and pass CQ. Details on working with CLs and the progression through
review and CQ can be found in the
[Chromium OS Contributing Guide](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/contributing.md)
and more specifically in the
[Going through review](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/contributing.md#Going-through-review)
section. CQ verifies that you have correctly generated your configuration
payload and that you have not violated the program's constraints.
### CQ Verifier Access for Partners
Some CQ verifiers will be visible to partners, for example the verifiers of the
project and program configs. Visible builds will appear as links on the Gerrit
page for your CL. The builds are displayed with [Milo](https://g3doc.corp.google.com/company/teams/chrome/ops/luci/milo.md?cl=head) (LUCI's UI).
**Note on stdout log access**: [LogDog](https://g3doc.corp.google.com/company/teams/chrome/ops/luci/logdog/index.md?cl=head) (LUCI's logging service)
currently doesn't support partner access. Thus, stdout logs for key steps of the
build are mirrored to per-project Google Storage buckets. The Google Storage
mirrored logs appear as links like "stdout (GS mirror)" on the Milo page.
## Contributing Protocol Buffer Schema Changes
Protobuf schemas live under the `config` directory. To make a schema change
(e.g. add a field), edit the `.proto` file and then run the `generate.sh` script
in the root of this repo to generate the Protobuf bindings.
See the [proto3 Language Guide](https://developers.google.com/protocol-buffers/docs/proto3)
for more background on Protobuf.
## Constraint Checkers
As described above, a project config is verified against the constraints of the
program before it is submitted. This is done by `check_config` locally and by
CQ builders before submission.
Constraints look and behave similar to Python unit tests, but are passed a
program and project `ConfigBundle` to do assertions on. Constraints that apply
to all programs and projects are in the [payload_utils/checker/common_checks](https://chromium.googlesource.com/chromiumos/config/+/HEAD/payload_utils/checker/common_checks/) directory. Constraints can also be program-specific; these
constraints are under the `checks` directory of the program repo. For example,
see the [Galaxy](https://chrome-internal.googlesource.com/chromeos/program/galaxy/+/HEAD/checks/)
test data program.
## Public Configs
The private project repo contains the entire project config; some config fields
must remain private and some can be made public for building from a public
checkout. Fields are private by default, and can be made public via the
[`chromiumos.config.public_replication.PublicReplication`](https://chromium.googlesource.com/chromiumos/config/+/HEAD/proto/chromiumos/config/public_replication/public_replication.proto)
message (see the message comment for the most up to date documentation).
The `gen_config` command will parse `PublicReplication` messages to generate
`public_config.jsonproto` and `public_sw_build_config` outputs, which are
filtered versions of the full `config.jsonproto` and `sw_build_config` outputs,
respectively. These public outputs will be automatically copied to the public
[`chromiumos/project`](https://chromium.googlesource.com/chromiumos/project/+/refs/heads/main)
repo after CLs are submitted, where they can be used in public ebuilds (because
the file structure of the public configs is symmetrical to the private configs,
the ebuild structure can be similar to private ebuilds).
As with other configuration, Starlark functions in `util/` will provide defaults
for public fields, but these settings can be overridden by individual programs
and projects.
## Directory Structure
### chromiumos/config
For contributing configuration changes for programs and projects, a familiarity
with the follow directories in this repo is helpful:
- `proto/`: Protobuf definitions for hardware configuration,
software configuration, etc. This serves as the main API for configuring your
project and program.
- `util/`: Starlark utilities for use in program and project repos. Some
utility functions are basic wrappers around Protobuf construction, others help
with patterns that are common across patterns, e.g. configuring firmware
payloads.
- `test/`: A fake program and project. Useful to demonstrate the use of the
Starlark utilities.
- `bin/`: Tools needed to work in the configuration ecosystem, see the [above
section](#Adding-Utilities-to-Your) on adding these tools to your `PATH`.
- `go/`: Golang proto bindings. Used by platform code.
- `python/`: Python proto bindings. Used by platform code.
The following directories are likely more useful for contributors to the
configuration and infrastructure systems:
- `infra/`, `recipes/`: Needed to roll proto definitions into
[Recipes](https://chromium.googlesource.com/infra/luci/recipes-py) repos.
- `payload_utils/`: Utilities for working on configuration payloads, e.g. CQ
checker to validate project configs.
- `presubmit/`: Common files and libraries for program and project repo
presubmits.
- `sbin/`: Tools admins use to create and manage programs and projects.
Regular users should not need to use these tools.
### Program and Project Repos
For contributing configuration changes for programs and projects, a familiarity
with their layout patterns is helpful.
- `config.star`: The main Starlark file to generate a program or project's
configuration payload. See
[Making Configuration Changes for your Project](#Making-Configuration-Changes-for-your-Project)
- `generated/`: Generated configuration payloads.
- `sw_build_config/`: Files for configuring software on the project's build.
Contains manually-edited and generated files.
- `public_sw_build_config/`: A filtered version of `sw_build_config`, for use
in public builds.
- `local_manifest.xml`: Local manifest for working on the project. See
[Project Setup for Partners](#Project-Setup-for-Partners)
- `config/`: Symlink to the `chromiumos/config` repo, for importing Starlark
utils.
- `program/`: Symlink from a project repo to the corresponding program repo, for
importing program-level Starlark functions.
- `PRESUBMIT.py`, `PRESUBMIT.cfg`: Presubmit configuration files. Shared across
all programs and projects via symlink.
## Making Bulk Changes Across Repos
Program and project config are spread across repos, so changes and refactors
often span multiple repos. A very common pattern occurs when a change in a
program repo causes changes in that program's project repos when running
`gen_config` for the projects. Tooling is available to make such changes more
automated and less tedious than handcrafting individual CLs. Specifically, using
the ClFactory tool and familiarity with `repo forall` and the
`chromite/bin/gerrit` tools is helpful for these changes.
### ClFactory
[ClFactory](https://chromium.googlesource.com/chromiumos/infra/recipes/+/HEAD/recipes/cl_factory.py)
is a builder that can generate CLs that are the fallout from changes
via other CLs. ClFactory was written to address the pattern mentioned above
where a change at the chromiumos/config or chromeos/program/$PROGRAM level
results in changes in a high number of dependent repos. In order to remain
consistent and pass CQ these typically must be submitted together. Generating
these changes locally, setting commit messages, wiring up Cq-Depends, and
sending out for review can be tedious, error prone, and time consuming.
ClFactory is intended to make such CLs for you.
With ClFactory you write your input CLs as normal. Then, to generate the
dependent CLs that result from the changes, you invoke a builder that takes care
of the rest. It will checkout the source, apply your input CLs, run `gen_config`
in the dependent projects, create the CLs, add reviewers, etc..
A wrapper script,
[cl_factory](https://chromium.googlesource.com/chromiumos/config/+/HEAD/bin/cl_factory),
that lives in the bin directory of this repo, has been provided to simplify
invoking ClFactory. The arguments are a bit involved, but the wrapper makes it
much simpler than crafting a `bb add` command directly, which is the command
that the wrapper delegates to. A typical invocation of ClFactory would look
something like this:
```
./bin/cl_factory \
--cl https://chrome-internal-review.googlesource.com/c/chromeos/program/galaxy/+/3095418 \
--regex src/program src/project \
--reviewers reviewer1@chromium.org reviewer2@google.com \
--ccs author@google.com \
--hashtag regen-audio-configs \
--message "Regenerate audio configs per changes at program level.
BUG=chromium:1092954
TEST=CQ"
```
This would take CL 3095418 as input and run `gen_config` in the projects that
match per the regex arguments. The resultant CLs would have reviewers, CCs, and
other attributes set as indicated. When the builder is launched `cl_factory`
will output a link to the milo page for that build. A link to this same build
will also appear in the commit message of the generated CLs. From that milo
build page you can follow the progress of generating the dependant CLs. The milo
page also provides some valuable information in the step output. In particular,
the "summarize results" step contains two pieces of information that will be of
interest to the CL author and the reviewers. The first piece is the "unified
diff" output. This will allow authors and reviewers to see what the entirety of
all the changes are without having to open each individual generated CL. The
second piece is the "gerrit commands." This output lists commands that can be
used to label verified, label reviewed, and label for commit queue in bulk from
the command line. This allows users to do this quickly as opposed to tediously
navigating the gerrit pages of the generated CLs.
### `repo forall` and `chromite/bin/gerrit` tooling
`repo forall` can be used to make many commits across repos:
```
# Begin branch in all projects.
repo start --all fixbuggyvalue
# Find all config.star files and fix bug.
find src/project -name config.star -exec sed -i 's/buggyvalue/goodvalue/' {} \;
# Make a commit for all project repos.
repo forall -r src/project -c 'git commit -a -m"
$(basename $REPO_PROJECT): Fix buggyvalue.
BUG=chromium:123
TEST=...
"'
# Upload changes with hashtag "fixbuggyvalue"
repo upload --ht=fixbuggyvalue --re=reviewer@google.com
```
Similarly, the `gerrit` tool can apply a label to many CLs:
```
gerrit label-cq `gerrit --raw search "owner:me hashtag:fixbuggyvalue"` 1
```
For anything where gerrit cannot accept multiple CLs, a shell loop
can be used, for example the reviewers command:
```
for cl in `gerrit -i --raw search "owner:me status:open hashtag:fixit"`; do
gerrit reviewers $cl reviewer1@google.com reviewer2@google.com
done
```
# DUT Attributes
The `starlark/dut_attributes` directory defines a `DutAttributesList` containing
all `DutAttributes` valid for use in test plans. New `DutAttributes` can be
added in this file.
Note that a **`DutAttribute` used on any branch cannot be deleted or modified**,
because this may break the test plan on the branch.