1*6dbdd20aSAndroid Build Coastguard Worker# Perfetto CI design document 2*6dbdd20aSAndroid Build Coastguard Worker 3*6dbdd20aSAndroid Build Coastguard WorkerThis CI is used on-top of (not in replacement of) AOSP's TreeHugger. 4*6dbdd20aSAndroid Build Coastguard WorkerIt gives early testing signals and coverage on other OSes and older Android 5*6dbdd20aSAndroid Build Coastguard Workerdevices not supported by TreeHugger. 6*6dbdd20aSAndroid Build Coastguard Worker 7*6dbdd20aSAndroid Build Coastguard WorkerSee the [Testing](/docs/contributing/testing.md) page for more details about the 8*6dbdd20aSAndroid Build Coastguard Workerproject testing strategy. 9*6dbdd20aSAndroid Build Coastguard Worker 10*6dbdd20aSAndroid Build Coastguard Worker## Architecture diagram 11*6dbdd20aSAndroid Build Coastguard Worker 12*6dbdd20aSAndroid Build Coastguard Worker 13*6dbdd20aSAndroid Build Coastguard Worker 14*6dbdd20aSAndroid Build Coastguard WorkerThere are four major components: 15*6dbdd20aSAndroid Build Coastguard Worker 16*6dbdd20aSAndroid Build Coastguard Worker1. Frontend: AppEngine. 17*6dbdd20aSAndroid Build Coastguard Worker2. Controller: AppEngine BG service. 18*6dbdd20aSAndroid Build Coastguard Worker3. Workers: Compute Engine + Docker. 19*6dbdd20aSAndroid Build Coastguard Worker4. Database: Firebase realtime database. 20*6dbdd20aSAndroid Build Coastguard Worker 21*6dbdd20aSAndroid Build Coastguard WorkerThey are coupled via the Firebase DB. The DB is the source of truth for the 22*6dbdd20aSAndroid Build Coastguard Workerwhole CI. 23*6dbdd20aSAndroid Build Coastguard Worker 24*6dbdd20aSAndroid Build Coastguard Worker## Controller 25*6dbdd20aSAndroid Build Coastguard Worker 26*6dbdd20aSAndroid Build Coastguard WorkerThe Controller orchestrates the CI. It's the most trusted piece of the system. 27*6dbdd20aSAndroid Build Coastguard Worker 28*6dbdd20aSAndroid Build Coastguard WorkerIt is based on a background AppEngine service. Such service is only 29*6dbdd20aSAndroid Build Coastguard Workertriggered by deferred tasks and periodic Cron jobs. 30*6dbdd20aSAndroid Build Coastguard Worker 31*6dbdd20aSAndroid Build Coastguard WorkerThe Controller is the only entity which performs authenticated access to Gerrit. 32*6dbdd20aSAndroid Build Coastguard WorkerIt uses a non-privileged gmail account and has no meaningful voting power. 33*6dbdd20aSAndroid Build Coastguard Worker 34*6dbdd20aSAndroid Build Coastguard WorkerThe controller loop does mainly the following: 35*6dbdd20aSAndroid Build Coastguard Worker 36*6dbdd20aSAndroid Build Coastguard Worker- It periodically (every 15s) polls Gerrit for CLs updated in the last 24h. 37*6dbdd20aSAndroid Build Coastguard Worker- It checks the list of CLs against the list of already known CLs in the DB. 38*6dbdd20aSAndroid Build Coastguard Worker- For each new CL it enqueues `N` new jobs in the database, one for each 39*6dbdd20aSAndroid Build Coastguard Worker configuration defined in [config.py](/infra/ci/config.py) (e.g. `linux-debug`, 40*6dbdd20aSAndroid Build Coastguard Worker `android-release`, ...). 41*6dbdd20aSAndroid Build Coastguard Worker- It monitors the state of jobs. When all jobs for a CL have been completed, 42*6dbdd20aSAndroid Build Coastguard Worker it posts a comment and adds the vote if the CL is marked as `Presubmit-Ready`. 43*6dbdd20aSAndroid Build Coastguard Worker- It does some other less-relevant bookkeeping. 44*6dbdd20aSAndroid Build Coastguard Worker- AppEngine is highly reliable and self-healing. If a task fails (e.g. because 45*6dbdd20aSAndroid Build Coastguard Worker of a Gerrit 500) it will be automatically re-tried with exponential backoff. 46*6dbdd20aSAndroid Build Coastguard Worker 47*6dbdd20aSAndroid Build Coastguard Worker## Frontend 48*6dbdd20aSAndroid Build Coastguard Worker 49*6dbdd20aSAndroid Build Coastguard WorkerThe frontend is an AppEngine service that hosts the CI website @ 50*6dbdd20aSAndroid Build Coastguard Worker[ci.perfetto.dev](https://ci.perfetto.dev). 51*6dbdd20aSAndroid Build Coastguard WorkerConversely to the Controller, it is exposed to the public via HTTP. 52*6dbdd20aSAndroid Build Coastguard Worker 53*6dbdd20aSAndroid Build Coastguard Worker- It's an almost fully static website based on HTML and Javascript. 54*6dbdd20aSAndroid Build Coastguard Worker- The only backend-side code ([frontend.py](/infra/ci/frontend/main.py)) 55*6dbdd20aSAndroid Build Coastguard Worker is used to proxy XHR GET requests to Gerrit, due to the lack of Gerrit 56*6dbdd20aSAndroid Build Coastguard Worker CORS headers. 57*6dbdd20aSAndroid Build Coastguard Worker- Such XHR requests are GET-only and anonymous. 58*6dbdd20aSAndroid Build Coastguard Worker- The frontend python code also serves as a memcache layer for Gerrit requests 59*6dbdd20aSAndroid Build Coastguard Worker that return immutable data (e.g. revision logs) to reduce the likeliness of 60*6dbdd20aSAndroid Build Coastguard Worker hitting Gerrit errors / timeouts. 61*6dbdd20aSAndroid Build Coastguard Worker 62*6dbdd20aSAndroid Build Coastguard Worker## Worker GCE VM 63*6dbdd20aSAndroid Build Coastguard Worker 64*6dbdd20aSAndroid Build Coastguard WorkerThe actual testing job happens inside these Google Compute Engine VMs. 65*6dbdd20aSAndroid Build Coastguard WorkerThe GCE instance is running a CrOS-based 66*6dbdd20aSAndroid Build Coastguard Worker[Container-Optimized](https://cloud.google.com/container-optimized-os/docs/) OS. 67*6dbdd20aSAndroid Build Coastguard Worker 68*6dbdd20aSAndroid Build Coastguard WorkerThe whole system image is read-only. The VM itself is stateless. No state is 69*6dbdd20aSAndroid Build Coastguard Workerpersisted outside of the DB and Google Cloud Storage (only for UI artifacts). 70*6dbdd20aSAndroid Build Coastguard WorkerThe SSD is used only as a scratch disk and is cleared on each reboot. 71*6dbdd20aSAndroid Build Coastguard Worker 72*6dbdd20aSAndroid Build Coastguard WorkerVMs are dynamically spawned using the Google Cloud Autoscaler and use a 73*6dbdd20aSAndroid Build Coastguard WorkerStackdriver Custom Metric pushed by the Controller as cost function. 74*6dbdd20aSAndroid Build Coastguard WorkerSuch metric is the number of queued + running jobs. 75*6dbdd20aSAndroid Build Coastguard Worker 76*6dbdd20aSAndroid Build Coastguard WorkerEach VM runs two types of Docker containers: _worker_ and the _sandbox_. 77*6dbdd20aSAndroid Build Coastguard WorkerThey are in a 1:1 relationship, each worker controls at most one sandbox 78*6dbdd20aSAndroid Build Coastguard Workerassociated. Workers are always alive (they work in polling-mode), while 79*6dbdd20aSAndroid Build Coastguard Workersandboxes are started and stopped by the worker on-demand. 80*6dbdd20aSAndroid Build Coastguard Worker 81*6dbdd20aSAndroid Build Coastguard WorkerOn each GCE instance there are M (currently 10) worker containers running and 82*6dbdd20aSAndroid Build Coastguard Workerhence up to M sandboxes. 83*6dbdd20aSAndroid Build Coastguard Worker 84*6dbdd20aSAndroid Build Coastguard Worker### Worker containers 85*6dbdd20aSAndroid Build Coastguard Worker 86*6dbdd20aSAndroid Build Coastguard WorkerWorker containers are trusted entities. They can impersonate the GCE service 87*6dbdd20aSAndroid Build Coastguard Workeraccount and have R/W access to the DB. They can also spawn sandbox containers. 88*6dbdd20aSAndroid Build Coastguard Worker 89*6dbdd20aSAndroid Build Coastguard WorkerTheir behavior depends only on code that is manually deployed and doesn't depend 90*6dbdd20aSAndroid Build Coastguard Workeron the checkout under test. The reason why workers are Docker containers is NOT 91*6dbdd20aSAndroid Build Coastguard Workersecurity but only reproducibility and maintenance. 92*6dbdd20aSAndroid Build Coastguard Worker 93*6dbdd20aSAndroid Build Coastguard WorkerEach worker does the following: 94*6dbdd20aSAndroid Build Coastguard Worker 95*6dbdd20aSAndroid Build Coastguard Worker- Poll for an available job from the `/jobs_queued` sub-tree of the DB. 96*6dbdd20aSAndroid Build Coastguard Worker- Move such job into `/jobs_running`. 97*6dbdd20aSAndroid Build Coastguard Worker- Start the sandbox container, passing down the job config and the git revision 98*6dbdd20aSAndroid Build Coastguard Worker via env vars. 99*6dbdd20aSAndroid Build Coastguard Worker- Stream the sandbox stdout to the `/logs` sub-tree of the DB. 100*6dbdd20aSAndroid Build Coastguard Worker- Terminate the sandbox container prematurely in case of timeouts or job 101*6dbdd20aSAndroid Build Coastguard Worker cancellations requested by the Controller. 102*6dbdd20aSAndroid Build Coastguard Worker- Upload UI artifacts to GCS. 103*6dbdd20aSAndroid Build Coastguard Worker- Update the DB to reflect completion of jobs, removing the entry from 104*6dbdd20aSAndroid Build Coastguard Worker `/jobs_running` and updating the `/jobs/$jobId/status` fields. 105*6dbdd20aSAndroid Build Coastguard Worker 106*6dbdd20aSAndroid Build Coastguard Worker### Sandbox containers 107*6dbdd20aSAndroid Build Coastguard Worker 108*6dbdd20aSAndroid Build Coastguard WorkerSandbox containers are untrusted entities. They can access the internet 109*6dbdd20aSAndroid Build Coastguard Worker(for git pull / install-build-deps) but they cannot impersonate the GCE service 110*6dbdd20aSAndroid Build Coastguard Workeraccount, cannot write into the DB, cannot write into GCS buckets. 111*6dbdd20aSAndroid Build Coastguard WorkerDocker here is used both as an isolation boundary and for reproducibility / 112*6dbdd20aSAndroid Build Coastguard Workerdebugging. 113*6dbdd20aSAndroid Build Coastguard Worker 114*6dbdd20aSAndroid Build Coastguard WorkerEach sandbox does the following: 115*6dbdd20aSAndroid Build Coastguard Worker 116*6dbdd20aSAndroid Build Coastguard Worker- Checkout the code at the revision specified in the job config. 117*6dbdd20aSAndroid Build Coastguard Worker- Run one of the [test/ci/](/test/ci/) scripts which will build and run tests. 118*6dbdd20aSAndroid Build Coastguard Worker- Return either a success (0) or fail (!= 0) exit code. 119*6dbdd20aSAndroid Build Coastguard Worker 120*6dbdd20aSAndroid Build Coastguard WorkerA sandbox container is almost completely stateless with the only exception of 121*6dbdd20aSAndroid Build Coastguard Workerthe semi-ephemeral `/ci/cache` mount-point. This mount-point is tmpfs-based 122*6dbdd20aSAndroid Build Coastguard Worker(hence cleared on reboot) but is shared across all sandboxes. It's used only to 123*6dbdd20aSAndroid Build Coastguard Workermaintain the shared ccache. 124*6dbdd20aSAndroid Build Coastguard Worker 125*6dbdd20aSAndroid Build Coastguard Worker# Data model 126*6dbdd20aSAndroid Build Coastguard Worker 127*6dbdd20aSAndroid Build Coastguard WorkerThe whole CI is based on 128*6dbdd20aSAndroid Build Coastguard Worker[Firebase Realtime DB](https://firebase.google.com/docs/database). 129*6dbdd20aSAndroid Build Coastguard WorkerIt is a high-scale JSON object accessible via a simple REST API. 130*6dbdd20aSAndroid Build Coastguard WorkerClients can GET/PUT/PATCH/DELETE individual sub-nodes without having a local 131*6dbdd20aSAndroid Build Coastguard Workerfull-copy of the DB. 132*6dbdd20aSAndroid Build Coastguard Worker 133*6dbdd20aSAndroid Build Coastguard Worker```bash 134*6dbdd20aSAndroid Build Coastguard Worker/ci 135*6dbdd20aSAndroid Build Coastguard Worker # For post-submit jobs. 136*6dbdd20aSAndroid Build Coastguard Worker /branches 137*6dbdd20aSAndroid Build Coastguard Worker /main-20190626000853 138*6dbdd20aSAndroid Build Coastguard Worker # ┃ ┗━ Committer-date of the HEAD of the branch. 139*6dbdd20aSAndroid Build Coastguard Worker # ┗━ Branch name 140*6dbdd20aSAndroid Build Coastguard Worker { 141*6dbdd20aSAndroid Build Coastguard Worker author: "[email protected]" 142*6dbdd20aSAndroid Build Coastguard Worker rev: "0552edf491886d2bb6265326a28fef0f73025b6b" 143*6dbdd20aSAndroid Build Coastguard Worker subject: "Cloud-based CI" 144*6dbdd20aSAndroid Build Coastguard Worker time_committed: "2019-07-06T02:35:14Z" 145*6dbdd20aSAndroid Build Coastguard Worker jobs: 146*6dbdd20aSAndroid Build Coastguard Worker { 147*6dbdd20aSAndroid Build Coastguard Worker 20190708153242--branches-main-20190626000853--android-...: 0 148*6dbdd20aSAndroid Build Coastguard Worker 20190708153242--branches-main-20190626000853--linux-...: 0 149*6dbdd20aSAndroid Build Coastguard Worker ... 150*6dbdd20aSAndroid Build Coastguard Worker } 151*6dbdd20aSAndroid Build Coastguard Worker } 152*6dbdd20aSAndroid Build Coastguard Worker /main-20190701235742 {...} 153*6dbdd20aSAndroid Build Coastguard Worker 154*6dbdd20aSAndroid Build Coastguard Worker # For pre-submit jobs. 155*6dbdd20aSAndroid Build Coastguard Worker /cls 156*6dbdd20aSAndroid Build Coastguard Worker /1000515-65 157*6dbdd20aSAndroid Build Coastguard Worker { 158*6dbdd20aSAndroid Build Coastguard Worker change_id: "platform%2F...~I575be190" 159*6dbdd20aSAndroid Build Coastguard Worker time_queued: "2019-07-08T15:32:42Z" 160*6dbdd20aSAndroid Build Coastguard Worker time_ended: "2019-07-08T15:33:25Z" 161*6dbdd20aSAndroid Build Coastguard Worker revision_id: "18c2e4d0a96..." 162*6dbdd20aSAndroid Build Coastguard Worker wants_vote: true 163*6dbdd20aSAndroid Build Coastguard Worker voted: true 164*6dbdd20aSAndroid Build Coastguard Worker jobs: { 165*6dbdd20aSAndroid Build Coastguard Worker 20190708153242--cls-1000515-65--android-clang: 0 166*6dbdd20aSAndroid Build Coastguard Worker ... 167*6dbdd20aSAndroid Build Coastguard Worker 20190708153242--cls-1000515-65--ui-clang: 0 168*6dbdd20aSAndroid Build Coastguard Worker } 169*6dbdd20aSAndroid Build Coastguard Worker } 170*6dbdd20aSAndroid Build Coastguard Worker /1000515-66 {...} 171*6dbdd20aSAndroid Build Coastguard Worker ... 172*6dbdd20aSAndroid Build Coastguard Worker /1011130-3 {...} 173*6dbdd20aSAndroid Build Coastguard Worker 174*6dbdd20aSAndroid Build Coastguard Worker /cls_pending 175*6dbdd20aSAndroid Build Coastguard Worker # Effectively this is an array of pending CLs that we might need to 176*6dbdd20aSAndroid Build Coastguard Worker # vote on at the end. Only the keys matter, the values have no 177*6dbdd20aSAndroid Build Coastguard Worker # semantic and are always 0. 178*6dbdd20aSAndroid Build Coastguard Worker /1000515-65: 0 179*6dbdd20aSAndroid Build Coastguard Worker 180*6dbdd20aSAndroid Build Coastguard Worker /jobs 181*6dbdd20aSAndroid Build Coastguard Worker /20190708153242--cls-1000515-65--android-clang-arm-debug: 182*6dbdd20aSAndroid Build Coastguard Worker # ┃ ┃ ┗━ Job type. 183*6dbdd20aSAndroid Build Coastguard Worker # ┃ ┗━ Path of the CL or branch object. 184*6dbdd20aSAndroid Build Coastguard Worker # ┗━ Datetime when the job was created. 185*6dbdd20aSAndroid Build Coastguard Worker { 186*6dbdd20aSAndroid Build Coastguard Worker src: "cls/1000515-66" 187*6dbdd20aSAndroid Build Coastguard Worker status: "QUEUED" 188*6dbdd20aSAndroid Build Coastguard Worker "STARTED" 189*6dbdd20aSAndroid Build Coastguard Worker "COMPLETED" 190*6dbdd20aSAndroid Build Coastguard Worker "FAILED" 191*6dbdd20aSAndroid Build Coastguard Worker "TIMED_OUT" 192*6dbdd20aSAndroid Build Coastguard Worker "CANCELLED" 193*6dbdd20aSAndroid Build Coastguard Worker "INTERRUPTED" 194*6dbdd20aSAndroid Build Coastguard Worker time_ended: "2019-07-07T12:47:22Z" 195*6dbdd20aSAndroid Build Coastguard Worker time_queued: "2019-07-07T12:34:22Z" 196*6dbdd20aSAndroid Build Coastguard Worker time_started: "2019-07-07T12:34:25Z" 197*6dbdd20aSAndroid Build Coastguard Worker type: "android-clang-arm-debug" 198*6dbdd20aSAndroid Build Coastguard Worker worker: "zqz2-worker-2" 199*6dbdd20aSAndroid Build Coastguard Worker } 200*6dbdd20aSAndroid Build Coastguard Worker /20190707123422--cls-1000515-66--android-clang-arm-rel {..} 201*6dbdd20aSAndroid Build Coastguard Worker 202*6dbdd20aSAndroid Build Coastguard Worker /jobs_queued 203*6dbdd20aSAndroid Build Coastguard Worker # Effectively this is an array. Only the keys matter, the values 204*6dbdd20aSAndroid Build Coastguard Worker # have no semantic and are always 0. 205*6dbdd20aSAndroid Build Coastguard Worker /20190708153242--cls-1000515-65--android-clang-arm-debug: 0 206*6dbdd20aSAndroid Build Coastguard Worker 207*6dbdd20aSAndroid Build Coastguard Worker /jobs_running 208*6dbdd20aSAndroid Build Coastguard Worker # Effectively this is an array. Only the keys matter, the values 209*6dbdd20aSAndroid Build Coastguard Worker # have no semantic and are always 0. 210*6dbdd20aSAndroid Build Coastguard Worker /20190707123422--cls-1000515-66--android-clang-arm-rel 211*6dbdd20aSAndroid Build Coastguard Worker 212*6dbdd20aSAndroid Build Coastguard Worker /logs 213*6dbdd20aSAndroid Build Coastguard Worker /20190707123422--cls-1000515-66--android-clang-arm-rel 214*6dbdd20aSAndroid Build Coastguard Worker /00a053-0000: "+ chmod 777 /ci/cache /ci/artifacts" 215*6dbdd20aSAndroid Build Coastguard Worker # ┃ ┗━ Monotonic counter to establish total order on log lines 216*6dbdd20aSAndroid Build Coastguard Worker # ┃ retrieved within the same read() batch. 217*6dbdd20aSAndroid Build Coastguard Worker # ┃ 218*6dbdd20aSAndroid Build Coastguard Worker # ┗━ Hex-encoded timestamp, relative since start of test. 219*6dbdd20aSAndroid Build Coastguard Worker /00a053-0001: "+ chown perfetto.perfetto /ci/ramdisk" 220*6dbdd20aSAndroid Build Coastguard Worker ... 221*6dbdd20aSAndroid Build Coastguard Worker 222*6dbdd20aSAndroid Build Coastguard Worker``` 223*6dbdd20aSAndroid Build Coastguard Worker 224*6dbdd20aSAndroid Build Coastguard Worker# Sequence Diagram 225*6dbdd20aSAndroid Build Coastguard Worker 226*6dbdd20aSAndroid Build Coastguard WorkerThis is what happens, in order, on a worker instance from boot to the test run. 227*6dbdd20aSAndroid Build Coastguard Worker 228*6dbdd20aSAndroid Build Coastguard Worker```bash 229*6dbdd20aSAndroid Build Coastguard Workermake -C /infra/ci worker-start 230*6dbdd20aSAndroid Build Coastguard Worker┗━ gcloud start ... 231*6dbdd20aSAndroid Build Coastguard Worker 232*6dbdd20aSAndroid Build Coastguard Worker[GCE] # From /infra/ci/worker/gce-startup-script.sh 233*6dbdd20aSAndroid Build Coastguard Workerdocker run worker-1 ... 234*6dbdd20aSAndroid Build Coastguard Worker... 235*6dbdd20aSAndroid Build Coastguard Workerdocker run worker-N ... 236*6dbdd20aSAndroid Build Coastguard Worker 237*6dbdd20aSAndroid Build Coastguard Worker[worker-X] # From /infra/ci/worker/Dockerfile 238*6dbdd20aSAndroid Build Coastguard Worker┗━ /infra/ci/worker/worker.py 239*6dbdd20aSAndroid Build Coastguard Worker ┗━ docker run sandbox-X ... 240*6dbdd20aSAndroid Build Coastguard Worker 241*6dbdd20aSAndroid Build Coastguard Worker[sandbox-X] # From /infra/ci/sandbox/Dockerfile 242*6dbdd20aSAndroid Build Coastguard Worker┗━ /infra/ci/sandbox/init.sh 243*6dbdd20aSAndroid Build Coastguard Worker ┗━ /infra/ci/sandbox/testrunner.sh 244*6dbdd20aSAndroid Build Coastguard Worker ┣━ git fetch refs/changes/... 245*6dbdd20aSAndroid Build Coastguard Worker ┇ ... 246*6dbdd20aSAndroid Build Coastguard Worker ┇ # This env var is passed by the test definition 247*6dbdd20aSAndroid Build Coastguard Worker ┇ # specified in /infra/ci/config.py . 248*6dbdd20aSAndroid Build Coastguard Worker ┗━ $PERFETTO_TEST_SCRIPT 249*6dbdd20aSAndroid Build Coastguard Worker ┣━ # Which is one of these: 250*6dbdd20aSAndroid Build Coastguard Worker ┣━ /test/ci/android_tests.sh 251*6dbdd20aSAndroid Build Coastguard Worker ┣━ /test/ci/fuzzer_tests.sh 252*6dbdd20aSAndroid Build Coastguard Worker ┣━ /test/ci/linux_tests.sh 253*6dbdd20aSAndroid Build Coastguard Worker ┗━ /test/ci/ui_tests.sh 254*6dbdd20aSAndroid Build Coastguard Worker ┣━ ninja ... 255*6dbdd20aSAndroid Build Coastguard Worker ┗━ out/dist/{unit,integration,...}test 256*6dbdd20aSAndroid Build Coastguard Worker``` 257*6dbdd20aSAndroid Build Coastguard Worker 258*6dbdd20aSAndroid Build Coastguard Worker### [gce-startup-script.sh](/infra/ci/worker/gce-startup-script.sh) 259*6dbdd20aSAndroid Build Coastguard Worker 260*6dbdd20aSAndroid Build Coastguard Worker- Is ran once per GVE vm, at (re)boot. 261*6dbdd20aSAndroid Build Coastguard Worker- It prepares the tmpfs mountpoint for the shared ccache. 262*6dbdd20aSAndroid Build Coastguard Worker- It wipes the SSD scratch disk for the build artifacts 263*6dbdd20aSAndroid Build Coastguard Worker- It pulls the latest {worker, sandbox} container images from 264*6dbdd20aSAndroid Build Coastguard Worker the Google Cloud Container registry. 265*6dbdd20aSAndroid Build Coastguard Worker- Sets up Docker and `iptables` (for the sandboxed network). 266*6dbdd20aSAndroid Build Coastguard Worker- Starts `N` worker containers in Docker. 267*6dbdd20aSAndroid Build Coastguard Worker 268*6dbdd20aSAndroid Build Coastguard Worker### [worker.py](/infra/ci/worker/worker.py) 269*6dbdd20aSAndroid Build Coastguard Worker 270*6dbdd20aSAndroid Build Coastguard Worker- It polls the DB to retrieve a job. 271*6dbdd20aSAndroid Build Coastguard Worker- When a job is retrieved starts a sandbox container. 272*6dbdd20aSAndroid Build Coastguard Worker- It streams the container stdout/stderr to the DB. 273*6dbdd20aSAndroid Build Coastguard Worker- It upload the build artifacts to GCS. 274*6dbdd20aSAndroid Build Coastguard Worker 275*6dbdd20aSAndroid Build Coastguard Worker### [testrunner.sh](/infra/ci/sandbox/testrunner.sh) 276*6dbdd20aSAndroid Build Coastguard Worker 277*6dbdd20aSAndroid Build Coastguard Worker- It is pinned in the container image. Does NOT depend on the particular 278*6dbdd20aSAndroid Build Coastguard Worker revision being tested. 279*6dbdd20aSAndroid Build Coastguard Worker- Checks out the repo at the revision specified (by the Controller) in the 280*6dbdd20aSAndroid Build Coastguard Worker job config pulled from the DB. 281*6dbdd20aSAndroid Build Coastguard Worker- Sets up ccache 282*6dbdd20aSAndroid Build Coastguard Worker- Deals with caching of buildtools/. 283*6dbdd20aSAndroid Build Coastguard Worker- Runs the test script specified in the job config from the checkout. 284*6dbdd20aSAndroid Build Coastguard Worker 285*6dbdd20aSAndroid Build Coastguard Worker### [{android,fuzzer,linux,ui}_tests.sh](/test/ci/linux_tests.sh) 286*6dbdd20aSAndroid Build Coastguard Worker 287*6dbdd20aSAndroid Build Coastguard Worker- Are NOT pinned in the container and are ran from the checked out revision. 288*6dbdd20aSAndroid Build Coastguard Worker- Finally build and run the test. 289*6dbdd20aSAndroid Build Coastguard Worker 290*6dbdd20aSAndroid Build Coastguard Worker## Playbook 291*6dbdd20aSAndroid Build Coastguard Worker 292*6dbdd20aSAndroid Build Coastguard Worker### Frontend (JS/HTML/CSS) changes 293*6dbdd20aSAndroid Build Coastguard Worker 294*6dbdd20aSAndroid Build Coastguard WorkerTest-locally: `make -C infra/ci/frontend test` 295*6dbdd20aSAndroid Build Coastguard Worker 296*6dbdd20aSAndroid Build Coastguard WorkerDeploy with `make -C infra/ci/frontend deploy` 297*6dbdd20aSAndroid Build Coastguard Worker 298*6dbdd20aSAndroid Build Coastguard Worker### Controller changes 299*6dbdd20aSAndroid Build Coastguard Worker 300*6dbdd20aSAndroid Build Coastguard WorkerDeploy with `make -C infra/ci/controller deploy` 301*6dbdd20aSAndroid Build Coastguard Worker 302*6dbdd20aSAndroid Build Coastguard WorkerIt is possible to try locally via the `make -C infra/ci/controller test` 303*6dbdd20aSAndroid Build Coastguard Workerbut this involves: 304*6dbdd20aSAndroid Build Coastguard Worker 305*6dbdd20aSAndroid Build Coastguard Worker- Manually stopping the production AppEngine instance via the Cloud Console 306*6dbdd20aSAndroid Build Coastguard Worker (stopping via the `gcloud` cli doesn't seem to work, b/136828660) 307*6dbdd20aSAndroid Build Coastguard Worker 308*6dbdd20aSAndroid Build Coastguard Worker### Worker/Sandbox changes 309*6dbdd20aSAndroid Build Coastguard Worker 310*6dbdd20aSAndroid Build Coastguard Worker1. Build and push the new docker containers with: 311*6dbdd20aSAndroid Build Coastguard Worker 312*6dbdd20aSAndroid Build Coastguard Worker `make -C infra/ci build push` 313*6dbdd20aSAndroid Build Coastguard Worker 314*6dbdd20aSAndroid Build Coastguard Worker2. Restart the GCE instances, either manually or via 315*6dbdd20aSAndroid Build Coastguard Worker 316*6dbdd20aSAndroid Build Coastguard Worker `make -C infra/ci restart-workers` 317*6dbdd20aSAndroid Build Coastguard Worker 318*6dbdd20aSAndroid Build Coastguard Worker### Purging the job queue 319*6dbdd20aSAndroid Build Coastguard Worker 320*6dbdd20aSAndroid Build Coastguard WorkerThis can be useful when there is an outage and too many jobs pile up. 321*6dbdd20aSAndroid Build Coastguard Worker - Stop the workers: `make -C infra/ci stop-workers` 322*6dbdd20aSAndroid Build Coastguard Worker - Open https://console.firebase.google.com/u/0/project/perfetto-ci/database/perfetto-ci/data/~2Fci 323*6dbdd20aSAndroid Build Coastguard Worker - Delete the `jobs_running`, `jobs_queued`, `workers` subtrees 324*6dbdd20aSAndroid Build Coastguard Worker - Restart the workers: `make -C infra/ci start-workers` 325*6dbdd20aSAndroid Build Coastguard Worker 326*6dbdd20aSAndroid Build Coastguard Worker## Security considerations 327*6dbdd20aSAndroid Build Coastguard Worker 328*6dbdd20aSAndroid Build Coastguard Worker- Both the Firebase DB and the gs://perfetto-artifacts GCS bucket are 329*6dbdd20aSAndroid Build Coastguard Worker world-readable and writable by the GAE and GCE service accounts. 330*6dbdd20aSAndroid Build Coastguard Worker 331*6dbdd20aSAndroid Build Coastguard Worker- The GAE service account also has the ability to log into Gerrit using a 332*6dbdd20aSAndroid Build Coastguard Worker dedicated gmail.com account. The GCE service account doesn't. 333*6dbdd20aSAndroid Build Coastguard Worker 334*6dbdd20aSAndroid Build Coastguard Worker- Overall, no account in this project has any interesting privilege: 335*6dbdd20aSAndroid Build Coastguard Worker - The Gerrit account used for commenting on CLs is just a random gmail account 336*6dbdd20aSAndroid Build Coastguard Worker and has no special voting power. 337*6dbdd20aSAndroid Build Coastguard Worker - The service accounts of GAE and GCE don't have any special capabilities 338*6dbdd20aSAndroid Build Coastguard Worker outside of the CI project itself. 339*6dbdd20aSAndroid Build Coastguard Worker 340*6dbdd20aSAndroid Build Coastguard Worker- This CI deals only with functional and performance testing and doesn't deal 341*6dbdd20aSAndroid Build Coastguard Worker with any sort of continuous deployment. 342*6dbdd20aSAndroid Build Coastguard Worker 343*6dbdd20aSAndroid Build Coastguard Worker- Presubmit jobs are only triggered if at least one of the following is true: 344*6dbdd20aSAndroid Build Coastguard Worker - The owner of the CL is a @google.com account. 345*6dbdd20aSAndroid Build Coastguard Worker - The user that applied the Presubmit-Ready label is a @google.com account. 346*6dbdd20aSAndroid Build Coastguard Worker 347*6dbdd20aSAndroid Build Coastguard Worker- Sandboxes are not too hard to escape (Docker is the only boundary) and can 348*6dbdd20aSAndroid Build Coastguard Worker pollute each other via the shared ccache. 349*6dbdd20aSAndroid Build Coastguard Worker 350*6dbdd20aSAndroid Build Coastguard Worker- As such neither pre-submit nor post-submit build artifacts are considered 351*6dbdd20aSAndroid Build Coastguard Worker trusted. They are only used for establishing functional correctness and 352*6dbdd20aSAndroid Build Coastguard Worker performance regression testing. 353*6dbdd20aSAndroid Build Coastguard Worker 354*6dbdd20aSAndroid Build Coastguard Worker- Binaries built by the CI are not ran on any other machines outside of the 355*6dbdd20aSAndroid Build Coastguard Worker CI project. They are deliberately not downloadable. 356*6dbdd20aSAndroid Build Coastguard Worker 357*6dbdd20aSAndroid Build Coastguard Worker- The only build artifacts that are retained (for up to 30 days) and uploaded to 358*6dbdd20aSAndroid Build Coastguard Worker the GCS bucket are the UI artifacts. This is for the only sake of getting 359*6dbdd20aSAndroid Build Coastguard Worker visual previews of the HTML changes. 360*6dbdd20aSAndroid Build Coastguard Worker 361*6dbdd20aSAndroid Build Coastguard Worker- UI artifacts are served from a different origin (the GCS per-bucket API) than 362*6dbdd20aSAndroid Build Coastguard Worker the production UI. 363