Commit Graph
5128 Commits
Author SHA1 Message Date
Aleksei Sviridkin c8ed1c652c chore(ci): adopt CNCF/k8s label conventions
Add .github/labels.yml as the canonical label set, synced into the
repository by .github/workflows/labels.yaml using EndBug/label-sync.

Conventions follow the Kubernetes scheme:
https://github.com/kubernetes/test-infra/blob/master/label_sync/labels.md

Six namespaced groups: kind/, priority/, triage/, lifecycle/, area/,
do-not-merge/. Cozystack-specific labels preserved (epic, community,
security/*, size:*).

Migration via aliases keeps references on existing issues and PRs:
- bug           -> kind/bug
- enhancement   -> kind/feature
- documentation -> kind/documentation
- question      -> kind/support
- frozen        -> lifecycle/frozen
- stale         -> lifecycle/stale
- do-not-merge  -> do-not-merge/work-in-progress

delete-other-labels is false on the initial rollout; redundant labels
("do not merge", duplicate, invalid, wontfix) stay until a follow-up
PR removes them after stabilisation.

The labels workflow has a validate job (python3 schema check) that
runs on PR. Sync runs only on push to main, weekly cron, and manual
dispatch. Schema invariants:
- description <= 100 chars (GitHub REST API limit)
- color is 6-char hex without leading #
- unique top-level names
- aliases do not collide with top-level names

PR auto-labeling (.github/workflows/pr-labeler.yaml):
- Parses PR title as Conventional Commits header (type, scope, !).
- type -> kind/* (feat -> kind/feature, fix -> kind/bug, docs ->
  kind/documentation, chore/refactor -> kind/cleanup; style, perf,
  test, build, ci, revert -> no kind label).
- scope -> area/* via embedded mapping; composite scopes split on
  comma. Bracket-style fallback ([scope] description) maps area/*
  but cannot infer kind/*.
- '[Backport release-1.x]' prefix is stripped; area/release and
  backport labels are added.
- '!' after type or 'BREAKING CHANGE:' footer in body adds
  kind/breaking-change.
- Unmapped scope or non-conventional title adds area/uncategorized
  to flag for human review.
- Additive only — never removes existing labels.

Hardcoded label references updated:
- .github/ISSUE_TEMPLATE/bug_report.md (bug -> kind/bug)
- .github/workflows/tags.yaml (documentation -> kind/documentation)

AGENTS.md gains an Activation entry pointing agents to labels.yml
as the source of truth and to contributing.md for the title
auto-labeling table.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-27 03:15:09 +03:00
Aleksei Sviridkin 10b9cdd481 fix(security): drop USER 65532 from cozystack-api and lineage-controller-webhook
The previous commit (6498d37b) added `USER 65532:65532` to seven
first-party scratch images. Two of them — cozystack-api and
lineage-controller-webhook — mount their TLS serving certs as a
secret with `defaultMode: 0400` (root-only). With USER 65532, the
process can no longer read `tls.crt` / `tls.key` and the webhook
pod fails to start, manifesting downstream as
`failed calling webhook "lineage.cozystack.io": dial tcp <ServiceIP>:443: connect: operation not permitted`
during install of the tenant-root HelmRelease in e2e.

Reverts the USER directive on those two images. Properly switching them
to non-root requires either flipping the secret mount to
`defaultMode: 0440` plus `securityContext.fsGroup: 65532` on the
pod, or relaxing to 0444 — both choices touch the runtime chart and
are out of scope for a Go-deps security PR. Tracked as a follow-up.

The remaining five hardened images (backup-controller,
backupstrategy-controller, token-proxy, flux-plunger, kubeovn-plunger)
do not mount root-only secrets and continue to run as 65532.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 04:41:27 +03:00
Aleksei Sviridkin 6498d37be7 fix(security): run first-party scratch images as non-root UID 65532
CodeRabbit (PR review on #2494) flagged that the first-party scratch
images leave the container process running as root because no USER
directive is set. Adds the standard distroless nonroot UID/GID
65532:65532 just before ENTRYPOINT in seven first-party Dockerfiles.

The chosen UID matches gcr.io/distroless/static:nonroot and the
existing convention in the kubevirt-csi-driver and kamaji images.
Statically-linked Go binaries copied with default permissions remain
world-readable, so they execute fine under the non-root identity
without an extra chown step in the builder stage.

Touched:
- packages/system/backup-controller/images/backup-controller/Dockerfile
- packages/system/backupstrategy-controller/images/backupstrategy-controller/Dockerfile
- packages/system/cozystack-api/images/cozystack-api/Dockerfile
- packages/system/dashboard/images/token-proxy/Dockerfile
- packages/system/flux-plunger/images/flux-plunger/Dockerfile
- packages/system/kubeovn-plunger/images/kubeovn-plunger/Dockerfile
- packages/system/lineage-controller-webhook/images/lineage-controller-webhook/Dockerfile

Vendored Dockerfiles (kubevirt-cloud-provider, redis-operator,
keycloak-operator, linstor-csi, multus-cni, objectstorage,
s3manager, kamaji, cluster-autoscaler) are intentionally left
untouched — their runtime user choice is upstream's call.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 03:45:14 +03:00
Aleksei Sviridkin 44e5ae508b fix(security): align OpenTelemetry exporter modules with otel core
CodeRabbit (PR review on #2494) flagged that go.opentelemetry.io/otel
core / sdk / metric / trace are at v1.43.0 in the root module while
the otlptrace and otlptracegrpc exporters are still pinned at v1.34.0.
The exporter line declares a hard dependency on a matching SDK minor,
so mixing v1.34.x exporters with v1.43.x core would break version
resolution if the exporter code path were exercised.

Bumps to latest stable across the otel surface:
- go.opentelemetry.io/otel/exporters/otlp/otlptrace 1.34.0 -> 1.43.0
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
  1.34.0 -> 1.43.0
- go.opentelemetry.io/proto/otlp 1.5.0 -> 1.10.0
- go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc
  0.61.0 -> 0.68.0
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
  0.61.0 -> 0.68.0

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 03:44:07 +03:00
Aleksei Sviridkin 7206a6780d ci: retry CI
Empty commit to retrigger Build that lost the OCI registry tag race
on the previous attempt.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 02:46:30 +03:00
Aleksei Sviridkin 3fea7cd487 fix(security): bump first-party Dockerfile builders to golang:1.26
The root go.mod now declares go 1.26.2 (raised in the first commit
of this PR). Every Dockerfile that copies the root go.mod and builds
a cozystack-owned binary has to use a matching base image, otherwise
the in-container go toolchain has to download go 1.26 on the fly
(via GOTOOLCHAIN=auto) at every build, which slows builds and breaks
in network-restricted CI sandboxes.

Bumps:
- packages/core/installer/images/cozystack-operator
- packages/system/backup-controller/images/backup-controller
- packages/system/backupstrategy-controller/images/backupstrategy-controller
- packages/system/cozystack-api/images/cozystack-api
- packages/system/cozystack-controller/images/cozystack-controller
- packages/system/flux-plunger/images/flux-plunger
- packages/system/kubeovn-plunger/images/kubeovn-plunger
- packages/system/lineage-controller-webhook/images/lineage-controller-webhook

All eight images go from golang:1.25-alpine to golang:1.26-alpine.
Also normalizes the cozystack-operator Dockerfile FROM stage keyword
from lowercase 'as' to uppercase 'AS' while touching it.

Vendored Dockerfiles (kubevirt-cloud-provider, redis-operator,
keycloak-operator, linstor-csi, multus-cni, objectstorage,
s3manager, kamaji) are intentionally untouched: they pull upstream
sources at build time and pin their go base image to whatever the
upstream commit was tested against.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 01:53:19 +03:00
Aleksei Sviridkin 9e0e093c30 fix(security): bump token-proxy deps to latest
The token-proxy is a first-party Go binary (not vendored) used by
the cozystack dashboard for JWT-validated reverse-proxy access to
tenant-scoped API endpoints.

Bumps:
- github.com/lestrrat-go/jwx/v3 3.0.13 -> 3.1.0
- github.com/lestrrat-go/httprc/v3 3.0.2 -> 3.0.5
- golang.org/x/crypto 0.46.0 -> 0.50.0
- golang.org/x/sys 0.39.0 -> 0.43.0
- go directive 1.24.0 -> 1.26.2
- builder image golang:1.24-alpine -> golang:1.26-alpine

The jwx 3.0 -> 3.1 line restructured an internal package
(internal/jwxio); only library internals are affected and main.go
needs no source changes. Also normalizes the Dockerfile FROM stage
keyword to uppercase AS while touching it.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 01:50:23 +03:00
Aleksei Sviridkin dd486fa95f fix(security): bump api/apps/v1alpha1 deps to latest
This module exposes the apps/v1alpha1 Go types to external consumers
and was missed in the initial sweep. Bumps it in line with the rest
of the security PR.

Bumps:
- k8s.io/apimachinery 0.35.2 -> 0.36.0
- golang.org/x/net 0.47.0 -> 0.53.0
- golang.org/x/text 0.31.0 -> 0.36.0
- go directive 1.25.0 -> 1.26.2

All bumps are transitive (the module itself only declares
k8s.io/apimachinery directly). No source changes required.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 01:50:14 +03:00
Aleksei Sviridkin 235d194e4a fix(security): bump kubeovn-webhook to latest deps
Bumps all CVE-flagged dependencies in kubeovn-webhook to their latest
stable versions.

CVE-flagged bumps:
- golang.org/x/net -> 0.53.0 (GHSA-vvpx-j8f3-3w6h high,
  GHSA-4374-p667-p6c8 high, GHSA-2wrh-6pvc-2jm9 medium,
  GHSA-qppj-fm5r-hxr3 medium, GHSA-4v7x-pqxf-cx7m medium,
  GHSA-xrjj-mj9h-534m medium, GHSA-qxp5-gwg8-xv66 medium,
  GHSA-vvgc-356p-c3xw medium)
- golang.org/x/oauth2 -> 0.36.0 (GHSA-6v2p-p543-phr9, high)
- google.golang.org/protobuf -> 1.36.11 (GHSA-8r3f-844c-mc37, medium)

Cascading bumps required to consume the latest x/net and x/oauth2
(which require Go 1.25+):
- go directive 1.23 -> 1.26.2
- builder image golang:1.23 -> golang:1.26

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 01:46:14 +03:00
Aleksei Sviridkin 0fa1ca5f03 fix(security): bump kubevirt-csi-driver to latest deps
Bumps all CVE-flagged dependencies in the kubevirt-csi-driver wrapper
to their latest stable versions and adapts the local main.go to the
new upstream service.NewKubevirtCSIDriver builder API.

CVE-flagged bumps:
- google.golang.org/grpc 1.65.0 -> 1.80.0 (GHSA-p77j-4mvh-x3m3, critical)
- github.com/opencontainers/runc -> 1.4.2 (GHSA-cgrx-mc8f-2prm,
  GHSA-qw9x-cqr3-wc7r, GHSA-9493-h29p-rfm2 high, GHSA-jfvp-7x6p-h2pv
  medium)
- golang.org/x/oauth2 -> 0.36.0 (GHSA-6v2p-p543-phr9, high)
- golang.org/x/net -> 0.53.0 (GHSA-vvgc-356p-c3xw, GHSA-qxp5-gwg8-xv66
  medium)

Cascading bumps required to consume runc 1.4.2 (which removed
libcontainer/userns) and the latest x/net (which requires Go 1.25+):
- k8s.io/* replace block 0.31.4 -> 0.36.0
- kubevirt.io/csi-driver upstream pin -> 20260424143118-bee6c348c004
- go directive 1.22.0 -> 1.26.2
- builder image golang:1.22.5 -> golang:1.26

The upstream csi-driver split NewKubevirtCSIDriver into a builder
chain (WithIdentityService / WithControllerService / WithNodeService);
main.go is rewritten to call the new entry points and gate them on
the runControllerService and runNodeService flags as before.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 01:46:14 +03:00
Aleksei Sviridkin 40558f1ac7 fix(security): bump root module Go deps to latest
Bumps all CVE-flagged transitive dependencies in the root go.mod to
their latest stable versions. Also raises the go directive to 1.26.2
to match the toolchain required by upgraded golang.org/x/* and
opentelemetry packages.

CVE-flagged bumps:
- google.golang.org/grpc 1.73.0 -> 1.80.0 (GHSA-p77j-4mvh-x3m3, critical)
- go.opentelemetry.io/otel 1.37.0 -> 1.43.0 (GHSA-mh2q-q3fh-2475 high,
  GHSA-9h8m-3fm2-qjrq high, GHSA-hfvc-g4fc-pqhx high)
- go.opentelemetry.io/otel/sdk 1.37.0 -> 1.43.0 (same advisories)
- golang.org/x/crypto 0.42.0 -> 0.50.0 (GHSA-f6x5-jh6r-wrfv,
  GHSA-j5w8-q4qc-rx2x medium)
- github.com/moby/spdystream 0.5.0 -> 0.5.1 (GHSA-pc3f-x583-g7j2, high)

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 01:45:51 +03:00
Aleksei Sviridkin ea0b4bcf37 ci: retry CI
Empty commit to retrigger Build job that failed on Docker Hub anonymous
pull rate limit (429 Too Many Requests) for golang:1.26.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-26 01:24:25 +03:00
IvanHunters 52edffbb9a fix(kamaji): increase memory limits and add startup probe (#2421)
## Summary

- Increase kamaji controller memory limit from 500Mi to 512Mi
- Increase kamaji controller memory request from 100Mi to 256Mi  
- Add startup probe with 60-second timeout (12 attempts × 5s periods)
- Increase readiness/liveness probe initialDelaySeconds from 5s/15s to
30s

## Problem

The kamaji controller was experiencing frequent CrashLoopBackOff due to
OOMKilled errors. Analysis showed:

- Container was being killed with exit code 137 (OOMKilled) after ~20-25
seconds of runtime
- Memory limit of 500Mi was insufficient for controller initialization
- Readiness probe was failing because it started too early (5s
initialDelay), before the controller finished leader election (~17s)

## Solution

**Memory increase:**
- Limit: 500Mi → 512Mi (based on production testing)
- Request: 100Mi → 256Mi (ensures adequate reservation)

**Startup probe:**
- Added to give controller up to 60 seconds to initialize without being
killed by liveness probe
- 12 attempts × 5s period = 60s maximum startup time

**Probe delays:**
- ReadinessProbe: 5s → 30s initialDelay (controller needs ~17s to
acquire leader lease)
- LivenessProbe: 15s → 30s initialDelay (aligned with readiness)

## Testing

Verified in production cluster:
- Controller runs stable with 0 restarts
- No more OOMKilled events
- Successfully creates kubeconfig secrets for tenant clusters

## Related Issues

Fixes tenant cluster components stuck in ContainerCreating due to
missing kubeconfig secrets (caused by crashing kamaji controller).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Introduced automated health checks using HTTP-based probes to monitor
service status during startup, continuous operation, and readiness to
handle traffic.
* Adjusted container memory resource allocation for enhanced stability
and performance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-24 23:11:53 +03:00
Aleksei Sviridkin 500816b71b refactor(ingress): move CiliumLoadBalancerIPPool to tenant chart
The pool is now rendered from packages/apps/tenant/templates/cilium-lb-pool.yaml instead of packages/extra/ingress/templates/cilium-lb-pool.yaml. Cilium LB IPAM forbids overlapping CIDRs across pools regardless of serviceSelector, so both the ingress-loadBalancer path and the upcoming per-tenant Gateway in #2470 cannot each own their own pool on the same publishing.externalIPs range. The tenant chart is the natural per-tenant owner — it already creates the Namespace, the cozystack-values Secret, and the HelmReleases for both ingress and gateway.

The new pool uses a namespace-only serviceSelector (io.kubernetes.service.namespace: <ns>), which matches any LoadBalancer Service in the tenant namespace. The metadata.name changed from <trim>-ingress to <trim>-exposure to reflect that the pool is not ingress-specific.

Only the ingress-loadBalancer signal is wired in this commit (_cluster.expose-mode=loadBalancer plus .Values.ingress=true on the publishing tenant). The gateway branch is added in #2470 on top of this commit — it rebases, drops its own packages/extra/gateway/templates/cilium-lb-pool.yaml, and adds an OR branch for .Values.gateway in the tenant template.

Pool-rendering unit tests moved from packages/extra/ingress/tests/ to packages/apps/tenant/tests/. The ingress chart tests keep the Service-level asserts. packages/apps/tenant/Makefile gains a test target so hack/helm-unit-tests.sh picks up the new suite.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 16:44:46 +03:00
Arsolitt 3eeda2ba35 chore(kubernetes): regenerate code after hami addon addition
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 16:12:34 +03:00
Arsolitt 1131e2f113 docs(hami): reference upstream repo for nodeConfiguration format
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 15:33:07 +03:00
Arsolitt 6a9c310a4b fix(hami): conditional values emission and cosmetic template cleanup
Only emit values key in hami.yaml when valuesOverride has content,
matching gpu-operator pattern. Add test verifying empty valuesOverride
does not produce spec.values. Fix trailing whitespace and missing
newlines in vendored chart templates.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 15:31:24 +03:00
Arsolitt 37d5ff0c6f fix(hami): align templates with project patterns and clean dead code
Unconditionally emit values in hami.yaml matching the project pattern.
Remove duplicate test case and add coverage for omitted valuesOverride key.
Delete dead PSP template and RBAC rules (policy/v1beta1 removed in K8s
1.25). Override kube-scheduler image registry to registry.k8s.io to avoid
Chinese registry for international users.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 14:07:17 +03:00
Arsolitt cd4590b426 docs(kubernetes): clarify storageClass default behavior
Specify that empty storageClass uses the management cluster default
StorageClass (annotated with is-default-class: true), not the
top-level chart storageClass value.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 14:01:48 +03:00
Arsolitt 2734dc0bcb fix(hami): clean up leftover hami-dra references and harden defaults
Remove broken hami-dra subchart dependency from vendored chart
(Chart.yaml, Chart.lock, values.yaml) and strip DRA condition guards
from all templates since the subchart was already deleted. Override
devicePlugin updateStrategy to OnDelete to prevent destructive rolling
updates of GPU workloads. Align gpu-operator template with project
pattern (unconditional values emission). Add nodeConfiguration format
documentation and test for conflicting valuesOverride scenario.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 14:00:48 +03:00
Arsolitt 3afcaa5d26 docs(kubernetes): clarify persistence scope in breaking changes note
Add explicit scope: persistence covers same-VM reboots only.
VM replacement by CAPI still provisions a fresh PVC.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 14:00:34 +03:00
Arsolitt e2b10d42c8 docs(kubernetes): correct overwrite: false comment reasoning
DataVolumes are tied to VM lifecycle — PVC does not survive VM
recreation. The real reason for overwrite: false is the same-VM
reboot path: XFS on /dev/vdb already exists and cloud-init must
skip reformatting.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 14:00:26 +03:00
Arsolitt 56054710e9 fix(kubernetes): use floor instead of ceil for memory capacity annotation
cluster-autoscaler relies on the capacity annotation to decide whether a
node can fit a pending pod. ceil rounds the allocatable value up by <1Mi,
which can advertise capacity that kubelet will never actually schedule.
floor produces a safe under-approximation instead.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 13:47:29 +03:00
Aleksei Sviridkin cc7d09b458 fix(tests): use far-future cron in etcd backup e2e to avoid job churn
Address review feedback from coderabbitai on
hack/e2e-apps/etcd.bats:89: the test verifies that the chart renders
EtcdBackupSchedule and that the etcd-operator materializes a CronJob,
not that backups fire. Use "0 0 1 1 *" so no Jobs run against the
intentionally invalid endpoint during the ~6-minute test window.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:44:21 +03:00
Aleksei Sviridkin 97eef022e5 fix(tests): poll for etcd HelmRelease existence before waiting on readiness
Address review feedback from coderabbitai on
hack/e2e-apps/etcd.bats:39-40: replace the sleep-then-wait pattern with
a wait_etcd_hr_ready helper that polls hr/etcd until the Cozystack API
reconciles the Etcd CR and only then waits for condition=ready.
kubectl wait exits immediately when the resource does not yet exist,
which caused spurious failures when HelmRelease creation took longer
than 5s.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:44:02 +03:00
Aleksei Sviridkin 86a93af283 fix(tests): stop masking etcd e2e cleanup failures
Address review feedback from coderabbitai on
hack/e2e-apps/etcd.bats:9-14: drop the '|| true' guards in setup() so
real teardown failures (RBAC errors, stuck finalizers, wait timeouts)
fail the test setup instead of letting the next test run against stale
HelmRelease, Secret, or EtcdBackupSchedule state. --ignore-not-found
still covers the empty-namespace case on a clean run.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:43:23 +03:00
Aleksei Sviridkin 040d5d4681 docs(etcd): use "custom resource" instead of "CRD" for EtcdBackup
Address review feedback from coderabbitai on
packages/extra/etcd/README.md:9: CRDs are schema definitions; what users
apply to trigger a restore or one-shot backup is a custom resource
instance of the EtcdBackup kind, not the CRD itself. Reword accordingly.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:43:05 +03:00
Aleksei Sviridkin f8f3b29480 fix(tests): correct stderr redirection order in etcd diagnostics
Address review feedback from coderabbitai on
hack/e2e-apps/etcd.bats:19-21: redirect stdout to fd 3 first, then dup
stderr onto the new fd 1 so failures from kubectl (NotFound, RBAC,
timeouts) reach the test diagnostics stream instead of being swallowed
by the bats-captured default stdout.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:42:37 +03:00
Aleksei Sviridkin aaf9dd047c fix(etcd): cast backup history limits to int in template
Address review feedback from gemini-code-assist on
packages/extra/etcd/templates/etcd-backup-schedule.yaml:20-21: explicitly
coerce successfulJobsHistoryLimit and failedJobsHistoryLimit to int so
string values passed via helm --set do not produce a type mismatch in
the EtcdBackupSchedule spec.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:42:17 +03:00
Aleksei Sviridkin 7da29afe6e docs(postgres-operator): fix backoffLimit/activeDeadlineSeconds comment math
Address review feedback from coderabbitai on
packages/system/postgres-operator/values.yaml:30.

The old comment's 5-minute ImagePullBackOff scenario conflicted with
the 180s activeDeadlineSeconds that the default maxAttempts/sleepSeconds
resolve to, so the numbers could not both be taken at face value.

Rewrite the comment to state the actual deadline math and frame the two
gates as an AND with activeDeadlineSeconds being the shorter one under
defaults, so readers understand why backoffLimit has little headroom
without an accompanying maxAttempts/sleepSeconds bump.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:33:07 +03:00
Aleksei Sviridkin fc057c0393 fix(postgres-operator): set resources on webhook-ready wait container
Address review feedback from gemini-code-assist on
packages/system/postgres-operator/templates/webhook-ready-hook.yaml:115.

The wait container had no resource requests or limits, so schedulers
treated it as BestEffort and downstream quota enforcement had no signal.
Set small requests (10m CPU, 32Mi memory) and conservative limits
(100m CPU, 64Mi memory) matching the actual footprint of the kubectl
polling loop.

Add a matching unittest assertion so the values stay in sync if anyone
touches the template.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:32:33 +03:00
Aleksei Sviridkin 648ad82dd3 refactor(postgres-operator): scope webhook-ready RBAC to release namespace
Address review feedback from gemini-code-assist on
packages/system/postgres-operator/templates/webhook-ready-hook.yaml:83.

The Job targets the cnpg-webhook-service/services/proxy subresource, which
is namespaced and lives in the release namespace. A namespaced Role and
RoleBinding grant the exact permission needed without creating global
RBAC for a namespaced probe, which is the principle of least privilege.

Also update the kind assertions in tests/webhook-ready-hook_test.yaml so
the unittest suite tracks the new Role/RoleBinding objects.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:31:57 +03:00
Arsolitt ab7deb2b05 chore(kubernetes): regenerate after HAMi addon integration
Run make generate to update generated types, schema, README,
and CRD definitions for the new HAMi addon.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 13:03:49 +03:00
Arsolitt 7b05ce0573 fix(kubernetes): update e2e test to use renamed diskSize field
The e2e test still used the old ephemeralStorage field name,
which triggers the migration guard fail() in the Helm template.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-24 11:21:41 +03:00
Denis Chernosov 3b35404489 fix(cozystack-engine): add managed Kubernetes without visible control-plane nodes support to lineage-controller-webhook (#2417)
Signed-off-by: Denis Chernosov <denis0.ru@gmail.com>
2026-04-24 11:32:20 +04:00
Kirill Ilin 9b0fe37523 chore(hetzner-robotlb): update robotlb chart to appVersion 0.0.6 (#2465)
## What this PR does

Bumps the vendored `robotlb` chart to the latest upstream build.
Chart version remains `0.1.3`; the bundled `appVersion` moves from
`0.0.5` to `0.0.6`.

The new `robotlb` release adds RBAC permissions for
`discovery.k8s.io/endpointslices` (`get`, `list`, `watch`), which are
required to manage services backed by `EndpointSlice` — notably
KubeVirt-exposed workloads that do not publish classic `Endpoints`.

Notes:
- Upstream also replaced `replicas: {{ .Values.replicas }}` with a
  hardcoded `replicas: 1` in `templates/deployment.yaml`. The
  effective replica count is unchanged (we already set `1`), but the
  value is no longer overridable via chart values. A minor cosmetic
  reformat was applied to `templates/role.yaml`.

Closes #2256

### Release note

```release-note
chore(hetzner-robotlb): update robotlb to 0.0.6 — adds RBAC for EndpointSlices so services backed by EndpointSlice (e.g. KubeVirt) are supported.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Extended service account permissions to access Kubernetes endpoint
slices from the discovery API.

* **Bug Fixes**
  * Deployment replica configuration now fixed to single instance.

* **Style**
  * Improved YAML formatting in role template declarations.

* **Chores**
  * Updated application version metadata to 0.0.6.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-24 09:57:21 +05:00
Aleksei Sviridkin ad7d25f486 chore(cilium): bump to v1.19.3 (#2464)
## What this PR does

Refreshes the vendored Cilium chart in `packages/system/cilium` from
v1.19.1 to v1.19.3 via `make update`. Chart templates, values, CRDs and
the Cilium image reference are regenerated from upstream.

### Motivation

- **v1.19.2** ships a critical fix for cert-manager HTTP-01 Gateway API
challenges on hostnames that have both HTTP and HTTPS listeners
([cilium#44492](https://github.com/cilium/cilium/pull/44492), backport
[#44517](https://github.com/cilium/cilium/pull/44517)). Without this
fix, cert-manager cannot issue certificates via Gateway API when a
redirect HTTP listener and a TLS HTTPS listener share a hostname.
- **v1.19.3** is the latest stable patch release in the v1.19.x line (15
Apr 2026).
- This bump is a prerequisite for upcoming Gateway API work tracked
separately.

### Upstream changes pulled in

- Cilium Envoy bootstrap config, operator clusterrole, config template,
`values.schema.json` and the cilium-agent DaemonSet refreshed from
upstream.
- New `templates/ztunnel/` directory (DaemonSet, Secret, ServiceAccount)
added by upstream — not enabled by default in Cozystack values.

### Release note

```release-note
chore(cilium): bump to v1.19.3 (cert-manager HTTP-01 fix via cilium#44492)
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added ztunnel encryption support with configurable deployment settings
  * Added ConfigDriftDetection for monitoring ConfigMap changes
  * Added endpoint policy update timeout configuration
  * Added load balancer service topology support
* Extended Envoy circuit breaker configuration with connection and
request limits

* **Updates**
  * Upgraded Cilium to v1.19.3
  * Updated container images (Envoy, certgen, Hubble relay, clustermesh)
* Enhanced Cilium operator RBAC capabilities for managing ServiceImport
finalizers

* **Removals**
  * Removed BIG TCP tunnel configuration option

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-24 06:42:47 +03:00
Aleksei Sviridkin 9b87bda06a fix(postgres-operator): block HelmRelease Ready until the cnpg webhook actually serves
The cnpg admission webhook's controller pod passes readinessProbe as soon
as the local HTTPS server binds to :9443. The HelmRelease marks itself
Ready right after that via helm install --wait. But the Service
cnpg-webhook-service needs its EndpointSlice populated and the data plane
(kube-proxy / cilium) programmed before kube-apiserver can reach the
webhook through the Service ClusterIP. That gap is short but not zero,
and any HelmRelease that depends on postgres-operator (cozy-keycloak,
tenant Postgres apps) can fire its own install inside the window and hit

  Internal error occurred: failed calling webhook "mcluster.cnpg.io":
  failed to call webhook: Post "https://cnpg-webhook-service.cozy-postgres-operator.svc:443/...":
  dial tcp <svc-ip>:443: connect: connection refused

which fails the install of the downstream release. Seen on cozystack/cozystack#2470
E2E run 24862782568.

Add a post-install,post-upgrade Helm hook Job that blocks the release
from reporting Ready until the webhook answers /readyz through the
apiserver service proxy. Apiserver proxy routes the call over the same
Service IP → EndpointSlice → pod path the admission webhook uses, so
once it responds, the webhook admission path is also working.

RBAC is minimal: a dedicated ServiceAccount with a ClusterRole that only
grants get on services/proxy scoped to https:cnpg-webhook-service:webhook-server.
The Job times out after 120s with 60 attempts at 2s intervals — longer
than any data-plane programming delay seen on E2E, but bounded.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 03:51:54 +03:00
Aleksei Sviridkin 6af74cec0e fix(ingress): accept pre-CIDR externalIPs in CiliumLoadBalancerIPPool
Address review feedback from gemini-code-assist on
packages/extra/ingress/templates/cilium-lb-pool.yaml:19: if the operator
passes an externalIP already in CIDR form (192.0.2.10/32 or 2001:db8::1/128),
the template appended a second /32 or /128 suffix producing an invalid
CiliumLoadBalancerIPPool block. Guard the suffix append on the absence of
"/" in the input.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-23 23:24:38 +03:00
Arsolitt 385ea7a17f feat(platform): register HAMi as optional system package
Add PackageSource for HAMi with dependency on gpu-operator.
Include HAMi in the iaas bundle as an optional package, allowing
host-level deployment alongside the existing kubernetes addon path.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 22:16:34 +03:00
Arsolitt 3c5521ee99 fix(hami): remove broken hami-dra subchart
The hami-dra subchart renders resources even when dra.enabled=false
because Helm dependency conditions don't work for vendored subcharts.
The subchart also contains duplicate YAML label keys
(app.kubernetes.io/component, app.kubernetes.io/name) and references
unpublished container images (v0.0.1-dev). DRA support can be
re-added when the upstream project stabilizes it.

Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 22:16:30 +03:00
Myasnikov Daniil 9d552d4086 ci(api): broaden codegen drift trigger paths and detect untracked files
- Add generated-output dirs (pkg/generated, internal/crdinstall/manifests,
  packages/system/*/definitions) and Makefile to the workflow paths: filter
  so PRs that modify only generated artifacts still trigger the drift check.
- Mirror the same paths in the root pre-commit hook's files: regex so
  manual edits to generated files or changes to the root generate target
  re-run make generate through pre-commit.
- Switch drift detection in the workflow from `git diff --exit-code` to
  `git status --porcelain` so new untracked files produced by make generate
  (e.g. generated YAML/Go for a new API type) also fail the job; dump
  `git diff --color=always` on failure for easier debugging.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-04-23 22:19:35 +05:00
Arsolitt 31de543e44 chore: revert unrelated backups deepcopy change
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 19:12:46 +03:00
Arsolitt 89aeb4cb83 test(kubernetes): add migration guard test for both fields present
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 19:12:46 +03:00
Arsolitt cac38eeca1 docs(kubernetes): add inline comment explaining overwrite false behavior
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 19:12:45 +03:00
Arsolitt a3393d4d14 fix(kubernetes): merge duplicate files blocks in KubeadmConfigTemplate
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 19:12:45 +03:00
Arsolitt 5b994b2cca docs(kubernetes): document migration failure consequences
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 19:12:45 +03:00
Arsolitt c5b3a93d52 fix(kubernetes): use hasKey for ephemeralStorage migration guard
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 19:12:45 +03:00
Arsolitt a1046b5ef0 fix(kubernetes): make storageClass optional with default in schema
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 19:12:45 +03:00
Arsolitt 8a441d6232 test(kubernetes): document omitted defaults in test fixture
Signed-off-by: Arsolitt <arsolitt@gmail.com>
2026-04-23 19:12:45 +03:00