Helm Chart for XNAT.
We are using the Helm Unittest plugin for regression testing the chart templates.
You can use the Helm Unittest docker image to run the tests.
From the top-level directory of this repo:
docker run -it --rm -v "$(pwd)/chart":/apps/chart helmunittest/helm-unittest /apps/chartThis will run all the tests in the charts/tests folder,
comparing the rendered templates to those in
charts/tests/__shapshot__.
To add a new test, add a YAML file to thecharts/tests
directory. The filename must end in _test.yaml, e.g. manifest_test.yaml.
To render the entire template:
templates:
- templates/manifest.yaml # path to your template to test
tests:
- it: manifest should match snapshot
asserts:
- matchSnapshot: {} # render and compare all fields in the templateThe first time you run the test, the template will be rendered and stored in the
charts/test/__snapshot__ directory. This
snapshot will then be used for regression testing in future test runs.
To render specific fields in the the template:
templates:
- templates/manifest.yaml # path to your template to test
tests:
- it: manifest should match snapshot
asserts:
- matchSnapshot:
path: spec.template.spec # path to a field you would like rendered in the snapshot
- matchSnapshot:
path: spec.volumeClaimTemplates # path to another field you would like rendered in the snapshotThis is useful if other parts of the template contain information that will change often, e.g. the release version of this chart.
To set values when rendering the template:
templates:
- templates/manifest.yaml # path to your template to test
tests:
- it: manifest should match snapshot
set:
config.enabled: true # override a default chart value
asserts:
- matchSnapshot: {}To update the snapshots, run the tests with the -u flag:
docker run -it --rm -v "$(pwd)/chart":/apps/chart helmunittest/helm-unittest:3.11.1-0.3.0 /apps/chart -uWe use ct for testing the chart in
CI.
To run ct locally, you will need to:
- create a local cluster
- install the CNPG operator
- create the required resources
- setup credentials for
ghcr.io/ucl-mirsg - run
ct
Create a cluster into which the chart will be installed using your preferred method. For example, using kind:
kind create cluster --name xnat --config chart/ci/kind-config.yamlWe use the CNPG Operator to deploy Postgres. The operator can be installed using Helm:
helm repo add cnpg https://cloudnative-pg.github.io/charts
helm repo update
helm upgrade --install cnpg \
--namespace cnpg-system \
--create-namespace \
cnpg/cloudnative-pgCreate the namespace:
kubectl apply -f chart/ci/manifests/namespace.yamlCreate the secret:
kubectl apply -f chart/ci/manifests/secrets.yamlYou will need to configure credentials to pull the xnat-image image from our
container registry (ghcr.io/ucl-mirsg).
Create a PAT
with read:packages scope.
To run the tests using ct:
ct install --config ct.yaml --helm-extra-set-args="--set imageCredentials.username=$GH_USER --set imageCredentials.password=$GH_PAT"Use the PAT you created above to set
imageCredentials.password.
Set imageCredential.username to be your GitHub username.
By default, ct will uninstall the chart after the tests pass. If you would
like to keep the chart installed, pass the --skip-clean-up flag to ct:
ct install --skip-clean-up --config ct.yaml --helm-extra-set-args=" --set imageCredentials.username=$GH_USER --set imageCredentials.password=$GH_PAT"This is useful if you would like to e.g. log into the XNAT UI. To do so, you will first need to forward the NGINX ingress controller port to your localhost:
kubectl port-forward --namespace=nginx-ingress service/nginx-ingress-nginx-controller 8080:80You can then go to localhost:8080 in your browser and log in with the username
mirsg_service and the serviceAdminPassword password set in the test
secrets.yaml file.
If you would like to uninstall the chart, first check the name of the installed chart:
helm list -n xnat-coreand make a note of the NAME. Then uninstall the chart:
helm uninstall <NAME> -n xnat-coreThe chart can be rendered using the default values with the following commands:
helm package --dependency-update chart
helm template xnat-core ./xnat-0.0.26.tgz > build/chart.yamlThe default values set for volumes will use emptyDir volumes. This means that
the volume shares the pod's lifetime and will be deleted when the pod is
deleted. To persist data set volumes.persistent to true and optionally set a
storage class with volumes.storageClass. For example if deploying on a local
Kubernetes cluster with k3d you can make use of the default
storage class local-path to persist data to the host. Setting
volumes.persistent to true and volumes.storageClass to local-path would
create persistent volume claims from the VolumeClaimTemplate defined by the
statefulset and dynamically provision the volumes. If you set
volumes.persistent to true and set volumes.existingClaim you will need to
manually create the persistent volume claims before deploying the chart.
| Name | Description | Value |
|---|---|---|
replicaCount |
Number of replicas | 1 |
image.pullPolicy |
image pull policy | IfNotPresent |
image.pullSecret |
Name of secret used to pull image | "" |
image.registry |
Image registry | ghcr.io |
image.namespace |
Image registry namespace | ucl-mirsg |
image.name |
Name of the image in the registry | "" |
image.tag |
Image tag | latest |
imageCredentials.enabled |
Enable or disable image pull secret | false |
imageCredentials.registry |
Image registry | "" |
imageCredentials.username |
Image registry username | "" |
imageCredentials.password |
Image registry password | "" |
imageCredentials.email |
Image registry email | "" |
nameOverride |
Override name | "" |
fullnameOverride |
Override fullname | "" |
serviceAccount.create |
Specifies whether a service account should be created | true |
serviceAccount.automount |
Automatically mount a ServiceAccount's API credentials? | true |
serviceAccount.annotations |
Annotations to add to the service account | {} |
serviceAccount.name |
The name of the service account to use. | "" |
service.port |
Service port | 80 |
service.type |
Service type | ClusterIP |
service.targetPort |
Service target port | 8080 |
volumes[0].name |
XNAT build volume name | xnat-build |
volumes[0].accessMode |
XNAT build volume access modes | ReadWriteOnce |
volumes[0].annotations |
XNAT build volume annotations | {} |
volumes[0].existingClaim |
XNAT build volume existingClaim | false |
volumes[0].persistent |
XNAT build volume persistent | true |
volumes[0].size |
XNAT build volume size | 1Gi |
volumes[0].storageClass |
XNAT build volume storageClass | nil |
volumes[1].name |
XNAT cache volume name | xnat-cache |
volumes[1].accessMode |
XNAT cache volume access modes | ReadWriteOnce |
volumes[1].annotations |
XNAT cache volume annotations | {} |
volumes[1].existingClaim |
XNAT cache volume existingClaim | false |
volumes[1].persistent |
XNAT cache volume persistent | true |
volumes[1].size |
XNAT cache volume size | 10Gi |
volumes[1].storageClass |
XNAT cache volume storageClass | nil |
volumes[2].name |
XNAT logs volume name | xnat-home-logs |
volumes[2].accessMode |
XNAT logs volume access modes | ReadWriteOnce |
volumes[2].annotations |
XNAT logs volume annotations | {} |
volumes[2].existingClaim |
XNAT logs volume existingClaim | false |
volumes[2].persistent |
XNAT logs volume persistent | true |
volumes[2].size |
XNAT logs volume size | 10Gi |
volumes[2].storageClass |
XNAT logs volume storageClass | nil |
volumes[3].name |
XNAT work volume name | xnat-home-work |
volumes[3].accessMode |
XNAT work volume access modes | ReadWriteOnce |
volumes[3].annotations |
XNAT work volume annotations | {} |
volumes[3].existingClaim |
XNAT work volume existingClaim | false |
volumes[3].persistent |
XNAT work volume persistent | true |
volumes[3].size |
XNAT work volume size | 10Gi |
volumes[3].storageClass |
XNAT work volume storageClass | nil |
volumes[4].name |
Catalina logs volume name | catalina-logs |
volumes[4].accessMode |
Catalina logs volume access modes | ReadWriteOnce |
volumes[4].annotations |
Catalina logs volume annotations | {} |
volumes[4].existingClaim |
Catalina logs volume existingClaim | false |
volumes[4].persistent |
Catalina logs volume persistent | true |
volumes[4].size |
Catalina logs volume size | 10Gi |
volumes[4].storageClass |
Catalina logs volume storageClass | nil |
volumeMounts[0].name |
XNAT build volume name | xnat-build |
volumeMounts[0].mountPath |
XNAT build volume mount path | /data/xnat/build |
volumeMounts[0].subPath |
XNAT build volume sub path | nil |
volumeMounts[1].name |
XNAT cache volume name | xnat-cache |
volumeMounts[1].mountPath |
XNAT cache volume mount path | /data/xnat/cache |
volumeMounts[1].subPath |
XNAT cache volume sub path | nil |
volumeMounts[2].name |
XNAT home logs volume name | xnat-home-logs |
volumeMounts[2].mountPath |
XNAT home logs volume mount path | /data/xnat/home/logs |
volumeMounts[2].subPath |
XNAT home logs volume sub path | nil |
volumeMounts[3].name |
XNAT home work volume name | xnat-home-work |
volumeMounts[3].mountPath |
XNAT home work volume mount path | /data/xnat/home/work |
volumeMounts[3].subPath |
XNAT home work volume sub path | nil |
volumeMounts[4].name |
Catalina logs volume name | catalina-logs |
volumeMounts[4].mountPath |
Catalina logs volume mount path | /usr/local/tomcat/logs |
volumeMounts[4].subPath |
Catalina logs volume sub path | nil |
extraVolumes[0].name |
XNAT archive volume name | xnat-archive |
extraVolumes[0].accessMode |
XNAT archive volume access modes | ReadWriteOnce |
extraVolumes[0].annotations |
XNAT archive volume annotations | {} |
extraVolumes[0].existingClaim |
XNAT archive volume existingClaim | false |
extraVolumes[0].persistent |
XNAT archive volume persistent | true |
extraVolumes[0].size |
XNAT archive volume size | 10Gi |
extraVolumes[0].storageClass |
XNAT archive volume storageClass | nil |
extraVolumes[1].name |
XNAT prearchive volume name | xnat-prearchive |
extraVolumes[1].accessMode |
XNAT prearchive volume access modes | ReadWriteOnce |
extraVolumes[1].annotations |
XNAT prearchive volume annotations | {} |
extraVolumes[1].existingClaim |
XNAT prearchive volume existingClaim | false |
extraVolumes[1].persistent |
XNAT prearchive volume persistent | true |
extraVolumes[1].size |
XNAT prearchive volume size | 10Gi |
extraVolumes[1].storageClass |
XNAT prearchive volume storageClass | nil |
extraVolumeMounts[0].name |
XNAT archive volume name | xnat-archive |
extraVolumeMounts[0].mountPath |
XNAT archive volume mount path | /data/xnat/archive |
extraVolumeMounts[0].subPath |
XNAT archive volume sub path | nil |
extraVolumeMounts[1].name |
XNAT prearchive volume name | xnat-prearchive |
extraVolumeMounts[1].mountPath |
XNAT prearchive volume mount path | /data/xnat/prearchive |
extraVolumeMounts[1].subPath |
XNAT prearchive volume sub path | nil |
csiStorageClasses |
StorageClass for CSI driver | {} |
siteUrl |
Site URL | "" |
auth.openid.provider |
OpenID provider name | openid1 |
auth.openid.enabled |
Enable or disable the config | false |
auth.openid.secretName |
Name of secret with clientID and clientSecret | openid-secret |
auth.openid.accessTokenUri |
OpenID access token URI | "" |
auth.openid.userAuthUri |
OpenID user authentication URI | "" |
auth.openid.link |
OpenID link | "" |
auth.localdb.secretName |
Name of secret with adminPassword and serviceAdminPassword | localdb-secret |
podAnnotations |
Annotations to add to the web pod | {} |
podLabels |
Labels to add to the web pod | {} |
podSecurityContext |
Pod security context | {} |
securityContext.runAsUser |
Tomcat container security context runAsUser | 1000 |
ingress.enabled |
Enable or disable the ingress deployment | false |
ingress.className |
Ingress class name | "" |
ingress.annotations |
Ingress annotations | {} |
ingress.hosts[0].host |
Ingress host | chart-example.local |
ingress.hosts[0].paths[0].path |
Ingress path | / |
ingress.hosts[0].paths[0].pathType |
Ingress path type | ImplementationSpecific |
ingress.tls |
Ingress TLS | [] |
resources.limits |
CPU and memory limits | {} |
resources.requests.cpu |
CPU and memory requests | 1 |
resources.requests.memory |
Memory requests | 2000Mi |
livenessProbe.failureThreshold |
Liveness probe failure threshold | 1 |
livenessProbe.httpGet.path |
Liveness probe httpGet path | /app/template/Login.vm#! |
livenessProbe.httpGet.port |
Liveness probe httpGet port | http |
livenessProbe.periodSeconds |
Liveness probe period seconds | 10 |
livenessProbe.timeoutSeconds |
Liveness probe timeout seconds | 5 |
readinessProbe.failureThreshold |
Readiness probe failure threshold | 1 |
readinessProbe.httpGet.path |
Readiness probe httpGet path | /app/template/Login.vm#! |
readinessProbe.httpGet.port |
Readiness probe httpGet port | http |
readinessProbe.periodSeconds |
Readiness probe period seconds | 10 |
readinessProbe.timeoutSeconds |
Readiness probe timeout seconds | 3 |
startupProbe.failureThreshold |
Startup probe failure threshold | 15 |
startupProbe.httpGet.path |
Startup probe httpGet path | /app/template/Login.vm#! |
startupProbe.httpGet.port |
Startup probe httpGet port | http |
startupProbe.periodSeconds |
Startup probe period seconds | 30 |
startupProbe.initialDelaySeconds |
Startup probe initial delay seconds | 60 |
autoscaling.enabled |
Enable or disable the autoscaling | false |
autoscaling.minReplicas |
Minimum number of replicas | 1 |
autoscaling.maxReplicas |
Maximum number of replicas | 100 |
autoscaling.targetCPUUtilizationPercentage |
Target CPU utilisation percentage | 80 |
nodeSelector |
Node selector | {} |
tolerations |
Tolerations to add to the web pod | [] |
affinity |
Affinity to add to the web pod | {} |
tomcat.catalinaOpts |
Override default CATALINA_OPTS | "" |
config.enabled |
Enable or disable the config | true |
config.image.pullPolicy |
Image pull policy | "" |
config.image.name |
Image name | xnat-config |
config.image.namespace |
Image namespace | ucl-mirsg |
config.image.registry |
Image registry | ghcr.io |
config.image.tag |
Image tag | latest |
config.jobAnnotations |
Annotations to add to the config job | {} |
config.extraWait |
Extra wait (in seconds) for admin account to be created after Tomcat has started | "" |
postgresql.enabled |
Whether to deploy a PostgreSQL cluster | true |
postgresql.backups.enabled |
Whether to enable database backups | false |
postgresql.cluster.imageName |
Name of the PostgreSQL container image | ghcr.io/cloudnative-pg/postgresql:14.17-standard-bookworm |
postgresql.cluster.instances |
Number of PostgreSQL instances | 1 |
postgresql.cluster.postgresql.parameters.shared_buffers |
Amount of memory used for shared buffers | 512MB |
postgresql.cluster.resources.requests.cpu |
CPU request | 1 |
postgresql.cluster.resources.requests.memory |
Memory request | 2Gi |
postgresql.cluster.resources.limits.cpu |
CPU limit | 2 |
postgresql.cluster.resources.limits.memory |
Memory limit | 4Gi |
postgresql.cluster.storage.size |
Size of the storage | 8Gi |
postgresql.cluster.initdb.database |
PostgreSQL database name | xnat |
postgresql.cluster.initdb.owner |
PostgreSQL owner | xnat |
postgresql.cluster.initdb.secret.name |
Name of the secret containing credentials for the database | pg-user-secret |
postgresql.version.postgresql |
PostgreSQL major version to use | 14 |
logging.enabled |
Enable or disable logging | false |