Support named additional Mumble services
Validate, publish and promote Mumble chart / chart (push) Failing after 33s

This commit is contained in:
2026-10-19 22:12:54 +02:00
parent 8a17ea4c1c
commit 25a7e49da2
5 changed files with 13 additions and 12 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ The PostgreSQL subchart is optional. With `postgresql.enabled=true`, set `postgr
The homelab deployment is selected in [homelab-gitops](https://code.brunner.ninja/feedc0de/homelab-gitops/src/branch/main/apps/mumble). It uses the optional PostgreSQL subchart and keeps the existing `default/mumble` Service and Deployment names, the `mumble-secrets` and TLS Secrets, and TCP/UDP port 64738. The old shared PostgreSQL database is deliberately left intact as rollback data. `bootstrap-homelab-secrets.sh` is a guarded, one-time secret recovery/bootstrap helper; it does not deploy workloads. Back up the dedicated PostgreSQL PVC and both Mumble Secrets together.
`directAccess.enabled` optionally creates a second `mumble-direct` Service on the same TCP/UDP ports. Set `directAccess.externalIPs` to addresses already routed to a cluster node. This Service uses cluster-wide endpoint routing, so an address on one node can reach a ready Mumble pod on another node. It leaves the primary LoadBalancer Service and its client-IP policy unchanged. The homelab uses this for the Funkfeuer/OLSR address on `arschrock`.
`service.additionalServices` optionally creates named additional Services on the same TCP/UDP ports. Each entry creates `mumble-<key>` and accepts Service `spec` fields such as `type` and `externalIPs`. For example, the homelab uses `service.additionalServices.funkfeuer.spec` with `type: ClusterIP` and `externalIPs: [10.12.4.170]`. This reaches a ready Mumble pod from an address routed to a cluster node and leaves the primary LoadBalancer Service and its client-IP policy unchanged.
Chart package versions come from Git tags using `git describe --tags --long`. The tag `v1.5.939` denotes the tested upstream Mumble release; a later chart-only commit publishes a distinct `1.5.939-N-gHASH` chart version. Source CI validates the chart, publishes it to the indexed `brunner.ninja` repository, and promotes only this chart's selected version in GitOps. CI has no Kubernetes credential.
@@ -1,14 +1,16 @@
{{- if and .Values.mumble.enabled .Values.directAccess.enabled }}
{{- if .Values.mumble.enabled }}
{{- range $name, $additional := .Values.service.additionalServices }}
---
apiVersion: v1
kind: Service
metadata:
name: mumble-direct
name: {{ printf "mumble-%s" $name | trunc 63 | trimSuffix "-" }}
labels:
app.kubernetes.io/name: mumble
spec:
type: ClusterIP
externalIPs:
{{ toYaml .Values.directAccess.externalIPs | indent 4 }}
{{- with $additional.spec }}
{{ toYaml . | indent 2 }}
{{- end }}
selector:
app.kubernetes.io/name: mumble
ports:
@@ -21,3 +23,4 @@ spec:
targetPort: mumble-udp
protocol: UDP
{{- end }}
{{- end }}
+1 -1
View File
@@ -4,7 +4,7 @@
"properties": {
"image": {"type": "object", "properties": {"repository": {"type": "string", "minLength": 1}, "tag": {"type": "string"}}},
"service": {"type": "object", "properties": {"type": {"enum": ["LoadBalancer", "ClusterIP"]}, "loadBalancerIP": {"type": "string"}, "externalTrafficPolicy": {"enum": ["Local", "Cluster"]}, "annotations": {"type": "object", "additionalProperties": {"type": "string"}}}},
"directAccess": {"type": "object", "properties": {"enabled": {"type": "boolean"}, "externalIPs": {"type": "array", "items": {"type": "string", "format": "ipv4"}}}, "if": {"properties": {"enabled": {"const": true}}}, "then": {"required": ["externalIPs"], "properties": {"externalIPs": {"minItems": 1}}}},
"service": {"type": "object", "properties": {"additionalServices": {"type": "object", "additionalProperties": {"type": "object", "required": ["spec"], "properties": {"spec": {"type": "object", "properties": {"type": {"enum": ["ClusterIP", "NodePort", "LoadBalancer"]}, "externalIPs": {"type": "array", "items": {"type": "string", "format": "ipv4"}}}}}}}}},
"database": {"type": "object", "properties": {"host": {"type": "string", "minLength": 1}}},
"secrets": {"type": "object", "properties": {"mumble": {"type": "string", "minLength": 1}, "postgresql": {"type": "string", "minLength": 1}, "tls": {"type": "string", "minLength": 1}}},
"config": {"type": "object", "properties": {"welcomeText": {"type": "string"}, "registrationName": {"type": "string"}, "registrationURL": {"type": "string"}, "registrationHostname": {"type": "string"}, "registrationLocation": {"type": "string"}}},
+1 -3
View File
@@ -11,9 +11,7 @@ service:
annotations: {}
loadBalancerIP: ""
externalTrafficPolicy: Local
directAccess:
enabled: false
externalIPs: []
additionalServices: {}
database:
host: postgresql
secrets:
+2 -2
View File
@@ -29,8 +29,8 @@ pod = deployment['spec']['template']['spec']
assert [container['name'] for container in pod['initContainers']] == ['render-config']
assert pod['containers'][0]['image'].endswith('v1.5.939')
assert any(volume.get('secret', {}).get('secretName') == 'mumble-tls' for volume in pod['volumes'])
direct = render('--set', 'directAccess.enabled=true', '--set', 'directAccess.externalIPs[0]=10.12.4.170')
direct_service = next(doc for doc in direct if doc['kind'] == 'Service' and doc['metadata']['name'] == 'mumble-direct')
direct = render('--set', 'service.additionalServices.funkfeuer.spec.type=ClusterIP', '--set', 'service.additionalServices.funkfeuer.spec.externalIPs[0]=10.12.4.170')
direct_service = next(doc for doc in direct if doc['kind'] == 'Service' and doc['metadata']['name'] == 'mumble-funkfeuer')
assert direct_service['spec']['externalIPs'] == ['10.12.4.170']
assert direct_service['spec']['type'] == 'ClusterIP'
assert 'externalTrafficPolicy' not in direct_service['spec']