Skip to content

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

Merged
Andrei Kvapil (kvaps) merged 1 commit into
mainfrom
feat/installer-generic-mode
Feb 16, 2026
Merged

feat(installer): add variant-aware templates for generic Kubernetes support#2010
Andrei Kvapil (kvaps) merged 1 commit into
mainfrom
feat/installer-generic-mode

Conversation

@lexfrei

@lexfrei Aleksei Sviridkin (lexfrei) commented Feb 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Extend the installer chart to support generic and hosted Kubernetes deployments via the existing cozystackOperator.variant parameter (introduced in [installer] Merge operator templates into single variant-based template #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

@coderabbitai

coderabbitai Bot commented Feb 10, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Add a templating "mode" parameter and mode-guards; introduce generic-mode templates and values for CozyStack, add mode validation, and update Makefile to pass --set mode=... to Helm and to build/push a chart package.

Changes

Cohort / File(s) Summary
Makefile & chart workflow
packages/core/installer/Makefile, Makefile
image target now depends on a new chart target; chart builds an OCI Helm package, optionally pushes it when PUSH=1, and cleans up. Helm template invocations are parameterized with --set mode=....
Values & defaults
packages/core/installer/values.yaml
Adds top-level mode (default "talos") and a cozystack block (rootHost, apiServerEndpoint, apiServerHost, apiServerPort, networking CIDRs) plus platform (enabled, variant) used by generic-mode templates.
Mode validation
packages/core/installer/templates/packagesource.yaml
Adds pre-flight validation: enforces .Values.mode ∈ {talos, generic, hosted} and fails with an explicit error if invalid.
Operator templates (mode-guarded)
packages/core/installer/templates/cozystack-operator.yaml, packages/core/installer/templates/cozystack-operator-generic.yaml, packages/core/installer/templates/cozystack-operator-hosted.yaml
Each operator manifest is wrapped in an if eq .Values.mode "<variant>" conditional so resources render only for the matching mode; resource definitions themselves are unchanged aside from env/config references in generic variant.
Generic-mode resources
packages/core/installer/templates/configmap-cozystack.yaml, packages/core/installer/templates/configmap-operator-config.yaml, packages/core/installer/templates/package-platform.yaml
New Helm templates that render only when .Values.mode == "generic": a cozystack ConfigMap, cozystack-operator-config ConfigMap (KUBERNETES_SERVICE_HOST/PORT), and a cozystack.cozystack-platform Package CR populated from .Values.cozystack.* and .Values.platform.*.
Helm packaging ignores
packages/core/installer/.helmignore
Adds .helmignore to exclude VCS/IDE and build artifacts (e.g., .git, Makefile, images/, example/, *.tgz) from chart packaging.

Sequence Diagram(s)

sequenceDiagram
  participant CI as Dev/CI (Makefile)
  participant Helm as Helm
  participant Chart as Installer Chart
  participant K8s as Kubernetes Manifests
  participant OCI as OCI Registry

  CI->>Helm: run `helm template` with `--set mode=<mode>`
  Helm->>Chart: render templates using `.Values.mode`
  alt mode == "generic"
    Chart-->>K8s: emit ConfigMaps + Platform Package + generic operator resources
  else mode == "talos"
    Chart-->>K8s: emit talos operator resources
  else mode == "hosted"
    Chart-->>K8s: emit hosted operator resources
  end
  CI->>CI: run `make chart` (package chart)
  CI->>OCI: push packaged chart (if PUSH=1)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nudged a mode flag, hopped through templates bright,
Talos, Generic, Hosted—each blooms into sight.
I tucked in ConfigMaps, packaged charts to play,
Pushed a tidy bundle, then munched on hay. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(installer): add variant-aware templates for generic Kubernetes support' accurately describes the main objective: introducing conditional template rendering based on deployment mode (talos/generic/hosted) to support multiple Kubernetes cluster types.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/installer-generic-mode

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as ready for review February 10, 2026 09:56
@dosubot dosubot Bot added the size/M This PR changes 30-99 lines, ignoring generated files label Feb 10, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello Aleksei Sviridkin (@lexfrei), I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the Cozystack installer's flexibility by introducing a deployment mode parameter. This allows the Helm chart to dynamically adapt to different Kubernetes environments (Talos, generic, or hosted) by conditionally deploying necessary resources. Specifically, it streamlines the deployment process for generic Kubernetes clusters by automatically generating previously manual ConfigMaps and an optional Platform Package Custom Resource, simplifying the overall installation experience.

Highlights

  • Mode-based Template Selection: Introduced a mode parameter (talos, generic, hosted) in the installer Helm chart to enable mode-specific resource deployment, allowing for conditional rendering of Kubernetes manifests.
  • Streamlined Generic Kubernetes Deployment: Automated the creation of cozystack and cozystack-operator-config ConfigMaps and an optional Platform Package Custom Resource for generic Kubernetes deployments, eliminating manual pre-configuration steps.
  • Makefile Updates: Updated the Makefile to include --set mode=X flags for helm template commands, ensuring correct manifest generation for each deployment variant (Talos, generic, hosted).

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • Makefile
    • Added --set mode=talos to the helm template command for the Talos variant.
    • Added --set mode=generic to the helm template command for the Generic Kubernetes variant.
    • Added --set mode=hosted to the helm template command for the Hosted variant.
  • packages/core/installer/templates/configmap-cozystack.yaml
    • Added a new template for a cozystack ConfigMap, which is rendered only when mode is set to generic.
  • packages/core/installer/templates/configmap-operator-config.yaml
    • Added a new template for a cozystack-operator-config ConfigMap, which is rendered only when mode is set to generic.
  • packages/core/installer/templates/cozystack-operator-generic.yaml
    • Wrapped the entire file content within a Helm if block, making it conditional on mode being generic.
  • packages/core/installer/templates/cozystack-operator-hosted.yaml
    • Wrapped the entire file content within a Helm if block, making it conditional on mode being hosted.
  • packages/core/installer/templates/cozystack-operator.yaml
    • Wrapped the entire file content within a Helm if block, making it conditional on mode being talos.
  • packages/core/installer/templates/package-platform.yaml
    • Added a new template for a Package Custom Resource, which is rendered only when mode is generic and platform.enabled is true.
  • packages/core/installer/values.yaml
    • Added a new mode field with a default value of "talos".
    • Added a new cozystack section for generic mode configuration, including rootHost, apiServerEndpoint, apiServerHost, apiServerPort, and networking CIDRs.
    • Added a new platform section for Platform Package configuration, including enabled and variant fields.
Activity
  • No review activity or comments have been recorded yet for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@dosubot dosubot Bot added the kind/feature Categorizes issue or PR as related to a new feature label Feb 10, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a 'mode' parameter to the Helm chart, allowing users to deploy Cozystack on Talos, generic Kubernetes, or hosted Kubernetes environments. The changes include modifications to the Makefile to set the mode for each variant and updates to the templates to conditionally render resources based on the selected mode. The reviewer suggested adding validation to the 'mode' parameter to ensure it is one of the expected values ('talos', 'generic', 'hosted') and to use Helm's 'required' function to fail fast if mandatory values like cozystack.rootHost, cozystack.apiServerEndpoint, and cozystack.apiServerHost are not provided in 'generic' mode.

Comment on lines +10 to +18
cozystack:
# Domain for Cozystack services (dashboard, grafana, etc.)
rootHost: ""
# Full URL to the Kubernetes API server (e.g., "https://10.0.0.1:6443")
apiServerEndpoint: ""
# 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)
apiServerHost: ""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The values cozystack.rootHost, cozystack.apiServerEndpoint, and cozystack.apiServerHost are given empty string defaults, but they appear to be required for a successful deployment in generic mode. Deploying with empty values for these settings will likely lead to a non-functional operator and related components, with failures occurring at runtime.

To improve the user experience and prevent misconfigurations, it's a best practice to use Helm's required function to fail fast during templating if a necessary value is not provided.

I suggest adding required checks in the templates where these values are used when mode is generic. For example:

In packages/core/installer/templates/configmap-cozystack.yaml:

{{- if eq .Values.mode "generic" }}
{{- required "A value for .Values.cozystack.rootHost is required in generic mode" .Values.cozystack.rootHost }}
{{- required "A value for .Values.cozystack.apiServerEndpoint is required in generic mode" .Values.cozystack.apiServerEndpoint }}
...

And in packages/core/installer/templates/configmap-operator-config.yaml:

{{- if eq .Values.mode "generic" }}
{{- required "A value for .Values.cozystack.apiServerHost is required in generic mode" .Values.cozystack.apiServerHost }}
...

This will provide a clear error message to the user if they forget to set these mandatory values.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We intentionally avoid required here because this chart uses helm template --show-only to render individual variant manifests (see Makefile manifests target). Helm evaluates ALL templates regardless of -s filtering, so required in generic-mode templates would break helm template -s templates/cozystack-operator.yaml --set mode=talos (the talos build path). Empty defaults are the trade-off for -s compatibility. Users get a clear runtime error (empty ConfigMap values → operator pod fails to start) rather than a silent success.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not applicable here — the Makefile uses helm template -s to selectively render templates for different modes. Helm evaluates all templates regardless of -s filtering, so required checks in mode-specific templates would break the build for other modes.

Comment thread packages/core/installer/values.yaml Outdated
platformSourceRef: 'digest=sha256:f59e562f2c91446117773ad457251d567706ea2964251a2b0acc65060fd1f3bc'

# Deployment mode: talos (default), generic, or hosted
mode: "talos"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The mode value determines which set of resources are rendered. Currently, if an invalid mode is provided (e.g., a typo like generc), Helm will silently produce an empty manifest for the operator, which can be confusing.

To make the chart more robust, consider adding validation to ensure mode is one of the expected values (talos, generic, hosted). You can use Helm's fail function to stop the installation with a clear error message if an invalid mode is used.

You could add a check like this, perhaps in a helper template or at the top of a main template:

{{- $validModes := list "talos" "generic" "hosted" -}}
{{- if not (has .Values.mode $validModes) -}}
{{-   fail (printf "Invalid mode: %q. Must be one of %v" .Values.mode $validModes) -}}
{{- end -}}

This will improve the chart's usability and prevent silent failures due to misconfiguration.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Added mode validation via fail in packagesource.yaml (rendered for all modes). Invalid mode now produces: Invalid mode "generc": must be one of talos, generic, hosted. Fixed in a226b55.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mode validation was added in packagesource.yaml — it will fail fast with a clear error message if someone sets an invalid mode value.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@packages/core/installer/templates/configmap-operator-config.yaml`:
- Around line 6-7: The ConfigMap namespace is templated to {{ .Release.Namespace
}} which mismatches the generic operator Deployment that expects the ConfigMap
in cozy-system; update the ConfigMap resource that defines
cozystack-operator-config to set namespace: cozy-system (so the
cozystack-operator-config ConfigMap is created in the same namespace the
Deployment cozystack-operator-generic.yaml looks in) ensuring the Deployment can
find the ConfigMap at runtime.

In `@packages/core/installer/templates/package-platform.yaml`:
- Around line 5-6: The Package CR metadata (metadata: / name:
cozystack.cozystack-platform) is missing a namespace and will be created in the
Helm release namespace; add a metadata field "namespace: cozy-system" to the
Package manifest so it matches the PackageSource and operator namespace (i.e.,
update the Package resource's metadata block to include namespace: cozy-system
alongside name: cozystack.cozystack-platform).

In `@packages/core/installer/values.yaml`:
- Around line 6-7: Add validation for .Values.mode to ensure it is one of the
allowed values ("talos","generic","hosted") to avoid silent template rendering
when a typo occurs; implement this by adding a guard at the top of a shared
template (or at the top of each operator template) that checks .Values.mode and
fails with a clear message if it is not in the allowed list (or alternatively
add a values.schema.json with an enum for mode so helm install/template will
reject invalid values); reference .Values.mode and the shared template name
(e.g., the common header partial) when implementing the check.
- Around line 10-26: The values.yaml defines empty defaults for
cozystack.rootHost, cozystack.apiServerEndpoint, and cozystack.apiServerHost
which cause silent failures in generic mode; update the Helm templates that
consume these values (e.g., configmap-operator-config.yaml, Package CR
templates) to use the Helm required function with clear messages (for example
reference .Values.cozystack.apiServerHost, .Values.cozystack.apiServerEndpoint,
.Values.cozystack.rootHost) so chart rendering fails with a helpful error when
mode=generic and these fields are missing; ensure the error messages reference
"mode=generic" and the specific field name to guide users.
🧹 Nitpick comments (3)
packages/core/installer/templates/cozystack-operator.yaml (1)

1-83: Significant duplication across mode-specific operator templates.

The three operator templates (cozystack-operator.yaml, cozystack-operator-generic.yaml, cozystack-operator-hosted.yaml) duplicate ~80 lines of identical YAML (Namespace, ServiceAccount, ClusterRoleBinding, Deployment skeleton). The only variation is the env block (lines 67–72 here). Consider extracting the shared resources into a helper template (_helpers.tpl) or a single file with mode-conditional blocks for just the env section. This reduces the maintenance burden of keeping three copies in sync whenever, e.g., a new toleration, label, or arg is added.

packages/core/installer/templates/package-platform.yaml (1)

8-8: Quote the variant value for safety.

While the current default isp-full-generic is safe, user-supplied values could contain YAML-special characters.

Proposed fix
-  variant: {{ .Values.platform.variant }}
+  variant: {{ .Values.platform.variant | quote }}
packages/core/installer/templates/configmap-cozystack.yaml (1)

1-15: Consider using required for critical networking values in generic mode.

When mode=generic, the user must supply networking parameters for the cluster to function. If any of these are omitted, the ConfigMap will silently contain empty strings, likely causing obscure failures downstream. Using Helm's required function would surface misconfiguration at install time.

♻️ Proposed fix: fail fast on missing values
 {{- if eq .Values.mode "generic" }}
 ---
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: cozystack
   namespace: {{ .Release.Namespace }}
 data:
-  root-host: {{ .Values.cozystack.rootHost | quote }}
-  api-server-endpoint: {{ .Values.cozystack.apiServerEndpoint | quote }}
-  ipv4-pod-cidr: {{ .Values.cozystack.networking.podCidr | quote }}
-  ipv4-pod-gateway: {{ .Values.cozystack.networking.podGateway | quote }}
-  ipv4-svc-cidr: {{ .Values.cozystack.networking.svcCidr | quote }}
-  ipv4-join-cidr: {{ .Values.cozystack.networking.joinCidr | quote }}
+  root-host: {{ required "cozystack.rootHost is required for generic mode" .Values.cozystack.rootHost | quote }}
+  api-server-endpoint: {{ required "cozystack.apiServerEndpoint is required for generic mode" .Values.cozystack.apiServerEndpoint | quote }}
+  ipv4-pod-cidr: {{ required "cozystack.networking.podCidr is required for generic mode" .Values.cozystack.networking.podCidr | quote }}
+  ipv4-pod-gateway: {{ required "cozystack.networking.podGateway is required for generic mode" .Values.cozystack.networking.podGateway | quote }}
+  ipv4-svc-cidr: {{ required "cozystack.networking.svcCidr is required for generic mode" .Values.cozystack.networking.svcCidr | quote }}
+  ipv4-join-cidr: {{ required "cozystack.networking.joinCidr is required for generic mode" .Values.cozystack.networking.joinCidr | quote }}
 {{- end }}

Comment thread packages/core/installer/templates/configmap-operator-config.yaml Outdated
Comment on lines +5 to +6
metadata:
name: cozystack.cozystack-platform

@coderabbitai coderabbitai Bot Feb 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Search for all Package CRs in the repo and check namespace patterns
rg -A 5 'kind: Package' packages/ --type yaml

Repository: cozystack/cozystack

Length of output: 37902


🏁 Script executed:

# Check the specific file context
cat -n packages/core/installer/templates/package-platform.yaml

Repository: cozystack/cozystack

Length of output: 788


🏁 Script executed:

# Search for other Package resource definitions to understand the pattern
fd -e yaml -path '*/templates/*' packages/core/ -exec grep -l 'kind: Package' {} \;

Repository: cozystack/cozystack

Length of output: 231


🏁 Script executed:

cat -n packages/core/installer/example/platform.yaml

Repository: cozystack/cozystack

Length of output: 648


🏁 Script executed:

# Search for any operator code that might indicate where it watches for Package resources
rg -i 'namespace.*package\|package.*namespace' packages/core/installer/ --type yaml

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

# Check if there's any documentation or comments about namespace expectations
rg -B 3 -A 3 'cozy-system' packages/core/installer/templates/

Repository: cozystack/cozystack

Length of output: 9607


Add namespace: cozy-system to the Package CR metadata.

The Package resource lacks an explicit namespace and will be created in the Helm release namespace. The related PackageSource resource explicitly specifies namespace: cozy-system for all components, and the operator runs in cozy-system. This should be made consistent:

Proposed fix
 metadata:
   name: cozystack.cozystack-platform
+  namespace: cozy-system
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
metadata:
name: cozystack.cozystack-platform
metadata:
name: cozystack.cozystack-platform
namespace: cozy-system
🤖 Prompt for AI Agents
In `@packages/core/installer/templates/package-platform.yaml` around lines 5 - 6,
The Package CR metadata (metadata: / name: cozystack.cozystack-platform) is
missing a namespace and will be created in the Helm release namespace; add a
metadata field "namespace: cozy-system" to the Package manifest so it matches
the PackageSource and operator namespace (i.e., update the Package resource's
metadata block to include namespace: cozy-system alongside name:
cozystack.cozystack-platform).

✅ Addressed in commit a226b55

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added namespace: cozy-system. Fixed in a226b55.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lexfrei Thank you for adding the namespace! This ensures the Package CR will be created in the correct cozy-system namespace consistently with the operator and PackageSource resources. 🎉


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guys, Packages are cluster-scoped resources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag CodeRabbit (@coderabbitai) in a new comment, and I'll come hopping out!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — Package is indeed cluster-scoped (+kubebuilder:resource:scope=Cluster). Removed namespace: cozy-system from the Package CR metadata. Fixed in c7a4fa4.

Comment thread packages/core/installer/values.yaml Outdated
Comment thread packages/core/installer/values.yaml Outdated
Comment on lines +10 to +26
cozystack:
# Domain for Cozystack services (dashboard, grafana, etc.)
rootHost: ""
# Full URL to the Kubernetes API server (e.g., "https://10.0.0.1:6443")
apiServerEndpoint: ""
# 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)
apiServerHost: ""
# Kubernetes API server port
apiServerPort: "6443"
# Network CIDRs (defaults match k3s)
networking:
podCidr: "10.42.0.0/16"
podGateway: "10.42.0.1"
svcCidr: "10.43.0.0/16"
joinCidr: "100.64.0.0/16"

@coderabbitai coderabbitai Bot Feb 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Empty defaults for required generic-mode fields will cause silent failures.

apiServerHost, apiServerEndpoint, and rootHost all default to "". When mode=generic, these flow into ConfigMaps and Package CRs, producing resources with empty/broken values. Consider adding required checks in the templates that consume these values so users get a clear error at render time rather than a broken deployment.

For example, in configmap-operator-config.yaml:

KUBERNETES_SERVICE_HOST: {{ required "cozystack.apiServerHost is required when mode=generic" .Values.cozystack.apiServerHost | quote }}
🤖 Prompt for AI Agents
In `@packages/core/installer/values.yaml` around lines 10 - 26, The values.yaml
defines empty defaults for cozystack.rootHost, cozystack.apiServerEndpoint, and
cozystack.apiServerHost which cause silent failures in generic mode; update the
Helm templates that consume these values (e.g., configmap-operator-config.yaml,
Package CR templates) to use the Helm required function with clear messages (for
example reference .Values.cozystack.apiServerHost,
.Values.cozystack.apiServerEndpoint, .Values.cozystack.rootHost) so chart
rendering fails with a helpful error when mode=generic and these fields are
missing; ensure the error messages reference "mode=generic" and the specific
field name to guide users.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above — required is incompatible with the helm template -s workflow used by the Makefile. Helm evaluates all templates regardless of -s filtering, so required in generic-mode templates breaks the talos/hosted build paths.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lexfrei, thank you for clarifying! That's a valid constraint—since helm template evaluates all templates regardless of -s, placing required checks in mode-specific templates would indeed break the other build variants in your Makefile.

Given that workflow, the current approach of conditional rendering with empty defaults is appropriate. Users will need to supply the required values when deploying with mode=generic, and runtime errors (e.g., from the operator trying to connect with an empty host) will surface the issue. You might consider documenting the required fields in the chart README or adding a note in the values.yaml comments to guide users, but that's entirely optional.


✏️ Learnings added
Learnt from: lexfrei
Repo: cozystack/cozystack PR: 2010
File: packages/core/installer/values.yaml:10-26
Timestamp: 2026-02-10T10:44:25.314Z
Learning: In the cozystack/cozystack repository, the Makefile uses `helm template -s` to selectively render templates for different modes (talos, generic, hosted). Because Helm evaluates all templates regardless of `-s` filtering, using `required` checks in mode-specific templates (e.g., generic-mode templates) would break the build for other modes. Therefore, avoid suggesting `required` validation for mode-specific values in Helm templates in this repository.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@dosubot dosubot Bot added size/L This PR changes 100-499 lines, ignoring generated files and removed size/M This PR changes 30-99 lines, ignoring generated files labels Feb 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/core/installer/Makefile`:
- Around line 47-50: In the chart Makefile target, ensure the built artifact
cozy-installer-$(COZYSTACK_VERSION).tgz is removed even if helm push fails: wrap
the sequence around a cleanup/trap so rm -f
cozy-installer-$(COZYSTACK_VERSION).tgz always runs (or use a single shell
invocation with `&&`/`;` plus a trap/EXIT handler) after running `helm package .
--version $(COZYSTACK_VERSION)` and `helm push ... oci://$(REGISTRY)`; reference
the chart target and variables COZYSTACK_VERSION and REGISTRY to locate where to
add the trap/combined command sequence.

Comment thread packages/core/installer/Makefile Outdated
namespace: cozy-system
data:
KUBERNETES_SERVICE_HOST: {{ required "cozystack.apiServerHost is required in generic mode" .Values.cozystack.apiServerHost | quote }}
KUBERNETES_SERVICE_PORT: {{ .Values.cozystack.apiServerPort | quote }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this required?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already mentioned above #2010 (comment)

autoMount:
enabled: true
kube-ovn:
MASTER_NODES: {{ .Values.cozystack.apiServerHost | quote }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to defer to the label selector approach with the "MASTER_NODES_LABEL" env?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — switched to MASTER_NODES_LABEL: "node-role.kubernetes.io/control-plane=true" which matches how the isp-full-generic variant configures kube-ovn in the platform chart. This lets kube-ovn auto-discover control plane nodes by label rather than relying on an explicit IP. Fixed in 750a7e1.

@lexfrei
Aleksei Sviridkin (lexfrei) force-pushed the feat/installer-generic-mode branch 2 times, most recently from c7a4fa4 to d36e8f7 Compare February 11, 2026 23:32
@lexfrei Aleksei Sviridkin (lexfrei) changed the title feat(installer): add mode-based template selection for generic Kubernetes support feat(installer): add variant-aware templates for generic Kubernetes support Feb 12, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This config map is deprecated since v1.0 and replaced by values in platform Package

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already removed in 5c35bc2 — values are now passed directly through spec.components.platform.values in package-platform.yaml.

Comment thread packages/core/installer/values.yaml Outdated
joinCidr: "100.64.0.0/16"

# Platform Package configuration (only used when cozystackOperator.variant=generic)
platform:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally this was designed to install manually.

What is proposed way now?

User might change some settings in this Package later, eg enable oidc, change hostname and so on.

We need to avoid cases when helm overriding them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is standard Helm behavior — any helm upgrade applies the values you provide, potentially overriding manual changes. Users are expected to maintain their values file, same as with any other Helm chart.

For a more robust workflow, we can recommend Helmfile in the docs — it keeps the chart reference and values together as a single declarative unit, making upgrades reproducible and safe.

The Package CR with platform.enabled=true is an optional convenience for initial bootstrap. Users who prefer full control can skip it (platform.enabled=false, the default) and create the Package CR manually.

{{- if and (eq .Values.cozystackOperator.variant "generic") .Values.platform.enabled }}
---
apiVersion: cozystack.io/v1alpha1
kind: Package

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might have potential race condition, add CRD for this CR are installed in a same helm chart

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No race condition here — Helm's built-in InstallOrder guarantees CRDs (position 13) are applied before unknown kinds (custom resources like Package, which go last).

See kind_sorter.go — the Less() method explicitly states "unknown kind is last."

In the current make manifests workflow, CRDs are rendered to a separate file (cozystack-crds.yaml) and applied independently, so ordering is also guaranteed there.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aleksei Sviridkin (@lexfrei) please take attention here

@dosubot dosubot Bot added size/M This PR changes 30-99 lines, ignoring generated files and removed size/L This PR changes 100-499 lines, ignoring generated files labels Feb 12, 2026
@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Feb 16, 2026
…upport

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
@kvaps
Andrei Kvapil (kvaps) merged commit 84b2fa9 into main Feb 16, 2026
5 checks passed
@kvaps
Andrei Kvapil (kvaps) deleted the feat/installer-generic-mode branch February 16, 2026 15:49
Andrei Kvapil (kvaps) added a commit to cozystack/website that referenced this pull request Feb 18, 2026
## Summary

- Add documentation for deploying Cozystack on non-Talos Kubernetes
distributions (k3s, kubeadm, RKE2) using the `isp-full-generic` bundle
- Align installation flow with the new Package-based configuration from
cozystack/cozystack#2010 (no manual ConfigMap creation)
- Place documentation under `/docs/v1/` to match the new versioning
structure

## Changes

- **New**: `content/en/docs/v1/install/kubernetes/generic.md` — full
deployment guide
- **Updated**: `content/en/docs/v1/install/kubernetes/_index.md` — add
Generic Kubernetes section alongside Talos methods

## Documentation Includes

- Host prerequisites (packages, kernel modules, services)
- Sysctl configuration with br_netfilter module loading
- Kubernetes distribution configs for k3s, kubeadm, and RKE2
- Step-by-step installation using operator manifest with REPLACE_ME
placeholder
- Package resource with platform configuration (networking CIDRs,
publishing host)
- Example Ansible playbooks for node preparation and deployment
- Troubleshooting section for common issues

## Related

- cozystack/cozystack#1939 (merged) — Added `isp-full-generic` bundle
- cozystack/cozystack#1950 — Tracking issue for complete non-Talos
support
- cozystack/cozystack#2010 — Variant-aware installer templates
(ConfigMap removal)

## Test Plan

- [ ] Verify Hugo builds without errors
- [ ] Review all internal links work correctly
- [ ] Test examples on k3s cluster
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/feature Categorizes issue or PR as related to a new feature lgtm This PR has been approved by a maintainer size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants