Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
127 lines (108 loc) · 5.8 KB
/
Copy pathMakefile
File metadata and controls
127 lines (108 loc) · 5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# AWS bench rig for rapira. See docs/operations.md for the targets and the knobs.
SHELL := /bin/bash
.NOTPARALLEL:
REGION ?= eu-central-1
SERVER_TYPE ?= c7a.2xlarge
LOADER_TYPE ?= c7a.xlarge
LOADER_COUNT ?= 2
AZ ?= eu-central-1a
TTL ?= 60
REF ?=
NIGHTLY ?=
NIGHTLY_DIR ?=
# sha7 of the base build on the binaries release of this repository.
BASE ?=
SUITE ?= ci
ROUNDS ?=
AMI ?=
TF_BACKEND ?= local
# 1 builds rapira with frame pointers for a perf session. Server builds only.
FRAME_POINTERS ?= 0
RUN ?=
PAGES ?= runs/pages
BUF_VERSION ?= v1.73.0
BUF ?= go run github.com/bufbuild/buf/cmd/buf@$(BUF_VERSION)
TF := terraform -chdir=terraform
AWSC := aws --region $(REGION)
.PHONY: preflight up provision status bench pgo report extend sync lock down nuke test grpc_fixtures board
preflight:
@$(AWSC) sts get-caller-identity >/dev/null 2>&1 || \
{ echo "ERROR: AWS auth failed; run: aws sso login"; exit 1; }
# The chosen knobs persist in rig.auto.tfvars so every later terraform
# operation (provision, status, down) sees the applied values.
up: preflight
@python3 -m rig needs --suite $(SUITE) >/dev/null
@test -n "$(NIGHTLY)$(REF)" || { echo "ERROR: set NIGHTLY=<sha7> or REF=<ref>, for example: make up REF=pr/97 BASE=<sha7>"; exit 1; }
@test -n "$(BASE)" || { echo "ERROR: set BASE=<sha7> of a build on the binaries release, for example: make up NIGHTLY=<sha7> BASE=<sha7>"; exit 1; }
@quota=$$($(AWSC) service-quotas get-service-quota --service-code ec2 --quota-code L-1216C47A --query Quota.Value --output text 2>/dev/null); \
test -n "$$quota" || { echo "ERROR: could not read quota L-1216C47A; check the AWS permissions"; exit 1; }; \
sv=$$($(AWSC) ec2 describe-instance-types --instance-types $(SERVER_TYPE) --query 'InstanceTypes[0].VCpuInfo.DefaultVCpus' --output text 2>/dev/null); \
test -n "$$sv" || { echo "ERROR: unknown instance type $(SERVER_TYPE)"; exit 1; }; \
lv=$$($(AWSC) ec2 describe-instance-types --instance-types $(LOADER_TYPE) --query 'InstanceTypes[0].VCpuInfo.DefaultVCpus' --output text 2>/dev/null); \
test -n "$$lv" || { echo "ERROR: unknown instance type $(LOADER_TYPE)"; exit 1; }; \
awk -v q=$$quota -v n=$$((sv + lv * $(LOADER_COUNT))) 'BEGIN { if (n > q) { printf "ERROR: the rig needs %d vCPUs, the account quota is %d (adjustable: quota L-1216C47A)\n", n, q; exit 1 } }'
@ip=$$(curl -fs https://checkip.amazonaws.com) || \
{ echo "ERROR: could not determine the operator IP"; exit 1; }; \
{ echo "region = \"$(REGION)\""; \
echo "az = \"$(AZ)\""; \
echo "server_instance_type = \"$(SERVER_TYPE)\""; \
echo "loader_instance_type = \"$(LOADER_TYPE)\""; \
echo "loader_count = $(LOADER_COUNT)"; \
echo "ssh_cidr = \"$$ip/32\""; \
$(if $(AMI),echo "ami_id = \"$(AMI)\"";) } > terraform/rig.auto.tfvars
@if [ "$(TF_BACKEND)" = s3 ]; then cp terraform/backend.tf.s3 terraform/backend.tf; else rm -f terraform/backend.tf; fi
$(TF) init -input=false
$(TF) apply -auto-approve -input=false || \
{ echo "ERROR: apply failed; a partial rig may be billing, run 'make down'. On InsufficientInstanceCapacity retry with AZ=eu-central-1b or 1c."; exit 1; }
@$(MAKE) --no-print-directory provision
provision:
@needs=$$(python3 -m rig needs --suite $(SUITE)) && \
python3 -m rig provision --ttl $(TTL) --needs "$$needs" --nightly "$(NIGHTLY)" --nightly-dir "$(NIGHTLY_DIR)" --ref "$(REF)" --base "$(BASE)" --frame-pointers "$(FRAME_POINTERS)"
status: preflight
@out=$$($(TF) output 2>/dev/null); \
if [ -n "$$out" ]; then echo "$$out"; else echo "(no terraform outputs; rig not applied)"; fi
@$(AWSC) ec2 describe-instances --filters Name=tag:Project,Values=rapira-bench \
Name=instance-state-name,Values=pending,running,shutting-down,stopping,stopped \
--query 'Reservations[].Instances[].{id:InstanceId,state:State.Name,type:InstanceType,role:Tags[?Key==`Role`]|[0].Value,ip:PublicIpAddress}' \
--output table
@python3 -m rig ttl 2>/dev/null || true
bench:
@python3 -m rig bench --suite $(SUITE) $(if $(ROUNDS),--rounds $(ROUNDS))
# Make a PGO profile of the new build in pgo/: an instrumented build serves the rate stage of each suite target.
pgo:
@python3 -m rig pgo --suite $(SUITE)
# RUN selects a run directory; the default is the newest one under runs/.
report:
@d="$(RUN)"; [ -n "$$d" ] || d=$$(ls runs/*/run.json 2>/dev/null | sort | tail -1); d=$${d%/run.json}; \
test -n "$$d" || { echo "ERROR: no run in runs/"; exit 1; }; \
python3 -m rig report "$${d%/}/run.json"
extend:
@python3 -m rig ttl --set $(TTL)
# Build the local, possibly uncommitted ../core working tree on the server.
sync:
@python3 -m rig sync --src ../core
# Creates the gRPC lock file. Needs PHP 8.5 and Composer.
lock:
box/lock-apps.sh
down: preflight
@$(TF) destroy -auto-approve -input=false || \
{ echo "retrying: placement group deletion can lag instance termination"; sleep 30; $(TF) destroy -auto-approve -input=false; }
@rm -f .ssh-known-hosts .ssh-cm-*
# Tag-scoped aws-cli teardown for lost tfstate or after the TTL fired.
# Recovery order after state loss: make nuke, then make up.
nuke: preflight
@REGION=$(REGION) terraform/nuke.sh
@rm -f .ssh-known-hosts .ssh-cm-*
test:
python3 -m unittest discover -s tests -t .
# Local only: needs Go and network access to the buf remote plugins.
grpc_fixtures:
$(BUF) build apps/grpc --as-file-descriptor-set -o apps/grpc/bench.binpb
$(BUF) generate apps/grpc --template apps/grpc/buf.gen.yaml
python3 apps/grpc/fixtures.py
# Serve the board and a local pages dir for a manual check. Fill the dir first:
# python3 -m rig publish --pages-dir runs/pages runs/<id>/run.json
board:
@test -f $(PAGES)/data/index.json || { echo "ERROR: no $(PAGES)/data/index.json; run: python3 -m rig publish --pages-dir $(PAGES) runs/<id>/run.json"; exit 1; }
cp board/index.html board/app.js board/style.css board/chart.umd.js $(PAGES)/
python3 -m http.server --bind 127.0.0.1 --directory $(PAGES) 8000