Skip to content

perf-sentinel chart v0.9.20

Choose a tag to compare

@github-actions github-actions released this 25 Jul 10:50
chart-v0.9.20

What's new in chart-v0.9.20

This chart release closes a class of defect where the chart rendered a configuration the daemon then refuses at startup, and where the deployment guide described behavior the code does not have. Four render-time guards replace four silent failures, each of which previously surfaced only as a CrashLoopBackOff, or as a 503 from the acknowledgment routes with nothing to explain it. Ownership of the two daemon tables the chart writes is now an explicit values flag instead of a guess about the shape of your config.toml, because TOML opens a table through a header, a dotted key or an inline table alike and a regex that only knows the first spelling appends a duplicate. appVersion is intentionally held at the current daemon release 0.9.17 because the binary did not change. The chart version advances to 0.9.20 on its own.

Added

  • workload.statefulset.persistence.manageDaemonPaths, true by default. It states who writes [daemon.ack] storage_path and [daemon.archive] path when persistence is on. Left at true, the chart writes both and refuses to render as soon as config.toml mentions either table, in any TOML spelling, naming the flag to flip. Set to false, the chart writes neither and you own both paths under /var/lib/perf-sentinel, which is what you want for [daemon.ack] toml_path or [daemon.archive] max_size_mb. The guard errs on the side of refusing, since the alternative is a config the daemon cannot parse, discovered at CrashLoopBackOff.

Fixed

  • A config.toml that touches [daemon.ack] or [daemon.archive] no longer renders a ConfigMap the daemon cannot parse. With persistence enabled the chart appended both tables unconditionally, so an operator setting [daemon.ack] api_key or toml_path, or [daemon.archive] max_size_mb, ended up with the same table twice in the rendered TOML. The parser rejects a table defined twice and the daemon crash-loops on it. This is what the new manageDaemonPaths value above resolves, and the guard now recognises the dotted-key (ack.storage_path under [daemon]) and inline-table forms that a header-only match missed.
  • [daemon.archive] is no longer injected when config.toml sets [green] enabled = false. The daemon refuses to start on that pairing, an archive of windows with no energy or carbon would make disclose output meaningless, and because the chart always passes --config explicitly the rejection is fatal rather than a fallback to defaults. Asking for anti-pattern detection without GreenOps, plus persistence, produced a CrashLoopBackOff. Declaring that archive yourself alongside green scoring off now fails the render in every workload mode, not only under persistence, since the daemon refuses it either way.
  • A service.ports.*.port moved without the matching [daemon] listen_port_* now fails the render. The containerPort, the liveness and readiness probes, the Service, the NetworkPolicy and the helm test pod all follow the Service value while the daemon binds the config value, so the pod listened where nothing looked, the readiness probe never passed and every OTLP span was dropped. An omitted listen_port_* is checked against the daemon's own defaults, 4318 and 4317, rather than skipped, since those are what the process actually binds.
  • workload.statefulset.persistence.enabled on a Deployment or DaemonSet fails the render instead of doing nothing. Persistence renders a volumeClaimTemplate, which only a StatefulSet has, so the operator got no volume, no durable acknowledgment path, and a 503 from the three ack routes with no indication why.
  • The helm test pod keeps its -test suffix. The name label was truncated at 63 characters after the suffix was appended, so a nameOverride of 62 or 63 characters erased the suffix entirely and handed the ephemeral test pod the workload's own selector labels, exactly what the label was introduced to avoid. The name is now truncated to 58 before the suffix is added.

Changed

  • values.schema.json accepts resources.claims, a standard Kubernetes field since 1.26 that the schema rejected outright while the chart advertises kubeVersion: ">=1.24.0-0".
  • serviceMonitor.interval and scrapeTimeout accept the full Prometheus Operator duration grammar. The previous pattern rejected composed durations such as 1m30s, along with 1d, 1w and 1y, all of which the operator accepts.
  • The deployment guide and the runbook stop contradicting the chart. The runbook described the liveness probe as a TCP check when the chart renders httpGet on /health, used the Docker Compose host port 14318 as the pod port instead of 4318, targeted a Deployment name the chart never renders, called the image distroless when it is FROM scratch with no CA bundle either, and recommended multiple replicas behind a load balancer without the trace-aware routing that makes that safe. The configuration reference also stated that the daemon refuses to start when the default ack storage path cannot be resolved, while the code logs a warning and leaves the ack routes on 503, reserving the fatal path for an operator-supplied path.

Behavior

  • The one migration. An existing release whose config.toml declares [daemon.ack] or [daemon.archive] while StatefulSet persistence is enabled will now fail to render on helm upgrade. Set workload.statefulset.persistence.manageDaemonPaths: false and make sure your own tables carry storage_path and path under /var/lib/perf-sentinel. That install was previously producing a ConfigMap with a duplicated table, so the daemon was already refusing to start on it.
  • A release whose Service port and daemon bind disagree will also fail to render. That install was already broken in cluster, the readiness probe could never pass, so the render error replaces a silent failure rather than a working deployment.
  • The helm test pod's name label changes only when nameOverride is longer than 58 characters. Every other install renders the same label as before.
  • No daemon behavior changes. No route disappears, no metric loses a label value, no configuration key changes its meaning, and acknowledgment signatures do not reset. appVersion stays at 0.9.17 and artifacthub.io/images still points at ghcr.io/robintra/perf-sentinel:0.9.17.
  • Every guard is checked by scripts/test/chart-render-guards-test.sh, fourteen scenarios run by the helm-ci workflow, and the render matrices gain a statefulset-persistence leg so the injection path is validated by kubeconform on every pull request. The guards were verified by rendering, not on a live cluster.

Install

The chart is published as an OCI artifact on GHCR, install it directly with no helm repo add step:

helm install perf-sentinel oci://ghcr.io/robintra/charts/perf-sentinel --version 0.9.20

Upgrade an existing release:

helm upgrade perf-sentinel oci://ghcr.io/robintra/charts/perf-sentinel --version 0.9.20

Full Changelog: chart-v0.9.19...chart-v0.9.20