1# ChromeOS Project Configuration 2 3[TOC] 4 5## Overview 6 7This repo contains schema definitions and utilities for configuring ChromeOS 8hardware and software. Other repos will use this repo to generate config 9payloads to drive ChromeOS builds, manufacturing, etc. 10 11The config payloads are [Protocol Buffers](https://developers.google.com/protocol-buffers) 12which are generated via [Starlark](https://docs.bazel.build/versions/master/skylark/language.html). 13A basic understanding of protobuf and Starlark is required to manage these 14configs. 15 16## Project Setup for Partners 17 18### Syncing Private Repos 19 20**Googlers should have the project and program config repos as part of the 21internal-manifest checkout and should not run these steps.** 22 23Partners will do a public checkout and then add 24config repos for the projects and programs they are working on. 25 261. Before beginning verify that you have appropriate permissions to work with 27 the project. This will usually mean having membership in the partner domain 28 account that is configured for your project. Inquire with your local 29 representative or Google contact if you need more information about the 30 partner domain accounts configured for your project. 311. Follow the [Chromium OS Quick Start Guide](http://www.chromium.org/chromium-os/quick-start-guide) 32 through to the end of the "Get the Source" section. This guide walks you 33 through installing prerequisites and syncing the public Chromium OS source 34 code into a `$SOURCE_REPO` directory. This step pulls down a lot of code and 35 could take up to an hour. 361. Verify the name of your `$PROGRAM` and `$PROJECT` with your local representative 37 or Google contact. 38 391. Run the following command to sync your `$PROGRAM` and `$PROJECT` from within your 40 chromiumos checkout in the `$SOURCE_REPO/src/config` directory: 41 42 ``` 43 ./setup_project.sh --program=$PROGRAM --project=$PROJECT 44 ``` 45 46 This command will execute a number of steps including checking out your 47 program and project and other related repositories, symlinking a local 48 manifest, and finally doing a full chromiumos sync. 49 50### Syncing to a specific ChromeOS version (buildspec) 51 52**Googlers have access to full private buildspecs and should not run these 53steps.** 54 55Partners only have access to public buildspecs, which do not include information 56about private partner-specific projects. Infrastructure now exists to create 57a project-specific buildspec from a local_manifest.xml file. The following 58workflow explains how to include said project-specific buildspecs in a public 59ChromeOS checkout, so that partners can properly sync to a specific ChromeOS 60version. 61 621. Make sure that you and your project(s) are enrolled in this program (a 63 Google contact will need to set this up for you.) 641. 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/`. 65 1. [Instructions for setting up `gsutil`](https://cloud.google.com/storage/docs/gsutil_install) 66 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): 67 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```. 68 1. Follow the link that `bb add` prints and verify that the run has successfully completed. 691. Run the following commands: 70 1. `export BUILDSPEC={your buildspec}`, e.g. `export BUILDSPEC=buildspecs/92/13963.2.0.xml`. 71 1. `export PROJECT={your project}`, e.g. `export PROJECT=galaxy`. 72 1. `export PROGRAM={your program}`, e.g. `export PROGRAM=milkyway`. 73 1. `export CHECKOUT={path to your checkout}`, e.g. `export CHECKOUT=~/my_checkout`. 74 1. ```(mkdir -p $CHECKOUT && cd $CHECKOUT && repo init -u gs://chromiumos-manifest-versions/$BUILDSPEC --standalone-manifest)``` 75 1. ```./setup_project.sh --checkout=$CHECKOUT --program=$PROGRAM --project=$PROJECT --buildspec=$BUILDSPEC``` 76 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). 77 1. ```cd $CHECKOUT && repo sync --force-sync -j12 --nmu``` (`--nmu` is a temporary workaround to a known bug, this will be resolved shortly.) 78 79Run `./setup_project.sh -h` for a full list of options/arguments, e.g. `--chipset`, `--all_projects`, and `--other-repos`. 80 81#### Googler Workflows: 82 831. Enrolling a new partner: 84 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). 85 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)). 861. Enrolling a new project: 87 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)). 88 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}```. 89 1. For now, you need to manually set the "Storage Object Viewer" permission for the appropriate groups ([example](https://screenshot.googleplex.com/63ioviutNRiebL2)). 90 91#### See Also 92* [go/per-project-buildspecs](http://go/per-project-buildspecs) 93* [go/cros-partner-buildspec-sync](http://go/cros-partner-buildspec-sync) 94 95### Configuring the Chroot 96 97**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.** 98 99Portage profiles are used to build ChromeOS with configuration from a single 100project repo. The profile can be set with `setup_board`: 101 102``` 103(cr) $ setup_board --board=$PROGRAM --profile=$PROJECT 104``` 105 106After the profile is set, `build_packages` can be called normally: 107 108``` 109(cr) ~/trunk/src/scripts $ ./build_packages --board=$PROGRAM 110``` 111 112Note that if no profile is set, the default `base` profile will use 113configuration from all projects in the program. 114 115#### Notes 116 117- The above profiles work by setting Portage `USE` flags which affect the 118`CROS_WORKON_PROJECT`s that are chosen. Any subset of projects can be chosen 119with these `USE` flags, e.g. 120 121``` 122(cr) $ USE="project_a project_b" emerge ... 123``` 124 125- The `project_all` `USE` flag is a convenience to use all projects. 126 127If you got to this point without an error you are set up to start working on 128your project. 129 130## Adding Utilities to Your `PATH` 131 132The `$SOURCE_REPO/src/config/bin` directory contains utilties for working with 133your project. Add the directory to the end of your `PATH`. You will probably 134want to add this configuration in your `~/.bashrc` file or other appropriate 135location so you don't have to repeatedly set the `PATH`: 136 137``` 138export PATH=$PATH:$SOURCE_REPO/src/config/bin 139``` 140 141## Working with Projects for Partners 142 143After setting up your project you'll want to note the location of several 144important repositories within the checkout: 145 146* `src/config`: The repository that contains this README.md file. This repository 147 contains the higher level framework including protocol buffer definitions, 148 configuration language constructs, constraint checking code, and binaries 149 for performing tasks. 150* `src/program/$PROGRAM`: The repository that defines the program of your 151 project. This repository defines the constraints that your project follows 152 and config constructs that are shared across projects in the program. 153* `src/project/$PROGRAM/$PROJECT`: The repository that defines your project. 154 This repository defines your project design under the constraints of the 155 program it belongs to. 156 157Partners will rarely propose changes to `src/config` and occasionally propose 158changes to `src/program/$PROGRAM`. The bulk of a partner's work will occur in 159in `src/project/$PROGRAM/$PROJECT`. 160 161## Making Configuration Changes for your Project 162 163Configuration changes are made to a project by adjusting the 164[Starlark](https://docs.bazel.build/versions/master/skylark/language.html) 165configuration definition in 166`$SOURCE_REPO/src/project/$PROGRAM/$PROJECT/config.star` and then running the 167`gen_config` script (added to the `PATH` above). An example session updating 168project configuration follows: 169 170``` 171cd $SOURCE_REPO/src/project/$PROGRAM/$PROJECT/ 172$EDITOR config.star 173# Adjust contents of config.star and save. 174gen_config config.star 175``` 176 177Note that many `config.star` files are executable, with the shebang 178`#!/usr/bin/env gen_config`. Thus `./config.star` can be used as a shortcut for 179`gen_config config.star` if `gen_config` is on `PATH`. 180 181This will cause the generation of payloads and config files that can be found 182at: 183 184* `$SOURCE_REPO/src/project/$PROGRAM/$PROJECT/generated/config.jsonproto` 185* `$SOURCE_REPO/src/project/$PROGRAM/$PROJECT/generated/project/sw_build_config/platform/chromeos-config/generated/project-config.json` 186 187`config.jsonproto` is a file containing the config protobuf 188[encoded as JSON](https://developers.google.com/protocol-buffers/docs/proto3#json). 189 190`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) 191and is present for backwards-compatibility. 192 193Before uploading the changes for review you should check to see if your 194changes pass constraint checks. You can do that by running the `check_config` 195script from within your project's root directory: 196 197``` 198cd $SOURCE_REPO/src/project/$PROGRAM/$PROJECT/ 199check_config 200``` 201 202If your changes pass the contraint checks you are ready to submit your 203CL. To submit the changes the user first commits the files and then submits 204them to commit queue (CQ): 205 206``` 207git add . 208git commit 209# Add commit message with BUG= and TEST= directives 210repo upload . 211``` 212 213This will result in a reviewable CL in 214[gerrit](https://chrome-internal-review.googlesource.com/). The exact URL 215for your CL will be output when the CL is uploaded. The CL will need to be 216approved and pass CQ. Details on working with CLs and the progression through 217review and CQ can be found in the 218[Chromium OS Contributing Guide](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/contributing.md) 219and more specifically in the 220[Going through review](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/contributing.md#Going-through-review) 221section. CQ verifies that you have correctly generated your configuration 222payload and that you have not violated the program's constraints. 223 224### CQ Verifier Access for Partners 225 226Some CQ verifiers will be visible to partners, for example the verifiers of the 227project and program configs. Visible builds will appear as links on the Gerrit 228page 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). 229 230**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) 231currently doesn't support partner access. Thus, stdout logs for key steps of the 232build are mirrored to per-project Google Storage buckets. The Google Storage 233mirrored logs appear as links like "stdout (GS mirror)" on the Milo page. 234 235## Contributing Protocol Buffer Schema Changes 236 237Protobuf schemas live under the `config` directory. To make a schema change 238(e.g. add a field), edit the `.proto` file and then run the `generate.sh` script 239in the root of this repo to generate the Protobuf bindings. 240 241See the [proto3 Language Guide](https://developers.google.com/protocol-buffers/docs/proto3) 242for more background on Protobuf. 243 244## Constraint Checkers 245 246As described above, a project config is verified against the constraints of the 247program before it is submitted. This is done by `check_config` locally and by 248CQ builders before submission. 249 250Constraints look and behave similar to Python unit tests, but are passed a 251program and project `ConfigBundle` to do assertions on. Constraints that apply 252to 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 253constraints are under the `checks` directory of the program repo. For example, 254see the [Galaxy](https://chrome-internal.googlesource.com/chromeos/program/galaxy/+/HEAD/checks/) 255test data program. 256 257## Public Configs 258 259The private project repo contains the entire project config; some config fields 260must remain private and some can be made public for building from a public 261checkout. Fields are private by default, and can be made public via the 262[`chromiumos.config.public_replication.PublicReplication`](https://chromium.googlesource.com/chromiumos/config/+/HEAD/proto/chromiumos/config/public_replication/public_replication.proto) 263message (see the message comment for the most up to date documentation). 264 265The `gen_config` command will parse `PublicReplication` messages to generate 266`public_config.jsonproto` and `public_sw_build_config` outputs, which are 267filtered versions of the full `config.jsonproto` and `sw_build_config` outputs, 268respectively. These public outputs will be automatically copied to the public 269[`chromiumos/project`](https://chromium.googlesource.com/chromiumos/project/+/refs/heads/main) 270repo after CLs are submitted, where they can be used in public ebuilds (because 271the file structure of the public configs is symmetrical to the private configs, 272the ebuild structure can be similar to private ebuilds). 273 274As with other configuration, Starlark functions in `util/` will provide defaults 275for public fields, but these settings can be overridden by individual programs 276and projects. 277 278## Directory Structure 279 280### chromiumos/config 281 282For contributing configuration changes for programs and projects, a familiarity 283with the follow directories in this repo is helpful: 284 285- `proto/`: Protobuf definitions for hardware configuration, 286software configuration, etc. This serves as the main API for configuring your 287project and program. 288 289- `util/`: Starlark utilities for use in program and project repos. Some 290utility functions are basic wrappers around Protobuf construction, others help 291with patterns that are common across patterns, e.g. configuring firmware 292payloads. 293 294- `test/`: A fake program and project. Useful to demonstrate the use of the 295Starlark utilities. 296 297- `bin/`: Tools needed to work in the configuration ecosystem, see the [above 298section](#Adding-Utilities-to-Your) on adding these tools to your `PATH`. 299 300- `go/`: Golang proto bindings. Used by platform code. 301 302- `python/`: Python proto bindings. Used by platform code. 303 304The following directories are likely more useful for contributors to the 305configuration and infrastructure systems: 306 307- `infra/`, `recipes/`: Needed to roll proto definitions into 308[Recipes](https://chromium.googlesource.com/infra/luci/recipes-py) repos. 309 310- `payload_utils/`: Utilities for working on configuration payloads, e.g. CQ 311checker to validate project configs. 312 313- `presubmit/`: Common files and libraries for program and project repo 314presubmits. 315 316- `sbin/`: Tools admins use to create and manage programs and projects. 317Regular users should not need to use these tools. 318 319### Program and Project Repos 320 321For contributing configuration changes for programs and projects, a familiarity 322with their layout patterns is helpful. 323 324- `config.star`: The main Starlark file to generate a program or project's 325configuration payload. See 326[Making Configuration Changes for your Project](#Making-Configuration-Changes-for-your-Project) 327 328- `generated/`: Generated configuration payloads. 329 330- `sw_build_config/`: Files for configuring software on the project's build. 331Contains manually-edited and generated files. 332 333- `public_sw_build_config/`: A filtered version of `sw_build_config`, for use 334in public builds. 335 336- `local_manifest.xml`: Local manifest for working on the project. See 337[Project Setup for Partners](#Project-Setup-for-Partners) 338 339- `config/`: Symlink to the `chromiumos/config` repo, for importing Starlark 340utils. 341 342- `program/`: Symlink from a project repo to the corresponding program repo, for 343importing program-level Starlark functions. 344 345- `PRESUBMIT.py`, `PRESUBMIT.cfg`: Presubmit configuration files. Shared across 346all programs and projects via symlink. 347 348## Making Bulk Changes Across Repos 349 350Program and project config are spread across repos, so changes and refactors 351often span multiple repos. A very common pattern occurs when a change in a 352program repo causes changes in that program's project repos when running 353`gen_config` for the projects. Tooling is available to make such changes more 354automated and less tedious than handcrafting individual CLs. Specifically, using 355the ClFactory tool and familiarity with `repo forall` and the 356`chromite/bin/gerrit` tools is helpful for these changes. 357 358### ClFactory 359 360[ClFactory](https://chromium.googlesource.com/chromiumos/infra/recipes/+/HEAD/recipes/cl_factory.py) 361is a builder that can generate CLs that are the fallout from changes 362via other CLs. ClFactory was written to address the pattern mentioned above 363where a change at the chromiumos/config or chromeos/program/$PROGRAM level 364results in changes in a high number of dependent repos. In order to remain 365consistent and pass CQ these typically must be submitted together. Generating 366these changes locally, setting commit messages, wiring up Cq-Depends, and 367sending out for review can be tedious, error prone, and time consuming. 368ClFactory is intended to make such CLs for you. 369 370With ClFactory you write your input CLs as normal. Then, to generate the 371dependent CLs that result from the changes, you invoke a builder that takes care 372of the rest. It will checkout the source, apply your input CLs, run `gen_config` 373in the dependent projects, create the CLs, add reviewers, etc.. 374 375A wrapper script, 376[cl_factory](https://chromium.googlesource.com/chromiumos/config/+/HEAD/bin/cl_factory), 377that lives in the bin directory of this repo, has been provided to simplify 378invoking ClFactory. The arguments are a bit involved, but the wrapper makes it 379much simpler than crafting a `bb add` command directly, which is the command 380that the wrapper delegates to. A typical invocation of ClFactory would look 381something like this: 382 383``` 384./bin/cl_factory \ 385 --cl https://chrome-internal-review.googlesource.com/c/chromeos/program/galaxy/+/3095418 \ 386 --regex src/program src/project \ 387 --reviewers reviewer1@chromium.org reviewer2@google.com \ 388 --ccs author@google.com \ 389 --hashtag regen-audio-configs \ 390 --message "Regenerate audio configs per changes at program level. 391 392BUG=chromium:1092954 393TEST=CQ" 394``` 395 396This would take CL 3095418 as input and run `gen_config` in the projects that 397match per the regex arguments. The resultant CLs would have reviewers, CCs, and 398other attributes set as indicated. When the builder is launched `cl_factory` 399will output a link to the milo page for that build. A link to this same build 400will also appear in the commit message of the generated CLs. From that milo 401build page you can follow the progress of generating the dependant CLs. The milo 402page also provides some valuable information in the step output. In particular, 403the "summarize results" step contains two pieces of information that will be of 404interest to the CL author and the reviewers. The first piece is the "unified 405diff" output. This will allow authors and reviewers to see what the entirety of 406all the changes are without having to open each individual generated CL. The 407second piece is the "gerrit commands." This output lists commands that can be 408used to label verified, label reviewed, and label for commit queue in bulk from 409the command line. This allows users to do this quickly as opposed to tediously 410navigating the gerrit pages of the generated CLs. 411 412### `repo forall` and `chromite/bin/gerrit` tooling 413 414`repo forall` can be used to make many commits across repos: 415 416``` 417# Begin branch in all projects. 418repo start --all fixbuggyvalue 419 420# Find all config.star files and fix bug. 421find src/project -name config.star -exec sed -i 's/buggyvalue/goodvalue/' {} \; 422 423# Make a commit for all project repos. 424repo forall -r src/project -c 'git commit -a -m" 425$(basename $REPO_PROJECT): Fix buggyvalue. 426 427BUG=chromium:123 428TEST=... 429"' 430 431# Upload changes with hashtag "fixbuggyvalue" 432repo upload --ht=fixbuggyvalue --re=reviewer@google.com 433``` 434 435Similarly, the `gerrit` tool can apply a label to many CLs: 436 437``` 438gerrit label-cq `gerrit --raw search "owner:me hashtag:fixbuggyvalue"` 1 439``` 440 441For anything where gerrit cannot accept multiple CLs, a shell loop 442can be used, for example the reviewers command: 443 444``` 445for cl in `gerrit -i --raw search "owner:me status:open hashtag:fixit"`; do 446 gerrit reviewers $cl reviewer1@google.com reviewer2@google.com 447done 448``` 449 450# DUT Attributes 451The `starlark/dut_attributes` directory defines a `DutAttributesList` containing 452all `DutAttributes` valid for use in test plans. New `DutAttributes` can be 453added in this file. 454 455Note that a **`DutAttribute` used on any branch cannot be deleted or modified**, 456because this may break the test plan on the branch. 457