| # Copyright (C) 2019 The Android Open Source Project | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| include $(shell python3 config.py makefile) | |
| override COMMON_DEPS := Makefile *.py | |
| override GCE_LOCAL_STARTUP_SCRIPT := worker/gce-startup-script.sh | |
| override SCRIPT_HASH := $(shell git hash-object ${GCE_LOCAL_STARTUP_SCRIPT} | cut -c 1-8) | |
| override GCE_STARTUP_SCRIPT := gs://perfetto/ci/worker-startup-script/${SCRIPT_HASH} | |
| BUILDER := docker | |
| .PHONY: help | |
| help: | |
| @echo "build: Builds the worker and sandbox containers" | |
| @echo "build-worker: Builds the worker container" | |
| @echo "build-sandbox: Builds the sandbox container" | |
| @echo "push: Pushes the containers to the registry" | |
| @echo "deploy-frontend: Deploys and restarts the controller" | |
| @echo "stop-workers: Stops the whole workers GCE instance group" | |
| @echo "start-workers: Starts the whole workers GCE instance group" | |
| @echo "restart-workers: Restarts the whole workers GCE instance group" | |
| .PHONY: build | |
| build: build-worker build-sandbox | |
| .PHONY: build-worker | |
| build-worker: .deps/${BUILDER}-worker | |
| .PHONY: build-sandbox | |
| build-sandbox: .deps/${BUILDER}-sandbox | |
| .PHONY: push | |
| push: build | |
| echo "If push below fails run: gcloud auth configure-docker us-docker.pkg.dev" | |
| ${BUILDER} push ${WORKER_IMG} | |
| ${BUILDER} push ${SANDBOX_IMG} | |
| .PHONY: clean | |
| clean: | |
| rm -rf .deps | |
| .deps/${BUILDER}-worker: worker/* ${COMMON_DEPS} | |
| mkdir -p worker/tmp | |
| cp -a config.py common_utils.py worker/tmp/ | |
| ${BUILDER} build --rm --force-rm -t ${WORKER_IMG} worker | |
| rm -rf worker/tmp/ | |
| touch $@ | |
| .deps/${BUILDER}-sandbox: sandbox/* ${COMMON_DEPS} | |
| mkdir -p sandbox/tmp | |
| cp -a config.py common_utils.py sandbox/tmp/ | |
| ${BUILDER} build --rm --force-rm -t ${SANDBOX_IMG} sandbox | |
| rm -rf sandbox/tmp/ | |
| touch $@ | |
| .deps/upload-startup-script: ${GCE_LOCAL_STARTUP_SCRIPT} ${COMMON_DEPS} | |
| gsutil -q cp -a public-read ${GCE_LOCAL_STARTUP_SCRIPT} ${GCE_STARTUP_SCRIPT} | |
| touch $@ | |
| .deps/gce-template: ${COMMON_DEPS} .deps/upload-startup-script | |
| gcloud compute --quiet --project=${PROJECT} \ | |
| instance-templates delete --quiet ${GCE_TEMPLATE} || true | |
| gcloud compute --quiet --project=${PROJECT} \ | |
| instance-templates create ${GCE_TEMPLATE} \ | |
| --enable-nested-virtualization \ | |
| --machine-type=${GCE_VM_TYPE} \ | |
| --network=projects/${PROJECT}/global/networks/default \ | |
| --network-tier=PREMIUM \ | |
| --metadata='startup-script-url=${GCE_STARTUP_SCRIPT},num-workers=${NUM_WORKERS_PER_VM},sandbox-img=${SANDBOX_IMG},worker-img=${WORKER_IMG},google-logging-enabled=true,enable-oslogin=TRUE' \ | |
| --maintenance-policy=MIGRATE \ | |
| --service-account=gce-ci-worker@${PROJECT}.iam.gserviceaccount.com \ | |
| --scopes=${GCE_SCOPES} \ | |
| --image=projects/cos-cloud/global/images/cos-121-18867-90-23 \ | |
| --boot-disk-size=100GB \ | |
| --boot-disk-type=pd-ssd \ | |
| --boot-disk-device-name=${GCE_TEMPLATE} \ | |
| --local-ssd=interface=NVME \ | |
| --local-ssd=interface=NVME | |
| touch $@ | |
| .PHONY: deploy-frontend | |
| deploy-frontend: | |
| make -C frontend deploy | |
| .PHONY: restart-workers | |
| restart-workers: stop-workers start-workers | |
| define start-workers-for-region | |
| gcloud compute --project=${PROJECT} \ | |
| instance-groups managed create ${GCE_GROUP_NAME}-$1 \ | |
| --region=$1 \ | |
| --base-instance-name=${GCE_GROUP_NAME}-$1 \ | |
| --template=${GCE_TEMPLATE} \ | |
| --size 0 | |
| gcloud compute --quiet --project=$(PROJECT) \ | |
| instance-groups managed set-autoscaling ${GCE_GROUP_NAME}-$1 \ | |
| --region=$1 \ | |
| --min-num-replicas=${AUTOSCALER_MIN} \ | |
| --max-num-replicas=${MAX_VMS_PER_REGION} \ | |
| --cool-down-period=60 \ | |
| --stackdriver-metric-filter="resource.type = \"global\"" \ | |
| --update-stackdriver-metric="custom.googleapis.com/$(PROJECT)/ci_job_queue_len" \ | |
| --stackdriver-metric-utilization-target=0.1 \ | |
| --stackdriver-metric-utilization-target-type=gauge | |
| endef | |
| .PHONY: start-workers | |
| start-workers: .deps/gce-template | |
| $(foreach region,$(GCE_REGIONS),$(call start-workers-for-region,$(region))) | |
| define stop-workers-for-region | |
| gcloud compute --quiet --project=${PROJECT} \ | |
| instance-groups managed delete ${GCE_GROUP_NAME}-$1 --region=$1 || true | |
| endef | |
| .PHONY: stop-workers | |
| stop-workers: | |
| $(foreach region,$(GCE_REGIONS),$(call stop-workers-for-region,$(region))) | |
| .PHONY: autoscaler-debug | |
| autoscaler-debug: | |
| gcloud compute instance-groups managed describe | |
| ${GCE_GROUP_NAME}-${GCE_REGIONS} \ | |
| --project=${PROJECT} \ | |
| --region=${GCE_REGIONS} | |
| # These are for testing only, start an individual VM. Use start-group for | |
| # production. | |
| .PHONY: stop-worker-for-testing | |
| stop-worker-for-testing: | |
| gcloud compute --quiet \ | |
| --project ${PROJECT} \ | |
| instances delete ${GCE_VM_NAME} \ | |
| --zone us-west1-c | |
| .PHONY: start-worker-for-testing | |
| start-worker-for-testing: .deps/gce-template | |
| gcloud compute --quiet \ | |
| --project ${PROJECT} \ | |
| instances create ${GCE_VM_NAME} \ | |
| --zone us-west1-c \ | |
| --source-instance-template=${GCE_TEMPLATE} | |
| # Debugging client to make OAuth2 authenticated requests manually. | |
| .PHONY: cli | |
| cli: | |
| GOOGLE_APPLICATION_CREDENTIALS=test-credentials.json \ | |
| python3 -i -c 'from common_utils import *; from config import *; \ | |
| SCOPES += ["https://www.googleapis.com/auth/firebase.database", \ | |
| "https://www.googleapis.com/auth/userinfo.email", \ | |
| "https://www.googleapis.com/auth/datastore"]' |