BackupVolumesInformation lives on the shared backupRequest and every
ItemBlock worker goroutine reaches pvcPvMap.insert via addVolumeInfo
whenever it backs up a PersistentVolume. The map had no synchronization,
so with --item-block-worker-count greater than 1 and a backup containing
multiple PVs, two workers could write the map concurrently. That is an
unrecoverable Go runtime fatal error, which kills the Velero server and
abandons the in-flight backup.
Guard pvcPvMap.data with an RWMutex so insert and retrieve are safe for
concurrent use, and guard the lazy initialization in InsertPVMap so
concurrent callers cannot each install their own map and lose entries.
The restore-side RestoreVolumeInfoTracker already locks around
pvPvc.insert. This brings the backup path in line.
Adds a regression test that reproduces the crash under -race without the
fix.
Fixes#10634
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Fix the MinIO image cache key in the kind e2e workflow
The build job restores the MinIO image with
minio-bitnami-${{ env.BITNAMI_CONTAINERS_COMMIT }} and the e2e jobs look
for the same key, but the save step writes
minio-bitnami-${{ steps.minio-version.outputs.dockerfile_sha }}. No step
has that id, so the expression is empty and the image is saved under a
key nothing ever reads.
Upstream only works because an entry under the right key is still in the
cache and kept alive by use; caches unused for seven days are evicted, so
a quiet week would leave every e2e job unable to load the image. A fork
has no such entry, so all of them fail at once:
Loading MinIO image...
./minio-image.tar: No such file or directory
Save under the key the restores ask for.
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
* Add changelog for #10631
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
---------
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
Pass caller-provided context.Context through cluster API queries during backup request preparation and snapshot location validation, ensuring context cancellation and deadlines are properly respected.
Closes#10620
Signed-off-by: Abhayraj Jaiswal <abhayraj916146@gmail.com>
* e2e: verify CSI snapshots on kind
Four snapshot cases cannot run on kind today. The backup itself succeeds
and the volume info lists the snapshots, but verification fails with
"Cloud provider kind is not valid": getProvider knows aws, vsphere, gcp
and azure, and CheckSnapshotsInProvider exempts only vanilla-zfs, so kind
falls through to a cloud lookup it has no API for.
Check kind in the cluster instead. A backup's VolumeSnapshotContents
exist only briefly while it is being created, so they cannot be counted
afterwards the way the cloud providers count snapshots; what Velero
recorded in the backup's volume info can be, one ready CSI snapshot per
volume. That is a weaker statement than the cloud checks make, since it
says the snapshots were taken and reported ready rather than that they
still exist in the storage provider. A backup expected to have none left,
after its deletion, is checked the other way round: nothing for it may
remain in the cluster, which reuses CheckVolumeSnapshotCR.
BuildSnapshotCheckPointFromVolumeInfo only collected those snapshot
handles for AWS and Azure, so on kind the checkpoint arrived with no
handles and EnableCSI false even with FEATURES=EnableCSI. Include kind.
This does not remove any of the CloudProvider == Kind skips; they need
Kibishii to offer a CSI StorageClass for kind as well.
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
* Add changelog for #10593
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
* e2e: check the snapshot handles rather than their count
Comparing the number of recorded snapshots against the number expected
cannot fail. BuildSnapshotCheckPointFromVolumeInfo already returns an
error when a volume is not ready to use, and again when the counts do not
match, and it appends to the list in that same loop, so the length is
settled before the check is reached.
It does not look at the handle it recorded, so a volume reported ready
with an empty snapshot handle passes today. Check that instead, which is
the difference between Velero saying a snapshot was taken and something
having been provisioned.
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
---------
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
* Fix Zip Slip path check accepting a sibling directory in archive extraction
sanitizeArchivePath confirmed an extracted tar entry stayed inside the
destination directory with strings.HasPrefix. HasPrefix has no separator
boundary, so a sibling directory whose name begins with the destination
directory's name - reached via a "../<destDir-name>-evil/x" entry -
satisfied the check and escaped the directory.
Verify containment with filepath.Rel instead, matching the check #10102
added to GetVersionedItemFilePath, rejecting a relative path equal to ".."
or under "../".
Fixes#10184
Signed-off-by: phatlc <phatle.hsd@gmail.com>
* Pin sanitizeArchivePath behaviour for entries naming destDir itself
An entry named "." or one with an empty name joins to destDir, so
filepath.Rel returns "." and the path is accepted. That is correct - it is
contained - but the table did not state it, and the returned path was not
asserted at all. Add the two rows and check targetPath on the accepted
cases so the containment boundary is pinned on both sides.
Signed-off-by: phatlc <phatle.hsd@gmail.com>
---------
Signed-off-by: phatlc <phatle.hsd@gmail.com>
* fix: defer VGS cleanup until backup finalization
The CSI PVC backup action deleted the VolumeGroupSnapshot and bound
VolumeGroupSnapshotContent after creating and waiting for all group
member VolumeSnapshots. At that point, Velero had not necessarily
completed processing the member VolumeSnapshots, CSI async operations,
or archive finalization.
Deleting the VGS triggered external-snapshotter member cleanup and could
remove VolumeSnapshot API objects still referenced by the Backup
workflow.
Remove immediate VGS/VGSC deletion from getVolumeSnapshotReference and
retain the group until the Backup reaches a terminal phase. Continue
processing VGS member VolumeSnapshots through the existing normal CSI
finalization path.
Add the velero.io/volume-group-snapshot-cleanup Backup finalizer before
VGS creation. Label VGSC resources with the Backup name and UID, enforce
DeletionPolicy=Retain before cleanup, and delete VGS/VGSC resources from
terminal Backup reconciliation only.
Make cleanup idempotent and retryable, including recovery of labeled
orphan VGSC resources. Remove the Backup finalizer only after VGS/VGSC
cleanup verification succeeds. Block Backup deletion while cleanup is
pending.
Add unit and controller integration tests covering finalizer
registration, VGS creation, terminal cleanup, failed-Backup cleanup,
orphan VGSC cleanup, and finalizer removal.
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* add changelog
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* Adress review feedback
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* remove stale VGS finalizer during snapshot restore
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* Improve codecoverage
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* explain VGS member snapshot cleanup timing
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* Second pass at review comment
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* Third pass at review comment
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* Dont swallow get errors
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* Patch backup CR only when annotation is missing
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
---------
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
Adds a gtag.js partial wired into both site head templates (baseof.html and
head-docs.html) so every page on velero.io reports into a single GA4 property.
The Measurement ID (G-XX7MWLVX37) is a CNCF-provisioned property for the Velero
project (CNCF Service Desk CNCFSD-3824). The tag renders only in production
builds, so local development and Netlify PR previews are excluded from the data.
This also satisfies the CLOMonitor analytics check for our CNCF incubation
work.
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
In invalidateBackupReposForBSL, pass the caller-provided context.Context to r.List and r.patchBackupRepository so that context cancellation and deadlines are properly respected during BackupRepository invalidation on BSL changes.
Closes#10604
Signed-off-by: Abhayraj Jaiswal <abhayraj916146@gmail.com>
* fix: regenerate CRD manifests for the status.activities field
PR #10552 ("Move the progress messages to activities") added a new
Activities []string field to PodVolumeBackupStatus, PodVolumeRestoreStatus,
DataUploadStatus, and DataDownloadStatus, but the CRD YAML manifests under
config/crd/{v1,v2alpha1}/bases were never regenerated to match -- so main's
installed CRDs have been silently out of sync with their own Go types since
that PR merged. Anything validating status writes against a strict/vendored
copy of these CRDs (e.g. an admission webhook, or the new --crd-schema-check
startup check in #9910) would reject a legitimate .status.activities write
as an unknown field.
Regenerated via: GOPATH=~/go bash hack/update-3generated-crd-code.sh
(controller-gen v0.16.5, matching go.mod's sigs.k8s.io/controller-tools pin).
No manual edits; the deepcopy diffs are the expected byproduct of the new
[]string field.
Co-authored-by: Hermes Agent <noreply@hermes-agent>
Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
* changelog: add entry for PR #10608
Co-authored-by: Hermes Agent <noreply@hermes-agent>
Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
---------
Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
Co-authored-by: Hermes Agent <noreply@hermes-agent>
* Migrate VolumeGroupSnapshot API from v1beta2 to v1
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* Add changelog
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
* Detect VolumeGroupSnapshot API version at runtime
Velero hardcoded the VolumeGroupSnapshot (VGS) API version, so VGS backup and
restore failed on clusters that serve a different version than Velero expects.
For example OCP 5.0 serves only groupsnapshot.storage.k8s.io/v1 and OCP 4.22
serves only v1beta1, while Velero targeted a single version and failed with
"no matches for kind" on the others.
Detect the served VGS API version at runtime via the discovery client
(preferring v1 > v1beta2 > v1beta1) and perform all VGS, VGSClass and VGSContent
I/O through the dynamic client, converting to and from the canonical v1 typed
structs. The controller-runtime typed client cannot negotiate versions because
it sends the GVK of the Go type, so the dynamic client is used at the I/O
boundary instead. Owner-reference matching is now version-independent (Kind and
UID), since the CSI controller stamps refs with whatever version the cluster
serves.
This builds on the v1 migration and external-snapshotter client bump from the
previous commits.
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Add changelog for VGS runtime version detection
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* docs: VGS supports v1/v1beta2/v1beta1 via runtime detection
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Remove superseded changelog for #10600 (covered by #10601)
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Use crClient + unstructured for VGS access instead of a dynamic client
Address review feedback: rather than a dedicated VGSClient wrapping
dynamic.Interface + discovery.DiscoveryInterface, perform all VolumeGroupSnapshot
I/O through the existing controller-runtime client with *unstructured.Unstructured.
The object's GVK is stamped to the served version and controller-runtime routes it
via its RESTMapper, giving the same multi-version behavior (v1/v1beta2/v1beta1)
that the typed client cannot.
This removes the extra client plumbing: no constructor signature changes to
NewRestoreFinalizerReconciler or server.go, no Factory DynamicClient/DiscoveryClient
mock churn, and no separate fake client package. The version is resolved from the
client's RESTMapper (preferring v1 > v1beta2 > v1beta1), and the helpers convert
to and from the canonical v1 typed structs.
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
---------
Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
Co-authored-by: Prasad Joshi <prajoshi@redhat.com>
locations.md linked to customize-locations.md, which does not exist; the page is customize-installation.md (same heading, and the same line already links there). minio.md linked debugging-install.md without the ../ the rest of that file uses, resolving to a nonexistent contributions/debugging-install.md. restore-reference.md had two dead same-page anchors: #resource-restore-order (heading is Restore order) and #durable-snapshot-pv-restore (heading is Snapshot PV Restore).
Signed-off-by: avneetbansal-aws <284363899+avneetbansal-aws@users.noreply.github.com>
Co-authored-by: avneetbansal-aws <284363899+avneetbansal-aws@users.noreply.github.com>
* Fix unchecked type assertion panic in ChangeImageNameAction
replaceImageName reads a restored container's image field out of the
unstructured object and asserts it to string without checking ok. The
comma-ok map lookup on the line above only confirms the "image" key is
present -- it says nothing about the value's type. A restored resource
whose image field is present but not a JSON string (e.g. a number,
bool, null, array, or object) causes an unrecovered
"interface conversion: interface {} is not string" panic in this
RestoreItemAction plugin whenever the optional image-remapping
ConfigMap feature is configured.
Switch to the comma-ok form of the assertion and skip (with a log
message) any container whose image field isn't a string, instead of
panicking.
Signed-off-by: Kaizhe Huang <derek0405@gmail.com>
* Add regression test for non-string image field panic
Covers the comma-ok assertion fix: replaceImageName operates on
generic unstructured content decoded from a backup tarball, which
isn't validated against the Pod schema before this code runs, so
"image" isn't guaranteed to be a string.
Signed-off-by: Kaizhe Huang <derek0405@gmail.com>
* Guard container-entry type assertion, use unstructured.NestedString
Addresses reviewer feedback: container.(map[string]any) was also an
unchecked assertion, and unstructured.NestedString gives safer,
more idiomatic type-checking than a manual comma-ok assertion. Also
switches the skip-path logging from Info to Warn per review.
Signed-off-by: Kaizhe Huang <derek0405@gmail.com>
---------
Signed-off-by: Kaizhe Huang <derek0405@gmail.com>
PodVolumeBackupStatus has no Node field, so the Node column was always
empty. The node is recorded in the spec.
Fixes#10444
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
* e2e: add kind VolumeGroupSnapshotClass test data
Velero selects a VolumeGroupSnapshotClass by the
velero.io/csi-volumegroupsnapshot-class label, and csi-driver-host-path
ships no VolumeGroupSnapshotClass at all, so there is nothing for the
selector to find on a kind cluster. Any VolumeGroupSnapshot e2e coverage
needs a class to exist first.
Add the kind entry alongside the existing volume-snapshot-class test
data, following the same layout and naming. Verified against a kind
cluster running external-snapshotter v8.6.0 and csi-driver-host-path:
applying this file and creating a VolumeGroupSnapshot that selects two
labelled PVCs reaches readyToUse with both member snapshots ready.
Nothing applies this file yet. It is a prerequisite for the
VolumeGroupSnapshot specs tracked in #7507, kept separate so the class
can be reviewed on its own.
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
* Add changelog for #10582
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
---------
Signed-off-by: krishhna24 <krishhnatupedev@gmail.com>
* Add e2e test for namespace selection by label in resource policy
Covers design step 8 of #9772: a backup with no explicit
--include-namespaces (the same shape a Schedule with no
includedNamespaces produces), relying entirely on a ResourcePolicy
ConfigMap's includedNamespacesByLabel to select which namespaces to
back up.
Creates labeled and unlabeled namespaces, backs up with a
ResourcePolicy ConfigMap setting includedNamespacesByLabel, and
verifies only the labeled namespaces are restored - closing the e2e
coverage gap #10275 deferred to velero-io/velero#10564.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
* Add changelog entry for e2e test PR
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
* Fix e2e test: create Backup directly, not via CLI's implicit --include-namespaces=*
The kind e2e run showed every unlabeled namespace getting backed up
and restored anyway. velero backup create's --include-namespaces flag
defaults to ["*"] when omitted (pkg/cmd/cli/backup/create.go), so
skipping the flag still sent an *explicit* wildcard - and
mergeNamespacesByLabel deliberately leaves an explicit "*" untouched
rather than narrowing it, so includedNamespacesByLabel never got a
chance to replace anything.
Create the Backup object directly via the controller-runtime client
instead, leaving BackupSpec.IncludedNamespaces genuinely unset - the
only way to exercise the "defaulted empty" narrowing path the CLI's
own default makes unreachable.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
---------
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit fixes the issue that when a namespace with label velero.io/exclude-from-backup: "true"
is added to the exludeNamespaces of a backup CR. There will be
duplicated entries of the namespace in the spec of the backup.
Signed-off-by: Daniel Jiang <daniel.jiang@broadcom.com>
Links to plugin-versioning.md and general-progress-monitoring.md broke when
those docs moved to design/Implemented/; two other relative paths had one
directory level wrong.
Signed-off-by: Zain <43629888+ZainnQureshii@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Adds ARCHITECTURE.md as a high-level, discoverable entry point to Velero's
architecture, goals, and use cases that links to velero.io and the design/
directory instead of duplicating content.
Expands ROADMAP.md from a single wiki link (which pointed at the stale
vmware-tanzu path) into a short description of how the roadmap is maintained,
and repoints the wiki link to velero-io.
Links ARCHITECTURE.md from the README so it is easy to find.
These docs address incubation-review feedback that Velero's goals,
architecture, and roadmap process were scattered across the website.
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
Add the maintainer information required by the CNCF Incubation criteria:
- State that all maintainers share collective responsibility for the entire
project, consistent with CODEOWNERS assigning ownership to the maintainer
group as a whole (no siloed per-area owners).
- Add a Contacting the maintainers section listing GitHub, Slack, the mailing
list, and the security disclosure process.
This makes MAINTAINERS.md cover names, contact information, domain of
responsibility, and affiliation as required for the Incubation application.
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>