From 5e2eda76014c325c69dc297749d1d123ed315626 Mon Sep 17 00:00:00 2001 From: Andrey Zhavoronkov Date: Thu, 18 Aug 2022 19:33:05 +0300 Subject: [PATCH] Extend helm to support Serverless functions and Analytics (#110) --- .github/workflows/full.yml | 2 +- .github/workflows/main.yml | 4 +- CHANGELOG.md | 1 + Dockerfile | 7 +- .../analytics/docker-compose.analytics.yml | 6 +- components/analytics/kibana/kibana.yml | 1 - components/analytics/kibana_conf.yml | 2 +- components/analytics/logstash/logstash.yml | 1 + .../serverless/docker-compose.serverless.yml | 2 +- cvat/apps/engine/backup.py | 5 +- cvat/apps/engine/views.py | 8 +- cvat/apps/lambda_manager/views.py | 13 +- cvat/settings/base.py | 3 +- docker-compose.ci.yml | 2 +- docker-compose.dev.yml | 2 +- docker-compose.yml | 70 ++++- helm-chart/Chart.yaml | 30 ++- helm-chart/README.md | 199 ++++++++++---- helm-chart/nuclio_func_common_files | 1 + helm-chart/templates/analytics/ingress.yaml | 56 ++++ .../analytics/middlewares/forwardauth.yaml | 18 ++ .../analytics/middlewares/stripprefix.yaml | 15 ++ .../cvat_backend/server/deployment.yml | 192 ++++++++++++++ helm-chart/templates/cvat_backend/service.yml | 7 +- .../cvat_backend/{ => utils}/deployment.yml | 56 ++-- .../worker_default/deployment.yml | 173 ++++++++++++ .../cvat_backend/worker_low/deployment.yml | 173 ++++++++++++ helm-chart/templates/cvat_nuclio/config.yml | 19 ++ helm-chart/templates/cvat_opa/config.yml | 2 +- helm-chart/templates/ingress.yaml | 4 +- helm-chart/values.yaml | 249 ++++++++++++------ .../openvino/dextr/nuclio/function.yaml | 10 + .../face-detection-0205/nuclio/function.yaml | 12 +- .../nuclio/function.yaml | 12 +- .../nuclio/function.yaml | 12 +- .../text-detection-0004/nuclio/function.yaml | 12 +- .../nuclio/function.yaml | 14 +- .../nuclio/function.yaml | 12 +- .../public/yolo-v3-tf/nuclio/function.yaml | 10 + .../retinanet/nuclio/function-gpu.yaml | 4 +- .../detectron2/retinanet/nuclio/function.yaml | 4 +- .../siammask/nuclio/function-gpu.yaml | 2 +- .../foolwood/siammask/nuclio/function.yaml | 2 +- .../saic-vul/fbrs/nuclio/function.yaml | 2 +- .../saic-vul/hrnet/nuclio/function-gpu.yaml | 2 +- .../shiyinzhang/iog/nuclio/function.yaml | 2 +- .../ultralytics/yolov5/nuclio/function.yaml | 2 +- .../nuclio/function-gpu.yaml | 2 +- .../nuclio/function.yaml | 2 +- .../mask_rcnn/nuclio/function-gpu.yaml | 2 +- .../matterport/mask_rcnn/nuclio/function.yaml | 4 +- .../administration/advanced/backup_guide.md | 4 +- .../administration/basics/installation.md | 19 +- .../en/docs/manual/basics/authorization.md | 2 +- ssh/README.md | 4 +- supervisord.conf => supervisord/all.conf | 0 supervisord/server.conf | 37 +++ supervisord/utils.conf | 37 +++ supervisord/worker.default.conf | 37 +++ supervisord/worker.low.conf | 36 +++ .../case_107_connected_file_share.js | 4 +- tests/docker-compose.email.yml | 2 +- tests/docker-compose.file_share.yml | 4 +- tests/python/README.md | 14 +- tests/python/shared/fixtures/init.py | 12 +- 65 files changed, 1414 insertions(+), 245 deletions(-) create mode 120000 helm-chart/nuclio_func_common_files create mode 100644 helm-chart/templates/analytics/ingress.yaml create mode 100644 helm-chart/templates/analytics/middlewares/forwardauth.yaml create mode 100644 helm-chart/templates/analytics/middlewares/stripprefix.yaml create mode 100644 helm-chart/templates/cvat_backend/server/deployment.yml rename helm-chart/templates/cvat_backend/{ => utils}/deployment.yml (77%) create mode 100644 helm-chart/templates/cvat_backend/worker_default/deployment.yml create mode 100644 helm-chart/templates/cvat_backend/worker_low/deployment.yml create mode 100644 helm-chart/templates/cvat_nuclio/config.yml rename supervisord.conf => supervisord/all.conf (100%) create mode 100644 supervisord/server.conf create mode 100644 supervisord/utils.conf create mode 100644 supervisord/worker.default.conf create mode 100644 supervisord/worker.low.conf diff --git a/.github/workflows/full.yml b/.github/workflows/full.yml index 1ba61db9..c4748f30 100644 --- a/.github/workflows/full.yml +++ b/.github/workflows/full.yml @@ -185,7 +185,7 @@ jobs: LOGS_DIR: "${{ github.workspace }}/rest_api" run: | mkdir $LOGS_DIR - docker logs test_cvat_1 > $LOGS_DIR/cvat.log + docker logs test_cvat_server_1 > $LOGS_DIR/cvat.log docker logs test_cvat_opa_1 2> $LOGS_DIR/cvat_opa.log - name: Uploading "cvat" container logs as an artifact diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1e2fa7fd..713e1bc3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -151,7 +151,7 @@ jobs: LOGS_DIR: "${{ github.workspace }}/rest_api" run: | mkdir $LOGS_DIR - docker logs test_cvat_1 > $LOGS_DIR/cvat.log + docker logs test_cvat_server_1 > $LOGS_DIR/cvat.log docker logs test_cvat_opa_1 2> $LOGS_DIR/cvat_opa.log - name: Uploading "cvat" container logs as an artifact @@ -288,7 +288,7 @@ jobs: DJANGO_SU_EMAIL: 'admin@localhost.company' DJANGO_SU_PASSWORD: '12qwaszx' run: | - docker exec -i cvat /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" + docker exec -i cvat_server /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" cd ./tests yarn --frozen-lockfile diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e26f428..0f772bb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - OpenCV.js caching and autoload () - Publishing dev version of CVAT docker images () - Support of Human Pose Estimation, Facial Landmarks (and similar) use-cases, new shape type: Skeleton () +- Added helm chart support for serverless functions and analytics () ### Changed - Bumped nuclio version to 1.8.14 diff --git a/Dockerfile b/Dockerfile index ba312c2b..79fd92ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -139,14 +139,16 @@ COPY --from=build-image /tmp/openh264/openh264*.tar.gz /tmp/ffmpeg/ffmpeg*.tar.g # Copy python virtual environment and FFmpeg binaries from build-image COPY --from=build-image /opt/venv /opt/venv ENV PATH="/opt/venv/bin:${PATH}" +ENV NUMPROCS=1 COPY --from=build-image /opt/ffmpeg /usr # Install and initialize CVAT, copy all necessary files COPY --chown=${USER} components /tmp/components +COPY --chown=${USER} supervisord/ ${HOME}/supervisord COPY --chown=${USER} ssh ${HOME}/.ssh -COPY --chown=${USER} supervisord.conf mod_wsgi.conf wait-for-it.sh manage.py ${HOME}/ -COPY --chown=${USER} cvat/ ${HOME}/cvat +COPY --chown=${USER} mod_wsgi.conf wait-for-it.sh manage.py ${HOME}/ COPY --chown=${USER} utils/ ${HOME}/utils +COPY --chown=${USER} cvat/ ${HOME}/cvat # RUN all commands below as 'django' user USER ${USER} @@ -156,3 +158,4 @@ RUN mkdir data share media keys logs /tmp/supervisord EXPOSE 8080 ENTRYPOINT ["/usr/bin/supervisord"] +CMD ["-c", "supervisord/all.conf"] diff --git a/components/analytics/docker-compose.analytics.yml b/components/analytics/docker-compose.analytics.yml index 3dbc8938..5a459e78 100644 --- a/components/analytics/docker-compose.analytics.yml +++ b/components/analytics/docker-compose.analytics.yml @@ -23,13 +23,15 @@ services: args: ELK_VERSION: 6.8.23 depends_on: ['elasticsearch'] + environment: + - ELASTICSEARCH_HOSTS=http://elasticsearch:9200 restart: always cvat_kibana_setup: container_name: cvat_kibana_setup image: cvat/server:${CVAT_VERSION:-latest} volumes: ['./components/analytics/kibana:/home/django/kibana:ro'] - depends_on: ['cvat'] + depends_on: ['cvat_server'] working_dir: '/home/django' networks: - cvat @@ -72,7 +74,7 @@ services: depends_on: ['elasticsearch'] restart: always - cvat: + cvat_server: environment: DJANGO_LOG_SERVER_HOST: logstash DJANGO_LOG_SERVER_PORT: 8080 diff --git a/components/analytics/kibana/kibana.yml b/components/analytics/kibana/kibana.yml index 4fba9171..0459f344 100644 --- a/components/analytics/kibana/kibana.yml +++ b/components/analytics/kibana/kibana.yml @@ -1,5 +1,4 @@ server.host: 0.0.0.0 -elasticsearch.url: http://elasticsearch:9200 elasticsearch.requestHeadersWhitelist: ['cookie', 'authorization', 'x-forwarded-user'] kibana.defaultAppId: 'discover' server.basePath: /analytics diff --git a/components/analytics/kibana_conf.yml b/components/analytics/kibana_conf.yml index 1c53b6a8..e5ccc75b 100644 --- a/components/analytics/kibana_conf.yml +++ b/components/analytics/kibana_conf.yml @@ -21,7 +21,7 @@ http: middlewares: analytics-auth: forwardauth: - address: http://cvat:8080/analytics + address: http://cvat_server:8080/analytics authRequestHeaders: - "Cookie" - "Authorization" diff --git a/components/analytics/logstash/logstash.yml b/components/analytics/logstash/logstash.yml index 73f412c1..01d28730 100644 --- a/components/analytics/logstash/logstash.yml +++ b/components/analytics/logstash/logstash.yml @@ -1,3 +1,4 @@ queue.type: persisted queue.max_bytes: 1gb queue.checkpoint.writes: 20 +http.host: 0.0.0.0 diff --git a/components/serverless/docker-compose.serverless.yml b/components/serverless/docker-compose.serverless.yml index a46e87ff..8991ffa9 100644 --- a/components/serverless/docker-compose.serverless.yml +++ b/components/serverless/docker-compose.serverless.yml @@ -18,7 +18,7 @@ services: ports: - '8070:8070' - cvat: + cvat_server: environment: CVAT_SERVERLESS: 1 diff --git a/cvat/apps/engine/backup.py b/cvat/apps/engine/backup.py index a24f3d18..9441ad62 100644 --- a/cvat/apps/engine/backup.py +++ b/cvat/apps/engine/backup.py @@ -839,7 +839,7 @@ def _import(importer, request, rq_id, Serializer, file_field_name, location_conf serializer = Serializer(data=request.data) serializer.is_valid(raise_exception=True) payload_file = serializer.validated_data[file_field_name] - fd, filename = mkstemp(prefix='cvat_') + fd, filename = mkstemp(prefix='cvat_', dir=settings.TMP_FILES_ROOT) with open(filename, 'wb+') as f: for chunk in payload_file.chunks(): f.write(chunk) @@ -863,9 +863,10 @@ def _import(importer, request, rq_id, Serializer, file_field_name, location_conf data = _import_from_cloud_storage(storage, file_name) - fd, filename = mkstemp(prefix='cvat_') + fd, filename = mkstemp(prefix='cvat_', dir=settings.TMP_FILES_ROOT) with open(filename, 'wb+') as f: f.write(data.getbuffer()) + rq_job = queue.enqueue_call( func=importer, args=(filename, request.user.id, org_id), diff --git a/cvat/apps/engine/views.py b/cvat/apps/engine/views.py index 58d724a7..2fa21a34 100644 --- a/cvat/apps/engine/views.py +++ b/cvat/apps/engine/views.py @@ -2096,7 +2096,7 @@ def _import_annotations(request, rq_id, rq_func, pk, format_name, serializer = AnnotationFileSerializer(data=request.data) if serializer.is_valid(raise_exception=True): anno_file = serializer.validated_data['annotation_file'] - fd, filename = mkstemp(prefix='cvat_{}'.format(pk)) + fd, filename = mkstemp(prefix='cvat_{}'.format(pk), dir=settings.TMP_FILES_ROOT) with open(filename, 'wb+') as f: for chunk in anno_file.chunks(): f.write(chunk) @@ -2114,7 +2114,7 @@ def _import_annotations(request, rq_id, rq_func, pk, format_name, data = _import_from_cloud_storage(storage, filename) - fd, filename = mkstemp(prefix='cvat_') + fd, filename = mkstemp(prefix='cvat_{}'.format(pk), dir=settings.TMP_FILES_ROOT) with open(filename, 'wb+') as f: f.write(data.getbuffer()) @@ -2262,7 +2262,7 @@ def _import_project_dataset(request, rq_id, rq_func, pk, format_name, filename=N serializer = DatasetFileSerializer(data=request.data) if serializer.is_valid(raise_exception=True): dataset_file = serializer.validated_data['dataset_file'] - fd, filename = mkstemp(prefix='cvat_{}'.format(pk)) + fd, filename = mkstemp(prefix='cvat_{}'.format(pk), dir=settings.TMP_FILES_ROOT) with open(filename, 'wb+') as f: for chunk in dataset_file.chunks(): f.write(chunk) @@ -2281,7 +2281,7 @@ def _import_project_dataset(request, rq_id, rq_func, pk, format_name, filename=N data = _import_from_cloud_storage(storage, filename) - fd, filename = mkstemp(prefix='cvat_') + fd, filename = mkstemp(prefix='cvat_', dir=settings.TMP_FILES_ROOT) with open(filename, 'wb+') as f: f.write(data.getbuffer()) diff --git a/cvat/apps/lambda_manager/views.py b/cvat/apps/lambda_manager/views.py index 3c13125d..f9f21e60 100644 --- a/cvat/apps/lambda_manager/views.py +++ b/cvat/apps/lambda_manager/views.py @@ -41,14 +41,16 @@ class LambdaGateway: NUCLIO_ROOT_URL = '/api/functions' def _http(self, method="get", scheme=None, host=None, port=None, - url=None, headers=None, data=None): + function_namespace=None, url=None, headers=None, data=None): NUCLIO_GATEWAY = '{}://{}:{}'.format( scheme or settings.NUCLIO['SCHEME'], host or settings.NUCLIO['HOST'], port or settings.NUCLIO['PORT']) + NUCLIO_FUNCTION_NAMESPACE = function_namespace or settings.NUCLIO['FUNCTION_NAMESPACE'] extra_headers = { 'x-nuclio-project-name': 'cvat', - 'x-nuclio-function-namespace': 'nuclio', + 'x-nuclio-function-namespace': NUCLIO_FUNCTION_NAMESPACE, + 'x-nuclio-invoke-via': 'domain-name', } if headers: extra_headers.update(headers) @@ -77,6 +79,13 @@ class LambdaGateway: return response def invoke(self, func, payload): + if os.getenv('KUBERNETES_SERVICE_HOST'): + return self._http(method="post", url='/api/function_invocations', + data=payload, headers={ + 'x-nuclio-function-name': func.id, + 'x-nuclio-path': '/' + }) + # Note: call the function directly without the nuclio dashboard # host.docker.internal for Linux will work only with Docker 20.10+ NUCLIO_TIMEOUT = settings.NUCLIO['DEFAULT_TIMEOUT'] diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 668346b5..5103d843 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -284,7 +284,8 @@ NUCLIO = { 'SCHEME': os.getenv('CVAT_NUCLIO_SCHEME', 'http'), 'HOST': os.getenv('CVAT_NUCLIO_HOST', 'localhost'), 'PORT': os.getenv('CVAT_NUCLIO_PORT', 8070), - 'DEFAULT_TIMEOUT': os.getenv('CVAT_NUCLIO_DEFAULT_TIMEOUT', 120) + 'DEFAULT_TIMEOUT': os.getenv('CVAT_NUCLIO_DEFAULT_TIMEOUT', 120), + 'FUNCTION_NAMESPACE': os.getenv('CVAT_NUCLIO_FUNCTION_NAMESPACE', 'nuclio'), } RQ_SHOW_ADMIN_LINK = True diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index dcc8e27c..551afbbd 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -13,7 +13,7 @@ services: context: . dockerfile: Dockerfile.ci depends_on: - - cvat + - cvat_server environment: COVERALLS_SERVICE_NAME: CONTAINER_COVERAGE_DATA_DIR: diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index a3faf40d..b9745728 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -6,7 +6,7 @@ version: '3.3' services: - cvat: + cvat_server: build: context: . args: diff --git a/docker-compose.yml b/docker-compose.yml index 1761221e..6fb2916c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,8 +25,8 @@ services: networks: - cvat - cvat: - container_name: cvat + cvat_server: + container_name: cvat_server image: cvat/server:${CVAT_VERSION:-latest} restart: always depends_on: @@ -40,6 +40,8 @@ services: CVAT_POSTGRES_HOST: 'cvat_db' ADAPTIVE_AUTO_ANNOTATION: 'false' no_proxy: elasticsearch,kibana,logstash,nuclio,opa,${no_proxy} + NUMPROCS: 1 + command: -c supervisord/server.conf labels: - traefik.enable=true - traefik.http.services.cvat.loadbalancer.server.port=8080 @@ -55,12 +57,74 @@ services: extra_hosts: - "host.docker.internal:host-gateway" + cvat_utils: + container_name: cvat_utils + image: cvat/server:${CVAT_VERSION:-latest} + restart: always + depends_on: + - cvat_redis + - cvat_db + - cvat_opa + environment: + CVAT_REDIS_HOST: 'cvat_redis' + CVAT_POSTGRES_HOST: 'cvat_db' + no_proxy: elasticsearch,kibana,logstash,nuclio,opa,${no_proxy} + command: -c supervisord/utils.conf + volumes: + - cvat_data:/home/django/data + - cvat_keys:/home/django/keys + - cvat_logs:/home/django/logs + networks: + - cvat + + cvat_worker_default: + container_name: cvat_worker_default + image: cvat/server:${CVAT_VERSION:-latest} + restart: always + depends_on: + - cvat_redis + - cvat_db + - cvat_opa + environment: + CVAT_REDIS_HOST: 'cvat_redis' + CVAT_POSTGRES_HOST: 'cvat_db' + no_proxy: elasticsearch,kibana,logstash,nuclio,opa,${no_proxy} + NUMPROCS: 2 + command: -c supervisord/worker.default.conf + volumes: + - cvat_data:/home/django/data + - cvat_keys:/home/django/keys + - cvat_logs:/home/django/logs + networks: + - cvat + + cvat_worker_low: + container_name: cvat_worker_low + image: cvat/server:${CVAT_VERSION:-latest} + restart: always + depends_on: + - cvat_redis + - cvat_db + - cvat_opa + environment: + CVAT_REDIS_HOST: 'cvat_redis' + CVAT_POSTGRES_HOST: 'cvat_db' + no_proxy: elasticsearch,kibana,logstash,nuclio,opa,${no_proxy} + NUMPROCS: 1 + command: -c supervisord/worker.low.conf + volumes: + - cvat_data:/home/django/data + - cvat_keys:/home/django/keys + - cvat_logs:/home/django/logs + networks: + - cvat + cvat_ui: container_name: cvat_ui image: cvat/ui:${CVAT_VERSION:-latest} restart: always depends_on: - - cvat + - cvat_server labels: - traefik.enable=true - traefik.http.services.cvat-ui.loadbalancer.server.port=80 diff --git a/helm-chart/Chart.yaml b/helm-chart/Chart.yaml index 381331e6..1e3f2e53 100644 --- a/helm-chart/Chart.yaml +++ b/helm-chart/Chart.yaml @@ -26,10 +26,36 @@ appVersion: latest dependencies: - name: redis - version: "12.9.*" + version: "16.13.*" repository: https://charts.bitnami.com/bitnami condition: redis.enabled + - name: postgresql - version: "10.3.*" + version: "10.16.*" repository: https://charts.bitnami.com/bitnami condition: postgresql.enabled + + - name: nuclio + version: 0.12.1 + repository: https://nuclio.github.io/nuclio/charts + condition: nuclio.enabled + + - name: logstash + version: "6.8.*" + repository: https://helm.elastic.co + condition: analytics.enabled + + - name: elasticsearch + version: "6.8.*" + repository: https://helm.elastic.co + condition: analytics.enabled + + - name: kibana + version: "6.8.*" + repository: https://helm.elastic.co + condition: analytics.enabled + + - name: traefik + version: 10.24.0 + repository: https://helm.traefik.io/traefik + condition: ingress.enabled diff --git a/helm-chart/README.md b/helm-chart/README.md index f4052e39..a0148314 100644 --- a/helm-chart/README.md +++ b/helm-chart/README.md @@ -6,7 +6,8 @@ - [Optional steps](#optional-steps) - [Configuration](#configuration) - [Postgresql password?](#postgresql-password) - - [Ingress parameters](#ingress-parameters) + - [(Optional) Enable Auto annotation feature](#optional-enable-auto-annotation-feature) + - [(Optional) Enable Analytics](#optional-enable-analytics) - [Deployment](#deployment) - [With overrides:](#with-overrides) - [Without overrides:](#without-overrides) @@ -15,39 +16,54 @@ - [FAQ](#faq) - [What is kubernetes and how it is working?](#what-is-kubernetes-and-how-it-is-working) - [What is helm and how it is working?](#what-is-helm-and-how-it-is-working) - - [How to enable ingress:](#how-to-enable-ingress) + - [How to setup Minikube?](#how-to-setup-minikube) - [How to understand what diff will be inflicted by 'helm upgrade'?](#how-to-understand-what-diff-will-be-inflicted-by-helm-upgrade) - [I want to use my own postgresql/redis with your chart.](#i-want-to-use-my-own-postgresqlredis-with-your-chart) - [I want to override some settings in values.yaml.](#i-want-to-override-some-settings-in-valuesyaml) - [Why you used external charts to provide redis and postgres?](#why-you-used-external-charts-to-provide-redis-and-postgres) ## Prerequisites -1. Installed and configured [kubernetes](https://kubernetes.io/) cluster. -2. Installed [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) -3. Installed [Helm](https://helm.sh/). -4. Installed [dependencies](#installing-dependencies) +1. Installed and configured [kubernetes](https://kubernetes.io/) cluster. If you do not already have a cluster, + you can create one by using [Minikube](https://github.com/kubernetes/minikube/). [How to setup Minikube](#how-to-setup-minikube). +1. Installed [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) +1. Installed [Helm](https://helm.sh/). +1. Installed [dependencies](#installing-dependencies) ### Installing dependencies To install and/or update run: -```sh -helm repo add bitnami https://charts.bitnami.com/bitnami -helm repo update +```shell helm dependency update ``` ### Optional steps -1. Install ingress of your choice (for example: ) -2. Create certificates for https (for example: ) +1. Ingress configuration for the Traefik ingress controller is enabled by default. + + Note for Minikube use: + - because the Traefik creates its main service with `Loadbalanser` type, + which involve the assignment of externalIP by Cloud, what never happens on Minikube, + you need to explicitly set the externalIP address for the traefic service. + Add the following to `values.override.yaml` file: + ```yaml + traefik: + service: + externalIPs: + - "your minikube IP (can be obtained with `minicube ip` command)" + ``` + - Also ensure that your CVAT ingress appears on your hosts file (/etc/hosts). + You can do this by running this command: + `cvat.local` is default domainname, you can override it via `values.override.yaml`. + ```shell + echo "$(minikube ip) cvat.local" | sudo tee -a /etc/hosts + ``` ## Configuration 1. Create `values.override.yaml` file inside `helm-chart` directory. -2. Fill `values.override.yaml` with new parameters for chart. -3. Override [postgresql password](#postgresql-password) -4. Create a rules.tar.gz archive containing all OPA rules inside this `helm-chart` directory. - ```sh - find ../cvat/apps/iam/rules -name "*.rego" -and ! -name '*test*' -exec basename {} \; | tar -czf rules.tar.gz -C ../cvat/apps/iam/rules/ -T - - ``` -5. (Optional) Add [ingress parameters](#ingress-parameters) +1. Fill `values.override.yaml` with new parameters for chart. +1. Override [postgresql password](#postgresql-password) +1. Create a rules.tar.gz archive containing all OPA rules inside this `helm-chart` directory. + ```shell + find ../cvat/apps/iam/rules -name "*.rego" -and ! -name '*test*' -exec basename {} \; | tar -czf rules.tar.gz -C ../cvat/apps/iam/rules/ -T - + ``` ### Postgresql password? Put below into your `values.override.yaml` @@ -66,48 +82,113 @@ postgresql: existingSecret: ``` -### Ingress parameters -Paste below parameters to `values.override.yaml` -```yaml -ingress: - enabled: true - annotations: - kubernetes.io/ingress.class: nginx - kubernetes.io/tls-acme: "true" - ingress.kubernetes.io/ssl-redirect: "true" - nginx.ingress.kubernetes.io/use-regex: "true" - nginx.ingress.kubernetes.io/secure-backends: "true" - nginx.ingress.kubernetes.io/proxy-body-size: "0" - nginx.ingress.kubernetes.io/proxy-send-timeout: "120" - nginx.ingress.kubernetes.io/proxy-read-timeout: "120" - cert-manager.io/cluster-issuer: - hosts: - - host: - paths: - - path: "/api/.*|git/.*|tensorflow/.*|auto_annotation/.*|analytics/.*|static/.*|admin|admin/.*|documentation/.*|dextr/.*|reid/.*" - service: - name: -backend-service - port: 8080 - - path: "/" - pathType: "Prefix" - service: - name: -frontend-service - port: 80 - - tls: - - hosts: - - - secretName: ingress-tls-cvat -``` +### (Optional) Enable Auto annotation feature + +Before starting, ensure that the following prerequisites are met: +- The Nuclio [CLI (nuctl)](https://nuclio.io/docs/latest/reference/nuctl/nuctl/) is installed. + To install the CLI, simply [download](https://github.com/nuclio/nuclio/releases) + the appropriate CLI version to your installation machine. + +1. Set `nuclio.enabled: true` in your `values.override.yaml` +1. Run `helm dependency update` in `helm-chart` directory +1. Because Nuclio functions are images that need to be pushed and pulled to/from the registry, + you need to configure credentials to pull from your preferable registry with the following settings: + Options: + - `values.override.yaml` file: + ```yaml + registry: + loginUrl: someurl + credentials: + username: someuser + password: somepass + ``` + - Or you can create a secret with credentials as described in the [guide](https://nuclio.io/docs/latest/setup/k8s/running-in-production-k8s/#the-preferred-deployment-method) + and set `registry.secretName=your-registry-credentials-secret-name` in the `values.override.yaml` file. + + - In the case of using Minikube, you can run a local unsecured registry with minikube add-ons: + ```shell + minikube addons enable registry + minikube addons enable registry-aliases + ``` + Before Docker container images can be pushed to your newly created unsecure registry, + you need to add its address (`$(minikube ip):5000`) to the list of unsecure registries to + instruct Docker to accept working against it: + follow the instructions in the [Docker documentation](https://docs.docker.com/registry/insecure/#deploy-a-plain-http-registry) + + You might also need to log into your registry account (docker login) + on the installation machine before running the deployment command. + +1. Create cvat project: + ```shell + nuctl --namespace create project cvat + ``` +1. Finaly deploy the fuction, i.e.: + - using minikube registry: + ```shell + nuctl deploy --project-name cvat --path serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio --registry $(minikube ip):5000 --run-registry registry.minikube + ``` + - using Docker hub: + ```shell + nuctl deploy --project-name cvat --path serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio --registry docker.io/your_username + ``` + +### (Optional) Enable Analytics + +1. Set `analytics.enabled: true` in your `values.override.yaml` +1. Run `helm dependency update` in `helm-chart` directory +1. Since custom images are required here, you will need to create them yourself + and push them to your preferred docker registry. + You might also need to log into your registry account (docker login) + on the installation machine before running the push command. + How to set up local registry when using Minikube see [previous section](#how_to_enable_auto_annotation_feature) + + - Let's build custom elasticsearch, logstash and kibana images with the following command + ```shell + docker-compose -f docker-compose.yml -f components/analytics/docker-compose.analytics.yml build + ``` + + - Tag images: + ```shell + docker tag cvat_kibana:latest /cvat_kibana:latest + docker tag cvat_elasticsearch:latest /cvat_elasticsearch:latest + docker tag cvat_logstash:latest /cvat_logstash:latest + ``` + + - Push to registry + ```shell + docker push /cvat_kibana:latest + docker push /cvat_elasticsearch:latest + docker push /cvat_logstash:latest + ``` + + - Add corresponding settings into `values.override.yaml`, i.e. for minikube registry: + ```yaml + logstash: + image: "registry.minikube/cvat_logstash" + imageTag: "latest" + + elasticsearch: + image: "registry.minikube/cvat_elasticsearch" + imageTag: "latest" + + kibana: + image: "registry.minikube/cvat_kibana" + imageTag: "latest" + ``` + + - Deploy + ```shell + helm upgrade --namespace --install ./helm-chart -f ./helm-chart/values.yaml -f values.override.yaml + ``` ## Deployment Make sure you are using correct kubernetes context. You can check it with `kubectl config current-context`. > **Warning:** The k8s service name of Open Policy Agent is fixed to opa by default. -This is done to be compatible with CVAT 2.0 but limits this helm chart to a single release per namespace. -The OPA url currently can´t be set as an environment variable. -As soon as this is possible you can set cvat.opa.composeCompatibleServiceName -to false in your value.override.yaml and configure the opa url as additional env. +> This is done to be compatible with CVAT 2.0 but limits this helm chart to a single release per namespace. +> The OPA url currently can´t be set as an environment variable. +> As soon as this is possible you can set cvat.opa.composeCompatibleServiceName +> to false in your value.override.yaml and configure the opa url as additional env. Execute following command from repo root directory ### With overrides: @@ -127,15 +208,17 @@ HELM_RELEASE_NAME="" &&\ BACKEND_POD_NAME=$(kubectl get pod --namespace $HELM_RELEASE_NAMESPACE -l tier=backend,app.kubernetes.io/instance=$HELM_RELEASE_NAME -o jsonpath='{.items[0].metadata.name}') &&\ kubectl exec -it --namespace $HELM_RELEASE_NAMESPACE $BACKEND_POD_NAME -c cvat-backend-app-container -- python manage.py createsuperuser ``` - ## FAQ ### What is kubernetes and how it is working? See ### What is helm and how it is working? See -### How to enable ingress: - Just set `ingress.enabled:` to `true`, then copy example, uncomment it and change values there +### How to setup Minikube +1. Please follow the official Minikube installation [guide](https://minikube.sigs.k8s.io/docs/start/) +1. ```shell + minikube start --addons registry,registry-aliases + ``` ### How to understand what diff will be inflicted by 'helm upgrade'? You can use for that ### I want to use my own postgresql/redis with your chart. diff --git a/helm-chart/nuclio_func_common_files b/helm-chart/nuclio_func_common_files new file mode 120000 index 00000000..8e401ec1 --- /dev/null +++ b/helm-chart/nuclio_func_common_files @@ -0,0 +1 @@ +../serverless/common/openvino \ No newline at end of file diff --git a/helm-chart/templates/analytics/ingress.yaml b/helm-chart/templates/analytics/ingress.yaml new file mode 100644 index 00000000..e2d145b0 --- /dev/null +++ b/helm-chart/templates/analytics/ingress.yaml @@ -0,0 +1,56 @@ +{{- $version := .Capabilities.KubeVersion.GitVersion -}} +{{- if and .Values.ingress.enabled .Values.analytics.enabled -}} +{{- $fullName := include "cvat.fullname" . -}} +{{- if semverCompare ">=1.19-0" $version -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" $version -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }}-analytics + namespace: {{ .Release.Namespace }} + labels: + {{- include "cvat.labels" . | nindent 4 }} + annotations: + traefik.ingress.kubernetes.io/router.middlewares: {{ $.Release.Namespace }}-stripprefix@kubernetescrd, + {{ $.Release.Namespace }}-forwardauth@kubernetescrd + {{- with .Values.analytics.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if semverCompare ">=1.19-0" $version }} + ingressClassName: {{ .Values.ingress.className }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + - path: {{ $.Values.analytics.ingress.path }} + {{- if $.Values.analytics.ingress.pathType }} + pathType: {{ $.Values.analytics.ingress.pathType }} + {{- end }} + {{- if semverCompare ">=1.19-0" $version }} + backend: + service: + {{- if $.Values.analytics.external.useExternal }} + name: {{ $.Values.analytics.ingress.service.name }} + {{- else }} + name: {{ $.Release.Name }}-{{ $.Values.analytics.ingress.service.name }} + {{- end }} + port: + number: {{ $.Values.analytics.ingress.service.port }} + {{- else }} + backend: + {{- if $.Values.analytics.external.useExternal }} + serviceName: {{ $.Values.analytics.ingress.service.name }} + {{- else }} + serviceName: {{ $.Release.Name }}-{{ $.Values.analytics.ingress.service.name }} + {{- end }} + servicePort: {{ $.Values.analytics.ingress.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm-chart/templates/analytics/middlewares/forwardauth.yaml b/helm-chart/templates/analytics/middlewares/forwardauth.yaml new file mode 100644 index 00000000..3857c3ea --- /dev/null +++ b/helm-chart/templates/analytics/middlewares/forwardauth.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ingress.enabled .Values.analytics.enabled }} + +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: forwardauth + namespace: {{ .Release.Namespace }} + annotations: + labels: + {{- include "cvat.labels" . | nindent 4 }} +spec: + forwardAuth: + address: http://{{ .Release.Name }}-backend-service:8080/analytics + authRequestHeaders: + - "Cookie" + - "Authorization" + +{{- end }} diff --git a/helm-chart/templates/analytics/middlewares/stripprefix.yaml b/helm-chart/templates/analytics/middlewares/stripprefix.yaml new file mode 100644 index 00000000..642a32e8 --- /dev/null +++ b/helm-chart/templates/analytics/middlewares/stripprefix.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.ingress.enabled .Values.analytics.enabled }} + +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: stripprefix + namespace: {{ .Release.Namespace }} + annotations: + labels: + {{- include "cvat.labels" . | nindent 4 }} +spec: + stripPrefix: + prefixes: + - /analytics +{{- end }} diff --git a/helm-chart/templates/cvat_backend/server/deployment.yml b/helm-chart/templates/cvat_backend/server/deployment.yml new file mode 100644 index 00000000..ef5ca23b --- /dev/null +++ b/helm-chart/templates/cvat_backend/server/deployment.yml @@ -0,0 +1,192 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-backend-server + namespace: {{ .Release.Namespace }} + labels: + app: cvat-app + tier: backend + component: server + {{- include "cvat.labels" . | nindent 4 }} + {{- with .Values.cvat.backend.server.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.cvat.backend.server.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.cvat.backend.server.replicas }} + strategy: + type: Recreate + selector: + matchLabels: + {{- include "cvat.labels" . | nindent 6 }} + {{- with .Values.cvat.backend.server.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + app: cvat-app + tier: backend + component: server + template: + metadata: + labels: + app: cvat-app + tier: backend + component: server + {{- include "cvat.labels" . | nindent 8 }} + {{- with .Values.cvat.backend.server.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cvat.backend.server.annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + containers: + - name: cvat-app-backend-server-container + image: {{ .Values.cvat.backend.image }}:{{ .Values.cvat.backend.tag }} + {{- with .Values.cvat.backend.server.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + args: ["-c", "supervisord/server.conf"] + env: + - name: ALLOWED_HOSTS + value: {{ .Values.cvat.backend.server.envs.ALLOWED_HOSTS | squote}} + - name: DJANGO_MODWSGI_EXTRA_ARGS + value: {{ .Values.cvat.backend.server.envs.DJANGO_MODWSGI_EXTRA_ARGS}} + {{- if .Values.redis.enabled }} + - name: CVAT_REDIS_HOST + value: "{{ .Release.Name }}-redis-master" + {{- else }} + - name: CVAT_REDIS_HOST + value: "{{ .Values.redis.external.host }}" + {{- end }} + {{- if .Values.postgresql.enabled }} + - name: CVAT_POSTGRES_HOST + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-hostname + - name: CVAT_POSTGRES_USER + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-username + - name: CVAT_POSTGRES_DBNAME + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-database + - name: CVAT_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-password + {{- else }} + - name: CVAT_POSTGRES_HOST + value: "{{ .Values.postgresql.external.host }}" + - name: CVAT_POSTGRES_USER + value: "{{ .Values.postgresql.external.user }}" + - name: CVAT_POSTGRES_DBNAME + value: "{{ .Values.postgresql.external.dbname }}" + - name: CVAT_POSTGRES_PASSWORD + value: "{{ .Values.postgresql.external.password }}" + - name: CVAT_POSTGRES_PORT + value: "{{ .Values.postgresql.external.port }}" + {{- end }} + {{- if .Values.nuclio.enabled }} + - name: CVAT_SERVERLESS + value: "1" + - name: CVAT_NUCLIO_HOST + value: "{{ .Release.Name }}-nuclio-dashboard" + - name: CVAT_NUCLIO_FUNCTION_NAMESPACE + value: "{{ .Release.Namespace }}" + {{- end }} + {{- if .Values.analytics.enabled}} + - name: CVAT_ANALYTICS + value: "1" + - name: DJANGO_LOG_SERVER_HOST + {{- if .Values.analytics.external.useExternal }} + value: "{{ .Values.analytics.logServerHost }}" + {{- else}} + value: "{{ .Release.Name }}-logstash" + {{- end}} + - name: DJANGO_LOG_SERVER_PORT + {{- if .Values.analytics.external.useExternal }} + value: "{{ .Values.analytics.logServerPort }}" + {{- else}} + value: "8080" + {{- end}} + {{- end}} + {{- with .Values.cvat.backend.server.additionalEnv }} + {{- toYaml . | nindent 10 }} + {{- end }} + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /home/django/data + name: cvat-backend-data + subPath: data + - mountPath: /home/django/keys + name: cvat-backend-data + subPath: keys + - mountPath: /home/django/logs + name: cvat-backend-data + subPath: logs + - mountPath: /home/django/models + name: cvat-backend-data + subPath: models + {{- with .Values.cvat.backend.server.additionalVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + initContainers: + {{- if .Values.cvat.backend.permissionFix.enabled }} + - name: user-data-permission-fix + image: busybox + command: ["/bin/chmod", "-R", "777", "/home/django"] + {{- with .Values.cvat.backend.server.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.cvat.backend.defaultStorage.enabled }} + - mountPath: /home/django/data + name: cvat-backend-data + subPath: data + - mountPath: /home/django/keys + name: cvat-backend-data + subPath: keys + - mountPath: /home/django/logs + name: cvat-backend-data + subPath: logs + - mountPath: /home/django/models + name: cvat-backend-data + subPath: models + {{- end }} + {{- with .Values.cvat.backend.server.additionalVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + {{- with .Values.cvat.backend.server.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cvat.backend.server.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.cvat.backend.defaultStorage.enabled }} + - name: cvat-backend-data + persistentVolumeClaim: + claimName: "{{ .Release.Name }}-backend-data" + {{- end }} + {{- with .Values.cvat.backend.server.additionalVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm-chart/templates/cvat_backend/service.yml b/helm-chart/templates/cvat_backend/service.yml index 88e1dfee..8d6dae34 100644 --- a/helm-chart/templates/cvat_backend/service.yml +++ b/helm-chart/templates/cvat_backend/service.yml @@ -7,11 +7,16 @@ metadata: {{- include "cvat.labels" . | nindent 4 }} app: cvat-app tier: backend + annotations: + {{- with .Values.cvat.backend.service.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: selector: app: cvat-app tier: backend + component: server {{- include "cvat.labels" . | nindent 4 }} - {{- with .Values.cvat.backend.service }} + {{- with .Values.cvat.backend.service.spec }} {{- toYaml . | nindent 2 }} {{- end }} diff --git a/helm-chart/templates/cvat_backend/deployment.yml b/helm-chart/templates/cvat_backend/utils/deployment.yml similarity index 77% rename from helm-chart/templates/cvat_backend/deployment.yml rename to helm-chart/templates/cvat_backend/utils/deployment.yml index 63970493..7aa4f5e6 100644 --- a/helm-chart/templates/cvat_backend/deployment.yml +++ b/helm-chart/templates/cvat_backend/utils/deployment.yml @@ -1,61 +1,57 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ .Release.Name }}-backend + name: {{ .Release.Name }}-backend-utils namespace: {{ .Release.Namespace }} labels: app: cvat-app tier: backend + component: utils {{- include "cvat.labels" . | nindent 4 }} - {{- with .Values.cvat.backend.labels }} + {{- with .Values.cvat.backend.utils.labels }} {{- toYaml . | nindent 4 }} {{- end }} - {{- with .Values.cvat.backend.annotations }} + {{- with .Values.cvat.backend.utils.annotations }} annotations: {{- toYaml . | nindent 4 }} {{- end }} spec: - replicas: {{ .Values.cvat.backend.replicas }} + replicas: {{ .Values.cvat.backend.utils.replicas }} strategy: type: Recreate selector: matchLabels: {{- include "cvat.labels" . | nindent 6 }} - {{- with .Values.cvat.backend.labels }} + {{- with .Values.cvat.backend.utils.labels }} {{- toYaml . | nindent 6 }} {{- end }} - app: cvat-app + app: cvat-app-utils tier: backend + component: utils template: metadata: labels: - app: cvat-app + app: cvat-app-utils tier: backend + component: utils {{- include "cvat.labels" . | nindent 8 }} - {{- with .Values.cvat.backend.labels }} + {{- with .Values.cvat.backend.utils.labels }} {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.cvat.backend.annotations }} + {{- with .Values.cvat.backend.utils.annotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} spec: containers: - - name: cvat-backend-app-container + - name: cvat-app-backend-utils-container image: {{ .Values.cvat.backend.image }}:{{ .Values.cvat.backend.tag }} - {{- with .Values.cvat.backend.resources }} + {{- with .Values.cvat.backend.utils.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} + args: ["-c", "supervisord/utils.conf"] env: - - name: DJANGO_MODWSGI_EXTRA_ARGS - value: {{ .Values.cvat.backend.envs.DJANGO_MODWSGI_EXTRA_ARGS}} - - name: ALLOWED_HOSTS - value: {{ .Values.cvat.backend.envs.ALLOWED_HOSTS | squote}} - - name: UI_HOST - value: "{{ .Release.Name }}-frontend-service" - - name: UI_PORT - value: "{{ .Values.cvat.frontend.service.ports }}" {{- if .Values.redis.enabled }} - name: CVAT_REDIS_HOST value: "{{ .Release.Name }}-redis-master" @@ -94,9 +90,15 @@ spec: - name: CVAT_POSTGRES_PASSWORD value: "{{ .Values.postgresql.external.password }}" - name: CVAT_POSTGRES_PORT - value: "{{ .Values.postgresql.external.port }}" + value: "{{ .Values.postgresql.external.port }}" {{- end }} - {{- with .Values.cvat.backend.additionalEnv }} + {{- if .Values.nuclio }} + - name: CVAT_SERVERLESS + value: "1" + - name: CVAT_NUCLIO_HOST + value: "{{ .Release.Name }}-nuclio-dashboard" + {{- end }} + {{- with .Values.cvat.backend.utils.additionalEnv }} {{- toYaml . | nindent 10 }} {{- end }} ports: @@ -114,7 +116,7 @@ spec: - mountPath: /home/django/models name: cvat-backend-data subPath: models - {{- with .Values.cvat.backend.additionalVolumeMounts }} + {{- with .Values.cvat.backend.utils.additionalVolumeMounts }} {{- toYaml . | nindent 10 }} {{- end }} initContainers: @@ -122,7 +124,7 @@ spec: - name: user-data-permission-fix image: busybox command: ["/bin/chmod", "-R", "777", "/home/django"] - {{- with .Values.cvat.backend.resources }} + {{- with .Values.cvat.backend.utils.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} @@ -141,15 +143,15 @@ spec: name: cvat-backend-data subPath: models {{- end }} - {{- with .Values.cvat.backend.additionalVolumeMounts }} + {{- with .Values.cvat.backend.utils.additionalVolumeMounts }} {{- toYaml . | nindent 10 }} {{- end }} {{- end }} - {{- with .Values.cvat.backend.affinity }} + {{- with .Values.cvat.backend.utils.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.cvat.backend.tolerations }} + {{- with .Values.cvat.backend.utils.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} @@ -159,7 +161,7 @@ spec: persistentVolumeClaim: claimName: "{{ .Release.Name }}-backend-data" {{- end }} - {{- with .Values.cvat.backend.additionalVolumes }} + {{- with .Values.cvat.backend.utils.additionalVolumes }} {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.imagePullSecrets }} diff --git a/helm-chart/templates/cvat_backend/worker_default/deployment.yml b/helm-chart/templates/cvat_backend/worker_default/deployment.yml new file mode 100644 index 00000000..01d3dbd1 --- /dev/null +++ b/helm-chart/templates/cvat_backend/worker_default/deployment.yml @@ -0,0 +1,173 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-backend-worker-default + namespace: {{ .Release.Namespace }} + labels: + app: cvat-app + tier: backend + component: worker-default + {{- include "cvat.labels" . | nindent 4 }} + {{- with .Values.cvat.backend.worker.default.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.cvat.backend.worker.default.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.cvat.backend.worker.default.replicas }} + strategy: + type: Recreate + selector: + matchLabels: + {{- include "cvat.labels" . | nindent 6 }} + {{- with .Values.cvat.backend.worker.default.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + app: cvat-app-worker-default + tier: backend + component: worker-default + template: + metadata: + labels: + app: cvat-app-worker-default + tier: backend + component: worker-default + {{- include "cvat.labels" . | nindent 8 }} + {{- with .Values.cvat.backend.worker.default.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cvat.backend.worker.default.annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + containers: + - name: cvat-app-backend-worker-default-container + image: {{ .Values.cvat.backend.image }}:{{ .Values.cvat.backend.tag }} + {{- with .Values.cvat.backend.worker.default.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + args: ["-c", "supervisord/worker.default.conf"] + env: + {{- if .Values.redis.enabled }} + - name: CVAT_REDIS_HOST + value: "{{ .Release.Name }}-redis-master" + {{- else }} + - name: CVAT_REDIS_HOST + value: "{{ .Values.redis.external.host }}" + {{- end }} + {{- if .Values.postgresql.enabled }} + - name: CVAT_POSTGRES_HOST + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-hostname + - name: CVAT_POSTGRES_USER + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-username + - name: CVAT_POSTGRES_DBNAME + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-database + - name: CVAT_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-password + {{- else }} + - name: CVAT_POSTGRES_HOST + value: "{{ .Values.postgresql.external.host }}" + - name: CVAT_POSTGRES_USER + value: "{{ .Values.postgresql.external.user }}" + - name: CVAT_POSTGRES_DBNAME + value: "{{ .Values.postgresql.external.dbname }}" + - name: CVAT_POSTGRES_PASSWORD + value: "{{ .Values.postgresql.external.password }}" + - name: CVAT_POSTGRES_PORT + value: "{{ .Values.postgresql.external.port }}" + {{- end }} + {{- if .Values.nuclio }} + - name: CVAT_SERVERLESS + value: "1" + - name: CVAT_NUCLIO_HOST + value: "{{ .Release.Name }}-nuclio-dashboard" + {{- end }} + {{- with .Values.cvat.backend.worker.default.additionalEnv }} + {{- toYaml . | nindent 10 }} + {{- end }} + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /home/django/data + name: cvat-backend-data + subPath: data + - mountPath: /home/django/keys + name: cvat-backend-data + subPath: keys + - mountPath: /home/django/logs + name: cvat-backend-data + subPath: logs + - mountPath: /home/django/models + name: cvat-backend-data + subPath: models + - mountPath: /home/django/tmp_storage + name: cvat-backend-data + subPath: tmp_storage + {{- with .Values.cvat.backend.worker.default.additionalVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + initContainers: + {{- if .Values.cvat.backend.permissionFix.enabled }} + - name: user-data-permission-fix + image: busybox + command: ["/bin/chmod", "-R", "777", "/home/django"] + {{- with .Values.cvat.backend.worker.default.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.cvat.backend.defaultStorage.enabled }} + - mountPath: /home/django/data + name: cvat-backend-data + subPath: data + - mountPath: /home/django/keys + name: cvat-backend-data + subPath: keys + - mountPath: /home/django/logs + name: cvat-backend-data + subPath: logs + - mountPath: /home/django/models + name: cvat-backend-data + subPath: models + {{- end }} + {{- with .Values.cvat.backend.worker.default.additionalVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + {{- with .Values.cvat.backend.worker.default.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cvat.backend.worker.default.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.cvat.backend.defaultStorage.enabled }} + - name: cvat-backend-data + persistentVolumeClaim: + claimName: "{{ .Release.Name }}-backend-data" + {{- end }} + {{- with .Values.cvat.backend.worker.default.additionalVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm-chart/templates/cvat_backend/worker_low/deployment.yml b/helm-chart/templates/cvat_backend/worker_low/deployment.yml new file mode 100644 index 00000000..70f9b577 --- /dev/null +++ b/helm-chart/templates/cvat_backend/worker_low/deployment.yml @@ -0,0 +1,173 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-backend-worker-low + namespace: {{ .Release.Namespace }} + labels: + app: cvat-app + tier: backend + component: worker-low + {{- include "cvat.labels" . | nindent 4 }} + {{- with .Values.cvat.backend.worker.low.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.cvat.backend.worker.low.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.cvat.backend.worker.low.replicas }} + strategy: + type: Recreate + selector: + matchLabels: + {{- include "cvat.labels" . | nindent 6 }} + {{- with .Values.cvat.backend.worker.low.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + app: cvat-app + tier: backend + component: worker-low + template: + metadata: + labels: + app: cvat-app + tier: backend + component: worker-low + {{- include "cvat.labels" . | nindent 8 }} + {{- with .Values.cvat.backend.worker.low.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cvat.backend.worker.low.annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + containers: + - name: cvat-app-backend-worker-low-container + image: {{ .Values.cvat.backend.image }}:{{ .Values.cvat.backend.tag }} + {{- with .Values.cvat.backend.worker.low.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + args: ["-c", "supervisord/worker.low.conf"] + env: + {{- if .Values.redis.enabled }} + - name: CVAT_REDIS_HOST + value: "{{ .Release.Name }}-redis-master" + {{- else }} + - name: CVAT_REDIS_HOST + value: "{{ .Values.redis.external.host }}" + {{- end }} + {{- if .Values.postgresql.enabled }} + - name: CVAT_POSTGRES_HOST + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-hostname + - name: CVAT_POSTGRES_USER + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-username + - name: CVAT_POSTGRES_DBNAME + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-database + - name: CVAT_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-{{ .Values.postgresql.secret.name }}" + key: postgresql-password + {{- else }} + - name: CVAT_POSTGRES_HOST + value: "{{ .Values.postgresql.external.host }}" + - name: CVAT_POSTGRES_USER + value: "{{ .Values.postgresql.external.user }}" + - name: CVAT_POSTGRES_DBNAME + value: "{{ .Values.postgresql.external.dbname }}" + - name: CVAT_POSTGRES_PASSWORD + value: "{{ .Values.postgresql.external.password }}" + - name: CVAT_POSTGRES_PORT + value: "{{ .Values.postgresql.external.port }}" + {{- end }} + {{- if .Values.nuclio }} + - name: CVAT_SERVERLESS + value: "1" + - name: CVAT_NUCLIO_HOST + value: "{{ .Release.Name }}-nuclio-dashboard" + {{- end }} + {{- with .Values.cvat.backend.worker.low.additionalEnv }} + {{- toYaml . | nindent 10 }} + {{- end }} + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /home/django/data + name: cvat-backend-data + subPath: data + - mountPath: /home/django/keys + name: cvat-backend-data + subPath: keys + - mountPath: /home/django/logs + name: cvat-backend-data + subPath: logs + - mountPath: /home/django/models + name: cvat-backend-data + subPath: models + - mountPath: /home/django/tmp_storage + name: cvat-backend-data + subPath: tmp_storage + {{- with .Values.cvat.backend.worker.low.additionalVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + initContainers: + {{- if .Values.cvat.backend.permissionFix.enabled }} + - name: user-data-permission-fix + image: busybox + command: ["/bin/chmod", "-R", "777", "/home/django"] + {{- with .Values.cvat.backend.worker.low.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.cvat.backend.defaultStorage.enabled }} + - mountPath: /home/django/data + name: cvat-backend-data + subPath: data + - mountPath: /home/django/keys + name: cvat-backend-data + subPath: keys + - mountPath: /home/django/logs + name: cvat-backend-data + subPath: logs + - mountPath: /home/django/models + name: cvat-backend-data + subPath: models + {{- end }} + {{- with .Values.cvat.backend.worker.low.additionalVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + {{- with .Values.cvat.backend.worker.low.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cvat.backend.worker.low.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.cvat.backend.defaultStorage.enabled }} + - name: cvat-backend-data + persistentVolumeClaim: + claimName: "{{ .Release.Name }}-backend-data" + {{- end }} + {{- with .Values.cvat.backend.worker.low.additionalVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm-chart/templates/cvat_nuclio/config.yml b/helm-chart/templates/cvat_nuclio/config.yml new file mode 100644 index 00000000..d0357507 --- /dev/null +++ b/helm-chart/templates/cvat_nuclio/config.yml @@ -0,0 +1,19 @@ +{{- if .Values.nuclio.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: cvat-nuclio-openvino-common + namespace: {{ .Release.Namespace }} + labels: + {{- include "cvat.labels" . | nindent 4 }} + app: cvat-app + tier: nuclio +{{- if semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion }} +immutable: true +{{- end }} +binaryData: + python3: |- + {{ .Files.Get "nuclio_func_common_files/python3" | b64enc }} + model_loader.py: + {{ .Files.Get "nuclio_func_common_files/model_loader.py" | b64enc }} +{{- end}} diff --git a/helm-chart/templates/cvat_opa/config.yml b/helm-chart/templates/cvat_opa/config.yml index e2903850..ddb5238e 100644 --- a/helm-chart/templates/cvat_opa/config.yml +++ b/helm-chart/templates/cvat_opa/config.yml @@ -14,4 +14,4 @@ immutable: true binaryData: rules.tar.gz: |- {{ .Files.Get "rules.tar.gz" | b64enc }} -{{- end}} \ No newline at end of file +{{- end}} diff --git a/helm-chart/templates/ingress.yaml b/helm-chart/templates/ingress.yaml index 86fc4651..6e512ce5 100644 --- a/helm-chart/templates/ingress.yaml +++ b/helm-chart/templates/ingress.yaml @@ -20,7 +20,7 @@ metadata: {{- end }} spec: {{- if semverCompare ">=1.19-0" $version }} - ingressClassName: nginx + ingressClassName: {{ .Values.ingress.className }} {{- end }} {{- if .Values.ingress.tls }} tls: @@ -45,7 +45,7 @@ spec: {{- if semverCompare ">=1.19-0" $version }} backend: service: - name: {{ .service.name }} + name: {{ $.Release.Name }}-{{ .service.name }} port: number: {{ .service.port }} {{- else }} diff --git a/helm-chart/values.yaml b/helm-chart/values.yaml index df35bf35..01ce3252 100644 --- a/helm-chart/values.yaml +++ b/helm-chart/values.yaml @@ -2,61 +2,75 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. + imagePullSecrets: [] nameOverride: "" fullnameOverride: "" cvat: backend: + server: + replicas: 1 + labels: {} + annotations: {} + resources: {} + affinity: {} + tolerations: [] + envs: + ALLOWED_HOSTS: "*" + DJANGO_MODWSGI_EXTRA_ARGS: "" + additionalEnv: [] + additionalVolumes: [] + additionalVolumeMounts: [] + worker: + default: + replicas: 2 + labels: {} + annotations: {} + resources: {} + affinity: {} + tolerations: [] + additionalEnv: [] + additionalVolumes: [] + additionalVolumeMounts: [] + low: + replicas: 1 + labels: {} + annotations: {} + resources: {} + affinity: {} + tolerations: [] + additionalEnv: [] + additionalVolumes: [] + additionalVolumeMounts: [] + utils: + replicas: 1 + labels: {} + annotations: {} + resources: {} + affinity: {} + tolerations: [] + additionalEnv: [] + additionalVolumes: [] + additionalVolumeMounts: [] replicas: 1 image: cvat/server tag: latest permissionFix: enabled: true - labels: {} - # test: test - annotations: {} - # test.io/test: test - resources: {} - affinity: {} - tolerations: [] - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/e2e-az-name - # operator: In - # values: - # - e2e-az1 - # - e2e-az2 - envs: - ALLOWED_HOSTS: "*" - DJANGO_MODWSGI_EXTRA_ARGS: "" - additionalEnv: [] - # Example: - # - name: volume-from-secret - # - name: TEST - # value: "test" - additionalVolumes: [] - # Example(assumes that pvc was already created): - # - name: tmp - # persistentVolumeClaim: - # claimName: tmp - additionalVolumeMounts: [] - # Example: - # - mountPath: /tmp - # name: tmp - # subPath: test service: - type: ClusterIP - ports: - - port: 8080 - targetPort: 8080 - protocol: TCP - name: http + annotations: + traefik.ingress.kubernetes.io/service.sticky.cookie: "true" + spec: + type: ClusterIP + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + name: http defaultStorage: - enabled: true - size: 20Gi + enabled: true + size: 20Gi frontend: replicas: 1 image: cvat/ui @@ -154,7 +168,7 @@ postgresql: user: postgres password: postgres dbname: cvat - # If not external following config will be applied by default + # If not external following config will be applied by default global: postgresql: existingSecret: cvat-postgres-secret @@ -173,38 +187,125 @@ redis: #See https://github.com/bitnami/charts/blob/master/bitnami/redis/ for more info enabled: true external: - host: 127.0.0.1 - usePassword: false + host: 127.0.0.1 + auth: + enabled: false cluster: enabled: false -ingress: +nuclio: enabled: false -# Example for nginx ingress and cert manager -# annotations: -# kubernetes.io/ingress.class: nginx -# kubernetes.io/tls-acme: "true" -# ingress.kubernetes.io/ssl-redirect: "true" -# nginx.ingress.kubernetes.io/use-regex: "true" -# nginx.ingress.kubernetes.io/secure-backends: "true" -# nginx.ingress.kubernetes.io/proxy-body-size: "0" -# nginx.ingress.kubernetes.io/proxy-send-timeout: "120" -# nginx.ingress.kubernetes.io/proxy-read-timeout: "120" -# cert-manager.io/cluster-issuer: -# hosts: -# - host: -# paths: -# - path: "/api/.*|git/.*|tensorflow/.*|auto_annotation/.*|analytics/.*|static/.*|admin|admin/.*|documentation/.*|dextr/.*|reid/.*" -# service: -# name: -backend-service -# port: 8080 -# - path : "/" -# pathType: "Prefix" -# service: -# name: -frontend-service -# port: 80 -# -# tls: -# - hosts: -# - -# secretName: ingress-tls-cvat +# See https://github.com/nuclio/nuclio/blob/master/hack/k8s/helm/nuclio/values.yaml for more info +# registry: +# loginUrl: someurl +# credentials: +# username: someuser +# password: somepass + +analytics: + enabled: false + external: + useExternal: false + logServerHost: logstash + logServerPort: 8080 + ingress: + path: /analytics + pathType: "Prefix" + annotations: + kubernetes.io/ingress.class: traefik + service: + name: kibana + port: 5601 + +# Because custom images are required here, you'll need to build them yourself and add them to your preferred docker registry. +# Ignored if analytics.enabled is false +# See https://github.com/elastic/helm-charts/blob/main/logstash/values.yaml for details +logstash: + image: "your_logstash_image" + imageTag: "latest" + # For compatibility with compose config + extraEnvs: + - name: "LOGSTASH_OUTPUT_HOST" + value: "elasticsearch-master:9200" + - name: LOGSTASH_OUTPUT_USER + value: "" + - name: LOGSTASH_OUTPUT_PASS + value: "" + imagePullPolicy: Always + service: + type: ClusterIP + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 8080 + +# Ignored if analytics.enabled is false +# See https://github.com/elastic/helm-charts/blob/main/elasticsearch/values.yaml for details +elasticsearch: + image: "your_elasticsearch_image" + imageTag: "latest" + replicas: 1 + minimumMasterNodes: 1 + +# Ignored if analytics.enabled is false +# See https://github.com/elastic/helm-charts/blob/main/kibana/values.yaml for details +kibana: + image: "your_kibana_image" + imageTag: "latest" + +ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web + kubernetes.io/ingress.class: traefik + hosts: + - host: cvat.local + paths: + - path: /api + pathType: "Prefix" + service: + name: backend-service + port: 8080 + - path: /admin + pathType: "Prefix" + service: + name: backend-service + port: 8080 + - path: /django-rq + pathType: "Prefix" + service: + name: backend-service + port: 8080 + - path: /git + pathType: "Prefix" + service: + name: backend-service + port: 8080 + - path: /opencv + pathType: "Prefix" + service: + name: backend-service + port: 8080 + - path: /profiler + pathType: "Prefix" + service: + name: backend-service + port: 8080 + - path : / + pathType: "Prefix" + service: + name: frontend-service + port: 80 + # tls: + # - hosts: + # - + # secretName: ingress-tls-cvat + +traefik: + logs: + general: + level: INFO + service: + externalIPs: + # - "192.168.49.2" diff --git a/serverless/openvino/dextr/nuclio/function.yaml b/serverless/openvino/dextr/nuclio/function.yaml index dc2ef094..230455ee 100644 --- a/serverless/openvino/dextr/nuclio/function.yaml +++ b/serverless/openvino/dextr/nuclio/function.yaml @@ -19,6 +19,16 @@ spec: - name: NUCLIO_PYTHON_EXE_PATH value: /opt/nuclio/common/openvino/python3 + volumes: + - volume: + name: openvino-common + configMap: + name: "cvat-nuclio-openvino-common" + defaultMode: 0750 + volumeMount: + name: openvino-common + mountPath: /opt/nuclio/common/openvino + build: image: cvat/openvino.dextr baseImage: openvino/ubuntu18_runtime:2020.2 diff --git a/serverless/openvino/omz/intel/face-detection-0205/nuclio/function.yaml b/serverless/openvino/omz/intel/face-detection-0205/nuclio/function.yaml index 131c8c4f..79d5883a 100644 --- a/serverless/openvino/omz/intel/face-detection-0205/nuclio/function.yaml +++ b/serverless/openvino/omz/intel/face-detection-0205/nuclio/function.yaml @@ -35,8 +35,18 @@ spec: - name: NUCLIO_PYTHON_EXE_PATH value: /opt/nuclio/common/openvino/python3 + volumes: + - volume: + name: openvino-common + configMap: + name: "cvat-nuclio-openvino-common" + defaultMode: 0750 + volumeMount: + name: openvino-common + mountPath: /opt/nuclio/common/openvino + build: - image: cvat/openvino.omz.intel.face-detection-0205 + image: cvat.openvino.omz.intel.face-detection-0205 baseImage: openvino/ubuntu18_dev:2021.1 directives: diff --git a/serverless/openvino/omz/intel/person-reidentification-retail-300/nuclio/function.yaml b/serverless/openvino/omz/intel/person-reidentification-retail-300/nuclio/function.yaml index ffa81ae8..672a695c 100644 --- a/serverless/openvino/omz/intel/person-reidentification-retail-300/nuclio/function.yaml +++ b/serverless/openvino/omz/intel/person-reidentification-retail-300/nuclio/function.yaml @@ -16,8 +16,18 @@ spec: - name: NUCLIO_PYTHON_EXE_PATH value: /opt/nuclio/common/openvino/python3 + volumes: + - volume: + name: openvino-common + configMap: + name: "cvat-nuclio-openvino-common" + defaultMode: 0750 + volumeMount: + name: openvino-common + mountPath: /opt/nuclio/common/openvino + build: - image: cvat/openvino.omz.intel.person-reidentification-retail-0300 + image: cvat.openvino.omz.intel.person-reidentification-retail-0300 baseImage: openvino/ubuntu18_dev:2020.2 directives: diff --git a/serverless/openvino/omz/intel/semantic-segmentation-adas-0001/nuclio/function.yaml b/serverless/openvino/omz/intel/semantic-segmentation-adas-0001/nuclio/function.yaml index 20e4941e..37556904 100644 --- a/serverless/openvino/omz/intel/semantic-segmentation-adas-0001/nuclio/function.yaml +++ b/serverless/openvino/omz/intel/semantic-segmentation-adas-0001/nuclio/function.yaml @@ -39,8 +39,18 @@ spec: - name: NUCLIO_PYTHON_EXE_PATH value: /opt/nuclio/common/openvino/python3 + volumes: + - volume: + name: openvino-common + configMap: + name: "cvat-nuclio-openvino-common" + defaultMode: 0750 + volumeMount: + name: openvino-common + mountPath: /opt/nuclio/common/openvino + build: - image: cvat/openvino.omz.intel.semantic-segmentation-adas-0001 + image: cvat.openvino.omz.intel.semantic-segmentation-adas-0001 baseImage: openvino/ubuntu18_dev:2020.2 directives: diff --git a/serverless/openvino/omz/intel/text-detection-0004/nuclio/function.yaml b/serverless/openvino/omz/intel/text-detection-0004/nuclio/function.yaml index eff14c11..8c2f226f 100644 --- a/serverless/openvino/omz/intel/text-detection-0004/nuclio/function.yaml +++ b/serverless/openvino/omz/intel/text-detection-0004/nuclio/function.yaml @@ -19,8 +19,18 @@ spec: - name: NUCLIO_PYTHON_EXE_PATH value: /opt/nuclio/common/openvino/python3 + volumes: + - volume: + name: openvino-common + configMap: + name: "cvat-nuclio-openvino-common" + defaultMode: 0750 + volumeMount: + name: openvino-common + mountPath: /opt/nuclio/common/openvino + build: - image: cvat/openvino.omz.intel.text-detection-0004 + image: cvat.openvino.omz.intel.text-detection-0004 baseImage: openvino/ubuntu18_dev:2020.2 directives: diff --git a/serverless/openvino/omz/public/faster_rcnn_inception_v2_coco/nuclio/function.yaml b/serverless/openvino/omz/public/faster_rcnn_inception_v2_coco/nuclio/function.yaml index 556154e0..5e55292b 100644 --- a/serverless/openvino/omz/public/faster_rcnn_inception_v2_coco/nuclio/function.yaml +++ b/serverless/openvino/omz/public/faster_rcnn_inception_v2_coco/nuclio/function.yaml @@ -1,5 +1,5 @@ metadata: - name: openvino-omz-public-faster_rcnn_inception_v2_coco + name: openvino-omz-public-faster_rcnn_inception-v2-coco namespace: cvat annotations: name: Faster RCNN @@ -98,8 +98,18 @@ spec: - name: NUCLIO_PYTHON_EXE_PATH value: /opt/nuclio/common/openvino/python3 + volumes: + - volume: + name: openvino-common + configMap: + name: "cvat-nuclio-openvino-common" + defaultMode: 0750 + volumeMount: + name: openvino-common + mountPath: /opt/nuclio/common/openvino + build: - image: cvat/openvino.omz.public.faster_rcnn_inception_v2_coco + image: cvat.openvino.omz.public.faster_rcnn_inception_v2_coco baseImage: openvino/ubuntu18_dev:2020.2 directives: diff --git a/serverless/openvino/omz/public/mask_rcnn_inception_resnet_v2_atrous_coco/nuclio/function.yaml b/serverless/openvino/omz/public/mask_rcnn_inception_resnet_v2_atrous_coco/nuclio/function.yaml index 8e7854e9..00c7c0eb 100644 --- a/serverless/openvino/omz/public/mask_rcnn_inception_resnet_v2_atrous_coco/nuclio/function.yaml +++ b/serverless/openvino/omz/public/mask_rcnn_inception_resnet_v2_atrous_coco/nuclio/function.yaml @@ -101,8 +101,18 @@ spec: - name: NUCLIO_PYTHON_EXE_PATH value: /opt/nuclio/common/openvino/python3 + volumes: + - volume: + name: openvino-common + configMap: + name: "cvat-nuclio-openvino-common" + defaultMode: 0750 + volumeMount: + name: openvino-common + mountPath: /opt/nuclio/common/openvino + build: - image: cvat/openvino.omz.public.mask_rcnn_inception_resnet_v2_atrous_coco + image: cvat.openvino.omz.public.mask_rcnn_inception_resnet_v2_atrous_coco baseImage: openvino/ubuntu18_dev:2020.2 directives: diff --git a/serverless/openvino/omz/public/yolo-v3-tf/nuclio/function.yaml b/serverless/openvino/omz/public/yolo-v3-tf/nuclio/function.yaml index 5e3966f1..f6d6d464 100644 --- a/serverless/openvino/omz/public/yolo-v3-tf/nuclio/function.yaml +++ b/serverless/openvino/omz/public/yolo-v3-tf/nuclio/function.yaml @@ -98,6 +98,16 @@ spec: - name: NUCLIO_PYTHON_EXE_PATH value: /opt/nuclio/common/openvino/python3 + volumes: + - volume: + name: openvino-common + configMap: + name: "cvat-nuclio-openvino-common" + defaultMode: 0750 + volumeMount: + name: openvino-common + mountPath: /opt/nuclio/common/openvino + build: image: cvat/openvino.omz.public.yolo-v3-tf baseImage: openvino/ubuntu18_dev:2020.2 diff --git a/serverless/pytorch/facebookresearch/detectron2/retinanet/nuclio/function-gpu.yaml b/serverless/pytorch/facebookresearch/detectron2/retinanet/nuclio/function-gpu.yaml index 21f2bde2..b864e1e5 100644 --- a/serverless/pytorch/facebookresearch/detectron2/retinanet/nuclio/function-gpu.yaml +++ b/serverless/pytorch/facebookresearch/detectron2/retinanet/nuclio/function-gpu.yaml @@ -1,5 +1,5 @@ metadata: - name: pth.facebookresearch.detectron2.retinanet_r101 + name: pth.facebookresearch.detectron2.retinanet-r101 namespace: cvat annotations: name: RetinaNet R101 @@ -96,7 +96,7 @@ spec: eventTimeout: 30s build: - image: cvat/pth.facebookresearch.detectron2.retinanet_r101 + image: cvat.pth.facebookresearch.detectron2.retinanet_r101 baseImage: ubuntu:20.04 directives: diff --git a/serverless/pytorch/facebookresearch/detectron2/retinanet/nuclio/function.yaml b/serverless/pytorch/facebookresearch/detectron2/retinanet/nuclio/function.yaml index ea8ac48f..0e4d5192 100644 --- a/serverless/pytorch/facebookresearch/detectron2/retinanet/nuclio/function.yaml +++ b/serverless/pytorch/facebookresearch/detectron2/retinanet/nuclio/function.yaml @@ -1,5 +1,5 @@ metadata: - name: pth.facebookresearch.detectron2.retinanet_r101 + name: pth.facebookresearch.detectron2.retinanet-r101 namespace: cvat annotations: name: RetinaNet R101 @@ -96,7 +96,7 @@ spec: eventTimeout: 30s build: - image: cvat/pth.facebookresearch.detectron2.retinanet_r101 + image: cvat.pth.facebookresearch.detectron2.retinanet_r101 baseImage: ubuntu:20.04 directives: diff --git a/serverless/pytorch/foolwood/siammask/nuclio/function-gpu.yaml b/serverless/pytorch/foolwood/siammask/nuclio/function-gpu.yaml index 64cfb1c6..119c3f54 100644 --- a/serverless/pytorch/foolwood/siammask/nuclio/function-gpu.yaml +++ b/serverless/pytorch/foolwood/siammask/nuclio/function-gpu.yaml @@ -17,7 +17,7 @@ spec: value: /opt/nuclio/SiamMask:/opt/nuclio/SiamMask/experiments/siammask_sharp build: - image: cvat/pth.foolwood.siammask + image: cvat.pth.foolwood.siammask baseImage: nvidia/cuda:11.1-devel-ubuntu20.04 directives: diff --git a/serverless/pytorch/foolwood/siammask/nuclio/function.yaml b/serverless/pytorch/foolwood/siammask/nuclio/function.yaml index 4911f8be..2df32550 100644 --- a/serverless/pytorch/foolwood/siammask/nuclio/function.yaml +++ b/serverless/pytorch/foolwood/siammask/nuclio/function.yaml @@ -17,7 +17,7 @@ spec: value: /opt/nuclio/SiamMask:/opt/nuclio/SiamMask/experiments/siammask_sharp build: - image: cvat/pth.foolwood.siammask + image: cvat.pth.foolwood.siammask baseImage: ubuntu:20.04 directives: diff --git a/serverless/pytorch/saic-vul/fbrs/nuclio/function.yaml b/serverless/pytorch/saic-vul/fbrs/nuclio/function.yaml index f8474ab9..fa2513fa 100644 --- a/serverless/pytorch/saic-vul/fbrs/nuclio/function.yaml +++ b/serverless/pytorch/saic-vul/fbrs/nuclio/function.yaml @@ -21,7 +21,7 @@ spec: value: /opt/nuclio/fbrs build: - image: cvat/pth.saic-vul.fbrs + image: cvat.pth.saic-vul.fbrs baseImage: python:3.6.11 directives: diff --git a/serverless/pytorch/saic-vul/hrnet/nuclio/function-gpu.yaml b/serverless/pytorch/saic-vul/hrnet/nuclio/function-gpu.yaml index 4e7789eb..350edcf4 100644 --- a/serverless/pytorch/saic-vul/hrnet/nuclio/function-gpu.yaml +++ b/serverless/pytorch/saic-vul/hrnet/nuclio/function-gpu.yaml @@ -21,7 +21,7 @@ spec: value: /opt/nuclio/hrnet build: - image: cvat/pth.saic-vul.hrnet + image: cvat-pth.saic-vul.hrnet baseImage: ubuntu:20.04 directives: diff --git a/serverless/pytorch/shiyinzhang/iog/nuclio/function.yaml b/serverless/pytorch/shiyinzhang/iog/nuclio/function.yaml index ff995312..c1d6c467 100644 --- a/serverless/pytorch/shiyinzhang/iog/nuclio/function.yaml +++ b/serverless/pytorch/shiyinzhang/iog/nuclio/function.yaml @@ -22,7 +22,7 @@ spec: value: /opt/nuclio/iog build: - image: cvat/pth.shiyinzhang.iog + image: cvat.pth.shiyinzhang.iog baseImage: continuumio/miniconda3 directives: diff --git a/serverless/pytorch/ultralytics/yolov5/nuclio/function.yaml b/serverless/pytorch/ultralytics/yolov5/nuclio/function.yaml index 4a4741c2..3ea923dd 100644 --- a/serverless/pytorch/ultralytics/yolov5/nuclio/function.yaml +++ b/serverless/pytorch/ultralytics/yolov5/nuclio/function.yaml @@ -95,7 +95,7 @@ spec: handler: main:handler eventTimeout: 30s build: - image: cvat/ultralytics-yolov5 + image: cvat.ultralytics-yolov5 baseImage: ultralytics/yolov5:latest-cpu directives: diff --git a/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio/function-gpu.yaml b/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio/function-gpu.yaml index 576edf25..bd233615 100644 --- a/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio/function-gpu.yaml +++ b/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio/function-gpu.yaml @@ -96,7 +96,7 @@ spec: eventTimeout: 30s build: - image: cvat/tf.faster_rcnn_inception_v2_coco + image: cvat.tf.faster_rcnn_inception_v2_coco baseImage: tensorflow/tensorflow:2.1.1-gpu directives: diff --git a/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio/function.yaml b/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio/function.yaml index 13a87239..a54c1de8 100644 --- a/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio/function.yaml +++ b/serverless/tensorflow/faster_rcnn_inception_v2_coco/nuclio/function.yaml @@ -96,7 +96,7 @@ spec: eventTimeout: 30s build: - image: cvat/tf.faster_rcnn_inception_v2_coco + image: cvat.tf.faster_rcnn_inception_v2_coco baseImage: tensorflow/tensorflow:2.1.1 directives: diff --git a/serverless/tensorflow/matterport/mask_rcnn/nuclio/function-gpu.yaml b/serverless/tensorflow/matterport/mask_rcnn/nuclio/function-gpu.yaml index f6e4497b..50436148 100644 --- a/serverless/tensorflow/matterport/mask_rcnn/nuclio/function-gpu.yaml +++ b/serverless/tensorflow/matterport/mask_rcnn/nuclio/function-gpu.yaml @@ -100,7 +100,7 @@ spec: - name: MASK_RCNN_DIR value: /opt/nuclio/Mask_RCNN build: - image: cvat/tf.matterport.mask_rcnn + image: cvat.tf.matterport.mask_rcnn baseImage: tensorflow/tensorflow:1.15.5-gpu-py3 directives: postCopy: diff --git a/serverless/tensorflow/matterport/mask_rcnn/nuclio/function.yaml b/serverless/tensorflow/matterport/mask_rcnn/nuclio/function.yaml index 0de22d1b..e54e3eb5 100644 --- a/serverless/tensorflow/matterport/mask_rcnn/nuclio/function.yaml +++ b/serverless/tensorflow/matterport/mask_rcnn/nuclio/function.yaml @@ -101,7 +101,7 @@ spec: - name: MASK_RCNN_DIR value: /opt/nuclio/Mask_RCNN build: - image: cvat/tf.matterport.mask_rcnn + image: cvat.tf.matterport.mask_rcnn baseImage: tensorflow/tensorflow:1.13.1-py3 directives: postCopy: @@ -114,7 +114,7 @@ spec: - kind: RUN value: curl -L https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5 -o Mask_RCNN/mask_rcnn_coco.h5 - kind: RUN - value: pip3 install numpy cython pyyaml keras==2.1.0 scikit-image Pillow + value: pip3 install numpy cython pyyaml keras==2.1.0 scikit-image 'imageio<=2.9.0' Pillow triggers: myHttpTrigger: diff --git a/site/content/en/docs/administration/advanced/backup_guide.md b/site/content/en/docs/administration/advanced/backup_guide.md index c6f372be..7fa7deb3 100644 --- a/site/content/en/docs/administration/advanced/backup_guide.md +++ b/site/content/en/docs/administration/advanced/backup_guide.md @@ -43,7 +43,7 @@ Backup data: ```bash mkdir backup docker run --rm --name temp_backup --volumes-from cvat_db -v $(pwd)/backup:/backup ubuntu tar -cjvf /backup/cvat_db.tar.bz2 /var/lib/postgresql/data -docker run --rm --name temp_backup --volumes-from cvat -v $(pwd)/backup:/backup ubuntu tar -cjvf /backup/cvat_data.tar.bz2 /home/django/data +docker run --rm --name temp_backup --volumes-from cvat_server -v $(pwd)/backup:/backup ubuntu tar -cjvf /backup/cvat_data.tar.bz2 /home/django/data # [optional] docker run --rm --name temp_backup --volumes-from cvat_elasticsearch -v $(pwd)/backup:/backup ubuntu tar -cjvf /backup/cvat_events.tar.bz2 /usr/share/elasticsearch/data ``` @@ -74,7 +74,7 @@ Restore data: ```bash cd docker run --rm --name temp_backup --volumes-from cvat_db -v $(pwd):/backup ubuntu bash -c "cd /var/lib/postgresql/data && tar -xvf /backup/cvat_db.tar.bz2 --strip 4" -docker run --rm --name temp_backup --volumes-from cvat -v $(pwd):/backup ubuntu bash -c "cd /home/django/data && tar -xvf /backup/cvat_data.tar.bz2 --strip 3" +docker run --rm --name temp_backup --volumes-from cvat_server -v $(pwd):/backup ubuntu bash -c "cd /home/django/data && tar -xvf /backup/cvat_data.tar.bz2 --strip 3" # [optional] docker run --rm --name temp_backup --volumes-from cvat_elasticsearch -v $(pwd):/backup ubuntu bash -c "cd /usr/share/elasticsearch/data && tar -xvf /backup/cvat_events.tar.bz2 --strip 4" ``` diff --git a/site/content/en/docs/administration/basics/installation.md b/site/content/en/docs/administration/basics/installation.md index ca795598..773c2469 100644 --- a/site/content/en/docs/administration/basics/installation.md +++ b/site/content/en/docs/administration/basics/installation.md @@ -108,7 +108,7 @@ For access from China, read [sources for users from China](#sources-for-users-fr below: ```bash - docker exec -it cvat bash -ic 'python3 ~/manage.py createsuperuser' + docker exec -it cvat_server bash -ic 'python3 ~/manage.py createsuperuser' ``` Choose a username and a password for your admin account. For more information @@ -181,14 +181,14 @@ For access from China, read [sources for users from China](#sources-for-users-fr below: ```bash - winpty docker exec -it cvat bash -ic 'python3 ~/manage.py createsuperuser' + winpty docker exec -it cvat_server bash -ic 'python3 ~/manage.py createsuperuser' ``` If you don't have winpty installed or the above command does not work, you may also try the following: ```bash # enter docker image first - docker exec -it cvat /bin/bash + docker exec -it cvat_server /bin/bash # then run python3 ~/manage.py createsuperuser ``` @@ -257,7 +257,7 @@ For access from China, read [sources for users from China](#sources-for-users-fr below: ```bash - docker exec -it cvat bash -ic 'python3 ~/manage.py createsuperuser' + docker exec -it cvat_server bash -ic 'python3 ~/manage.py createsuperuser' ``` Choose a username and a password for your admin account. For more information @@ -369,9 +369,10 @@ docker-compose.override.yml for this purpose: version: '3.3' services: - cvat: - environment: - CVAT_SHARE_URL: 'Mounted from /mnt/share host directory' + cvat_server: + volumes: + - cvat_share:/home/django/share:ro + cvat_worker_default: volumes: - cvat_share:/home/django/share:ro @@ -383,9 +384,7 @@ volumes: o: bind ``` -You can change the share device path to your actual share. For user convenience -we have defined the environment variable \$CVAT_SHARE_URL. This variable -contains a text (url for example) which is shown in the client-share browser. +You can change the share device path to your actual share. You can [mount](/docs/administration/advanced/mounting_cloud_storages/) your cloud storage as a FUSE and use it later as a share. diff --git a/site/content/en/docs/manual/basics/authorization.md b/site/content/en/docs/manual/basics/authorization.md index 58ad95ca..cdd44bc0 100644 --- a/site/content/en/docs/manual/basics/authorization.md +++ b/site/content/en/docs/manual/basics/authorization.md @@ -18,7 +18,7 @@ weight: 1 groups to the user. Please use the command below to create an admin account: ```bash - docker exec -it cvat bash -ic 'python3 ~/manage.py createsuperuser' + docker exec -it cvat_server bash -ic 'python3 ~/manage.py createsuperuser' ``` - If you want to create a non-admin account, you can do that using the link below diff --git a/ssh/README.md b/ssh/README.md index 30d2cd93..ed4205e7 100644 --- a/ssh/README.md +++ b/ssh/README.md @@ -6,7 +6,7 @@ If you have any problems with a git repository cloning inside the CVAT: - Make sure that SSH keys have been added to the CVAT container: ```bash -docker exec -it cvat bash -ic 'ls .ssh' +docker exec -it cvat_server bash -ic 'ls .ssh' ``` - If you need a proxy for connecting to the Internet, specify the socks_proxy variable before build the container. @@ -19,7 +19,7 @@ socks_proxy=proxy-example.com:1080 docker-compose build - Try to clone a repository via SSH directly in the container by the command: ```bash -docker exec -it cvat bash -ic 'cd /tmp -r && git clone ' +docker exec -it cvat_server bash -ic 'cd /tmp -r && git clone ' ``` - Finally try to clone it on your local machine and if it's successful, contact with us via [Gitter chat](https://gitter.im/opencv-cvat) or [Github issues](https://github.com/opencv/cvat/issues). diff --git a/supervisord.conf b/supervisord/all.conf similarity index 100% rename from supervisord.conf rename to supervisord/all.conf diff --git a/supervisord/server.conf b/supervisord/server.conf new file mode 100644 index 00000000..9f4cfbe0 --- /dev/null +++ b/supervisord/server.conf @@ -0,0 +1,37 @@ +[unix_http_server] +file = /tmp/supervisord/supervisor.sock + +[supervisorctl] +serverurl = unix:///tmp/supervisord/supervisor.sock + + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisord] +nodaemon=true +logfile=%(ENV_HOME)s/logs/supervisord.log ; supervisord log file +logfile_maxbytes=50MB ; maximum size of logfile before rotation +logfile_backups=10 ; number of backed up logfiles +loglevel=debug ; info, debug, warn, trace +pidfile=/tmp/supervisord/supervisord.pid ; pidfile location +childlogdir=%(ENV_HOME)s/logs/ ; where child log files will live + +[program:clamav_update] +command=bash -c "if [ \"${CLAM_AV}\" = 'yes' ]; then /usr/bin/freshclam -d \ + -l %(ENV_HOME)s/logs/freshclam.log --foreground=true; fi" + +[program:runserver] +; Here need to run a couple of commands to initialize DB and copy static files. +; We cannot initialize DB on build because the DB should be online. Also some +; apps are dynamically loaded by an environment variable. It can lead to issues +; with docker cache. Thus it is necessary to run collectstatic here for such +; apps. +command=%(ENV_HOME)s/wait-for-it.sh %(ENV_CVAT_POSTGRES_HOST)s:5432 -t 0 -- bash -ic \ + "rm -f /tmp/cvat-server/httpd.pid && python3 ~/manage.py migrate && \ + python3 ~/manage.py collectstatic --no-input && \ + exec python3 $HOME/manage.py runmodwsgi --log-to-terminal --port 8080 \ + --limit-request-body 1073741824 --log-level INFO --include-file ~/mod_wsgi.conf \ + %(ENV_DJANGO_MODWSGI_EXTRA_ARGS)s --locale %(ENV_LC_ALL)s \ + --server-root /tmp/cvat-server" +numprocs=%(ENV_NUMPROCS)s \ No newline at end of file diff --git a/supervisord/utils.conf b/supervisord/utils.conf new file mode 100644 index 00000000..6ed7d04d --- /dev/null +++ b/supervisord/utils.conf @@ -0,0 +1,37 @@ +[unix_http_server] +file = /tmp/supervisord/supervisor.sock + +[supervisorctl] +serverurl = unix:///tmp/supervisord/supervisor.sock + + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisord] +nodaemon=true +logfile=%(ENV_HOME)s/logs/supervisord.log ; supervisord log file +logfile_maxbytes=50MB ; maximum size of logfile before rotation +logfile_backups=10 ; number of backed up logfiles +loglevel=debug ; info, debug, warn, trace +pidfile=/tmp/supervisord/supervisord.pid ; pidfile location +childlogdir=%(ENV_HOME)s/logs/ ; where child log files will live + +[program:ssh-agent] +command=bash -c "rm /tmp/ssh-agent.sock -f && /usr/bin/ssh-agent -d -a /tmp/ssh-agent.sock" +priority=1 +autorestart=true + +[program:git_status_updater] +command=%(ENV_HOME)s/wait-for-it.sh %(ENV_CVAT_REDIS_HOST)s:6379 -t 0 -- bash -ic \ + "python3 ~/manage.py update_git_states" +environment=SSH_AUTH_SOCK="/tmp/ssh-agent.sock" +numprocs=1 + +[program:rqscheduler] +command=%(ENV_HOME)s/wait-for-it.sh %(ENV_CVAT_REDIS_HOST)s:6379 -t 0 -- bash -ic \ + "python3 /opt/venv/bin/rqscheduler --host %(ENV_CVAT_REDIS_HOST)s -i 30" +environment=SSH_AUTH_SOCK="/tmp/ssh-agent.sock" +numprocs=1 + +environment=SSH_AUTH_SOCK="/tmp/ssh-agent.sock" diff --git a/supervisord/worker.default.conf b/supervisord/worker.default.conf new file mode 100644 index 00000000..a61eb9fa --- /dev/null +++ b/supervisord/worker.default.conf @@ -0,0 +1,37 @@ +[unix_http_server] +file = /tmp/supervisord/supervisor.sock + +[supervisorctl] +serverurl = unix:///tmp/supervisord/supervisor.sock + + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisord] +nodaemon=true +logfile=%(ENV_HOME)s/logs/supervisord.log ; supervisord log file +logfile_maxbytes=50MB ; maximum size of logfile before rotation +logfile_backups=10 ; number of backed up logfiles +loglevel=debug ; info, debug, warn, trace +pidfile=/tmp/supervisord/supervisord.pid ; pidfile location +childlogdir=%(ENV_HOME)s/logs/ ; where child log files will live + +[program:ssh-agent] +command=bash -c "rm /tmp/ssh-agent.sock -f && /usr/bin/ssh-agent -d -a /tmp/ssh-agent.sock" +priority=1 +autorestart=true + +[program:rqworker_default] +command=%(ENV_HOME)s/wait-for-it.sh %(ENV_CVAT_REDIS_HOST)s:6379 -t 0 -- bash -ic \ + "exec python3 %(ENV_HOME)s/manage.py rqworker -v 3 default" +environment=SSH_AUTH_SOCK="/tmp/ssh-agent.sock" +numprocs=%(ENV_NUMPROCS)s +process_name=rqworker_default_%(process_num)s + +environment=SSH_AUTH_SOCK="/tmp/ssh-agent.sock" + +[program:clamav_update] +command=bash -c "if [ \"${CLAM_AV}\" = 'yes' ]; then /usr/bin/freshclam -d \ + -l %(ENV_HOME)s/logs/freshclam.log --foreground=true; fi" +numprocs=1 diff --git a/supervisord/worker.low.conf b/supervisord/worker.low.conf new file mode 100644 index 00000000..a706fc08 --- /dev/null +++ b/supervisord/worker.low.conf @@ -0,0 +1,36 @@ +[unix_http_server] +file = /tmp/supervisord/supervisor.sock + +[supervisorctl] +serverurl = unix:///tmp/supervisord/supervisor.sock + + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisord] +nodaemon=true +logfile=%(ENV_HOME)s/logs/supervisord.log ; supervisord log file +logfile_maxbytes=50MB ; maximum size of logfile before rotation +logfile_backups=10 ; number of backed up logfiles +loglevel=debug ; info, debug, warn, trace +pidfile=/tmp/supervisord/supervisord.pid ; pidfile location +childlogdir=%(ENV_HOME)s/logs/ ; where child log files will live + +[program:ssh-agent] +command=bash -c "rm /tmp/ssh-agent.sock -f && /usr/bin/ssh-agent -d -a /tmp/ssh-agent.sock" +priority=1 +autorestart=true + +[program:rqworker_low] +command=%(ENV_HOME)s/wait-for-it.sh %(ENV_CVAT_REDIS_HOST)s:6379 -t 0 -- bash -ic \ + "exec python3 %(ENV_HOME)s/manage.py rqworker -v 3 low" +environment=SSH_AUTH_SOCK="/tmp/ssh-agent.sock" +numprocs=%(ENV_NUMPROCS)s + +[program:clamav_update] +command=bash -c "if [ \"${CLAM_AV}\" = 'yes' ]; then /usr/bin/freshclam -d \ + -l %(ENV_HOME)s/logs/freshclam.log --foreground=true; fi" +numprocs=1 + +environment=SSH_AUTH_SOCK="/tmp/ssh-agent.sock" diff --git a/tests/cypress/integration/actions_tasks3/case_107_connected_file_share.js b/tests/cypress/integration/actions_tasks3/case_107_connected_file_share.js index e369dc59..f84ada41 100644 --- a/tests/cypress/integration/actions_tasks3/case_107_connected_file_share.js +++ b/tests/cypress/integration/actions_tasks3/case_107_connected_file_share.js @@ -21,7 +21,7 @@ context('Connected file share.', () => { .should('be.visible') .within(() => { cy.get('[aria-label="plus-square"]').click(); - cy.exec('docker exec -i cvat /bin/bash -c "ls ~/share"').then((command) => { + cy.exec('docker exec -i cvat_server /bin/bash -c "ls ~/share"').then((command) => { stdoutToList = command.stdout.split('\n'); // [image_case_107_1.png, image_case_107_2.png, image_case_107_3.png] expect(stdoutToList.length).to.be.eq(3); @@ -75,7 +75,7 @@ context('Connected file share.', () => { expect(fileRenameCommand.code).to.be.eq(0); }, ); - cy.exec('docker exec -i cvat /bin/bash -c "find ~/share -name *.png -type f"').then( + cy.exec('docker exec -i cvat_server /bin/bash -c "find ~/share -name *.png -type f"').then( (findFilesCommand) => { // [image_case_107_2.png, image_case_107_3.png] expect(findFilesCommand.stdout.split('\n').length).to.be.eq(2); diff --git a/tests/docker-compose.email.yml b/tests/docker-compose.email.yml index 46e315e7..418a1cda 100644 --- a/tests/docker-compose.email.yml +++ b/tests/docker-compose.email.yml @@ -1,6 +1,6 @@ version: '3.3' services: - cvat: + cvat_server: environment: DJANGO_SETTINGS_MODULE: cvat.settings.email_settings diff --git a/tests/docker-compose.file_share.yml b/tests/docker-compose.file_share.yml index 82eea201..01028163 100644 --- a/tests/docker-compose.file_share.yml +++ b/tests/docker-compose.file_share.yml @@ -1,8 +1,6 @@ version: '3.3' services: - cvat: - environment: - CVAT_SHARE_URL: 'Mounted from asset for case 107 host directory' + cvat_worker_default: volumes: - ./tests/cypress/integration/actions_tasks3/assets/case_107:/home/django/share:rw diff --git a/tests/python/README.md b/tests/python/README.md index a462357a..3cc30e17 100644 --- a/tests/python/README.md +++ b/tests/python/README.md @@ -68,8 +68,8 @@ for i, color in enumerate(colormap): To backup DB and data volume, please use commands below. ```console -docker exec test_cvat_1 python manage.py dumpdata --indent 2 --natural-foreign --exclude=auth.permission --exclude=contenttypes > assets/cvat_db/data.json -docker exec test_cvat_1 tar -cjv /home/django/data > assets/cvat_db/cvat_data.tar.bz2 +docker exec test_cvat_server_1 python manage.py dumpdata --indent 2 --natural-foreign --exclude=auth.permission --exclude=contenttypes > assets/cvat_db/data.json +docker exec test_cvat_server_1 tar -cjv /home/django/data > assets/cvat_db/cvat_data.tar.bz2 ``` > Note: if you won't be use --indent options or will be use with other value @@ -89,8 +89,8 @@ python shared/utils/dump_objects.py To restore DB and data volume, please use commands below. ```console -cat shared/assets/cvat_db/data.json | docker exec -i test_cvat_1 python manage.py loaddata --format=json - -cat shared/assets/cvat_db/cvat_data.tar.bz2 | docker exec -i test_cvat_1 tar --strip 3 -C /home/django/data/ -xj +cat shared/assets/cvat_db/data.json | docker exec -i test_cvat_server_1 python manage.py loaddata --format=json - +cat shared/assets/cvat_db/cvat_data.tar.bz2 | docker exec -i test_cvat_server_1 tar --strip 3 -C /home/django/data/ -xj ``` ## Assets directory structure @@ -174,7 +174,7 @@ Assets directory has two parts: ``` docker exec test_cvat_db_1 dropdb --if-exists cvat docker exec test_cvat_db_1 createdb cvat - docker exec test_cvat_1 python manage.py migrate + docker exec test_cvat_server_1 python manage.py migrate ``` 1. Perform migrate when some relation does not exists. Example of error message: @@ -183,7 +183,7 @@ Assets directory has two parts: ``` Solution: ``` - docker exec test_cvat_1 python manage.py migrate + docker exec test_cvat_server_1 python manage.py migrate ``` 1. If for some reason you need to recreate cvat database, but using `dropdb` @@ -195,5 +195,5 @@ Assets directory has two parts: In this case you should terminate all existent connections for cvat database, you can perform it with command: ``` - docker exec test_cvat_db_1 psql -U root -d postgres -v from=cvat -v to=test_db -f restore.sql + docker exec test_cvat_db_1 psql -U root -d postgres -v from=cvat_server -v to=test_db -f restore.sql ``` diff --git a/tests/python/shared/fixtures/init.py b/tests/python/shared/fixtures/init.py index 8042db74..ffed4f69 100644 --- a/tests/python/shared/fixtures/init.py +++ b/tests/python/shared/fixtures/init.py @@ -87,7 +87,7 @@ def docker_cp(source, target): def exec_cvat(command): - _run(f"docker exec {PREFIX}_cvat_1 {command}") + _run(f"docker exec {PREFIX}_cvat_server_1 {command}") def exec_cvat_db(command): @@ -104,12 +104,12 @@ def running_containers(): def dump_db(): - if 'test_cvat_1' not in running_containers(): + if 'test_cvat_server_1' not in running_containers(): pytest.exit("CVAT is not running") with open(osp.join(CVAT_DB_DIR, "data.json"), "w") as f: try: run( # nosec - "docker exec test_cvat_1 \ + "docker exec test_cvat_server_1 \ python manage.py dumpdata \ --indent 2 --natural-foreign \ --exclude=auth.permission --exclude=contenttypes".split(), @@ -150,13 +150,13 @@ def wait_for_server(): def restore_data_volumes(): docker_cp( osp.join(CVAT_DB_DIR, "cvat_data.tar.bz2"), - f"{PREFIX}_cvat_1:/tmp/cvat_data.tar.bz2", + f"{PREFIX}_cvat_server_1:/tmp/cvat_data.tar.bz2", ) exec_cvat("tar --strip 3 -xjf /tmp/cvat_data.tar.bz2 -C /home/django/data/") def start_services(rebuild=False): - if any([cn in ["cvat", "cvat_db"] for cn in running_containers()]): + if any([cn in ["cvat_server", "cvat_db"] for cn in running_containers()]): pytest.exit( "It's looks like you already have running cvat containers. Stop them and try again. " f"List of running containers: {', '.join(running_containers())}" @@ -172,7 +172,7 @@ def start_services(rebuild=False): docker_cp( osp.join(CVAT_DB_DIR, "restore.sql"), f"{PREFIX}_cvat_db_1:/tmp/restore.sql" ) - docker_cp(osp.join(CVAT_DB_DIR, "data.json"), f"{PREFIX}_cvat_1:/tmp/data.json") + docker_cp(osp.join(CVAT_DB_DIR, "data.json"), f"{PREFIX}_cvat_server_1:/tmp/data.json") @pytest.fixture(autouse=True, scope="session")