History
Release history
What shipped when, what it means for a cluster running the previous version, and the rules the project holds itself to about compatibility.
Status#
1.0.0 2026-08-31#
The first tagged release. Everything the rest of this site documents is in it.
| Change | What it means for you |
|---|---|
| Durable volumes | A volume can now outlive its pod. Its contents live in S3 and are restored into a fresh directory at publish, archived and mirrored at unpublish. No mount(2), no privileged container and no node affinity, so the volume survives losing its node. |
| PVC-declared volumes | An optional Controller service lets a workload use a volumeClaimTemplate instead of an inline csi: block. The driver still holds no Kubernetes permissions; the RBAC belongs to the provisioner sidecar. |
| Server-side append | A growing file no longer re-uploads whole. appendUpload selects UploadPartCopy, or native offset-append on S3 Express directory buckets, and segment compaction now assembles server-side. |
| Presigned multipart, and signer-less POST policies | A signer that signs the multipart operations lifts presigned mode's 5 GiB cap. A static POST policy in the volume's Secret removes the signer service entirely. |
| Statistics web UI | An optional read-only page with uploads per hour and per day, bytes, retries and failures, aggregated across every node through a headless Service. Off by default. |
| Prometheus metrics, volume stats, Helm chart | A /metrics endpoint, NodeGetVolumeStats reporting usage to kubelet, and a chart equivalent to the kustomize base, published as an OCI artifact at ghcr.io/trion-development/csi-s3-archiver-chart so helm install oci://… needs no chart repository. |
| Compression and server-side encryption | compression: gzip and SSE-S3 or SSE-KMS per volume. |
| Secret rotation without pod restarts | requiresRepublish, so a rotated nodePublishSecretRef reaches running pods. |
| JSON logging | S3A_LOG_FORMAT=json for collectors that would otherwise re-parse the text format. |
| Measured resource limits | The shipped requests and limits come from hack/measure-resources.sh rather than from guesswork, and the measurement is repeatable. |
Breaking changes#
None yet. This section exists so that when there is one, it is somewhere obvious rather than buried in a table.
Two changes illustrate what counts as one:
- The volume state file's schema is at v1, and 1.0.0 is the first release to write one, so no other version exists in the field. Segment bookkeeping and the object length that server-side append needs were additive: An older file would still read, with the new fields defaulting to zero, so upgrading a driver never discards a node's manifests and re-uploads everything. That is the property to preserve.
- The memory request is 128Mi, set from measurement rather than estimate. A value below the driver's idle usage under-provisions every node, which is the kind of change that warrants a note here.
Versioning policy#
| Component | Policy |
|---|---|
| The driver | Semantic versioning, in force from 1.0.0 onwards. A breaking change means a major version and an entry in breaking changes. |
| Volume attributes | Additive. An attribute is never repurposed; an unknown one fails the publish loudly rather than being ignored, so a typo is never silent. |
| State file schema | Explicitly versioned, and at version 1: 1.0.0 is the first release to write one, so no other version exists in the field. Additions that default harmlessly keep the number and stay readable; one that does not raises it, and a file the driver cannot read is dropped with an error rather than guessed at, because a wrong manifest causes silent data loss. |
| The signer contract | Versioned explicitly, and at v1. The multipart operations are opt-in per volume rather than probed, because a putObject-only signer answers them plausibly and wrongly. |
| Object layout in the bucket | Stable. Keys are {prefix}{relative path}, and the .parts/ layout for the segments strategy is documented. |
| The CSI spec | Vendored at v1.12.0. A spec upgrade is a release note. |
How releases are built#
Worth knowing if you verify what you deploy.
- A
v*tag triggers the release workflow. Each architecture builds its own native binary on its own native runner. The toolchain no longer forces that split, becausenative-imagecan cross-compile aarch64 from an amd64 host (which is how a maintainer produces a complete multi-architecture tag from one laptop). The reason to keep it is that a native runner can also run what it built, and the conformance suite, the upload round trip and the UI check all execute the binary. - Every architecture image is verified before it is pushed: The CSI conformance suite, an upload round trip in both credential modes, and the statistics UI, all against the binary that ships.
- Images are signed with keyless cosign. The signature covers the digest, so moving a tag afterwards does not carry it along. Two identities can appear in that certificate, because a release cut by hand from a maintainer's machine is signed by that person's GitHub account while a workflow-built one is signed by the workflow. The command below accepts either; narrow it if you want to trust only one.
- The multi-architecture tag is stitched from the per-architecture ones, and the stitch step refuses to sign a manifest that does not carry every architecture.
- The release attaches the rendered install YAML pinned to that release, so applying it later installs the same thing.
cosign verify \
--certificate-identity-regexp '^(985728\+everflux@users\.noreply\.github\.com|https://github\.com/trion-development/csi-s3-archiver/.*)$' \
--certificate-oidc-issuer-regexp '^https://(github\.com/login/oauth|token\.actions\.githubusercontent\.com)$' \
ghcr.io/trion-development/csi-s3-archiver:1.0.0