From 542b2050146e813a9a547b577f0563470a77f6e6 Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Mon, 29 Apr 2024 18:26:21 +0200 Subject: [PATCH 01/12] Make serve charts work on a rancher desktop You need to change volumesk8s manually and delete network policies for the whole thing to work --- apps/jupyter-lab/values.yaml | 3 - apps/volumek8s/values.yaml | 10 +++- serve/Chart.yaml | 4 +- serve/templates/celery-beat-deployment.yaml | 2 - serve/templates/celery-flower-deployment.yaml | 2 - serve/templates/celery-worker-deployment.yaml | 2 - .../templates/event-listener-deployment.yaml | 2 - serve/templates/media-vol.yaml | 2 +- serve/templates/nginx-deployment.yaml | 2 - serve/templates/studio-deployment.yaml | 14 ++++- serve/values.yaml | 59 +++++++++---------- 11 files changed, 49 insertions(+), 53 deletions(-) diff --git a/apps/jupyter-lab/values.yaml b/apps/jupyter-lab/values.yaml index 28f1ce5..d6e2b71 100644 --- a/apps/jupyter-lab/values.yaml +++ b/apps/jupyter-lab/values.yaml @@ -19,9 +19,6 @@ global: apps: volumek8s: -imagePullSecrets: - - name: regcred - minio: access_key: minio secret_key: minio123 diff --git a/apps/volumek8s/values.yaml b/apps/volumek8s/values.yaml index c29e83d..a5a4776 100644 --- a/apps/volumek8s/values.yaml +++ b/apps/volumek8s/values.yaml @@ -1,4 +1,7 @@ -accessModes: ReadWriteMany +# locally +accessModes: ReadWriteOnce +# remote +# accessModes: ReadWriteMany storageClass: default appname: volumek8s @@ -9,4 +12,7 @@ project: volume: size: 10Mi storageClass: false - accessModes: ReadWriteMany +# locally + accessModes: ReadWriteOnce +# remote +# accessModes: ReadWriteMany \ No newline at end of file diff --git a/serve/Chart.yaml b/serve/Chart.yaml index 77ac066..b1c68d6 100644 --- a/serve/Chart.yaml +++ b/serve/Chart.yaml @@ -24,10 +24,10 @@ dependencies: condition: redis.enabled - name: rabbitmq - version: 11.9.1 + version: 11.16.2 repository: https://charts.bitnami.com/bitnami condition: rabbitmq.enabled - + - name: common repository: https://charts.bitnami.com/bitnami tags: diff --git a/serve/templates/celery-beat-deployment.yaml b/serve/templates/celery-beat-deployment.yaml index 71ce6d4..dba1638 100644 --- a/serve/templates/celery-beat-deployment.yaml +++ b/serve/templates/celery-beat-deployment.yaml @@ -121,8 +121,6 @@ spec: - mountPath: /app/studio/settings.py subPath: settings.py name: {{ .Release.Name}}-settings-configmap - imagePullSecrets: - - name: ghcrsecret restartPolicy: Always volumes: - name: {{ .Release.Name}}-settings-configmap diff --git a/serve/templates/celery-flower-deployment.yaml b/serve/templates/celery-flower-deployment.yaml index a6e7089..d77a4fe 100644 --- a/serve/templates/celery-flower-deployment.yaml +++ b/serve/templates/celery-flower-deployment.yaml @@ -103,8 +103,6 @@ spec: - mountPath: /app/studio/settings.py subPath: settings.py name: {{ .Release.Name}}-settings-configmap - imagePullSecrets: - - name: ghcrsecret restartPolicy: Always volumes: {{- if .Values.chartcontroller.addSecret }} diff --git a/serve/templates/celery-worker-deployment.yaml b/serve/templates/celery-worker-deployment.yaml index 1a8e735..bd9e8a7 100644 --- a/serve/templates/celery-worker-deployment.yaml +++ b/serve/templates/celery-worker-deployment.yaml @@ -127,8 +127,6 @@ spec: - mountPath: /app/studio/settings.py subPath: settings.py name: {{ .Release.Name}}-settings-configmap - imagePullSecrets: - - name: ghcrsecret restartPolicy: Always volumes: {{- if .Values.chartcontroller.addSecret }} diff --git a/serve/templates/event-listener-deployment.yaml b/serve/templates/event-listener-deployment.yaml index 62fc082..5939dee 100644 --- a/serve/templates/event-listener-deployment.yaml +++ b/serve/templates/event-listener-deployment.yaml @@ -71,8 +71,6 @@ spec: requests: cpu: {{ .Values.eventListener.resources.requests.cpu }} memory: {{ .Values.eventListener.resources.requests.memory }} - imagePullSecrets: - - name: ghcrsecret restartPolicy: Always volumes: status: {} diff --git a/serve/templates/media-vol.yaml b/serve/templates/media-vol.yaml index f39274f..c541a4e 100644 --- a/serve/templates/media-vol.yaml +++ b/serve/templates/media-vol.yaml @@ -6,7 +6,7 @@ metadata: "helm.sh/resource-policy": keep spec: accessModes: - - {{ .Values.studio.media.storage.accessModes | default "ReadWriteMany"}} + - {{ .Values.studio.media.storage.accessModes }} storageClassName: {{ include "stackn.studio.media.storageclass" . }} resources: requests: diff --git a/serve/templates/nginx-deployment.yaml b/serve/templates/nginx-deployment.yaml index 3e25624..5eef53b 100644 --- a/serve/templates/nginx-deployment.yaml +++ b/serve/templates/nginx-deployment.yaml @@ -60,6 +60,4 @@ spec: requests: cpu: {{ .Values.studio.static.resources.requests.cpu }} memory: {{ .Values.studio.static.resources.requests.memory }} - imagePullSecrets: - - name: ghcrsecret diff --git a/serve/templates/studio-deployment.yaml b/serve/templates/studio-deployment.yaml index 73dcaa9..02a0a0d 100644 --- a/serve/templates/studio-deployment.yaml +++ b/serve/templates/studio-deployment.yaml @@ -144,6 +144,10 @@ spec: - name: mediavol mountPath: {{ .Values.studio.media.mount_path }} {{ end }} + {{ if eq .Values.environment "local" }} + - mountPath: /app + name: sourcecode + {{ end }} resources: limits: cpu: {{ .Values.studio.resources.limits.cpu }} @@ -175,9 +179,7 @@ spec: initialDelaySeconds: {{ .Values.studio.livenessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.studio.livenessProbe.periodSeconds }} {{- end }} - imagePullSecrets: - - name: ghcrsecret - + restartPolicy: Always volumes: {{- if .Values.chartcontroller.addSecret }} @@ -196,3 +198,9 @@ spec: persistentVolumeClaim: claimName: {{ .Release.Name }}-{{ .Values.studio.media.storage.claimName }} {{ end }} + {{ if eq .Values.environment "local" }} + - hostPath: + path: {{ .Values.source_code_path }} + type: Directory + name: sourcecode + {{ end }} diff --git a/serve/values.yaml b/serve/values.yaml index 3c5cec7..335bfad 100644 --- a/serve/values.yaml +++ b/serve/values.yaml @@ -2,19 +2,27 @@ # Declare variables to be passed into STACKn templates. # REQUIREMENT: -# - set a storage class with ability to serve ReadWriteMany +# - set a storage class with ability to serve ReadWriteOnce # Name: storageClassName, and/or set anchor &śtorage_class # Description: Set a storage class for the resources that are reused for multi-mount-points in cluster. To reduce wasteful copying we allow to use the same dataset volume to be mounted multiple times. -# Default: microk8s-hostpath, use nfs-client for docker-for-desktop +# Default: microk8s-hostpath, use local-path for k3s/Rancher Desktop #Set global values to overide default +environment: "local" +source_code_path: "/Users/nikch187/Projects/sll/stackn" +# https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors +# for local development +storageClass: &storage_class local-path +#storage access mode +access_mode: &access_mode ReadWriteOnce + global: studio: superUser: "" ##these are currently not handled by stackn: default: admin superuserPassword: "" superuserEmail: "" ##these are currently not handled by stackn: default: admin@test.com existingSecret: "" - storageClass: "" + storageClass: *storage_class postgresql: auth: username: studio @@ -22,10 +30,9 @@ global: postgresPassword: "" database: studio existingSecret: "" - storageClass: - - + storageClass: *storage_class +namespace: default existingSecret: "" serviceAccount: create: true @@ -53,7 +60,8 @@ studio: replicas: 1 strategy: type: RollingUpdate - debug: false + # Only locally + debug: true init: true reset_db: false enable_project_extra_settings: false @@ -78,7 +86,7 @@ studio: replicas: 1 strategy: type: Recreate - image: ghcr.io/scilifelabdatacentre/stackn/serve-ingress:develop-20240326 + image: ghcr.io/scilifelabdatacentre/stackn/serve-ingress:develop-20240417 pullPolicy: IfNotPresent resources: limits: @@ -88,7 +96,7 @@ studio: cpu: "100m" memory: "256Mi" image: - repository: ghcr.io/scilifelabdatacentre/stackn/serve-studio:develop-20240326 + repository: ghcr.io/scilifelabdatacentre/stackn/serve-studio:develop-20240417 pullPolicy: IfNotPresent resources: limits: @@ -98,12 +106,12 @@ studio: cpu: "400m" memory: "2Gi" storage: - storageClass: "" + storageClass: *storage_class media: storage: - storageClass: "" + storageClass: *storage_class size: "5Gi" - accessModes: ReadWriteMany + accessModes: *access_mode claimName: studio-media mountStudio: false mount_path: /app/media/ @@ -122,13 +130,13 @@ studio: allowPrivilegeEscalation: false privileged: false readinessProbe: - enabled: true + enabled: false tcpSocket: port: 8080 initialDelaySeconds: 20 periodSeconds: 10 livenessProbe: - enabled: true + enabled: false tcpSocket: port: 8080 initialDelaySeconds: 20 @@ -154,13 +162,10 @@ studio: #kubernetes config kubeconfig: "" -#storage access mode -accessmode: ReadWriteMany - #the cluster domain name (default usually cluster.local) cluster_domain: cluster.local -# Enable ingress if you want your to access the studio solution from a kubernetes host/localhost. +# Enable ingress if you want to access the studio solution from a kubernetes host/localhost. domain: studio.127.0.0.1.nip.io session_cookie_domain: .127.0.0.1.nip.io ingress: @@ -195,8 +200,8 @@ postgresql: enabled: true size: "10Gi" accessModes: - - ReadWriteMany - storageClass: + - *access_mode + storageClass: *storage_class podLabels: {"app":"stackn-studio"} redis: @@ -215,21 +220,10 @@ rabbitmq: persistence: enabled: true - - -# Will be added in future realease, for now keep "enabled:false" +# Will be added in future release, for now keep "enabled:false" postgresql-ha: enabled: false -### DEPLOY SECRETS WITH private helm chart 'secrets' from platform/secrets -## Name: imagePullSecret -## Description: Secret to pull images from our private repository. -imagePullSecrets: - - name: regcred - -## to create a regcred -## kubectl create secret docker-registry regcred --docker-server= --docker-username= --docker-password= - celeryWorkers: replicas: 2 resources: @@ -258,6 +252,7 @@ docker-registry: enabled: false prometheus: +# Only locally enabled: false grafana: From e1774c43df0c3e926308fda02f1c51ab50dba91a Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Tue, 23 Jul 2024 11:47:23 +0200 Subject: [PATCH 02/12] settings config map is now sync with stackn repo --- .../templates/studio-settings-configmap.yaml | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/serve/templates/studio-settings-configmap.yaml b/serve/templates/studio-settings-configmap.yaml index 73f2a9a..35fc743 100644 --- a/serve/templates/studio-settings-configmap.yaml +++ b/serve/templates/studio-settings-configmap.yaml @@ -104,18 +104,16 @@ data: 'django_filters', 'django_structlog', 'tagulous', + "crispy_forms", + "crispy_bootstrap5", 'guardian', "portal", "projects", "models", - "monitor", "apps", "api", - "customtags", - "news", "axes", # django-axes for brute force login protection "django_password_validators", # django-password-validators for password validation - "collections_module", ] + DJANGO_WIKI_APPS {{ if .Values.studio.custom_apps.enabled }} @@ -177,6 +175,9 @@ data: # Main Url conf for loading all the routing path in Studio ROOT_URLCONF = 'studio.urls' + CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" + CRISPY_TEMPLATE_PACK = "bootstrap5" + # Tagulous serialization settings SERIALIZATION_MODULES = { 'xml': 'tagulous.serializers.xml_serializer', @@ -356,7 +357,7 @@ data: # Apps APPS_MODEL = "apps.Apps" - APPINSTANCE_MODEL = "apps.AppInstance" + APPINSTANCE_MODEL = "apps.BaseAppInstance" APPCATEGORIES_MODEL ="apps.AppCategories" # Models @@ -415,14 +416,11 @@ data: VERSION = {{ .Values.studio.version | quote }} MIGRATION_MODULES = { - 'apps': 'studio.migrations.apps', - 'models': 'studio.migrations.models', - 'monitor': 'studio.migrations.monitor', - 'portal': 'studio.migrations.portal', - 'projects': 'studio.migrations.projects', + "apps": "apps.migrations", + "models": "models.migrations", + "portal": "portal.migrations", + "projects": "projects.migrations", "common": "common.migrations", - "news": "news.migrations", - "collections_module": "collections_module.migrations", } {{ if .Values.studio.custom_migrations.enabled }} From fb08db8e76782abe666f493df1c02f4f8e8501d4 Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Tue, 23 Jul 2024 14:22:50 +0200 Subject: [PATCH 03/12] Delete all references of imagePullSecrets because we are not pulling images from any private registry --- apps/custom-app/templates/deployment.yaml | 4 ---- apps/custom-app/values.yaml | 3 --- apps/dash/templates/deployment.yaml | 4 ---- apps/dash/values.yaml | 3 --- apps/jupyter-lab/templates/deployment.yaml | 4 ---- apps/mlflow/chart/values.yaml | 3 --- apps/python-serve/chart/templates/deployment.yaml | 4 ---- apps/python-serve/chart/values.yaml | 3 --- apps/pytorch-serve/chart/values.yaml | 3 --- apps/rstudio/templates/deployment.yaml | 4 ---- apps/rstudio/values.yaml | 3 --- apps/shiny/templates/deployment.yaml | 4 ---- apps/shiny/values.yaml | 3 --- apps/tensorflow-serve/chart/values.yaml | 3 --- apps/tissuumaps/templates/deployment.yaml | 4 ---- apps/tissuumaps/values.yaml | 6 ------ apps/vscode/templates/deployment.yaml | 4 ---- apps/vscode/values.yaml | 3 --- serve/templates/studio-deployment.yaml | 8 ++++++++ serve/templates/studio-service.yaml | 5 +++++ 20 files changed, 13 insertions(+), 65 deletions(-) diff --git a/apps/custom-app/templates/deployment.yaml b/apps/custom-app/templates/deployment.yaml index e9a866a..8fdc69f 100644 --- a/apps/custom-app/templates/deployment.yaml +++ b/apps/custom-app/templates/deployment.yaml @@ -27,10 +27,6 @@ spec: type: app pod: {{ .Values.appname }} spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} automountServiceAccountToken: false securityContext: seccompProfile: diff --git a/apps/custom-app/values.yaml b/apps/custom-app/values.yaml index a3879e2..af6c814 100644 --- a/apps/custom-app/values.yaml +++ b/apps/custom-app/values.yaml @@ -22,9 +22,6 @@ service: name: customapp-svc port: 80 -imagePullSecrets: - - name: regcred - ingress: secretName: prod-ingress diff --git a/apps/dash/templates/deployment.yaml b/apps/dash/templates/deployment.yaml index dc5b8a9..b60716a 100644 --- a/apps/dash/templates/deployment.yaml +++ b/apps/dash/templates/deployment.yaml @@ -27,10 +27,6 @@ spec: type: app pod: {{ .Values.appname }} spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} automountServiceAccountToken: false securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} diff --git a/apps/dash/values.yaml b/apps/dash/values.yaml index e89640f..ffba171 100644 --- a/apps/dash/values.yaml +++ b/apps/dash/values.yaml @@ -18,9 +18,6 @@ service: name: dashapp-svc port: 80 -imagePullSecrets: - - name: regcred - ingress: secretName: prod-ingress diff --git a/apps/jupyter-lab/templates/deployment.yaml b/apps/jupyter-lab/templates/deployment.yaml index cce794a..51cc2aa 100644 --- a/apps/jupyter-lab/templates/deployment.yaml +++ b/apps/jupyter-lab/templates/deployment.yaml @@ -80,10 +80,6 @@ spec: - name: {{ $key }} mountPath: /home/jovyan/work/{{ $key }} {{- end }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirst volumes: diff --git a/apps/mlflow/chart/values.yaml b/apps/mlflow/chart/values.yaml index 97fad01..a8a2e45 100644 --- a/apps/mlflow/chart/values.yaml +++ b/apps/mlflow/chart/values.yaml @@ -22,9 +22,6 @@ s3: service: port: -imagePullSecrets: - - name: regcred - ingress: v1beta1: false secretName: prod-ingress diff --git a/apps/python-serve/chart/templates/deployment.yaml b/apps/python-serve/chart/templates/deployment.yaml index f35e023..33871ff 100644 --- a/apps/python-serve/chart/templates/deployment.yaml +++ b/apps/python-serve/chart/templates/deployment.yaml @@ -27,10 +27,6 @@ spec: type: app pod: {{ .Values.appname }} spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} automountServiceAccountToken: false securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} diff --git a/apps/python-serve/chart/values.yaml b/apps/python-serve/chart/values.yaml index fbabd29..b7fe70f 100644 --- a/apps/python-serve/chart/values.yaml +++ b/apps/python-serve/chart/values.yaml @@ -16,9 +16,6 @@ appconfig: service: name: pythonserve-svc -imagePullSecrets: - - name: regcred - ingress: secretName: prod-ingress diff --git a/apps/pytorch-serve/chart/values.yaml b/apps/pytorch-serve/chart/values.yaml index 033bdfc..b42757b 100644 --- a/apps/pytorch-serve/chart/values.yaml +++ b/apps/pytorch-serve/chart/values.yaml @@ -42,9 +42,6 @@ model_card: enabled: false path: model-card -imagePullSecrets: - - name: regcred - ingress: podSecurityContext: diff --git a/apps/rstudio/templates/deployment.yaml b/apps/rstudio/templates/deployment.yaml index e07895e..6dee4f5 100644 --- a/apps/rstudio/templates/deployment.yaml +++ b/apps/rstudio/templates/deployment.yaml @@ -27,10 +27,6 @@ spec: type: app pod: {{ .Values.appname }} spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} automountServiceAccountToken: false securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} diff --git a/apps/rstudio/values.yaml b/apps/rstudio/values.yaml index e3beb34..7e58bbb 100644 --- a/apps/rstudio/values.yaml +++ b/apps/rstudio/values.yaml @@ -19,9 +19,6 @@ service: name: rstudio-svc port: 80 -imagePullSecrets: - - name: regcred - ingress: v1beta1: false secretName: prod-ingress diff --git a/apps/shiny/templates/deployment.yaml b/apps/shiny/templates/deployment.yaml index 9634070..548720e 100644 --- a/apps/shiny/templates/deployment.yaml +++ b/apps/shiny/templates/deployment.yaml @@ -27,10 +27,6 @@ spec: type: app pod: {{ .Values.appname }} spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} automountServiceAccountToken: false securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} diff --git a/apps/shiny/values.yaml b/apps/shiny/values.yaml index 49a507c..7edac64 100644 --- a/apps/shiny/values.yaml +++ b/apps/shiny/values.yaml @@ -19,9 +19,6 @@ service: name: shiny-svc port: 80 -imagePullSecrets: - - name: regcred - ingress: secretName: prod-ingress diff --git a/apps/tensorflow-serve/chart/values.yaml b/apps/tensorflow-serve/chart/values.yaml index 87fb906..a8cdf5b 100644 --- a/apps/tensorflow-serve/chart/values.yaml +++ b/apps/tensorflow-serve/chart/values.yaml @@ -40,9 +40,6 @@ model_card: enabled: false path: model-card -imagePullSecrets: - - name: regcred - ingress: podSecurityContext: diff --git a/apps/tissuumaps/templates/deployment.yaml b/apps/tissuumaps/templates/deployment.yaml index 80ab621..099d012 100644 --- a/apps/tissuumaps/templates/deployment.yaml +++ b/apps/tissuumaps/templates/deployment.yaml @@ -27,10 +27,6 @@ spec: type: app pod: {{ .Values.appname }} spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} automountServiceAccountToken: false securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} diff --git a/apps/tissuumaps/values.yaml b/apps/tissuumaps/values.yaml index d84c914..6426839 100644 --- a/apps/tissuumaps/values.yaml +++ b/apps/tissuumaps/values.yaml @@ -21,12 +21,6 @@ service: targetport: 80 port: 80 -imagePullSecrets: - - name: regcred - -ingress: - secretName: prod-ingress - podSecurityContext: seccompProfile: type: RuntimeDefault diff --git a/apps/vscode/templates/deployment.yaml b/apps/vscode/templates/deployment.yaml index 3b4da30..44dd343 100644 --- a/apps/vscode/templates/deployment.yaml +++ b/apps/vscode/templates/deployment.yaml @@ -31,10 +31,6 @@ spec: affinity: {{ .Values.affinity | toYaml | nindent 8 | trim }} {{ end }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} automountServiceAccountToken: false securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} diff --git a/apps/vscode/values.yaml b/apps/vscode/values.yaml index ba8e539..8dc9297 100644 --- a/apps/vscode/values.yaml +++ b/apps/vscode/values.yaml @@ -30,9 +30,6 @@ service: port: 80 targetport: 8080 -imagePullSecrets: - - name: regcred - ingress: v1beta1: false secretName: prod-ingress diff --git a/serve/templates/studio-deployment.yaml b/serve/templates/studio-deployment.yaml index 02a0a0d..e8eda3e 100644 --- a/serve/templates/studio-deployment.yaml +++ b/serve/templates/studio-deployment.yaml @@ -54,9 +54,17 @@ spec: containers: - args: - sh + {{ if eq .Values.environment "local" }} + - -c + - "/usr/sbin/sshd -D" + {{ else }} - scripts/run_web.sh + {{ end }} ports: - containerPort: 8080 + {{- if eq .Values.environment "local" }} + - containerPort: 22 + {{- end }} env: - name: DEBUG {{- if .Values.studio.debug }} diff --git a/serve/templates/studio-service.yaml b/serve/templates/studio-service.yaml index 39c2e8b..7c672ab 100644 --- a/serve/templates/studio-service.yaml +++ b/serve/templates/studio-service.yaml @@ -7,6 +7,11 @@ spec: - name: "8080" port: 8080 targetPort: 8080 + {{- if eq .Values.environment "local" }} + - name: ssh + port: 22 + targetPort: 22 + {{- end }} selector: name: {{ .Release.Name }}-{{ .Values.studio.servicename }} status: From 44aae8e655058d11582da0496f6468e7c4fc4a60 Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Tue, 23 Jul 2024 16:08:34 +0200 Subject: [PATCH 04/12] Update values.yaml to reflect new way of local deployment --- serve/values.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/serve/values.yaml b/serve/values.yaml index 335bfad..6a3a7cc 100644 --- a/serve/values.yaml +++ b/serve/values.yaml @@ -8,13 +8,14 @@ # Default: microk8s-hostpath, use local-path for k3s/Rancher Desktop #Set global values to overide default -environment: "local" -source_code_path: "/Users/nikch187/Projects/sll/stackn" -# https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors -# for local development -storageClass: &storage_class local-path +environment: "remote" +# Template for remote development +# Storage class used by the KTH cluster +storageClass: &storage_class ontap-nas +#storageClass: &storage_class local-path #storage access mode -access_mode: &access_mode ReadWriteOnce +access_mode: &access_mode ReadWriteMany +#access_mode: &access_mode ReadWriteOnce global: studio: @@ -60,8 +61,7 @@ studio: replicas: 1 strategy: type: RollingUpdate - # Only locally - debug: true + debug: false init: true reset_db: false enable_project_extra_settings: false @@ -95,7 +95,7 @@ studio: requests: cpu: "100m" memory: "256Mi" - image: + image: repository: ghcr.io/scilifelabdatacentre/stackn/serve-studio:develop-20240417 pullPolicy: IfNotPresent resources: @@ -130,13 +130,13 @@ studio: allowPrivilegeEscalation: false privileged: false readinessProbe: - enabled: false + enabled: true tcpSocket: port: 8080 initialDelaySeconds: 20 periodSeconds: 10 livenessProbe: - enabled: false + enabled: true tcpSocket: port: 8080 initialDelaySeconds: 20 @@ -162,6 +162,7 @@ studio: #kubernetes config kubeconfig: "" +accessmode: *access_mode #the cluster domain name (default usually cluster.local) cluster_domain: cluster.local @@ -252,7 +253,6 @@ docker-registry: enabled: false prometheus: -# Only locally enabled: false grafana: From 82ee076519def6c86c4fa004e39045da4605da4e Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Tue, 23 Jul 2024 16:10:38 +0200 Subject: [PATCH 05/12] UPD README.md --- README.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 344d54d..75cff05 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,72 @@ git clone https://github.com/ScilifelabDataCentre/serve-charts.git Then navigate to the `serve-charts/serve` folder, and run +If you want to run this locally, override values the following way: + +```yaml +environment: "local" +# Path will be mounted using rancher desktop to the /app path in the container +source_code_path: "/Users/nikch187/Projects/sll/stackn" +# https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors +# for local development +storageClass: &storage_class local-path +#storage access mode +access_mode: &access_mode ReadWriteOnce +accessmode: *access_mode + +global: + studio: + superuserPassword: "Test@12345" + superuserEmail: "admin@sll.se" + storageClass: *storage_class + postgresql: + storageClass: *storage_class + +studio: + # Only locally on a debug environment + debug: true + storage: + storageClass: *storage_class + media: + storage: + storageClass: *storage_class + accessModes: *access_mode + + # We use pull policy Never because see the following link: + # https://github.com/rancher-sandbox/rancher-desktop/issues/952#issuecomment-993135128 + static: + image: mystudio + pullPolicy: Never + + image: + repository: mystudio + pullPolicy: Never + + securityContext: + # Disables security context for local development + # Essentially allow the container to run as root + enabled: false + + readinessProbe: + enabled: false + + livenessProbe: + enabled: false + +postgresql: + primary: + persistence: + storageClass: *storage_class + accessModes: + - *access_mode + +``` + +And then run the following commands: + ``` helm dependency update -helm install serve . +helm install serve . -f values.yaml -f values-local.yaml ``` Depending on your storageclass, you might have to set this aswell. From fcc44b721d01320303b3893b6c84fc0ae8d6a0d3 Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Wed, 24 Jul 2024 15:47:37 +0200 Subject: [PATCH 06/12] UPD README.md. Added information on how to setup charts repo and rancher desktop locally --- README.md | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 245 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 75cff05..9185641 100644 --- a/README.md +++ b/README.md @@ -9,16 +9,135 @@ This repository contains Helm charts for SciLifeLab Serve. It is based on the o If you are using SciLifeLab Serve and notice a bug or if there is a feature you would like to be added feel free to [create an issue](https://github.com/ScilifelabDataCentre/stackn/issues/new/choose) with a bug report or feature request. ## How to deploy + +### Prerequisites + +- A Kubernetes cluster version **1.28.6** +- Helm 3 +- A storage class for dynamic provisioning of persistent volumes + +If you are going to run this on a remote cluster, then you probably don't need to think about this +as these things will be provided by your cloud provider. + +But in case of a local deployment, navigate to the next section. + +#### Setup for local deployment + +If you are going to run this locally, you need to have a Kubernetes cluster running on your machine. +You can use [Rancher Desktop](https://rancherdesktop.io/) for this purpose. + +Follow their instruction to install Rancher Desktop, and then start it. + +Recommended settings for Rancher Desktop: +- `Preferences > Kubernetes` select kubernetes version `1.28.6`. +- `Preferences > Container Engine` select `containerd` as the container engine. +- `Preferences > Virtual Machine > Emulation` select `QEMU` + - If you are running on an M3 Mac select `VZ` +- `Preferences > Virtual Machine > Hardware` select `4 CPUs` and `16 GB` of memory. + +##### Stackn image + +By default, the image is pulled from the public registry. This image is the one we are using in production. +So you don't need to build the image yourself if you want to just try it out locally. + +But if you want to develop, you need to build the image yourself. + +**Building image for Rancher Desktop** + +Rancher Desktop brings a number of tools when you install it. +One of them is `nerdctl` which is a drop-in replacement for `docker` and `docker-compose`. + +Rancher Desktop also brings a local registry that you can use to push images to. +And this registry can be accessed from your Kubernetes cluster and used as if you were using docker. + +See [Stackn](https://github.com/ScilifelabDataCentre/stackn/) repository for up-to-date instructions on +how to build the image for local development. + +But this setup expects that you have an image tagged `mystudio` built using `nerdctl` and pushed to the `k8s.io` namespace. + +### Deploying + +> Using the following you'll make sure that your Rancher Desktop installation is working as expected using the default settings. +> These instructions are almost the same as the ones you would use for a remote cluster except for the storage class. +> If it doesn't work you should debug your installation and contact team members for help. + +**Outcomes of this section** +- You'll prepare your environment for the proper local deployment of Serve; +- Running instance of Serve on your local machine available on [http://studio.127.0.0.1.nip.io/](http://studio.127.0.0.1.nip.io/). + + + First, clone this repository + +```bash +$ git clone https://github.com/ScilifelabDataCentre/serve-charts.git ``` -git clone https://github.com/ScilifelabDataCentre/serve-charts.git + +Then navigate to the `serve-charts/serve` folder + +```bash +$ cd serve-charts/serve ``` -Then navigate to the `serve-charts/serve` folder, and run +Now you need to create an override file for the `values.yaml` file. -If you want to run this locally, override values the following way: +Create a file called `values-local.yaml` and add the following content: -```yaml +```yaml filename="values-local.yaml" +# https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors +# for local development +storageClass: &storage_class local-path +#storage access mode +access_mode: &access_mode ReadWriteOnce +accessmode: *access_mode + +global: + studio: + superuserPassword: "Test@12345" + superuserEmail: "admin@sll.se" + storageClass: *storage_class + postgresql: + storageClass: *storage_class + +studio: + # Only locally on a debug environment + debug: true + storage: + storageClass: *storage_class + media: + storage: + storageClass: *storage_class + accessModes: *access_mode + +postgresql: + primary: + persistence: + storageClass: *storage_class + accessModes: + - *access_mode +``` + +This is necessary because the default values are set for a production environment. Specifically, the storage class +has to change because the default storage class is not available in a Rancher Desktop environment. + +```bash +$ helm dependency update +# The following command will install the chart with the values from values.yaml and values-local.yaml +# values-local.yaml will override the values from values.yaml +$ helm install serve . -f values.yaml -f values-local.yaml +``` + +As a result you should have a running instance of Serve on your local machine available on [http://studio.127.0.0.1.nip.io/](http://studio.127.0.0.1.nip.io/). + +#### Swapping default docker image with the one built locally + +
+ TJ;DR Just commands + + ```bash + $ git clone https://github.com/ScilifelabDataCentre/serve-charts.git + $ cd serve-charts/serve + $ cat < values-local.yaml environment: "local" # Path will be mounted using rancher desktop to the /app path in the container source_code_path: "/Users/nikch187/Projects/sll/stackn" @@ -73,29 +192,138 @@ postgresql: persistence: storageClass: *storage_class accessModes: - - *access_mode + - *access_mode + EOF + $ helm upgrade serve . -f values.yaml -f values-local.yaml + ``` +
-``` +**Outcomes of this section:** +- Instead of a Django server, you'll have an ssh server running for the [PyCharm setup](TODO: link); +- You'll have a host machine's folder with the [Stackn](https://github.com/ScilifelabDataCentre/stackn/) code mounted to the container; -And then run the following commands: +Now that everything is running, you can swap the default image with the one you built locally. +> See the [Stackn image section](#stackn-image) for instructions on how to build the image. + +Go back to the `values-local.yaml` file update it with the following content: + +```yaml filename="values-local.yaml" +environment: "local" + +# Path will be mounted using rancher desktop to the /app path in the container +source_code_path: "/absolute/path/to/your/stackn" +# https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors +# ... +studio: + # Append the following to the end of the studio section + + # We use pull policy Never because see the following link: + # https://github.com/rancher-sandbox/rancher-desktop/issues/952#issuecomment-993135128 + static: + image: mystudio + pullPolicy: Never + + image: + repository: mystudio + pullPolicy: Never + + securityContext: + # Disables security context for local development + # Essentially allow the container to run as root + enabled: false + + readinessProbe: + enabled: false + + livenessProbe: + enabled: false ``` -helm dependency update -helm install serve . -f values.yaml -f values-local.yaml -``` -Depending on your storageclass, you might have to set this aswell. -For instance, if you use `microk8s`, them you run +
+ Full content of the values-local.yaml file + +```yaml + environment: "local" + # Path will be mounted using rancher desktop to the /app path in the container + source_code_path: "/Users/nikch187/Projects/sll/stackn" + # https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors + # for local development + storageClass: &storage_class local-path + #storage access mode + access_mode: &access_mode ReadWriteOnce + accessmode: *access_mode + + global: + studio: + superuserPassword: "Test@12345" + superuserEmail: "admin@sll.se" + storageClass: *storage_class + postgresql: + storageClass: *storage_class + + studio: + # Only locally on a debug environment + debug: true + storage: + storageClass: *storage_class + media: + storage: + storageClass: *storage_class + accessModes: *access_mode + + # We use pull policy Never because see the following link: + # https://github.com/rancher-sandbox/rancher-desktop/issues/952#issuecomment-993135128 + static: + image: mystudio + pullPolicy: Never + + image: + repository: mystudio + pullPolicy: Never + + securityContext: + # Disables security context for local development + # Essentially allow the container to run as root + enabled: false + + readinessProbe: + enabled: false + + livenessProbe: + enabled: false + + postgresql: + primary: + persistence: + storageClass: *storage_class + accessModes: + - *access_mode + ``` + +
+ +After doing this run the following command to upgrade the deployment: +```bash +helm upgrade serve . -f values.yaml -f values-local.yaml ``` -helm install --set global.postgresql.storageClass=microk8s-hostpath serve . + +Now you can proceed to set up PyCharm. + +If you don't want to set up PyCharm, you can just run Django from the container. + +```bash +$ kubectl get po +# Get the name of the studio pod +$ kubectl exec -it -- /bin/bash +# Now you are inside the container +$ sh scripts/run_web.sh ``` -All resources will by default be created in the default namespace. -Serve will be avaliable at https://studio.127.0.0.1.nip.io -Obs that you might have to make changes to your particular ingress controller (nginx is supported in this chart) to connect to the URL. -If the ingress does not work for any reason, you can try to port-forward the studio service port to your localhost. +Please note, that the folder you are in, `/app`, is the folder where the code is mounted. +It means that you can make changes to the code on your host machine and see the changes in the container. ## Deploy an SSL certificate From 0e00ada91e662b3a9601cf2751d3c4d0fd301605 Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Thu, 25 Jul 2024 14:46:15 +0200 Subject: [PATCH 07/12] UPD README.md added links to stackn sections in README with how to set up environment --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9185641..d4b8b85 100644 --- a/README.md +++ b/README.md @@ -199,12 +199,12 @@ postgresql: **Outcomes of this section:** -- Instead of a Django server, you'll have an ssh server running for the [PyCharm setup](TODO: link); +- Instead of a Django server, you'll have an ssh server running for the [PyCharm setup](https://github.com/ScilifelabDataCentre/stackn/?tab=readme-ov-file#deploy-serve-for-local-development-with-rancher-desktop) - You'll have a host machine's folder with the [Stackn](https://github.com/ScilifelabDataCentre/stackn/) code mounted to the container; Now that everything is running, you can swap the default image with the one you built locally. -> See the [Stackn image section](#stackn-image) for instructions on how to build the image. +> See the [Stackn image section](https://github.com/ScilifelabDataCentre/stackn/?tab=readme-ov-file#deploy-serve-for-local-development-with-rancher-desktop) for instructions on how to build the image. Go back to the `values-local.yaml` file update it with the following content: @@ -309,7 +309,7 @@ After doing this run the following command to upgrade the deployment: helm upgrade serve . -f values.yaml -f values-local.yaml ``` -Now you can proceed to set up PyCharm. +Now you can proceed to [set up PyCharm](https://github.com/ScilifelabDataCentre/stackn?tab=readme-ov-file#pycharm-setup) If you don't want to set up PyCharm, you can just run Django from the container. From 9dfd5c32228266081170011e85e3ff587f5d226a Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Tue, 3 Sep 2024 16:43:17 +0200 Subject: [PATCH 08/12] DEL duplicate crispy dependencies from studio settings config map Rename `stackn` to `serve` --- README.md | 22 +++++++++---------- .../templates/studio-settings-configmap.yaml | 2 -- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 7ef4c6c..fc9c470 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Recommended settings for Rancher Desktop: - If you are running on an M3 Mac select `VZ` - `Preferences > Virtual Machine > Hardware` select `4 CPUs` and `16 GB` of memory. -##### Stackn image +##### Serve image By default, the image is pulled from the public registry. This image is the one we are using in production. So you don't need to build the image yourself if you want to just try it out locally. @@ -50,7 +50,7 @@ One of them is `nerdctl` which is a drop-in replacement for `docker` and `docker Rancher Desktop also brings a local registry that you can use to push images to. And this registry can be accessed from your Kubernetes cluster and used as if you were using docker. -See [Stackn](https://github.com/ScilifelabDataCentre/stackn/) repository for up-to-date instructions on +See [Serve](https://github.com/ScilifelabDataCentre/serve/) repository for up-to-date instructions on how to build the image for local development. But this setup expects that you have an image tagged `mystudio` built using `nerdctl` and pushed to the `k8s.io` namespace. @@ -140,7 +140,7 @@ As a result you should have a running instance of Serve on your local machine av $ cat < values-local.yaml environment: "local" # Path will be mounted using rancher desktop to the /app path in the container -source_code_path: "/Users/nikch187/Projects/sll/stackn" +source_code_path: "/Users/nikch187/Projects/sll/serve" # https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors # for local development storageClass: &storage_class local-path @@ -199,12 +199,12 @@ postgresql: **Outcomes of this section:** -- Instead of a Django server, you'll have an ssh server running for the [PyCharm setup](https://github.com/ScilifelabDataCentre/stackn/?tab=readme-ov-file#deploy-serve-for-local-development-with-rancher-desktop) -- You'll have a host machine's folder with the [Stackn](https://github.com/ScilifelabDataCentre/stackn/) code mounted to the container; +- Instead of a Django server, you'll have an ssh server running for the [PyCharm setup](https://github.com/ScilifelabDataCentre/serve/?tab=readme-ov-file#deploy-serve-for-local-development-with-rancher-desktop) +- You'll have a host machine's folder with the [Serve](https://github.com/ScilifelabDataCentre/serve/) code mounted to the container; Now that everything is running, you can swap the default image with the one you built locally. -> See the [Stackn image section](https://github.com/ScilifelabDataCentre/stackn/?tab=readme-ov-file#deploy-serve-for-local-development-with-rancher-desktop) for instructions on how to build the image. +> See the [Serve image section](https://github.com/ScilifelabDataCentre/serve/?tab=readme-ov-file#deploy-serve-for-local-development-with-rancher-desktop) for instructions on how to build the image. Go back to the `values-local.yaml` file update it with the following content: @@ -212,7 +212,7 @@ Go back to the `values-local.yaml` file update it with the following content: environment: "local" # Path will be mounted using rancher desktop to the /app path in the container -source_code_path: "/absolute/path/to/your/stackn" +source_code_path: "/absolute/path/to/your/serve" # https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors # ... studio: @@ -246,7 +246,7 @@ studio: ```yaml environment: "local" # Path will be mounted using rancher desktop to the /app path in the container - source_code_path: "/Users/nikch187/Projects/sll/stackn" + source_code_path: "/Users/nikch187/Projects/sll/serve" # https://helm.sh/docs/chart_template_guide/yaml_techniques/#yaml-anchors # for local development storageClass: &storage_class local-path @@ -309,7 +309,7 @@ After doing this run the following command to upgrade the deployment: helm upgrade serve . -f values.yaml -f values-local.yaml ``` -Now you can proceed to [set up PyCharm](https://github.com/ScilifelabDataCentre/stackn?tab=readme-ov-file#pycharm-setup) +Now you can proceed to [set up PyCharm](https://github.com/ScilifelabDataCentre/serve?tab=readme-ov-file#pycharm-setup) If you don't want to set up PyCharm, you can just run Django from the container. @@ -375,10 +375,10 @@ studio: inactive_users: false #Users that sign-up can be inactive by default if desired csrf_trusted_origins: "https://studio.127.0.0.1.nip.io:8082" #extra trusted origin for django server, for example if you port-forward to port 8082 image: # using a local image registry with hostname k3d-registry - repository: k3d-registry:35187/stackn:develop #This image can be built from Dockerfile (https://github.com/scaleoutsystems/stackn) + repository: k3d-registry:35187/serve:develop #This image can be built from Dockerfile (https://github.com/scaleoutsystems/serve) pullPolicy: Always # used to ensure that each time we redeploy always pull the latest image static: - image: k3d-registry:35187/stackn-nginx:develop #This image can be built from Dockerfile.nginx (https://github.com/scaleoutsystems/stackn) + image: k3d-registry:35187/serve-nginx:develop #This image can be built from Dockerfile.nginx (https://github.com/scaleoutsystems/serve) media: storage: accessModes: ReadWriteOnce diff --git a/serve/templates/studio-settings-configmap.yaml b/serve/templates/studio-settings-configmap.yaml index a9b0ae8..50a4f53 100644 --- a/serve/templates/studio-settings-configmap.yaml +++ b/serve/templates/studio-settings-configmap.yaml @@ -104,8 +104,6 @@ data: 'django_filters', 'django_structlog', 'tagulous', - "crispy_forms", - "crispy_bootstrap5", 'guardian', "crispy_forms", "crispy_bootstrap5", From ef79a2b8666ede181234e8e5a9c4241fccb96e92 Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Tue, 3 Sep 2024 16:47:32 +0200 Subject: [PATCH 09/12] return secret for ingress to tissuumaps/values.yaml --- apps/tissuumaps/values.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/tissuumaps/values.yaml b/apps/tissuumaps/values.yaml index 6426839..1229e3e 100644 --- a/apps/tissuumaps/values.yaml +++ b/apps/tissuumaps/values.yaml @@ -21,6 +21,9 @@ service: targetport: 80 port: 80 +ingress: + secretName: prod-ingress + podSecurityContext: seccompProfile: type: RuntimeDefault From d59320695aed64f99072d4d057c9d168dab224d8 Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Tue, 3 Sep 2024 17:23:29 +0200 Subject: [PATCH 10/12] change ReadWriteOnce to ReadWriteMany fo volumesk8s --- apps/volumek8s/values.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/volumek8s/values.yaml b/apps/volumek8s/values.yaml index a5a4776..903c335 100644 --- a/apps/volumek8s/values.yaml +++ b/apps/volumek8s/values.yaml @@ -1,7 +1,7 @@ # locally -accessModes: ReadWriteOnce +#accessModes: ReadWriteOnce # remote -# accessModes: ReadWriteMany + accessModes: ReadWriteMany storageClass: default appname: volumek8s @@ -13,6 +13,6 @@ volume: size: 10Mi storageClass: false # locally - accessModes: ReadWriteOnce +# accessModes: ReadWriteOnce # remote -# accessModes: ReadWriteMany \ No newline at end of file + accessModes: ReadWriteMany \ No newline at end of file From 5bd9739371f2fa2e63af85e9b4006e8f1e89225e Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Tue, 3 Sep 2024 17:26:34 +0200 Subject: [PATCH 11/12] Fix indent errors --- apps/volumek8s/values.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/volumek8s/values.yaml b/apps/volumek8s/values.yaml index 903c335..68896a8 100644 --- a/apps/volumek8s/values.yaml +++ b/apps/volumek8s/values.yaml @@ -1,7 +1,7 @@ # locally -#accessModes: ReadWriteOnce +# accessModes: ReadWriteOnce # remote - accessModes: ReadWriteMany +accessModes: ReadWriteMany storageClass: default appname: volumek8s @@ -13,6 +13,6 @@ volume: size: 10Mi storageClass: false # locally -# accessModes: ReadWriteOnce +# accessModes: ReadWriteOnce # remote accessModes: ReadWriteMany \ No newline at end of file From 61422c30dc409c61a1a24328bf15b092da3cd283 Mon Sep 17 00:00:00 2001 From: Nikita Churikov Date: Wed, 25 Sep 2024 17:42:09 +0200 Subject: [PATCH 12/12] Fix linting --- apps/volumek8s/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/volumek8s/values.yaml b/apps/volumek8s/values.yaml index 68896a8..3474e0c 100644 --- a/apps/volumek8s/values.yaml +++ b/apps/volumek8s/values.yaml @@ -15,4 +15,4 @@ volume: # locally # accessModes: ReadWriteOnce # remote - accessModes: ReadWriteMany \ No newline at end of file + accessModes: ReadWriteMany