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)
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)
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)
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)
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)
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
```
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>
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)
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)
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)
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)
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)
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)
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)
## 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)
… 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
```
<!-- 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.
[](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2606)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- 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.
[](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2605)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 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
[](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2604)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 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
```
## 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.
[](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2607)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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>
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>
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>
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>
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>
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>
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>
Document the five instance-type series (t1/c1/s1/u1/m1) introduced
alongside the legacy preset deprecation, the per-size CPU and memory
matrix, and the 1:1 legacy-to-instance-type mapping table that powers
cozy-lib aliases, migration 39, and the operator-side deprecation
warning.
Single source of truth referenced from:
- packages/library/cozy-lib/templates/_resourcepresets.tpl
- packages/core/platform/images/migrations/migrations/39
- pkg/apis/apps/presets/legacy.go
Includes an explicit callout that legacy `medium` (1 CPU / 1Gi) and
instance-type `*.medium` (2 CPU) are not the same — same word,
different resources.
Replace inline preset tables in packages/apps/postgres/README.md and
packages/apps/kafka/README.md with a short paragraph that names the
five series and points at the canonical doc, since the per-app
inline tables listed only the legacy seven and would drift further
as the canonical matrix evolves.
Co-authored-by: Matthieu ROBIN <matthieu@hidora.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Pin the 1:1 equivalence between legacy flat preset names and their
instance-type counterparts in helm-unittest for three charts that
exercise different preset shapes:
- postgres — top-level only
- clickhouse — top + nested clickhouseKeeper preset
- opensearch — top + nested dashboards preset
Each case asserts that nano <-> t1.nano, small <-> t1.small,
medium <-> c1.small, large <-> c1.medium, and micro <-> t1.micro
render the same CPU and memory.
packages/apps/{clickhouse,opensearch}/Makefile gain a `test:` target
that calls helm unittest so hack/helm-unit-tests.sh actually runs the
new suites in CI; without it the suites would land as dead weight.
hack/check-rd-presets.sh enforces two invariants in `make unit-tests`:
- every packages/system/*-rd/cozyrds/*.yaml openAPISchema carries
the canonical 47-preset enum (40 instance-type + 7 legacy);
- no chart template carries a hardcoded legacy preset literal in
a defaultingSanitize (list "<legacy>" ...) form.
Both turn an accidental drop of a per-chart Makefile step or an
accidental legacy hardcode into a CI failure rather than silent
production-time validation rejection.
Co-authored-by: Matthieu ROBIN <matthieu@hidora.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Add a new pre-upgrade hook migration that walks every HelmRelease
spec.values and every app CR spec under apps.cozystack.io/v1alpha1, and
rewrites legacy flat resourcesPreset values (nano/micro/small/medium/
large/xlarge/2xlarge) to their instance-type equivalents (t1/c1).
Mapping is 1:1 by CPU and memory — the migration never bumps resource
usage. The same table lives in cozy-lib (legacy aliases) and in
pkg/apis/apps/presets/legacy.go.
Properties:
- Idempotent: re-running on a converted cluster is a no-op because
non-legacy values fall through the jq map_legacy else arm.
- Best-effort: a single failed patch logs a warning and continues;
cozy-lib legacy aliases keep charts rendering with identical CPU
and memory even if the migration is incomplete. kubectl patch
stderr is captured and surfaced in the WARN line so operators see
why a patch was rejected.
- Distinguishes "no items" from "kubectl errored" (RBAC stripped,
network down, CRD missing) so a broken cluster cannot look
identical to a clean no-op run and stamp the version
unconditionally.
- Dry-run: MIGRATION_DRY_RUN=1 prints the would-be patches and
leaves the version stamp at 39.
- Final summary echoed to both stdout and stderr.
- Version stamp only advances to 40 on a fully successful real run.
Bump migrations.targetVersion 39 -> 40 so the hook executes on the
next platform upgrade.
Co-authored-by: Matthieu ROBIN <matthieu@hidora.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
cozystack-api now scans each app CR Create and Update for the legacy
flat resourcesPreset names (nano, micro, small, medium, large, xlarge,
2xlarge) and emits a klog warning per occurrence with the dotted JSON
path inside the spec and the suggested 1:1 instance-type replacement.
Example log line:
Postgres/foo in tenant-x uses deprecated resourcesPreset "small" at
spec.resourcesPreset; migrate to "t1.small" (1:1 equivalent CPU and
memory)
Warnings are non-blocking. Legacy values still render correctly through
the cozy-lib legacy alias table; the warning helps operators discover
remaining legacy data after the platform upgrade.
The mapping table lives in pkg/apis/apps/presets/legacy.go and is the
single Go-side source of truth. The walker handles top-level, nested,
in-array, non-string and malformed-spec inputs. The wrapper warns are
emitted via a pure helper deprecationMessagesFor so the message format
is unit-testable without intercepting klog.
Co-authored-by: Matthieu ROBIN <matthieu@hidora.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Rewrite resourcesPreset values in every apps/* and extras/* chart from
the legacy flat names to the new instance-type form, using the 1:1
mapping:
nano -> t1.nano micro -> t1.micro
small -> t1.small medium -> c1.small
large -> c1.medium xlarge -> c1.large
2xlarge -> c1.xlarge
Each affected values.yaml carries the canonical 47-value enum (40
instance-type names plus 7 legacy aliases) so the schema accepts both
forms during the deprecation window. cozyvalues-gen regenerates the
matching api/apps/v1alpha1/*/types.go kubebuilder enum and defaults,
the chart values.schema.json, the README parameter table, and the
ApplicationDefinition openAPISchema in packages/system/*-rd/cozyrds.
Three hardcoded legacy literals in chart templates migrated:
- packages/apps/harbor/templates/harbor.yaml:121 (portal)
- packages/apps/opensearch/templates/opensearch.yaml:43 (dashboards)
- packages/system/keycloak/templates/sts.yaml:115 (heap fallback)
packages/apps/foundationdb/Makefile gains the missing hack/update-crd.sh
call. Without it, every regen left foundationdb-rd cozyrds stale and
new FoundationDB app CRs through cozystack-api were rejected at
validation for any non-legacy resourcesPreset value.
Every default-rendered chart produces identical CPU and memory to the
value applied before the rename, courtesy of the legacy alias table in
cozy-lib and the 1:1 default mapping.
Co-authored-by: Matthieu ROBIN <matthieu@hidora.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Restructure the resource preset table into a flat <series>.<size> naming
convention inspired by KubeVirt and cloud-provider instance types. Five
series cover the full CPU-to-memory ratio range:
t1 (Tiny, 1:0.5) — burstable, low memory
c1 (Compute, 1:1) — CPU-balanced, CPU-bound workloads
s1 (Standard, 1:2) — proxies, caches, lightweight services
u1 (Universal, 1:4) — databases and messaging
m1 (Memory, 1:8) — search and analytics
Each series provides eight sizes (nano, micro, small, medium, large,
xlarge, 2xlarge, 4xlarge), yielding 40 presets in total. Ephemeral
storage remains 2Gi for every preset.
The seven legacy flat names (nano, micro, small, medium, large, xlarge,
2xlarge) are retained as backward-compatibility aliases returning their
original CPU and memory values. Existing HelmReleases and app CRs
continue to render identical resources without a migration step. The
legacy block is deprecated and will be removed in a future release; the
1:1 conversion table is:
nano -> t1.nano (250m / 128Mi)
micro -> t1.micro (500m / 256Mi)
small -> t1.small (1 / 512Mi)
medium -> c1.small (1 / 1Gi)
large -> c1.medium (2 / 2Gi)
xlarge -> c1.large (4 / 4Gi)
2xlarge -> c1.xlarge (8 / 8Gi)
Also fix the preset helper docstring to pass the preset string straight
to unsanitizedPreset, replacing the prior list applied-to-tuple form
that silently invoked the dot value as a function.
Co-authored-by: Matthieu ROBIN <matthieu@hidora.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Point values.yaml to ghcr.io/cozystack/cozystack/kilo with the
freshly built image digest, replacing the upstream ghcr.io/squat/kilo
reference.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Address review feedback from gemini-code-assist on Dockerfile:36:
Remove custom Fastly CDN repo pinned to v3.20 while base image is
alpine:3.23 — use default repos from the base image instead.
Signed-off-by: Arsolitt <arsolitt@gmail.com>