From 87fbd08f74451c18d2fdbef551d5933a78375b63 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 13 Nov 2022 22:22:07 +0100 Subject: [PATCH] helm: Add helm chart tests (#20394) * helm: Fix consistent list indentation * helm: Add helm lint and helm template tests * helm: Add helm template --validate test * helm: Add helm install test --- .github/workflows/test-chart.yml | 138 +++++++++++++++++++++ chart/.helmignore | 15 ++- chart/README.md | 2 +- chart/dev-values.yaml | 25 ++++ chart/templates/cronjob-media-remove.yaml | 14 +-- chart/templates/deployment-sidekiq.yaml | 14 +-- chart/templates/job-assets-precompile.yaml | 14 +-- chart/templates/job-chewy-upgrade.yaml | 14 +-- chart/templates/job-db-migrate.yaml | 14 +-- 9 files changed, 213 insertions(+), 37 deletions(-) create mode 100644 .github/workflows/test-chart.yml create mode 100644 chart/dev-values.yaml diff --git a/.github/workflows/test-chart.yml b/.github/workflows/test-chart.yml new file mode 100644 index 0000000000..b9ff808559 --- /dev/null +++ b/.github/workflows/test-chart.yml @@ -0,0 +1,138 @@ +# This is a GitHub workflow defining a set of jobs with a set of steps. +# ref: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions +# +name: Test chart + +on: + pull_request: + paths: + - "chart/**" + - "!**.md" + - ".github/workflows/test-chart.yml" + push: + paths: + - "chart/**" + - "!**.md" + - ".github/workflows/test-chart.yml" + branches-ignore: + - "dependabot/**" + workflow_dispatch: + +permissions: + contents: read + +defaults: + run: + working-directory: chart + +jobs: + lint-templates: + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + + - name: Install dependencies (yamllint) + run: pip install yamllint + + - run: helm dependency update + + - name: helm lint + run: | + helm lint . \ + --values dev-values.yaml + + - name: helm template + run: | + helm template . \ + --values dev-values.yaml \ + --output-dir rendered-templates + + - name: yamllint (only on templates we manage) + run: | + rm -rf rendered-templates/mastodon/charts + + yamllint rendered-templates \ + --config-data "{rules: {indentation: {spaces: 2}, line-length: disable}}" + + # This job helps us validate that rendered templates are valid k8s resources + # against a k8s api-server, via "helm template --validate", but also that a + # basic configuration can be used to successfully startup mastodon. + # + test-install: + runs-on: ubuntu-22.04 + timeout-minutes: 15 + + strategy: + fail-fast: false + matrix: + include: + # k3s-channel reference: https://update.k3s.io/v1-release/channels + - k3s-channel: latest + - k3s-channel: stable + + # This represents the oldest configuration we test against. + # + # The k8s version chosen is based on the oldest still supported k8s + # version among two managed k8s services, GKE, EKS. + # - GKE: https://endoflife.date/google-kubernetes-engine + # - EKS: https://endoflife.date/amazon-eks + # + # The helm client's version can influence what helper functions is + # available for use in the templates, currently we need v3.6.0 or + # higher. + # + - k3s-channel: v1.21 + helm-version: v3.6.0 + + steps: + - uses: actions/checkout@v3 + + # This action starts a k8s cluster with NetworkPolicy enforcement and + # installs both kubectl and helm. + # + # ref: https://github.com/jupyterhub/action-k3s-helm#readme + # + - uses: jupyterhub/action-k3s-helm@v3 + with: + k3s-channel: ${{ matrix.k3s-channel }} + helm-version: ${{ matrix.helm-version }} + metrics-enabled: false + traefik-enabled: false + docker-enabled: false + + - run: helm dependency update + + # Validate rendered helm templates against the k8s api-server + - name: helm template --validate + run: | + helm template --validate mastodon . \ + --values dev-values.yaml + + - name: helm install + run: | + helm install mastodon . \ + --values dev-values.yaml \ + --timeout 10m + + # This actions provides a report about the state of the k8s cluster, + # providing logs etc on anything that has failed and workloads marked as + # important. + # + # ref: https://github.com/jupyterhub/action-k8s-namespace-report#readme + # + - name: Kubernetes namespace report + uses: jupyterhub/action-k8s-namespace-report@v1 + if: always() + with: + important-workloads: >- + deploy/mastodon-sidekiq + deploy/mastodon-streaming + deploy/mastodon-web + job/mastodon-assets-precompile + job/mastodon-chewy-upgrade + job/mastodon-create-admin + job/mastodon-db-migrate diff --git a/chart/.helmignore b/chart/.helmignore index 886747ed0b..0cbed473aa 100644 --- a/chart/.helmignore +++ b/chart/.helmignore @@ -1,3 +1,17 @@ +# A helm chart's templates and default values can be packaged into a .tgz file. +# When doing that, not everything should be bundled into the .tgz file. This +# file describes what to not bundle. +# +# Manually added by us +# -------------------- +# +dev-values.yaml +mastodon-*.tgz + + +# Boilerplate .helmignore from `helm create mastodon` +# --------------------------------------------------- +# # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. @@ -21,4 +35,3 @@ .idea/ *.tmproj .vscode/ -mastodon-*.tgz diff --git a/chart/README.md b/chart/README.md index 272d59a81f..78d75368cc 100644 --- a/chart/README.md +++ b/chart/README.md @@ -7,7 +7,7 @@ Kubernetes cluster. The basic usage is: 1. `helm dep update` 1. `helm install --namespace mastodon --create-namespace my-mastodon ./ -f path/to/additional/values.yaml` -This chart has been tested on Helm 3.0.1 and above. +This chart is tested with k8s 1.21+ and helm 3.6.0+. # Configuration diff --git a/chart/dev-values.yaml b/chart/dev-values.yaml new file mode 100644 index 0000000000..b3a963ea11 --- /dev/null +++ b/chart/dev-values.yaml @@ -0,0 +1,25 @@ +# Chart values used for testing the Helm chart. +# +mastodon: + secrets: + secret_key_base: dummy-secret_key_base + otp_secret: dummy-otp_secret + vapid: + private_key: dummy-vapid-private_key + public_key: dummy-vapid-public_key + +# ref: https://github.com/bitnami/charts/tree/main/bitnami/redis#parameters +redis: + replica: + replicaCount: 1 + +# ref: https://github.com/bitnami/charts/tree/main/bitnami/elasticsearch#parameters +elasticsearch: + master: + replicaCount: 1 + data: + replicaCount: 1 + coordinating: + replicaCount: 1 + ingest: + replicaCount: 1 diff --git a/chart/templates/cronjob-media-remove.yaml b/chart/templates/cronjob-media-remove.yaml index b175f0ee75..41f1feb825 100644 --- a/chart/templates/cronjob-media-remove.yaml +++ b/chart/templates/cronjob-media-remove.yaml @@ -25,13 +25,13 @@ spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app.kubernetes.io/part-of - operator: In - values: - - rails - topologyKey: kubernetes.io/hostname + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/part-of + operator: In + values: + - rails + topologyKey: kubernetes.io/hostname {{- end }} volumes: - name: assets diff --git a/chart/templates/deployment-sidekiq.yaml b/chart/templates/deployment-sidekiq.yaml index 878b01150f..94af99b112 100644 --- a/chart/templates/deployment-sidekiq.yaml +++ b/chart/templates/deployment-sidekiq.yaml @@ -42,13 +42,13 @@ spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app.kubernetes.io/part-of - operator: In - values: - - rails - topologyKey: kubernetes.io/hostname + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/part-of + operator: In + values: + - rails + topologyKey: kubernetes.io/hostname {{- end }} volumes: - name: assets diff --git a/chart/templates/job-assets-precompile.yaml b/chart/templates/job-assets-precompile.yaml index 30d54b76f5..bc5ff7bfb8 100644 --- a/chart/templates/job-assets-precompile.yaml +++ b/chart/templates/job-assets-precompile.yaml @@ -25,13 +25,13 @@ spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app.kubernetes.io/part-of - operator: In - values: - - rails - topologyKey: kubernetes.io/hostname + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/part-of + operator: In + values: + - rails + topologyKey: kubernetes.io/hostname {{- end }} volumes: - name: assets diff --git a/chart/templates/job-chewy-upgrade.yaml b/chart/templates/job-chewy-upgrade.yaml index 5b22a86105..f86a4e34f6 100644 --- a/chart/templates/job-chewy-upgrade.yaml +++ b/chart/templates/job-chewy-upgrade.yaml @@ -26,13 +26,13 @@ spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app.kubernetes.io/part-of - operator: In - values: - - rails - topologyKey: kubernetes.io/hostname + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/part-of + operator: In + values: + - rails + topologyKey: kubernetes.io/hostname {{- end }} volumes: - name: assets diff --git a/chart/templates/job-db-migrate.yaml b/chart/templates/job-db-migrate.yaml index db09c6ea2b..41324fbd0c 100644 --- a/chart/templates/job-db-migrate.yaml +++ b/chart/templates/job-db-migrate.yaml @@ -25,13 +25,13 @@ spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app.kubernetes.io/part-of - operator: In - values: - - rails - topologyKey: kubernetes.io/hostname + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/part-of + operator: In + values: + - rails + topologyKey: kubernetes.io/hostname {{- end }} volumes: - name: assets