feat(installer): add variant-aware templates for generic Kubernetes support (#2010)

## Summary

- Extend the installer chart to support generic and hosted Kubernetes
deployments via the existing `cozystackOperator.variant` parameter
(introduced in #2034)
- For `variant=generic`: render ConfigMaps (`cozystack`,
`cozystack-operator-config`) and an optional Platform Package CR —
resources previously required to be created manually before deploying on
non-Talos clusters
- Add variant validation in `packagesource.yaml` to fail fast on typos
- Publish the installer chart as an OCI Helm artifact

## Motivation

Deploying Cozystack on generic Kubernetes (k3s, kubeadm, RKE2) currently
requires manually creating ConfigMaps before applying the rendered
operator manifest. This change makes the installer chart variant-aware
so that:

1. `helm template -s` workflow continues to produce correct rendered
manifests
2. `helm install --set cozystackOperator.variant=generic` becomes a
viable single-command deployment path for generic clusters
3. Required ConfigMaps and optional Platform Package CR are generated
from values, eliminating manual steps

## OCI Helm chart publishing

The installer chart is now packaged and pushed to the OCI registry as
part of the `image` build target via `make chart`. A `.helmignore` file
ensures only chart-relevant files are included in the published
artifact.

## Test plan

- [ ] `helm template` with `variant=talos` (default) renders: operator +
PackageSource
- [ ] `helm template` with `variant=generic` renders: operator + 2
ConfigMaps + PackageSource
- [ ] `helm template` with `variant=generic` + `platform.enabled=true`
renders: + Package CR
- [ ] `helm template` with `variant=hosted` renders: operator +
PackageSource
- [ ] Invalid variant value produces a clear error message
- [ ] `make manifests` generates all asset files
- [ ] `helm package` produces a clean chart without build artifacts
This commit is contained in:
Andrei Kvapil 2026-02-16 16:49:49 +01:00 committed by GitHub
commit 84b2fa90dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 38 additions and 15 deletions

View file

@ -48,15 +48,16 @@ manifests:
> _out/assets/cozystack-operator-talos.yaml
# Generic Kubernetes variant (k3s, kubeadm, RKE2)
helm template installer packages/core/installer -n cozy-system \
--set cozystackOperator.variant=generic \
--set cozystack.apiServerHost=REPLACE_ME \
-s templates/cozystack-operator.yaml \
-s templates/packagesource.yaml \
--set cozystackOperator.variant=generic \
> _out/assets/cozystack-operator-generic.yaml
# Hosted variant (managed Kubernetes)
helm template installer packages/core/installer -n cozy-system \
--set cozystackOperator.variant=hosted \
-s templates/cozystack-operator.yaml \
-s templates/packagesource.yaml \
--set cozystackOperator.variant=hosted \
> _out/assets/cozystack-operator-hosted.yaml
cozypkg:

View file

@ -0,0 +1,11 @@
# VCS and IDE
.git
.gitignore
# Build artifacts
Makefile
images/
example/
*.tgz
# NOTE: definitions/ is intentionally NOT excluded — needed by crds.yaml via .Files.Glob

View file

@ -15,7 +15,7 @@ apply:
diff:
cozyhr show --namespace $(NAMESPACE) $(NAME) --plain | kubectl diff -f -
image: pre-checks image-operator image-packages
image: pre-checks image-operator image-packages chart
image-operator:
docker buildx build -f images/cozystack-operator/Dockerfile ../../.. \
@ -43,3 +43,9 @@ image-packages:
test -n "$$DIGEST" && \
yq -i '.cozystackOperator.platformSourceUrl = strenv(REPO)' values.yaml && \
yq -i '.cozystackOperator.platformSourceRef = "digest=" + strenv(DIGEST)' values.yaml
chart:
set -e; \
PKG=$$(helm package . --version $(COZYSTACK_VERSION) | awk '{print $$NF}'); \
trap 'rm -f "$$PKG"' EXIT; \
if [ "$(PUSH)" = "1" ]; then helm push "$$PKG" oci://$(REGISTRY); fi

View file

@ -72,20 +72,11 @@ spec:
value: "7445"
{{- else if eq .Values.cozystackOperator.variant "generic" }}
env:
# Generic Kubernetes: read from ConfigMap
# Create cozystack-operator-config ConfigMap before applying this manifest
# Generic Kubernetes: API server endpoint
- name: KUBERNETES_SERVICE_HOST
valueFrom:
configMapKeyRef:
name: cozystack-operator-config
key: KUBERNETES_SERVICE_HOST
optional: false
value: {{ required "cozystack.apiServerHost is required in generic mode" .Values.cozystack.apiServerHost | quote }}
- name: KUBERNETES_SERVICE_PORT
valueFrom:
configMapKeyRef:
name: cozystack-operator-config
key: KUBERNETES_SERVICE_PORT
optional: false
value: {{ .Values.cozystack.apiServerPort | quote }}
{{- else if eq .Values.cozystackOperator.variant "hosted" }}
# Hosted: use in-cluster service account, no env override needed
env: []

View file

@ -1,3 +1,7 @@
{{- $validVariants := list "talos" "generic" "hosted" -}}
{{- if not (has .Values.cozystackOperator.variant $validVariants) -}}
{{- fail (printf "Invalid cozystackOperator.variant %q: must be one of talos, generic, hosted" .Values.cozystackOperator.variant) -}}
{{- end -}}
---
apiVersion: cozystack.io/v1alpha1
kind: PackageSource

View file

@ -4,3 +4,13 @@ cozystackOperator:
image: ghcr.io/cozystack/cozystack/cozystack-operator:v1.0.0-beta.4@sha256:322dd7358df369525f76e6e43512482e38caec5315d36a878399d2d60bf2f18d
platformSourceUrl: 'oci://ghcr.io/cozystack/cozystack/cozystack-packages'
platformSourceRef: 'digest=sha256:b88502242b535a31ab33c06ffc0a96d1c67230d2db2c5e873fa23f6523592ff6'
# Generic variant configuration (only used when cozystackOperator.variant=generic)
cozystack:
# Kubernetes API server host (IP only, no protocol/port)
# Must be the INTERNAL IP of the control-plane node
# (the IP visible on the node's network interface, not a public/NAT IP)
# Used by the operator and networking components (cilium, kube-ovn)
apiServerHost: ""
# Kubernetes API server port
apiServerPort: "6443"