Commit Graph
3749 Commits
Author SHA1 Message Date
myasnikovdaniil 67a89c24ca [Backport release-1.4] fix(platform): add OpenSearch to PaaS bundle (#2757)
## What this PR does

Backport of #2648 to `release-1.4`.

OpenSearch ships as a complete package set in `release-1.4`
(`packages/apps/opensearch/`, `packages/system/opensearch-operator/`,
`packages/system/opensearch-rd/`, and the `opensearch-operator` /
`opensearch-application` PackageSources), but the PaaS bundle template
never referenced the two `cozystack.opensearch-*` PackageSources.

Result on any cluster with `bundles.paas.enabled=true`:
- `opensearch-operator` is not deployed → no `OpenSearchCluster` CRD
- `opensearch-rd` is not deployed → no
`ApplicationDefinition/opensearch`,
  so the dashboard catalog has no OpenSearch entry and tenants cannot
  create `opensearches.apps.cozystack.io`

This adds the two missing includes to
`packages/core/platform/templates/bundles/paas.yaml`, matching #2648
exactly.

### Release note
```release-note
Fix: OpenSearch is now installed by the PaaS bundle (`bundles.paas.enabled=true`); previously the operator and ApplicationDefinition were defined but never referenced from the bundle, so OpenSearch did not appear in the dashboard catalog.
```
api/apps/v1alpha1/v1.4.2
2026-05-27 23:43:41 +05:00
Myasnikov Daniil ea55d60d62 [Backport release-1.4] fix(platform): add OpenSearch to PaaS bundle
# Description
Backport of #2648 to `release-1.4`.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-05-27 23:35:41 +05:00
myasnikovdaniil d046606adb [Backport release-1.4] fix(csi): verify VMI Ready after kubevirt-csi Publish to surface stuck-PVC failures (#2748)
# Description
Backport of #2659 to `release-1.4`.
2026-05-27 20:38:24 +05:00
myasnikovdaniil 0c7a8eab99 [Backport release-1.4] fix(csi): route RWX Block volumes to upstream hotplug detach (#2749)
# Description
Backport of #2658 to `release-1.4`.
2026-05-27 20:38:07 +05:00
Myasnikov Daniil d73def2250 fix(csi): tighten isNFSVolume to Filesystem-only
Address review feedback from gemini-code-assist on
packages/apps/kubernetes/images/kubevirt-csi-driver/controller.go:562:
classify a PVC as NFS only when its VolumeMode is Filesystem (or nil,
which defaults to Filesystem), instead of "anything not Block". Future
VolumeMode values will no longer be silently routed to the NFS path.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit c0db80591d)
2026-05-26 20:42:34 +00:00
Myasnikov Daniil ac5014d548 fix(csi): route RWX Block volumes to upstream hotplug detach
WrappedControllerService.ControllerUnpublishVolume decided between NFS
cleanup and upstream hotplug detach using only hasRWXAccessMode(pvc).
RWX Block volumes (KubeVirt live-migration disks) match that check and
were routed to the NFS path, which only deletes a CiliumNetworkPolicy.
For a block volume that CNP does not exist, so removeCNPOwnerReference
returns successfully without doing anything, and the function reports
success without ever calling upstream's hotplug detach. The DataVolume
entry stays in VM.spec.template.spec.volumes; when the same PVC later
attaches to a different VM, linstor-csi's anti-split-brain check sees
pods from two different VMs referencing the same RWX block PVC and
rejects the attach permanently.

Introduce isNFSVolume(pvc) requiring both ReadWriteMany access mode and
VolumeMode=Filesystem (always true for PVCs provisioned via our NFS
CreateVolume path). RWX Block now delegates to upstream, which removes
the entry from VM spec via RemoveVolumeFromVM. The same predicate
replaces the access-mode check in ControllerExpandVolume - RWX Block
volumes still need in-VM disk expansion.

Fixes #2634

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 712c93da07)
2026-05-26 20:42:34 +00:00
Myasnikov Daniil 56725330d0 fix(csi): return gRPC errors when post-Publish VMI readiness check cannot run
The fallback branches in publishHotplugVolume silently returned the
upstream success response when the node ID failed to parse or the VMI
get call returned an error. external-attacher then set Attached=true
without VolumeReady proof, which recreates the false-positive attach
this wrapper exists to prevent.

Fail loudly instead:

- parseErr -> codes.Internal: external-attacher is expected to provide
  a well-formed "namespace/name" node ID per the CSI contract; if it
  does not, surface the contract violation rather than mask it.
- getErr -> codes.Unavailable: this is the same code returned for the
  not-Ready and not-present cases just below, so the retry behavior on
  the attacher side stays consistent. By the time we reach this branch
  the upstream Publish call already succeeded, which means it just
  looked the VMI up; a transient get error here is a race or API hiccup
  and a retry is safe.

Also add a one-line comment on GetVirtualMachine: in the upstream
kubevirt.io/csi-driver client this method returns a
VirtualMachineInstance despite its name, so accessing
vmi.Status.VolumeStatus on the result is type-correct.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit cbe4b863ec)
2026-05-26 20:42:17 +00:00
Myasnikov Daniil adcbce805f fix(csi): verify VMI Ready after Publish to surface stuck-PVC failures
Upstream ControllerPublishVolume has a fast path that returns success
based only on the volume's presence in VM.spec.template.spec.volumes
(via EnsureVolumeAvailableVM). If a prior Publish wrote that entry but
the volume never became Ready in VMI status - e.g. the infra PVC is
stuck ClaimPending because LINSTOR cannot autoplace - the retry hits
the fast path and reports success. external-attacher marks the
VolumeAttachment Attached=true, but QEMU was never sent device_add, so
the tenant kubelet fails NodeStageVolume with:

    rpc error: code = Unknown desc = couldn't find device by serial id

Wrap upstream Publish for hotplug volumes (non-NFS) with a post-call
check that the volume reached VolumeReady in VMI.Status.VolumeStatus.
When it has not, the RPC returns codes.Unavailable carrying the actual
reason (e.g. "PVC is in phase ClaimPending"), so external-attacher
keeps retrying and the underlying provisioning failure is visible at
the CSI layer rather than as a confusing "device not found by serial
id" on the tenant kubelet.

This is a wrapper-side workaround for an upstream defect in
kubevirt.io/csi-driver; the structural fix belongs upstream (tighten
the fast path to require VMI Ready) and will be filed separately.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 5bb5e95a30)
2026-05-26 20:42:17 +00:00
myasnikovdaniil c2a1707396 chore(release): cut v1.4.1 (#2701)
This PR prepares the release `v1.4.1`.
v1.4.1
2026-05-22 11:01:54 +05:00
cozystack-ci[bot] 9252e0c931 Prepare release v1.4.1
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-05-22 04:10:56 +00:00
myasnikovdaniil 74ee1b514c [Backport release-1.4] fix(postgres): accept integer values for postgresql.parameters in schema (#2715)
# Description
Backport of #2687 to `release-1.4`.
api/apps/v1alpha1/v1.4.1
2026-05-22 08:59:18 +05:00
Myasnikov Daniil 2a3ed53960 fix(postgres): regenerate deepcopy for IntOrString parameters map
Companion regen for the type change in the previous commit. The
deepcopy generator emits a fresh import for intstr and updates the
inner make() call to match the new map value type. Caught by the
codegen-drift check on CI.

Generated by `make generate` at repo root (hack/update-codegen.sh).

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 26db323c19)
2026-05-22 03:59:02 +00:00
Myasnikov Daniil 4915af4cf9 ci(pre-commit): bump cozyvalues-gen to v1.4.0
v1.4.0 adds the `intOrString` type alias used by the postgres package's
`postgresql.parameters` schema in this PR. CI must install v1.4.0 so the
"Verify generated code is up to date" check regenerates the same schema
shape (anyOf + x-kubernetes-int-or-string: true) rather than reverting
to {type: string}.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 7cc0194f20)
2026-05-22 03:59:02 +00:00
Myasnikov Daniil aede243ef0 fix(postgres): drive postgresql.parameters int-or-string from the generator
Ivan's original schema edits were correct in intent but lived in the
generated artifacts (values.schema.json and the embedded openAPISchema
in postgres-rd/cozyrds/postgres.yaml). `make generate` reverts them
because values.yaml's `@field {map[string]string}` annotation is the
source of truth -- same regeneration trap that caught #2466 (issue #2597).

cozyvalues-gen v1.4.0 (cozystack/cozyvalues-gen#25, merged 2026-05-21)
adds an `intOrString` type alias for map values that emits
`additionalProperties.anyOf: [integer, string]` plus
`x-kubernetes-int-or-string: true`. Move the change to source by
flipping the annotation, then regenerate:

- packages/apps/postgres/values.yaml: `@field {map[string]intOrString}`
  with updated description noting integer values are accepted.
- packages/apps/postgres/values.schema.json: regenerated -- now carries
  anyOf + x-kubernetes-int-or-string: true.
- packages/system/postgres-rd/cozyrds/postgres.yaml: embedded
  openAPISchema regenerated to match.
- packages/apps/postgres/README.md: regenerated type column.
- api/apps/v1alpha1/postgresql/types.go: Parameters is now
  `map[string]intstr.IntOrString`.

The result survives future regenerations. The template's
`{{ \$value | toString | quote }}` already coerces both inputs to
quoted strings, verified end-to-end with helm template against both
`max_connections: 100` (int) and `max_connections: "100"` (string) --
identical render output. Dangerous-param block list still rejects
archive_cleanup_command and recovery_end_command additions from the
prior commit.

Co-Authored-By: IvanHunters <xorokhotnikov@gmail.com>
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 14e196cf22)
2026-05-22 03:59:02 +00:00
IvanHunters 4a453b8410 fix(postgres): block archive_cleanup_command and recovery_end_command
Add archive_cleanup_command and recovery_end_command to the dangerous
parameters blocklist in db.yaml. Both are PostgreSQL shell-exec hooks
identical in threat model to archive_command/restore_command and must
not be settable by tenants.

Also update the BLOCKED list in values.schema.json, values.yaml, and
the embedded openAPISchema in cozyrds/postgres.yaml to reflect the
two new blocked parameters.

Additionally update the embedded openAPISchema in cozyrds/postgres.yaml
to allow integer values for postgresql.parameters (anyOf string|integer),
matching the fix already applied to values.schema.json.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
(cherry picked from commit 388e823916)
2026-05-22 03:59:02 +00:00
IvanHunters d450747d4d fix(postgres): accept integer values for postgresql.parameters in schema
The template already coerces all parameter values to strings via
'toString | quote', but the JSON schema had 'additionalProperties: {type: string}'
which caused Helm schema validation to fail before the template ran
when users passed integer values (e.g. max_connections: 100).

Accept both string and integer types in additionalProperties so that
existing configurations with unquoted numbers continue to work.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
(cherry picked from commit 8c89556e79)
2026-05-22 03:59:02 +00:00
myasnikovdaniil 84cda9cf26 [Backport release-1.4] fix(platform): migrate ephemeralStorage to diskSize via pre-upgrade hook (#2712)
Add pre-upgrade migration 41 that walks all
kuberneteses.apps.cozystack.io Application CRs and renames
nodeGroups[*].ephemeralStorage to diskSize, preserving the user's value.

Without this migration, clusters upgraded after PR #2454 either fail to
reconcile (hard fail blocks all Flux operations) or silently lose the
user's disk size setting (default 20Gi replaces whatever was
configured).

The migration is idempotent and best-effort: a failed patch is logged
and leaves the version stamp at 41 for retry on next upgrade.

Update the chart-side guard error message to direct operators to the
migration job logs when the field appears post-upgrade (regression
detector). Bump migrations.targetVersion 41 -> 42.

Assisted-By: Claude <noreply@anthropic.com>

(cherry picked from commit ed1bb53d2c)

<!-- 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 are not an exhaustive list — pick the most specific scope for
the change and extend the list when a genuinely new area appears.
Examples:
- System components: dashboard, platform, operator, cilium, kube-ovn,
linstor, fluxcd, cluster-api
- Managed apps: postgres, mariadb, redis, kafka, clickhouse,
virtual-machine, kubernetes
- 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.
-->

## What this PR does


### Screenshots

<!-- REQUIRED for UI changes: attach screenshots or screen recordings
demonstrating
the visual impact of your changes. PRs with UI changes without
screenshots will not be merged. -->

### Release note

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

```release-note

```
2026-05-22 08:56:26 +05:00
Myasnikov Daniil 6790f74073 fix(e2e-sandbox): use curl -fsSL when downloading mc
The minio client was downloaded without -L, so when dl.min.io served
a 302 redirect, curl wrote the HTML body ("<a href=...>Found</a>") to
/usr/local/bin/mc, chmod +x'd it, and shipped that as the binary. When
the bucket E2E test ran "mc alias set ...", the shell tried to interpret
the HTML as a script and errored with:

    /usr/local/bin/mc: 1: cannot open a: No such file

(dash reading "<a" as an input redirect from a file named "a").

The image is rebuilt per CI run from cached layers; the broken mc layer
was cached and reused. Adding -fsSL fixes the download and the textual
change busts the cache so the next build pulls a real ELF binary.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
(cherry picked from commit 45937d6d13)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-05-21 23:01:19 +05:00
IvanHunters eee5eb9848 fix(platform): migrate ephemeralStorage to diskSize via pre-upgrade hook
Add pre-upgrade migration 41 that walks all kuberneteses.apps.cozystack.io
Application CRs and renames nodeGroups[*].ephemeralStorage to diskSize,
preserving the user's value.

Without this migration, clusters upgraded after PR #2454 either fail to
reconcile (hard fail blocks all Flux operations) or silently lose the user's
disk size setting (default 20Gi replaces whatever was configured).

The migration is idempotent and best-effort: a failed patch is logged and
leaves the version stamp at 41 for retry on next upgrade.

Update the chart-side guard error message to direct operators to the
migration job logs when the field appears post-upgrade (regression detector).
Bump migrations.targetVersion 41 -> 42.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit ed1bb53d2c)
2026-05-21 17:37:38 +05:00
myasnikovdaniil a5a4236aff [Backport release-1.4] fix(cluster-api): fix kamaji OOM and set limits on unset providers (#2709)
# Description
Backport of #2708 to `release-1.4`.
2026-05-21 16:31:50 +05:00
Myasnikov Daniil 5134666ebd fix(cluster-api): fix kamaji OOM and set limits on unset providers
The kamaji control-plane-provider override in templates/providers.yaml
targeted containers[name=manager], but the upstream container is named
"controller". The CAPI operator merges container overrides by name, so
the intended cpu: 1 / memory: 1024Mi limits were silently dropped and
the upstream default of memory: 128Mi was used, producing repeated
OOMKilled restarts of the kamaji controller (exit code 137).

The other three providers (core, bootstrap, infraprovider/kubevirt)
ship upstream with no resources block and have no cozystack override,
so they run BestEffort and are first to evict under memory pressure.
Set modest limits (500m / 256Mi) and requests (10m / 64Mi) matching
typical CAPI controller-manager footprint.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 6ae66f72a6)
2026-05-21 10:14:40 +00:00
myasnikovdaniil b3ed9c3f4c [Backport release-1.4] fix(kafka): remove ZooKeeper PVCs on uninstall (#2705)
# Description
Backport of #2679 to `release-1.4`.
2026-05-21 11:38:58 +05:00
Arsolitt 99b58ea92a test(kafka): assert ZooKeeper PVC-1 is created before deletion check
Address review feedback from coderabbitai on hack/e2e-apps/kafka.bats:58:
The post-delete `while kubectl get pvc data-kafka-$name-zookeeper-1` loop
exits immediately when the PVC has never been created, so a regression
that prevents Strimzi from provisioning the second ZooKeeper PVC would
silently pass the reclamation check. Mirror the PVC-0 readiness guard
(existence + Bound) for PVC-1 before deleting the Kafka CR so the test
only proceeds once both PVCs are observed.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Arsolitt <arsolitt@gmail.com>
(cherry picked from commit 2086f3e6b6)
2026-05-21 06:38:11 +00:00
Arsolitt 650c98338c test(kafka): verify ZooKeeper PVCs are reclaimed by the operator
Address review feedback from gemini-code-assist on
hack/e2e-apps/kafka.bats:53-55:
Replace the manual kubectl delete of the two ZooKeeper PVCs with a poll
that waits for the Strimzi operator to reclaim them. With deleteClaim:
true on the ZooKeeper persistent-claim storage, the operator removes
the PVCs as part of Kafka CR deletion; manual deletion would either
race the operator, fail with NotFound, or silently mask a regression
in the reclamation path.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Arsolitt <arsolitt@gmail.com>
(cherry picked from commit c4b0606e67)
2026-05-21 06:38:11 +00:00
Arsolitt 0b84a0a4f9 fix(kafka): reclaim ZooKeeper PVCs on Kafka release deletion
Set deleteClaim: true on the ZooKeeper persistent-claim storage so the
Strimzi operator removes the PVCs together with the rest of the cluster
when the Kafka CR is deleted. Previously the Kafka broker PVCs were
reclaimed (deleteClaim: true) but the ZooKeeper PVCs were orphaned,
forcing manual cleanup before the same release name could be reused.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Arsolitt <arsolitt@gmail.com>
(cherry picked from commit 69a479df5a)
2026-05-21 06:38:11 +00:00
myasnikovdaniil aa06369553 [Backport release-1.4] fix(opensearch-operator): replace deprecated kube-rbac-proxy image (#2695)
# Description
Backport of #2689 to `release-1.4`.
2026-05-20 19:23:34 +05:00
Myasnikov Daniil 098c82ff79 fix(opensearch-operator): use values.yaml override instead of patch
Move the kube-rbac-proxy image override from a patch + vendored-chart
edit to a values.yaml override under kubeRbacProxy.image.repository.

This matches the project convention documented in docs/agents/overview.md
("Override configuration in root values.yaml") and the pattern used by
sibling packages such as kamaji.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit e5437240e7)
2026-05-20 14:01:47 +00:00
Myasnikov Daniil 3f71081a88 fix(opensearch-operator): replace deprecated kube-rbac-proxy image
The gcr.io/kubebuilder/kube-rbac-proxy image is no longer available
since GCR was deprecated. Replace it with quay.io/brancz/kube-rbac-proxy
from the original upstream author.

Applied as a local patch in patches/ because upstream chart 2.8.1+ drops
kubeRbacProxy entirely but also bumps CRDs to controller-gen v0.19.0 with
significant schema changes — out of scope for this fix.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit d0a0b06afd)
2026-05-20 14:01:47 +00:00
myasnikovdaniil f5c84eb6ba chore(release): cut v1.4.0-rc.2 (#2646)
This PR prepares the release `v1.4.0-rc.2`.
v1.4.0-rc.2
2026-05-14 10:15:38 +05:00
cozystack-ci[bot] 9f655e29ff Prepare release v1.4.0-rc.2
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-05-13 21:48:39 +00:00
myasnikovdaniil 680803acae feat(dashboard): replace UI with new cozystack-ui build (#2507)
## Summary

Replaces the old openapi-ui with the new cozystack-ui build from the
cozystack-ui repository.

## Key Changes

### New UI
- **Image**: `999669/cozystack-ui:latest@sha256:ea4e832c2...`
- **Architecture**: `linux/amd64`
- **Repository**: https://github.com/cozystack/cozystack-ui
(feat/ui-overhaul branch)

### Removed Components
- Removed BFF (Backend-For-Frontend) container - new UI communicates
directly with Kubernetes API
- Removed old openapi-ui and openapi-ui-k8s-bff build targets from
Makefile
- Removed old UI Dockerfiles and patch files

### RBAC Updates
- Added read permissions for `cozystack.io/applicationdefinitions` to
fix 403 errors
- New UI requires access to applicationdefinitions for marketplace and
catalog functionality

### Bug Fixes
- Fixed VNC WebSocket connections to use dynamic URLs instead of
hardcoded localhost:8001
- VNC now works properly in-cluster deployments

## Testing

Tested on dev3.infra.aenix.org cluster:
- ✅ Dashboard loads correctly
- ✅ Application definitions accessible
- ✅ VNC connections working
- ✅ Backup pages functional
- ✅ All TypeScript errors resolved

## Migration Notes

The new UI is a complete rewrite with:
- Modern React 19 + TypeScript stack
- Improved backup management pages
- Better type safety and error handling
- Direct Kubernetes API communication (no BFF needed)
api/apps/v1alpha1/v1.4.0-rc.2
2026-05-13 22:54:15 +05:00
Andrey Kolkov c5b46f31fe fix(platform): align field of Altinity backup-strategy for similarity… (#2645)
… with others

<!-- 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 are not an exhaustive list — pick the most specific scope for
the change and extend the list when a genuinely new area appears.
Examples:
- System components: dashboard, platform, operator, cilium, kube-ovn,
linstor, fluxcd, cluster-api
- Managed apps: postgres, mariadb, redis, kafka, clickhouse,
virtual-machine, kubernetes
- 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.
-->

## What this PR does


### Screenshots

<!-- REQUIRED for UI changes: attach screenshots or screen recordings
demonstrating
the visual impact of your changes. PRs with UI changes without
screenshots will not be merged. -->

### Release note

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

```release-note
align Altinity backup strategy field name for similarity with others
```
2026-05-13 20:17:19 +04:00
myasnikovdaniil 42b5cc4fd6 Merge branch 'main' into feat/new-ui
Signed-off-by: myasnikovdaniil <60174387+myasnikovdaniil@users.noreply.github.com>
2026-05-13 20:19:47 +05:00
myasnikovdaniil e5018e378e chore(release): cut v1.4.0-rc.1 (#2644)
This PR prepares the release `v1.4.0-rc.1`.
v1.4.0-rc.1
2026-05-13 19:10:58 +05:00
Andrey Kolkov 84874353ce fix(platform): align field of Altinity backup-strategy for similarity with others
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
2026-05-13 17:15:51 +04:00
cozystack-ci[bot] 252c18f3e8 Prepare release v1.4.0-rc.1
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-05-13 12:29:01 +00:00
Andrey Kolkov 70693ff35e feat(platform): add foundationdb backups (#2606)
<!-- 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 are not an exhaustive list — pick the most specific scope for
the change and extend the list when a genuinely new area appears.
Examples:
- System components: dashboard, platform, operator, cilium, kube-ovn,
linstor, fluxcd, cluster-api
- Managed apps: postgres, mariadb, redis, kafka, clickhouse,
virtual-machine, kubernetes
- 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.
-->

## What this PR does


### Screenshots

<!-- REQUIRED for UI changes: attach screenshots or screen recordings
demonstrating
the visual impact of your changes. PRs with UI changes without
screenshots will not be merged. -->

### Release note

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

```release-note
implement backup controller for foundationdb backups 
```

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

* **New Features**
* Added FoundationDB backup & restore support via a new FoundationDB
backup strategy and controller; controller now handles FoundationDB
backup/restore jobs.

* **Examples**
* Added a complete FoundationDB backup/restore demo with helper scripts,
step-by-step step scripts, run-all, and cleanup tooling.

* **Documentation**
* New admin and tenant guides plus a README explaining the example
workflow and verification steps.

* **Deprecations**
* In-chart FoundationDB backup configuration marked DEPRECATED—migrate
to BackupClass + FoundationDB strategy.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2606)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
api/apps/v1alpha1/v1.4.0-rc.1
2026-05-13 12:06:18 +04:00
Andrey Kolkov 92930ad1aa feat(platform): add implementation of backup-strategy controller for foundationdb
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
2026-05-13 09:49:19 +04:00
Andrey Kolkov 5f83ae72a8 feat(platform): implement backup strategy for mariadb (#2605)
<!-- 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 are not an exhaustive list — pick the most specific scope for
the change and extend the list when a genuinely new area appears.
Examples:
- System components: dashboard, platform, operator, cilium, kube-ovn,
linstor, fluxcd, cluster-api
- Managed apps: postgres, mariadb, redis, kafka, clickhouse,
virtual-machine, kubernetes
- 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.
-->

## What this PR does


### Screenshots

<!-- REQUIRED for UI changes: attach screenshots or screen recordings
demonstrating
the visual impact of your changes. PRs with UI changes without
screenshots will not be merged. -->

### Release note

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

```release-note
implement backup strategy for MariaDB
```

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

* **New Features**
* Added native MariaDB backup/restore strategy using the operator-native
BackupClass/Plan/RestoreJob flow with example manifests for end-to-end
workflows.

* **Documentation**
* Added MariaDB how‑to and examples; marked legacy restic/chart-side
backup parameters as DEPRECATED and documented migration guidance.

* **Tests**
* Added unit tests covering MariaDB backup/restore reconciliation,
templating, storage handling, idempotency, URIs, and deadlines.

* **Chores**
* Extended controller RBAC to allow observing MariaDB operator
resources.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2605)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-12 17:10:55 +04:00
Andrei Kvapil f38a047aa6 feat(kilo): add patched image build with cross mesh granularity (#2604)
## What this PR does

Adds infrastructure for building a patched kilo image from upstream
`main` branch source, following the same pattern as the kamaji package.

The patch introduces a new `cross` mesh granularity mode — WireGuard
tunnels are created only between nodes in different locations, while
intra-location traffic stays on the CNI overlay.

Changes:
- `images/kilo/Dockerfile` — multi-stage build: fetches upstream
tarball, applies patches, builds `kg`/`kgctl` binaries with CNI plugins
and iptables-wrapper
- `images/kilo/patches/feat-add-cross-mesh-granularity.diff` — adds
`CrossGranularity` to the kilo binary
- `Makefile` — new `image:` target for building the patched image,
updated `update:` target to pin upstream commit SHA

### Screenshots

N/A — no UI changes.

### Release note

```release-note
feat(kilo): add patched image build with cross mesh granularity support
```

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

* **New Features**
* Added "cross" mesh granularity mode for finer topology grouping,
adjusted routing/encryption behavior
* Added e2e tests covering cross-mode scenarios for improved reliability

* **Chores**
* Build automation now tracks latest main commit and derives image
digests from build metadata
* Introduced multi-stage container build and runtime packaging for kilo,
including required networking tooling
* **Configuration**
  * Updated default image reference to a new repository and digest

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2604)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-12 12:38:53 +02:00
Andrei Kvapil 92d128e8ff feat(keycloak): support extraEnv values and userProfile customization (#2613)
## What this PR does

Two related quality-of-life additions to the Keycloak system component:

1. **`keycloak` chart now accepts `extraEnv`.** Operators can append
extra
`EnvVar` entries to the Keycloak StatefulSet container without forking
the
   chart. Useful when a custom theme needs runtime configuration via
`kcContext.properties`, or when an extension expects environment
variables.

2. **`keycloak-configure` chart now exposes a top-level `userProfile`
value**
that is mirrored verbatim into
`ClusterKeycloakRealm.spec.userProfileConfig`.
   This lets operators declare custom user-profile attributes (required
fields, validators, permissions, ...) declaratively, alongside the
existing
   `login` and `smtp` blocks.

Both values default to empty, so existing deployments are unaffected.

### Release note

```release-note
feat(keycloak): support extraEnv values and userProfile customization
```
2026-05-12 12:38:35 +02:00
Andrey Kolkov 62605a198b feat(platform): implement backup strategy for mariadb
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
2026-05-12 13:56:29 +04:00
Andrei Kvapil c247bf48e5 feat(apps): instance-type resource presets with five series (#2607)
## What this PR does

Closes #1959.

Continuation of @matthieu-robin's instance-type resource presets work,
addressing the migration gaps and resource regressions surfaced during
the review of #1959.

Resource presets now follow a cloud-style `<series>.<size>` naming
convention. Five series cover the full CPU-to-memory ratio range, each
with eight sizes (`nano` through `4xlarge`):

| Series | Ratio | Use case |
| ------ | ----- | -------- |
| `t1`   | 1:0.5 | Tiny / burstable, low memory |
| `c1`   | 1:1   | Compute-balanced |
| `s1`   | 1:2   | Standard — proxies, caches |
| `u1`   | 1:4   | Universal — databases, messaging |
| `m1`   | 1:8   | Memory — search, analytics |

40 instance-type presets in total. The seven legacy flat names (`nano`,
`micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`) remain
accepted as deprecated aliases.

### Upgrade path

The combination of three mechanisms makes the rename a no-op for
existing deployments:

1. **`cozy-lib` legacy aliases** — preserve the exact pre-rename CPU and
memory for every legacy name. `helm template ... --set
resourcesPreset=small` continues to render `1 CPU / 512Mi`, identical to
before. No HelmRelease that already lives on the cluster breaks.
2. **Migration 39** — a pre-upgrade hook walks every
`HelmRelease.spec.values` and every app CR under
`apps.cozystack.io/v1alpha1`, rewriting legacy values to their 1:1
instance-type equivalents (`nano → t1.nano`, `medium → c1.small`, etc).
Idempotent, best-effort, dry-runnable via `MIGRATION_DRY_RUN=1`,
distinguishes "no items" from "kubectl errored" so a broken cluster
cannot silently stamp the version.
3. **`cozystack-api` deprecation warning** — every `Create` and `Update`
on an app CR with a legacy value emits a `klog` warning naming the JSON
path and the 1:1 replacement, so operators discover any remaining legacy
data after the platform upgrade.

The legacy-to-instance-type mapping is 1:1 by CPU and memory:

| Legacy   | CPU  | Memory | Instance-type |
| -------- | ---- | ------ | ------------- |
| `nano`   | 250m | 128Mi  | `t1.nano`     |
| `micro`  | 500m | 256Mi  | `t1.micro`    |
| `small`  | 1    | 512Mi  | `t1.small`    |
| `medium` | 1    | 1Gi    | `c1.small`    |
| `large`  | 2    | 2Gi    | `c1.medium`   |
| `xlarge` | 4    | 4Gi    | `c1.large`    |
| `2xlarge`| 8    | 8Gi    | `c1.xlarge`   |

Mirrored in four places (cozy-lib template, Go package, migration jq,
docs) with cross-reference comments so drift is visible.

### Why not just #1959

The implementation in #1959 had three blockers that motivated this
rewrite:

- **`cozy-lib` lost the legacy names entirely**, so any existing
HelmRelease with `resourcesPreset: small` failed render with `Preset key
'small' invalid`. Aliases close this hole.
- **Migration only touched HelmReleases**, leaving app CRs unmigrated;
the next `kubectl edit` would fail enum validation. The new migration
walks both.
- **Defaults silently inflated memory**, e.g. Redis `nano → m1.nano`
jumped from 128Mi to 2Gi (×16). With two replicas plus sentinel the e2e
VM ran out of memory, producing the Redis 90s timeout that blocked the
original PR. New defaults preserve resources 1:1.

### Deprecation timeline

Legacy aliases are scheduled for removal in a future cozystack release.
The combination of migration + operator warnings is expected to converge
production clusters before then. Removal will land as a separate PR with
its own migration cleanup pass.

### Test plan

- `make unit-tests` — Go tests for the preset walker + warning helper,
`helm unittest` legacy↔instance-type parity suites for
`postgres`/`clickhouse`/`opensearch`, RD schema invariance check via
`hack/check-rd-presets.sh`.
- `make generate` is idempotent.
- `helm template ./packages/apps/redis` with the new default renders
250m / 128Mi (matches pre-rename Redis exactly — closes the e2e
blocker).
- `helm template ./packages/apps/postgres --set resourcesPreset=small`
renders 1 / 512Mi (legacy alias works).
- Migration dry-run is exercised via `MIGRATION_DRY_RUN=1`.

### Documentation

See
[`docs/operations/resource-presets.md`](docs/operations/resource-presets.md)
for the full size matrix and migration table.

### Release note

```release-note
feat(cozy-lib): introduce `<series>.<size>` instance-type resource presets (t1/c1/s1/u1/m1 × 8 sizes). Legacy flat names (nano…2xlarge) remain accepted as deprecated 1:1 aliases; migration 39 rewrites stored values to the new form. CPU and memory are preserved exactly across the rename.
```


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

* **New Features**
* Expanded resource preset options to instance-style names (e.g., t1.*,
c1.*, m1.*); legacy flat names remain supported as deprecated aliases.
  * Deprecation warnings now surface when legacy presets are detected.

* **Documentation**
* Added a comprehensive resource-presets guide and updated chart/app
docs to the new naming convention.

* **Tests**
* Added compatibility tests ensuring legacy ↔ instance-type presets
render identical resources.

* **Chores**
  * Migration and CI checks to detect/upgrade legacy preset values.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2607)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-12 11:04:57 +02:00
Kirill Ilin 3e5b370f74 chore(keycloak): use generic example values in chart comments
Replace deployment-specific examples in the new extraEnv and
userProfile docs with generic placeholders so the chart comments do
not lean on any particular downstream use case.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-05-12 13:13:19 +05:00
Kirill Ilin 2261ef7e25 feat(keycloak-configure): plumb userProfile into ClusterKeycloakRealm
Operators can now declare custom user-profile attributes (required
fields, validators, permissions, ...) via a new top-level userProfile
value. The value is mirrored verbatim into the
ClusterKeycloakRealm.spec.userProfileConfig managed by the EDP
keycloak-operator.

The default remains empty, so realms that don't need custom user
profile configuration are unaffected.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-05-12 13:09:29 +05:00
Kirill Ilin 6413052abc feat(keycloak): expose extraEnv values to the StatefulSet
Custom themes (Keycloakify, FTL) often need runtime values from the
deployment environment via kcContext.properties. Adding an extraEnv
list to the chart lets operators inject those values per cluster
without forking the chart.

The new field appends verbatim to the container env list and accepts
the full corev1.EnvVar schema, including valueFrom for secret or
configMap-backed values.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
2026-05-12 13:09:21 +05:00
Aleksei Sviridkin 55a98b8815 docs(apps): point seven app README preset tables at canonical docs
Address review feedback from coderabbitai across:
  - packages/apps/kubernetes/README.md
  - packages/apps/mariadb/README.md
  - packages/apps/nats/README.md
  - packages/apps/qdrant/README.md
  - packages/apps/redis/README.md
  - packages/apps/tcp-balancer/README.md
  - packages/apps/vpn/README.md

Each of these READMEs left an inline 7-row preset table listing only
the legacy flat names after the parameters block above already
defaulted to an instance-type value (e.g. `t1.nano`). cozyvalues-gen
only regenerates the `## Parameters` block, so the hand-written
section drifted.

Replace the inline tables with the same short paragraph already used
by postgres and kafka READMEs: name the five series, note that the
seven legacy names remain accepted as deprecated aliases, and link to
the canonical reference at docs/operations/resource-presets.md so the
full size matrix and legacy mapping live in exactly one place.

Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-05-12 03:08:52 +03:00
Aleksei Sviridkin e90736ed5f test(presets): surface diff on FormatDeprecationMessages mismatch
Address review feedback from coderabbitai on
pkg/apis/apps/presets/legacy_test.go:151.

Replace the index-by-index loop over `got` with a single t.Fatalf
that prints both slices via %#v. The previous loop iterated only
across `got`, so extra entries in `want` would slip past unreported
when `got` was shorter than `want`; t.Fatalf with full slice
representations names both sides regardless of length.

Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-05-12 03:07:48 +03:00
Aleksei Sviridkin af46317d16 fix(api): log JSON parse error on deprecation walk
Address review feedback from gemini-code-assist on
pkg/registry/apps/application/rest.go:1777.

When app.Spec.Raw cannot be unmarshalled to map[string]any the
deprecation walker now logs a klog.V(2) line naming the kind, name,
namespace and the underlying error before returning. Upstream
validation still owns rejecting invalid specs (this hook is purely
informational), so the log stays at debug verbosity rather than
surfacing as a warning that would fire on transient inputs the
caller is about to reject anyway.

Helper signature changed to (kind, namespace, name string, raw []byte)
so the malformed-input path is reachable from existing unit tests
without forcing a fake Application wrapper.

Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-05-12 03:07:12 +03:00
Aleksei Sviridkin 9d9750e736 fix(hack): tighten resourcesPreset enum check
Address review feedback from gemini-code-assist on hack/check-rd-presets.sh:26
and coderabbitai on hack/check-rd-presets.sh:37.

- Switch the jq enum extractor from a description-substring heuristic
  (test("preset"; "i")) to a JSON path-suffix selector that matches
  fields literally named resourcesPreset. Eliminates false positives
  from unrelated fields whose descriptions happen to mention "preset".
- Use grep -F for literal enum membership so the "." in entries like
  t1.nano cannot accidentally match arbitrary characters (e.g. a typo
  t1xnano would have satisfied t1.nano under basic regex).

Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-05-12 03:04:48 +03:00