Skip to content
This repository has been archived by the owner on Nov 14, 2023. It is now read-only.

Commit

Permalink
Rework the backend entrypoint (cvat-ai#6750)
Browse files Browse the repository at this point in the history
* Make it possible to run migrations without starting the server, and
vice versa. This is not yet used, but it will be needed later to enable
database initialization/upgrade in a configuration with multiple server
containers.

* Wait for migrations to complete in worker containers, to be safe.
Workers also use the database.

* Add a help message and a way to run the shell (useful for
development).

* Add support for initialization scripts, which helps simplify the
smokescreen hack needed for the webhook tests.
  • Loading branch information
SpecLad authored and mikhail-treskin committed Oct 25, 2023
1 parent ea9ce9f commit 994f84c
Show file tree
Hide file tree
Showing 15 changed files with 98 additions and 51 deletions.
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -202,5 +202,4 @@ WORKDIR ${HOME}
RUN mkdir -p data share keys logs /tmp/supervisord static

EXPOSE 8080
ENTRYPOINT ["/usr/bin/supervisord"]
CMD ["-c", "supervisord/all.conf"]
ENTRYPOINT ["./backend_entrypoint.sh"]
72 changes: 66 additions & 6 deletions backend_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,68 @@
#!/bin/sh
#!/usr/bin/env bash

set -e
set -eu

${HOME}/wait-for-it.sh ${CVAT_POSTGRES_HOST}:5432 -t 0
python3 ${HOME}/manage.py migrate
python3 ${HOME}/manage.py collectstatic --no-input
exec /usr/bin/supervisord -c supervisord/server.conf
fail() {
printf >&2 "%s: %s\n" "$0" "$1"
exit 1
}

wait_for_db() {
~/wait-for-it.sh "${CVAT_POSTGRES_HOST}:5432" -t 0
}

cmd_bash() {
exec bash "$@"
}

cmd_init() {
wait_for_db
~/manage.py migrate
}

cmd_run() {
if [ "$#" -ne 1 ]; then
fail "run: expected 1 argument"
fi

if [ "$1" = "server" ]; then
~/manage.py collectstatic --no-input
fi

wait_for_db

echo "waiting for migrations to complete..."
while ! ~/manage.py migrate --check; do
sleep 1
done

exec supervisord -c "supervisord/$1.conf"
}

if [ $# -eq 0 ]; then
echo >&2 "$0: at least one subcommand required"
echo >&2 ""
echo >&2 "available subcommands:"
echo >&2 " bash <bash args...>"
echo >&2 " init"
echo >&2 " run <config name>"
exit 1
fi

for init_script in /etc/cvat/init.d/*; do
if [ -r "$init_script" ]; then
. "$init_script"
fi
done

while [ $# -ne 0 ]; do
if [ "$(type -t "cmd_$1")" != "function" ]; then
fail "unknown subcommand: $1"
fi

cmd_name="$1"

shift

"cmd_$cmd_name" "$@"
done
16 changes: 8 additions & 8 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ services:
CVAT_ANALYTICS: 1
CVAT_BASE_URL:
SMOKESCREEN_OPTS: ${SMOKESCREEN_OPTS:-}
entrypoint: /home/django/backend_entrypoint.sh
command: init run server
labels:
- traefik.enable=true
- traefik.http.services.cvat.loadbalancer.server.port=8080
Expand Down Expand Up @@ -79,7 +79,7 @@ services:
DJANGO_LOG_SERVER_PORT: 80
no_proxy: clickhouse,grafana,vector,nuclio,opa,${no_proxy:-}
NUMPROCS: 1
command: -c supervisord/utils.conf
command: run utils
volumes:
- cvat_data:/home/django/data
- cvat_keys:/home/django/keys
Expand All @@ -102,7 +102,7 @@ services:
no_proxy: clickhouse,grafana,vector,nuclio,opa,${no_proxy:-}
NUMPROCS: 2
SMOKESCREEN_OPTS: ${SMOKESCREEN_OPTS:-}
command: -c supervisord/worker.import.conf
command: run worker.import
volumes:
- cvat_data:/home/django/data
- cvat_keys:/home/django/keys
Expand All @@ -125,7 +125,7 @@ services:
DJANGO_LOG_SERVER_PORT: 80
no_proxy: clickhouse,grafana,vector,nuclio,opa,${no_proxy:-}
NUMPROCS: 2
command: -c supervisord/worker.export.conf
command: run worker.export
volumes:
- cvat_data:/home/django/data
- cvat_keys:/home/django/keys
Expand All @@ -148,7 +148,7 @@ services:
DJANGO_LOG_SERVER_PORT: 80
no_proxy: clickhouse,grafana,vector,nuclio,opa,${no_proxy:-}
NUMPROCS: 1
command: -c supervisord/worker.annotation.conf
command: run worker.annotation
volumes:
- cvat_data:/home/django/data
- cvat_keys:/home/django/keys
Expand All @@ -172,7 +172,7 @@ services:
no_proxy: clickhouse,grafana,vector,nuclio,opa,${no_proxy:-}
NUMPROCS: 1
SMOKESCREEN_OPTS: ${SMOKESCREEN_OPTS:-}
command: -c supervisord/worker.webhooks.conf
command: run worker.webhooks
volumes:
- cvat_data:/home/django/data
- cvat_keys:/home/django/keys
Expand All @@ -194,7 +194,7 @@ services:
DJANGO_LOG_SERVER_PORT: 80
no_proxy: clickhouse,grafana,vector,nuclio,opa,${no_proxy:-}
NUMPROCS: 1
command: -c supervisord/worker.quality_reports.conf
command: run worker.quality_reports
volumes:
- cvat_data:/home/django/data
- cvat_keys:/home/django/keys
Expand All @@ -217,7 +217,7 @@ services:
CLICKHOUSE_HOST: clickhouse
no_proxy: clickhouse,grafana,vector,nuclio,opa,${no_proxy:-}
NUMPROCS: 2
command: -c supervisord/worker.analytics_reports.conf
command: run worker.analytics_reports
volumes:
- cvat_data:/home/django/data
- cvat_keys:/home/django/keys
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
args: ["-c", "supervisord/worker.webhooks.conf"]
args: ["run", "worker.webhooks"]
env:
{{- if .Values.redis.enabled }}
- name: CVAT_REDIS_HOST
Expand Down
2 changes: 1 addition & 1 deletion helm-chart/templates/cvat_backend/server/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
command: ["/home/django/backend_entrypoint.sh"]
args: ["init", "run", "server"]
env:
- name: ALLOWED_HOSTS
value: {{ .Values.cvat.backend.server.envs.ALLOWED_HOSTS | squote}}
Expand Down
2 changes: 1 addition & 1 deletion helm-chart/templates/cvat_backend/utils/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
args: ["-c", "supervisord/utils.conf"]
args: ["run", "utils"]
env:
{{- if .Values.redis.enabled }}
- name: CVAT_REDIS_HOST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
args: ["-c", "supervisord/worker.analytics_reports.conf"]
args: ["run", "worker.analytics_reports"]
env:
{{- if .Values.redis.enabled }}
- name: CVAT_REDIS_HOST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
args: ["-c", "supervisord/worker.annotation.conf"]
args: ["run", "worker.annotation"]
env:
{{- if .Values.redis.enabled }}
- name: CVAT_REDIS_HOST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
args: ["-c", "supervisord/worker.export.conf"]
args: ["run", "worker.export"]
env:
{{- if .Values.redis.enabled }}
- name: CVAT_REDIS_HOST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
args: ["-c", "supervisord/worker.import.conf"]
args: ["run", "worker.import"]
env:
{{- if .Values.redis.enabled }}
- name: CVAT_REDIS_HOST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
args: ["-c", "supervisord/worker.quality_reports.conf"]
args: ["run", "worker.quality_reports"]
env:
{{- if .Values.redis.enabled }}
- name: CVAT_REDIS_HOST
Expand Down
Empty file modified manage.py
100644 → 100755
Empty file.
3 changes: 1 addition & 2 deletions supervisord/server.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ process_name=%(program_name)s-%(process_num)s

[fcgi-program:uvicorn]
socket=unix:///tmp/uvicorn.sock
command=%(ENV_HOME)s/wait-for-it.sh %(ENV_CVAT_POSTGRES_HOST)s:5432 -t 0 -- python3 -m uvicorn
--fd 0 --forwarded-allow-ips='*' cvat.asgi:application
command=python3 -m uvicorn --fd 0 --forwarded-allow-ips='*' cvat.asgi:application
autorestart=true
environment=SSH_AUTH_SOCK="/tmp/ssh-agent.sock",CVAT_EVENTS_LOCAL_DB_FILENAME="events_%(process_num)03d.db"
numprocs=%(ENV_NUMPROCS)s
Expand Down
6 changes: 6 additions & 0 deletions tests/allow_webhooks_receiver.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# We want to exclude webhooks_receiver from SSRF protection,
# so that the server can access it.
# --allow-address doesn't allow hostnames, so we have to resolve
# the IP address ourselves.
webhooks_ip_addr="$(getent hosts webhooks | head -1 | awk '{ print $1 }')"
export SMOKESCREEN_OPTS="$SMOKESCREEN_OPTS --allow-address=\"$webhooks_ip_addr\""
33 changes: 8 additions & 25 deletions tests/docker-compose.test_servers.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
services:
cvat_worker_webhooks:
depends_on:
- webhook_receiver
entrypoint:
- /bin/bash
- -euc
# We want to exclude webhooks_receiver from SSRF protection,
# so that the server can access it.
# --allow-address doesn't allow hostnames, so we have to resolve
# the IP address ourselves.
- |
webhooks_ip_addr="$$(getent hosts webhooks | head -1 | awk '{ print $$1 }')"
export SMOKESCREEN_OPTS=--allow-address="$$webhooks_ip_addr"
exec /usr/bin/supervisord -c supervisord/worker.webhooks.conf
x-allow-webhook-receiver: &allow-webhook-receiver
depends_on:
- webhook_receiver
volumes:
- ./tests/allow_webhooks_receiver.sh:/etc/cvat/init.d/allow_webhooks_receiver.sh:ro

cvat_server:
depends_on:
- webhook_receiver
entrypoint:
- /bin/bash
- -euc
- |
webhooks_ip_addr="$$(getent hosts webhooks | head -1 | awk '{ print $$1 }')"
export SMOKESCREEN_OPTS=--allow-address="$$webhooks_ip_addr"
exec /home/django/backend_entrypoint.sh
services:
cvat_worker_webhooks: *allow-webhook-receiver

cvat_server: *allow-webhook-receiver

webhook_receiver:
image: python:3.9-slim
Expand Down

0 comments on commit 994f84c

Please sign in to comment.