-
Notifications
You must be signed in to change notification settings - Fork 290
/
Makefile
285 lines (221 loc) · 10.5 KB
/
Makefile
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
help:
@sed \
-e '/^[a-zA-Z0-9_\-\/\-]*:.*##/!d' \
-e 's/:.*##\s*/:/' \
-e 's/^\(.\+\):\(.*\)/$(shell tput setaf 6)\1$(shell tput sgr0):\2/' \
$(MAKEFILE_LIST) | column -c2 -t -s :
DOCKER_COMPOSE_FILE = docker-compose-developer.yml
DOCKER_COMPOSE_DEV_LABEL = com.grafana.oncall.env=dev
# compose profiles
MYSQL_PROFILE = mysql
POSTGRES_PROFILE = postgres
SQLITE_PROFILE = sqlite
ENGINE_PROFILE = engine
UI_PROFILE = oncall_ui
REDIS_PROFILE = redis
RABBITMQ_PROFILE = rabbitmq
PROMETHEUS_PROFILE = prometheus
GRAFANA_PROFILE = grafana
TELEGRAM_POLLING_PROFILE = telegram_polling
DEV_ENV_DIR = ./dev
DEV_ENV_FILE = $(DEV_ENV_DIR)/.env.dev
DEV_ENV_EXAMPLE_FILE = $(DEV_ENV_FILE).example
DEV_HELM_FILE = $(DEV_ENV_DIR)/helm-local.yml
DEV_HELM_USER_SPECIFIC_FILE = $(DEV_ENV_DIR)/helm-local.dev.yml
ENGINE_DIR = ./engine
VENV_DIR = ./venv
REQUIREMENTS_DEV_IN = $(ENGINE_DIR)/requirements-dev.in
REQUIREMENTS_DEV_TXT = $(ENGINE_DIR)/requirements-dev.txt
REQUIREMENTS_IN = $(ENGINE_DIR)/requirements.in
REQUIREMENTS_TXT = $(ENGINE_DIR)/requirements.txt
REQUIREMENTS_ENTERPRISE_TXT = $(ENGINE_DIR)/requirements-enterprise.txt
SQLITE_DB_FILE = $(ENGINE_DIR)/oncall.db
# make sure that DEV_HELM_USER_SPECIFIC_FILE and SQLITE_DB_FILE always exists
# (NOTE: touch will only create the file if it doesn't already exist)
$(shell touch $(DEV_HELM_USER_SPECIFIC_FILE))
$(shell touch $(SQLITE_DB_FILE))
# -n flag only copies DEV_ENV_EXAMPLE_FILE-> DEV_ENV_FILE if it doesn't already exist
$(shell cp -n $(DEV_ENV_EXAMPLE_FILE) $(DEV_ENV_FILE))
include $(DEV_ENV_FILE)
# if COMPOSE_PROFILES is set in DEV_ENV_FILE use it
# otherwise use a default (or what is passed in as an arg)
ifeq ($(COMPOSE_PROFILES),)
COMPOSE_PROFILES=$(ENGINE_PROFILE),$(UI_PROFILE),$(REDIS_PROFILE),$(GRAFANA_PROFILE)
endif
# conditionally assign DB based on what is present in COMPOSE_PROFILES
ifeq ($(findstring $(MYSQL_PROFILE),$(COMPOSE_PROFILES)),$(MYSQL_PROFILE))
DB=$(MYSQL_PROFILE)
else ifeq ($(findstring $(POSTGRES_PROFILE),$(COMPOSE_PROFILES)),$(POSTGRES_PROFILE))
DB=$(POSTGRES_PROFILE)
else
DB=$(SQLITE_PROFILE)
endif
# conditionally assign BROKER_TYPE based on what is present in COMPOSE_PROFILES
# if the user specifies both rabbitmq and redis, we'll make the assumption that rabbitmq is the broker
ifeq ($(findstring $(RABBITMQ_PROFILE),$(COMPOSE_PROFILES)),$(RABBITMQ_PROFILE))
BROKER_TYPE=$(RABBITMQ_PROFILE)
else
BROKER_TYPE=$(REDIS_PROFILE)
endif
# TODO: remove this when docker-compose local setup is removed
# https://stackoverflow.com/a/649462
define _DEPRECATION_MESSAGE
⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
NOTE: docker-compose based make commands will be deprecated on (or around) October 1, 2023, in favour of
tilt/k8s based commands. Please familirize yourself with the tilt/k8s commands.
See https://github.com/grafana/oncall/tree/dev/dev for instructions on how to use tilt helm/k8s commands.
⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
endef
export _DEPRECATION_MESSAGE
define echo_deprecation_message
@echo "$$_DEPRECATION_MESSAGE"
endef
# SQLITE_DB_FiLE is set to properly mount the sqlite db file
DOCKER_COMPOSE_ENV_VARS := COMPOSE_PROFILES=$(COMPOSE_PROFILES) DB=$(DB) BROKER_TYPE=$(BROKER_TYPE)
# It's better to output pip log on the fly while building because it takes a lot of time
DOCKER_COMPOSE_ENV_VARS += BUILDKIT_PROGRESS=plain
ifeq ($(DB),$(SQLITE_PROFILE))
DOCKER_COMPOSE_ENV_VARS += SQLITE_DB_FILE=$(SQLITE_DB_FILE)
endif
define run_docker_compose_command
$(call echo_deprecation_message)
$(DOCKER_COMPOSE_ENV_VARS) docker compose -f $(DOCKER_COMPOSE_FILE) $(1)
endef
define run_engine_docker_command
$(call run_docker_compose_command,run --rm oncall_engine_commands $(1))
endef
define run_ui_docker_command
$(call run_docker_compose_command,run --rm oncall_ui sh -c '$(1)')
endef
# always use settings.ci_test django settings file when running the tests
# if we use settings.dev it's very possible that some fail just based on the settings alone
define run_backend_tests
$(call run_engine_docker_command,pytest --ds=settings.ci_test $(1))
endef
.PHONY: local/up
local/up: cluster/up ## (beta) deploy all containers locally via tilt (k8s cluster will be created if it doesn't exist)
tilt up
.PHONY: local/down
local/down: ## (beta) remove all containers deployed via tilt
tilt down
.PHONY: local/clean
local/clean: cluster/down ## (beta) clean up k8s local dev environment
.PHONY: cluster/up
cluster/up: ## (beta) create a local development k8s cluster
ctlptl apply -f dev/kind-config.yaml
.PHONY: cluster/down
cluster/down: ## (beta) delete local development k8s cluster
ctlptl delete -f dev/kind-config.yaml
start: ## start all of the docker containers
$(call run_docker_compose_command,up --remove-orphans -d)
init: ## build the frontend plugin code then run make start
# if the oncall UI is to be run in docker we should do an initial build of the frontend code
# this makes sure that it will be available when the grafana container starts up without the need to
# restart the grafana container initially
ifeq ($(findstring $(UI_PROFILE),$(COMPOSE_PROFILES)),$(UI_PROFILE))
$(call run_ui_docker_command,pnpm install && pnpm build:dev)
endif
stop: # stop all of the docker containers
$(call run_docker_compose_command,down)
restart: ## restart all docker containers
$(call run_docker_compose_command,restart)
build: ## rebuild images (e.g. when changing requirements.txt)
$(call run_docker_compose_command,build)
cleanup: stop ## this will remove all of the images, containers, volumes, and networks
## associated with your local OnCall developer setup
$(call echo_deprecation_message)
docker system prune --filter label="$(DOCKER_COMPOSE_DEV_LABEL)" --all --volumes --force
docker volume prune --filter label="$(DOCKER_COMPOSE_DEV_LABEL)" --all --force
install-pre-commit:
@if [ ! -x "$$(command -v pre-commit)" ]; then \
echo "installing pre-commit"; \
pip install $$(grep "pre-commit" $(ENGINE_DIR)/requirements-dev.txt); \
else \
echo "pre-commit already installed"; \
fi
lint: install-pre-commit ## run both frontend and backend linters
## may need to run `pnpm install` from within `grafana-plugin`
## to install several `pre-commit` dependencies
pre-commit run --all-files
install-precommit-hook: install-pre-commit
pre-commit install
test: ## run backend tests
$(call run_backend_tests)
test-dev: ## very similar to `test` command, but allows you to pass arbitray args to pytest
## for example, `make test-dev ARGS="--last-failed --pdb"
$(call run_backend_tests,$(ARGS))
test-helm: ## run helm unit tests
helm unittest ./helm/oncall $(ARGS)
start-celery-beat: ## start celery beat
$(call run_engine_docker_command,celery -A engine beat -l info)
purge-queues: ## purge celery queues
$(call run_engine_docker_command,celery -A engine purge -f)
shell: ## starts an OnCall engine Django shell
$(call run_engine_docker_command,python manage.py shell)
dbshell: ## opens a DB shell
$(call run_engine_docker_command,python manage.py dbshell)
engine-manage: ## run Django's `manage.py` script, inside of a docker container, passing `$CMD` as arguments.
## e.g. `make engine-manage CMD="makemigrations"`
## https://docs.djangoproject.com/en/4.1/ref/django-admin/#django-admin-makemigrations
$(call run_engine_docker_command,python manage.py $(CMD))
test-e2e: ## run the e2e tests in headless mode
pnpm --dir grafana-plugin test:e2e
test-e2e-watch: ## start e2e tests in watch mode
pnpm --dir grafana-plugin test:e2e:watch
test-e2e-show-report: ## open last e2e test report
pnpm --dir grafana-plugin playwright show-report
ui-test: ## run the UI tests
$(call run_ui_docker_command,pnpm test)
ui-lint: ## run the UI linter
$(call run_ui_docker_command,pnpm lint)
ui-build: ## build the UI
$(call run_ui_docker_command,pnpm build)
ui-command: ## run any command, inside of a UI docker container, passing `$CMD` as arguments.
## e.g. `make ui-command CMD="pnpm test"`
$(call run_ui_docker_command,$(CMD))
exec-engine: ## exec into engine container's bash
docker exec -it oncall_engine bash
_backend-debug-enable: ## enable Django's debug mode and Silk profiling (this is disabled by default for performance reasons)
$(shell ./dev/add_env_var.sh DEBUG True $(DEV_ENV_FILE))
$(shell ./dev/add_env_var.sh SILK_PROFILER_ENABLED True $(DEV_ENV_FILE))
_backend-debug-disable: ## disable Django's debug mode and Silk profiling
$(shell ./dev/add_env_var.sh DEBUG False $(DEV_ENV_FILE))
$(shell ./dev/add_env_var.sh SILK_PROFILER_ENABLED False $(DEV_ENV_FILE))
backend-debug-enable: _backend-debug-enable stop start
backend-debug-disable: _backend-debug-disable stop start
pip-compile-locked-dependencies: ## compile engine requirements.txt files
$(shell cd engine && uv pip compile requirements.in -o requirements.txt)
$(shell cd engine && uv pip compile requirements-dev.in -o requirements-dev.txt)
# The below commands are useful for running backend services outside of docker
define backend_command
export `grep -v '^#' $(DEV_ENV_FILE) | xargs -0` && \
export BROKER_TYPE=$(BROKER_TYPE) && \
. $(VENV_DIR)/bin/activate && \
cd engine && \
$(1)
endef
backend-bootstrap:
python3.12 -m venv $(VENV_DIR)
$(VENV_DIR)/bin/pip install -U pip wheel uv
$(VENV_DIR)/bin/uv pip sync --python=$(VENV_DIR)/bin/python $(REQUIREMENTS_TXT) $(REQUIREMENTS_DEV_TXT)
@if [ -f $(REQUIREMENTS_ENTERPRISE_TXT) ]; then \
$(VENV_DIR)/bin/uv pip install --python=$(VENV_DIR)/bin/python -r $(REQUIREMENTS_ENTERPRISE_TXT); \
fi
backend-migrate:
$(call backend_command,python manage.py migrate)
backend-compile-deps:
uv pip compile --strip-extras $(REQUIREMENTS_IN)
uv pip compile --strip-extras $(REQUIREMENTS_DEV_IN)
backend-upgrade-deps:
uv pip compile --strip-extras --upgrade $(REQUIREMENTS_IN)
run-backend-server:
$(call backend_command,python manage.py runserver 0.0.0.0:8080)
run-backend-celery:
$(call backend_command,python manage.py start_celery)
backend-command:
$(call backend_command,$(CMD))
backend-manage-command: ## run Django's `manage.py` script, passing `$CMD` as arguments.
## e.g. `make backend-manage-command CMD="makemigrations"`
## https://docs.djangoproject.com/en/4.1/ref/django-admin/#django-admin-makemigrations
## alternatively you can open docker container with engine and run commands from there
$(call backend_command,python manage.py $(CMD))