From bdf7cf022cdb603f55ae10bf9239695b7b5c0b67 Mon Sep 17 00:00:00 2001 From: feedc0de Date: Sun, 18 Oct 2026 18:57:35 +0200 Subject: [PATCH] Add maintained mosquitto Helm chart --- .gitea/workflows/ci.yml | 86 ++++++++++++++++++++++++ README.md | 16 +++++ chart/mosquitto/Chart.yaml | 6 ++ chart/mosquitto/templates/resources.yaml | 65 ++++++++++++++++++ chart/mosquitto/values.yaml | 13 ++++ install.sh | 10 +++ scripts/chart-version.sh | 9 +++ test.sh | 10 +++ 8 files changed, 215 insertions(+) create mode 100644 .gitea/workflows/ci.yml create mode 100644 README.md create mode 100644 chart/mosquitto/Chart.yaml create mode 100644 chart/mosquitto/templates/resources.yaml create mode 100644 chart/mosquitto/values.yaml create mode 100755 install.sh create mode 100755 scripts/chart-version.sh create mode 100755 test.sh diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..9b7709a --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,86 @@ +name: Validate, publish and promote mosquitto + +on: + push: + branches: [main] + pull_request: + +env: + HELM_VERSION: v4.2.2 + CHART_NAME: mosquitto + GITOPS_REPOSITORY: feedc0de/homelab-gitops + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: azure/setup-helm@v4 + with: + version: ${{ env.HELM_VERSION }} + - run: ./test.sh + + publish: + if: gitea.ref == 'refs/heads/main' + needs: validate + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: azure/setup-helm@v4 + with: + version: ${{ env.HELM_VERSION }} + - name: Publish chart + env: + PACKAGE_USERNAME: ${{ secrets.PACKAGE_USERNAME }} + PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }} + run: | + set -euo pipefail + CHART_VERSION=$(./scripts/chart-version.sh) + install -d dist + helm package "chart/${CHART_NAME}" --destination dist --version "${CHART_VERSION}" + curl --fail-with-body \ + --user "${PACKAGE_USERNAME}:${PACKAGE_TOKEN}" \ + --request POST \ + --upload-file "dist/${CHART_NAME}-${CHART_VERSION}.tgz" \ + https://code.brunner.ninja/api/packages/feedc0de/helm/api/charts + printf 'CHART_VERSION=%s\n' "${CHART_VERSION}" >> "${GITHUB_ENV}" + - name: Check that this is still current main + id: current-main + env: + COMMIT_SHA: ${{ gitea.sha }} + run: | + git fetch --no-tags origin main + if [ "$(git rev-parse FETCH_HEAD)" = "${COMMIT_SHA}" ]; then + echo 'promote=true' >> "${GITEA_OUTPUT}" + else + echo 'promote=false' >> "${GITEA_OUTPUT}" + fi + - name: Check out GitOps + if: steps.current-main.outputs.promote == 'true' + uses: actions/checkout@v4 + with: + repository: ${{ env.GITOPS_REPOSITORY }} + ref: main + token: ${{ secrets.GITOPS_TOKEN }} + path: homelab-gitops + - name: Promote exact chart version + if: steps.current-main.outputs.promote == 'true' + working-directory: homelab-gitops + run: | + set -euo pipefail + ./scripts/update-chart-version.sh "${CHART_NAME}" "${CHART_VERSION}" + git config user.name feedc0de + git config user.email feedc0de@users.noreply.code.brunner.ninja + git add "bootstrap/${CHART_NAME}.yaml" + if git diff --cached --quiet; then exit 0; fi + git commit -m "Deploy ${CHART_NAME} chart ${CHART_VERSION}" + for attempt in 1 2 3; do + if git push origin HEAD:main; then exit 0; fi + test "${attempt}" != 3 + git fetch origin main + git rebase origin/main + done diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8c063c --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# mosquitto Helm chart + +This repository maintains the public `mosquitto` Helm chart. + +```sh +helm repo add brunner.ninja https://brunner.ninja/charts +helm repo update brunner.ninja +helm upgrade --install mosquitto brunner.ninja/mosquitto +``` + +Git tags version the chart. A `v1.0.0` tag publishes chart `1.0.0`; later +commits publish immutable versions such as `1.0.0-1-gabcdef0` using +`git describe --tags --long`. + +Homelab-specific values live in +[`homelab-gitops/apps/mosquitto`](https://code.brunner.ninja/feedc0de/homelab-gitops/src/branch/main/apps/mosquitto). diff --git a/chart/mosquitto/Chart.yaml b/chart/mosquitto/Chart.yaml new file mode 100644 index 0000000..f4f87cc --- /dev/null +++ b/chart/mosquitto/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: mosquitto +description: Minimal Eclipse Mosquitto broker deployment +type: application +version: 0.1.0 +appVersion: 2.1.2 diff --git a/chart/mosquitto/templates/resources.yaml b/chart/mosquitto/templates/resources.yaml new file mode 100644 index 0000000..d34d7c4 --- /dev/null +++ b/chart/mosquitto/templates/resources.yaml @@ -0,0 +1,65 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mosquitto-config +data: + mosquitto.conf: | +{{ .Values.config | indent 4 }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mosquitto +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: {app: mosquitto} + template: + metadata: + labels: {app: mosquitto} + spec: + automountServiceAccountToken: false + containers: + - name: mosquitto + image: {{ printf "%s:%s" .Values.image.repository .Values.image.tag | quote }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: [{name: mqtt, containerPort: 1883}] + startupProbe: &probe + tcpSocket: {port: mqtt} + periodSeconds: 2 + failureThreshold: 30 + readinessProbe: + <<: *probe + periodSeconds: 5 + failureThreshold: 3 + livenessProbe: + <<: *probe + periodSeconds: 15 + failureThreshold: 3 + resources: {{- toYaml .Values.resources | nindent 10 }} + securityContext: + allowPrivilegeEscalation: false + capabilities: {drop: [ALL]} + volumeMounts: + - name: config + mountPath: /mosquitto/config/mosquitto.conf + subPath: mosquitto.conf + volumes: + - name: config + configMap: {name: mosquitto-config} +--- +apiVersion: v1 +kind: Service +metadata: + name: mosquitto + {{- with .Values.service.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- with .Values.service.loadBalancerIP }} + loadBalancerIP: {{ . }} + {{- end }} + ports: + - {name: mqtt, port: 1883, protocol: TCP, targetPort: mqtt} + selector: {app: mosquitto} diff --git a/chart/mosquitto/values.yaml b/chart/mosquitto/values.yaml new file mode 100644 index 0000000..eaa848c --- /dev/null +++ b/chart/mosquitto/values.yaml @@ -0,0 +1,13 @@ +replicaCount: 1 +image: + repository: docker.io/library/eclipse-mosquitto + tag: 2.1.2-alpine + pullPolicy: IfNotPresent +service: + type: ClusterIP + loadBalancerIP: "" + annotations: {} +config: | + listener 1883 + allow_anonymous true +resources: {} diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..4152748 --- /dev/null +++ b/install.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -eu + +namespace=${NAMESPACE:-default} +release=${RELEASE_NAME:-mosquitto} +helm repo add brunner.ninja https://brunner.ninja/charts --force-update +helm repo update brunner.ninja +helm upgrade --install "$release" brunner.ninja/mosquitto \ + --namespace "$namespace" --create-namespace \ + --wait --timeout 10m "$@" diff --git a/scripts/chart-version.sh b/scripts/chart-version.sh new file mode 100755 index 0000000..4a7ba2e --- /dev/null +++ b/scripts/chart-version.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -eu + +description=$(git describe --tags --long --match 'v[0-9]*') +version=${description#v} +case "$version" in + *-0-g*) version=${version%%-0-g*} ;; +esac +printf '%s\n' "$version" diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..258cc3a --- /dev/null +++ b/test.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -eu + +chart="chart/mosquitto" +helm lint "$chart" +rendered=$(mktemp) +trap 'rm -f "$rendered"' EXIT +helm template mosquitto "$chart" > "$rendered" +grep -q '^kind: Deployment$' "$rendered" +grep -q '^kind: Service$' "$rendered"