## What this PR does
`packages/system/etcd-operator/templates/metrics.yaml` rendered a
`VMServiceScrape` (`operator.victoriametrics.com/v1beta1`)
unconditionally, so the `cozy-etcd-operator/etcd-operator` HelmRelease
fails to install on any cluster that does not have the VictoriaMetrics
operator CRDs, with `no matches for kind "VMServiceScrape" in version
"operator.victoriametrics.com/v1beta1"`. That made the VictoriaMetrics
operator a hard dependency of etcd-operator, which it should not be.
This wraps only the `VMServiceScrape` document in a
`.Capabilities.APIVersions.Has "operator.victoriametrics.com/v1beta1"`
gate, following the precedent already established in
`packages/system/linstor/templates/podscrape.yaml`. The
`etcd-operator-metrics` Service keeps rendering unconditionally, so any
scraper — a `VMServiceScrape` when the CRD is present, or something else
entirely — can still target the `metrics` port.
Note: this is a Cozystack-packaging-only issue. The upstream
etcd-operator repo's own chart is unaffected — it already gates its
scrape object.
Added `packages/system/etcd-operator/tests/metrics_test.yaml` (`helm
unittest`) pinning the new behavior: the Service always renders, and the
`VMServiceScrape` renders only when the capability is injected.
Kept this minimal — a pure capabilities gate with no new values key,
matching linstor's style, rather than adding a values toggle.
Follow-up (out of scope for this PR):
`packages/extra/etcd/templates/podscrape.yaml` (a `VMPodScrape`) is
unconditional the same way and would hit the same install failure on a
cluster without the VictoriaMetrics operator.
`packages/system/monitoring-agents` also ships several unconditional
`VMServiceScrape`/`VMPodScrape` objects, though that package may already
assume the VictoriaMetrics operator is present as part of the monitoring
stack it belongs to.
### Screenshots
Not applicable — no UI change.
### Downstream repositories
- [x] No downstream repository is affected by this change
### Release note
```release-note
fix(etcd-operator): stop requiring the VictoriaMetrics operator to install etcd-operator; the VMServiceScrape now only renders when the operator's CRD is present
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Metrics collection now works without the VictoriaMetrics operator API,
while scrape configuration is rendered when that API is available.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Controller-only release: EtcdMember Pods that reach a terminal phase
are replaced instead of being left behind, and EtcdCluster status is no
longer rewritten while etcd itself is unreachable. No CRD, RBAC or
values changes; re-vendoring the CRDs produces an empty diff.
Assisted-By: LLM
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
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.
Signed-off-by: Andrey Kolkov <andrey.kolkov@aenix.io>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The etcd-operator HelmRelease rendered a VMServiceScrape unconditionally, so it failed to install with "no matches for kind VMServiceScrape" on any cluster without the VictoriaMetrics operator CRDs. Wrap it in the same Capabilities.APIVersions gate linstor's podscrape.yaml uses, leaving the metrics Service unconditional.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
The manager image tag derives from .Chart.AppVersion, so bumping appVersion
to v0.5.4 without updating the two image literals in the deployment unittest
broke the suite (helm-unittest gates the PR via `make unit-tests`). Update
both asserts (manager container image and the agent OPERATOR_IMAGE env) to
ghcr.io/cozystack/etcd-operator:v0.5.4. Suite is green again (18/18).
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrey Kolkov <androndo@gmail.com>
v0.5.3 carries the S3 request-checksum fix (cozystack/etcd-operator#342): the
snapshot agent sets RequestChecksumCalculation=WhenRequired on BOTH the S3 client
and the transfer manager, so multipart snapshot uploads (>5 MiB — every real etcd
snapshot) no longer carry the CRC32 STREAMING-UNSIGNED-PAYLOAD-TRAILER that Ceph
RGW rejects with 400 InvalidArgument. Also pulls in #340 (observed EtcdMember
versions) and #341 (--watch-namespace).
- system/etcd-operator: appVersion v0.5.2 -> v0.5.3 (image tag follows AppVersion),
bump ETCD_OPERATOR_REF, update deployment unittest expectations.
- system/etcd-operator-crds: re-vendor CRDs from v0.5.3. etcdmembers gains the
additive #340 status.version field + "Running" printer column and picks up the
peerAutoTLS spec field the vendored copy was already missing (all additive,
backward-compatible; etcdclusters/etcdsnapshots unchanged). Fix the stale
`make update`: upstream has no config/crd kustomization — CRDs live in
charts/etcd-operator/crd-bases — so vendor those directly and stamp
helm.sh/resource-policy: keep.
Verified end-to-end on a Ceph RGW backend: the v0.5.2 (client-only) agent fails a
multipart snapshot upload with the 400 above; v0.5.3 uploads an 11 MiB multipart
snapshot successfully.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrey Kolkov <andrey.kolkov@aenix.io>
- backupstrategy-controller: trim() the decoded S3 endpoint before scheme
stripping so a trailing newline in the Secret can't yield a malformed URL
- etcd-operator: give the pre-upgrade selector-fix hook container resource
requests/limits (matches postgres-operator webhook-ready), +unittest
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Addresses review on #3265:
- pre-upgrade-selector-fix hook: add runAsUser: 65532. clastix/kubectl's
image user is the non-numeric name `nonroot`, which the kubelet cannot
verify against runAsNonRoot: true — so the Pod fails admission and the
hook never runs, silently blocking the very 1.5->1.6 upgrade it exists to
unblock. Matches postgres-operator's webhook-ready hook (same image).
- Digest-pin the kubectl image (the comment already claimed digest-pinning
but shipped a floating v1.32 tag). Reuse the digest postgres-operator
already vendors, add the renovate annotation, and template repo:tag@digest.
- Tests (both charts have CI helm-unittest suites, none previously covered
these):
- etcd-operator/tests/selector-fix-hook_test.yaml: hook wiring, namespaced
least-privilege RBAC, numeric-non-root securityContext (guards the
runAsUser regression above), digest-pinned image.
- etcd-operator/tests/deployment_test.yaml: assert the 256Mi cold-start
memory floor so it can't silently drop back to an OOMKilling value.
- extra/etcd/tests/etcd-cluster_test.yaml: assert the transitional
etcd-headless Service (headless, publishNotReadyAddresses, member
selector, client/peer ports).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>