From aee5c8aa2b67e45c61d5e0e1c8909d4fa54a1283 Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 22 Jun 2026 16:59:04 -0400 Subject: [PATCH 1/9] fix(lightspeed): pre-create /rag-content/vector_db/notebooks in init container On EKS/AKS, the RAG init container populates /rag-content/ but never creates the notebooks subdirectory. At runtime, llama-stack tries to write /rag-content/vector_db/notebooks/faiss_store.db and fails with PermissionError because it cannot create the directory on a volume it doesn't own. OCP avoids this via fsGroup/supplemental group defaults. The fix pre-creates the directory and widens permissions before the sidecar starts, matching the fix the operator already applies via chmod -R 777 for the rest of vector_db. Fixes: RHDHBUGS-3371 Co-Authored-By: Claude Sonnet 4.6 (1M context) --- charts/backstage/values.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/charts/backstage/values.yaml b/charts/backstage/values.yaml index b4e46c39..863cfe39 100644 --- a/charts/backstage/values.yaml +++ b/charts/backstage/values.yaml @@ -137,6 +137,8 @@ global: echo 'Copying Lightspeed RAG data...' && cp -r /rag/vector_db /rag-content/ && cp -r /rag/embeddings_model /rag-content/ && + mkdir -p /rag-content/vector_db/notebooks && + chmod -R a+rwX /rag-content && echo 'Copy complete.' env: [] # -- Resource requests/limits for the Lightspeed RAG bootstrap init container. From d500e6bc2c2c32f35b0a7d8393e0521d96c8cb29 Mon Sep 17 00:00:00 2001 From: Lucas Yoon <94267691+JslYoon@users.noreply.github.com> Date: Tue, 23 Jun 2026 13:20:29 -0400 Subject: [PATCH 2/9] Update charts/backstage/values.yaml Co-authored-by: Jordan Dubrick --- charts/backstage/values.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/charts/backstage/values.yaml b/charts/backstage/values.yaml index 863cfe39..5f54fe57 100644 --- a/charts/backstage/values.yaml +++ b/charts/backstage/values.yaml @@ -194,7 +194,14 @@ upstream: registry: quay.io repository: rhdh-community/rhdh tag: next-1.10 - pullPolicy: "" +backstage: + image: + registry: quay.io + repository: rhdh-community/rhdh + tag: next-1.10 + pullPolicy: "" + podSecurityContext: + fsGroup: 1001 command: [] # FIXME (tumido): USE POSTGRES_PASSWORD and POSTGRES_USER instead of POSTGRES_ADMIN_PASSWORD # This is a hack. In {fedora,rhel}/postgresql images, regular user is forbidden From f65c857cfd4f16a0d99e97776816cdb9bf71223a Mon Sep 17 00:00:00 2001 From: Lucas Yoon <94267691+JslYoon@users.noreply.github.com> Date: Tue, 23 Jun 2026 13:20:38 -0400 Subject: [PATCH 3/9] Update charts/backstage/values.yaml Co-authored-by: Jordan Dubrick --- charts/backstage/values.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/charts/backstage/values.yaml b/charts/backstage/values.yaml index 5f54fe57..67441c1b 100644 --- a/charts/backstage/values.yaml +++ b/charts/backstage/values.yaml @@ -139,7 +139,11 @@ global: cp -r /rag/embeddings_model /rag-content/ && mkdir -p /rag-content/vector_db/notebooks && chmod -R a+rwX /rag-content && - echo 'Copy complete.' + mkdir -p /tmp/data && + echo 'Copying Lightspeed RAG data...' && + cp -r --no-preserve=mode,ownership /rag/vector_db /rag-content/ && + cp -r --no-preserve=mode,ownership /rag/embeddings_model /rag-content/ && + echo 'Copy complete.' env: [] # -- Resource requests/limits for the Lightspeed RAG bootstrap init container. resources: From 0caaa25359e0d12337d7d759b7fab04ba20e8065 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 23 Jun 2026 13:43:49 -0400 Subject: [PATCH 4/9] fix duplication and lint Signed-off-by: Lucas --- charts/backstage/values.yaml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/charts/backstage/values.yaml b/charts/backstage/values.yaml index 67441c1b..3088f1bb 100644 --- a/charts/backstage/values.yaml +++ b/charts/backstage/values.yaml @@ -135,15 +135,11 @@ global: - >- mkdir -p /tmp/data && echo 'Copying Lightspeed RAG data...' && - cp -r /rag/vector_db /rag-content/ && - cp -r /rag/embeddings_model /rag-content/ && + cp -r --no-preserve=mode,ownership /rag/vector_db /rag-content/ && + cp -r --no-preserve=mode,ownership /rag/embeddings_model /rag-content/ && mkdir -p /rag-content/vector_db/notebooks && chmod -R a+rwX /rag-content && - mkdir -p /tmp/data && - echo 'Copying Lightspeed RAG data...' && - cp -r --no-preserve=mode,ownership /rag/vector_db /rag-content/ && - cp -r --no-preserve=mode,ownership /rag/embeddings_model /rag-content/ && - echo 'Copy complete.' + echo 'Copy complete.' env: [] # -- Resource requests/limits for the Lightspeed RAG bootstrap init container. resources: @@ -205,6 +201,7 @@ backstage: tag: next-1.10 pullPolicy: "" podSecurityContext: + enabled: false fsGroup: 1001 command: [] # FIXME (tumido): USE POSTGRES_PASSWORD and POSTGRES_USER instead of POSTGRES_ADMIN_PASSWORD From 810aab8fafcc130939b2fc7f254ad5d3d4ca05c5 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 23 Jun 2026 13:51:43 -0400 Subject: [PATCH 5/9] chore(backstage): bump chart to 5.12.5, regenerate schema and docs Signed-off-by: Lucas --- charts/backstage/Chart.yaml | 2 +- charts/backstage/README.md | 167 +++++++++++- charts/backstage/values.schema.json | 240 ++---------------- charts/must-gather/README.md | 13 +- charts/orchestrator-infra/README.md | 2 +- .../README.md | 2 +- .../orchestrator-software-templates/README.md | 2 +- 7 files changed, 185 insertions(+), 243 deletions(-) diff --git a/charts/backstage/Chart.yaml b/charts/backstage/Chart.yaml index 0d602ef9..4b29d297 100644 --- a/charts/backstage/Chart.yaml +++ b/charts/backstage/Chart.yaml @@ -47,4 +47,4 @@ sources: [] # Versions are expected to follow Semantic Versioning (https://semver.org/) # Note that when this chart is published to https://github.com/openshift-helm-charts/charts # it will follow the RHDH versioning 1.y.z -version: 5.12.4 +version: 5.12.5 diff --git a/charts/backstage/README.md b/charts/backstage/README.md index ec6fbe1a..ad387a1c 100644 --- a/charts/backstage/README.md +++ b/charts/backstage/README.md @@ -1,7 +1,7 @@ # RHDH Backstage Helm Chart for OpenShift -![Version: 5.12.4](https://img.shields.io/badge/Version-5.12.4-informational?style=flat-square) +![Version: 5.12.5](https://img.shields.io/badge/Version-5.12.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) A Helm chart for deploying Red Hat Developer Hub, which is a Red Hat supported version of Backstage. @@ -21,7 +21,7 @@ For the **Generally Available** version of this chart, see: | Name | Email | Url | | ---- | ------ | --- | -| Red Hat | | | +| Red Hat | | https://redhat.com | ## TL;DR @@ -29,7 +29,7 @@ For the **Generally Available** version of this chart, see: helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add redhat-developer https://redhat-developer.github.io/rhdh-chart -helm install my-backstage redhat-developer/backstage --version 5.12.4 +helm install my-backstage redhat-developer/backstage --version 5.12.5 ``` ## Introduction @@ -156,13 +156,168 @@ Kubernetes: `>= 1.27.0-0` | Repository | Name | Version | |------------|------|---------| -| file://./vendor/backstage/charts/backstage/ | upstream(backstage) | 2.7.0 | +| file://./vendor/backstage/charts/backstage/ | backstage | 2.7.0 | | https://charts.bitnami.com/bitnami | common | 2.39.0 | ## Values | Key | Description | Type | Default | |-----|-------------|------|---------| +| backstage.image.pullPolicy | | string | `""` | +| backstage.image.registry | | string | `"quay.io"` | +| backstage.image.repository | | string | `"rhdh-community/rhdh"` | +| backstage.image.tag | | string | `"next-1.10"` | +| backstage.ingress.host | | string | `"{{ .Values.global.host }}"` | +| backstage.metrics.serviceMonitor.enabled | | bool | `false` | +| backstage.metrics.serviceMonitor.path | | string | `"/metrics"` | +| backstage.metrics.serviceMonitor.port | | string | `"http-metrics"` | +| backstage.podSecurityContext.appConfig.app.baseUrl | | string | `"https://{{- include \"rhdh.hostname\" . }}"` | +| backstage.podSecurityContext.appConfig.auth.providers | | object | `{}` | +| backstage.podSecurityContext.appConfig.backend.auth.externalAccess[0].options.secret | | string | `"${BACKEND_SECRET}"` | +| backstage.podSecurityContext.appConfig.backend.auth.externalAccess[0].options.subject | | string | `"legacy-default-config"` | +| backstage.podSecurityContext.appConfig.backend.auth.externalAccess[0].type | | string | `"legacy"` | +| backstage.podSecurityContext.appConfig.backend.baseUrl | | string | `"https://{{- include \"rhdh.hostname\" . }}"` | +| backstage.podSecurityContext.appConfig.backend.cors.origin | | string | `"https://{{- include \"rhdh.hostname\" . }}"` | +| backstage.podSecurityContext.appConfig.backend.database.connection.password | | string | `"${POSTGRESQL_ADMIN_PASSWORD}"` | +| backstage.podSecurityContext.appConfig.backend.database.connection.user | | string | `"postgres"` | +| backstage.podSecurityContext.args[0] | | string | `"--config"` | +| backstage.podSecurityContext.args[1] | | string | `"dynamic-plugins-root/app-config.dynamic-plugins.yaml"` | +| backstage.podSecurityContext.command | | list | `[]` | +| backstage.podSecurityContext.containerSecurityContext.allowPrivilegeEscalation | | bool | `false` | +| backstage.podSecurityContext.containerSecurityContext.capabilities.drop[0] | | string | `"ALL"` | +| backstage.podSecurityContext.containerSecurityContext.readOnlyRootFilesystem | | bool | `true` | +| backstage.podSecurityContext.containerSecurityContext.runAsNonRoot | | bool | `true` | +| backstage.podSecurityContext.containerSecurityContext.seccompProfile.type | | string | `"RuntimeDefault"` | +| backstage.podSecurityContext.enabled | | bool | `false` | +| backstage.podSecurityContext.extraEnvVars[0].name | | string | `"BACKEND_SECRET"` | +| backstage.podSecurityContext.extraEnvVars[0].valueFrom.secretKeyRef.key | | string | `"backend-secret"` | +| backstage.podSecurityContext.extraEnvVars[0].valueFrom.secretKeyRef.name | | string | `"{{ include \"rhdh.backend-secret-name\" $ }}"` | +| backstage.podSecurityContext.extraEnvVars[1].name | | string | `"POSTGRESQL_ADMIN_PASSWORD"` | +| backstage.podSecurityContext.extraEnvVars[1].valueFrom.secretKeyRef.key | | string | `"{{- include \"rhdh.postgresql.adminPasswordKey\" . }}"` | +| backstage.podSecurityContext.extraEnvVars[1].valueFrom.secretKeyRef.name | | string | `"{{- include \"rhdh.postgresql.secretName\" . }}"` | +| backstage.podSecurityContext.extraVolumeMounts[0].mountPath | | string | `"/opt/app-root/src/dynamic-plugins-root"` | +| backstage.podSecurityContext.extraVolumeMounts[0].name | | string | `"dynamic-plugins-root"` | +| backstage.podSecurityContext.extraVolumeMounts[1].mountPath | | string | `"/extensions"` | +| backstage.podSecurityContext.extraVolumeMounts[1].name | | string | `"extensions-catalog"` | +| backstage.podSecurityContext.extraVolumeMounts[2].mountPath | | string | `"/tmp"` | +| backstage.podSecurityContext.extraVolumeMounts[2].name | | string | `"temp"` | +| backstage.podSecurityContext.extraVolumes[0] | Ephemeral volume that will contain the dynamic plugins installed by the initContainer below at start. | object | `{"ephemeral":{"volumeClaimTemplate":{"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"5Gi"}}}}},"name":"dynamic-plugins-root"}` | +| backstage.podSecurityContext.extraVolumes[0].ephemeral.volumeClaimTemplate.spec.resources.requests.storage | Size of the volume that will contain the dynamic plugins. It should be large enough to contain all the plugins. | string | `"5Gi"` | +| backstage.podSecurityContext.extraVolumes[1].configMap.defaultMode | | int | `420` | +| backstage.podSecurityContext.extraVolumes[1].configMap.name | | string | `"{{ printf \"%s-dynamic-plugins\" .Release.Name }}"` | +| backstage.podSecurityContext.extraVolumes[1].configMap.optional | | bool | `true` | +| backstage.podSecurityContext.extraVolumes[1].name | | string | `"dynamic-plugins"` | +| backstage.podSecurityContext.extraVolumes[2].name | | string | `"dynamic-plugins-npmrc"` | +| backstage.podSecurityContext.extraVolumes[2].secret.defaultMode | | int | `420` | +| backstage.podSecurityContext.extraVolumes[2].secret.optional | | bool | `true` | +| backstage.podSecurityContext.extraVolumes[2].secret.secretName | | string | `"{{ printf \"%s-dynamic-plugins-npmrc\" .Release.Name }}"` | +| backstage.podSecurityContext.extraVolumes[3].name | | string | `"dynamic-plugins-registry-auth"` | +| backstage.podSecurityContext.extraVolumes[3].secret.defaultMode | | int | `416` | +| backstage.podSecurityContext.extraVolumes[3].secret.optional | | bool | `true` | +| backstage.podSecurityContext.extraVolumes[3].secret.secretName | | string | `"{{ printf \"%s-dynamic-plugins-registry-auth\" .Release.Name }}"` | +| backstage.podSecurityContext.extraVolumes[4].emptyDir | | object | `{}` | +| backstage.podSecurityContext.extraVolumes[4].name | | string | `"npmcacache"` | +| backstage.podSecurityContext.extraVolumes[5] | Ephemeral volume used by the install-dynamic-plugins init container to extract catalog entities from the catalog index image. Mounted at the /extensions path in the backstage-backend main container for automatic discovery by the extension catalog backend providers. | object | `{"emptyDir":{},"name":"extensions-catalog"}` | +| backstage.podSecurityContext.extraVolumes[6].emptyDir | | object | `{}` | +| backstage.podSecurityContext.extraVolumes[6].name | | string | `"temp"` | +| backstage.podSecurityContext.fsGroup | | int | `1001` | +| backstage.podSecurityContext.initContainers[0].command[0] | | string | `"./install-dynamic-plugins.sh"` | +| backstage.podSecurityContext.initContainers[0].command[1] | | string | `"/dynamic-plugins-root"` | +| backstage.podSecurityContext.initContainers[0].env[0].name | | string | `"NPM_CONFIG_USERCONFIG"` | +| backstage.podSecurityContext.initContainers[0].env[0].value | | string | `"/opt/app-root/src/.npmrc.dynamic-plugins"` | +| backstage.podSecurityContext.initContainers[0].env[1].name | | string | `"MAX_ENTRY_SIZE"` | +| backstage.podSecurityContext.initContainers[0].env[1].value | | string | `"40000000"` | +| backstage.podSecurityContext.initContainers[0].env[2].name | | string | `"CATALOG_INDEX_IMAGE"` | +| backstage.podSecurityContext.initContainers[0].env[2].value | | string | `"{{ .Values.global.catalogIndex.image.registry }}/{{ .Values.global.catalogIndex.image.repository }}:{{ .Values.global.catalogIndex.image.tag }}"` | +| backstage.podSecurityContext.initContainers[0].env[3].name | | string | `"CATALOG_ENTITIES_EXTRACT_DIR"` | +| backstage.podSecurityContext.initContainers[0].env[3].value | | string | `"/extensions"` | +| backstage.podSecurityContext.initContainers[0].image | Image used by the initContainer to install dynamic plugins into the `dynamic-plugins-root` volume mount. It could be replaced by a custom image based on this one. | string | `quay.io/rhdh-community/rhdh:next-1.10` | +| backstage.podSecurityContext.initContainers[0].imagePullPolicy | | string | `""` | +| backstage.podSecurityContext.initContainers[0].name | | string | `"install-dynamic-plugins"` | +| backstage.podSecurityContext.initContainers[0].resources.limits.cpu | | string | `"1000m"` | +| backstage.podSecurityContext.initContainers[0].resources.limits.ephemeral-storage | | string | `"5Gi"` | +| backstage.podSecurityContext.initContainers[0].resources.limits.memory | | string | `"2.5Gi"` | +| backstage.podSecurityContext.initContainers[0].resources.requests.cpu | | string | `"250m"` | +| backstage.podSecurityContext.initContainers[0].resources.requests.memory | | string | `"256Mi"` | +| backstage.podSecurityContext.initContainers[0].securityContext.allowPrivilegeEscalation | | bool | `false` | +| backstage.podSecurityContext.initContainers[0].securityContext.capabilities.drop[0] | | string | `"ALL"` | +| backstage.podSecurityContext.initContainers[0].securityContext.readOnlyRootFilesystem | | bool | `true` | +| backstage.podSecurityContext.initContainers[0].securityContext.runAsNonRoot | | bool | `true` | +| backstage.podSecurityContext.initContainers[0].securityContext.seccompProfile.type | | string | `"RuntimeDefault"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[0].mountPath | | string | `"/dynamic-plugins-root"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[0].name | | string | `"dynamic-plugins-root"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[1].mountPath | | string | `"/opt/app-root/src/dynamic-plugins.yaml"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[1].name | | string | `"dynamic-plugins"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[1].readOnly | | bool | `true` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[1].subPath | | string | `"dynamic-plugins.yaml"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[2].mountPath | | string | `"/opt/app-root/src/.npmrc.dynamic-plugins"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[2].name | | string | `"dynamic-plugins-npmrc"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[2].readOnly | | bool | `true` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[2].subPath | | string | `".npmrc"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[3].mountPath | | string | `"/opt/app-root/src/.config/containers"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[3].name | | string | `"dynamic-plugins-registry-auth"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[3].readOnly | | bool | `true` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[4].mountPath | | string | `"/opt/app-root/src/.npm/_cacache"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[4].name | | string | `"npmcacache"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[5].mountPath | | string | `"/extensions"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[5].name | | string | `"extensions-catalog"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[6].mountPath | | string | `"/tmp"` | +| backstage.podSecurityContext.initContainers[0].volumeMounts[6].name | | string | `"temp"` | +| backstage.podSecurityContext.initContainers[0].workingDir | | string | `"/opt/app-root/src"` | +| backstage.podSecurityContext.installDir | | string | `"/opt/app-root/src"` | +| backstage.podSecurityContext.livenessProbe.failureThreshold | | int | `3` | +| backstage.podSecurityContext.livenessProbe.httpGet.path | | string | `"/.backstage/health/v1/liveness"` | +| backstage.podSecurityContext.livenessProbe.httpGet.port | | string | `"backend"` | +| backstage.podSecurityContext.livenessProbe.httpGet.scheme | | string | `"HTTP"` | +| backstage.podSecurityContext.livenessProbe.periodSeconds | | int | `10` | +| backstage.podSecurityContext.livenessProbe.successThreshold | | int | `1` | +| backstage.podSecurityContext.livenessProbe.timeoutSeconds | | int | `4` | +| backstage.podSecurityContext.readinessProbe.failureThreshold | | int | `3` | +| backstage.podSecurityContext.readinessProbe.httpGet.path | | string | `"/.backstage/health/v1/readiness"` | +| backstage.podSecurityContext.readinessProbe.httpGet.port | | string | `"backend"` | +| backstage.podSecurityContext.readinessProbe.httpGet.scheme | | string | `"HTTP"` | +| backstage.podSecurityContext.readinessProbe.periodSeconds | | int | `10` | +| backstage.podSecurityContext.readinessProbe.successThreshold | | int | `2` | +| backstage.podSecurityContext.readinessProbe.timeoutSeconds | | int | `4` | +| backstage.podSecurityContext.resources.limits.cpu | | string | `"1000m"` | +| backstage.podSecurityContext.resources.limits.ephemeral-storage | | string | `"5Gi"` | +| backstage.podSecurityContext.resources.limits.memory | | string | `"2.5Gi"` | +| backstage.podSecurityContext.resources.requests.cpu | | string | `"250m"` | +| backstage.podSecurityContext.resources.requests.memory | | string | `"1Gi"` | +| backstage.podSecurityContext.startupProbe.failureThreshold | | int | `3` | +| backstage.podSecurityContext.startupProbe.httpGet.path | | string | `"/.backstage/health/v1/liveness"` | +| backstage.podSecurityContext.startupProbe.httpGet.port | | string | `"backend"` | +| backstage.podSecurityContext.startupProbe.httpGet.scheme | | string | `"HTTP"` | +| backstage.podSecurityContext.startupProbe.initialDelaySeconds | | int | `30` | +| backstage.podSecurityContext.startupProbe.periodSeconds | | int | `20` | +| backstage.podSecurityContext.startupProbe.successThreshold | | int | `1` | +| backstage.podSecurityContext.startupProbe.timeoutSeconds | | int | `4` | +| backstage.postgresql.auth.secretKeys.adminPasswordKey | | string | `"postgres-password"` | +| backstage.postgresql.auth.secretKeys.userPasswordKey | | string | `"password"` | +| backstage.postgresql.enabled | | bool | `true` | +| backstage.postgresql.image.registry | | string | `"quay.io"` | +| backstage.postgresql.image.repository | | string | `"fedora/postgresql-15"` | +| backstage.postgresql.image.tag | | string | `"latest"` | +| backstage.postgresql.postgresqlDataDir | | string | `"/var/lib/pgsql/data/userdata"` | +| backstage.postgresql.primary.containerSecurityContext.allowPrivilegeEscalation | | bool | `false` | +| backstage.postgresql.primary.containerSecurityContext.capabilities.drop[0] | | string | `"ALL"` | +| backstage.postgresql.primary.containerSecurityContext.enabled | | bool | `false` | +| backstage.postgresql.primary.extraEnvVars[0].name | | string | `"POSTGRESQL_ADMIN_PASSWORD"` | +| backstage.postgresql.primary.extraEnvVars[0].valueFrom.secretKeyRef.key | | string | `"{{- include \"rhdh.postgresql.adminPasswordKey\" . }}"` | +| backstage.postgresql.primary.extraEnvVars[0].valueFrom.secretKeyRef.name | | string | `"{{- include \"postgresql.v1.secretName\" . }}"` | +| backstage.postgresql.primary.persistence.enabled | | bool | `true` | +| backstage.postgresql.primary.persistence.mountPath | | string | `"/var/lib/pgsql/data"` | +| backstage.postgresql.primary.persistence.size | | string | `"1Gi"` | +| backstage.postgresql.primary.podSecurityContext.enabled | | bool | `false` | +| backstage.postgresql.primary.resources.limits.cpu | | string | `"250m"` | +| backstage.postgresql.primary.resources.limits.ephemeral-storage | | string | `"20Mi"` | +| backstage.postgresql.primary.resources.limits.memory | | string | `"1024Mi"` | +| backstage.postgresql.primary.resources.requests.cpu | | string | `"250m"` | +| backstage.postgresql.primary.resources.requests.memory | | string | `"256Mi"` | +| backstage.postgresql.serviceBindings.enabled | | bool | `true` | +| backstage.service.extraPorts[0].name | | string | `"http-metrics"` | +| backstage.service.extraPorts[0].port | | int | `9464` | +| backstage.service.extraPorts[0].targetPort | | int | `9464` | | global.auth | Enable service authentication within Backstage instance | object | `{"backend":{"enabled":true,"existingSecret":"","value":""}}` | | global.auth.backend | Backend service to service authentication
Ref: https://backstage.io/docs/auth/service-to-service-auth/ | object | `{"enabled":true,"existingSecret":"","value":""}` | | global.auth.backend.enabled | Enable backend service to service authentication, unless configured otherwise it generates a secret value | bool | `true` | @@ -245,10 +400,6 @@ Kubernetes: `>= 1.27.0-0` | test.image.tag | Test connection pod image tag. Note that the image needs to have both the `sh` and `curl` binaries in it. | string | `"latest"` | | test.injectTestNpmrcSecret | Whether to inject a fake dynamic plugins npmrc secret.
See RHDHBUGS-1893 and RHDHBUGS-1464 for the motivation behind this.
This is only used for testing purposes and should not be used in production.
Only relevant when `test.enabled` field is set to `true`. | bool | `false` | | upstream | Upstream Backstage [chart configuration](https://github.com/backstage/charts/blob/main/charts/backstage/values.yaml) | object | Use Openshift compatible settings | -| upstream.backstage.extraVolumes[0] | Ephemeral volume that will contain the dynamic plugins installed by the initContainer below at start. | object | `{"ephemeral":{"volumeClaimTemplate":{"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"5Gi"}}}}},"name":"dynamic-plugins-root"}` | -| upstream.backstage.extraVolumes[0].ephemeral.volumeClaimTemplate.spec.resources.requests.storage | Size of the volume that will contain the dynamic plugins. It should be large enough to contain all the plugins. | string | `"5Gi"` | -| upstream.backstage.extraVolumes[5] | Ephemeral volume used by the install-dynamic-plugins init container to extract catalog entities from the catalog index image. Mounted at the /extensions path in the backstage-backend main container for automatic discovery by the extension catalog backend providers. | object | `{"emptyDir":{},"name":"extensions-catalog"}` | -| upstream.backstage.initContainers[0].image | Image used by the initContainer to install dynamic plugins into the `dynamic-plugins-root` volume mount. It could be replaced by a custom image based on this one. | string | `quay.io/rhdh-community/rhdh:next-1.10` | ## Opinionated Backstage deployment diff --git a/charts/backstage/values.schema.json b/charts/backstage/values.schema.json index 65838959..1dcab435 100644 --- a/charts/backstage/values.schema.json +++ b/charts/backstage/values.schema.json @@ -185,7 +185,7 @@ "enabled": true, "initContainer": { "args": [ - "mkdir -p /tmp/data && echo 'Copying Lightspeed RAG data...' && cp -r /rag/vector_db /rag-content/ && cp -r /rag/embeddings_model /rag-content/ && echo 'Copy complete.'" + "mkdir -p /tmp/data && echo 'Copying Lightspeed RAG data...' && cp -r --no-preserve=mode,ownership /rag/vector_db /rag-content/ && cp -r --no-preserve=mode,ownership /rag/embeddings_model /rag-content/ && mkdir -p /rag-content/vector_db/notebooks && chmod -R a+rwX /rag-content && echo 'Copy complete.'" ], "command": [ "sh", @@ -1488,37 +1488,7 @@ "type": "object" }, "appConfig": { - "default": { - "app": { - "baseUrl": "https://{{- include \"rhdh.hostname\" . }}" - }, - "auth": { - "providers": {} - }, - "backend": { - "auth": { - "externalAccess": [ - { - "options": { - "secret": "${BACKEND_SECRET}", - "subject": "legacy-default-config" - }, - "type": "legacy" - } - ] - }, - "baseUrl": "https://{{- include \"rhdh.hostname\" . }}", - "cors": { - "origin": "https://{{- include \"rhdh.hostname\" . }}" - }, - "database": { - "connection": { - "password": "${POSTGRESQL_ADMIN_PASSWORD}", - "user": "postgres" - } - } - } - }, + "default": {}, "examples": [ { "app": { @@ -1533,10 +1503,7 @@ ] }, "args": { - "default": [ - "--config", - "dynamic-plugins-root/app-config.dynamic-plugins.yaml" - ], + "default": [], "items": { "type": "string" }, @@ -1576,7 +1543,10 @@ "type": "object" }, "command": { - "default": [], + "default": [ + "node", + "packages/backend" + ], "items": { "type": "string" }, @@ -2991,26 +2961,7 @@ "type": "array" }, "extraEnvVars": { - "default": [ - { - "name": "BACKEND_SECRET", - "valueFrom": { - "secretKeyRef": { - "key": "backend-secret", - "name": "{{ include \"rhdh.backend-secret-name\" $ }}" - } - } - }, - { - "name": "POSTGRESQL_ADMIN_PASSWORD", - "valueFrom": { - "secretKeyRef": { - "key": "{{- include \"rhdh.postgresql.adminPasswordKey\" . }}", - "name": "{{- include \"rhdh.postgresql.secretName\" . }}" - } - } - } - ], + "default": [], "examples": [ [ { @@ -3198,20 +3149,7 @@ "type": "array" }, "extraVolumeMounts": { - "default": [ - { - "mountPath": "/opt/app-root/src/dynamic-plugins-root", - "name": "dynamic-plugins-root" - }, - { - "mountPath": "/extensions", - "name": "extensions-catalog" - }, - { - "mountPath": "/tmp", - "name": "temp" - } - ], + "default": [], "items": { "description": "VolumeMount describes a mounting of a Volume within a container.", "properties": { @@ -3254,61 +3192,7 @@ "type": "array" }, "extraVolumes": { - "default": [ - { - "ephemeral": { - "volumeClaimTemplate": { - "spec": { - "accessModes": [ - "ReadWriteOnce" - ], - "resources": { - "requests": { - "storage": "5Gi" - } - } - } - } - }, - "name": "dynamic-plugins-root" - }, - { - "configMap": { - "defaultMode": 420, - "name": "{{ printf \"%s-dynamic-plugins\" .Release.Name }}", - "optional": true - }, - "name": "dynamic-plugins" - }, - { - "name": "dynamic-plugins-npmrc", - "secret": { - "defaultMode": 420, - "optional": true, - "secretName": "{{ printf \"%s-dynamic-plugins-npmrc\" .Release.Name }}" - } - }, - { - "name": "dynamic-plugins-registry-auth", - "secret": { - "defaultMode": 416, - "optional": true, - "secretName": "{{ printf \"%s-dynamic-plugins-registry-auth\" .Release.Name }}" - } - }, - { - "emptyDir": {}, - "name": "npmcacache" - }, - { - "emptyDir": {}, - "name": "extensions-catalog" - }, - { - "emptyDir": {}, - "name": "temp" - } - ], + "default": [], "items": { "description": "Volume represents a named volume in a pod that may be accessed by any container in the pod.", "properties": { @@ -4923,95 +4807,7 @@ "type": "object" }, "initContainers": { - "default": [ - { - "command": [ - "./install-dynamic-plugins.sh", - "/dynamic-plugins-root" - ], - "env": [ - { - "name": "NPM_CONFIG_USERCONFIG", - "value": "/opt/app-root/src/.npmrc.dynamic-plugins" - }, - { - "name": "MAX_ENTRY_SIZE", - "value": "40000000" - }, - { - "name": "CATALOG_INDEX_IMAGE", - "value": "{{ .Values.global.catalogIndex.image.registry }}/{{ .Values.global.catalogIndex.image.repository }}:{{ .Values.global.catalogIndex.image.tag }}" - }, - { - "name": "CATALOG_ENTITIES_EXTRACT_DIR", - "value": "/extensions" - } - ], - "image": "{{ include \"backstage.image\" . }}", - "imagePullPolicy": "", - "name": "install-dynamic-plugins", - "resources": { - "limits": { - "cpu": "1000m", - "ephemeral-storage": "5Gi", - "memory": "2.5Gi" - }, - "requests": { - "cpu": "250m", - "memory": "256Mi" - } - }, - "securityContext": { - "allowPrivilegeEscalation": false, - "capabilities": { - "drop": [ - "ALL" - ] - }, - "readOnlyRootFilesystem": true, - "runAsNonRoot": true, - "seccompProfile": { - "type": "RuntimeDefault" - } - }, - "volumeMounts": [ - { - "mountPath": "/dynamic-plugins-root", - "name": "dynamic-plugins-root" - }, - { - "mountPath": "/opt/app-root/src/dynamic-plugins.yaml", - "name": "dynamic-plugins", - "readOnly": true, - "subPath": "dynamic-plugins.yaml" - }, - { - "mountPath": "/opt/app-root/src/.npmrc.dynamic-plugins", - "name": "dynamic-plugins-npmrc", - "readOnly": true, - "subPath": ".npmrc" - }, - { - "mountPath": "/opt/app-root/src/.config/containers", - "name": "dynamic-plugins-registry-auth", - "readOnly": true - }, - { - "mountPath": "/opt/app-root/src/.npm/_cacache", - "name": "npmcacache" - }, - { - "mountPath": "/extensions", - "name": "extensions-catalog" - }, - { - "mountPath": "/tmp", - "name": "temp" - } - ], - "workingDir": "/opt/app-root/src" - } - ], + "default": [], "items": { "description": "A single application container that you want to run within a pod.", "properties": { @@ -6239,7 +6035,7 @@ "type": "array" }, "installDir": { - "default": "/opt/app-root/src", + "default": "/app", "title": "Directory containing the backstage installation", "type": "string" }, @@ -7247,7 +7043,7 @@ "type": "array" }, "host": { - "default": "{{ .Values.global.host }}", + "default": "", "examples": [ "backstage.10.0.0.1.nip.io" ], @@ -7342,7 +7138,7 @@ "type": "integer" } ], - "default": "http-metrics", + "default": "http-backend", "description": "The port where the metrics are exposed. If using OpenTelemetry as [documented here](https://backstage.io/docs/tutorials/setup-opentelemetry/), then the port needs to be explicitly specified. OpenTelemetry's default port is 9464.", "title": "ServiceMonitor endpoint port" } @@ -7984,13 +7780,7 @@ "type": "string" }, "extraPorts": { - "default": [ - { - "name": "http-metrics", - "port": 9464, - "targetPort": 9464 - } - ], + "default": [], "items": { "type": "object" }, diff --git a/charts/must-gather/README.md b/charts/must-gather/README.md index d42e2e55..630b4b1b 100644 --- a/charts/must-gather/README.md +++ b/charts/must-gather/README.md @@ -12,7 +12,7 @@ A Helm chart for running the RHDH Must-Gather diagnostic tool on Kubernetes | Name | Email | Url | | ---- | ------ | --- | -| Red Hat | | | +| Red Hat | | https://redhat.com | ## Source Code @@ -108,7 +108,7 @@ The command removes all the Kubernetes resources associated with the chart and d | Key | Description | Type | Default | |-----|-------------|------|---------| | affinity | Affinity rules for pod scheduling | object | `{}` | -| dataHolder | Runs alongside the gather container and stays alive so you can exec in and retrieve the output. | object | `{"resources":{"limits":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"},"requests":{"cpu":"50m","ephemeral-storage":"32Mi","memory":"64Mi"}}}` | +| dataHolder | Data holder container configuration -- Runs alongside the gather container and stays alive so you can exec in and retrieve the output. | object | `{"resources":{"limits":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"},"requests":{"cpu":"50m","ephemeral-storage":"32Mi","memory":"64Mi"}}}` | | dataHolder.resources | Resource requests and limits for the data-holder container | object | `{"limits":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"},"requests":{"cpu":"50m","ephemeral-storage":"32Mi","memory":"64Mi"}}` | | fullnameOverride | | string | `""` | | gather | Gather script configuration | object | `{"clusterInfo":false,"cmdTimeout":"30","extraArgs":[],"extraEnvVars":[],"heapDump":{"bufferSize":"","enabled":false,"instances":"","method":"","remoteDir":"","timeout":""},"logLevel":"info","namespaces":[],"since":"","sinceTime":"","withHelm":true,"withIngress":true,"withNamespaceInspect":true,"withOperator":true,"withOrchestrator":true,"withPlatform":true,"withRoute":true,"withSecrets":false}` | @@ -123,7 +123,7 @@ The command removes all the Kubernetes resources associated with the chart and d | gather.heapDump.remoteDir | Directory in container where heap dumps are written for SIGUSR2 method. Must be writable inside the gather container. | string | `""` | | gather.heapDump.timeout | Timeout in seconds for heap dump collection | string | `""` | | gather.logLevel | Log level: info, INFO, debug, DEBUG, trace, TRACE | string | `"info"` | -| gather.namespaces | Example: ["rhdh-prod", "rhdh-staging"] | list | `[]` | +| gather.namespaces | Limit collection to specific namespaces (only effective when rbac.scope is "cluster"). -- Ignored when rbac.scope is "namespace" (collection is restricted to the release namespace). -- Example: ["rhdh-prod", "rhdh-staging"] | list | `[]` | | gather.since | Relative time for log collection (e.g., "2h", "30m") | string | `""` | | gather.sinceTime | Absolute timestamp for log collection (RFC3339 format) | string | `""` | | gather.withOperator | Collection features (enabled by default; set to false to skip) | bool | `true` | @@ -143,7 +143,7 @@ The command removes all the Kubernetes resources associated with the chart and d | podSecurityContext | Pod security context | object | `{"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | | rbac | RBAC configuration | object | `{"create":true,"rules":{"backstages":true,"ingresses":true,"knative":true,"olm":true,"platform":true,"routes":true,"sonataflow":true},"scope":"cluster"}` | | rbac.create | Create RBAC resources (Role/ClusterRole and bindings) | bool | `true` | -| rbac.rules | a rule here does not require disabling the corresponding gather.with* flag. | object | `{"backstages":true,"ingresses":true,"knative":true,"olm":true,"platform":true,"routes":true,"sonataflow":true}` | +| rbac.rules | Control which API-group rules are included in the Role/ClusterRole. -- Disable a rule if the installing user cannot grant those permissions -- (Kubernetes requires you to already hold any permission you grant). -- The gather script handles missing permissions gracefully, so disabling -- a rule here does not require disabling the corresponding gather.with* flag. | object | `{"backstages":true,"ingresses":true,"knative":true,"olm":true,"platform":true,"routes":true,"sonataflow":true}` | | rbac.rules.backstages | rhdh.redhat.com — Backstage custom resources | bool | `true` | | rbac.rules.ingresses | networking.k8s.io — Ingresses, NetworkPolicies | bool | `true` | | rbac.rules.knative | operator.knative.dev, operator.serverless.openshift.io — Knative/Serverless | bool | `true` | @@ -151,12 +151,13 @@ The command removes all the Kubernetes resources associated with the chart and d | rbac.rules.platform | config.openshift.io — ClusterVersions, Infrastructures (cluster scope only) | bool | `true` | | rbac.rules.routes | route.openshift.io — OpenShift Routes | bool | `true` | | rbac.rules.sonataflow | sonataflow.org — SonataFlow custom resources | bool | `true` | +| rbac.scope | Scope of the RBAC role: "cluster" creates a ClusterRole with cluster-wide read access; -- "namespace" creates a namespace-scoped Role limited to the release namespace only -- (gather.namespaces is ignored; collection is restricted to the release namespace) | string | `"cluster"` | | resources | Resource requests and limits for the gather container | object | `{"limits":{"cpu":"500m","ephemeral-storage":"128Mi","memory":"512Mi"},"requests":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"}}` | | securityContext | Container security context | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}` | | serviceAccount | Service account configuration | object | `{"annotations":{},"name":"","tokenExpirationSeconds":3600}` | | serviceAccount.annotations | Annotations to add to the service account | object | `{}` | -| serviceAccount.name | If not set, a name is generated using the fullname template. | string | `""` | -| serviceAccount.tokenExpirationSeconds | into the gather init container (minimum 600). | int | `3600` | +| serviceAccount.name | The name of the service account to use. -- If not set, a name is generated using the fullname template. | string | `""` | +| serviceAccount.tokenExpirationSeconds | Expiration (in seconds) for the bound service account token projected -- into the gather init container (minimum 600). | int | `3600` | | strategy | Deployment strategy | object | `{"type":"Recreate"}` | | test | Helm test configuration | object | `{"enabled":true,"image":{"digest":"","pullPolicy":"","registry":"docker.io","repository":"bitnami/kubectl","tag":"latest"}}` | | test.enabled | Enable the Helm test | bool | `true` | diff --git a/charts/orchestrator-infra/README.md b/charts/orchestrator-infra/README.md index 30c8cf39..82e10a11 100644 --- a/charts/orchestrator-infra/README.md +++ b/charts/orchestrator-infra/README.md @@ -10,7 +10,7 @@ Helm chart to deploy the Orchestrator solution's required infrastructure suite o | Name | Email | Url | | ---- | ------ | --- | -| Red Hat Developer Hub Team | | | +| Red Hat Developer Hub Team | | https://github.com/redhat-developer/rhdh-chart | ## Source Code diff --git a/charts/orchestrator-software-templates-infra/README.md b/charts/orchestrator-software-templates-infra/README.md index 65d8331e..3bf112f5 100644 --- a/charts/orchestrator-software-templates-infra/README.md +++ b/charts/orchestrator-software-templates-infra/README.md @@ -10,7 +10,7 @@ A Helm chart to install Openshift GitOps and Openshift Pipelines, which are requ | Name | Email | Url | | ---- | ------ | --- | -| Red Hat Developer Hub Team | | | +| Red Hat Developer Hub Team | | https://github.com/redhat-developer/rhdh-chart | ## Source Code diff --git a/charts/orchestrator-software-templates/README.md b/charts/orchestrator-software-templates/README.md index e1275a97..92278e62 100644 --- a/charts/orchestrator-software-templates/README.md +++ b/charts/orchestrator-software-templates/README.md @@ -10,7 +10,7 @@ This Helm chart deploys the Orchestrator Software Templates for Red Hat Develope | Name | Email | Url | | ---- | ------ | --- | -| Red Hat Developer Hub Team | | | +| Red Hat Developer Hub Team | | https://github.com/redhat-developer/rhdh-chart | ## Source Code From 9ad9e2f340298ff7bf11ccc97ca45e34b9fa7e5f Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 23 Jun 2026 13:55:09 -0400 Subject: [PATCH 6/9] chore: revert non-backstage README regeneration Signed-off-by: Lucas --- charts/must-gather/README.md | 13 ++++++------- charts/orchestrator-infra/README.md | 2 +- .../orchestrator-software-templates-infra/README.md | 2 +- charts/orchestrator-software-templates/README.md | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/charts/must-gather/README.md b/charts/must-gather/README.md index 630b4b1b..d42e2e55 100644 --- a/charts/must-gather/README.md +++ b/charts/must-gather/README.md @@ -12,7 +12,7 @@ A Helm chart for running the RHDH Must-Gather diagnostic tool on Kubernetes | Name | Email | Url | | ---- | ------ | --- | -| Red Hat | | https://redhat.com | +| Red Hat | | | ## Source Code @@ -108,7 +108,7 @@ The command removes all the Kubernetes resources associated with the chart and d | Key | Description | Type | Default | |-----|-------------|------|---------| | affinity | Affinity rules for pod scheduling | object | `{}` | -| dataHolder | Data holder container configuration -- Runs alongside the gather container and stays alive so you can exec in and retrieve the output. | object | `{"resources":{"limits":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"},"requests":{"cpu":"50m","ephemeral-storage":"32Mi","memory":"64Mi"}}}` | +| dataHolder | Runs alongside the gather container and stays alive so you can exec in and retrieve the output. | object | `{"resources":{"limits":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"},"requests":{"cpu":"50m","ephemeral-storage":"32Mi","memory":"64Mi"}}}` | | dataHolder.resources | Resource requests and limits for the data-holder container | object | `{"limits":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"},"requests":{"cpu":"50m","ephemeral-storage":"32Mi","memory":"64Mi"}}` | | fullnameOverride | | string | `""` | | gather | Gather script configuration | object | `{"clusterInfo":false,"cmdTimeout":"30","extraArgs":[],"extraEnvVars":[],"heapDump":{"bufferSize":"","enabled":false,"instances":"","method":"","remoteDir":"","timeout":""},"logLevel":"info","namespaces":[],"since":"","sinceTime":"","withHelm":true,"withIngress":true,"withNamespaceInspect":true,"withOperator":true,"withOrchestrator":true,"withPlatform":true,"withRoute":true,"withSecrets":false}` | @@ -123,7 +123,7 @@ The command removes all the Kubernetes resources associated with the chart and d | gather.heapDump.remoteDir | Directory in container where heap dumps are written for SIGUSR2 method. Must be writable inside the gather container. | string | `""` | | gather.heapDump.timeout | Timeout in seconds for heap dump collection | string | `""` | | gather.logLevel | Log level: info, INFO, debug, DEBUG, trace, TRACE | string | `"info"` | -| gather.namespaces | Limit collection to specific namespaces (only effective when rbac.scope is "cluster"). -- Ignored when rbac.scope is "namespace" (collection is restricted to the release namespace). -- Example: ["rhdh-prod", "rhdh-staging"] | list | `[]` | +| gather.namespaces | Example: ["rhdh-prod", "rhdh-staging"] | list | `[]` | | gather.since | Relative time for log collection (e.g., "2h", "30m") | string | `""` | | gather.sinceTime | Absolute timestamp for log collection (RFC3339 format) | string | `""` | | gather.withOperator | Collection features (enabled by default; set to false to skip) | bool | `true` | @@ -143,7 +143,7 @@ The command removes all the Kubernetes resources associated with the chart and d | podSecurityContext | Pod security context | object | `{"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | | rbac | RBAC configuration | object | `{"create":true,"rules":{"backstages":true,"ingresses":true,"knative":true,"olm":true,"platform":true,"routes":true,"sonataflow":true},"scope":"cluster"}` | | rbac.create | Create RBAC resources (Role/ClusterRole and bindings) | bool | `true` | -| rbac.rules | Control which API-group rules are included in the Role/ClusterRole. -- Disable a rule if the installing user cannot grant those permissions -- (Kubernetes requires you to already hold any permission you grant). -- The gather script handles missing permissions gracefully, so disabling -- a rule here does not require disabling the corresponding gather.with* flag. | object | `{"backstages":true,"ingresses":true,"knative":true,"olm":true,"platform":true,"routes":true,"sonataflow":true}` | +| rbac.rules | a rule here does not require disabling the corresponding gather.with* flag. | object | `{"backstages":true,"ingresses":true,"knative":true,"olm":true,"platform":true,"routes":true,"sonataflow":true}` | | rbac.rules.backstages | rhdh.redhat.com — Backstage custom resources | bool | `true` | | rbac.rules.ingresses | networking.k8s.io — Ingresses, NetworkPolicies | bool | `true` | | rbac.rules.knative | operator.knative.dev, operator.serverless.openshift.io — Knative/Serverless | bool | `true` | @@ -151,13 +151,12 @@ The command removes all the Kubernetes resources associated with the chart and d | rbac.rules.platform | config.openshift.io — ClusterVersions, Infrastructures (cluster scope only) | bool | `true` | | rbac.rules.routes | route.openshift.io — OpenShift Routes | bool | `true` | | rbac.rules.sonataflow | sonataflow.org — SonataFlow custom resources | bool | `true` | -| rbac.scope | Scope of the RBAC role: "cluster" creates a ClusterRole with cluster-wide read access; -- "namespace" creates a namespace-scoped Role limited to the release namespace only -- (gather.namespaces is ignored; collection is restricted to the release namespace) | string | `"cluster"` | | resources | Resource requests and limits for the gather container | object | `{"limits":{"cpu":"500m","ephemeral-storage":"128Mi","memory":"512Mi"},"requests":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"}}` | | securityContext | Container security context | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}` | | serviceAccount | Service account configuration | object | `{"annotations":{},"name":"","tokenExpirationSeconds":3600}` | | serviceAccount.annotations | Annotations to add to the service account | object | `{}` | -| serviceAccount.name | The name of the service account to use. -- If not set, a name is generated using the fullname template. | string | `""` | -| serviceAccount.tokenExpirationSeconds | Expiration (in seconds) for the bound service account token projected -- into the gather init container (minimum 600). | int | `3600` | +| serviceAccount.name | If not set, a name is generated using the fullname template. | string | `""` | +| serviceAccount.tokenExpirationSeconds | into the gather init container (minimum 600). | int | `3600` | | strategy | Deployment strategy | object | `{"type":"Recreate"}` | | test | Helm test configuration | object | `{"enabled":true,"image":{"digest":"","pullPolicy":"","registry":"docker.io","repository":"bitnami/kubectl","tag":"latest"}}` | | test.enabled | Enable the Helm test | bool | `true` | diff --git a/charts/orchestrator-infra/README.md b/charts/orchestrator-infra/README.md index 82e10a11..30c8cf39 100644 --- a/charts/orchestrator-infra/README.md +++ b/charts/orchestrator-infra/README.md @@ -10,7 +10,7 @@ Helm chart to deploy the Orchestrator solution's required infrastructure suite o | Name | Email | Url | | ---- | ------ | --- | -| Red Hat Developer Hub Team | | https://github.com/redhat-developer/rhdh-chart | +| Red Hat Developer Hub Team | | | ## Source Code diff --git a/charts/orchestrator-software-templates-infra/README.md b/charts/orchestrator-software-templates-infra/README.md index 3bf112f5..65d8331e 100644 --- a/charts/orchestrator-software-templates-infra/README.md +++ b/charts/orchestrator-software-templates-infra/README.md @@ -10,7 +10,7 @@ A Helm chart to install Openshift GitOps and Openshift Pipelines, which are requ | Name | Email | Url | | ---- | ------ | --- | -| Red Hat Developer Hub Team | | https://github.com/redhat-developer/rhdh-chart | +| Red Hat Developer Hub Team | | | ## Source Code diff --git a/charts/orchestrator-software-templates/README.md b/charts/orchestrator-software-templates/README.md index 92278e62..e1275a97 100644 --- a/charts/orchestrator-software-templates/README.md +++ b/charts/orchestrator-software-templates/README.md @@ -10,7 +10,7 @@ This Helm chart deploys the Orchestrator Software Templates for Red Hat Develope | Name | Email | Url | | ---- | ------ | --- | -| Red Hat Developer Hub Team | | https://github.com/redhat-developer/rhdh-chart | +| Red Hat Developer Hub Team | | | ## Source Code From 47df148a14c36d7c4f04109dedc15237677e6fbf Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 23 Jun 2026 13:58:06 -0400 Subject: [PATCH 7/9] chore(backstage): fix README maintainer URL and dependency alias format Signed-off-by: Lucas --- charts/backstage/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/backstage/README.md b/charts/backstage/README.md index ad387a1c..a776d625 100644 --- a/charts/backstage/README.md +++ b/charts/backstage/README.md @@ -21,7 +21,7 @@ For the **Generally Available** version of this chart, see: | Name | Email | Url | | ---- | ------ | --- | -| Red Hat | | https://redhat.com | +| Red Hat | | | ## TL;DR @@ -156,7 +156,7 @@ Kubernetes: `>= 1.27.0-0` | Repository | Name | Version | |------------|------|---------| -| file://./vendor/backstage/charts/backstage/ | backstage | 2.7.0 | +| file://./vendor/backstage/charts/backstage/ | upstream(backstage) | 2.7.0 | | https://charts.bitnami.com/bitnami | common | 2.39.0 | ## Values From fcc0a0c264645ad141ad21b43385f037db5beaa8 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 23 Jun 2026 15:00:38 -0400 Subject: [PATCH 8/9] fix(backstage): restore upstream.backstage structure corrupted by spurious top-level key Signed-off-by: Lucas --- charts/backstage/values.yaml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/charts/backstage/values.yaml b/charts/backstage/values.yaml index 3088f1bb..e61c685e 100644 --- a/charts/backstage/values.yaml +++ b/charts/backstage/values.yaml @@ -194,15 +194,9 @@ upstream: registry: quay.io repository: rhdh-community/rhdh tag: next-1.10 -backstage: - image: - registry: quay.io - repository: rhdh-community/rhdh - tag: next-1.10 - pullPolicy: "" - podSecurityContext: - enabled: false - fsGroup: 1001 + pullPolicy: "" + podSecurityContext: + enabled: false command: [] # FIXME (tumido): USE POSTGRES_PASSWORD and POSTGRES_USER instead of POSTGRES_ADMIN_PASSWORD # This is a hack. In {fedora,rhel}/postgresql images, regular user is forbidden From 5aa9e3a3984d8ba7b54b51b28cc8a2778ec9654a Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 23 Jun 2026 15:08:12 -0400 Subject: [PATCH 9/9] chore(backstage): regenerate README and schema after upstream.backstage structure fix Signed-off-by: Lucas --- charts/backstage/README.md | 159 +------------------ charts/backstage/values.schema.json | 238 ++++++++++++++++++++++++++-- 2 files changed, 228 insertions(+), 169 deletions(-) diff --git a/charts/backstage/README.md b/charts/backstage/README.md index a776d625..964ea75f 100644 --- a/charts/backstage/README.md +++ b/charts/backstage/README.md @@ -163,161 +163,6 @@ Kubernetes: `>= 1.27.0-0` | Key | Description | Type | Default | |-----|-------------|------|---------| -| backstage.image.pullPolicy | | string | `""` | -| backstage.image.registry | | string | `"quay.io"` | -| backstage.image.repository | | string | `"rhdh-community/rhdh"` | -| backstage.image.tag | | string | `"next-1.10"` | -| backstage.ingress.host | | string | `"{{ .Values.global.host }}"` | -| backstage.metrics.serviceMonitor.enabled | | bool | `false` | -| backstage.metrics.serviceMonitor.path | | string | `"/metrics"` | -| backstage.metrics.serviceMonitor.port | | string | `"http-metrics"` | -| backstage.podSecurityContext.appConfig.app.baseUrl | | string | `"https://{{- include \"rhdh.hostname\" . }}"` | -| backstage.podSecurityContext.appConfig.auth.providers | | object | `{}` | -| backstage.podSecurityContext.appConfig.backend.auth.externalAccess[0].options.secret | | string | `"${BACKEND_SECRET}"` | -| backstage.podSecurityContext.appConfig.backend.auth.externalAccess[0].options.subject | | string | `"legacy-default-config"` | -| backstage.podSecurityContext.appConfig.backend.auth.externalAccess[0].type | | string | `"legacy"` | -| backstage.podSecurityContext.appConfig.backend.baseUrl | | string | `"https://{{- include \"rhdh.hostname\" . }}"` | -| backstage.podSecurityContext.appConfig.backend.cors.origin | | string | `"https://{{- include \"rhdh.hostname\" . }}"` | -| backstage.podSecurityContext.appConfig.backend.database.connection.password | | string | `"${POSTGRESQL_ADMIN_PASSWORD}"` | -| backstage.podSecurityContext.appConfig.backend.database.connection.user | | string | `"postgres"` | -| backstage.podSecurityContext.args[0] | | string | `"--config"` | -| backstage.podSecurityContext.args[1] | | string | `"dynamic-plugins-root/app-config.dynamic-plugins.yaml"` | -| backstage.podSecurityContext.command | | list | `[]` | -| backstage.podSecurityContext.containerSecurityContext.allowPrivilegeEscalation | | bool | `false` | -| backstage.podSecurityContext.containerSecurityContext.capabilities.drop[0] | | string | `"ALL"` | -| backstage.podSecurityContext.containerSecurityContext.readOnlyRootFilesystem | | bool | `true` | -| backstage.podSecurityContext.containerSecurityContext.runAsNonRoot | | bool | `true` | -| backstage.podSecurityContext.containerSecurityContext.seccompProfile.type | | string | `"RuntimeDefault"` | -| backstage.podSecurityContext.enabled | | bool | `false` | -| backstage.podSecurityContext.extraEnvVars[0].name | | string | `"BACKEND_SECRET"` | -| backstage.podSecurityContext.extraEnvVars[0].valueFrom.secretKeyRef.key | | string | `"backend-secret"` | -| backstage.podSecurityContext.extraEnvVars[0].valueFrom.secretKeyRef.name | | string | `"{{ include \"rhdh.backend-secret-name\" $ }}"` | -| backstage.podSecurityContext.extraEnvVars[1].name | | string | `"POSTGRESQL_ADMIN_PASSWORD"` | -| backstage.podSecurityContext.extraEnvVars[1].valueFrom.secretKeyRef.key | | string | `"{{- include \"rhdh.postgresql.adminPasswordKey\" . }}"` | -| backstage.podSecurityContext.extraEnvVars[1].valueFrom.secretKeyRef.name | | string | `"{{- include \"rhdh.postgresql.secretName\" . }}"` | -| backstage.podSecurityContext.extraVolumeMounts[0].mountPath | | string | `"/opt/app-root/src/dynamic-plugins-root"` | -| backstage.podSecurityContext.extraVolumeMounts[0].name | | string | `"dynamic-plugins-root"` | -| backstage.podSecurityContext.extraVolumeMounts[1].mountPath | | string | `"/extensions"` | -| backstage.podSecurityContext.extraVolumeMounts[1].name | | string | `"extensions-catalog"` | -| backstage.podSecurityContext.extraVolumeMounts[2].mountPath | | string | `"/tmp"` | -| backstage.podSecurityContext.extraVolumeMounts[2].name | | string | `"temp"` | -| backstage.podSecurityContext.extraVolumes[0] | Ephemeral volume that will contain the dynamic plugins installed by the initContainer below at start. | object | `{"ephemeral":{"volumeClaimTemplate":{"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"5Gi"}}}}},"name":"dynamic-plugins-root"}` | -| backstage.podSecurityContext.extraVolumes[0].ephemeral.volumeClaimTemplate.spec.resources.requests.storage | Size of the volume that will contain the dynamic plugins. It should be large enough to contain all the plugins. | string | `"5Gi"` | -| backstage.podSecurityContext.extraVolumes[1].configMap.defaultMode | | int | `420` | -| backstage.podSecurityContext.extraVolumes[1].configMap.name | | string | `"{{ printf \"%s-dynamic-plugins\" .Release.Name }}"` | -| backstage.podSecurityContext.extraVolumes[1].configMap.optional | | bool | `true` | -| backstage.podSecurityContext.extraVolumes[1].name | | string | `"dynamic-plugins"` | -| backstage.podSecurityContext.extraVolumes[2].name | | string | `"dynamic-plugins-npmrc"` | -| backstage.podSecurityContext.extraVolumes[2].secret.defaultMode | | int | `420` | -| backstage.podSecurityContext.extraVolumes[2].secret.optional | | bool | `true` | -| backstage.podSecurityContext.extraVolumes[2].secret.secretName | | string | `"{{ printf \"%s-dynamic-plugins-npmrc\" .Release.Name }}"` | -| backstage.podSecurityContext.extraVolumes[3].name | | string | `"dynamic-plugins-registry-auth"` | -| backstage.podSecurityContext.extraVolumes[3].secret.defaultMode | | int | `416` | -| backstage.podSecurityContext.extraVolumes[3].secret.optional | | bool | `true` | -| backstage.podSecurityContext.extraVolumes[3].secret.secretName | | string | `"{{ printf \"%s-dynamic-plugins-registry-auth\" .Release.Name }}"` | -| backstage.podSecurityContext.extraVolumes[4].emptyDir | | object | `{}` | -| backstage.podSecurityContext.extraVolumes[4].name | | string | `"npmcacache"` | -| backstage.podSecurityContext.extraVolumes[5] | Ephemeral volume used by the install-dynamic-plugins init container to extract catalog entities from the catalog index image. Mounted at the /extensions path in the backstage-backend main container for automatic discovery by the extension catalog backend providers. | object | `{"emptyDir":{},"name":"extensions-catalog"}` | -| backstage.podSecurityContext.extraVolumes[6].emptyDir | | object | `{}` | -| backstage.podSecurityContext.extraVolumes[6].name | | string | `"temp"` | -| backstage.podSecurityContext.fsGroup | | int | `1001` | -| backstage.podSecurityContext.initContainers[0].command[0] | | string | `"./install-dynamic-plugins.sh"` | -| backstage.podSecurityContext.initContainers[0].command[1] | | string | `"/dynamic-plugins-root"` | -| backstage.podSecurityContext.initContainers[0].env[0].name | | string | `"NPM_CONFIG_USERCONFIG"` | -| backstage.podSecurityContext.initContainers[0].env[0].value | | string | `"/opt/app-root/src/.npmrc.dynamic-plugins"` | -| backstage.podSecurityContext.initContainers[0].env[1].name | | string | `"MAX_ENTRY_SIZE"` | -| backstage.podSecurityContext.initContainers[0].env[1].value | | string | `"40000000"` | -| backstage.podSecurityContext.initContainers[0].env[2].name | | string | `"CATALOG_INDEX_IMAGE"` | -| backstage.podSecurityContext.initContainers[0].env[2].value | | string | `"{{ .Values.global.catalogIndex.image.registry }}/{{ .Values.global.catalogIndex.image.repository }}:{{ .Values.global.catalogIndex.image.tag }}"` | -| backstage.podSecurityContext.initContainers[0].env[3].name | | string | `"CATALOG_ENTITIES_EXTRACT_DIR"` | -| backstage.podSecurityContext.initContainers[0].env[3].value | | string | `"/extensions"` | -| backstage.podSecurityContext.initContainers[0].image | Image used by the initContainer to install dynamic plugins into the `dynamic-plugins-root` volume mount. It could be replaced by a custom image based on this one. | string | `quay.io/rhdh-community/rhdh:next-1.10` | -| backstage.podSecurityContext.initContainers[0].imagePullPolicy | | string | `""` | -| backstage.podSecurityContext.initContainers[0].name | | string | `"install-dynamic-plugins"` | -| backstage.podSecurityContext.initContainers[0].resources.limits.cpu | | string | `"1000m"` | -| backstage.podSecurityContext.initContainers[0].resources.limits.ephemeral-storage | | string | `"5Gi"` | -| backstage.podSecurityContext.initContainers[0].resources.limits.memory | | string | `"2.5Gi"` | -| backstage.podSecurityContext.initContainers[0].resources.requests.cpu | | string | `"250m"` | -| backstage.podSecurityContext.initContainers[0].resources.requests.memory | | string | `"256Mi"` | -| backstage.podSecurityContext.initContainers[0].securityContext.allowPrivilegeEscalation | | bool | `false` | -| backstage.podSecurityContext.initContainers[0].securityContext.capabilities.drop[0] | | string | `"ALL"` | -| backstage.podSecurityContext.initContainers[0].securityContext.readOnlyRootFilesystem | | bool | `true` | -| backstage.podSecurityContext.initContainers[0].securityContext.runAsNonRoot | | bool | `true` | -| backstage.podSecurityContext.initContainers[0].securityContext.seccompProfile.type | | string | `"RuntimeDefault"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[0].mountPath | | string | `"/dynamic-plugins-root"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[0].name | | string | `"dynamic-plugins-root"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[1].mountPath | | string | `"/opt/app-root/src/dynamic-plugins.yaml"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[1].name | | string | `"dynamic-plugins"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[1].readOnly | | bool | `true` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[1].subPath | | string | `"dynamic-plugins.yaml"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[2].mountPath | | string | `"/opt/app-root/src/.npmrc.dynamic-plugins"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[2].name | | string | `"dynamic-plugins-npmrc"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[2].readOnly | | bool | `true` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[2].subPath | | string | `".npmrc"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[3].mountPath | | string | `"/opt/app-root/src/.config/containers"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[3].name | | string | `"dynamic-plugins-registry-auth"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[3].readOnly | | bool | `true` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[4].mountPath | | string | `"/opt/app-root/src/.npm/_cacache"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[4].name | | string | `"npmcacache"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[5].mountPath | | string | `"/extensions"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[5].name | | string | `"extensions-catalog"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[6].mountPath | | string | `"/tmp"` | -| backstage.podSecurityContext.initContainers[0].volumeMounts[6].name | | string | `"temp"` | -| backstage.podSecurityContext.initContainers[0].workingDir | | string | `"/opt/app-root/src"` | -| backstage.podSecurityContext.installDir | | string | `"/opt/app-root/src"` | -| backstage.podSecurityContext.livenessProbe.failureThreshold | | int | `3` | -| backstage.podSecurityContext.livenessProbe.httpGet.path | | string | `"/.backstage/health/v1/liveness"` | -| backstage.podSecurityContext.livenessProbe.httpGet.port | | string | `"backend"` | -| backstage.podSecurityContext.livenessProbe.httpGet.scheme | | string | `"HTTP"` | -| backstage.podSecurityContext.livenessProbe.periodSeconds | | int | `10` | -| backstage.podSecurityContext.livenessProbe.successThreshold | | int | `1` | -| backstage.podSecurityContext.livenessProbe.timeoutSeconds | | int | `4` | -| backstage.podSecurityContext.readinessProbe.failureThreshold | | int | `3` | -| backstage.podSecurityContext.readinessProbe.httpGet.path | | string | `"/.backstage/health/v1/readiness"` | -| backstage.podSecurityContext.readinessProbe.httpGet.port | | string | `"backend"` | -| backstage.podSecurityContext.readinessProbe.httpGet.scheme | | string | `"HTTP"` | -| backstage.podSecurityContext.readinessProbe.periodSeconds | | int | `10` | -| backstage.podSecurityContext.readinessProbe.successThreshold | | int | `2` | -| backstage.podSecurityContext.readinessProbe.timeoutSeconds | | int | `4` | -| backstage.podSecurityContext.resources.limits.cpu | | string | `"1000m"` | -| backstage.podSecurityContext.resources.limits.ephemeral-storage | | string | `"5Gi"` | -| backstage.podSecurityContext.resources.limits.memory | | string | `"2.5Gi"` | -| backstage.podSecurityContext.resources.requests.cpu | | string | `"250m"` | -| backstage.podSecurityContext.resources.requests.memory | | string | `"1Gi"` | -| backstage.podSecurityContext.startupProbe.failureThreshold | | int | `3` | -| backstage.podSecurityContext.startupProbe.httpGet.path | | string | `"/.backstage/health/v1/liveness"` | -| backstage.podSecurityContext.startupProbe.httpGet.port | | string | `"backend"` | -| backstage.podSecurityContext.startupProbe.httpGet.scheme | | string | `"HTTP"` | -| backstage.podSecurityContext.startupProbe.initialDelaySeconds | | int | `30` | -| backstage.podSecurityContext.startupProbe.periodSeconds | | int | `20` | -| backstage.podSecurityContext.startupProbe.successThreshold | | int | `1` | -| backstage.podSecurityContext.startupProbe.timeoutSeconds | | int | `4` | -| backstage.postgresql.auth.secretKeys.adminPasswordKey | | string | `"postgres-password"` | -| backstage.postgresql.auth.secretKeys.userPasswordKey | | string | `"password"` | -| backstage.postgresql.enabled | | bool | `true` | -| backstage.postgresql.image.registry | | string | `"quay.io"` | -| backstage.postgresql.image.repository | | string | `"fedora/postgresql-15"` | -| backstage.postgresql.image.tag | | string | `"latest"` | -| backstage.postgresql.postgresqlDataDir | | string | `"/var/lib/pgsql/data/userdata"` | -| backstage.postgresql.primary.containerSecurityContext.allowPrivilegeEscalation | | bool | `false` | -| backstage.postgresql.primary.containerSecurityContext.capabilities.drop[0] | | string | `"ALL"` | -| backstage.postgresql.primary.containerSecurityContext.enabled | | bool | `false` | -| backstage.postgresql.primary.extraEnvVars[0].name | | string | `"POSTGRESQL_ADMIN_PASSWORD"` | -| backstage.postgresql.primary.extraEnvVars[0].valueFrom.secretKeyRef.key | | string | `"{{- include \"rhdh.postgresql.adminPasswordKey\" . }}"` | -| backstage.postgresql.primary.extraEnvVars[0].valueFrom.secretKeyRef.name | | string | `"{{- include \"postgresql.v1.secretName\" . }}"` | -| backstage.postgresql.primary.persistence.enabled | | bool | `true` | -| backstage.postgresql.primary.persistence.mountPath | | string | `"/var/lib/pgsql/data"` | -| backstage.postgresql.primary.persistence.size | | string | `"1Gi"` | -| backstage.postgresql.primary.podSecurityContext.enabled | | bool | `false` | -| backstage.postgresql.primary.resources.limits.cpu | | string | `"250m"` | -| backstage.postgresql.primary.resources.limits.ephemeral-storage | | string | `"20Mi"` | -| backstage.postgresql.primary.resources.limits.memory | | string | `"1024Mi"` | -| backstage.postgresql.primary.resources.requests.cpu | | string | `"250m"` | -| backstage.postgresql.primary.resources.requests.memory | | string | `"256Mi"` | -| backstage.postgresql.serviceBindings.enabled | | bool | `true` | -| backstage.service.extraPorts[0].name | | string | `"http-metrics"` | -| backstage.service.extraPorts[0].port | | int | `9464` | -| backstage.service.extraPorts[0].targetPort | | int | `9464` | | global.auth | Enable service authentication within Backstage instance | object | `{"backend":{"enabled":true,"existingSecret":"","value":""}}` | | global.auth.backend | Backend service to service authentication
Ref: https://backstage.io/docs/auth/service-to-service-auth/ | object | `{"enabled":true,"existingSecret":"","value":""}` | | global.auth.backend.enabled | Enable backend service to service authentication, unless configured otherwise it generates a secret value | bool | `true` | @@ -400,6 +245,10 @@ Kubernetes: `>= 1.27.0-0` | test.image.tag | Test connection pod image tag. Note that the image needs to have both the `sh` and `curl` binaries in it. | string | `"latest"` | | test.injectTestNpmrcSecret | Whether to inject a fake dynamic plugins npmrc secret.
See RHDHBUGS-1893 and RHDHBUGS-1464 for the motivation behind this.
This is only used for testing purposes and should not be used in production.
Only relevant when `test.enabled` field is set to `true`. | bool | `false` | | upstream | Upstream Backstage [chart configuration](https://github.com/backstage/charts/blob/main/charts/backstage/values.yaml) | object | Use Openshift compatible settings | +| upstream.backstage.extraVolumes[0] | Ephemeral volume that will contain the dynamic plugins installed by the initContainer below at start. | object | `{"ephemeral":{"volumeClaimTemplate":{"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"5Gi"}}}}},"name":"dynamic-plugins-root"}` | +| upstream.backstage.extraVolumes[0].ephemeral.volumeClaimTemplate.spec.resources.requests.storage | Size of the volume that will contain the dynamic plugins. It should be large enough to contain all the plugins. | string | `"5Gi"` | +| upstream.backstage.extraVolumes[5] | Ephemeral volume used by the install-dynamic-plugins init container to extract catalog entities from the catalog index image. Mounted at the /extensions path in the backstage-backend main container for automatic discovery by the extension catalog backend providers. | object | `{"emptyDir":{},"name":"extensions-catalog"}` | +| upstream.backstage.initContainers[0].image | Image used by the initContainer to install dynamic plugins into the `dynamic-plugins-root` volume mount. It could be replaced by a custom image based on this one. | string | `quay.io/rhdh-community/rhdh:next-1.10` | ## Opinionated Backstage deployment diff --git a/charts/backstage/values.schema.json b/charts/backstage/values.schema.json index 1dcab435..e3f7fc58 100644 --- a/charts/backstage/values.schema.json +++ b/charts/backstage/values.schema.json @@ -1488,7 +1488,37 @@ "type": "object" }, "appConfig": { - "default": {}, + "default": { + "app": { + "baseUrl": "https://{{- include \"rhdh.hostname\" . }}" + }, + "auth": { + "providers": {} + }, + "backend": { + "auth": { + "externalAccess": [ + { + "options": { + "secret": "${BACKEND_SECRET}", + "subject": "legacy-default-config" + }, + "type": "legacy" + } + ] + }, + "baseUrl": "https://{{- include \"rhdh.hostname\" . }}", + "cors": { + "origin": "https://{{- include \"rhdh.hostname\" . }}" + }, + "database": { + "connection": { + "password": "${POSTGRESQL_ADMIN_PASSWORD}", + "user": "postgres" + } + } + } + }, "examples": [ { "app": { @@ -1503,7 +1533,10 @@ ] }, "args": { - "default": [], + "default": [ + "--config", + "dynamic-plugins-root/app-config.dynamic-plugins.yaml" + ], "items": { "type": "string" }, @@ -1543,10 +1576,7 @@ "type": "object" }, "command": { - "default": [ - "node", - "packages/backend" - ], + "default": [], "items": { "type": "string" }, @@ -2961,7 +2991,26 @@ "type": "array" }, "extraEnvVars": { - "default": [], + "default": [ + { + "name": "BACKEND_SECRET", + "valueFrom": { + "secretKeyRef": { + "key": "backend-secret", + "name": "{{ include \"rhdh.backend-secret-name\" $ }}" + } + } + }, + { + "name": "POSTGRESQL_ADMIN_PASSWORD", + "valueFrom": { + "secretKeyRef": { + "key": "{{- include \"rhdh.postgresql.adminPasswordKey\" . }}", + "name": "{{- include \"rhdh.postgresql.secretName\" . }}" + } + } + } + ], "examples": [ [ { @@ -3149,7 +3198,20 @@ "type": "array" }, "extraVolumeMounts": { - "default": [], + "default": [ + { + "mountPath": "/opt/app-root/src/dynamic-plugins-root", + "name": "dynamic-plugins-root" + }, + { + "mountPath": "/extensions", + "name": "extensions-catalog" + }, + { + "mountPath": "/tmp", + "name": "temp" + } + ], "items": { "description": "VolumeMount describes a mounting of a Volume within a container.", "properties": { @@ -3192,7 +3254,61 @@ "type": "array" }, "extraVolumes": { - "default": [], + "default": [ + { + "ephemeral": { + "volumeClaimTemplate": { + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "5Gi" + } + } + } + } + }, + "name": "dynamic-plugins-root" + }, + { + "configMap": { + "defaultMode": 420, + "name": "{{ printf \"%s-dynamic-plugins\" .Release.Name }}", + "optional": true + }, + "name": "dynamic-plugins" + }, + { + "name": "dynamic-plugins-npmrc", + "secret": { + "defaultMode": 420, + "optional": true, + "secretName": "{{ printf \"%s-dynamic-plugins-npmrc\" .Release.Name }}" + } + }, + { + "name": "dynamic-plugins-registry-auth", + "secret": { + "defaultMode": 416, + "optional": true, + "secretName": "{{ printf \"%s-dynamic-plugins-registry-auth\" .Release.Name }}" + } + }, + { + "emptyDir": {}, + "name": "npmcacache" + }, + { + "emptyDir": {}, + "name": "extensions-catalog" + }, + { + "emptyDir": {}, + "name": "temp" + } + ], "items": { "description": "Volume represents a named volume in a pod that may be accessed by any container in the pod.", "properties": { @@ -4807,7 +4923,95 @@ "type": "object" }, "initContainers": { - "default": [], + "default": [ + { + "command": [ + "./install-dynamic-plugins.sh", + "/dynamic-plugins-root" + ], + "env": [ + { + "name": "NPM_CONFIG_USERCONFIG", + "value": "/opt/app-root/src/.npmrc.dynamic-plugins" + }, + { + "name": "MAX_ENTRY_SIZE", + "value": "40000000" + }, + { + "name": "CATALOG_INDEX_IMAGE", + "value": "{{ .Values.global.catalogIndex.image.registry }}/{{ .Values.global.catalogIndex.image.repository }}:{{ .Values.global.catalogIndex.image.tag }}" + }, + { + "name": "CATALOG_ENTITIES_EXTRACT_DIR", + "value": "/extensions" + } + ], + "image": "{{ include \"backstage.image\" . }}", + "imagePullPolicy": "", + "name": "install-dynamic-plugins", + "resources": { + "limits": { + "cpu": "1000m", + "ephemeral-storage": "5Gi", + "memory": "2.5Gi" + }, + "requests": { + "cpu": "250m", + "memory": "256Mi" + } + }, + "securityContext": { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + }, + "readOnlyRootFilesystem": true, + "runAsNonRoot": true, + "seccompProfile": { + "type": "RuntimeDefault" + } + }, + "volumeMounts": [ + { + "mountPath": "/dynamic-plugins-root", + "name": "dynamic-plugins-root" + }, + { + "mountPath": "/opt/app-root/src/dynamic-plugins.yaml", + "name": "dynamic-plugins", + "readOnly": true, + "subPath": "dynamic-plugins.yaml" + }, + { + "mountPath": "/opt/app-root/src/.npmrc.dynamic-plugins", + "name": "dynamic-plugins-npmrc", + "readOnly": true, + "subPath": ".npmrc" + }, + { + "mountPath": "/opt/app-root/src/.config/containers", + "name": "dynamic-plugins-registry-auth", + "readOnly": true + }, + { + "mountPath": "/opt/app-root/src/.npm/_cacache", + "name": "npmcacache" + }, + { + "mountPath": "/extensions", + "name": "extensions-catalog" + }, + { + "mountPath": "/tmp", + "name": "temp" + } + ], + "workingDir": "/opt/app-root/src" + } + ], "items": { "description": "A single application container that you want to run within a pod.", "properties": { @@ -6035,7 +6239,7 @@ "type": "array" }, "installDir": { - "default": "/app", + "default": "/opt/app-root/src", "title": "Directory containing the backstage installation", "type": "string" }, @@ -7043,7 +7247,7 @@ "type": "array" }, "host": { - "default": "", + "default": "{{ .Values.global.host }}", "examples": [ "backstage.10.0.0.1.nip.io" ], @@ -7138,7 +7342,7 @@ "type": "integer" } ], - "default": "http-backend", + "default": "http-metrics", "description": "The port where the metrics are exposed. If using OpenTelemetry as [documented here](https://backstage.io/docs/tutorials/setup-opentelemetry/), then the port needs to be explicitly specified. OpenTelemetry's default port is 9464.", "title": "ServiceMonitor endpoint port" } @@ -7780,7 +7984,13 @@ "type": "string" }, "extraPorts": { - "default": [], + "default": [ + { + "name": "http-metrics", + "port": 9464, + "targetPort": 9464 + } + ], "items": { "type": "object" },