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>
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.
```
# 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.
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)
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)
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>
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>
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>
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>
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>
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>
## 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.
```
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>
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)
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)
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)
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)
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)
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>
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
## 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
```
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
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)
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)
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)
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>
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)
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)
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)