Commit Graph
554 Commits
Author SHA1 Message Date
IvanHunters 30dbb291ce feat(cluster-autoscaler): add Switch Cloud externalgrpc provider support
Patch the vendored CA chart to support extraContainers (needed for the
externalgrpc sidecar pattern) and add externalgrpc to the Deployment
render condition (upstream chart skips the Deployment when no
autoscalingGroups/autoDiscovery are set, which is the case for external
gRPC providers).

New files:
- values-switchcloud.yaml: cloudProvider=externalgrpc, switchcloud-provider
  sidecar, provider-id-setter DaemonSet via extraObjects
- sources/cluster-autoscaler-switchcloud.yaml: PackageSource for Cozystack

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
2026-05-04 21:46:22 +03:00
IvanHunters 67553e5d8e feat(talos): add openstack platform image build support
Add openstack platform profile alongside existing nocloud and metal profiles.
Enables building Talos disk images for OpenStack-based deployments (e.g. Switch Cloud).
The openstack platform reads machine config from OpenStack IMDS user-data endpoint
instead of the nocloud path, making it compatible with standard OpenStack deployments.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
2026-05-04 21:09:37 +03:00
Andrei Kvapil b5a1ae57de feat(etcd): update operator to v0.4.3 and expose S3 backup schedules (#2428)
## What this PR does

Bumps the vendored `etcd-operator` chart from `v0.4.2` to `v0.4.3` and
wires the new backup machinery through the cozystack `Etcd` app API.

Upstream v0.4.3 ships two new CRDs — `EtcdBackup` (one-shot snapshot)
and `EtcdBackupSchedule` (periodic snapshots) — along with the
`EtcdCluster.spec.bootstrap` restore field, a new `OPERATOR_IMAGE` env
on the operator deployment, and a replacement of the deprecated
`gcr.io/kubebuilder/kube-rbac-proxy` image. The chart portion of this PR
is a clean re-vendor via `make update` — no local patches.

On top of the bump, `packages/extra/etcd` exposes a new optional
`backup.*` values block. When `backup.enabled=true`, the chart renders
an `EtcdBackupSchedule` referencing the platform `EtcdCluster/etcd` and
a `Secret/etcd-s3-creds` with the S3 credentials expected by the
backup-agent. The values field names (`destinationPath`, `endpointURL`,
`s3AccessKey`, `s3SecretKey`, `schedule`) mirror the existing `postgres`
backup pattern for consistency. The chart `fail`s at template render if
any of the four required S3 fields are empty or if `destinationPath` is
malformed (missing `s3://` prefix, `//` segments, no bucket).

Test coverage: 15 `helm-unittest` cases across
`tests/backup-secret_test.yaml` and
`tests/etcd-backup-schedule_test.yaml` (wired into `make test`, picked
up by `hack/helm-unit-tests.sh`), plus three bats cases in
`hack/e2e-apps/etcd.bats` covering the baseline `Etcd` app, the `backup:
{}` default-off path, and the full `backup.enabled=true` case that
verifies the `EtcdBackupSchedule` materializes and the operator
generates the downstream `CronJob`.

`packages/core/platform/sources/etcd-operator.yaml` now sets
`upgradeCRDs: CreateReplace` on the etcd-operator component, so Flux
applies the new CRDs on upgrade of the chart instead of silently
skipping them.

Depends on #2427.

### Scope deferred to follow-ups

- The one-shot `EtcdBackup` CRD is vendored but not exposed through this
chart — users can still hand-apply the CRD directly.
- `EtcdCluster.spec.bootstrap` (restore from an existing snapshot) is
likewise vendored but not exposed. Both gaps are called out in
`packages/extra/etcd/README.md`.

### Release note

```release-note
feat(etcd): update etcd-operator to v0.4.3 and expose S3 backup schedules on the Etcd app. Set `backup.enabled=true` along with `backup.s3AccessKey`, `backup.s3SecretKey`, `backup.destinationPath`, and `backup.endpointURL` to schedule periodic snapshots.
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Scheduled S3 backups for etcd clusters (configurable cron, generated
S3 credentials) and restore/init from S3 or PVC via new backup
resources.

* **Tests**
* New end-to-end tests for etcd lifecycle and backup scenarios; added
Helm unit tests for backup templates and validations.

* **Documentation**
  * Backup configuration guide and parameter reference added.

* **Chores**
* Operator chart version bump; RBAC, webhooks, and deployment wiring
updated; added chart test target.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-01 13:16:08 +02:00
Andrei Kvapil 70e507ee5c fix(security): bump Go dependencies to clear Dependabot CVE alerts (#2494)
## What this PR does

Closes the 25 open Dependabot Go-ecosystem alerts on this repository (2
critical, 11 high, 12 moderate) by bumping the affected dependencies in
five Go modules to their latest stable versions. Splits the work into
six signed commits, one per logical block, so the diff in each commit
can be reviewed in isolation.

### Full advisory coverage

| # | Module | Severity | Package | Advisory | Title | Vulnerable |
Shipped |
|---|---|---|---|---|---|---|---|
| 29 | `go.mod` | critical | `google.golang.org/grpc` |
[GHSA-p77j-4mvh-x3m3](https://github.com/advisories/GHSA-p77j-4mvh-x3m3)
| gRPC-Go authorization bypass via missing leading slash in `:path` | `<
1.79.3` | `1.80.0` |
| 28 | `kubevirt-csi-driver/go.mod` | critical |
`google.golang.org/grpc` |
[GHSA-p77j-4mvh-x3m3](https://github.com/advisories/GHSA-p77j-4mvh-x3m3)
| gRPC-Go authorization bypass via missing leading slash in `:path` | `<
1.79.3` | `1.80.0` |
| 32 | `go.mod` | high | `go.opentelemetry.io/otel` |
[GHSA-mh2q-q3fh-2475](https://github.com/advisories/GHSA-mh2q-q3fh-2475)
| Multi-value `baggage` header extraction causes excessive allocations
(remote DoS amplification) | `>= 1.36.0, <= 1.40.0` | `1.43.0` |
| 31 | `go.mod` | high | `github.com/moby/spdystream` |
[GHSA-pc3f-x583-g7j2](https://github.com/advisories/GHSA-pc3f-x583-g7j2)
| SpdyStream: DoS on CRI | `<= 0.5.0` | `0.5.1` |
| 30 | `go.mod` | high | `go.opentelemetry.io/otel/sdk` |
[GHSA-hfvc-g4fc-pqhx](https://github.com/advisories/GHSA-hfvc-g4fc-pqhx)
| BSD `kenv` command not using absolute path enables PATH hijacking |
`>= 1.15.0, <= 1.42.0` | `1.43.0` |
| 27 | `go.mod` | high | `go.opentelemetry.io/otel/sdk` |
[GHSA-9h8m-3fm2-qjrq](https://github.com/advisories/GHSA-9h8m-3fm2-qjrq)
| OpenTelemetry Go SDK vulnerable to arbitrary code execution via PATH
hijacking | `>= 1.21.0, < 1.40.0` | `1.43.0` |
| 26 | `kubevirt-csi-driver/go.mod` | high |
`github.com/opencontainers/runc` |
[GHSA-cgrx-mc8f-2prm](https://github.com/advisories/GHSA-cgrx-mc8f-2prm)
| runc container escape and DoS due to arbitrary write gadgets and
procfs write redirects | `<= 1.2.7` | `1.4.2` |
| 25 | `kubevirt-csi-driver/go.mod` | high |
`github.com/opencontainers/runc` |
[GHSA-qw9x-cqr3-wc7r](https://github.com/advisories/GHSA-qw9x-cqr3-wc7r)
| runc container escape with malicious config due to `/dev/console`
mount and related races | `>= 1.0.0-rc3, <= 1.2.7` | `1.4.2` |
| 24 | `kubevirt-csi-driver/go.mod` | high |
`github.com/opencontainers/runc` |
[GHSA-9493-h29p-rfm2](https://github.com/advisories/GHSA-9493-h29p-rfm2)
| runc container escape via "masked path" abuse due to mount race
conditions | `<= 1.2.7` | `1.4.2` |
| 23 | `kubevirt-csi-driver/go.mod` | high | `golang.org/x/oauth2` |
[GHSA-6v2p-p543-phr9](https://github.com/advisories/GHSA-6v2p-p543-phr9)
| Improper Validation of Syntactic Correctness of Input | `< 0.27.0` |
`0.36.0` |
| 16 | `kubeovn-webhook/go.mod` | high | `golang.org/x/oauth2` |
[GHSA-6v2p-p543-phr9](https://github.com/advisories/GHSA-6v2p-p543-phr9)
| Improper Validation of Syntactic Correctness of Input | `< 0.27.0` |
`0.36.0` |
| 4 | `kubeovn-webhook/go.mod` | high | `golang.org/x/net` |
[GHSA-4374-p667-p6c8](https://github.com/advisories/GHSA-4374-p667-p6c8)
| HTTP/2 rapid reset can cause excessive work in `net/http` | `< 0.17.0`
| `0.53.0` |
| 3 | `kubeovn-webhook/go.mod` | high | `golang.org/x/net` |
[GHSA-vvpx-j8f3-3w6h](https://github.com/advisories/GHSA-vvpx-j8f3-3w6h)
| `golang.org/x/net` vulnerable to Uncontrolled Resource Consumption |
`< 0.7.0` | `0.53.0` |
| 22 | `kubevirt-csi-driver/go.mod` | medium | `golang.org/x/net` |
[GHSA-vvgc-356p-c3xw](https://github.com/advisories/GHSA-vvgc-356p-c3xw)
| `golang.org/x/net` vulnerable to Cross-site Scripting | `< 0.38.0` |
`0.53.0` |
| 21 | `kubevirt-csi-driver/go.mod` | medium | `golang.org/x/net` |
[GHSA-qxp5-gwg8-xv66](https://github.com/advisories/GHSA-qxp5-gwg8-xv66)
| HTTP Proxy bypass using IPv6 Zone IDs | `< 0.36.0` | `0.53.0` |
| 20 | `kubevirt-csi-driver/go.mod` | medium |
`github.com/opencontainers/runc` |
[GHSA-jfvp-7x6p-h2pv](https://github.com/advisories/GHSA-jfvp-7x6p-h2pv)
| runc can be confused to create empty files/directories on the host |
`< 1.1.14` | `1.4.2` |
| 19 | `go.mod` | medium | `golang.org/x/crypto` |
[GHSA-f6x5-jh6r-wrfv](https://github.com/advisories/GHSA-f6x5-jh6r-wrfv)
| `golang.org/x/crypto/ssh/agent` vulnerable to panic if message is
malformed (OOB read) | `< 0.45.0` | `0.50.0` |
| 18 | `go.mod` | medium | `golang.org/x/crypto` |
[GHSA-j5w8-q4qc-rx2x](https://github.com/advisories/GHSA-j5w8-q4qc-rx2x)
| `golang.org/x/crypto/ssh` allows an attacker to cause unbounded memory
consumption | `< 0.45.0` | `0.50.0` |
| 14 | `kubeovn-webhook/go.mod` | medium | `golang.org/x/net` |
[GHSA-vvgc-356p-c3xw](https://github.com/advisories/GHSA-vvgc-356p-c3xw)
| `golang.org/x/net` vulnerable to Cross-site Scripting | `< 0.38.0` |
`0.53.0` |
| 11 | `kubeovn-webhook/go.mod` | medium | `golang.org/x/net` |
[GHSA-qxp5-gwg8-xv66](https://github.com/advisories/GHSA-qxp5-gwg8-xv66)
| HTTP Proxy bypass using IPv6 Zone IDs | `< 0.36.0` | `0.53.0` |
| 9 | `kubeovn-webhook/go.mod` | medium | `golang.org/x/net` |
[GHSA-xrjj-mj9h-534m](https://github.com/advisories/GHSA-xrjj-mj9h-534m)
| `golang.org/x/net/http2` vulnerable to possible excessive memory
growth | `< 0.4.0` | `0.53.0` |
| 8 | `kubeovn-webhook/go.mod` | medium | `golang.org/x/net` |
[GHSA-4v7x-pqxf-cx7m](https://github.com/advisories/GHSA-4v7x-pqxf-cx7m)
| `net/http`, `x/net/http2`: close connections when receiving too many
headers | `< 0.23.0` | `0.53.0` |
| 7 | `kubeovn-webhook/go.mod` | medium | `google.golang.org/protobuf` |
[GHSA-8r3f-844c-mc37](https://github.com/advisories/GHSA-8r3f-844c-mc37)
| `protojson.Unmarshal` infinite loop on certain forms of invalid JSON |
`< 1.33.0` | `1.36.11` |
| 6 | `kubeovn-webhook/go.mod` | medium | `golang.org/x/net` |
[GHSA-qppj-fm5r-hxr3](https://github.com/advisories/GHSA-qppj-fm5r-hxr3)
| HTTP/2 Stream Cancellation Attack | `< 0.17.0` | `0.53.0` |
| 5 | `kubeovn-webhook/go.mod` | medium | `golang.org/x/net` |
[GHSA-2wrh-6pvc-2jm9](https://github.com/advisories/GHSA-2wrh-6pvc-2jm9)
| Improper rendering of text nodes in `golang.org/x/net/html` | `<
0.13.0` | `0.53.0` |

Sorted by severity (critical → high → medium), then by alert number. The
`Module` column lists the manifest path inside the repo (`go.mod` is the
root); `Vulnerable` is what GitHub flagged in the original advisory;
`Shipped` is the version this PR pins to.

### Modules bumped

1. Root `go.mod` (`github.com/cozystack/cozystack`) — purely transitive
bumps for `grpc`, `otel`, `otel/sdk`, `x/crypto`, `spdystream`.
2. `api/apps/v1alpha1/go.mod` — bumps `k8s.io/apimachinery` and
`golang.org/x/net`/`x/text` for consistency with the root module's `go
1.26.2` directive.
3. `packages/apps/kubernetes/images/kubevirt-csi-driver/go.mod` — bumps
the upstream `kubevirt.io/csi-driver` pin to its latest commit, raises
the `k8s.io/*` replace block from `v0.31.4` to `v0.36.0`, bumps `runc`
to `v1.4.2`, and adapts `main.go` to the upstream's new builder-style
API for `service.NewKubevirtCSIDriver` (the constructor was split into
`WithIdentityService` / `WithControllerService` / `WithNodeService`).
4. `packages/system/kubeovn-webhook/images/kubeovn-webhook/go.mod` —
direct bumps to `golang.org/x/net`, `golang.org/x/oauth2`,
`google.golang.org/protobuf`.
5. `packages/system/dashboard/images/token-proxy/go.mod` — bumps `jwx`,
`httprc`, `x/crypto`, `x/sys` for consistency with the root module's
directive.

All five modules now declare `go 1.26.2`. The three vendored-image
Dockerfiles (`kubevirt-csi-driver`, `kubeovn-webhook`, `token-proxy`)
move to `golang:1.26{,-alpine}`.

### First-party Dockerfile bumps

The root `go.mod` directive jump to `1.26.2` means every Dockerfile that
copies the root `go.mod` and builds a cozystack-owned binary needs a
matching base image, otherwise the in-container toolchain has to pull
`go 1.26` on the fly via `GOTOOLCHAIN=auto` at every build. Eight images
are bumped from `golang:1.25-alpine` to `golang:1.26-alpine`:
`cozystack-operator`, `cozystack-api`, `cozystack-controller`,
`backup-controller`, `backupstrategy-controller`, `flux-plunger`,
`kubeovn-plunger`, `lineage-controller-webhook`.

Vendored Dockerfiles (`kubevirt-cloud-provider`, `redis-operator`,
`keycloak-operator`, `linstor-csi`, `multus-cni`, `objectstorage`,
`s3manager`, `kamaji`) are intentionally untouched: each one fetches its
source from upstream at build time and pins its `golang:` base image to
whatever the upstream commit was tested against.

### Why bump past the advisory minimums

Bumping each affected dependency to its latest stable rather than the
lowest patched version means we pick up subsequent (non-CVE) bug fixes
for free and reduce the number of follow-up Dependabot bumps the next
reviewer has to triage. Where this required a cascading bump (e.g.
`runc` v1.4.2 only compiles together with `mount-utils` v0.32+, which
dropped the deprecated `libcontainer/userns` import path), the cascade
was followed through.

### Build verification

`go build ./...` and `go vet ./...` are clean across all five modules
locally. Two `go vet` warnings in the root module
(`pkg/lineage/lineage_test.go:76` unkeyed struct fields,
`cmd/cozypkg/cmd/add.go:521` non-constant format string) and three
`randfill.Continue` test panics in `pkg/apis/{apps,core}/install` and
`pkg/apiserver` also reproduce on `main` and are out of scope for this
PR.

### Out of scope

The `k8s.io/*` libraries in `kubeovn-webhook/go.mod` are still pinned at
`v0.26.0`; they are not flagged by Dependabot and bumping them would be
a separate, much larger maintenance change.

### Release note

```release-note
fix(security): bump Go dependencies in root, api/apps/v1alpha1, kubevirt-csi-driver, kubeovn-webhook, and token-proxy modules to clear all open Dependabot CVE alerts
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
  * Upgraded Go toolchain across components and build stages to 1.26.x.
* Updated numerous dependencies for compatibility, stability and
security (Kubernetes APIs, gRPC, OpenTelemetry, golang.org/x/*, and
related libs).
* Several containers now run as a non-root user (UID/GID 65532) to
improve runtime security.

* **Refactor**
* CSI driver initialization refactored to a builder-style pattern
enabling conditional service wiring.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-01 13:16:03 +02:00
Andrei KvapilandClaude 179b603cfc feat(talos): bump Talos to v1.13.0
Bumps Talos Linux from v1.12.7 to v1.13.0. The v1.13 release line also
contains the kernel fix for CVE-2026-31431 ("Copy Fail").

Refreshes the bundled system extension digests (amdgpu, i915, drbd, zfs)
to their 1.13.0-aligned builds.

Generated via `make update` in packages/core/talos.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
2026-04-30 23:22:04 +02:00
Andrei KvapilandClaude 8549f3b9c3 fix(talos): bump Talos to v1.12.7 (CVE-2026-31431)
Bumps Talos Linux from v1.12.6 to v1.12.7, which includes the kernel
fix for CVE-2026-31431 ("Copy Fail") — an unprivileged-to-root local
privilege escalation in the Linux kernel crypto subsystem (algif_aead).

Also refreshes the bundled system extension digests (amd-ucode, amdgpu,
bnx2-bnx2x, i915, intel-ice-firmware, qlogic-firmware, drbd, zfs) to
their 1.12.7-aligned builds.

Generated via `make update` in packages/core/talos.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
2026-04-30 23:09:31 +02:00
Aleksei Sviridkin f45facca77 feat(hami): add HAMi GPU virtualization system package (#2484)
## What this PR does

Documentation: https://github.com/cozystack/website/pull/517

Integrates [HAMi](https://github.com/Project-HAMi/HAMi) v2.8.1 (CNCF
Sandbox) into Cozystack as a system-level package for fractional GPU
sharing in tenant Kubernetes clusters.

The integration covers three layers:

- **System chart** (`packages/system/hami/`): Vendors upstream HAMi Helm
chart with device plugin, scheduler extender, mutating webhook, and
RuntimeClass configuration. The broken DRA subchart was removed — it
renders resources even when disabled and references unpublished images.

- **Kubernetes app addon** (`packages/apps/kubernetes/`): HAMi exposed
as an optional toggle (`hami.enabled`). Automatically disables GPU
Operator's native device plugin when active to avoid conflicts. Enforces
hard dependency on GPU Operator.

- **Platform registration** (`packages/core/platform/`): HAMi declared
as PackageSource with gpu-operator dependency, included in the iaas
bundle.

**Known limitation**: HAMi-core relies on a private glibc symbol
(`_dl_sym`) removed in glibc 2.34, which breaks compute isolation on
modern container images (Ubuntu 22.04+, PyTorch/TensorFlow official
images). Alpine/musl is entirely incompatible. See the package README
for details and upstream issue references.

### Screenshots

N/A — no UI changes.

### Release note

```release-note
feat(hami): add HAMi GPU virtualization as an optional system package for fractional GPU sharing. Enables memory and compute isolation for NVIDIA GPUs across tenant workloads. Integrates with GPU Operator and can be enabled per-cluster via the hami.enabled toggle. Note: compute isolation requires glibc < 2.34 in workload containers.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added HAMi GPU virtualization middleware as an optional cluster addon
to enable fractional GPU sharing.
* HAMi addon includes an enable toggle (default: disabled) and a
customizable Helm values override; when enabled it enforces GPU Operator
presence and adjusts GPU Operator values accordingly.
* New HelmRelease integration for deploying HAMi with dependency
ordering and conditional rendering.

* **Documentation**
* Added HAMi setup guide, compatibility notes, and updated cluster addon
configuration reference.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-29 16:22:58 +03:00
Timofei Larkin 69ad74e457 fix(cozystack-engine): add managed Kubernetes without visible control-plane nodes support to lineage-controller-webhook (#2481)
<!-- Thank you for making a contribution! Here are some tips for you:
- Use Conventional Commits for the PR title: `type(scope): description`
- Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore
- Scopes for system components: dashboard, platform, cilium, kube-ovn,
linstor, fluxcd, cluster-api
- Scopes for managed apps: postgres, mariadb, redis, kafka, clickhouse,
virtual-machine, kubernetes
- Scopes for development and maintenance: api, hack, tests, ci, docs,
maintenance
- Breaking changes: append `!` after type/scope (`feat(api)!: ...`) or
add a `BREAKING CHANGE:` footer
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

In environments where control-plane nodes are not available (e.g., AWS
managed nodes, Cozy-in-Cozy tenant Kubernetes clusters), the DaemonSet
cannot schedule any pods because no nodes match this selector.

## What this PR does

This PR adds ability to replace DaemonSet by Deployment with custom
number of replicas for HA purpose. Default values saves current
behavior.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Optional Deployment mode for lineage-controller-webhook with
configurable replicas
  * PodDisruptionBudget support when Deployment mode is enabled

* **Updates**
* Improved pod scheduling: node affinity replaces nodeSelector, optional
tolerations, and pod anti-affinity when using Deployment
* Clarified behavior for local API endpoint scheduling (only applies
when pod lands on nodes running an API server)

* **Documentation**
  * Added README with usage examples and parameter details
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-29 15:24:27 +04:00
Arsolitt 9b5848ed26 fix(platform): register HAMi as kubernetes-application component
The HelmRelease at packages/apps/kubernetes/templates/helmreleases/hami.yaml
references chartRef.name 'cozystack-kubernetes-application-kubevirt-kubernetes-hami',
but that component was missing from the kubernetes-application PackageSource.
The HelmRelease would sit in Stalled: ArtifactNotFound at install time.

Add kubernetes-hami next to kubernetes-gpu-operator under variant kubevirt,
mirroring the existing pattern for every other tenant-cluster addon. The
standalone cozystack.hami PackageSource is retained — same shape as
gpu-operator, which is registered both standalone (for bundles/iaas) and
as a kubernetes-application component (for tenant-cluster HelmReleases).

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-29 11:13:55 +03:00
Arsolitt f6ee54e4ea Merge remote-tracking branch 'origin/main' into feat/hami-integration
Signed-off-by: Arsolitt <arsolitt@gmail.com>

# Conflicts:
#	api/apps/v1alpha1/kubernetes/types.go
#	packages/apps/kubernetes/templates/helmreleases/gpu-operator.yaml
#	packages/system/kubernetes-rd/cozyrds/kubernetes.yaml
2026-04-28 18:58:57 +03:00
Timofei LarkinandClaude Opus 4.7 1dc02d44f4 refactor(lineage-controller-webhook): align with cozystack-api shape
Collapse the chart to a single Deployment shape that mirrors
cozystack-api: 2 replicas, soft (preferred) nodeAffinity to
node-role.kubernetes.io/control-plane via Exists, permissive
tolerations, soft podAntiAffinity on hostname, an unconditional
PodDisruptionBudget with maxUnavailable: 1, and a Service with
spec.trafficDistribution: PreferClose. The same shape works on
Talos / kubeadm / k3s and on managed Kubernetes / Cozy-in-Cozy
tenant clusters without per-distro overrides — fixing #2417 by
making the soft control-plane affinity gracefully fall back to
worker scheduling when no control-plane nodes are visible.

Drop the DaemonSet path entirely. The previous PR's deployment.enabled
toggle, the workload-kind switch in templates/workload.yaml, the
fail-guard for localK8sAPIEndpoint+nodeAffinity=[], the conditional
PDB, and the values-shape knobs for nodeAffinity and tolerations all
go away as a consequence. Override the standard Deployment fields
through the usual component-values mechanism if a non-default topology
is ever needed.

Mark localK8sAPIEndpoint.enabled deprecated and flip the default to
false. The flag injects KUBERNETES_SERVICE_HOST=status.hostIP, which
is only valid when the pod is actually scheduled on an apiserver-
bearing node. With the new soft control-plane affinity, the pod can
land off-control-plane and crash-loop. The latency motivation for the
flag is real but pending separate webhook performance work; once
addressed, the flag can be removed.

Revert all changes to packages/core/platform/images/migrations/migrations/20.
The earlier ds/...-or-deploy/... fallback was over-engineered: per
run-migrations.sh, migration 20 fires only when CURRENT < 20 (i.e.
direct upgrades from pre-0.37 to 1.3+), and that path is unsupported
anyway. The original ds/... rollout-status line is dead code on every
supported install and upgrade path.

Add helm-unittest coverage for: the default Deployment shape (replicas,
soft nodeAffinity, soft podAntiAffinity, tolerations); no env vars at
the default localK8sAPIEndpoint.enabled=false; PDB rendered
unconditionally with maxUnavailable: 1, including at replicas=1 (the
no-op case); replicas value drives spec.replicas; and that
localK8sAPIEndpoint.enabled=true does inject the env vars. The Service
test continues to assert trafficDistribution: PreferClose with no
internalTrafficPolicy.

Add a slim README documenting the topology, parameters, and the
deprecation note for localK8sAPIEndpoint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
2026-04-28 14:55:11 +03:00
Aleksei Sviridkin 3fea7cd487 fix(security): bump first-party Dockerfile builders to golang:1.26
The root go.mod now declares go 1.26.2 (raised in the first commit
of this PR). Every Dockerfile that copies the root go.mod and builds
a cozystack-owned binary has to use a matching base image, otherwise
the in-container go toolchain has to download go 1.26 on the fly
(via GOTOOLCHAIN=auto) at every build, which slows builds and breaks
in network-restricted CI sandboxes.

Bumps:
- packages/core/installer/images/cozystack-operator
- packages/system/backup-controller/images/backup-controller
- packages/system/backupstrategy-controller/images/backupstrategy-controller
- packages/system/cozystack-api/images/cozystack-api
- packages/system/cozystack-controller/images/cozystack-controller
- packages/system/flux-plunger/images/flux-plunger
- packages/system/kubeovn-plunger/images/kubeovn-plunger
- packages/system/lineage-controller-webhook/images/lineage-controller-webhook

All eight images go from golang:1.25-alpine to golang:1.26-alpine.
Also normalizes the cozystack-operator Dockerfile FROM stage keyword
from lowercase 'as' to uppercase 'AS' while touching it.

Vendored Dockerfiles (kubevirt-cloud-provider, redis-operator,
keycloak-operator, linstor-csi, multus-cni, objectstorage,
s3manager, kamaji) are intentionally untouched: they pull upstream
sources at build time and pin their go base image to whatever the
upstream commit was tested against.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 01:53:19 +03:00
Arsolitt 385ea7a17f feat(platform): register HAMi as optional system package
Add PackageSource for HAMi with dependency on gpu-operator.
Include HAMi in the iaas bundle as an optional package, allowing
host-level deployment alongside the existing kubernetes addon path.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 22:16:34 +03:00
Aleksei Sviridkin adc7abe5c1 feat(ingress): add loadBalancer exposure mode via CiliumLoadBalancerIPPool
Service.spec.externalIPs is deprecated upstream in Kubernetes v1.36
(KEP-5707, kubernetes#137293). The AllowServiceExternalIPs feature gate
is expected to default to off around v1.40 and the implementation to
be removed around v1.43. For bare-metal installs that rely on
externalIPs today, cozystack needs a migration path.

This change adds an opt-in 'loadBalancer' exposure mode for the
ingress-nginx Service:

- New platform value 'publishing.exposure' (enum: externalIPs |
  loadBalancer, default externalIPs). Plumbed through cozystack-values
  into each tenant's ingress HelmRelease via the new 'expose-mode' key.
- Unknown values and loadBalancer with an empty externalIPs list fail
  the chart render with explicit error messages, rather than silently
  producing a broken Service.
- When exposure=loadBalancer and the current namespace matches
  publishing.ingressName, the Service becomes type: LoadBalancer with
  externalTrafficPolicy: Local.
- A new template renders a CiliumLoadBalancerIPPool whose blocks come
  from publishing.externalIPs (IPv4 addresses get /32, IPv6 addresses
  get /128) and whose serviceSelector uses Cilium's synthetic
  io.kubernetes.service.namespace key combined with the standard
  app.kubernetes.io/name: ingress-nginx label. No custom label is
  written to the Service itself, avoiding cross-tenant collisions from
  user-defined labels.

Default behaviour is unchanged: without opting in, the Service is
still ClusterIP + spec.externalIPs as today.

Scope: only ingress-nginx is migrated by this setting. Other cozystack
components that still write Service.spec.externalIPs directly (notably
the vpn app) must be migrated separately before the v1.40 feature gate
flip.

Tests: packages/extra/ingress/tests/exposure_test.yaml adds 13
helm-unittest cases covering both modes, IPv4/IPv6, empty-token
filtering, unknown-mode rejection, and the non-matching-namespace
fallback.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-23 17:35:36 +03:00
cozystack-ci[bot] b52e2801b4 Prepare release v1.3.0
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-04-22 07:28:09 +00:00
Aleksei Sviridkin 6deca1b07d chore(etcd-operator): opt into CreateReplace upgrade policy for CRDs
v0.4.3 introduced new CRDs (EtcdBackup, EtcdBackupSchedule). Flux defaults to Skip on upgrade, so on existing clusters those CRDs never land without a manual kubectl apply.

Setting upgradeCRDs: CreateReplace on the etcd-operator component tells PackageReconciler to wire hr.Spec.Upgrade.Crds accordingly. etcd-operator's CRDs evolve additively between versions, so CreateReplace is safe here.

Depends on the PackageSource.Spec.Variants[].Components[].Install.UpgradeCRDs field — must ship with a cozystack-operator release that recognizes it. Without that, this field is ignored and the HelmRelease still defaults to Skip.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-20 18:59:21 +03:00
cozystack-ci[bot] 12bf6b0e26 Prepare release v1.3.0-rc.1
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-04-16 08:50:30 +00:00
myasnikovdaniil 482d813d01 Add vm-default-images package (#2258)
<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does


### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[vm-default-images] Added package that brings set of images that can be used clusterwide
[vm-disk] Updated source "image" for prettier dropdown selection
[vm-disk] Added new source for vm-disk called disk - to use as source vm-disk from same namespace.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Clone VM disks by specifying an existing vm-disk as the source.
* Global default image collection and chart to publish pre-provisioned
images.

* **UI**
* Forms provide selectable lists for default images and existing VM
disks.

* **Migration**
* Migration to rename existing image DataVolumes to the new
default-images naming and bumped migration version.

* **Documentation**
* VM disk docs and README updated to reflect image sourcing and cloning.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-16 08:05:23 +05:00
Myasnikov DaniilandClaude Opus 4.6 e6ba9817be [platform] Make vm-default-images opt-in, not default in iaas bundle
The package imports ~320Gi of golden-image PVCs (ubuntu-noble, fedora,
debian, centos, etc.) as soon as it's installed. On small test and dev
clusters that's enough to consume the entire replicated storage pool,
after which no tenant PVCs — including the ones E2E itself provisions —
can be bound. It's also unreasonable to force that cost on every iaas
user: many deployments don't need prebuilt images at all, and the ones
that do often want to curate their own subset.

Switch the bundle entry from 'package.default' to 'package.optional.default',
matching the treatment already applied to gpu-operator directly below it.
Users who want the golden images can opt in via:

    bundles:
      enabledPackages:
        - cozystack.vm-default-images

The package, its Source, and migration 38 all stay in place — nothing
else changes for users who explicitly enable it. Users who previously
relied on the bundle auto-installing it will need to add the package
to enabledPackages on upgrade; this is called out in the release note.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-15 19:47:25 +05:00
myasnikovdaniil c6739cf95a [linstor-gui] Add package for LINBIT linstor-gui web UI (#2382)
## What this PR does

Adds a new Cozystack system package `linstor-gui` that ships [LINBIT's
LINSTOR web UI](https://github.com/LINBIT/linstor-gui) (GPL-3.0) so
operators can manage nodes, resources, volumes and snapshots from a
browser instead of the `linstor` CLI.

Changes:
- `packages/system/linstor-gui/` — umbrella chart with:
- `images/linstor-gui/Dockerfile` builds the image from the upstream
`pkg.linbit.com` tarball (v2.3.0) on top of
`nginxinc/nginx-unprivileged:1.29-alpine`, mirroring the build pattern
already used for `piraeus-server` and `linstor-csi`.
- `templates/configmap-nginx.yaml` — chart-supplied `nginx.conf` that
proxies `/v1` and `/metrics` to
`linstor-controller.cozy-linstor.svc:3371` over **mTLS**, using the
existing `linstor-client-tls` secret created by the `linstor` package.
- `templates/deployment.yaml` — read-only rootfs, non-root (UID 101),
`runAsNonRoot`, `RuntimeDefault` seccomp, no SA token mounted,
`reloader.stakater.com/auto` on the Deployment.
- `templates/service.yaml` — **ClusterIP only**. No Ingress is shipped
because the LINSTOR controller API is a privileged cluster-wide storage
surface and auth depends on the deployment's OIDC setup; operators wire
up ingress + auth explicitly.
- `tests/deployment_test.yaml` — `helm-unittest` covering Service shape,
TLS secret mount, securityContext, and nginx proxy+mTLS config.
- `packages/core/platform/sources/linstor-gui.yaml` — new
`PackageSource` depending on `cozystack.linstor`.
- `packages/core/platform/templates/bundles/system.yaml` — registers
`linstor-gui` as an **optional** system package (controlled via
`bundles.enabledPackages`), alongside `velero`, `telepresence`, etc.

### Why standalone (not a sidecar in the controller pod)

LINBIT's upstream Dockerfile is designed for this standalone
reverse-proxy topology, and keeping the UI as its own Deployment means
it scales, upgrades, and restarts independently of `linstor-controller`.
The price is the small amount of mTLS config in `nginx.conf`, all of
which lives in the chart's ConfigMap.

### Release note

```release-note
[linstor-gui] Add an opt-in system package that deploys LINBIT's linstor-gui web UI alongside the LINSTOR controller. Enable via `bundles.enabledPackages: [cozystack.linstor-gui]`, then `kubectl -n cozy-linstor port-forward svc/linstor-gui 3373:80` to access.
```

## Test plan

- [ ] `make unit-tests` (requires `helm-unittest` plugin) passes on the
new `tests/deployment_test.yaml`
- [ ] `make image` in `packages/system/linstor-gui/` builds and pushes
the image
- [ ] Install the package on a dev cluster with LINSTOR already
deployed; confirm the pod comes up
- [ ] `kubectl -n cozy-linstor port-forward svc/linstor-gui 3373:80` →
browser loads the UI at `localhost:3373`
- [ ] UI lists LINSTOR nodes, storage pools and resources correctly
(proves mTLS proxy to `/v1` works)
- [ ] Disable via `bundles.enabledPackages` removal; verify the
`Package` resource is cleaned up


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* LINSTOR GUI added as an optional system package deployable to the
cozy-linstor namespace.
* Web UI serves on port 3373, proxies LINSTOR controller over mTLS, and
exposes a /healthz endpoint.
* Image build and release targets added to produce multi-arch container
images.

* **Documentation**
* New README with deployment guidance, connection examples, and
configurable options (endpoint, client secret, image, replicas).

* **Tests**
* Helm chart tests validating service, deployment, config and mTLS
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-15 17:32:50 +05:00
Myasnikov DaniilandClaude Opus 4.6 0b5a1df3c2 [platform] Bump migration targetVersion to 39 for migration 38
Address review feedback from lexfrei on migrations/38:2:
Migration 38 requires targetVersion 39 to execute, since run-migrations.sh
iterates seq $CURRENT_VERSION $((TARGET_VERSION - 1)).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-14 20:00:25 +05:00
Myasnikov DaniilandClaude Opus 4.6 b9a17295cc [platform] Wire vm-default-images into iaas bundle
The PackageSource for vm-default-images existed but was never included
in any bundle, so it would never be installed.  Add it to iaas.yaml
immediately after kubevirt-cdi (which it depends on) so it is deployed
together with the rest of the KubeVirt IaaS stack.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-14 19:59:19 +05:00
Myasnikov DaniilandClaude Opus 4.6 6b6118ce56 [platform] Add migration 38 to rename vm-image-* DataVolumes to vm-default-images-*
The vm-disk package previously referenced golden-image DataVolumes with
the prefix "vm-image-<name>" in the cozy-public namespace.  The new
vm-default-images package creates them as "vm-default-images-<name>",
so any existing vm-disk that sources an image by name would fail to
find its PVC after upgrade.

Migration 38 renames every DataVolume in cozy-public whose name starts
with "vm-image-" to "vm-default-images-" (dropping the old object and
re-creating with the new name) so live vm-disk resources keep resolving
their source PVC transparently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-14 19:59:19 +05:00
Myasnikov Daniil bec35e3aad [vm-default-images] Added new optional package
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-14 19:59:19 +05:00
Timofei Larkin a8559e1a9b [scheduler] Make cozystack-scheduler storage-aware via LINSTOR extender (#2330)
## What this PR does

Makes `cozystack-scheduler` LINSTOR storage-aware by configuring it to
call the existing `linstor-scheduler-extender` as a scheduler extender.
This fixes #2328 (phase 1): pods with both a `SchedulingClass` and
LINSTOR PVCs now get storage-locality-aware placement instead of
bypassing LINSTOR's filter/prioritize logic.

Changes:
- **linstor-scheduler package**: expose the extender sidecar (port 8099)
via a new ClusterIP Service; patch the vendored deployment to add a
`app.kubernetes.io/component: scheduler` label for clean Service
targeting
- **cozystack-scheduler package**: bump to v0.3.0 which adds
configurable `extenders` support; set the LINSTOR extender URL in
wrapper values
- **tests**: helm-unittest for extender rendering in the ConfigMap

### Release note

```release-note
[scheduler] cozystack-scheduler now calls the LINSTOR scheduler extender for storage-aware pod placement. Pods assigned to a SchedulingClass that also use LINSTOR-backed PVCs will prefer nodes with local volume replicas.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added scheduler extender support: exposes an extender Service and adds
pod metadata to enable extender routing.

* **Chores**
  * Bumped scheduler chart and image versions to 0.3.0.
* Added default extender configuration and a sample remote extender
entry.
* Updated build scripts to apply an additional patch and added a test
target.

* **Tests**
* Added Helm tests validating rendered ConfigMap with and without
extender configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-13 19:19:10 +04:00
Timofei LarkinandClaude Opus 4.6 37229aa0ac feat(scheduler): storage-aware scheduling
Expose the existing linstor-scheduler-extender sidecar as a ClusterIP
Service and configure cozystack-scheduler to call it during the
scheduling cycle. Pods with both a SchedulingClass and LINSTOR PVCs
now get storage-locality-aware placement.

- Add extender Service (port 8099) for linstor-scheduler
- Patch vendored deployment to label pods for Service selector
- Bump cozystack-scheduler to v0.3.0 (configurable extenders)
- Add "linstor" PackageSource variant with extender values
- Default variant ships without extender for non-LINSTOR clusters
- Select linstor variant in system bundle
- Add helm-unittest tests for both packages

Ref: #2328

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
2026-04-13 17:15:09 +03:00
Myasnikov DaniilandClaude Opus 4.6 ae88fe3779 [linstor-gui] Add package for LINBIT linstor-gui web UI
Ships LINBIT's LINSTOR web UI (GPL-3.0) as an opt-in system package under
packages/system/linstor-gui so operators can manage LINSTOR nodes, resources,
and volumes from a browser instead of the linstor CLI.

The UI is built from the upstream pkg.linbit.com tarball onto an
nginx-unprivileged base image. A chart-supplied nginx.conf proxies /v1 and
/metrics to the LINSTOR controller REST API over mTLS using the existing
linstor-client-tls secret created by the linstor package.

Only a ClusterIP Service is created; no Ingress is shipped, because LINSTOR's
controller API is a privileged cluster-wide storage surface and auth depends
on the deployment's OIDC setup. Operators opt in via bundles.enabledPackages
and wire up ingress + auth themselves (port-forward works out of the box).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-13 11:48:35 +05:00
Aleksei Sviridkin abd6667eb3 [cilium] Move AppArmor podAnnotations to a non-Talos-only values file
E2E revealed that the kube-apiserver rejects a DaemonSet carrying a
per-container AppArmor annotation for a container that is not present
in the pod spec:

    DaemonSet.apps 'cilium' is invalid:
    spec.template.annotations[container.apparmor.security.beta.kubernetes.io/mount-cgroup]:
    Invalid value: 'mount-cgroup': container not found

On Talos (isp-full bundle) values-talos.yaml sets
cgroup.autoMount.enabled=false, so the upstream chart does not render
the mount-cgroup init container, and our unconditional podAnnotations
entry for it becomes an invalid reference.

Move the podAnnotations block from the shared values.yaml into a new
values-apparmor.yaml and include it only in the cilium-generic and
kubeovn-cilium-generic PackageSource variants, where
cgroup.autoMount.enabled is explicitly true. Talos variants
(cilium, cilium-kilo, kubeovn-cilium) get no AppArmor annotations,
which is safe because the Talos kernel does not load the AppArmor
LSM anyway.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-11 16:39:58 +03:00
Myasnikov Daniil a3f50ba2bd Fix system postgresql images to 17.7-standard-trixie
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-10 12:47:46 +05:00
Andrei Kvapil 94223327fe Release v1.2.1 (#2306)
This PR prepares the release `v1.2.1`.
2026-04-02 18:56:08 +02:00
IvanHunters fd1714442e feat(postgres): hardcode PostgreSQL 17 for monitoring and add migration
Add migration 37 to backfill spec.version=v17 for existing PostgreSQL
resources without a version set.

Hardcode PostgreSQL 17.7 image in monitoring databases (Grafana and Alerta)
to ensure compatibility with monitoring queries that expect PostgreSQL 17
features (pg_stat_checkpointer, updated pg_stat_bgwriter).

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
2026-03-31 00:46:47 +03:00
Andrei Kvapil acd1933bae fix(platform): propagate resource allocation ratios to packages (#2296)
## What this PR does

Fixes a regression introduced in the bundle restructure (2d022e38) where
`cpuAllocationRatio`, `memoryAllocationRatio`, and
`ephemeralStorageAllocationRatio` from `platform/values.yaml` became
no-ops — never propagated to child packages.

The old monolithic bundles read these values from the cozystack
ConfigMap via `lookup` and passed them explicitly. After migration to
the Package CRD model, the bridge was lost: cozy-lib expects the ratios
in `_cluster` config (via `cozystack-values` Secret), but platform never
wrote them there, so the hardcoded defaults (10, 1, 40) were always used
regardless of what the user configured.

This commit restores the propagation by:
- Adding `cpu-allocation-ratio`, `memory-allocation-ratio`, and
`ephemeral-storage-allocation-ratio` to the `_cluster` section in the
`cozystack-values` Secret, so cozy-lib in all managed applications picks
them up
- Passing `cpuAllocationRatio` to the kubevirt Package component values,
so the KubeVirt CR gets the configured value

### Release note

```release-note
[platform] Fix propagation of resource allocation ratios (cpu, memory, ephemeral-storage) to managed applications and KubeVirt, which were silently ignored since the bundle restructure.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Added new resource allocation configuration fields to platform
templates for flexible resource management.
* Enhanced conditional handling of resource settings within container
infrastructure components.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-30 20:15:07 +02:00
Andrei Kvapil d6b2b412f4 [vm-instance] Rename subnets to networks and add dropdown selector (#2263)
## What this PR does

Renames the misleading `subnets` field to `networks` in VMInstance. The
old field
name implied the VM was creating subnets, when in reality it attaches
the VM to
existing VPC network attachments (NetworkAttachmentDefinitions). This
change:

- Adds a new `networks` field as the primary way to attach VMs to VPC
networks
- Keeps `subnets` as deprecated with backward-compatible fallback via
Helm `default`
- Fails with a clear error if both `networks` and `subnets` are set
simultaneously
- Adds an API-backed dropdown selector for `networks[].name` listing
available
  NetworkAttachmentDefinitions in the namespace
- Hides the deprecated `subnets` field from the dashboard UI

### Release note

```release-note
[vm-instance] Rename `subnets` field to `networks` in VMInstance for clarity.
The old `subnets` field is deprecated but still supported for backward compatibility.
A dropdown selector for available networks has been added to the dashboard.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added native networks field for VM attachments and a UI dropdown to
select network attachments; UI hides deprecated subnet fields for VM
instances.

* **Deprecations**
* subnets is deprecated; use networks moving forward (subnets retained
for backward compatibility).

* **Chores / Migration**
* Added a migration to copy existing subnets into networks and bumped
platform migration target version.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-30 20:07:44 +02:00
myasnikovdaniil 364653508f [platform] Prevent installed packages deletion (#2273)
<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does

Adds annotation `helm.sh/resource-policy: keep` to all packages to
prevent its automatic deletion when:
1, Package added to `disabledPackages` parameter in
`cozystack.cozystack-platform` package
2. Package removed form `enabledPackages` parameter in
`cozystack.cozystack-platform` package

This change bring back [docs explained
behavior](https://cozystack.io/docs/v1/operations/configuration/components/)
- platform administrator should manually delete package if needed.

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[platform] Prevent installed packages deletion
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated Helm templates to configure resource-policy annotations on
package resources, ensuring proper resource lifecycle management and
retention policies during cluster deployments.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-30 21:36:45 +05:00
Kirill Ilin c73f677c79 fix(vm-instance): remove fail on both networks and subnets set
After migration 36 copies subnets to networks, both fields are populated.
The fail guard would break Helm reconciliation. Instead, networks simply
takes priority via the existing default fallback.

Also handle missing VMInstance CRD gracefully in migration 36.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-03-30 11:11:56 +05:00
Kirill Ilin 149cb67692 feat(platform): add migration 36 to copy subnets to networks in VMInstance
Existing VMInstance resources store network attachments in the deprecated
spec.subnets field. This migration copies subnets to the new spec.networks
field so the dashboard UI correctly displays attached networks. The old
subnets field is kept intact because migrations run before the new CRD is
applied.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-03-30 10:59:03 +05:00
Kirill Ilin b42a8ed7e4 fix(platform): propagate resource allocation ratios to packages
Since the bundle restructure in 2d022e38, the cpuAllocationRatio,
memoryAllocationRatio and ephemeralStorageAllocationRatio values from
platform values.yaml were no longer propagated to child packages.

The old monolithic bundles read these values from the cozystack
ConfigMap via lookup and passed them explicitly. After migration to
the Package CRD model, the bridge was lost: cozy-lib expects the
ratios in _cluster config (via cozystack-values Secret), but platform
never wrote them there, so the hardcoded defaults were always used.

This commit restores the propagation by:
- Adding cpu/memory/ephemeral-storage allocation ratios to the
  _cluster section in the cozystack-values Secret, so cozy-lib in
  all managed applications picks them up.
- Passing cpuAllocationRatio to the kubevirt Package component, so
  the KubeVirt CR gets the configured value.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-03-30 09:50:08 +05:00
cozystack-bot c652e1e0f9 Prepare release v1.2.0
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-03-27 14:00:46 +00:00
Andrei Kvapil 73ad82a00c [talos] Bump Talos to v1.12.6 (#2254)
## What this PR does

Bumps Talos OS from v1.12.1 to v1.12.6 across all image build profiles
(initramfs, installer, iso, kernel, metal, nocloud). Updates all system
extension image references and digests accordingly:

- amd-ucode: 20251125 → 20260309
- amdgpu: 20251125-v1.12.1 → 20260309-v1.12.6
- bnx2-bnx2x: 20251125 → 20260309
- intel-ice-firmware: 20251125 → 20260309
- i915: 20251125-v1.12.1 → 20260309-v1.12.6
- intel-ucode: 20251111 → 20260227
- qlogic-firmware: 20251125 → 20260309
- drbd: 9.2.16-v1.12.1 → 9.2.16-v1.12.6
- zfs: 2.4.0-v1.12.1 → 2.4.1-v1.12.6

### Release note

```release-note
[talos] Bump Talos to v1.12.6
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Chores

* Updated Talos image profiles from v1.12.1 to v1.12.6 across all
deployment configurations (initramfs, installer, ISO, kernel, metal, and
Nocloud).
* Updated hardware drivers and firmware extensions to latest pinned
versions, including AMD/Intel microcode, GPU drivers, network adapters,
and storage modules.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-27 09:59:23 +01:00
Myasnikov Daniil a243f3d72a [platform] Added resource-policy to keep installed packages
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-03-26 19:06:04 +05:00
Andrei Kvapil 1598d7fd03 [talos] Bump Talos to v1.12.6
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
2026-03-20 15:51:59 +01:00
Timofei Larkin 51949124c5 [platform] Enable cozystack-scheduler by default
## What this PR does

Install the cozystack-scheduler package and the SchedulingClass CRD by
default.

### Release-note

```release-note
[cozystack-scheduler] Enable the cozystack-scheduler and SchedulingClass
CRD by default.
```

Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
2026-03-20 11:26:39 +03:00
Aleksei Sviridkin 4bdc7241af [kube-ovn] Fix MASTER_NODES for multi-master generic Kubernetes clusters (#2245)
## What this PR does

Removes the `apiServerEndpoint` fallback for `MASTER_NODES` in the
`isp-full-generic` variant.

When `MASTER_NODES` is not explicitly set (the default), the template
used to parse a single IP from `apiServerEndpoint` and pass it to
kube-ovn. This prevented kube-ovn from discovering all control-plane
nodes, breaking OVN RAFT consensus on multi-master clusters
(`ovn-central` crashed with `host ip X not in env NODE_IPS`).

Now kube-ovn uses its built-in Helm `lookup` to find all control-plane
nodes by the `MASTER_NODES_LABEL`
(`node-role.kubernetes.io/control-plane=true`), correctly discovering
all masters.

Explicit `MASTER_NODES` override via platform values is preserved.

The `isp-full` (Talos) variant is not affected — it uses a separate code
path.

Fixes #2242

### Release note

```release-note
[kube-ovn] Fix multi-master support for generic Kubernetes clusters by letting kube-ovn auto-discover control-plane nodes by label instead of falling back to a single API server IP
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced support for automatic control plane node discovery using
Kubernetes node labels, providing greater flexibility and scalability
options for cluster configurations.

* **Bug Fixes**
* Removed unreliable automatic node configuration fallback logic to
improve overall deployment consistency and predictability. Master nodes
now require explicit configuration or automatic discovery through
Kubernetes node labels.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-19 13:27:14 +03:00
Kirill Ilin 08676b9c05 fix(installer): add build revision marker to trigger platform reconciliation
When only leaf packages change but the platform chart remains unchanged,
the Flux ArtifactGenerator produces an ExternalArtifact with the same
content digest. This prevents the platform HelmRelease from reconciling,
so lookup() in repository.yaml never runs and cozystack-packages
OCIRepository does not pick up the new OCI digest.

Write a content-based hash of the working tree state to
core/platform/.build-revision before pushing the OCI artifact, ensuring
the platform chart content always changes on every build.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-03-18 21:37:23 +05:00
Aleksei Sviridkin 7c2c804810 fix(kubeovn): let kube-ovn discover master nodes by label on multi-master clusters
Remove the apiServerEndpoint fallback for MASTER_NODES in the
isp-full-generic variant. When MASTER_NODES is not explicitly set,
kube-ovn now uses its built-in Helm lookup to find all control-plane
nodes by the MASTER_NODES_LABEL, correctly discovering all masters
instead of just the single API server IP.

The previous fallback always produced a single IP (the API endpoint),
which broke OVN RAFT consensus on multi-master clusters because
ovn-central was configured with only one node in NODE_IPS.

Explicit MASTER_NODES override is preserved for users who need it.

Fixes: #2242

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-03-18 17:05:09 +03:00
Andrei Kvapil a0f60d4377 [apps] Add managed OpenSearch service (#1953)
## Summary
- Add `packages/apps/opensearch/` — managed OpenSearch application chart
with multi-version support (v1/v2/v3), TLS, HTTP Basic auth, custom
users, OpenSearch Dashboards, external access, topology spread policies
- Add `packages/system/opensearch-operator/` — wrapper around opster
OpenSearch operator v2.8.0 with sysctl daemonset for `vm.max_map_count`
- Add `packages/system/opensearch-rd/` — ApplicationDefinition for
Cozystack platform integration (dashboard UI, schema validation,
resource exposure)

## Details
- **Versions**: v1 → 1.3.20, v2 → 2.11.1, v3 → 3.0.0
- **Security**: Auto-generated admin credentials, TLS on transport +
HTTP, bcrypt-hashed security config
- **Dashboards**: Optional deployment with TLS, configurable replicas
and resources
- **External access**: LoadBalancer services for OpenSearch (9200) and
Dashboards (5601) with DNS annotations
- **Tests**: Comprehensive Helm test suite (opensearch, security, users)

## Test plan
- [x] `helm template` renders correctly with default values
- [x] `helm template` renders correctly with dashboards, external
access, and custom users enabled
- [ ] Deploy on a test cluster with the operator installed
- [ ] Verify OpenSearch cluster reaches green status
- [ ] Verify Dashboards connectivity
- [ ] Verify external access via LoadBalancer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Managed OpenSearch charts and operator with CRDs, RBAC, external
LoadBalancer services, per-user secrets, security/config secrets,
dashboards, and a sysctl DaemonSet.

* **Documentation**
* New chart READMEs, values.yaml, and JSON schema documenting
configuration, defaults, and version mappings.

* **Tests**
* Extensive manifest tests covering rendering, security, users, storage,
topology, and version selection.

* **Chores**
* Build tooling, Makefiles, packaging ignores, and version update
scripts added.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-18 11:22:00 +01:00
Andrei Kvapil 3fef40e9f7 [dashboard] Add keycloakInternalUrl for backend-to-backend OIDC requests (#2224)
## What this PR does

Adds `authentication.oidc.keycloakInternalUrl` platform value that
allows oauth2-proxy
in the dashboard to route backend calls (token exchange, JWKS, userinfo,
logout) through
an internal cluster URL while keeping browser redirects on the external
Keycloak URL.

When set, oauth2-proxy uses `--skip-oidc-discovery` and explicit
endpoint URLs pointing
to the internal Keycloak service. This avoids external DNS lookups and
TLS overhead for
pod-to-pod communication.

Fully backward-compatible: when the value is empty (default), behavior
is unchanged.

### Release note

```release-note
[dashboard] Added `authentication.oidc.keycloakInternalUrl` platform value to route oauth2-proxy backend requests through internal Keycloak service URL, bypassing external DNS and TLS.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added configuration support for an internal KeyCloak URL, enabling
backend authentication requests to be routed through an alternative
endpoint while maintaining existing external URLs for browser
interactions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-16 14:54:41 +01:00
Andrey Kolkov 38d58a77dc Fix/backups (#2149)
<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does


### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[backups] Added fix to roles and changed backupstrategy-controller location
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
  * Updated backup controller namespace configuration.
* Enhanced backup controller permissions for leader election and event
recording capabilities.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-16 17:31:06 +04:00
Kirill Ilin 689c2a5e4a feat(dashboard): add keycloakInternalUrl for backend-to-backend OIDC requests
When set, oauth2-proxy skips OIDC discovery and routes all backend calls
(token exchange, JWKS, userinfo, logout) through the internal cluster URL
while keeping browser redirects on the external URL. This avoids external
DNS lookups and TLS overhead for pod-to-pod communication with Keycloak.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-03-16 11:03:55 +05:00
Andrei Kvapil 941fb02cd1 [cozystack-scheduler] Add custom scheduler as an optional system package (#2205)
## What this PR does

Adds the cozystack-scheduler as an optional system package, vendored
from https://github.com/cozystack/cozystack-scheduler. The scheduler
extends the default kube-scheduler with SchedulingClass-aware affinity
plugins, allowing platform operators to define cluster-wide scheduling
constraints via a SchedulingClass CRD. Pods opt in via the
`scheduler.cozystack.io/scheduling-class` annotation.

The package includes:
- Helm chart with RBAC, ConfigMap, Deployment, and CRD
- PackageSource definition for the cozystack package system
- Optional inclusion in the platform system bundle

### Release note

```release-note
[cozystack-scheduler] Add cozystack-scheduler as an optional system
package. The custom scheduler supports SchedulingClass CRDs for
cluster-wide node affinity, pod affinity, and topology spread constraints.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added cozystack-scheduler component as an optional system package.
* Introduced SchedulingClass custom resource for advanced scheduling
configurations.
* Scheduler supports node affinity, pod affinity, pod anti-affinity, and
topology spread constraints.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-12 13:38:25 +01:00