Commit Graph
5361 Commits
Author SHA1 Message Date
myasnikovdaniil 13e202a53e [Backport release-1.6] feat(monitoring): add optional email receiver to alertmanager (#4614)
## What this PR does

Manual backport of #3800 to `release-1.6`.

The automated backport, #4609, stopped on a conflict in
`packages/system/monitoring-rd/cozyrds/monitoring.yaml` and pushed the
markers as its only commit, so it would ship conflict markers in the
ApplicationDefinition if merged.

That file is generated, and its schema and `keysOrder` lines already
differ between main and 1.6 for reasons unrelated to this change.
Everything else applies unchanged. I kept the `release-1.6` version of
the file and ran `make generate` in `packages/extra/monitoring` with
cozyvalues-gen 1.6.0. The README and `values.schema.json` came out
identical to the cherry-picked ones, and the regenerated schema adds
exactly the eight `alerta.alerts.email` properties that #3800 adds on
main, with nothing removed.

Verified on this branch: `helm unittest` passes 164 tests in 8 suites
for `packages/system/monitoring`, both new email suites included, and 9
tests for `packages/extra/monitoring`. The file set and line counts
match #3800.

Close #4609 in favour of this one, or tell me to take a different route
and I will.

### Screenshots

Not a UI change.

### Downstream repositories

Same walk as #3800: `packages/extra/monitoring` gains values fields, its
reference page on the website regenerates from `README.md` on the next
stable tag, and the Terraform provider does not model the monitoring
service. No package is added or renamed, and no CRD, tooling or node
contract is touched.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
feat(monitoring): add optional email alerting through alerta.alerts.email, with configurable severity and alert-name selection and an SMTP password read from the fixed Secret alertmanager-email-password
```
2026-10-14 12:35:45 +05:00
myasnikovdaniil b50fdf532c [Backport release-1.6] fix(dashboard, foundationdb): show the connection ConfigMap to tenants (#4684)
## What this PR does

Backport of #4612 to `release-1.6`, together with its follow-up #4789.
All three commits are cherry-picked. Two of them needed their
`ApplicationDetailPage.test.tsx` cases added by hand, because on this
branch that file has none of the virtual machine tab tests they sit next
to on main.

FoundationDB keeps its connection string in a ConfigMap that tenants may
read, and the console had no view for ConfigMaps. The application page
gets a ConfigMaps tab for the ConfigMaps named in the application's
resource map, with a copy button for each value. Each read uses an
exact-name field selector, so no general ConfigMap access is needed. The
FoundationDB chart now renders its resource map with monitoring disabled
too, and tenant roles may read it. If the resource map stops being
readable after a successful read, the tab goes away instead of keeping
the old names.

### Validation

- All 6 FoundationDB chart tests pass, and so do all 338 console tests
in 52 files and the TypeScript check.
- Tests cover finding the ConfigMaps through the resource map, reading
only the named ones in the active namespace, copying a value, a failed
copy, a denied read, malformed resource maps, and a resource map that
answers 403 or 404 after a successful read. The four tests for the last
case fail without the #4789 commit.

### Screenshots

The tab is the same as in #4612, which has a screenshot of it.

### Downstream repositories

Walked the trigger map against the diff. It changes a FoundationDB chart
template and its test, and the console, with no values, schema, CRD or
`hack/` file, and the console is vendored in this repository. No
companion repository needs an update.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
fix(dashboard): backport FoundationDB connection ConfigMaps to release-1.6
```
2026-10-14 12:35:35 +05:00
myasnikovdaniil 2388d09965 [Backport release-1.6] fix(etcd): leave compaction to etcd and pass the real quota to defrag (#4874)
## What this PR does

backport of #4873 to `release-1.6`. the commit is cherry-picked
unchanged from fe59a6bf9.

the defrag CronJob and the EtcdCluster template are the same on this
branch: etcd compacts itself with `autoCompactionMode: periodic` and a
5m retention, and `quotaBackendBytes` comes from the same
`calculateQuotaBackendBytes` helper. so the job runs a second compaction
that fails with `mvcc: required revision has been compacted` on idle
clusters, and it measures `dbQuotaUsage` against the tool's 2 GiB
default. it now passes `--compaction=false` and the chart's own quota.
the etcd chart tests pass here, 21 of 21.

### Screenshots

Not a UI change.

### Downstream repositories

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
fix(etcd): the defrag job no longer compacts on top of etcd's periodic auto-compaction, and it evaluates its 80% quota threshold against the cluster's real quotaBackendBytes instead of 2 GiB.
```
2026-10-14 12:35:25 +05:00
myasnikovdaniil fdaa9e1572 [Backport release-1.6] fix(mongodb): set the s3 bucket and prefix on the bootstrap restore (#4780)
## What this PR does

backport of #4779 to `release-1.6`. the template change is cherry-picked
unchanged from a6cf0e5ce. one test needed an edit for this branch, see
below.

the bug is the same here, and v1.6.4 ships this exact template. with
`bootstrap.enabled: true` the chart renders a
`PerconaServerMongoDBRestore` without `spec.backupSource.s3.bucket`,
which the operator crd requires, so the api server rejects it and the
release fails. the restore now takes the bucket and prefix from the same
helpers as the backup storage, so it reads from where the backups are
written. both places quote the values, the backup storage still leaves
out an empty prefix. a `destinationPath` that names no bucket fails at
render time.

this branch has no `backup.insecureSkipTLSVerify`. the backup storage
and the restore both hardcode `false`, so
`tests/restore-storage_test.yaml` checks `false` on both sides here
instead of setting the value to `true`.

- `helm unittest` passes 109 of 109 tests in 8 suites. before this
change it was 101 in 7.
- against the release-1.6 templates 7 of the 8 new cases fail, the same
7 as on main.
- `helm template` of the `PerconaServerMongoDB` gives the same picture
as on main for 8 `destinationPath` forms. 5 render the same storage, the
two bucket root forms only stop rendering a `prefix: null` the api
server prunes anyway, and `s3://2024/10` goes from ints the crd rejects
to strings.
- offline validation against the crd on this branch matches main. all 8
forms fail with `spec.backupSource.s3.bucket: Required value` before the
fix, and after it 7 pass and `s3://` stops at render time.
- `make generate` with cozyvalues-gen v1.6.0, the version this branch's
ci pins, leaves every generated file unchanged.
- `packages/apps/mongodb/Makefile` has no `test` target on this branch,
so ci does not run these suites here. i ran them by hand with
helm-unittest 1.1.2.
- no restore was run against a live cluster.

on upgrade, releases with `bootstrap.enabled: false` render the same
manifests as before. a release that still has `bootstrap.enabled: true`
creates its restore on the first reconcile after the upgrade, and the
operator starts restoring into the cluster as it is at that moment. the
release note says so.

### Screenshots

not a ui change.

### Downstream repositories

same diff as #4779, where the trigger map was walked file by file. no
entry matches.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
fix(mongodb): backport the bootstrap restore fix to 1.6. a mongodb app created with bootstrap.enabled now gets a PerconaServerMongoDBRestore with the s3 bucket and prefix of backup.destinationPath, so the api server accepts it and the operator looks for the backup where the backup storage wrote it.

on upgrade, an app that still has bootstrap.enabled set to true, for example after an earlier restore attempt that failed on the missing bucket, creates its restore on the first reconcile, and the operator restores the backup into the cluster as it is at that moment. set bootstrap.enabled to false before the upgrade on every mongodb app that should not be restored.
```
2026-10-14 12:35:15 +05:00
myasnikovdaniil 48bcb33ca5 [Backport release-1.6] fix(linstor): use severity warning in piraeus-datastore alerts (#4740)
## What this PR does

Backport of the LINSTOR severity fix and its alert-rule guard from #3799
to `release-1.6`, together with the guard's follow-up #4812. Seven
piraeus-datastore rules use `warn`, which the default Alerta alarm model
does not accept, and they now use `warning`. Alert names, expressions
and thresholds stay unchanged.

Cherry-picked `3ade16a380c9d03b83ff28ea02af3b800fdd1b0f` and
`bd2cc0a749531433a237a9c8a6e21a6f21dee200` with their authors and
cherry-pick references. The KEDA severity commit from the same main PR
is left out because the KEDA rule it fixes does not exist on
release-1.6. The follow-up from #4812 is cherry-picked too. It makes the
guard catch a quoted kind or a kind followed by a comment, and fail on a
rule group it cannot see into once template actions are stripped.

### Validation

- All nine checks in `hack/alert-severity-contract.bats` pass with
`hack/cozytest.sh` on this branch. The wider discovery finds the same 39
rule files as before and no rule group comes out empty.
- Against `release-1.6` at `da98ddc08` without the fix, the same
contract fails on exactly the seven `warn` rules corrected here.
- Delivery through Alertmanager and Alerta was not exercised.

### Screenshots

Not a UI change.

### Downstream repositories

The file-level trigger map was checked against both changed files: a
rule file under `packages/system/piraeus-operator/alerts/` and a new
test under `hack/`. No existing tool, make target, API schema, package,
output resource or documented workflow is renamed or changed. No
companion repository update is required.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
fix(linstor): backport accepted warning severity for seven piraeus-datastore alerts to release-1.6, with a regression guard for first-party alert rules
```
2026-10-14 12:35:04 +05:00
myasnikovdaniil 629dcc455d [Backport release-1.6] fix(platform): keep the legacy etcd-operator stopped after etcd adoption (#4739)
## What this PR does

Backport of #4738 to `release-1.6`, cherry-picked without changes from
`6248d458ad57c5991700dc26c5abc1340b1a05f4`.

Migration 50 scaled the legacy etcd-operator back to 1 after adopting
the legacy etcd clusters. Until a tenant's etcd HelmRelease reconciled
the new chart, Flux re-created the legacy EtcdCluster from the old one,
and the running legacy operator re-created the legacy StatefulSet and
took the legacy `etcd-headless` Service away from the adopted
EtcdMembers. The garbage collector deleted the Service when the new
chart pruned that EtcdCluster, and the adopted members'
`etcd-<i>.etcd-headless` names stopped resolving. This hit every tenant
etcd on a cluster upgraded from 1.4.3 to 1.6.4, and upgrades from 1.4
and 1.5 to 1.6 go through this branch. The operator now stays at 0 after
a successful adoption until the etcd-operator HelmRelease replaces it,
and a failed adoption still restores it through the EXIT trap. The full
timeline from the audit log and the repair for already upgraded clusters
are in #4738.

### Validation

- The commit applies cleanly to `release-1.6` at `da98ddc08`.
- `hack/cozytest.sh hack/migration-50-etcd-adopt.bats` passes all 29
tests on this branch. The new test fails against the release-1.6 script
with `FAIL: the legacy operator was scaled back up after a successful
adoption`.

### Screenshots

Not a UI change.

### Downstream repositories

Same diff as #4738, where the trigger map was walked file by file. No
entry matches.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
fix(platform): backport to 1.6 the fix that keeps the legacy etcd-operator stopped after migration 50 adopts the legacy etcd clusters, so the adopted members keep their etcd-headless DNS names through the upgrade.
```
2026-10-14 12:34:55 +05:00
myasnikovdaniil 17f3386453 [Backport release-1.6] fix(postgres): cap the default shared_buffers at a quarter of the memory limit (#4725)
## What this PR does

Backport of #4724 to `release-1.6`, including the memory-request cap
required by CloudNativePG when memory is overcommitted.

The chart renders no `shared_buffers`, and CloudNativePG 1.28.2, the
operator version on this branch, does not set one either, so PostgreSQL
starts with its built-in 128MB. That is the whole memory limit on
`t1.nano` and half of it on `t1.micro`, the chart's default preset, and
a dump, index scans over a large table or a replica catching up after a
failover can fill the pool and get the instance OOMKilled. Below a 512Mi
memory limit the chart defaults `shared_buffers` to a quarter of the
limit with a 16MB floor, capped at the rendered memory request rounded
down to whole MiB. From 512Mi up nothing is rendered and those clusters
are unchanged. An explicit `shared_buffers` in `postgresql.parameters`
still wins.

On upgrade every cluster below 512Mi that does not set `shared_buffers`
gets the new value. With the CloudNativePG defaults the chart keeps,
`unsupervised` and `restart`, the operator restarts the replicas first
and then the primary in place, so writes pause for one PostgreSQL
restart, and a single-instance cluster is unavailable for that time.

### Validation

- The commit applies cleanly to `release-1.6` at `da98ddc08`.
- `helm unittest` passes all 50 tests in 7 suites on this branch. The
added cases cover memory overcommit, fractional MiB requests, a request
below the 16MB floor, explicit values and the unchanged 512Mi threshold.
Four cases fail against the previous PR template.
- `helm template` of the chart on this branch renders `t1.small` exactly
as before, and the default preset differs only by `shared_buffers:
"64MB"`.
- `make generate` with cozyvalues-gen v1.6.0, the version this branch's
CI pins, leaves the generated files unchanged.

### Screenshots

Not a UI change.

### Downstream repositories

Same diff as #4724, where the trigger map was walked file by file. No
entry matches.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
fix(postgres): backport the small-preset shared_buffers default to 1.6. Without an explicit shared_buffers and below a 512Mi memory limit, PostgreSQL now gets a quarter of the limit with a 16MB floor, capped at the memory request, instead of its built-in 128MB, so a full buffer pool no longer takes the whole limit on t1.nano or half of it on t1.micro. Affected clusters restart their instances once on upgrade, the primary last.
```
2026-10-14 12:34:45 +05:00
myasnikovdaniil 29642c105b [Backport release-1.6] fix(nats): enable JetStream for the generated account (#4677)
## What this PR does

Backport of #4675 to `release-1.6`, cherry-picked without changes from
`15b7092f3ada7c26fbaa7c67be26e59ced73992f`. #4675 is merged in main now.

With `users` configured and `jetstream.enabled: true`, the application
chart enables JetStream on the server but generates account `A` without
it. Authentication and ordinary NATS messaging work, while
`$JS.API.INFO` returns error 10039, "JetStream not enabled for account".

The generated account now gets `jetstream: true` when persistent
messaging is enabled and the account does not set JetStream itself.
Tenant-supplied limits, explicit disablement, other accounts and the
existing generated-user merge are kept. nats-server matches config keys
case-insensitively and walks the account map in no fixed order, so a
`JetStream` key in any casing counts as set. Otherwise the account would
carry both keys and the server would apply either one, changing from
restart to restart.

Existing instances with `users` pick this up on upgrade. The rendered
NATS config changes, so the StatefulSet rolls its pods once, and account
`A` gets JetStream without account limits unless
`config.merge.accounts.A.jetstream` sets them.

### Validation

- The commit applies cleanly to `release-1.6` at `da98ddc08`.
- `helm unittest` passes all 65 application-chart tests on this branch.
- The run on NATS Server 2.11.10 is described in #4675.

### Screenshots

Not a UI change.

### Downstream repositories

The diff changes an application template and chart tests only. Public
values, schemas, output resource names and tooling contracts are
unchanged. The website NATS documentation contains no account-level
workaround to remove. No downstream trigger applies.


- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note



```release-note
fix(nats): enable JetStream on the account generated for users when jetstream.enabled is true, keeping any explicit account-level JetStream setting. Instances with users roll their NATS pods once on upgrade.
```
2026-10-14 12:34:36 +05:00
myasnikovdaniil f50f4a85e5 [Backport release-1.6] fix(api): let the garbage collector finalize Applications (#4683)
## What this PR does

Backport of #4610 to `release-1.6`. `Update` on this branch has no
`applyLiveMetadata`, so the finalizer merge and the copy of the deletion
metadata are done inline, in `Update` and in its conflict retry. The
tests are the same as on main.

An Application and its HelmRelease share one UID, so the garbage
collector keeps one graph node for both and may finalize it through the
Application endpoint. The API never returned finalizers on an
Application, so when the collector dropped `foregroundDeletion` or
`orphan` through it, the HelmRelease kept `foregroundDeletion` after
Helm had uninstalled the release and the deletion never completed. The
Application now carries the two garbage collection finalizers, and an
update that adds or removes one of them applies the same change to the
HelmRelease. Controller finalizers such as `finalizers.fluxcd.io` stay
owned by the live object.

### Validation

- `go test ./pkg/registry/apps/application/...` passes on this branch.
- Making the finalizer merge return the live list turns four tests red,
the conflict-retry test among them.
- No API types change, so code generation is not affected.

### Screenshots

Not a UI change.

### Downstream repositories

Walked the trigger map against the diff. It changes the Application REST
handler and its test, with no chart, values, schema, CRD or `hack/`
file, so no companion repository needs an update.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:

### Release note

```release-note
fix(api): an application deleted with foreground or orphan propagation no longer leaves its HelmRelease stuck with the foregroundDeletion or orphan finalizer
```
2026-10-14 12:34:26 +05:00
myasnikovdaniil 6086bd1b46 [Backport release-1.6] feat(keycloak): expose zone placement for Keycloak and the database proxy (#4856)
# Description
Backport of #4606 to `release-1.6`.
2026-10-14 12:33:56 +05:00
myasnikovdaniil f95ba62000 [Backport release-1.6] fix(cert-manager): enable the Gateway API solver in the host cert-manager (#4808)
# Description
Backport of #4039 to `release-1.6`.
2026-10-14 12:33:46 +05:00
myasnikovdaniil 008c0256b4 [Backport release-1.6] fix(cozy-lib): round the sanitized CPU request up to a whole milli-CPU (#4590)
# Description
Backport of #3522 to `release-1.6`.
2026-10-14 12:33:36 +05:00
myasnikovdaniil e23815ba00 [Backport release-1.6] fix(kubernetes): apply worker TalosConfigTemplate server-side (#4575)
# Description
Backport of #4163 to `release-1.6`.
2026-10-14 12:33:27 +05:00
myasnikovdaniil 0c5564aae4 [Backport release-1.6] fix(kubernetes): probe Keycloak CRDs by output in oidc-bootstrap cleanup (#4571)
# Description
Backport of #3520 to `release-1.6`.
2026-10-14 12:33:17 +05:00
myasnikovdaniil 6fea44c4a5 [Backport release-1.6] chore(hetzner-robotlb): update robotlb to 0.1.0 (#4560)
# Description
Backport of #4557 to `release-1.6`.
2026-10-14 12:32:41 +05:00
Yan Bondarenko 1241cfd4e5 fix(etcd): leave compaction to etcd and pass the real quota to defrag
The hourly defrag CronJob runs etcd-defrag with its defaults, which compact
to the latest revision before defragmenting. Every cluster already compacts
itself with a periodic five-minute retention, so the second compaction
either fails with "required revision has been compacted" when nothing was
written since, or drops the history that retention keeps for watchers to
resume from.

The same defaults evaluate dbQuotaUsage in the defrag rule against 2 GiB
rather than the quotaBackendBytes the cluster runs with, so the 80 percent
threshold fires at a different database size than intended.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit fe59a6bf91)
2026-10-11 20:25:46 +03:00
Andrei Kvapil 4c8c53610a feat(keycloak): expose zone placement for the keycloak-db instances
The Keycloak StatefulSet and the database proxy can already be spread
across failure domains, but the CloudNativePG Cluster behind them could
only follow the cluster-wide topology constraint, with no way to pick
zones for this database alone. With both instances in one zone, losing
that zone loses the database and every login with it.

Add database.affinity (CloudNativePG shape) and
database.topologySpreadConstraints, with empty defaults so nothing
changes unless an installation opts in. The cnpg.io/cluster label
selector is added to constraints that carry none, and the constraints
replace the cluster-wide ones for this database when set.

Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit dde75d6cf5)
2026-10-10 23:50:31 +00:00
Kirill Ilin f8766f7b03 feat(keycloak): let Keycloak and its database proxy spread across zones
Neither the Keycloak StatefulSet nor the keycloak-kms-proxy Deployment
exposed any placement, so the scheduler was free to put both replicas of
each in one failure domain. For Keycloak that is worse than it looks: a
StatefulSet does not replace a pod stuck on an unreachable node, so losing
that domain takes every replica for as long as it stays lost.

Expose affinity and topologySpreadConstraints for both, empty by default
so nothing changes unless an installation opts in, and give the proxy a
PodDisruptionBudget once it runs more than one replica.

Assisted-By: LLM
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 218384ed32)
2026-10-10 23:50:31 +00:00
Yan Bondarenko 2e7802ce52 test(monitoring): stop the alert severity guard from missing rule sources
The guard found rule files by an exact `kind: PrometheusRule` or
`kind: VMRule` line, so a quoted kind or one followed by a comment took the
file out of the check. A rule group whose rules all come from template
actions is empty once those are stripped, so it passed with nothing
checked. Discovery now accepts those spellings, and a rule document without
groups, or a group without a visible alert or recording rule, fails the run
the way a file that cannot be parsed does.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit dc814f3ae5)
2026-10-07 20:23:50 +03:00
Aleksei Sviridkin 57a139587f fix(cert-manager): enable the Gateway API solver in the controller
With the platform Gateway enabled, the ClusterIssuers in
cert-manager-issuers and the per-tenant Issuers rendered for
TenantGateway carry an http01.gatewayHTTPRoute solver, but the
controller only honours that solver when Gateway API support is
switched on, and the vendored chart leaves it off. Every HTTP-01
challenge behind the Gateway then fails with "gateway api is not
enabled" and no ACME certificate is issued.

Pass a ControllerConfiguration with enableGatewayAPI to the host
cert-manager through the component values of its platform Package.
The host always ships the Gateway API CRDs and orders cert-manager
after them, so the flag is safe on every variant.

It is not a default of the system/cert-manager chart: the same chart
is installed into tenant clusters, where the CRDs are an opt-in addon
and a controller started with Gateway API support and no CRDs exits
at startup. The tenant side keeps opting in on its own.

Signed-off-by: Aleksei Sviridkin <f@lex.la>
Assisted-by: LLM
(cherry picked from commit 76b9e55102)
2026-10-07 14:48:08 +00:00
Yan Bondarenko 07be46d37c fix(dashboard): drop the resource map ConfigMaps once the map is unreadable
React Query keeps the last successful list when a refetch fails. After the
resource map became forbidden or went away, the hook went on parsing that
old copy, so the ConfigMaps tab stayed with stale names, and a malformed
map kept its old error, instead of the tab going away as it does when the
map is unreadable from the start.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 8ce3f853af)
2026-10-07 11:00:42 +03:00
Yan Bondarenko e63439bb50 fix(api): let the garbage collector finalize Applications
An Application and its HelmRelease share one UID, so the garbage
collector keeps a single graph node for both and may finalize it through
the Application endpoint. The API never returned finalizers on an
Application, and every update restored the HelmRelease finalizers from
the live object. When the collector came to drop foregroundDeletion or
orphan through the Application, removeFinalizer found no such finalizer
and returned as if it were already gone. The HelmRelease then kept
foregroundDeletion after Helm had uninstalled the release, and the
deletion never completed.

The Application now carries the two garbage collection finalizers, and
an update that adds or removes one of them applies the same change to
the HelmRelease. Controller finalizers such as finalizers.fluxcd.io stay
owned by the live object, so helm uninstall still runs before the
release goes away. The deletion timestamp and grace period are copied
from the live object, which keeps an update of a terminating release
valid.

Backport of 46b5a542fe to release-1.6. Update on this branch has no
applyLiveMetadata, so the finalizer merge and the deletion metadata copy
are done inline, in Update and in its conflict retry. The tests are the
same as on main.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
2026-10-07 00:56:47 +03:00
Yan Bondarenko 45bce211d1 fix(postgres): cap shared_buffers at the memory request
CloudNativePG rejects clusters whose shared_buffers exceeds the memory
request. Memory overcommit can put that request below both a quarter of
the limit and the 16MB floor.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 7af129b6a1)
2026-10-07 00:48:30 +03:00
Yan Bondarenko eb97d7a52c fix(postgres): cap the default shared_buffers at a quarter of the memory limit
The chart renders no shared_buffers, so PostgreSQL starts with its 128MB
default whatever the container gets. A full pool is the whole memory
limit on t1.nano and half of it on t1.micro, the default preset. The
pool is shared memory that the kernel cannot reclaim without swap, so
when a dump, index scans over a large table or a replica catching up
after a failover fill it, the instance is OOMKilled.

Instances below a 512Mi memory limit now default to a quarter of the
limit, at least 16MB. From 512Mi up a quarter is at least 128MB, so
those instances render exactly as before. shared_buffers needs a
restart, so on upgrade CloudNativePG restarts every instance below
512Mi that does not set it explicitly.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 0b39d7ea89)
2026-10-07 00:48:30 +03:00
Yan Bondarenko 7779208932 fix(mongodb): set the s3 bucket and prefix on the bootstrap restore
With bootstrap.enabled the chart rendered a PerconaServerMongoDBRestore
without backupSource.s3.bucket. The operator CRD requires that field, so
the API server rejected the restore and the HelmRelease failed. The prefix
was missing too, and it matters just as much. For a backupSource restore
the operator builds the PBM storage from backupSource.s3 alone and takes
only the backup name from backupSource.destination, so a restore without
the prefix would look for the backup at the bucket root.

The restore now takes the bucket and prefix from the same helpers that
fill the backup storage, so it reads from where the backups are written.
Both places quote the two values, so a numeric bucket or prefix stays a
string instead of making the resource invalid. The backup storage still
leaves out an empty prefix, so running releases keep the same object. A
destinationPath that names no bucket fails at render time instead of
reaching the operator with an empty bucket.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit a6cf0e5ce4)
2026-10-06 21:30:34 +03:00
Yan Bondarenko 2610fb8565 fix(dashboard): show ConfigMaps listed in the application resource map
FoundationDB keeps its connection string in a ConfigMap that its operator
writes, and tenants may read it, but the console had no view for
ConfigMaps. Tenant roles grant ConfigMaps by name only, so the tab takes
the names from the application's resource map and reads each one with a
metadata.name field selector, which RBAC checks against resourceNames.
An application without a readable resource map shows no tab, while a
listed ConfigMap that cannot be read is reported instead of looking
empty.

On release-1.6 ApplicationDetailPage.test.tsx has none of the virtual
machine tab tests it sits next to on main, so only the ConfigMaps case
is added there.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 2fa7fea29b)
2026-10-04 12:07:43 +03:00
Yan Bondarenko 5b0682a073 fix(foundationdb): let tenants read the dashboard resource map
The resource map is the only object that names the connection ConfigMap
for a client such as the dashboard. It was rendered only with monitoring
enabled, and the tenant role could not read it, so a tenant session had
no way to find the ConfigMap it is allowed to read.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit e3ae8033e6)
2026-10-04 12:07:13 +03:00
Yan Bondarenko a8c7880cb6 test(monitoring): guard alert severities against the Alerta alarm model
Alerta refuses an alert whose severity is not in its alarm model, so a
rule with such a label is dropped every time it fires and the alert never
reaches anyone. Seven piraeus-datastore rules used warn and the keda
at-max rule used info, and nothing in the tree caught either.

The contract collects every PrometheusRule and VMRule document under
packages, in alerts files and in chart templates, and fails on any
alerting rule whose labels.severity is missing or not in the accepted
list. Helm actions are stripped before parsing, so a templated rule is
still checked, and a file that cannot be parsed fails the run instead of
being skipped. Values are compared as whole words.

none stays out of the list because the Alertmanager config routes it to
a blackhole receiver. Vendored charts under packages/**/charts/** are out
of scope because they are re-vendored rather than edited.

Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
Assisted-by: LLM
(cherry picked from commit bd2cc0a749)
2026-10-04 11:13:32 +03:00
Yan Bondarenko afc51e425d fix(linstor): use severity warning instead of warn in piraeus-datastore alerts
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 3ade16a380)
2026-10-04 11:13:32 +03:00
Yan Bondarenko 95d7026c2e fix(nats): enable JetStream for the generated account
With users configured and jetstream.enabled true, the chart enables
JetStream on the server but generates account A without it, so every
JetStream call from those users fails with error 10039, "JetStream not
enabled for account". The generated account now gets jetstream: true
unless it already sets JetStream itself. nats-server matches config keys
case-insensitively and walks the account map in no fixed order, so a
JetStream key in any casing counts as set. Otherwise the account would
carry both keys and the server would apply either one, changing from
restart to restart.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 15b7092f3a)
2026-10-04 11:13:31 +03:00
Yan Bondarenko e708662e50 fix(platform): keep the legacy etcd-operator stopped after etcd adoption
Migration 50 scales the legacy etcd-operator to 0, adopts every legacy
etcd.aenix.io cluster with etcd-migrate and then scales the operator
back to 1. At that point it is still the legacy operator, and it has
nothing left to manage. Until a tenant's etcd HelmRelease reconciles the
new chart, Flux can upgrade it with the old one, which re-creates the
legacy EtcdCluster that etcd-migrate just orphan-deleted. The legacy
operator then reconciles it, re-creates the legacy StatefulSet and
rewrites the legacy etcd-headless Service, dropping the owner references
etcd-migrate pointed at the adopted EtcdMembers. When the new chart
prunes the legacy EtcdCluster, the garbage collector deletes the Service
with it, and the adopted members' etcd-<i>.etcd-headless names stop
resolving.

After a successful adoption the operator now stays at 0 until the
etcd-operator HelmRelease replaces the Deployment with the v1alpha2
operator later in the same upgrade. A failed or interrupted adoption
still restores it through the EXIT trap.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 6248d458ad)
2026-10-03 18:25:59 +03:00
Yan Bondarenko 0e76dda5ae feat(monitoring): add optional email alert delivery
Platform alerts need an email delivery path alongside Alerta without
exposing arbitrary namespace Secrets through tenant-controlled values.
SMTP credentials therefore use a fixed Secret name.

Alertmanager parses the addresses and connects to the SMTP host only
when it sends a notification, so a malformed value there drops alerts
instead of failing the release. The chart validates these fields when
it renders. Addresses must be literal dot-atom mailboxes, and a domain
literal must hold a dotted-quad IPv4 address, because IPv6 literal
syntax differs across the supported Go mail parsers. A bracketed
smarthost must be a valid IPv4 or IPv6 address, and its port must be
between 1 and 65535 without leading zeros. The repeat interval follows
the Alertmanager duration grammar and range, so a value that renders is
one Alertmanager loads.

Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
Assisted-by: LLM
(cherry picked from commit 17aaf3e038)
2026-09-30 17:45:05 +03:00
Mattia Eleuteri 6e70d38f20 fix(cozy-lib): round the sanitized CPU request up to a whole milli-CPU
cozy-lib.resources.sanitize divides the CPU limit by cpuAllocationRatio
and rendered the quotient as a bare float. When the ratio does not
divide the value evenly the result is finer than a milli-CPU, and the
VPA admission webhook rejects it outright:

  admission webhook "vpa.k8s.io" denied the request:
  minAllowed: CPU [62500u] must be a whole number of milli CPUs

packages/extra/etcd routes its VPA minAllowed/maxAllowed through the
helper, so 250m / 4 = 62.5m left the etcd HelmRelease looping
UpgradeFailed -> RollbackFailed forever: the rollback target renders the
same invalid value. Since v1.6.0 HelmReleases wait on each other, so
that one stuck app also blocks tenant-root, cozystack-basics and
kubevirt-cdi-operator, and without CDI the Talos worker rollover cannot
import the worker OS image. Only the divisors of 250 worked as ratios,
which is an artefact of one chart's hardcoded floor rather than a real
constraint on the operator.

The request is rounded up, never down, so it stays at or above the
intended fraction of the limit. It is rounded only when it has to be:
if the milli-CPU value equals its own ceiling, the float keeps its
current rendering, so nothing changes on the default ratio of 10 or on
any ratio that divides evenly; otherwise it renders as the ceiling in
m. The comparison is exact, with no tolerance. sprig's divf and mulf run
on shopspring/decimal rather than float64, so mulf (divf 0.25 10.0)
1000.0 renders exactly 25 and there is no binary-float noise on this
codepath to absorb. A tolerance would reintroduce the bug: a value
whole-milli only to within it, such as 100.0000004m at ratio 1, would
read as exact and render "0.1000000004", rejected for the same reason
62.5m is. The same predicate covers sub-milli input, since ceil carries
any positive request to at least 1m, and a zero request stays "0".

Fixes #2917

Assisted-by: LLM
Signed-off-by: Mattia Eleuteri <mattia@hidora.io>
(cherry picked from commit 7c9ab0e28e)
2026-09-29 18:18:15 +00:00
Mattia Eleuteri 4b8ce05919 fix(kubernetes): apply worker TalosConfigTemplate server-side
The talos-reconcile Job runs under a 256Mi limit and applies its
TalosConfigTemplate client-side. Building the merge patch means pulling
the cluster's full OpenAPI schema down, which on a management cluster
carrying a few hundred CRDs costs around 290Mi of RSS, so the kernel
OOMKills kubectl before the Job can finish.

Only the merge path pays that cost. The first run creates the object and
stays cheap, so a fresh install succeeds and the Job then
CrashLoopBackOffs on every reconcile afterwards, which means on every
chart upgrade. Measured against a 438-CRD cluster with the Job's own
kubectl (alpine/k8s:1.33.4), cold discovery cache:

  get -o jsonpath                    52Mi
  apply, object absent (create)      52Mi
  apply, object present (merge)     292Mi   <- OOMKilled at 256Mi
  apply --server-side                56Mi

--validate=false changes nothing, so the cost is the merge strategy
lookup rather than validation.

Server-side apply leaves the merge to the apiserver and the client never
needs the schema. --force-conflicts keeps the Job authoritative over an
object an earlier client-side apply created.

Assisted-by: LLM
Signed-off-by: Mattia Eleuteri <mattia@hidora.io>
(cherry picked from commit 1728b49e0c)
2026-09-29 15:24:51 +00:00
Mattia Eleuteri 0b2a73e809 fix(kubernetes): probe Keycloak CRDs by output in oidc-bootstrap cleanup
`kubectl api-resources --api-group=<absent group>` exits 0 and prints an
empty list, so guarding on the exit code always fell through. The delete
then failed with `the server doesn't have a resource type "keycloakclient"`
— `--ignore-not-found` covers a missing object, not an unknown type.

Because the oidc-bootstrap Job is a post-install/post-upgrade Helm hook,
that failure blocked the Helm upgrade of every `kubernetes-<cluster>`
release on any cluster without the EDP Keycloak operator CRDs, which is
the default configuration (`oidc.mode: None`).

Capture the discovery output once and gate each delete on its own
resource type, matching the probe idiom already used by the platform
migrations and the ouroboros cleanup hook.

Fixes #3516

Signed-off-by: Mattia Eleuteri <mattia@hidora.io>
Assisted-by: LLM
(cherry picked from commit 06400ac033)
2026-09-29 11:26:23 +00:00
Kirill Ilin 27b1d61ce9 chore(hetzner-robotlb): update robotlb to 0.1.0
The upstream project moved from the intreecom GitHub organization to
treetscom, so the chart and image are now pulled from the new location.

Assisted-By: LLM
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 5d02c94e71)
2026-09-29 08:51:58 +00:00
myasnikovdaniil da98ddc088 [Backport release-1.6] fix(e2e-sandbox): install mc from its GitHub release (#4535)
## What this PR does

Backports the [mc download
fix](https://github.com/cozystack/cozystack/commit/e66f1345640293403441d9f507659dcf68738d6b)
from [the dependency
rollup](https://github.com/cozystack/cozystack/pull/4447) to
`release-1.6`. Only the mc commit is cherry-picked, with its original
author and `-x` reference.

The [release-line
build](https://github.com/cozystack/cozystack/actions/runs/36392555199/job/108831432467)
fails because `dl.min.io` returns HTTP 410. This is the same problem as
[the closed mc download
issue](https://github.com/cozystack/cozystack/issues/4487), whose fix
had only reached `main`.

Validation: the local amd64 image builds and `mc --version` works inside
it. Downloads, SHA256 and ELF architecture checks passed for amd64 and
arm64, and the install command rejects corrupted downloads and
unsupported architectures. The full `make unit-tests` target passed.

### Screenshots

No UI changes.

### Downstream repositories

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:

### Release note

```release-note
fix(e2e-sandbox): restore mc installation in release-1.6 builds using pinned GitHub release assets and SHA256 checks
```
2026-09-28 15:40:22 +05:00
Aleksei Sviridkin eeb943144c fix(e2e-sandbox): install mc from its GitHub release
dl.min.io now answers 410 Gone for every community mc build, since
MinIO archived the project, so the sandbox image no longer builds.
The final mc release is still published as a GitHub release asset.
Pin it and verify the per-arch checksum, because the old install
trusted whatever the URL served.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
(cherry picked from commit e66f134564)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-09-28 14:14:20 +05:00
myasnikovdaniil 130c7d80a0 chore(release): promote v1.6.4-rc.1 -> v1.6.4 (#4533)
Promotes `v1.6.4-rc.1` to stable `v1.6.4` without rebuilding containers.
Their digests remain bit-for-bit what passed rc e2e; the tag-rewritten
packages tree is re-serialized as a temporary OCI candidate and pinned
here by digest. On merge, pull-requests-release.yaml verifies that
candidate against this tree before creating the write-once `v1.6.4` tag,
retagging the candidate and container digests to `v1.6.4` (+`:latest`
when this is the newest stable), publishing the stable cozy-installer
chart, and publishing the release. Do NOT squash-merge (decision B): the
stable tag must attach to a real merge commit.

⚠️ **RC e2e gate bypassed** — this promotion did not verify green full
e2e evidence for `v1.6.4-rc.1`.

ℹ️ E2E already ran against the immutable rc, so this promote PR does not
run E2E by default. A maintainer may add the `full-e2e` label to run the
full suite again.

✅ Includes `docs/changelogs/v1.6.4.md`, which finalize uses verbatim as
the published release body.

✅ Website docs PR opened/refreshed on `cozystack/website` (branch
`update-docs-v1.6.4`), generated from the `release-1.6.4` staging
branch. **Do NOT merge that PR until `v1.6.4` is published** — merging
it early flips the site's latest-version pointer to an unpublished
version and 404s its docs/API links (see the PR body).
v1.6.4 api/apps/v1alpha1/v1.6.4
2026-09-28 12:36:14 +05:00
cozystack-ci[bot] de56e7b5b8 docs: add changelog for v1.6.4
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-09-28 05:45:09 +00:00
cozystack-ci[bot] 5a32ce0163 Pin promoted packages artifact for v1.6.4
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-09-28 05:35:29 +00:00
cozystack-ci[bot] cb155b1bf7 Prepare release v1.6.4 (promoted from v1.6.4-rc.1)
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-09-28 05:35:26 +00:00
Aleksei Sviridkin a977a6b53b test(kafka): wait for ZooKeeper PVC deletion (#4484)
This reopens a fork pull request from a branch in this repository so its
CI can run. The commit is the one from #4481 by @yankawai, unchanged. On
release-1.6 the pull-request CI pushes the images it builds, and a run
from a fork has no registry credentials, so #4481 could never get past
the build jobs to e2e. The description below is the author's.

## What this PR does

Wait for both ZooKeeper PVCs to disappear after Kafka deletion. Negative
assertions can stop on an API read error before their timeout; deletion
watches wait for the resource to be removed. The existing Bound and
KafkaTopic checks are unchanged.

Carries the test-only change from c92828ce in #4339, which was not
included in #4402. This targets `release-1.6`; the Kafka suite on `main`
uses KRaft without ZooKeeper.

Validated with Chainsaw 0.2.15: delayed deletion, an already absent PVC,
an interrupted watch, and the read-error fixture pass. A retained PVC
and forbidden access fail. The full Kafka E2E run remains for CI.

### Screenshots

Not applicable.

### Downstream repositories

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:

### Release note

```release-note
NONE
```
2026-09-25 23:37:01 +04:00
cozystack-ci[bot] 550a8be0b4 Prepare release v1.6.4-rc.1
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-09-25 12:58:03 +00:00
Yan Bondarenko ead8bb3a57 test(kafka): wait for ZooKeeper PVC deletion
Negative PVC assertions can stop on an API read error before the deletion
 timeout expires.

Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
2026-09-25 13:56:34 +03:00
myasnikovdaniil 6f00d308e4 [Backport release-1.6] feat(kubevirt): expose migration configuration through platform values (#4402)
This reopens a fork backport from a branch in this repository so its CI
can run. The commit is the one from #4339 by @yankawai, unchanged. On
release-1.6 the pull-request CI pushes the images it builds, and a run
from a fork has no registry credentials, so #4339 stopped at the build
jobs and never reached e2e. The description below is the author's.

## What this PR does

Manual backport of #4254 to `release-1.6`.

The automated backport, #4322, stopped with conflict markers in four
files as its only commit, so it is red on DCO and unmergeable as it
stands.

Every conflict has the same cause: the `kubevirt.disabledFeatureGates`
work landed on main after 1.6 was cut, and the cherry-pick carried it
into hunks this line does not have. Four differences follow:

- platform values gains a `kubevirt` block holding `migrations` alone,
and the iaas bundle gains only the migrations hop;
- the wiring test takes the four migrations cases and the case for a
null `kubevirt` block, without the assertions that belong to
disabledFeatureGates cases this line does not have;
- `update_idempotency_test.sh` gains `run_update_logged`, a four-line
helper that arrived on main with that work and the new cases need;
- the kubevirt Makefile header counts six sed patches rather than five.

Verified on this branch: 9 kubevirt chart tests, 31 platform wiring
tests (102 across the platform suite), and `update_idempotency_test`
PASS under GNU make and sed. Removing the new awk guard from the
Makefile turns that test red naming the migrations block, so the ported
guard is doing work. On this line `(.Values.kubevirt).migrations` is the
only reader of `.Values.kubevirt`; rewriting it as
`.Values.kubevirt.migrations` turns the null-block case red with a nil
pointer.

Feature summary, unchanged from #4254: cluster-wide migration settings
could only be applied by patching the KubeVirt CR, because the kubevirt
chart did not render `migrations` and the platform bundle did not
forward it. `kubevirt.migrations` now passes through the generated
Package to `spec.configuration.migrations`. A hand patch of that Package
is undone on the next platform render, so this hop is the only supported
setter.

```yaml
kubevirt:
  migrations:
    bandwidthPerMigration: 625M
    parallelMigrationsPerCluster: 2
    parallelOutboundMigrationsPerNode: 1
```

### Screenshots

Not a UI change.

### Downstream repositories

Walked the trigger map against the diff: platform values, the iaas
bundle and the kubevirt chart. The v1.6 reference page of the platform
values had no `kubevirt` section, so the row goes there as a follow-up
that should land with this backport.

- [ ] No downstream repository is affected by this change
- [x] [cozystack/website](https://github.com/cozystack/website) -
follow-up: cozystack/website#705

### Release note

```release-note
feat(kubevirt): expose `kubevirt.migrations` in the platform values and forward it to `spec.configuration.migrations` on the KubeVirt CR, so live-migration bandwidth and parallelism can be set without patching a Package that the platform re-renders.
```
v1.6.4-rc.1
2026-09-25 14:46:13 +05:00
myasnikovdaniil 0dc238a94a [Backport release-1.6] fix(kubeovn): retry VM migration setup after scheduling (#4328)
# Description
Backport of #4253 to `release-1.6`, together with #3460 which it depends
on. On 1.6 kube-ovn chart and image still come from
cozystack/kubeovn-chart, so draft Dockerfile had nothing to build it and
kubeovn build failed (no `image` target). #3460 moves build in-tree on
same kube-ovn 1.15.10 this branch runs, and brings nightly-mirror fix
for kube-ovn split registry host that becomes needed once kube-ovn is
built by CI. Bot draft also dropped second commit of #4253
(`fix-vmim-target-pod-retry.diff`), it is back now.

I built image locally, all three patches apply to kube-ovn v1.15.10 and
`TestVMIMigrationSchedulingRetry` passes.
2026-09-25 14:46:00 +05:00
myasnikovdaniil 6d25310774 [Backport release-1.6] fix(cluster-api): backport live migration before host eviction (#4474)
# Description
Backport of #4291 to `release-1.6`.
2026-09-25 14:45:54 +05:00
myasnikovdaniil 0cf1403be4 [Backport release-1.6] fix(linstor): add opt-in graceful satellite shutdown on Talos (#4401)
This reopens a fork backport from a branch in this repository so its CI
can run. The commit is the one from #4338 by @yankawai, unchanged. On
release-1.6 the pull-request CI pushes the images it builds, and a run
from a fork has no registry credentials, so #4338 stopped at the build
jobs and never reached e2e. The description below is the author's.

## What this PR does

Manual backport of #4292 to `release-1.6`.

The automated backport, #4320, stopped on a conflict in
`packages/system/linstor/values.yaml` and pushed the markers as its only
commit, so it is red on DCO and would ship conflict markers in a values
file if merged.

The conflict is `drbd.enabled`, which does not exist on this line: the
DRBD-less-substrate switch landed on main after 1.6 was cut, and the
cherry-pick pulled its values block in with the hunk it needed.
Everything else in the change applies unchanged, so three differences
follow from that one cause:

- the preStop hook is gated on `talos.gracefulShutdown.enabled` alone
rather than on it and `drbd.enabled`;
- the values block adds `talos.gracefulShutdown` only;
- the case asserting the hook is omitted on a Talos substrate without
DRBD goes with the flag it sets, and the README line that named both
flags names `talos.enabled`.

Verified on this branch: 11 Helm tests and the 20 behavioural Python
tests pass. The file set and line counts match #4292 apart from those
three points.

Feature summary, unchanged from #4292: Cozystack's Talos configuration
removes the systemd DRBD shutdown guard without a replacement.
`talos.gracefulShutdown.enabled`, disabled by default, releases unused
Secondary DRBD resources before the satellite stops so their backing
devices, including ZFS zvols, can be released during normal shutdown.
The hook skips Primary resources and open devices, rechecks each
candidate, and stops on ambiguous status, command failure or timeout. It
never forces, demotes, calls the Kubernetes API or asks for extra
permissions. It is opt-in because preStop also runs on ordinary
satellite restarts, and Piraeus has one DaemonSet per node with no
cluster-wide rollout barrier.

### Screenshots

Not a UI change.

### Downstream repositories

Walked the trigger map against the diff: this touches one system chart,
its hook script and its tests. No downstream repository restates the
linstor chart values.

- [x] No downstream repository is affected by this change

### Release note

```release-note
fix(linstor): add `talos.gracefulShutdown.enabled`, off by default, so a satellite releases unused Secondary DRBD resources before it stops and their backing devices, ZFS zvols included, can be released during a normal Talos shutdown. Enable it only where satellite and node restarts are serialized: the hook also runs on ordinary pod restarts, and Piraeus has one DaemonSet per node.
```
2026-09-25 14:45:34 +05:00
IvanHunters 9f2d21e5e8 [Backport release-1.6] fix(workloadmonitor): populate VM instance-profile label from the KubeVirt preference annotation (#4454)
# Description
Backport of #4448 to `release-1.6`.
2026-09-25 11:14:24 +03:00