diff --git a/README.md b/README.md index ae348479..99ea3289 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,6 @@ ## Installation -## Pre-installation steps - - ### Create namespace We'll install Studio and related components in a dedicated `studio` namespace. @@ -131,6 +128,19 @@ global: -----END RSA PRIVATE KEY----- ``` + +## Upgrading to 0.60.x and above + +Version 0.60.0 fixes an issue with Ingress objects not getting cleaned up. +To upgrade to 0.60.0 and above, you need to manually delete the existing Ingress object before upgrading: + +```bash +kubectl delete ingress -l app.kubernetes.io/managed-by=Helm --namespace studio +kubectl delete ingress blobvault --namespace studio +``` + +The rest of the upgrade process is the same as described below. + ## Update Studio Version Studio's `studio-values.yaml` file points to the `latest` image tag, instructing Helm to always pull @@ -168,3 +178,4 @@ $ helm uninstall studio --namespace studio ### Available Configuration See [values file](charts/studio/values.yaml) with all available configuration flags. + diff --git a/charts/studio/Chart.lock b/charts/studio/Chart.lock index e00c1538..11226fb3 100644 --- a/charts/studio/Chart.lock +++ b/charts/studio/Chart.lock @@ -1,7 +1,4 @@ dependencies: -- name: nginx - repository: https://charts.bitnami.com/bitnami - version: 13.2.30 - name: redis repository: https://charts.bitnami.com/bitnami version: 17.14.3 @@ -11,5 +8,5 @@ dependencies: - name: kuberay-operator repository: https://ray-project.github.io/kuberay-helm version: 0.6.0 -digest: sha256:3b2dc8c1ca3e1841605034aca0e0dd7119c1fbcf17eecc47c997bf4510bce4cf -generated: "2023-08-16T00:49:28.269211675Z" +digest: sha256:11e47f1d691977c00cf3dd4454365b63ebdb81db484e837a1f720616a50fec63 +generated: "2023-08-18T21:39:06.308367+02:00" diff --git a/charts/studio/Chart.yaml b/charts/studio/Chart.yaml index 5865bb17..e2c8abb3 100644 --- a/charts/studio/Chart.yaml +++ b/charts/studio/Chart.yaml @@ -2,16 +2,13 @@ apiVersion: v2 name: studio description: A Helm chart for Kubernetes type: application -version: 0.5.2 +version: 0.6.0 appVersion: "v2.29.0" maintainers: - name: iterative email: support@iterative.ai icon: "https://static.iterative.ai/logo/studio.svg" dependencies: - - name: nginx - version: "13.2.30" - repository: "https://charts.bitnami.com/bitnami" - name: redis condition: redis.enabled version: "17.14.3" diff --git a/charts/studio/README.md b/charts/studio/README.md index 4e7b461f..d9386220 100644 --- a/charts/studio/README.md +++ b/charts/studio/README.md @@ -1,6 +1,6 @@ # studio -![Version: 0.5.2](https://img.shields.io/badge/Version-0.5.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.29.0](https://img.shields.io/badge/AppVersion-v2.29.0-informational?style=flat-square) +![Version: 0.6.0](https://img.shields.io/badge/Version-0.6.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.29.0](https://img.shields.io/badge/AppVersion-v2.29.0-informational?style=flat-square) A Helm chart for Kubernetes @@ -14,7 +14,6 @@ A Helm chart for Kubernetes | Repository | Name | Version | |------------|------|---------| -| https://charts.bitnami.com/bitnami | nginx | 13.2.30 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | | https://charts.bitnami.com/bitnami | redis | 17.14.3 | | https://ray-project.github.io/kuberay-helm | kuberay-operator | 0.6.0 | @@ -27,7 +26,7 @@ A Helm chart for Kubernetes | global.blobvault.accessKeyId | string | `""` | Blobvault S3 access key ID | | global.blobvault.bucket | string | `""` | Blobvault S3 bucket name | | global.blobvault.endpointUrl | string | `""` | Blobvault S3 endpoint URL | -| global.blobvault.persistentVolume | object | `{"accessModes":["ReadWriteOnce"],"size":"30Gi","storageClassName":""}` | Blobvault local backing store settings. | +| global.blobvault.persistentVolume | object | `{"accessModes":["ReadWriteOnce"],"size":"30Gi","storageClassName":""}` | Blobvault local backing store settings. Not used when `global.blobvault.bucket` is set. | | global.blobvault.persistentVolume.accessModes | list | ReadWriteOnce | Blobvault local backing store access mode. | | global.blobvault.persistentVolume.size | string | `"30Gi"` | Blobvault local backing store size. | | global.blobvault.persistentVolume.storageClassName | string | default storage class in the cluster. | Blobvault local backing store storage class. | @@ -84,13 +83,6 @@ A Helm chart for Kubernetes | global.scmProviders.webhookHost | string | `$global.host` value. | Custom hostname for incoming webhook (if Studio runs on a private network and you use SaaS versions of GitHub, GitLab, or Bitbucket) | | global.secretKey | string | `""` | Studio: Secret key for signing Webhook payloads We recommend you set this externally. If left empty, a random key will be generated. | | imagePullSecrets | list | `[]` | Secret containing Docker registry credentials | -| nginx.extraVolumeMounts[0].mountPath | string | `"/blobvault"` | | -| nginx.extraVolumeMounts[0].name | string | `"blobvault"` | | -| nginx.extraVolumes[0].name | string | `"blobvault"` | | -| nginx.extraVolumes[0].persistentVolumeClaim.claimName | string | `"blobvault"` | | -| nginx.ingress.enabled | bool | `false` | | -| nginx.serverBlock | string | see in `values.yaml` | Nginx for blobvault configuration | -| nginx.service.type | string | `"ClusterIP"` | | | pgBouncer | object | `{"affinity":{},"autoscaling":{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80},"enabled":false,"envFromSecret":"","envVars":{},"image":{"pullPolicy":"IfNotPresent","repository":"docker.io/bitnami/pgbouncer","tag":"1.20.1"},"nodeSelector":{},"podAnnotations":{},"podSecurityContext":{},"replicaCount":1,"resources":{"limits":{"cpu":"1000m","memory":"1024Mi"},"requests":{"cpu":"500m","memory":"512Mi"}},"securityContext":{},"service":{"port":6432,"type":"ClusterIP"},"serviceAccountName":"","tolerations":[]}` | PgBouncer settings group | | pgBouncer.affinity | object | `{}` | PgBouncer pod affinity configuration | | pgBouncer.autoscaling | object | `{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80}` | PgBouncer autoscaling configuration | @@ -143,6 +135,10 @@ A Helm chart for Kubernetes | studioBeat | object | `{"affinity":{},"autoscaling":{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80},"envFromSecret":"","envVars":{},"nodeSelector":{},"podAnnotations":{},"podSecurityContext":{},"replicaCount":1,"resources":{"limits":{"cpu":"200m","memory":"256Mi"},"requests":{"cpu":"100m","memory":"128Mi"}},"securityContext":{},"tolerations":[]}` | Studio Beat settings group | | studioBeat.envFromSecret | string | `""` | The name of an existing Secret that contains sensitive environment variables passed to beat pods. | | studioBeat.envVars | object | `{}` | Additional environment variables for beat pods | +| studioBlobvault | object | `{"image":{"repository":"nginx","tag":"1.25.1-alpine"},"podSecurityContext":{},"securityContext":{},"service":{"port":80}}` | Studio: Additional service to expose the blobvault files generated by the worker It is enabled automatically if the worker is scaled to 1 replica and no bucket is configured | +| studioBlobvault.image | object | `{"repository":"nginx","tag":"1.25.1-alpine"}` | Image to use for the blobvault service | +| studioBlobvault.image.repository | string | `"nginx"` | Image repository | +| studioBlobvault.image.tag | string | `"1.25.1-alpine"` | Image tag | | studioDvcxWorker | object | `{"affinity":{},"autoscaling":{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80},"envFromSecret":"","envVars":{},"ephemeralStorage":{"persistentVolumeClaim":{"storageClass":""},"size":"1Gi","type":"emptyDir"},"image":{"pullPolicy":"IfNotPresent","repository":"docker.iterative.ai/studio-dvcx-worker"},"nodeSelector":{},"podAnnotations":{},"podSecurityContext":{},"replicaCount":1,"resources":{"limits":{"cpu":"8000m","ephemeral-storage":"10Gi","memory":"16Gi"},"requests":{"cpu":"500m","ephemeral-storage":"500Mi","memory":"512Mi"}},"securityContext":{},"tolerations":[]}` | Studio DVCx Worker settings group | | studioDvcxWorker.affinity | object | `{}` | DVCx worker pod affinity configuration | | studioDvcxWorker.autoscaling | object | `{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80}` | DVCx worker autoscaling configuration | diff --git a/charts/studio/nginx/backend-sidecar.conf b/charts/studio/nginx/backend-sidecar.conf new file mode 100644 index 00000000..27f04671 --- /dev/null +++ b/charts/studio/nginx/backend-sidecar.conf @@ -0,0 +1,32 @@ +server { + listen 80; + access_log /dev/stdout; + error_log /dev/stdout debug; + + {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} + rewrite /{{ include "studio.basePath" . }}/(.*) /$1 break; + {{- end }} + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://backend; + } +} + +upstream backend { + server 127.0.0.1:8000; +} + +# Health check endpoint +server { + access_log /dev/null main; + error_log /dev/null info; + + listen 8080; + location / { + return 200 'OK'; + } +} diff --git a/charts/studio/nginx/blobvault.conf b/charts/studio/nginx/blobvault.conf new file mode 100644 index 00000000..ed888238 --- /dev/null +++ b/charts/studio/nginx/blobvault.conf @@ -0,0 +1,57 @@ +server { + listen 80; + server_name _; + access_log /dev/stdout; + error_log /dev/stdout debug; + + root /blobvault; + + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Studio-Trace-Id'; + + {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} + rewrite /{{ include "studio.basePath" . }}/blobvault/(.*) /$1 break; + {{- else }} + rewrite /blobvault/(.*) /$1 break; + {{- end }} + + location ~ \.gz$ { + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + if ($request_method = 'GET') { + add_header Content-Encoding gzip; + } + gzip off; + types { } default_type "application/json"; + } + + location /blobvault { + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + + gzip on; + + try_files $uri $uri/ =404; + } +} + +# Health check endpoint +server { + access_log /dev/null main; + error_log /dev/null info; + + listen 8080; + location / { + return 200 'OK'; + } +} diff --git a/charts/studio/nginx/nginx.conf b/charts/studio/nginx/nginx.conf new file mode 100644 index 00000000..a6ae4cbf --- /dev/null +++ b/charts/studio/nginx/nginx.conf @@ -0,0 +1,33 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /dev/stdout main; + error_log /dev/stdout info; + + sendfile on; + tcp_nopush on; + + server_tokens off; + + keepalive_timeout 65; + + gzip on; + + + include /etc/nginx/conf.d/*.conf; +} diff --git a/charts/studio/templates/_helpers.tpl b/charts/studio/templates/_helpers.tpl index 006cdc5e..5416267f 100644 --- a/charts/studio/templates/_helpers.tpl +++ b/charts/studio/templates/_helpers.tpl @@ -97,6 +97,15 @@ app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end }} +{{- define "studio-blobvault.labels" -}} +helm.sh/chart: {{ include "studio.chart" . }} +{{ include "studio-blobvault.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + {{- define "pgbouncer.labels" -}} helm.sh/chart: {{ include "studio.chart" . }} {{ include "pgbouncer.selectorLabels" . }} @@ -115,6 +124,11 @@ app.kubernetes.io/name: {{ include "studio.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} +{{- define "studio-blobvault.selectorLabels" -}} +app.kubernetes.io/name: studio-blobvault +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + {{- define "studio-backend.selectorLabels" -}} app.kubernetes.io/name: studio-backend app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/charts/studio/templates/configmap-studio-nginx.yaml b/charts/studio/templates/configmap-studio-nginx.yaml new file mode 100644 index 00000000..79e247f8 --- /dev/null +++ b/charts/studio/templates/configmap-studio-nginx.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-nginx +data: +{{ ( tpl (.Files.Glob "nginx/*").AsConfig . ) | indent 2 }} diff --git a/charts/studio/templates/deployment-studio-backend.yaml b/charts/studio/templates/deployment-studio-backend.yaml index 5562a9da..e1e7f6a8 100644 --- a/charts/studio/templates/deployment-studio-backend.yaml +++ b/charts/studio/templates/deployment-studio-backend.yaml @@ -19,7 +19,9 @@ spec: metadata: annotations: checksum/configmap-studio-backend: {{ include (print $.Template.BasePath "/configmap-studio-backend.yaml") . | sha256sum }} + checksum/configmap-studio-nginx: {{ include (print $.Template.BasePath "/configmap-studio-nginx.yaml") . | sha256sum }} {{- include "studio.checksum" . | indent 8 }} + {{- with .Values.studioBackend.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} @@ -46,7 +48,7 @@ spec: args: - | ./manage.py migrate - {{- if .Release.IsUpgrade }} + {{- if and .Release.IsUpgrade (not .Values.ci) }} ./manage.py migrate phonenumber --fake-initial ./manage.py migrate {{- end }} @@ -73,7 +75,7 @@ spec: imagePullPolicy: {{ .Values.studioBackend.image.pullPolicy }} args: [ "uwsgi", "--ini", "uwsgi.ini" ] ports: - - name: http + - name: studio-http containerPort: 8000 protocol: TCP startupProbe: @@ -101,8 +103,10 @@ spec: failureThreshold: 5 timeoutSeconds: 60 volumeMounts: + {{ if not .Values.global.blobvault.bucket }} - name: blobvault mountPath: /blobvault + {{- end }} - name: studio-ca-certificates mountPath: /usr/local/share/ca-certificates resources: @@ -127,13 +131,55 @@ spec: - secretRef: name: {{ .Values.studioBackend.envFromSecret }} {{- end }} + {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} + - name: nginx-sidecar + image: "{{ .Values.studioBlobvault.image.repository }}:{{ .Values.studioBlobvault.image.tag }}" + imagePullPolicy: "IfNotPresent" + ports: + - name: nginx-http + containerPort: 80 + protocol: TCP + livenessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 8080 + periodSeconds: 10 + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - name: nginx-sidecar + mountPath: /etc/nginx/conf.d/default.conf + subPath: backend-sidecar.conf + resources: + requests: + cpu: 10m + memory: 64Mi + limits: + cpu: 100m + memory: 256Mi + {{- end }} volumes: + {{ if not .Values.global.blobvault.bucket }} - name: blobvault persistentVolumeClaim: claimName: blobvault + {{- end }} - name: studio-ca-certificates configMap: name: studio-ca-certificates + {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} + - name: nginx-config + configMap: + name: {{ .Release.Name }}-nginx + - name: nginx-sidecar + configMap: + name: {{ .Release.Name }}-nginx + {{- end }} {{- with .Values.studioBackend.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/charts/studio/templates/deployment-studio-blobvault-nginx.yaml b/charts/studio/templates/deployment-studio-blobvault-nginx.yaml new file mode 100644 index 00000000..6e9f9323 --- /dev/null +++ b/charts/studio/templates/deployment-studio-blobvault-nginx.yaml @@ -0,0 +1,85 @@ +{{ if not .Values.global.blobvault.bucket }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-blobvault + labels: + {{- include "studio-blobvault.labels" . | nindent 4 }} +spec: + replicas: 1 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + selector: + matchLabels: + {{- include "studio-blobvault.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/configmap-studio-nginx: {{ include (print $.Template.BasePath "/configmap-studio-nginx.yaml") . | sha256sum }} + {{- include "studio.checksum" . | indent 8 }} + {{- with .Values.studioBlobvault.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "studio-blobvault.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "studio.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.studioBlobvault.podSecurityContext | nindent 8 }} + containers: + - name: nginx + securityContext: + {{- toYaml .Values.studioBlobvault.securityContext | nindent 12 }} + image: "{{ .Values.studioBlobvault.image.repository }}:{{ .Values.studioBlobvault.image.tag }}" + imagePullPolicy: "IfNotPresent" + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + tcpSocket: + port: 8080 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 8080 + periodSeconds: 10 + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - name: nginx-config + mountPath: /etc/nginx/conf.d/default.conf + subPath: blobvault.conf + - name: blobvault-pvc + mountPath: /blobvault + readOnly: true + resources: + requests: + cpu: 10m + memory: 64Mi + limits: + cpu: 100m + memory: 256Mi + volumes: + - name: nginx-config + configMap: + name: {{.Release.Name}}-nginx + - name: blobvault-pvc + persistentVolumeClaim: + claimName: blobvault + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: "kubernetes.io/hostname" + labelSelector: + matchLabels: + {{- include "studio-worker.selectorLabels" . | nindent 18 }} + {{- end }} diff --git a/charts/studio/templates/deployment-studio-worker.yaml b/charts/studio/templates/deployment-studio-worker.yaml index ef9d1050..5d5dea0f 100644 --- a/charts/studio/templates/deployment-studio-worker.yaml +++ b/charts/studio/templates/deployment-studio-worker.yaml @@ -63,14 +63,18 @@ spec: name: {{ .Values.studioWorker.envFromSecret }} {{- end }} volumeMounts: + {{- if not .Values.global.blobvault.bucket }} - name: blobvault mountPath: /blobvault + {{- end }} - name: studio-ca-certificates mountPath: /usr/local/share/ca-certificates volumes: + {{- if not .Values.global.blobvault.bucket }} - name: blobvault persistentVolumeClaim: claimName: blobvault + {{- end }} - name: studio-ca-certificates configMap: name: studio-ca-certificates diff --git a/charts/studio/templates/ingress-blobvault.yaml b/charts/studio/templates/ingress-blobvault-nginx.yaml similarity index 77% rename from charts/studio/templates/ingress-blobvault.yaml rename to charts/studio/templates/ingress-blobvault-nginx.yaml index 8f8d49e7..fa565e08 100644 --- a/charts/studio/templates/ingress-blobvault.yaml +++ b/charts/studio/templates/ingress-blobvault-nginx.yaml @@ -1,3 +1,4 @@ +{{- if not .Values.global.blobvault.bucket }} {{- if .Values.global.ingress.enabled -}} {{- if and .Values.global.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} {{- if not (hasKey .Values.global.ingress.annotations "kubernetes.io/ingress.class") }} @@ -13,12 +14,12 @@ apiVersion: extensions/v1beta1 {{- end }} kind: Ingress metadata: - name: blobvault + name: {{.Release.Name}}-blobvault + labels: + {{- include "studio-blobvault.labels" . | nindent 4 }} annotations: - helm.sh/hook: post-install,post-upgrade - helm.sh/hook-weight: "-1" - argocd.argoproj.io/hook: PostSync - nginx.ingress.kubernetes.io/rewrite-target: /$2 + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{.Release.Namespace}} {{- with .Values.global.ingress.annotations }} {{- toYaml . | nindent 4 }} {{- end }} @@ -34,13 +35,14 @@ spec: secretName: {{ .tlsSecretName }} {{- end }} {{- end }} + rules: - http: paths: {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} - - path: /{{ include "studio.basePath" . }}/blobvault(/|$)(.*) + - path: /{{ include "studio.basePath" . }}/blobvault {{- else }} - - path: /blobvault(/|$)(.*) + - path: /blobvault {{- end }} {{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }} pathType: ImplementationSpecific @@ -48,15 +50,15 @@ spec: backend: {{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }} service: - name: {{ .Release.Name }}-nginx + name: {{ .Release.Name }}-blobvault port: name: http {{- else }} - serviceName: {{ .Release.Name }}-nginx - servicePort: 80 + serviceName: {{ .Release.Name }}-blobvault + servicePort: {{ .Values.studioBlobvault.service.port | default 80 }} {{- end }} {{- if .Values.global.ingress.hostnameEnabled }} host: {{ .Values.global.host }} {{- end }} {{- end }} - +{{- end }} diff --git a/charts/studio/templates/ingress-studio-api.yaml b/charts/studio/templates/ingress-studio-api.yaml index 61993888..8da82eda 100644 --- a/charts/studio/templates/ingress-studio-api.yaml +++ b/charts/studio/templates/ingress-studio-api.yaml @@ -16,13 +16,10 @@ metadata: name: {{ .Release.Name }}-studio-api labels: {{- include "studio-ui.labels" . | nindent 4 }} + "app.kubernetes.io/managed-by": "Helm" annotations: - helm.sh/hook: post-install,post-upgrade - helm.sh/hook-weight: "-1" - argocd.argoproj.io/hook: PostSync - {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} - nginx.ingress.kubernetes.io/rewrite-target: /$1 - {{- end }} + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{.Release.Namespace}} {{- with .Values.global.ingress.annotations }} {{- toYaml . | nindent 4 }} {{- end }} @@ -42,7 +39,7 @@ spec: - http: paths: {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} - - path: /{{ include "studio.basePath" . }}/(api(?:/|$).*) + - path: /{{ include "studio.basePath" . }}/api {{- else }} - path: /api {{- end }} diff --git a/charts/studio/templates/ingress-studio-ui.yaml b/charts/studio/templates/ingress-studio-ui.yaml index 5b80dcf7..637dd2b5 100644 --- a/charts/studio/templates/ingress-studio-ui.yaml +++ b/charts/studio/templates/ingress-studio-ui.yaml @@ -16,10 +16,10 @@ metadata: name: {{ .Release.Name }}-studio-ui labels: {{- include "studio-ui.labels" . | nindent 4 }} + "app.kubernetes.io/managed-by": "Helm" annotations: - helm.sh/hook: post-install,post-upgrade - helm.sh/hook-weight: "-1" - argocd.argoproj.io/hook: PostSync + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{.Release.Namespace}} {{- with .Values.global.ingress.annotations }} {{- toYaml . | nindent 4 }} {{- end }} @@ -39,7 +39,7 @@ spec: - http: paths: {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} - - path: /{{ include "studio.basePath" . }}((?:/|$).*) + - path: /{{ include "studio.basePath" . }} {{- else }} - path: / {{- end }} diff --git a/charts/studio/templates/ingress-studio-webhook.yaml b/charts/studio/templates/ingress-studio-webhook.yaml index 9c9dee91..7ecd0eba 100644 --- a/charts/studio/templates/ingress-studio-webhook.yaml +++ b/charts/studio/templates/ingress-studio-webhook.yaml @@ -16,13 +16,10 @@ metadata: name: {{ .Release.Name }}-studio-webhook labels: {{- include "studio-ui.labels" . | nindent 4 }} + "app.kubernetes.io/managed-by": "Helm" annotations: - helm.sh/hook: post-install,post-upgrade - helm.sh/hook-weight: "-1" - argocd.argoproj.io/hook: PostSync - {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} - nginx.ingress.kubernetes.io/rewrite-target: /$1 - {{- end }} + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{.Release.Namespace}} {{- with .Values.global.ingress.annotations }} {{- toYaml . | nindent 4 }} {{- end }} @@ -42,7 +39,7 @@ spec: - http: paths: {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} - - path: /{{ include "studio.basePath" . }}/(webhook(?:/|$).*) + - path: /{{ include "studio.basePath" . }}/webhook {{- else }} - path: /webhook {{- end }} diff --git a/charts/studio/templates/persistentvolume.yaml b/charts/studio/templates/persistentvolume.yaml index 7a39308b..4eb2ce59 100644 --- a/charts/studio/templates/persistentvolume.yaml +++ b/charts/studio/templates/persistentvolume.yaml @@ -1,4 +1,5 @@ --- +{{ if not .Values.global.blobvault.bucket }} apiVersion: v1 kind: PersistentVolumeClaim metadata: @@ -18,3 +19,4 @@ spec: resources: requests: storage: {{ .Values.global.blobvault.persistentVolume.size }} +{{- end }} diff --git a/charts/studio/templates/service-backend.yaml b/charts/studio/templates/service-backend.yaml index d3916a0e..4252deac 100644 --- a/charts/studio/templates/service-backend.yaml +++ b/charts/studio/templates/service-backend.yaml @@ -8,7 +8,11 @@ spec: type: {{ .Values.studioBackend.service.type }} ports: - port: {{ .Values.studioBackend.service.port }} - targetPort: http + {{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }} + targetPort: nginx-http + {{- else }} + targetPort: studio-http + {{- end }} protocol: TCP name: http selector: diff --git a/charts/studio/templates/service-blobvault-nginx.yaml b/charts/studio/templates/service-blobvault-nginx.yaml new file mode 100644 index 00000000..b76a8525 --- /dev/null +++ b/charts/studio/templates/service-blobvault-nginx.yaml @@ -0,0 +1,17 @@ +{{ if not .Values.global.blobvault.bucket }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-blobvault + labels: + {{- include "studio-blobvault.labels" . | nindent 4 }} +spec: + type: {{ .Values.studioBackend.service.type }} + ports: + - port: {{ .Values.studioBlobvault.service.port | default 80 }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "studio-blobvault.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/studio/values.yaml b/charts/studio/values.yaml index daad9fc1..e9f11cc2 100644 --- a/charts/studio/values.yaml +++ b/charts/studio/values.yaml @@ -49,6 +49,7 @@ global: blobvault: # -- Blobvault local backing store settings. + # Not used when `global.blobvault.bucket` is set. persistentVolume: # -- Blobvault local backing store access mode. # @default -- ReadWriteOnce @@ -190,93 +191,6 @@ global: # -- (DEPRECATED) BitBucket Webhook URL webhookUrl: "" -nginx: - service: - type: ClusterIP - - ingress: - enabled: false - - extraVolumes: - - name: blobvault - persistentVolumeClaim: - claimName: blobvault - - extraVolumeMounts: - - name: blobvault - mountPath: /blobvault - - # -- Nginx for blobvault configuration - # @default -- see in `values.yaml` - serverBlock: |- - server { - listen 8080; - server_name _; - - root /blobvault; - - location ~ \.gz$ { - if ($request_method = 'OPTIONS') { - add_header 'Access-Control-Allow-Origin' '*'; - # - # Cookies - # - add_header 'Access-Control-Allow-Credentials' 'true'; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; - # - # Custom headers and headers various browsers *should* be OK with but aren't - # - add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Studio-Trace-Id'; - # - # Tell client that this pre-flight info is valid for 20 days - # - add_header 'Access-Control-Max-Age' 1728000; - add_header 'Content-Type' 'text/plain charset=UTF-8'; - add_header 'Content-Length' 0; - return 204; - } - if ($request_method = 'GET') { - add_header 'Access-Control-Allow-Origin' '*'; - add_header 'Access-Control-Allow-Credentials' 'true'; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; - add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Studio-Trace-Id'; - add_header Content-Encoding gzip; - } - gzip off; - types { } default_type "application/json"; - } - - - location / { - if ($request_method = 'OPTIONS') { - add_header 'Access-Control-Allow-Origin' '*'; - # - # Cookies - # - add_header 'Access-Control-Allow-Credentials' 'true'; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; - # - # Custom headers and headers various browsers *should* be OK with but aren't - # - add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Studio-Trace-Id'; - # - # Tell client that this pre-flight info is valid for 20 days - # - add_header 'Access-Control-Max-Age' 1728000; - add_header 'Content-Type' 'text/plain charset=UTF-8'; - add_header 'Content-Length' 0; - return 204; - } - if ($request_method = 'GET') { - add_header 'Access-Control-Allow-Origin' '*'; - add_header 'Access-Control-Allow-Credentials' 'true'; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; - add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Studio-Trace-Id'; - } - - try_files $uri $uri/ =404; - } - } redis: # -- Redis enabled @@ -832,6 +746,31 @@ studioDvcxWorker: # -- DVCx worker pod affinity configuration affinity: {} +# -- Studio: Additional service to expose the blobvault files generated by the worker +# It is enabled automatically if the worker is scaled to 1 replica and no bucket is configured +studioBlobvault: + + # -- Image to use for the blobvault service + image: + # -- Image repository + repository: nginx + # -- Image tag + tag: 1.25.1-alpine + + service: + port: 80 + + podSecurityContext: {} + # fsGroup: 2000 + + securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + serviceAccount: # Specifies whether a service account should be created create: false