Validate Helm Charts / Detect changed charts (pull_request) Successful in 3s
Validate Helm Charts / Resource quantities (pull_request) Successful in 14s
Validate Helm Charts / Build keycloak (pull_request) Successful in 4s
Validate Helm Charts / Trivy config keycloak (pull_request) Successful in 12s
Install-test / Install-test keycloak (pull_request) Successful in 3m10s
Validate Helm Charts / Install-test (pull_request) Successful in 3m10s
Publish Helm Chart with patched Application Version / publish-helm-chart (push) Successful in 7s
Publish Keycloak Helm Chart / Publish Keycloak Helm Chart (push) Successful in 7s
SonarQube Analysis / SonarQube Analysis (push) Successful in 28s
223 lines
12 KiB
YAML
223 lines
12 KiB
YAML
# CI values for the keycloak install-test.
|
|
#
|
|
# WHY THIS CHART IS TESTED RATHER THAN EXCLUDED, and what a green run is worth.
|
|
# Keycloak has no volume, needs one throwaway PostgreSQL and reaches Ready on
|
|
# its own, so an exclusion would be hard to justify. More importantly, this is
|
|
# the only place where the four riskiest assumptions of the chart are exercised
|
|
# at all - none of them is observable in a render.
|
|
#
|
|
# WHAT A GREEN RUN PROVES, point by point (the measurement points of Gitea #83):
|
|
#
|
|
# 1. THE TWO INIT CONTAINERS WORK AT ALL. The seed container copies the
|
|
# image's own augmentation output into the volume, the build container
|
|
# mounts that volume at /opt/keycloak/lib/quarkus and runs `kc.sh build`
|
|
# into it - both with readOnlyRootFilesystem: true. If the seeding
|
|
# assumption were wrong (QuarkusEntryPoint loads
|
|
# quarkus/quarkus-application.dat before it dispatches any command,
|
|
# `build` included), the build container could not start, and the pod
|
|
# would sit in Init with the reason only in its log.
|
|
# 2. readOnlyRootFilesystem: true HOLDS FOR THE SERVING CONTAINER, with
|
|
# emptyDirs only at /opt/keycloak/lib/quarkus, /opt/keycloak/data and
|
|
# /tmp - and NOT at /opt/keycloak/conf, which would hide the
|
|
# cache-ispn.xml that cache=ispn reads.
|
|
# 3. `start --optimized` ACCEPTS THE PRE-BUILT INSTALLATION and does not
|
|
# re-augment. A disagreement between the build options and the serving
|
|
# container would show up here as a crash loop rather than as a slow
|
|
# start, because the path it would want to rewrite is read-only.
|
|
# 4. TWO REPLICAS BOTH COME UP AND STAY UP against one database - the
|
|
# rollout is complete only when BOTH pods are Ready, so a second replica
|
|
# 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 - three runs, all
|
|
# three 72s and 0 restarts.
|
|
# THAT WAS LUCK, OR A FAST WEEK, AND NOT AN INVARIANT - which took an A/B
|
|
# inside Gitea PR #92 to establish, because the first five runs there made
|
|
# it look like the new theme mount had destabilized the start:
|
|
# WITH the theme mount (spec of #88)
|
|
# run 585: 101s, ONE restart on one pod
|
|
# run 590: 82s, 0
|
|
# run 593: 191s, 0
|
|
# run 595: 101s, ONE
|
|
# run 597: 111s, ONE -> 3 of 5
|
|
# WITHOUT it (the same branch, the pair commented out; pod template
|
|
# hash 5844db56b6, i.e. BYTE-IDENTICAL to the spec PR #87 measured)
|
|
# run 598: 81s, 0
|
|
# run 599: 171s, ONE -> 1 of 2
|
|
# So the restart happens WITHOUT the mount as well, and #88 is not its
|
|
# cause. It is pre-existing, intermittent behaviour of THIS chart's first
|
|
# install: always exactly one restart on one pod, 35-80s before that pod
|
|
# reports Ready. It does not track the runner's speed either - the fastest
|
|
# (81s) and the slowest (191s) run of the whole series restarted nothing.
|
|
# WHAT THE RESTART IS HAS NOT BEEN ESTABLISHED, and that is the finding
|
|
# worth keeping: the harness dumps container logs only when a run FAILS
|
|
# (diagnose() hangs off the EXIT trap behind "RC -ne 0") and all seven runs
|
|
# PASSED - A GREEN RUN CANNOT EXPLAIN A RESTART IT REPORTS. Answering it
|
|
# means making the final-state step print the restart reasons whenever a
|
|
# counter is above zero; that is a change to ci/run-install-test.sh with a
|
|
# CI-CD wiki obligation of its own, and it was deliberately NOT made inside
|
|
# #88. A first install that serializes two replicas on the Liquibase
|
|
# migration lock is a plausible place for it - stated as the hypothesis it
|
|
# is, because nothing here measured it.
|
|
# THE METHOD IS THE PART TO REUSE: a counter that moved in the same round
|
|
# as a change is not evidence against the change until the control case has
|
|
# run on the SAME machine. Three clean runs two days earlier were not that
|
|
# control, and treating them as one would have cost this PR its conclusion
|
|
# in both directions.
|
|
# 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
|
|
# container), the resource quantities are valid, and the schema accepts a
|
|
# realistic non-default values file.
|
|
#
|
|
# WHAT IT DOES NOT PROVE, and the first entry is the one not to misread:
|
|
# - THAT jdbc-ping ACTUALLY FOUND THE PEER. Two replicas both reaching Ready
|
|
# is NOT that proof, and believing it was is the mistake this paragraph
|
|
# exists to prevent: readiness reports this node's own health, so a node
|
|
# that never found its peer is Ready, healthy and alone - and two such
|
|
# nodes are two islands that each believe they are the cluster. The
|
|
# Infinispan view has to be read out of the log, which is what step 2 of
|
|
# NOTES.txt tells the operator to do. So measurement point 4 of the plan
|
|
# stays open after this test; what the test does rule out is the louder
|
|
# half (a second replica that cannot start or cannot share the database).
|
|
# - that hostname-admin serves the console cleanly on a second hostname. No
|
|
# ingress controller answers in CI and nothing drives a browser, so
|
|
# measurement point 5 stays open too. What IS checked is that both Ingress
|
|
# objects are accepted, that the Service port they name exists, and that
|
|
# Keycloak accepts both hostname values as full URLs at start.
|
|
# - anything about an upgrade. The rolling-update restriction between minor
|
|
# versions is a property of two versions meeting, and this test installs
|
|
# one.
|
|
# - that the PostgreSQL here resembles production. It is one pod with an
|
|
# emptyDir, so nothing about durability, connection limits or latency
|
|
# transfers.
|
|
|
|
secrets:
|
|
# Materialized by ci/keycloak/fixtures.yaml as ci-keycloak-db-secret and
|
|
# ci-keycloak-bootstrap-admin-secret (the OnePasswordItem stub CRD comes from
|
|
# ci/common/).
|
|
databaseSecretRef: op://ci/keycloak-db
|
|
bootstrapAdminSecretRef: op://ci/keycloak-bootstrap-admin
|
|
|
|
keycloak:
|
|
# TWO, i.e. the chart's default, and the whole reason this fixture is not a
|
|
# one-replica shortcut. With one replica the install-test would be green
|
|
# without ever showing whether the second node is found - and "a path the
|
|
# test does not walk is a path we have not proven" is the lesson Gitea #80
|
|
# paid for. The install-test script waits for the Deployment's rollout, and a
|
|
# rollout is only complete when BOTH pods are Ready, so cluster formation is
|
|
# inside the assertion rather than next to it.
|
|
replicas: 2
|
|
|
|
db:
|
|
# The throwaway PostgreSQL from fixtures.yaml. Plain Service name: both are
|
|
# in the same namespace.
|
|
host: postgres
|
|
database: keycloak
|
|
# Small but not degenerate: 2 replicas x 5 = 10 connections against
|
|
# postgres:16-alpine's default max_connections of 100, which leaves the
|
|
# fixture comfortable while still exercising the pool options.
|
|
pool:
|
|
initialSize: 1
|
|
minSize: 1
|
|
maxSize: 5
|
|
|
|
# The chart default, spelled out because it is load-bearing for what this
|
|
# test means: metrics-enabled is what puts the DATABASE check into
|
|
# /health/ready (upstream's check table, "Requires Metrics: Yes"). With it
|
|
# off, readiness would pass without ever touching the database, and a green
|
|
# run would say nothing about the connection at all.
|
|
#
|
|
# It is also a BUILD option, so with it true the init container has to build
|
|
# an installation differing from the published image in three options rather
|
|
# than two - which is what makes a build that silently did nothing fail the
|
|
# run instead of looking identical.
|
|
metrics:
|
|
enabled: true
|
|
|
|
# Set on purpose, although one release cannot collide with itself: it
|
|
# exercises the KC_CACHE_EMBEDDED_CLUSTER_NAME path, and a name Keycloak
|
|
# rejected would fail the start rather than pass unnoticed.
|
|
cache:
|
|
clusterName: ci-keycloak
|
|
|
|
resources:
|
|
# Below the chart's defaults to stay inside the runner's budget, and the
|
|
# memory number is chosen rather than rounded: the image sizes the heap at
|
|
# 70% of the LIMIT, so 600Mi x limitFactor 3 = 1800Mi gives a ~1260Mi heap.
|
|
# Upstream's floor is "at least 750 MB" for the limit; going much below
|
|
# this makes the JVM the reason a run fails.
|
|
requests:
|
|
cpu: 250m
|
|
memory: 600Mi
|
|
ephemeral-storage: 256Mi
|
|
|
|
build:
|
|
resources:
|
|
requests:
|
|
cpu: 250m
|
|
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
|
|
# ("http") actually exists - a typo there is otherwise invisible until
|
|
# somebody opens the URL.
|
|
enabled: true
|
|
domain: keycloak.ci.example.com
|
|
clusterIssuer: ci-selfsigned
|
|
admin:
|
|
# The second hostname, on as well, so the chart renders KC_HOSTNAME_ADMIN
|
|
# and Keycloak has to accept it as a full URL. That is the half of
|
|
# measurement point 5 a cluster-less test can reach: Keycloak validates
|
|
# both hostname values at start ("verified that full URL is used, incl.
|
|
# scheme and hostname"), so a chart that built a bare host here would fail
|
|
# the start instead of serving a broken console later.
|
|
enabled: true
|
|
domain: keycloak-admin.ci.example.com
|