Commit Graph
1939 Commits
Author SHA1 Message Date
IvanHunters 4874dbe6b2 chore(hetzner-robotlb): update robotlb to 0.1.0
Backport of #4557 to release-1.6. The upstream project moved GitHub organisations from intreecom to treetscom, and no image has been published under the old location since. The chart on this branch still points there, so the component cannot pull at all: the Deployment sits in ImagePullBackOff while the HelmRelease reports healthy, because Helm only waited for the objects to be created.

0.1.0 also carries the fix that makes balancer targeting follow the service's externalTrafficPolicy, which a cluster relying on `Local` needs in order to keep sending traffic only to nodes that run the backing pods.

(cherry picked from commit b314514950)

Assisted-by: LLM
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
2026-10-06 20:35:12 +03: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
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
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.
```
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
Yan Bondarenko 2744dcf42a docs(cluster-api): explain the omitted migration priority by the pinned API
CAPK v0.1.10 pins kubevirt.io/api v1.5.0, whose
VirtualMachineInstanceMigrationSpec carries only vmiName; upstream #392
sets priority against v1.9.0. The typed migration does not compile against
the pinned API, which is why the patch builds it unstructured.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit bc2ba106e1)
2026-09-25 10:46:45 +05:00
Yan Bondarenko 6360e05c20 fix(cluster-api): bound pending migration submission
A migration that KubeVirt never processes must not block host eviction indefinitely. Keep its submission deadline separate from active migration and fallback drain windows.

Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit c85f35070c)
2026-09-25 10:46:45 +05:00
Yan Bondarenko 64b76615ce docs(cluster-api): clarify trusted backport image delivery
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit bb3a2fa220)
2026-09-25 10:46:45 +05:00
Yan Bondarenko a0e1c8a63a fix(cluster-api): backport live migration before host eviction
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit c8f4906e93)
2026-09-25 10:46:44 +05:00
Yan Bondarenko bfb42248db feat(kubevirt): expose migration configuration through platform values
Backport of #4254 to release-1.6.

Cluster-wide migration settings could only be applied by patching the KubeVirt
CR: the kubevirt chart did not render `migrations`, and the platform bundle did
not forward it. The optional `kubevirt.migrations` platform value now passes
through the generated Package to `spec.configuration.migrations`, and a hand
patch of that Package is undone on the next platform render, so this hop is the
only supported setter.

Four differences from main, all from release-1.6 predating the
disabledFeatureGates work:

- 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 absent here;
- update_idempotency_test.sh gains `run_update_logged`, which arrived on main
  alongside 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 not decorative. On this line
(.Values.kubevirt).migrations is the only reader of .Values.kubevirt, and
rewriting it as .Values.kubevirt.migrations turns the null-block case red with a
nil pointer.

The automated backport in #4322 stopped with conflict markers in four files as
its only commit, which is why this exists.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
2026-09-25 09:35:57 +05:00
Aleksei Sviridkin d159113a0b fix(linstor): add opt-in graceful satellite shutdown on Talos
Backport of #4292 to release-1.6.

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 uses no force,
demotion, Kubernetes API calls or extra permissions.

Three differences from main, all from the same cause: release-1.6 has no
drbd.enabled flag, since the DRBD-less-substrate switch landed after 1.6 was
cut. The hook is therefore gated on talos.gracefulShutdown.enabled alone, the
values block adds only that key, and the case asserting the hook is omitted on
a substrate without DRBD is left out along with the flag it sets. The README
line naming both flags names talos.enabled instead. Nothing else differs.

The automated backport in #4320 stopped at the same values.yaml hunk and
pushed the conflict markers as its only commit, which is why this exists.

Verified on this branch: 11 Helm tests and the 20 behavioural Python tests
pass.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-09-25 09:35:57 +05:00
Yan Bondarenko e087e38e8a fix(kubeovn): retry migration setup until target pod exists
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 6e90447091)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-09-25 09:35:56 +05:00
Yan Bondarenko 0a359e5f4d fix(kubeovn): retry VM migration setup after scheduling
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 55a2918fcb)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-09-25 09:35:56 +05:00
Andrei Kvapil 54fac75f80 feat(kubeovn): build the chart and image in-tree
kubeovn was the last package whose chart and image were produced by a
separate repository: packages/system/kubeovn pulled a tarball from the
latest cozystack/kubeovn-chart tag at update time, and that repository
built and pushed the image. The wrapper existed only to cache the
upstream chart; with the current caching that reason is gone, and the
split cost a second repository, a second release step, and a package
whose provenance a reader could not follow without leaving the tree.

Move the wrapper in, shaped like packages/system/cilium: update pulls
the upstream kube-ovn chart directly and applies patches/mtu.diff, and
image builds images/kubeovn and pins the digest into values.yaml. The
MTU patch already carried monorepo-relative paths, so it applies here
unchanged.

Also carries cozystack/kubeovn-chart#5, which never got a tag: pin
OVN_IPSEC_KEY_DIR under /var/lib. The kube-ovn default sits in
/etc/origin, which a Talos node cannot create, so enabling IPsec left
the node without ESP security associations.

Co-authored-by: Timofei Larkin <lllamnyp@gmail.com>
Co-authored-by: Kirill Ilin <stitch14@yandex.ru>
Co-authored-by: Aleksei Sviridkin <f@lex.la>
Assisted-By: Claude
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
(cherry picked from commit 7ebce2e942)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-09-25 09:35:55 +05:00
IvanHunters ee8923f351 fix(opensearch-operator): name the component reconciler a stall sits in
The cluster controller runs nine component reconcilers in sequence and none
of them logs unconditionally when it is entered: the TLS one's only line
above its work sits on the no-security early return, which the chart in this
repository never renders, and the rolling restart one opens at V(1), off at
the verbosity the operator ships with. So a call that stops returning leaves
nothing behind at all. The operator log ends on whatever ran before it, the
object is silently no longer reconciled, and from the outside that is
indistinguishable from an operator with nothing to do. Two e2e runs ended
exactly that way, the operator going quiet at the moment the chart rewrote
the CR and never coming back: https://github.com/cozystack/cozystack/issues/4332.

Each component is now wrapped so a call still in flight after a minute
reports its own name and how long it has been running, and keeps reporting on
that interval while it is stuck. A single line dated at the start of a stall
does not answer the question a reader has five minutes in, which is whether
the call is still there. Nothing is written while a component behaves, so a
healthy cluster costs no extra lines.

The finalizer path is left alone: every DeleteResources at this version
returns immediately, so a watchdog there could only spawn goroutines for
calls that cannot block.

A diagnostic rather than a fix: drop it once the stall itself is understood.

Assisted-by: LLM
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
(cherry picked from commit 6a34c9f037)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-09-24 17:11:35 +05:00
IvanHunters 4ef7efc39d fix(opensearch-operator): keep a single-replica cluster electable after bootstrap
The operator deletes the bootstrap pod as soon as initialization completes and
never looks at the voting configuration first. With one cluster_manager replica
there are exactly two eligible nodes, OpenSearch keeps the configuration at an
odd size of one, and the voter it keeps is the bootstrap node that formed the
cluster. Deleting that pod takes away the only vote there was, and the survivor
can never hold an election again, because changing the configuration itself
needs a quorum. The cluster is unusable about a minute after it installs, and a
node with no cluster-manager still answers the readiness probe, so nothing says
so until something restarts the pod.

Build the operator in-tree, the way kamaji and redis-operator already are, and
carry a patch that excludes the bootstrap node from the voting configuration and
waits for that to commit before deleting the pod. Reaching the cluster is a
precondition rather than a nicety: every failure keeps the pod and requeues,
because a bootstrap pod that outlives its purpose costs a pod, while a cluster
that cannot elect does not recover without a human.

Deleting a pod is a request rather than a wait, so clearing the exclusion
afterwards can find the node still in the cluster and fail. That path requeues
and is retried once the pod is really gone, which keeps a stale entry out of the
capped exclusion list; clearing stays at the API default wait_for_removal=true
so it cannot re-admit a node some other operation is still draining.

Upstream carries the same defect, tracked as
opensearch-project/opensearch-k8s-operator#1448.

Assisted-by: LLM
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
(cherry picked from commit b222cb6580)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-09-24 17:11:35 +05:00
Aleksei Sviridkin f80ea540a8 fix(reloader): add startupProbe to survive slow first start under load
Reloader binds its :9090 listener as the last statement of
startReloader, so /live and /metrics answer connection refused until
everything before it has finished. The blocking part of that prologue
is the package-level IsOpenshift = isOpenshift() in pkg/kube, which
issues a GET /apis/project.openshift.io against the API server on a
context carrying no deadline, before main() is even entered. That
latency belongs to the API server, and the container waits it out at a
100m CPU limit.

The chart renders no startupProbe, so the only grace period is the
liveness budget: initialDelaySeconds 10 + periodSeconds 10 *
failureThreshold 5, about 60 seconds. A first start that needs longer
is killed mid-prologue, and the restart does not resume it, it runs it
again from the beginning, so the loop sustains itself. The blast
radius reaches past reloader: the LINSTOR stack lists
cozystack.reloader in dependsOn, which fans out to every component of
that stack, so a reloader stuck in this loop blocks the whole install.

Render a values-driven startupProbe on /live so liveness only begins
evaluating once the listener is up. Budget = periodSeconds 5 times
failureThreshold 45, so about 225 seconds. timeoutSeconds matches the
5s the chart already gives liveness rather than the kubelet default of
1s, which a throttled process can exceed while holding the socket
open.

Both liveness knobs the chart already exposes could buy the same grace
with no patch to carry. Widening failureThreshold buys it permanently,
loosening hang detection for the life of the container.
initialDelaySeconds is start-up-only and would genuinely do, but it is
a fixed blind window on every start, whereas a startup probe returns
liveness to its tight budget the moment the listener binds.

The chart is vendored, so the template change is carried as
patches/deployment-startup-probe.diff and reapplied by `make update`,
which now drives the shared %-update rule with an exact chart version
pin instead of pulling whatever is latest. The patch is applied with
--forward because patch(1) defaults diverge by implementation over a
tree that already carries the change: GNU 2.7.6 refuses and exits 1,
Apple 2.0-12u11 takes its "Assume -R? [y]" default and strips the hunk
back out with exit 0, and GNU under --batch does the same. --forward
refuses in all three.

A helm unittest pins the probe, its budget, the no-op path the
template promises for an unset value, and the liveness numbers the
budget is sized against, so the documented arithmetic cannot drift
away from the chart without a red test. The same target asserts that
the vendored Chart.yaml still records the pinned version, so raising
the pin without re-running `make update` fails instead of leaving the
tree and the pin quietly disagreeing.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
(cherry picked from commit 7f67d02fb7)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-09-24 12:09:34 +05:00
myasnikovdaniil 89c44b4d83 [Backport release-1.6] fix(dashboard): let dashboard users read backup CRD schemas (#4307)
# Description
Backport of #4236 to `release-1.6`.
2026-09-23 17:58:42 +05:00
myasnikovdaniil de1f25998f [Backport release-1.6] fix(backups): give the barman-cloud sidecar its own resources (#4336)
# Description
Backport of #4220 to `release-1.6`.
2026-09-23 17:58:38 +05:00
myasnikovdaniil 8697eccd9f [Backport release-1.6] fix(linstor): reconnect only the stalled peer in the satellite plunger (#4319)
# Description
Backport of #4184 to `release-1.6`.
2026-09-23 17:58:34 +05:00
myasnikovdaniil 37ca9b0ac6 [Backport release-1.6] fix(linstor): wait for temporary probe devices (#4335)
# Description
Backport of #4100 to `release-1.6`.
2026-09-23 17:58:15 +05:00
myasnikovdaniil 4d710fccac [Backport release-1.6] fix(rabbitmq): right-size the default resources preset to s1.nano (#4393)
## What this PR does

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

The automated backport, #4372, pushed conflict markers in
`packages/apps/rabbitmq/README.md` and
`packages/system/rabbitmq-rd/cozyrds/rabbitmq.yaml` as its only commit,
so it would ship them if merged. Both are generated files, and the
conflict is the `tls` block that landed on main after 1.6 was cut.
Everything else applies unchanged, so two differences follow:

- the README parameter table and the cozyrd schema are regenerated from
the 1.6 values with cozyvalues-gen v1.6.0, so they carry the new default
and descriptions without `tls`;
- the 1.6 rabbitmq `Makefile` has no `test` target, so the helm-unittest
sweep would never enter the package and the new preset suite would not
run. The second commit adds the same two lines main already has.

Verified on this branch: the rabbitmq suite passes 4/4, `make -n test`
answers the sweep probe, and a second `make generate` produces no drift.

Change summary, unchanged from #3936: the default `resourcesPreset`
moves from `t1.nano` (128Mi) to `s1.nano` (250m CPU, 512Mi), because a
default-sized RabbitMQ 4.2 broker was OOMKilled on `t1.nano` and never
became Ready. The `resources` and `resourcesPreset` descriptions say the
preset fills every resource `resources` leaves unset.

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

### Screenshots

Not a UI change.

### Downstream repositories

Walked the trigger map against the diff: one app chart with a changed
default. The provider follow-up is
cozystack/terraform-provider-cozystack#34, labelled `target/1.7`.

- [ ] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [x]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up: cozystack/terraform-provider-cozystack#34
- [ ]
[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(rabbitmq): raise the default resources preset from t1.nano to s1.nano so a default-sized broker is not OOMKilled. Existing brokers that never set resourcesPreset move to s1.nano on upgrade and roll their pods.
```
2026-09-23 17:58:06 +05:00
myasnikovdaniil 5a5a127fff [Backport release-1.6] fix(kafka): make topics[].config optional (#4334)
# Description
Backport of #3935 to `release-1.6`.
2026-09-23 17:58:02 +05:00
myasnikovdaniil 391425f11b [Backport release-1.6] fix(kubernetes): pin KubeVirt CSI sidecars to SIG Storage releases (#4313)
# Description
Backport of #3934 to `release-1.6`.
2026-09-23 17:57:57 +05:00
Yan Bondarenko 0cfa93e58b fix(rabbitmq): right-size the default resources preset to s1.nano
A default-sized RabbitMQ 4.2 broker was OOMKilled on t1.nano (128Mi)
and never became Ready; its working set peaked at 125.8Mi. s1.nano keeps
the 250m CPU and gives 512Mi. The resources and resourcesPreset
descriptions now say the preset fills every resource that resources
leaves unset. The parameter table and the cozyrd schema are regenerated
from the 1.6 values, which carry no tls block.

(cherry picked from commit 12e64a99cd)
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
2026-09-23 01:15:39 +03:00
Yan Bondarenko 245ffd62f1 fix(backups): give the sidecar sizing its reason per caller
The Keycloak comment and the helper doc claimed the tenant LimitRange as the
reason for the resources, but cozy-keycloak has no LimitRange and neither
does a tenant that leaves resourceQuotas empty: there the sidecar had no
requests and no limit at all, and the change gives it a 1Gi ceiling where
there was none. The comments and both doc blocks now say what applies to
each caller. No rendered object changes.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 4dc6065ec9)
2026-09-18 18:45:00 +00:00
Yan Bondarenko 59e1352d85 fix(backups): give the barman-cloud sidecar its own resources
The barman-cloud plugin injects its sidecar without resource requests or
limits. Tenant namespaces ship a LimitRange that defaults containers to
128Mi, so the sidecar inherits that default and is OOMKilled mid-backup:
the ObjectStore stays healthy, the Cluster stays Ready, and only the
backup fails. A cgroup high-water mark of 254 MiB on a 38 MB database
shows the default cannot hold it.

The shared cozy-lib helper and the Go path that builds the platform's own
ObjectStore now request 100m/256Mi and cap memory at 1Gi. No CPU limit is
set, matching the entityOperator precedent in the kafka chart: a
throttled sidecar stalls WAL archiving instead of failing it.

The helper is renamed from checksumSidecarConfiguration to
sidecarConfiguration, since it no longer carries only the checksum pin.

Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 9214430bd8)
2026-09-18 18:45:00 +00:00
Yan Bondarenko c963b57836 fix(linstor): wait for temporary probe devices
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit cee9065589)
2026-09-18 18:26:24 +00:00
Yan Bondarenko 6e5277937e fix(kafka): make topics[].config optional
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 8ec76a3614)
2026-09-18 17:53:38 +00:00
Yan Bondarenko f2cbc35d33 fix(linstor): reconnect only the stalled peer in the satellite plunger
drbd_stall_act disconnects one peer with "drbdadm disconnect res:peer"
but then runs "drbdadm connect res", which walks every connection of
the resource. The peers that are still connected make drbdsetup fail
with "Device has a net-config (use disconnect first)" (exit code 10),
the helper only logs "WARN: action failed" and the stalled peer stays
disconnected.

Reconnect the same res:peer pair that was just disconnected.

Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 8c649df7de)
2026-09-18 09:38:42 +00:00
Yan Bondarenko 5066e33b27 fix(kubernetes): pin KubeVirt CSI sidecars to SIG Storage releases
Signed-off-by: Yan Bondarenko <202671653+yankawai@users.noreply.github.com>
(cherry picked from commit 296d3008d9)
2026-09-18 08:43:14 +00:00
Andrey Kolkov 75ef827b4c fix(dashboard): let dashboard users read backup CRD schemas
The dashboard backup build/edit forms build each form from the CRD's
OpenAPI schema, which useCRDSchema fetches directly from
apiextensions.k8s.io with the logged-in user's token — a cluster-scoped
get on the CRD by name. No role a tenant user carries granted
customresourcedefinitions, so every tenant user hit a 403 on the schema
lookup and the form never rendered, while kubectl kept working through
the existing backup CR grants.

The tenant personas are bound only by RoleBindings, which cannot
authorize a cluster-scoped request, so the grant belongs on
cozystack-dashboard-readonly: it is bound to system:authenticated by a
ClusterRoleBinding and already carries the dashboard's other
cluster-scoped reads. Add a get on the five backups.cozystack.io CRDs,
scoped by resourceNames to those schemas only.

Fixes: cozystack/cozystack#4053

Assisted-By: LLM
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
(cherry picked from commit 3a8a06b44f)
2026-09-17 14:29:34 +00:00
Aleksei Sviridkin 15a69e754f fix(cdi): update CDI to v1.66.1
Brings two upstream fixes CDI v1.64.0 users hit in the field:

- qemu-img 10.1.0-24.el9 restores HTTP imports to block volumes on
  4Kn devices (DRBD/LINSTOR), the regression that kept this repo
  from following v1.65.0. The earlier -21 build shipped in v1.66.0
  did not carry the fix, which is why this targets v1.66.1.
- import-controller no longer clears event-based bound-condition
  annotations on every pod sync, removing the resourceVersion storm
  on prime PVCs during WFFC imports that starved the scheduler with
  FailedScheduling retries. The fix is commit e547586e9, a one-line
  guard in updatePvcFromPod that rides inside a squash titled after
  its kubevirtci changes, so neither the release notes nor the pull
  request title mention it.

The operator manifest is refetched with make update. Two local
customizations survive as patches now: the startupProbe patch gains
the correct -p4 strip level (it never applied from the package
directory as written), and the control-plane tolerations that were
hand-edited into the manifest since v0.0.1 move into
patches/tolerations.diff so the next refetch cannot drop them.

Behavioral notes for this bump: CDI /metrics now requires a bearer
token (nothing in this repo scrapes it); scratch PVCs inherit the
target StorageClass instead of the cluster default; the PVC-rendering
webhook is always registered but only matches PVCs labeled
cdi.kubevirt.io/applyStorageProfile=true, which nothing here sets.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <3811295@gmail.com>
(cherry picked from commit 44b95e747d)
2026-09-07 22:51:35 +00:00
Andrey Kolkov cf9c77d36d feat(etcd-operator): bump to v0.5.5 and vendor EtcdDefragPolicy CRDs
v0.5.5 ships the EtcdDefrag and EtcdDefragPolicy API types (a controller
plus a cron that stamps scheduled defrag runs). Vendor both CRDs into the
etcd-operator-crds package and grant the manager ClusterRole the verbs the
new controllers need: defragpolicies read/patch, defrags full CRUD, the two
new /status subresources, and cluster-scoped event emission.

Backport of #3968 to release-1.6. The automatic cherry-pick could not merge
the etcd-operator-crds Makefile and left the conflict markers in the file;
resolved by taking the five-CRD list the two new CRDs require. The comment
that came with it on main describes an update target that counts annotations
and swaps templates/ atomically — this branch has neither, so it is left out
rather than carried in as a false description. Everything else applied
unchanged.

Signed-off-by: Andrey Kolkov <andrey.kolkov@aenix.io>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
2026-09-08 00:12:54 +02:00
cozystack-ci[bot] d3a2037d1f Prepare release v1.6.3 (promoted from v1.6.3-rc.2)
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-09-04 06:05:07 +00:00
cozystack-ci[bot] 3745279867 Prepare release v1.6.3-rc.2
Signed-off-by: cozystack-ci[bot] <274107086+cozystack-ci[bot]@users.noreply.github.com>
2026-09-03 14:46:55 +00:00
Alexey Artamonov 768f29a235 feat(clickhouse): add configurable version parameter
Add a `version` value (v25.8, v25.3, v24.9; default v24.9) to the
ClickHouse chart, backed by files/versions.yaml and resolved by
templates/_versions.tpl for both the ClickHouse server and Keeper
images, so the Cozystack API returns the engine version (spec.version)
like the other managed-DB charts. Default v24.9 -> 24.9.2.42 keeps
existing installations byte-for-byte identical.

The maintainer-run hack/update-versions.sh generator intersects the
server/keeper Docker Hub tags byte-collated (LC_ALL=C) so comm keeps
tags across the X.9 -> X.10 boundary; freezes the default major to the
tag it already ships (read from versions.yaml, so the freeze follows the
default); errors on a dropped default or an unresolvable major; writes
atomically; and runs on stock macOS bash 3.2 / BSD. Covered by
hack/clickhouse-update-versions_test.bats (10 cases) and the
tests/version_test.yaml helm-unittest suite.

Refs: #1246
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
(cherry picked from commit 3c78c0be56)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Assisted-By: LLM
2026-09-03 18:45:14 +05:00
myasnikovdaniil b158962660 [Backport release-1.6] fix(postgres): let in-place restore re-bootstrap instead of wedging (#3988)
# Description
Backport of #3959 to `release-1.6`.
2026-09-03 12:27:11 +05:00
myasnikovdaniil c4440f250c feat(workloadmonitor): bucket metrics endpoint override (#3443) [backport release-1.6] (#3558)
## What this PR does

Hand-backport of #3443 to `release-1.6`. The change merged to `main` on
2026-07-24, after v1.6.0 was cut, so it never reached any 1.6 patch and
is currently slated to wait for 1.7. This lands it in 1.6.2.

The cozystack-controller meters S3 bucket sizes for billing by querying
SeaweedFS metrics from a VictoriaMetrics vmselect it discovers via the
`namespace.cozystack.io/monitoring` label on the tenant namespace. That
discovery assumes the monitoring stack scraping SeaweedFS runs in the
same cluster. Some deployments host SeaweedFS (API and metrics both) in
a separate cluster, where discovery can never produce a reachable
endpoint. This adds a single controller flag,
`--seaweedfs-metrics-endpoint`, exposed as the chart value
`cozystackController.seaweedfsMetricsEndpoint`, to point bucket-size
metrics at a remote Prometheus-compatible query API. Empty keeps the
existing label-based discovery, so behaviour is unchanged by default.

### Backport adaptations

Clean cherry-pick of `95e4faf68`; no adaptations required. `go build
./cmd/...` and the full `internal/controller` test suite pass.

### Screenshots

Not applicable — no UI change.

### Downstream repositories

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

### Release note

```release-note
feat(workloadmonitor): add --seaweedfs-metrics-endpoint to fetch S3 bucket size metrics from a remote Prometheus-compatible endpoint, for deployments where SeaweedFS and its monitoring stack run in a separate cluster
```
2026-09-03 10:48:36 +05:00
Andrey Kolkov 22b1e074a5 fix(postgres): let in-place restore re-bootstrap instead of wedging
An in-place RestoreJob (targetApplicationRef omitted) re-bootstraps the
Postgres app under its own name. On stock v1.6.2 it never comes back up,
for two independent reasons in the same restore patch - both surface only
in place, because a to-copy restore targets a different app.

1. Archive-vs-recovery serverName collision. The driver set the restored
   cluster's WAL-archive serverName equal to the recovery source
   (bootstrap.serverName = bootstrap.oldName = sourceServerName) while the
   chart pinned the archiver serverName to the release name. In place those
   coincide, so the cluster archived onto the source's own WAL prefix and
   barman-cloud-check-wal-archive refused to start ("Expected empty
   archive"). Fixed by giving the restored cluster a fresh
   bootstrap.newServerName, keyed by the RestoreJob UID (unique per
   restore, stable across reconciles); the chart archives there while
   externalClusters still recovers from bootstrap.serverName. This is what
   the manual CNPG strategies hit (serverName defaults to the cluster
   name); the cozy-default flow dodged it (serverName is <ns>-<app>).

2. useSystemBucket guard. The restore populates explicit S3 coordinates
   (destinationPath / s3CredentialsSecret / endpointCA) but left
   backup.useSystemBucket=true, so the chart's "bootstrap.enabled is
   incompatible with useSystemBucket" guard failed the HelmRelease upgrade
   and the cluster never re-rendered. This is what the cozy-default
   (system-bucket) flow hits on an in-place restore. Fixed by clearing
   useSystemBucket in the restore patch, since the app is now on the
   explicit-creds path. The driver's app view (postgresapp.Backup) gains
   the field, without omitempty so a false survives the merge patch.

Both are exercised only by an in-place restore; the postgres backup e2e
drove only to-copy, so neither surfaced in CI. A step 50 in-place restore
now guards reason 1 (manual-strategy flow); reason 2 is covered by a Go
unit assertion (a system-bucket in-place e2e needs the platform bucket in
CI and is left as a follow-up).

Signed-off-by: Andrey Kolkov <androndo@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 5bcdb8cfb8)
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Assisted-By: LLM
2026-09-02 19:09:38 +05:00
Myasnikov Daniil f81e06013d chore(keycloak): bump KMS proxy to 0.2.2
Pin the released image by digest so package rendering is reproducible.

Assisted-By: GPT-5 <noreply@openai.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 6d9444056d)
2026-08-31 07:10:50 +00:00
Kirill Ilin 47736edabc fix(keycloak): pin the Vault leg to the configured CA and roll on rotation
SSL_CERT_FILE alone does not narrow trust. crypto/x509 replaces only its file
list and then scans SSL_CERT_DIR unconditionally, and the pinned proxy image
ships /etc/ssl/certs/ca-certificates.crt, so the connection guarding the KEK
trusted the private CA plus every public root — a mis-issued certificate for the
Vault hostname was still accepted. Set SSL_CERT_DIR to the mount as well, which
collapses the pool to the CA the operator configured.

An unvalidated caBundle failed open on top of that: a non-PEM value is dropped
silently by AppendCertsFromPEM, leaving the proxy on the image's roots with no
error at all. Reject it at render time, the way backend and auth already are.

Rotating an inline caBundle had no effect either. The pod template did not
change, so no new pods, and crypto/x509 memoizes the pool per process — the
upgrade reported success while the old CA stayed in use until some later
restart. Derive a checksum/vault-ca annotation from the bundle so the rollout
happens with the change.

Also add vault.caSecretKey: the projected key was hardcoded to ca.crt, and a
bundle stored under another name (a cert-manager Certificate from an ACME issuer
emits no ca.crt at all) wedged the pod at mount time with no way to correct it
from values.

Drop the claim that the database leg verifies against its own CA pool: the chart
never sets KKP_BACKEND_CA_FILE, so that leg is plaintext today, as the note 30
lines above already says. The conclusion holds — it never consults the system
trust store — but for the other reason.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 517e33f67b)
2026-08-28 07:29:22 +00:00
Kirill Ilin 04f01d3f6a fix(keycloak): keep the Vault CA options inert on the static KMS backend
The volume and mount that consume the Vault CA sit at pod level, outside the
vault-transit env block, while $vaultCASecret was seeded from caSecretName
regardless of the backend. With kms.backend=static and caSecretName set, the
Deployment mounted a Secret the chart never renders, so the proxy — the single
choke point for all Keycloak DB traffic — would sit in ContainerCreating.

Gate both CA keys, and the mutual-exclusion check between them, on
vault-transit, so the whole vault.* subtree behaves the same way under static:
ignored. Project only ca.crt from a pre-seeded Secret, which keeps a
cert-manager tls.key out of the container and turns a bundle stored under
another key into a mount failure rather than an opaque TLS error later.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 98ef5413f4)
2026-08-28 07:29:22 +00:00
Kirill Ilin 2afcaf365a feat(keycloak): let the KMS proxy trust a private Vault CA
The proxy could only reach a Vault whose certificate chains to a publicly
trusted root, so a Vault fronted by an internal load balancer with a
self-signed certificate was unreachable over HTTPS.

Allow the CA to be supplied inline (caBundle, the chart renders the Secret) or
as a pre-seeded Secret (caSecretName), mounted and exposed as SSL_CERT_FILE.
That redirects only the system trust store, which nothing but the Vault client
consults — the database leg verifies against its own CA pool.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 3531553176)
2026-08-28 07:29:22 +00:00
Andrei Kvapil 2a73909776 fix(kubeovn-webhook): restrict the webhook port to the API server
Backport of #3955. The automated cherry-pick carried only the first
commit of that PR and committed the values.yaml conflict, so this
resolution brings the branch to what actually merged to main: the port
comes from a single helper feeding the container port, the Service
targetPort and the policy, the rationale sits in template comments
rather than being rendered into every manifest, and the dead egress
default-deny toggle is gone.

Two deliberate differences from main. The image stays on the digest this
release line already ships rather than main's older one, and the
--client-ca-file argument is left out along with the values key it
reads: both belong to #2698, which was never backported here, and the
image on this line does not take the flag.

Assisted-By: Claude
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
2026-08-27 18:07:37 +02:00
Andrei Kvapil 5c41f8a4c3 BACKPORT-CONFLICT 2026-08-27 15:53:12 +00:00
Andrei Kvapil 79c4022fb1 fix(console): address the review findings on the Admin portal rework
Four of the five findings share one root cause: a node in the tenant
tree can attach to its nearest *visible* ancestor when its real parent
is inaccessible, and per-row actions then derived their target from
that bridged ancestor.

The Edit action on a bridged tenant row pointed at a Tenant CR that
does not exist. The CR lives in the real parent's namespace, so the
target now comes from realParentNamespace — and Edit is offered only
when that namespace is readable, because otherwise there is no CR the
user could open and the button could only ever dead-end. The test that
asserted two Edit buttons had frozen the broken target as expected
behaviour; it now names the rows it expects, and the Edit button gained
a title so that assertion means something.

An inherited module chip is rendered only when the providing tenant is
NOT visible, yet it was a live button: clicking it denied the instance
GET and switched the active tenant to a namespace outside the visible
set, which the selector then bounced to an arbitrary fallback. It is
now an inert badge that states where the module comes from.

InfoRedirect's missing-definition branch hardcoded /console, throwing an
admin out of the portal its own docstring promises to preserve.

The sidebar's alsoMatch used a bare startsWith, so /admin/apps would
light up for /admin/apps-v2. It now matches whole path segments.

And SecretsTab let a rejected clipboard write escape as an unhandled
rejection, leaving the button silent — a denied permission or an
insecure context was indistinguishable from a no-op. It now reports the
failure.

Declined: CodeRabbit asked to split `import { useK8sList, type K8sResource }`
into a separate `import type`. The inline modifier is valid under
verbatimModuleSyntax and is what 26 other imports in this console use,
so the change would make the file the odd one out.

Reported-by: Ivan Okhotnikov <ivan.okhotnikov@aenix.io>
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
(cherry picked from commit 724354ffe1)
2026-08-24 21:38:01 +00:00
Andrei Kvapil 3e5e6d05b4 feat(dashboard): land on the Console instead of the Marketplace
Opening the dashboard without a path sent the user to the catalog, and
the header gave Marketplace the primary emphasis. The Console is the
better entry point: it shows what the tenant already runs, which is
what someone opening the dashboard almost always came for. The
Marketplace stays one click away for when the intent is to add
something new.

The landing path becomes a named constant beside the portal helper, so
the redirect and the tab emphasis cannot drift apart, and the library's
own default tab set is reordered to match rather than contradict its
only consumer.

Assisted-By: Claude
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
(cherry picked from commit bfd4ea0643)
2026-08-24 21:38:01 +00:00
Andrei Kvapil aea290432b fix(dashboard): let a masked secret be copied and confirm the copy
Copying a secret key required revealing it on screen first, and the
button gave no sign that anything reached the clipboard. The value the
list already carries is enough to copy, so the button works while the
key stays masked, and it briefly turns into a check mark to confirm.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
(cherry picked from commit cfd5444f16)
2026-08-24 21:38:01 +00:00