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>
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>
The negative-floor guard read $min, already int .minReplicaCount, and int
truncates toward zero, so a fractional negative such as -0.5 became 0 and slipped
past into exactly the scale-to-zero-capable ScaledObject the type check above
exists to prevent. Test the untruncated value instead.
The annotations test only set an extra key with no pause, so it exercised the
pass-through branch and never the merge where the pause pair is the destination
and must win a key collision. Pass a colliding paused-scale-in="false" alongside a
distinct key and assert the pause value overrides it on the rendered object.
Assisted-by: LLM
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
cozy-lib.keda.scaledObject only checked max >= min, so an all-negative or
mixed-sign pair (min -5, max -3) passed the ordering guard and rendered a
ScaledObject with a nonsensical floor. Reject minReplicaCount < 0 before the
ordering check. Also add a cozy-lib-tests case for the documented annotations
parameter, which had no caller and no coverage. Follow-up from #3954 (#4187).
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
Restrict the KEDA operator ClusterRole: set permissions.operator.restrict.secret
so it drops cluster-wide secret list/watch, and pin rbac.scaledRefKinds to
postgresql.cnpg.io/clusters so it no longer holds a wildcard */scale across every
group.
Gate DatabaseAutoscalerKedaOperatorDown on the presence of keda-hpa-* HPA series
so a tenant running its own Monitoring app (which never scrapes keda_build_info,
root-only) does not fire it forever about a healthy platform component. Make the
two negative containsDocument matchers in the bundles-default test non-vacuous
(any: true) so "KEDA is not installed by default" is actually asserted. Drop the
unused pollingInterval/cooldownPeriod params from the cozy-lib keda helper.
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
Address review findings on the KEDA read-replica autoscaler where the
implementation diverged from the merged design proposal.
Fail-safe read load. Gate the `or vector(0)` floor on the existence of ANY CNPG
instance pod (`count(kube_pod_labels{...instance_role=~".+"}) > 0`) — primary or
replica — so the query is empty ONLY when no CNPG pod labels exist at all (a
broken kube-state-metrics pipeline), not during initial provisioning when the
sole replica-side pod is CNPG's join Job (jobRole, not instanceRole). Also pin
`ignoreNullValues: "false"` on the trigger: KEDA's prometheus scaler defaults it
true, turning an EMPTY result into metric 0 (not an error) — the HPA would then
desire 0 and clamp to the floor, i.e. silently scale a broken-pipeline cluster
DOWN. With it false an empty result is a scaler error, so the HPA HOLDS and
DatabaseAutoscalerScalerErrors fires; gating on any instance role keeps a healthy
cluster (including a long basebackup) from tripping that alert.
Constant seed = max(replicas, effectiveMin), so enable/dryRun/transition flips
are a merge no-op with no dip and never undercut the quorum floor.
Fail closed when the quorum floor exceeds maxReplicas (was: effectiveMax silently
raised both bounds, unbounded for a large maxSyncReplicas).
Dry-run / transition keep the HPA (unidirectional pause pair, not the HPA-deleting
full pause) but both SelectPolicy=Disabled, so desired normalizes to current — the
recommendation is read from the read-load metric, not a diverging desired count.
Observability. DatabaseAutoscalerAtMax keys on desired >= maxReplicas, NOT the
ScalingLimited condition (which is also true at the floor, so it fired on every
idle cluster with wrong "raise maxReplicas" advice). Dashboard read-load panels
are per-cluster (label_cnpg_io_cluster) with a CPU panel for ReadCPUUtilization
and the exact clamp in descriptions; ScaleStuck's Pending intersection is scoped
to CNPG pods; alerts.yaml narrative comments moved to Go-template comments so they
do not ship into the PrometheusRule.
Guard the seeding invariant: TestBuildHelmReleaseSpecNoForceOrDriftDetection.
Regenerated README/schema/types.
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
Address IvanHunters' deep review round on #3954:
- [MAJOR] Enabling autoscaling directly on an existing non-quorum database no
longer collapses it to 1 instance and deletes every replica PVC. The chart now
SEEDS spec.instances at the quorum floor (effectiveMin) on BOTH the quorum and
non-quorum active paths instead of omitting the field in the non-quorum case;
the constant seed is a three-way-merge no-op so KEDA still owns the runtime
count via /scale, and the enable dip is capped at the floor (>=2) rather than
collapsing to 1. Documents the client-side-3-way-merge (not SSA) assumption
that the no-op relies on.
- [MINOR] Fail closed on autoscaling.minReplicas > autoscaling.maxReplicas instead
of silently resolving the ceiling upward (which defeated maxReplicas as a cost
knob). The stray maxReplicas: 0 case now rejects rather than clamps.
- [MINOR] The disable-wedge guard, its values note and its test no longer emit the
invalid `kubectl scale --subresource=scale` (scale has no --subresource); use
`kubectl scale cluster.postgresql.cnpg.io/<name> --replicas=N`.
- [MINOR] Correct the enablement note: raising minReplicas/maxSyncReplicas on a
live cluster is NOT harmless when KEDA's live count exceeds the new floor (it
decommissions surplus replicas + PVCs); prescribe pin-first for raises too.
- [MINOR] Add DatabaseAutoscalerKedaOperatorDown (absent(keda_build_info)): when
the operator is unhealthy a ScaledObject never becomes an HPA and no other alert
can fire. Intersect DatabaseAutoscalerScaleStuck with a Pending pod so a healthy
long basebackup (Running pod, desired>current >15m) no longer false-fires.
- [MINOR] Keep the KEDA CRDs on package uninstall (crds.additionalAnnotations
resource-policy: keep via the shim) so removing the keda package doesn't
cascade-delete every tenant ScaledObject.
- [MINOR] cozy-lib helper: reject a non-numeric bound (int "two" -> 0 -> a
scale-to-zero ScaledObject) and render an explicit pollingInterval/cooldownPeriod
of 0 (`if not kindIs invalid`, not `with`).
- [MINOR] Note the read-load fail-open: a broken metrics join reads as idle and
silently pins autoscaling at the floor under real load.
New/updated tests cover the non-quorum seed, the min>max guard, the corrected
kubectl message, the operator-down + Pending-intersected alerts, the CRD keep
policy, and the non-numeric-bound helper guard.
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
Address the remaining IvanHunters review points on #3954:
- [MAJOR] Disabling autoscaling wedged the HelmRelease under synchronous quorum.
An autoscaled + maxSyncReplicas>=1 cluster runs with instances seeded from
effectiveMin while replicas stays at its default, so flipping autoscaling off
rendered instances: <replicas> next to the quorum and CNPG's webhook rejected
it ("maxSyncReplicas must be lower than the number of instances"). Add a
symmetric render-time guard on the static-count path (covers off/dryRun/
transition): fail with an actionable message when replicas <= maxSyncReplicas.
- [MINOR] Role-scope the freeze brake's currentInstances count
(label_cnpg_io_instance_role=~".+") so lingering CNPG join/bootstrap Job pods
(cnpg.io/cluster but jobRole, not instanceRole) don't inflate it and nudge
desired up while the brake is meant to hold it.
- [MINOR] Default maxReplicationLagSeconds to 0 (brake opt-in): only the
non-braking path is validated live, so ship the validated default and let the
freeze be enabled explicitly until its branch is exercised under load.
- [MINOR] Document the floor-change and non-quorum-disable dips (same three-way-
merge hazard) and the pin-replicas-first mitigation.
- [NIT] Coerce the cozy-lib helper's `paused` (eq "true") so a caller passing the
string "false" does not pause the ScaledObject.
- [NIT] Trim the keda.clusterDomain injection comment so it no longer ships ~8
verbatim lines into the cozystack-values Secret on every cluster.
Regenerate types/schema/README/postgres-rd. New tests cover the disable-wedge
guard, the role-scoped freeze count, and the string-"false" paused coercion.
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
Address the branch-review nits:
- Fail closed when the monitoring namespace is unset. serverAddress builds
vmselect-shortterm.<ns-monitoring>.svc, and an empty ns-monitoring rendered the
malformed vmselect-shortterm..svc:8481, surfacing late as a KEDA scaler error.
The platform always injects it, but a hand-rendered/misconfigured tenant now
gets an actionable render-time failure mirroring the KEDA-CRD and target guards.
Tested.
- Document that the database-autoscaling PrometheusRule matches every KEDA HPA /
ScaledObject error (the underlying series carry no owning-app label), which is
correct only while database autoscaling is KEDA's sole consumer in cozystack;
note to scope the rules if a non-database ScaledObject is ever added.
- Correct the cozy-lib.keda.scaledObject usage example: `paused` should reflect
dry-run OR migration transition, not dry-run alone, so a second engine copying
the example does not drop the transition pause.
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
Two review findings:
- The enablement note claimed the two-phase `transition` flow avoids the
count dip when enabling autoscaling on an existing cluster. It does not:
helm-controller upgrades with Helm's three-way merge (not SSA), which keys off
the old-vs-new manifest diff, not KEDA's live /scale value. At phase 2 the
chart stops rendering the staged static count, so the field is deleted (no
quorum -> CNPG defaults to 1, a brief collapse) or changed (quorum -> rebased
to effectiveMin), then the warm KEDA restores it. Rewrite the docs to state the
flow reduces (KEDA is pre-warmed, no cold-start) but does not eliminate the dip,
and spell out the suspend + scale-subresource pin that actually makes the
handoff dip-free. This is the SSA-vs-three-way-merge handoff the design proposal
left for the PoC to settle.
- Pin metricType: AverageValue on the Prometheus trigger in
cozy-lib.keda.scaledObject. The desired = ceil(query / threshold) identity
holds only for an AverageValue external metric; it was relying on KEDA's
default. Make it explicit and assert it so a re-vendor or default change cannot
silently break the arithmetic.
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
Implement the KEDA-based read-replica autoscaler for postgres per the
merged design proposal (cozystack/community#44):
- cozy-lib.keda.scaledObject: engine-agnostic helper rendering a KEDA
ScaledObject (scale target, effective bounds, prometheus trigger,
scale-down behavior, optional pause), fail-closed on bad input.
- postgres: an `autoscaling` values block (enabled / minReplicas /
maxReplicas / target / maxReplicationLagSeconds / dryRun). Under active
autoscaling the chart drops the static .spec.instances so Flux and the
KEDA-managed HPA no longer contend, and renders a ScaledObject whose
minReplicaCount folds in the synchronous-quorum floor
(max(minReplicas, maxSyncReplicas+1, 2)); when the floor exceeds
maxReplicas, quorum wins. dry-run keeps the static count and pauses the
ScaledObject. The WorkloadMonitor tracks the quorum floor instead of a
stale static value.
Covered by helm unittest (cozy-lib helper: valid render, pause, three
fail-closed guards; postgres: instances dropped, quorum-floored bounds,
quorum-over-max, dry-run pause). Regenerated values.schema.json, README,
Go types and postgres-rd.
Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
cozy-lib.resources.toFloat knew every suffix of the Kubernetes quantity
grammar except `u` and `n`. A suffix it does not recognise is not an
error: the unit letter stays on the string, `float64` cannot parse the
result and yields zero silently, and the caller divides or compares
that zero as if it were the value.
The node group CPU request guard is one such caller. A request of 100u
above a limit of 50u compared zero against zero and rendered, so the
pair reached API server validation on the worker's Pod instead of
failing where the values were written.
Pinned by a suite over the whole suffix grammar, one value per form,
because the failure has no error to notice it by.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <3811295@gmail.com>
`_cluster` and `_namespace` reach a chart through valuesFrom on the
cozystack-values Secret, so they are absent whenever a chart is rendered
on its own: `helm lint`, a plain `helm template`, and any helm-unittest
suite that does not set them. Twelve of the helpers in _cozyconfig.tpl
read straight through the missing map and abort the render rather than
returning their documented empty default.
Two spellings, one cause. `index .Values._cluster "root-host"` raises
`index of untyped nil`, and `.Values._namespace.host` raises
`nil pointer evaluating interface {}.host`. In both cases the trailing
`| default ""` never runs: it applies to the result, and there is no
result, only an error. That default covered a key missing from a map
that exists, never a missing map.
Guard the map instead, which is what `cozy-lib.images-registry` in this
same file already did:
(index (.Values._cluster | default dict) "root-host") | default ""
`index` on an empty map returns nil harmlessly, so the trailing default
applies as it always read. With the map present, `| default dict`
returns it untouched.
This changes no rendered output. Every one of the 34 charts that symlink
cozy-lib was rendered before and after, both with the injected values
populated and with them set to empty maps, and every result is
byte-identical. Eight charts differ between any two runs because they
generate passwords; rendering the unchanged tree twice reproduces
exactly those eight, which is how they are excluded.
What this does not do is fix a chart that fails today. The charts that
cannot render standalone read the injected values directly in their own
templates rather than through these helpers, so they are unaffected by a
change to the library and are being addressed where they live.
Twelve of the thirteen helpers here have no callers anywhere in
packages/ at present; only `cozy-lib.images-registry` is reached, from
`cozy-lib.image`, and it was already guarded. The guard is still worth
having on the rest: they are the library's public surface, they are what
a chart author copies when reaching for cluster configuration, and the
broken spelling propagates by being read. `cozy-lib.image` is called
from four templates, so these helpers do get adopted once they exist.
Add a suite in cozy-lib-tests, which is where library behaviour is
pinned because a library chart renders nothing of its own. One case
covers the uninjected state, which needs no mocking since neither key is
in values.yaml, and one covers the injected state so the guard cannot
quietly change what a populated map returns. The injected case includes
`scheduling` and `branding` specifically: those two are the helpers
whose body was restructured rather than wrapped, so they are the ones
whose present-map behaviour most needs pinning. Against the unguarded
helpers the first case fails with `index of untyped nil`.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Rename the Secret cozy-lib.tls.caCertSecret renders from "<release>-ca-cert"
to "<release>.tenant-ca", the same canonical, key-free name the
CA-extraction controller publishes, so a chart that holds its CA PEM at
render time and an operator whose CA is minted asynchronously converge on
one object a tenant can name. "<release>-ca-cert" is not a free name —
Percona Server for MongoDB already claims it with a key-bearing Secret.
Harden the write guard: require a complete BEGIN/END CERTIFICATE block,
keep failing closed on any PEM private-key header, and coerce a non-string
caCert value before trimming so an unquoted numeric YAML scalar cannot
panic the template.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Address review on the S3 request-checksum fix:
- Extend the fix to the platform-managed useSystemBucket=true flow, whose
ObjectStore is built in Go by applyClusterPluginBackup (SSA-applied), not
chart-rendered. Add InstanceSidecarConfiguration to cnpgtypes.ObjectStoreSpec
and set AWS_REQUEST_CHECKSUM_CALCULATION=when_required on it via
barmanSidecarConfiguration(). The platform's own default system bucket is
SeaweedFS, a non-AWS S3 gateway of the same class as Ceph RGW. Unit test in
cnpgstrategy_controller_test.go asserts the applied ObjectStore carries it.
- Factor the duplicated instanceSidecarConfiguration block (3x across two
charts) into a shared cozy-lib helper (cozy-lib.barman.checksumSidecarConfiguration).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrey Kolkov <andrey.kolkov@aenix.io>
The post-delete cleanup Jobs in the harbor and mariadb charts hardcoded
`docker.io/clastix/kubectl:v1.32` — a moving tag pulled directly from
Docker Hub. This broke build reproducibility (the tag can be re-pushed),
was a supply-chain risk, and could not be satisfied on air-gapped /
mirrored clusters, where it failed at the worst moment: during uninstall,
when the post-delete hook runs and stalls release teardown.
Add a canonical `cozy-lib.image` helper that prefixes a registry-relative
image path with `cozy-lib.images-registry` when set and returns it
unchanged (no leading "/") when empty, so standard installs resolve from
the default registry and mirrored installs resolve internally. Consume it
from both cleanup hooks with the image digest-pinned to the immutable
multi-arch index sha256:b9ef7d8dbe65bcc81a46c09b8dc7543103055021c4f43287bf59e92a8f4fe05c
(the same digest already pinned for postgres-operator's webhook hook).
Keep the pin fresh with a custom Renovate manager: the repo disables the
helm-values manager (enabledManagers), and the ref is built at render time
by the helper rather than being a Dockerfile/go.mod dependency, so the
built-in managers cannot see it. A regex manager over the hook templates
tracks clastix/kubectl by tag+digest — mirroring the existing extra/etcd
manager — so the supply-chain pin does not silently age.
Also harden `cozy-lib.images-registry` against a nil .Values._cluster so
the helper never crashes the render — relevant precisely because the hook
renders during teardown. Helm unit tests assert the rendered image (routed,
digest-pinned, no leading slash) by pattern rather than an exact digest, so
a Renovate bump keeps them green.
Closes#3088
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Алексей Артамонов <alexeyartamonov1987@gmail.com>
Per-app TLS issues a per-release self-signed CA, but the only objects
that carry ca.crt — the cert-manager CA and leaf Secrets — also carry
private keys. Granting a tenant read on those to obtain the trust
anchor also hands over a server or CA private key.
Add cozy-lib.tls.caCertSecret, which renders a canonical Opaque Secret
holding only ca.crt and labelled internal.cozystack.io/tenantresource=
true. The tenantsecret registry surfaces label-bearing Secrets under
core.cozystack.io/tenantsecrets, which the base tenant roles already
grant, so tenants reach the trust anchor without any grant on a Secret
that contains tls.key. The helper fails closed on empty input and
refuses any PEM carrying private key material.
Covered by helm-unittest in the cozy-lib test chart.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Restructure the resource preset table into a flat <series>.<size> naming
convention inspired by KubeVirt and cloud-provider instance types. Five
series cover the full CPU-to-memory ratio range:
t1 (Tiny, 1:0.5) — burstable, low memory
c1 (Compute, 1:1) — CPU-balanced, CPU-bound workloads
s1 (Standard, 1:2) — proxies, caches, lightweight services
u1 (Universal, 1:4) — databases and messaging
m1 (Memory, 1:8) — search and analytics
Each series provides eight sizes (nano, micro, small, medium, large,
xlarge, 2xlarge, 4xlarge), yielding 40 presets in total. Ephemeral
storage remains 2Gi for every preset.
The seven legacy flat names (nano, micro, small, medium, large, xlarge,
2xlarge) are retained as backward-compatibility aliases returning their
original CPU and memory values. Existing HelmReleases and app CRs
continue to render identical resources without a migration step. The
legacy block is deprecated and will be removed in a future release; the
1:1 conversion table is:
nano -> t1.nano (250m / 128Mi)
micro -> t1.micro (500m / 256Mi)
small -> t1.small (1 / 512Mi)
medium -> c1.small (1 / 1Gi)
large -> c1.medium (2 / 2Gi)
xlarge -> c1.large (4 / 4Gi)
2xlarge -> c1.xlarge (8 / 8Gi)
Also fix the preset helper docstring to pass the preset string straight
to unsanitizedPreset, replacing the prior list applied-to-tuple form
that silently invoked the dot value as a function.
Co-authored-by: Matthieu ROBIN <matthieu@hidora.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Move common-envs.mk and package.mk from scripts/ to hack/ directory.
Update all Makefile includes to use new paths. Remove unused
issue-flux-certificates.sh script.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Replace Helm lookup functions with FluxCD valuesFrom mechanism for
reading cluster and namespace configuration.
Changes:
- Create Secret cozystack-values in each namespace with values.yaml key
containing _cluster and _namespace configuration as nested YAML
- Configure HelmReleases to read from this Secret via valuesFrom
(valuesKey defaults to values.yaml, so it can be omitted)
- Update cozy-lib helpers to access config via .Values._cluster
- Add default values for required _cluster keys to ensure all fields exist
- Update Go code (cozystack-api and helm reconciler) to use new format
This eliminates the need for Helm lookup functions while maintaining
the same configuration interface for charts.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
This patch breaks introduces a helper function in cozy-lib to correctly
handle special case resources when transforming a nested map of limits
and requests to a flat map suitable for use in resourceQuotas. As a
result, admins can now specify any types of resources as resource quotas
for tenants, and they will be correctly transformed to the correct
format for the underlying kubernetes ResourceQuota. In addition to the
previously supported compute resources, such as CPU, memory, and custom
resources, like GPUs, special quota strings such as
"services.loadbalancers" are now correctly handled.
```release-note
[cozy-lib,platform] Support resource quotas for special kubernetes
quotas, such as service.loadbalncer count and others.
```
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
This patch adds special handling for raw Kubernetes ResourceQuota fields,
such as `services.loadbalancers`, preventing them from being wrapped as
`limits.*` or `requests.*` keys by the flatten helper. This ensures that
LoadBalancer quotas render correctly in tenant specifications.
```release-note
[cozy-lib] Correctly render services.loadbalancers in ResourceQuota without limits.* or requests.* prefixes.
```
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
## What this PR does
The cozy-lib library package got complicated enough to warrant its own
unit tests. Since unit tests are a "good thing" (tm), a somewhat generic
framework for running all kinds of unit tests was introduced into the CI
pipeline and Makefile targets. For now all it runs is `make test`
against the `packages/{library,apps,system,extra}/*` directories,
wherever a `test` target is present in the Makefile, and for now this is
only for the `cozy-lib` Helm library chart.
### Release note
```release-note
[ci,dx] Introduce a scaffold for running unit tests locally and in CI
and add the first unit tests for the cozy-lib helper Helm chart.
```
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
If running in Hetzner and using Hetzner's cloud load balancers, node
ports need to be allocated for the load balancer to function correctly.
Therefore if RobotLB is enabled, we probably need to assign node ports.
Release note:
[platform] Autodetect if node ports should be assigned to load balancer
services.
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
This patch passes Java heap parameters to Keycloak to prevent OOM errors
when the JVM lacks compatibility with cgroups v2 and fails to recognize
container memory requests and limits. A new function is introduced in
cozy-lib to calculate the heap parameters from requests and limits,
setting Xmx to 75% of the memory limit and Xms to the lesser of the
memory request or 25% of the memory limits.
Change log:
[keycloak] Calculate and pass Java heap parameters explicitly to prevent
OOM errors.
[cozy-lib] Introduce helper function to calculate Java heap params based
on memory requests and limits.
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
This patch removes the loophole to leave resource requests and limits
unspecified in managed apps. Any of cpu, memory, and ephemeral storage
are now filled in from the resource preset (default or user-specified)
if not explicitly specified in .Values.resources. "none" is no longer an
accepted value in resourcePresets and the primary resources now always
have some explicit value for proper billing and isolation.
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
* **Refactor**
* Updated the structure of resource presets for improved clarity and
processing.
* Adjusted template logic to streamline resource handling and removed
previous resource limit calculations.
* Modified template parameters to enhance flexibility in resource
processing.
* **Chores**
* Improved internal template invocation for better compatibility with
resource data.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
With this change a request for a virtual machine with 3 vCPUs will
reserve exactly the same amount of physical compute, as a request for a
Clickhouse instance with `{"resources": {"cpu": "3"}}` in its values,
with the scaling factor being KubeVirt's CPU allocation ratio.
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
This patch introduces reusable library charts that provide
backward-compatibility for users that specify their resources as
explicit requests and limits for cpu, however this input is processed so
that limits are set equal to requests except for CPU which only gets
requests. Users can now embrace the new form by directly specifying
resources in the first level of nesting (e.g. resources.cpu=100m instead
of .resources.requests.cpu=100m). The order of precedence is top-level,
then requests, then limits, ensuring that nothing will break in terms of
scheduling, however workloads that specified limits much higher than
requests might get a performance hit, now that they cannot use all this
excess capacity. This should only affect memory-hungry workloads in
low-contention environments.
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>