* Fix PodVolumeBackup metadata loss on fs-backup timeout
When a backup hits the fs-backup timeout, WaitAllPodVolumesProcessed
returned nil because PVBs were only collected from the indexer in the
done branch of the select. This discarded all PVB metadata including
already-completed PVBs, making their data unrestorable.
Move the PVB collection loop to run after the select so tracked PVBs
are always persisted regardless of timeout.
Fixes#9986
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Add changelog for PR #9995
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Filter non-completed PVBs in hasPodVolumeBackup
After preserving tracked PVBs on timeout, non-completed PVBs (in-progress
or with no snapshot ID) would cause hasPodVolumeBackup to return true,
leading the restore to skip the original PV and dynamically re-provision
it without any data to restore from.
Only match PVBs that are Completed with a valid SnapshotID.
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Add unit tests for hasPodVolumeBackup phase filtering
Verify that hasPodVolumeBackup only matches PVBs that are Completed
with a valid SnapshotID, and rejects in-progress, failed, or
empty-snapshot PVBs.
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
---------
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Validate user-provided labels and annotations in maintenance job
User-provided labels and annotations from maintenance JobConfigs
are now validated before being applied to the maintenance Job pod
template. Invalid label keys, label values, and annotation keys
are skipped with a warning log. This prevents the Kubernetes API
from rejecting the entire Job when a user provides labels or
annotations that violate naming rules.
Additionally, user-provided labels can no longer overwrite the
internal RepositoryNameLabel used for job tracking.
Fixes velero-io/velero#9981
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Add tests for label and annotation validation in maintenance job
Add test cases to TestBuildJob covering:
- Invalid label key is skipped
- Invalid label value is skipped
- Label value exceeding 63 characters is skipped
- User-provided label cannot overwrite RepositoryNameLabel
- Invalid annotation key is skipped
Also fix a latent test issue where param.BackupRepo was not reset
between test cases, and add the missing assertion for
expectedPodAnnotation which was defined but never checked.
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Fix gofmt formatting in maintenance test file
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
* Add changelog for PR #9982
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
---------
Signed-off-by: Shubham Pampattiwar <spampatt@redhat.com>
Added CLI for creating restore resource policies, and view
the resource policies associated with resource if present.
Only list the name of the configmap for now.
Signed-off-by: Adam Zhang <adam.zhang@broadcom.com>
* Add change-id and volume-id retrieve logic for both vks and vanilla k8s environment.
* Add change-id and volume-id support code in exposer.
Signed-off-by: Xun Jiang <xun.jiang@broadcom.com>
restore filters via resource policy, support ClusterScopedFilterPolicy
and NamespaceFilterPolicies.
Signed-off-by: Adam Zhang <adam.zhang@broadcom.com>
Add resourcePolicy field for restore CRD which is backed by
a configmap that holds ClusterScopedFilterPolicy and
NamespacedFilterPolicies for restore side filtering.
Signed-off-by: Adam Zhang <adam.zhang@broadcom.com>
Fixes a flaky test in TestWaitExecHandleHooks:
"should return no error with 2 spec hooks in 2 different containers,
1st container starts running after 10ms, 2nd container after 20ms,
both succeed"
Observed failure (CI run https://github.com/velero-io/velero/actions/runs/28119573625/job/83267758421):
mock: Unexpected Method Call
ExecutePodCommand called with resourceVersion:"3" (both containers running),
but mock was registered expecting resourceVersion:"2" (container1 running,
container2 still waiting).
Root cause: the two source.Modify calls were 10ms apart. The informer's
DeltaFIFO queue can coalesce rapid updates, delivering only the latest pod
state (resourceVersion:3) to the handler before the hook for container1 fires.
The comment "each of these states will be seen by the UpdateFunc handler" was
incorrect — intermediate states can be silently skipped under load.
Fix: add waitForSignal chan struct{} to the change struct and onCalled func()
to the expectedExecution struct. The goroutine now blocks after sending the
first change until the mock signals that the hook has fired (via close), then
sends the second change. This guarantees the handler observes the intermediate
pod state (resourceVersion:2) when executing container1's hook.
Signed-off-by: Lubron Zhan <lubronzhan@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract pkg/apis into a standalone Go module with its own go.mod/go.sum,
and wire it back into the main module via a local replace directive.
Signed-off-by: Lubron Zhan <lubronzhan@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Merge backup PV labels instead of wholesale replacement during restore finalization
Change patchDynamicPVWithVolumeInfo to merge backup labels into the
dynamically provisioned PV rather than overwriting its entire label map.
Labels already present on the new PV (e.g. topology labels set by the
provisioner) are preserved, and only missing labels from the backup are
added. This prevents stale topology labels from the source cluster from
overwriting correct values set by the target cluster's provisioner.
Update needPatch to only trigger when backup labels are absent from the
new PV, not when values differ — since differing values now intentionally
favour the dynamically provisioned PV.
Signed-off-by: Joseph <joseph@amazee.io>
Signed-off-by: Joseph <jvaikath@redhat.com>
* Add changelog
Signed-off-by: Joseph <jvaikath@redhat.com>
* Update changelog to reflect new approach
Signed-off-by: Joseph <joseph@amazee.io>
Signed-off-by: Joseph <jvaikath@redhat.com>
* Trigger CI rebuild
Signed-off-by: Joseph <joseph@amazee.io>
Signed-off-by: Joseph <jvaikath@redhat.com>
---------
Signed-off-by: Joseph <joseph@amazee.io>
Signed-off-by: Joseph <jvaikath@redhat.com>
* Add CONTAINER_TOOL variable to Makefile for podman support
Local development targets (shell, lint, build-image, clean, serve-docs)
hardcode `docker`, preventing developers who use podman from running
them. Add a CONTAINER_TOOL variable that defaults to `docker` and can
be overridden:
make lint CONTAINER_TOOL=podman
CI/release targets (container builds, manifest push, buildx instance
management) are left unchanged since they use Docker-specific features
like `docker buildx` and `docker manifest`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joseph <jvaikath@redhat.com>
* Add changelog for PR #9904
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joseph <jvaikath@redhat.com>
* Add guards to prevent podman on docker-only targets
Multi-arch image targets (container, push-manifest, etc.) require
docker buildx/manifest which podman does not support. Add explicit
guards that fail fast with a clear error message instead of producing
cryptic runtime failures.
Guarded targets: container, container-linux, container-windows,
push-manifest, push-build-image, and the buildx path in build-image.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joseph <jvaikath@redhat.com>
* Trigger CI rebuild
Signed-off-by: Joseph <jvaikath@redhat.com>
---------
Signed-off-by: Joseph <jvaikath@redhat.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces a concurrent-safe sync.Map cache to the backup Request struct
to memoize GetNamespaceFilter results. This avoids re-evaluating glob
patterns for every item, significantly improving backup performance while
preserving the original exact-match precedence logic.
Signed-off-by: Adam Zhang <adam.zhang@broadcom.com>