feat(keycloak): extraVolumes/extraVolumeMounts for custom themes and providers (1.1.0+up26.8.0)
Validate Helm Charts / Detect changed charts (pull_request) Successful in 11s
Validate Helm Charts / Resource quantities (pull_request) Successful in 15s
Validate Helm Charts / Build keycloak (pull_request) Successful in 4s
Validate Helm Charts / Trivy config keycloak (pull_request) Successful in 17s
Install-test / Install-test keycloak (pull_request) Successful in 3m9s
Validate Helm Charts / Install-test (pull_request) Successful in 3m9s
Validate Helm Charts / Detect changed charts (pull_request) Successful in 11s
Validate Helm Charts / Resource quantities (pull_request) Successful in 15s
Validate Helm Charts / Build keycloak (pull_request) Successful in 4s
Validate Helm Charts / Trivy config keycloak (pull_request) Successful in 17s
Install-test / Install-test keycloak (pull_request) Successful in 3m9s
Validate Helm Charts / Install-test (pull_request) Successful in 3m9s
This commit is contained in:
6 files changed
+214
-2
No files matched your search
@@ -85,6 +85,28 @@ spec:
|
||||
emptyDir: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
# A MINIMAL BUT REAL LOGIN THEME, so that the install-test actually walks the
|
||||
# path keycloak.extraVolumes exists for (Gitea #88) instead of only rendering
|
||||
# it. ci/keycloak/test-values.yaml mounts it on the SUBPATH
|
||||
# /opt/keycloak/themes/ci-theme - never on /opt/keycloak/themes itself, which
|
||||
# would hide the image's base, keycloak and keycloak.v2 themes.
|
||||
name: ci-keycloak-theme
|
||||
data:
|
||||
# A theme's layout is <theme>/<type>/theme.properties, and a ConfigMap key
|
||||
# cannot contain a slash - so the "login/" directory is produced by
|
||||
# items[].path in the volume, which can. That indirection is exactly the part
|
||||
# of the theme route a render cannot verify and a running pod can.
|
||||
theme.properties: |
|
||||
parent=keycloak.v2
|
||||
# The reason the issue was opened: Keycloak has no logo field on an identity
|
||||
# provider, so the icon on its login button comes only from a login theme.
|
||||
# Nothing in CI drives a browser, so this line is carried rather than
|
||||
# checked - what the run proves is that the theme reaches the container.
|
||||
kcLogoIdP-ci-provider = fa fa-lock
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgres
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
# that crashed, deadlocked on the schema migration lock or fought the
|
||||
# first over the database would fail the run. Measured in Gitea PR #87:
|
||||
# 71.8s from `helm install` to both Ready, 0 restarts.
|
||||
# 5. A MOUNTED LOGIN THEME SURVIVES ALL OF THAT (Gitea #88) - the full
|
||||
# argument sits at keycloak.extraVolumes further down, including what it
|
||||
# still does not prove.
|
||||
# Plus the mechanical half: the Secret key names match what the Deployment
|
||||
# references, /health/started, /health/live and /health/ready all answer on
|
||||
# the management port (so health-enabled really was baked in by the init
|
||||
@@ -124,6 +127,48 @@ keycloak:
|
||||
memory: 512Mi
|
||||
ephemeral-storage: 256Mi
|
||||
|
||||
# THE EXTRA VOLUME PAIR, WALKED RATHER THAN RENDERED (Gitea #88). The theme
|
||||
# ConfigMap comes from fixtures.yaml. Three things this puts inside the
|
||||
# assertion that no render reaches:
|
||||
#
|
||||
# 1. A MOUNT ON A SUBPATH OF A DIRECTORY THAT EXISTS IN THE IMAGE IS
|
||||
# ACCEPTED ALONGSIDE readOnlyRootFilesystem: true.
|
||||
# /opt/keycloak/themes/ci-theme does not exist in the image, so the
|
||||
# runtime has to create the mount point inside a root filesystem that is
|
||||
# about to be read-only. If that did not work, every container of this
|
||||
# pod would fail to start.
|
||||
# 2. `kc.sh build` STILL SUCCEEDS WITH THE EXTRA MOUNT PRESENT. The mounts
|
||||
# are rendered on the build init container too (that is what makes SPI
|
||||
# providers work at all), so this fixture is also the test that the extra
|
||||
# mount does not disturb the augmentation - a failure would leave the pod
|
||||
# in Init with the reason only in a log.
|
||||
# 3. `start --optimized` COMES UP WITH A RUNTIME THEME IN PLACE. The plan of
|
||||
# #88 called that "a reasoned expectation, not verified"; a Ready pod with
|
||||
# this mounted is the verification, and it is the one that matters for the
|
||||
# unusual two-init-container construction of this chart.
|
||||
#
|
||||
# WHAT IT STILL DOES NOT PROVE, and it would be easy to overclaim here: that
|
||||
# the LOGIN PAGE renders and that base/keycloak/keycloak.v2 are still listed.
|
||||
# The health endpoints answer regardless of the themes directory, and nothing
|
||||
# in this harness makes an HTTP request to / or runs a command in the pod. That
|
||||
# the subpath hides nothing is a property of the mount path rather than a
|
||||
# measurement - and the kcLogoIdP line needs a browser plus a realm setting,
|
||||
# neither of which exists in CI.
|
||||
extraVolumes:
|
||||
- name: login-theme
|
||||
configMap:
|
||||
name: ci-keycloak-theme
|
||||
items:
|
||||
- key: theme.properties
|
||||
path: login/theme.properties
|
||||
extraVolumeMounts:
|
||||
- name: login-theme
|
||||
# THE SUBPATH, AND THE WHOLE POINT OF THE EXAMPLE: a volume on
|
||||
# /opt/keycloak/themes would hide the image's own three themes and break
|
||||
# the login page while the pod stayed Ready.
|
||||
mountPath: /opt/keycloak/themes/ci-theme
|
||||
readOnly: true
|
||||
|
||||
ingress:
|
||||
# Left ON although no ingress controller answers in CI: the point is that
|
||||
# both objects are accepted and that the Service port they name BY NAME
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ type: application
|
||||
# procedure lives in NOTES.txt and on the wiki page instead of in a
|
||||
# packageRules entry. Read the "MINOR UPGRADES" section of NOTES.txt before
|
||||
# merging an app-version PR that changes the minor.
|
||||
version: 1.0.0+up26.8.0
|
||||
version: 1.1.0+up26.8.0
|
||||
appVersion: "26.8.0"
|
||||
|
||||
maintainers:
|
||||
|
||||
@@ -146,6 +146,23 @@ spec:
|
||||
mountPath: {{ include "keycloak.dataDir" . }}
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
{{- with .Values.keycloak.extraVolumeMounts }}
|
||||
# THE EXTRA MOUNTS, HERE AS WELL AS ON THE SERVING CONTAINER, AND
|
||||
# THIS OCCURRENCE IS THE LOAD-BEARING ONE (Gitea #88). Do not
|
||||
# "clean it up" to the serving container only: an SPI provider JAR
|
||||
# is a BUILD-time concern. Upstream, on adding one: "After that if
|
||||
# you are using `--optimized`, you must run the `build` command in
|
||||
# order to update the server's provider registry with the
|
||||
# implementations from the JAR file." That build is THIS container,
|
||||
# so a JAR mounted only below is absent while the registry is
|
||||
# written - it never gets registered and nothing reports it.
|
||||
#
|
||||
# One list for both places on purpose: two lists would be two
|
||||
# chances to mount an extension in the wrong one, and the wrong one
|
||||
# fails silently. The price is that every extra volume is present at
|
||||
# build time too, which values.yaml names at the value.
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
||||
# Fully qualified: an unqualified reference would resolve to Docker
|
||||
@@ -358,6 +375,13 @@ spec:
|
||||
mountPath: {{ include "keycloak.dataDir" . }}
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
{{- with .Values.keycloak.extraVolumeMounts }}
|
||||
# The extra mounts, second of the two places (see the build init
|
||||
# container above). This is where a login THEME is read - themes are
|
||||
# a runtime concern, so one mounted here takes effect even though
|
||||
# this container serves a pre-built installation.
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
# DELIBERATELY NOT MOUNTED: /opt/keycloak/conf. It is not empty in
|
||||
# the image - it carries keycloak.conf and, more importantly,
|
||||
# cache-ispn.xml, which is the Infinispan configuration cache=ispn
|
||||
@@ -371,3 +395,11 @@ spec:
|
||||
emptyDir: {}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
{{- with .Values.keycloak.extraVolumes }}
|
||||
# Verbatim, because a volume source can be any of the Kubernetes forms
|
||||
# and the chart interprets none of them. The one path rule that matters
|
||||
# is about the MOUNT and not the volume: never /opt/keycloak/themes
|
||||
# itself, which would hide the image's base, keycloak and keycloak.v2
|
||||
# themes - see values.yaml at keycloak.extraVolumes.
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -143,7 +143,15 @@
|
||||
"minAvailable": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
},
|
||||
"env": { "$ref": "#/definitions/env" }
|
||||
"env": { "$ref": "#/definitions/env" },
|
||||
"extraVolumes": {
|
||||
"description": "Additional pod volumes, rendered verbatim into the pod spec. The ITEMS stay loosely typed on purpose - a volume source can be any of the Kubernetes forms (configMap, secret, persistentVolumeClaim, emptyDir, projected, csi, ...), and a stricter schema here would reject valid configurations rather than catch mistakes; the API server validates the shape anyway. Declaring the key itself is not optional, because the levels above carry additionalProperties: false. Places files, configures nothing: an extra root CA additionally needs KC_TRUSTSTORE_PATHS (a runtime option, so keycloak.env) and a theme additionally needs to be selected per realm in Keycloak's database.",
|
||||
"type": ["array", "null"]
|
||||
},
|
||||
"extraVolumeMounts": {
|
||||
"description": "Additional volume mounts, rendered verbatim and TWICE - on the build init container as well as on the serving container (Gitea #88). That is deliberate: a login theme is read at runtime, but an SPI provider JAR must be present while `kc.sh build` writes the provider registry, or it is never registered and nothing reports it. Items loosely typed for the same reason as extraVolumes. Never mount on /opt/keycloak/themes itself - it would hide the image's base, keycloak and keycloak.v2 themes; use a subpath /opt/keycloak/themes/<name>.",
|
||||
"type": ["array", "null"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ingress": {
|
||||
|
||||
@@ -509,6 +509,111 @@ keycloak:
|
||||
# KC_SPI_* provider settings.
|
||||
env: []
|
||||
|
||||
# ADDITIONAL VOLUMES AND THEIR MOUNTS - the way a file gets into this pod at
|
||||
# all (Gitea #88). Deliberately GENERIC rather than a theme-specific key:
|
||||
# the same pair serves a custom login theme, an SPI provider JAR and an extra
|
||||
# root CA, and the chart does not have to decide how a theme is delivered
|
||||
# (ConfigMap, Secret, PVC, an init container of your own filling an
|
||||
# emptyDir). Both lists are passed through verbatim, so an entry may use any
|
||||
# Kubernetes volume source.
|
||||
#
|
||||
# THE MOUNTS ARE RENDERED TWICE - ON THE build INIT CONTAINER AND ON THE
|
||||
# SERVING CONTAINER - AND THAT IS THE POINT, NOT AN OVERSIGHT. One list, two
|
||||
# places, because the two cases are resolved at different times:
|
||||
#
|
||||
# * The SERVING container is where a THEME is read. Themes are a runtime
|
||||
# concern, so a theme mounted there takes effect in the running server
|
||||
# even though this chart serves a pre-built installation.
|
||||
# * The build INIT container is where `kc.sh build` runs (point 2 at the
|
||||
# top of this file), and a PROVIDER is a build-time concern. Upstream, on
|
||||
# dropping a provider JAR into providers/: "After that if you are using
|
||||
# `--optimized`, you must run the `build` command in order to update the
|
||||
# server's provider registry with the implementations from the JAR file."
|
||||
# This chart runs `start --optimized`, so a JAR that is mounted only on
|
||||
# the serving container is absent while the registry is written: it never
|
||||
# gets registered, the file sits there at runtime, and NOTHING reports
|
||||
# it - no error, no warning, just an extension that does nothing.
|
||||
#
|
||||
# Not on the SEED init container: it has a different layout (it only writes
|
||||
# the shared volume at /quarkus-build and runs no Keycloak command), so a
|
||||
# mount there would be pointless.
|
||||
#
|
||||
# The side effect of the second place, said out loud rather than discovered:
|
||||
# an extra volume is present AT BUILD TIME as well. For a theme that is
|
||||
# without consequence. For a Secret it means an init container of this pod
|
||||
# sees it too - the same pod either way, but it belongs stated.
|
||||
#
|
||||
# WHAT THIS PAIR DOES NOT DO: it places files, it does not configure
|
||||
# Keycloak. Two cases where that difference is the whole thing:
|
||||
#
|
||||
# * AN EXTRA ROOT CA IS NOT TRUSTED BY BEING MOUNTED. A file in the pod is
|
||||
# in no truststore; Keycloak reads one only from truststore-paths, so the
|
||||
# mount has to be accompanied by KC_TRUSTSTORE_PATHS pointing at the
|
||||
# mounted DIRECTORY. That is a RUNTIME option (checked against the 26.8.0
|
||||
# option table, where it carries no build icon), so keycloak.env above is
|
||||
# the right place for it and the build-option guard does not refuse it.
|
||||
# * A THEME IS NOT ACTIVATED BY BEING MOUNTED, AND THIS CHART CANNOT
|
||||
# ACTIVATE IT. The selection lives PER REALM in Keycloak's database
|
||||
# (Realm settings -> Themes -> Login theme). Mounting makes a theme
|
||||
# selectable, never selected - so do not go looking for a bug when a
|
||||
# freshly mounted theme changes nothing.
|
||||
#
|
||||
# THE THEME CASE, AND THE ONE MISTAKE EVERYBODY MAKES EXACTLY ONCE:
|
||||
#
|
||||
# DO NOT MOUNT ON /opt/keycloak/themes. The image's own themes live there
|
||||
# (base, keycloak, keycloak.v2) and a volume at that path HIDES ALL THREE -
|
||||
# the login page is then broken rather than merely unstyled. Mount on a
|
||||
# SUBPATH that does not exist in the image, /opt/keycloak/themes/<name>,
|
||||
# which hides nothing. Same mechanism and same class of mistake as the
|
||||
# "DELIBERATELY NOT MOUNTED: /opt/keycloak/conf" note in the Deployment,
|
||||
# where an emptyDir would hide the cache-ispn.xml that cache=ispn reads.
|
||||
#
|
||||
# extraVolumes:
|
||||
# - name: login-theme
|
||||
# configMap:
|
||||
# name: my-login-theme
|
||||
# # A theme's own layout is <theme>/<type>/theme.properties, and a
|
||||
# # ConfigMap key may not contain a slash - so the subdirectory comes
|
||||
# # from items[].path, which may.
|
||||
# items:
|
||||
# - key: theme.properties
|
||||
# path: login/theme.properties
|
||||
# extraVolumeMounts:
|
||||
# - name: login-theme
|
||||
# # NOT /opt/keycloak/themes - see above.
|
||||
# mountPath: /opt/keycloak/themes/my-theme
|
||||
# readOnly: true
|
||||
#
|
||||
# With that in place a theme.properties carrying
|
||||
#
|
||||
# parent=keycloak.v2
|
||||
# kcLogoIdP-<alias> = fa fa-lock
|
||||
#
|
||||
# is what puts an icon on an identity provider's login button - Keycloak has
|
||||
# no logo field on a provider, so a login theme is the only way to set one.
|
||||
#
|
||||
# FOUR PROPERTIES OF THE THEME ROUTE THAT COST TIME IF THEY ARE NOT KNOWN:
|
||||
#
|
||||
# 1. A ConfigMap carries binary content ONLY in binaryData (base64). An SVG
|
||||
# is text and fits in data; a PNG does not. And the 1 MiB limit per
|
||||
# ConfigMap applies - ample for a theme with SVG icons, not enough for
|
||||
# bundled web fonts, which belong in a PVC or an image of your own.
|
||||
# 2. THEMES ARE CACHED, and in production that is wanted. It means a theme
|
||||
# change takes effect only after a pod restart. Two things add up here:
|
||||
# this chart hashes no user-supplied ConfigMap either (it renders none of
|
||||
# its own - point 1 at the top of this file), so editing the theme
|
||||
# ConfigMap restarts nothing by itself. Use
|
||||
# `kubectl rollout restart deploy/<release>-keycloak-deployment`.
|
||||
# Do not configure the cache away to avoid this.
|
||||
# 3. The realm selection is not ours to make - see above.
|
||||
# 4. A CUSTOM LOGIN THEME CAN MAKE THE IDENTITY-PROVIDER BUTTONS DISAPPEAR
|
||||
# ENTIRELY when its template does not include the social fragment
|
||||
# correctly (reported repeatedly upstream, keycloak/keycloak#42711).
|
||||
# After switching a realm's theme, LOOK AT THE LOGIN PAGE - a healthy
|
||||
# pod says nothing about whether the buttons are still there.
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
ingress:
|
||||
# The PUBLIC ingress - the login endpoint, the token endpoints, the account
|
||||
# console. On by default, because an identity provider nothing can reach is
|
||||
|
||||
Reference in new issue
Block a user