From 7f51017842db0e9377ef7b3a721b139e13714640 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Wed, 7 Jan 2026 17:01:49 +0800 Subject: [PATCH 01/90] block data mover design Signed-off-by: Lyndon-Li --- .../block-data-mover/backup-architecture.png | Bin 0 -> 510455 bytes design/block-data-mover/block-data-mover.md | 432 ++++++++++++++++++ design/block-data-mover/caos-extension.png | Bin 0 -> 530939 bytes design/block-data-mover/cbt.png | Bin 0 -> 385919 bytes .../block-data-mover/data-path-overview.png | Bin 0 -> 398164 bytes .../block-data-mover/restore-architecture.png | Bin 0 -> 487646 bytes design/block-data-mover/vgdp-backup.png | Bin 0 -> 559858 bytes design/block-data-mover/vgdp-restore.png | Bin 0 -> 516403 bytes 8 files changed, 432 insertions(+) create mode 100644 design/block-data-mover/backup-architecture.png create mode 100644 design/block-data-mover/block-data-mover.md create mode 100644 design/block-data-mover/caos-extension.png create mode 100644 design/block-data-mover/cbt.png create mode 100644 design/block-data-mover/data-path-overview.png create mode 100644 design/block-data-mover/restore-architecture.png create mode 100644 design/block-data-mover/vgdp-backup.png create mode 100644 design/block-data-mover/vgdp-restore.png diff --git a/design/block-data-mover/backup-architecture.png b/design/block-data-mover/backup-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..a5a50fe82aa9e217ad30a0fdf63adcb0f10b6d5d GIT binary patch literal 510455 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
FKtL9wJ9K7 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 Cf}(H$ literal 0 HcmV?d00001 diff --git a/design/block-data-mover/block-data-mover.md b/design/block-data-mover/block-data-mover.md new file mode 100644 index 0000000000..2a7d8c2d9d --- /dev/null +++ b/design/block-data-mover/block-data-mover.md @@ -0,0 +1,432 @@ +# Block Data Mover Design + +## Glossary & Abbreviation + +**Backup Storage**: The storage to store the backup data. Check [Unified Repository design][1] for details. +**Backup Repository**: Backup repository is layered between BR data movers and Backup Storage to provide BR related features that is introduced in [Unified Repository design][1]. +**Velero Generic Data Path (VGDP)**: VGDP is the collective of modules that is introduced in [Unified Repository design][1]. Velero uses these modules to finish data transfer for various purposes (i.e., PodVolume backup/restore, Volume Snapshot Data Movement). VGDP modules include uploaders and the backup repository. +**Velero Built-in Data Mover (VBDM)**: VBDM, which is introduced in [Volume Snapshot Data Movement design][2] and [Unified Repository design][1], is the built-in data mover shipped along with Velero, it includes Velero data mover controllers and VGDP. +**Data Mover Pods**: Intermediate pods which hold VGDP and complete the data transfer. See [VGDP Micro Service for Volume Snapshot Data Movement][3] for details. +**Change Block Tracking (CBT)**: CBT is the mechanism to track changed blocks, so that backups could back up the changed data only. CBT usually provides by the comupting/storage plateform. +**TCO**: Total Cost of Ownership. This is a general criteria for products/solutions, but also means a lot for BR solutions. For example, this means what kind of backup storage (and its cost) it requires, the retention policy of backup copies, the ways to remove backup data redundancy, etc. + +## Background +At present, [CSI Snapshot Data Movement][2] which is implemented by VBDM, ships a file system uploader, so the backup/restore is done from file system only. +However, once possible, block level backup/restore is better than file system level backup/restore: +- Block level backup could leverage CBT to process minimual size of data so significantly reduce the overhead to network, backup repository and backup storage. As a result, TCO is significantly reduced. +- Block level backup/restore is performant in throughput and resource consumption, because it doesn't need to handle the complexity of the file system, especially for the case that huge number of small files in the file system. +- Block level backup/restore is less OS dependent because the uploader doesn't need the OS to be aware of the file system in the volume. + +At present, [Kubernetes CBT API][4] is mature and close to Beta stage. Many plateform/storage has supported/is going to support it. + +Therefore, it is very important for Velero to deliver the block level backup/restore and recommend users to use it over the file system data mover as long as: +- The volume is backed by block storage so block level access is possible +- The plateform supports CBT + +Meanwhile, file system data mover is still valuable for below scenarios: +- The volume is backed by file storage, e.g., AWS EFS, Azure File, CephFS, VKS File Volume, etc. +- The volume is backed by block storage but CBT is not available +- The volume doesn't support CSI snapshot, so Velero fs-backup method is used + +There are rich features delivered with VGDP, VBDM and [VGDP micro service][3], to reuse these features, block data mover should be built based on these modules. + +Velero VBDM supports linux and Windows nodes, however, Windows container doesn't support block mode volumes, so backing up/restoring from Windows nodes is not supported until Windows container removes this limitation. As a result, if there are both linux and Windows nodes in the cluster, block data mover can only run in linux nodes. + +## Goals + +Add a block data mover to VBDM and support block level backup/restore for [CSI Snapshot Data Movement][2], which includes: +- Support block level full backup for both `FileSystem` and `Block` mode volumes +- Support block level incremental backup for both `FileSystem` and `Block` mode volumes +- Support block level restore from full/incremental backup for both `FileSystem` and `Block` mode volumes +- Support block level backup/restore for both linux and Windows workloads +- Support all existing features, i.e., load concurrency, node selection, cache volume, deduplication, compression, encryption, etc. for the block data mover + +## Non-Goals + +- fs-backup does the backup/restore from file system level only, so block level backup/restore is not supported +- Volumes that are backed by file system storages, can only be backed up/restored from file system level, so block level backup/restore is not supported +- Backing up/restoring from Windows nodes is not supported +- Block level incremental backup requires special capabilities of the backup repository, and Velero [Unified Repository][1] supports multiple kinds of backup repositories. The current design focus on Kopia repository only, block level incremental backup support of other repositories will be considered when the specific backup repository is integrated to [Velero Unified Repository][1] + +## Architecture + +### Data Path + +Below shows the architecture of VGDP when integrating to Unified Repository (implemented by Kopia repository). +A new block data mover will be added besides the existing file system data mover, the both data movers read/write data from/to the same backup repository through Unified Repo interface. +Unified Repo interface and the backup repository needs to be enhanced to support incremental backups. + +![Data path overview](data-path-overview.png) + +### Backup + +Below is the architecture for block data mover backup which is developed based on the existing VBDM: + +![Backup architecture](backup-architecture.png) + +Below are the major changes based on the existing VBDM: +**Exposer**: Exposer needs to create block mode backupPVC all the time regardless of the sourcePVC mode. +**CBT**: This is a new layer to retrieve, transform and store the changed blocks, it interacts with CSI SnapshotMetadataService through gRPC. +**Uploader**: A new block uploader is added. It interacts with CBT layer, holds special logics to make performant data read from block devices and holds special logics to write incremental data to Unified Repository. +**Extended Kopia repo**: A new Incremental Aware Object Extension is added to Kopia's CAOS, so as to support incremental data write. + +### Restore + +Below is architecture for block data mover restore which is developed based on the existing VBDM: + +![Restore architecture](restore-architecture.png) + +Below are the major changes based on the existing VBDM: +**Exposer**: While the restorePV is in block mode, exposer needs to rebind the restorePV to a targetPVC in either file system mode or block mode. +**Uploader**: The same block uploader holds special logics to make performant data write to block devices and holds special logics to read data from the backup chain in Unified repository. + +## Detailed Design + +### Selectable Data Mover Type +At present, the backup accepts a `DataMover` parameter and when its value is empty or `velero`, VBDM is used. +After block data mover is introduced, VBDM will have two types of data movers, Velero file system data mover and Velero block data mover. +A new type string `velero-block` is introduced for Velero block data mover, that is, when `DataMover` is set as `velero-block`, Velero block data mover is used. +Another new value `velero-fs` is introduced for Velero file system data mover, that is, when `DataMover` is set as `velero-fs`, Velero file system data mover is used. +For backwards compatibility consideration, `velero` is preserved a valid value, it refers to the default data mover, and the default data mover may change among releases. +When `DataMover` is empty or `velero`, the default data mover is used. At present, Velero file system data mover is the default data mover; we can change the default one to Velero block data mover in future releases. + +### Controllers +Backup controller and Restore controller are kept as is, async operations are still used to interact with VBDM with block data mover. +DataUpload controller and DataDownload controller are almost kpet as is, with some minor changes to handle the data mover type and backup type appropriately and convey it to the exposers. With [VGDP Micro Service][3], the controllers are almost isolated from VGDP, so no major changes are required. + +### Exposer + +#### CSI Snapshot Exposer +The existing CSI Snapshot Exposer is reused with some changes to decide the backupPVC volume mode by access mode. Specifically, for Velero block data mover, access mode is always `Block`, so the backupPVC volume mode is always `Block`. +Once the backupPVC is created with correct volume mode, the existing code could create the backupPod and mount the backupPVC appropriately. + +#### Generic Restore Exposer +The existing Generic Restore Exposer is reused, but the workflow needs some changes. +For block data mover, the restorePV is in Block mode all the time, whereas, the targetPVC may be in either file system mode or block mode. +However, Kubernetes doesn't allow to bound a PV to a PVC with mismatch volume mode. + +Therefore, the workflow of ***Finish Volume Readiness*** as introduced in [Volume Snapshot Data Movement design][2] is changed as below: +- When restore completes and restorePV is created, set restorePV's `deletionPolicy` to `Retain` +- Create another rebindPV and copy restorePV's `volumeHandle` +- Delete restorePV +- Set the rebindPV's claim reference (the ```claimRef``` filed) to targetPVC +- Add the ```velero.io/dynamic-pv-restore``` label to the rebindPV + +In this way, the targetPVC will be bound immediately by Kubernetes to rebindPV. + +These changes work for file system data mover as well, so the old workflow will be replaced, only the new workflow is kept. + +### VGDP + +Below is the VGDP workflow during backup: + +![VGDP Backup](vgdp-backup.png) + +Below is the VGDP workflow during restore: + +![VGDP Restore](vgdp-restore.png) + +#### Unified Repo +For block data mover, one Unified Repo Object is created for each volume, and some metadata is also saved into Unified Repo to describe the volume. +During the backup, the write conducts a skippable-write manner: +- For the data range that the write does not skip, object is written with the real data +- For the data range that is skipped, the data is either filled as ZERO or cloned from the parent object. Specifically, for a full backup, data is filled as ZERO; for an incremental backup, data is cloned from the parent object + +To support incremental backup, `ObjectWriter` interface needs to extend to support `io.WriterAt`, so that uploader could conduct a skippable-write manner: +```go +type ObjectWriter interface { + io.WriteCloser + io.WriterAt + + // Seeker is used in the cases that the object is not written sequentially + io.Seeker + + // Checkpoint is periodically called to preserve the state of data written to the repo so far. + // Checkpoint returns a unified identifier that represent the current state. + // An empty ID could be returned on success if the backup repository doesn't support this. + Checkpoint() (ID, error) + + // Result waits for the completion of the object write. + // Result returns the object's unified identifier after the write completes. + Result() (ID, error) +} +``` + +To clone data from parent object, the caller needs to specify the parent object. To support this, `ObjectWriteOptions` is extended with `ParentObject`. +The existing `AccessMode` could be used to indicate the data access type, either file system or block: + +```go +// ObjectWriteOptions defines the options when creating an object for write +type ObjectWriteOptions struct { + FullPath string // Full logical path of the object + DataType int // OBJECT_DATA_TYPE_* + Description string // A description of the object, could be empty + Prefix ID // A prefix of the name used to save the object + AccessMode int // OBJECT_DATA_ACCESS_* + BackupMode int // OBJECT_DATA_BACKUP_* + AsyncWrites int // Num of async writes for the object, 0 means no async write + ParentObject ID // the parent object based on which incremental write will be done +} +``` + +To support non-Kopia uploader to save snapshots to Unified Repo, snapshot related methods will be added to `BackupRepo` interface: +```go + // SaveSnapshot saves a repo snapshot + SaveSnapshot(ctx context.Context, snapshot Snapshot) (ID, error) + + // GetSnapshot returns a repo snapshot from snapshot ID + GetSnapshot(ctx context.Context, id ID) (Snapshot, error) + + // DeleteSnapshot deletes a repo snapshot + DeleteSnapshot(ctx context.Context, id ID) error + + // ListSnapshot lists all snapshots in repo for the given source (if specified) + ListSnapshot(ctx context.Context, source string) ([]Snapshot, error) +``` + +To support non-Kopia uploader to save metadata, which is used to describe the the backed up objects, some metadata related methods will be added to `BackupRepo` interface: +```go + // WriteMetadata writes metadata to the repo, metadata is used to describe data, e.g., file system + // dirs are saved as metadata + WriteMetadata(ctx context.Context, meta *Metadata, opt ObjectWriteOptions) (ID, error) + + // ReadMetadata reads a metadata from repo by the metadata's object ID + ReadMetadata(ctx context.Context, id ID) (*Metadata, error) +``` + +kopia-lib for Unified Repo will implement these interfaces by calling the corresponding Kopia repository functions. + +### Kopia Repository +CAOS of Kopia repository implements Unfied Repo's Objects. However, CAOS supports full and sequential write only. +To make it support skippable write, a new Incremental Aware Object Extension is created based on the existing CAOS. + +#### Block Address Table +Kopia CAOS uses Block Address Table (BAT) to track objects. It will be reused for both full backups and incremental backups. + +![Incremental Aware Object Extension](caos-extension.png) + +For Incremental Aware Object Extension, one object represents one volume. +For full backup, the skipped areas will be written as all ZERO by Incremental Aware Object Extension, since Kopia repository's interface doesn't support skippable write. But it is fine, the ZERO data will be deduplicated by Kopia repository so nothing is actually written to the backup storage. +For incremental backup, Incremental Aware Object Extension clones the table entries from the parent object for the skipped areas; for the written area, Incremental Aware Object Extension writes the data to Kopia repository and generate new entries. Finally, Incremental Aware Object Extension generates a new block address table for the incremental object which covers its entire logical space. + +Incremental Aware Object Extension is automatically activated for block mode data access as set by `AccessMode` of `ObjectWriteOptions`. + +#### Deduplication +The Incremental Aware Object Extension uses fix-sized splitter for deduplication, this is good enough for block level backup, reasons: +- Not like a file, a disk write never inserts data to the middle of the disk, it only does in-place update or append. So the data never shifts between two disks or the same disk of two different backups +- File system IO to disk general aligned to a specific size, e.g., 4KB for NTFS and ext4, as long as the chunk size is a multiply of this size, it effectively reduces the case that one IO kills two deduplication chunks +- For the usage cases that the disk is used as raw block device without a file system, the IO is still conducted by aligning to a specific boundary + +The chunk size is intentionally chosen as 1MB, reasons: +- 1MB is a multiply of 4KB for file systems or common block sizes for raw block device usages +- 1MB is the start boundary of partitions for modern operating systems, for both MBR and GPT, so partition metadata could be isolated to a separate chunk +- The more chunks are there, the more indexes in the repository, 1MB is a modreate value regarding to the overhead of indexes for Kopia repository + +#### Benefits +Since the existing block address table(BAT) of CAOS is reused and kept as is, it brings below benefits: +- All the entries are still managed by Kopia CAOS, so Velero doesn't need to keep an extra data +- The objects written by Velero block uploader is still recgnozible by Kopia, for both full backup and incremental backup +- The existing data management in Kopia repository still works for objects generated by Velero block uploader, e.g., snapshot GC, repository maintenance, etc. + +Most importantly, this solution is super perfromant: +- During incremental write, it doesn't copy any data from the parent object, instead, it only clones object block address entries +- During backup deletion, it doesn't need to move any data, it only deletes the BAT for the object + +#### Uploader behavior +The block uploader's skippable write must also be aligned to this 1MB boundary, because Incremental Aware Object Extension needs to clone the entries that have been skipped from the parent object. +File system uploader is still using variable-sized deduplication, it is fine to keep data from the two uploaders into the same Kopia repository, though normally they won't be mutrally deduplicated. +Volume could be resized; and volume size may not be aligned to 1MB boundary. The uploader need to handle the resize appropriately since Incremental Aware Object Extension cannot copy a BAT entry partially. + +#### CBT Layer +CBT provides below functionalities: +1. For a full backup, it provides the allocated data ranges. E.g., for a 1TB volume, there may be only 1MB of files, with this functionality, the uploader could skip the ranges without real data +2. For an incremental backup, it provides the changed data ranges based on the provided parent snapshot. In this way, the uploader could skip the unchanged data and achieves an incremental backup + +For case 1, the uploader calls Unfied Repo Object's `WriteAt` method with the offset for the allocated data, ranges ahead of the offset will be filled as ZERO by unified repository. +For case 2, the uploader calls Unfied Repo Object's `WriteAt` method with the offset for the changed data, ranges ahead of the offset will be cloned from the parent object unified repository. + +A changeId is stored with each backup, the next backup will retrieve the parent snapshot's changeId and use it to retrieve the CBT. + +The CBT retrieved from Kubernetes API are a list of `BlockMetadata`, each of range could be with fixed size or variable size. +Block uploader needs to maintain its own granularity that is friendly to its backup repository and uploader, as mentioned above. + +From Kubernetes API, `GetMetadataAllocated` or `GetMetadataDelta` are called looply until all `BlockMetadata` are retrieved. +On the other hand, considering the complexity in uploader, e.g., multiple stream between read and write, the workflow should be driven by the uploader instead of the CBT iterator, therefore, in practice, all the allocated/changed blocks should be retrieved and preserved before passing it to the uploader. + +As another fact, directly saving `BlockMetadata` list will be memory consuming. + +With all the above considerations, the `Bitmap` data structure is used to save the allocated/changed blocks, calling CBT Bitmap. +CBT Bitmap chunk size could be set as 1MB or a multiply of it, but a larger chunk size would amplify the backup size, so 1MB size will be use. + +Finally, interactions among CSI Snapshot Metadata Service, CBT Layer and Uploader is like below: + +![CBT Layer](cbt.png) + +In this way, CBT layer and uploader are decoupled and CBT bitmap plays as a north bound parameter of the uploader. + +#### Block Uploader +Block uploader consists of the reader and writer which are running asynchronously. +During backup, reader reads data from the block device and also refers to CBT Bitmap for allocated/changed blocks; writer writes data to the Unified Repo. +During restore, reader reads data from the Unified Repo; writer writes data to the block device. +Reader and writer connects by a ring buffer, that is, reader pushs the block data to the ring buffer and writer gets data from the ring buffer and write to the target. + +To improve performance, block device is opened with direct IO, so that no data is going through the system cache unnecessarily. + +Uploader implementation is OS dependent, but since Windows container doesn't support block volumes, the current implementation is for linux only. + +#### ChangeId +ChangeId identifies the base that CBT is generated from, it must strictly map to the parent snapshot in the repository. Otherwise, there will be data corruption in the incremental backup. +Therefore, ChangeId is saved together with the repository snapshot. +The data mover always queries parent snapshot from Unified Repo together with the ChangeId. In this way, no mismatch would happen. +Inside the uploader, the upper layer (DataUpload controller) could also provide the ChangeId as a mechanism of double confirmation. The received ChangeId would be re-evaluated against the one in the provided snapshot. + +#### Incremental Size +By the end of the backup, incremental size is also returned by the uploader, as same as Velero file system uploader. The size indicates how much data are unquie so processed by the uploader, based on the provided CBT. + +### Fallback to Full Backup +There are some occasions that the incremental backup won't continue, so the data mover fallbacks to full backup: +- `GetMetadataAllocated` or `GetMetadataDelta` returns error +- ChangeId is missing +- Parent snapshot is missing + +### Volume Size Change +Incremental backup could continue when volume is resized. +Block uploader supports to write disk with arbibrary size. +When volume resize happens, block uploader needs to handle it appropriately in below ways: +- The new boundary should always be Max(oldSize, newSize) +- Always rewrite the tail between RoundDownTo1M(newSize) and newSize + +That is to say, the tail must be rewrite since Incremental Aware Object Extension cannot copy BAT entries halfly for the incremental backup. + +### Cancellation +The existing Cancellation mechanism is reused, so there is no change outside of the block uploader. +Inside the uploader, cancellation checkpoints are embedded to the uploader reader and writer, so that the execution could quit in a reasonable time once cancellation happens. + +### Parallelism +Parallelism among data movers will reuse the existing mechanism --- load concurrency. +Inside the data mover, uploader reader and writer are always running in parallel. The number of reader and writer is always 1. +Sequaltial read/write of the volume is always optimized, there is no prove that multiple readers/writers are beneficial. + +### Progress Report +Progress report outside of the data mover will reuse the existing mechanism. +Innside the data mover, progress update is embedded to the uploader writer. +The progress struct is kept as is, Velero block data mover still supports `TotalBytes` and `BytesDone`: +```go +type Progress struct { + TotalBytes int64 `json:"totalBytes,omitempty"` + BytesDone int64 `json:"doneBytes,omitempty"` +} +``` + +### Selectable Backup Type +For many reasons, a periodical full backup is required: +- From user experience, a periodical full is required to make sure the data integrity among the incremental backups, e.g., every 1 week or 1 month + +Therefore, backup type (full/incremental) should be supported in Velero's manual backup and backup schedule. +Backup type will also be added to `volumeInfo.json` to support observability purposes. + +Backup TTL is still used for users to specify a backup's retention time. By default, both full and incremetnal backups are with 30 days retention, even though this is not so reasonable for the full backups. This could be enhanced when Velero supports sophisticated retention policy. +As a workaround, users could create two schedules for the same scope of backup, one is for full backups, with less frequency and longer backup TTL; the other one is for incremental backups, with normal frequency and shorter backup TTL. + +#### File System Data Mover +At present, Velero file system data mover doesn't support selectable backup type, instead, incremental backups are always conducted once possible. +From user experience this is not reasonable. + +Therefore, to solve this problem and to make it align with Velero block data mover, Velero file system data mover will support backup type as well. + +At present, the data path for Velero file system data mover has already supported it, we only need to expose this functionality to users. + +### Data Mover Selection +At present, in the Backup CRD, there is a `DataMover` field for users to specify the data mover to be used. This field will be kept, once it is set, all the data movements in the backup will use the specified data mover. + +However, this is not enough. In one backup, users may include volumes backed by both block storage and file system storage. +To meet this requirement, VolumePolicy will be enhanced to support the `DataMover` action. + +The selected data mover for each volume should be updated to `volumeInfo.json`. + +### Backup Describe +Backup type should be added to backup description, this value could be retrieved from `volumeInfo.json`. +The `DataMover` item in the existing backup description should be updated to reflect the actual data mover completing the backup, this information could be retrieved from `volumeInfo.json`. + +### Backup Sync +No more data is required for sync, so Backup Sync is kept as is. + +### Backup Deletion +As mentioned above, no data is moved when deleting a repo snapshot for Velero block data mover, so Backup Deletion is kept as is. + +### Restarts +Restarts mechanism is reused without any change. + +### Logging +Logging mechanism is not changed. + +### Backup CRD +A `backupType` field is added to Backup CRD, three values are supported `""`, `full` or `incremental`. +`full` indicates the data mover to take a full backup. +`""` fallbacks to `incremental` which indicates the data mover to take an incremental backup. + +```yaml + spec: + description: BackupSpec defines the specification for a Velero backup. + properties: + backupType: + description: BackupType indicates the type of the backup + enum: + - full + - incremental + - "" + type: string +``` + +### DataUpload CRD +A `parentSnapshot` field is added to the DataUpload CRD, below values are supported: +- `""`: it fallbacks to `auto` +- `auto`: it means the data mover finds the recent snapshot of the same volume from Unified Repository and use it as the parent +- `none`: it means the data mover is not assigned with a parent snapshot, so it runs a full backup +- a specific snapshotID: it means the data mover use the specific snapshotID to find the parent snapshot. If it cannot be found, the data mover fallbacks to a full backup + +The last option is for a backup plan, it will not be used for now and may be useful when Velero supports sophisticated retention policy. This means, Velero always finds the recent backup as the parent. + +When `backupType` of the Backup is `full`, the data mover controller sets `none` to `parentSnapshot` of DataUpload. +When `backupType` of the Backup is `incremental`, the data mover controller sets `auto` to `parentSnapshot` of DataUpload. And `""` is just kept for backwards compatibility consideration. + +```yaml + spec: + description: DataUploadSpec is the specification for a DataUpload. + properties: + parentSnapshot: + description: |- + ParentSnapshot specifies the parent snapshot that current backup is based on. + If its value is "" or "auto", the data mover finds the recent backup of the same volume as parent. + If its value is "none", the data mover will do a full backup + If its value is a specific snapshotID, the data mover finds the specific snapshot as parent. + type: string +``` + +### DataDownload CRD +No change is required to DataDownload CRD. + +## Plugin Data Movers +The current design doesn't break anything for plugin data movers. +The enhancement in VolumePolicy could also be used for plugin data movers. That is, users could select a plugin data mover through VolumePolicy as same as Velero built-in data movers. + +## Installation +No change to Installation. + +## Upgrade +No impacts to Upgrade. The new fields in the CRDs are all optional fields and have backwards compatible values. + +## CLI +Backup type parameter is added to Velero CLI as below: +``` +velero backup create --full +velero schedule create --full +``` +When the parameter is not specified, by default, Velero goes with incremental backups. + + + +[1]: Implemented/unified-repo-and-kopia-integration/unified-repo-and-kopia-integration.md +[2]: Implemented/volume-snapshot-data-movement/volume-snapshot-data-movement.md +[3]: Implemented/vgdp-micro-service/vgdp-micro-service.md +[4]: https://kubernetes.io/blog/2025/09/25/csi-changed-block-tracking/ \ No newline at end of file diff --git a/design/block-data-mover/caos-extension.png b/design/block-data-mover/caos-extension.png new file mode 100644 index 0000000000000000000000000000000000000000..928c1e352210dadda76988a4d0f5d123d7944709 GIT binary patch literal 530939 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

SuZV_%|4j?dhQ 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 literal 0 HcmV?d00001 diff --git a/design/block-data-mover/cbt.png b/design/block-data-mover/cbt.png new file mode 100644 index 0000000000000000000000000000000000000000..f20d287c2db90adffe6b84757b37883474666fa8 GIT binary patch literal 385919 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 z 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�bDN@W43W?Ekn_YzwgY)c$n47l)6g;;#}PbR45rYuWUe7A13cWlYA+l(iP&u>~+SJB#Z@0^wbhIcM%*wcrJorT`LRxoxPM?QqoDwGtC|-(U zVB@LtQk}FeB1#;OkAiQ%{nqSq@OU+SS3M<;@48$YoC*Y#IH^EU%kUinN*v#Hxi&Z) z0*S^caS}yLM?UNE87jPNImZydn@lAdl@6t5&TFoa%o?KoN+A09=7H zdFRV|CLuJ9RL6T21!IgR09CY W8W=B^>E@~c0000SWpYe+ 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 literal 0 HcmV?d00001 From a23092911172c8a69f9ac40f7f123eac943b70e9 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Fri, 6 Feb 2026 18:22:36 +0800 Subject: [PATCH 02/90] block data mover design Signed-off-by: Lyndon-Li --- changelogs/unreleased/9528-Lyndon-Li | 1 + design/block-data-mover/block-data-mover.md | 141 +++++++++++++++----- 2 files changed, 112 insertions(+), 30 deletions(-) create mode 100644 changelogs/unreleased/9528-Lyndon-Li diff --git a/changelogs/unreleased/9528-Lyndon-Li b/changelogs/unreleased/9528-Lyndon-Li new file mode 100644 index 0000000000..52bb4a8f33 --- /dev/null +++ b/changelogs/unreleased/9528-Lyndon-Li @@ -0,0 +1 @@ +Add block data mover design for block level incremental backup by integrating with Kubernetes CBT \ No newline at end of file diff --git a/design/block-data-mover/block-data-mover.md b/design/block-data-mover/block-data-mover.md index 2a7d8c2d9d..28bdc7b11b 100644 --- a/design/block-data-mover/block-data-mover.md +++ b/design/block-data-mover/block-data-mover.md @@ -7,23 +7,29 @@ **Velero Generic Data Path (VGDP)**: VGDP is the collective of modules that is introduced in [Unified Repository design][1]. Velero uses these modules to finish data transfer for various purposes (i.e., PodVolume backup/restore, Volume Snapshot Data Movement). VGDP modules include uploaders and the backup repository. **Velero Built-in Data Mover (VBDM)**: VBDM, which is introduced in [Volume Snapshot Data Movement design][2] and [Unified Repository design][1], is the built-in data mover shipped along with Velero, it includes Velero data mover controllers and VGDP. **Data Mover Pods**: Intermediate pods which hold VGDP and complete the data transfer. See [VGDP Micro Service for Volume Snapshot Data Movement][3] for details. -**Change Block Tracking (CBT)**: CBT is the mechanism to track changed blocks, so that backups could back up the changed data only. CBT usually provides by the comupting/storage plateform. +**Change Block Tracking (CBT)**: CBT is the mechanism to track changed blocks, so that backups could back up the changed data only. CBT usually provides by the comupting/storage platform. **TCO**: Total Cost of Ownership. This is a general criteria for products/solutions, but also means a lot for BR solutions. For example, this means what kind of backup storage (and its cost) it requires, the retention policy of backup copies, the ways to remove backup data redundancy, etc. ## Background -At present, [CSI Snapshot Data Movement][2] which is implemented by VBDM, ships a file system uploader, so the backup/restore is done from file system only. -However, once possible, block level backup/restore is better than file system level backup/restore: -- Block level backup could leverage CBT to process minimual size of data so significantly reduce the overhead to network, backup repository and backup storage. As a result, TCO is significantly reduced. +Kubernetes supports two kinds of volume mode, `FileSystem` and `Block`, for persistent volumes. Underlyingly, the storage could use a block storage to provision either `FileSystem` mode or `Block` mode volumes; and the storage could use a file storage to provision `FileSystem` mode volumes. +For volumes provisioned by block storage, they could be backed up/restored from the block level, regardless the volume mode of the persistent volume. +On the other hand, as long as the data could be accessed from the file system, a backup/restore could be conducted from the file system level. That is to say `FileSystem` mode volumes could be backed up/restored from the file system level, regardless of the backend storage type. +Then if a `FileSystem` mode volume is provisioned by a block storage, the volume could be backed up/restored either from the file system level or block level. + +For Velero, [CSI Snapshot Data Movement][2] which is implemented by VBDM, ships a file system uploader, so the backup/restore is done from file system only. + +Once possible, block level backup/restore is better than file system level backup/restore: +- Block level backup could leverage CBT to process minimal size of data, so it significantly reduces the overhead to network, backup repository and backup storage. As a result, TCO is significantly reduced. - Block level backup/restore is performant in throughput and resource consumption, because it doesn't need to handle the complexity of the file system, especially for the case that huge number of small files in the file system. - Block level backup/restore is less OS dependent because the uploader doesn't need the OS to be aware of the file system in the volume. -At present, [Kubernetes CBT API][4] is mature and close to Beta stage. Many plateform/storage has supported/is going to support it. +At present, [Kubernetes CBT API][4] is mature and close to Beta stage. Many platform/storage has supported/is going to support it. Therefore, it is very important for Velero to deliver the block level backup/restore and recommend users to use it over the file system data mover as long as: - The volume is backed by block storage so block level access is possible -- The plateform supports CBT +- The platform supports CBT -Meanwhile, file system data mover is still valuable for below scenarios: +Meanwhile, file system level backup/restore is still valuable for below scenarios: - The volume is backed by file storage, e.g., AWS EFS, Azure File, CephFS, VKS File Volume, etc. - The volume is backed by block storage but CBT is not available - The volume doesn't support CSI snapshot, so Velero fs-backup method is used @@ -32,6 +38,8 @@ There are rich features delivered with VGDP, VBDM and [VGDP micro service][3], t Velero VBDM supports linux and Windows nodes, however, Windows container doesn't support block mode volumes, so backing up/restoring from Windows nodes is not supported until Windows container removes this limitation. As a result, if there are both linux and Windows nodes in the cluster, block data mover can only run in linux nodes. +Both the Kubernetes CBT service and Velero work in the boundary of the cluster, even though the backend storage may be shared by multiple clusters, Velero can only protection workloads in the same cluster where it is running. + ## Goals Add a block data mover to VBDM and support block level backup/restore for [CSI Snapshot Data Movement][2], which includes: @@ -40,6 +48,7 @@ Add a block data mover to VBDM and support block level backup/restore for [CSI S - Support block level restore from full/incremental backup for both `FileSystem` and `Block` mode volumes - Support block level backup/restore for both linux and Windows workloads - Support all existing features, i.e., load concurrency, node selection, cache volume, deduplication, compression, encryption, etc. for the block data mover +- Support volumes processed from file system level and block level in the same backup/restore ## Non-Goals @@ -83,16 +92,69 @@ Below are the major changes based on the existing VBDM: ## Detailed Design ### Selectable Data Mover Type + +#### Per Backup Selection At present, the backup accepts a `DataMover` parameter and when its value is empty or `velero`, VBDM is used. After block data mover is introduced, VBDM will have two types of data movers, Velero file system data mover and Velero block data mover. A new type string `velero-block` is introduced for Velero block data mover, that is, when `DataMover` is set as `velero-block`, Velero block data mover is used. Another new value `velero-fs` is introduced for Velero file system data mover, that is, when `DataMover` is set as `velero-fs`, Velero file system data mover is used. -For backwards compatibility consideration, `velero` is preserved a valid value, it refers to the default data mover, and the default data mover may change among releases. -When `DataMover` is empty or `velero`, the default data mover is used. At present, Velero file system data mover is the default data mover; we can change the default one to Velero block data mover in future releases. +For backwards compatibility consideration, `velero` is preserved a valid value, it refers to the default data mover, and the default data mover may change among releases. At present, Velero file system data mover is the default data mover; we can change the default one to Velero block data mover in future releases. + +#### Volume Policy +It is a valid case that users have multiple volumes in a single backup, while they want to use Velero file system data mover for some of the volumes and use Velero block data mover for some others. +To meet this requirement, a combined solution of Per Backup Selection and Volume Policy is used. + +Here are the data structs for VolumePolicy: +```go +type volPolicy struct { + action Action + conditions []volumeCondition +} + +type volumeCondition interface { + match(v *structuredVolume) bool + validate() error +} + +type structuredVolume struct { + capacity resource.Quantity + storageClass string + nfs *nFSVolumeSource + csi *csiVolumeSource + volumeType SupportedVolume + pvcLabels map[string]string + pvcPhase string +} + +type Action struct { + Type VolumeActionType `yaml:"type"` + Parameters map[string]any `yaml:"parameters,omitempty"` +} + +const ( + ConfigmapRefType string = "configmap" + Skip VolumeActionType = "skip" + FSBackup VolumeActionType = "fs-backup" + Snapshot VolumeActionType = "snapshot" +) +``` + +`action.parameters` is used to provide extra information of the action. This is an ideal place to differentate Velero file system data mover and Velero block data mover. +Therefore, Velero built-in data mover will support `dataMover` key in `parameters`, with the value either `velero-fs` or `velero-block`. While `velero-fs` and `velero-block` are with the same meaning with Per Backup Selection. + +As an example, here is how a user might use both `velero-block` and `velero-fs` in a single backup: +- Users set `DataMover` parameter for the backup as `velero-block` +- Users add a record into Volume Policy, make `conditions` to filter the volumes they want to backup through Velero file system data mover, make `action.type` as `snapshot` and insert a record into `action.parameter` as `dataMover:velero-fs` + +In this way, all volumes matched by `conditions` will be backed up with Velero file system data mover; while the others will fallback to the per backup method Velero block data mover. + +Vice versa, users could set the per backup method as file system data mover and select volumes for Velero block data mover. + +The selected data mover for each volume should be recorded to `volumeInfo.json`. ### Controllers Backup controller and Restore controller are kept as is, async operations are still used to interact with VBDM with block data mover. -DataUpload controller and DataDownload controller are almost kpet as is, with some minor changes to handle the data mover type and backup type appropriately and convey it to the exposers. With [VGDP Micro Service][3], the controllers are almost isolated from VGDP, so no major changes are required. +DataUpload controller and DataDownload controller are almost kept as is, with some minor changes to handle the data mover type and backup type appropriately and convey it to the exposers. With [VGDP Micro Service][3], the controllers are almost isolated from VGDP, so no major changes are required. ### Exposer @@ -107,7 +169,7 @@ However, Kubernetes doesn't allow to bound a PV to a PVC with mismatch volume mo Therefore, the workflow of ***Finish Volume Readiness*** as introduced in [Volume Snapshot Data Movement design][2] is changed as below: - When restore completes and restorePV is created, set restorePV's `deletionPolicy` to `Retain` -- Create another rebindPV and copy restorePV's `volumeHandle` +- Create another rebindPV and copy restorePV's `volumeHandle` but the `volumeMode` matches to the targetPVC - Delete restorePV - Set the rebindPV's claim reference (the ```claimRef``` filed) to targetPVC - Add the ```velero.io/dynamic-pv-restore``` label to the rebindPV @@ -184,7 +246,7 @@ To support non-Kopia uploader to save snapshots to Unified Repo, snapshot relate ListSnapshot(ctx context.Context, source string) ([]Snapshot, error) ``` -To support non-Kopia uploader to save metadata, which is used to describe the the backed up objects, some metadata related methods will be added to `BackupRepo` interface: +To support non-Kopia uploader to save metadata, which is used to describe the backed up objects, some metadata related methods will be added to `BackupRepo` interface: ```go // WriteMetadata writes metadata to the repo, metadata is used to describe data, e.g., file system // dirs are saved as metadata @@ -220,12 +282,12 @@ The Incremental Aware Object Extension uses fix-sized splitter for deduplication The chunk size is intentionally chosen as 1MB, reasons: - 1MB is a multiply of 4KB for file systems or common block sizes for raw block device usages - 1MB is the start boundary of partitions for modern operating systems, for both MBR and GPT, so partition metadata could be isolated to a separate chunk -- The more chunks are there, the more indexes in the repository, 1MB is a modreate value regarding to the overhead of indexes for Kopia repository +- The more chunks are there, the more indexes in the repository, 1MB is a moderate value regarding to the overhead of indexes for Kopia repository #### Benefits Since the existing block address table(BAT) of CAOS is reused and kept as is, it brings below benefits: - All the entries are still managed by Kopia CAOS, so Velero doesn't need to keep an extra data -- The objects written by Velero block uploader is still recgnozible by Kopia, for both full backup and incremental backup +- The objects written by Velero block uploader is still recognizable by Kopia, for both full backup and incremental backup - The existing data management in Kopia repository still works for objects generated by Velero block uploader, e.g., snapshot GC, repository maintenance, etc. Most importantly, this solution is super perfromant: @@ -234,7 +296,7 @@ Most importantly, this solution is super perfromant: #### Uploader behavior The block uploader's skippable write must also be aligned to this 1MB boundary, because Incremental Aware Object Extension needs to clone the entries that have been skipped from the parent object. -File system uploader is still using variable-sized deduplication, it is fine to keep data from the two uploaders into the same Kopia repository, though normally they won't be mutrally deduplicated. +File system uploader is still using variable-sized deduplication, it is fine to keep data from the two uploaders into the same Kopia repository, though normally they won't be mutually deduplicated. Volume could be resized; and volume size may not be aligned to 1MB boundary. The uploader need to handle the resize appropriately since Incremental Aware Object Extension cannot copy a BAT entry partially. #### CBT Layer @@ -280,6 +342,32 @@ Therefore, ChangeId is saved together with the repository snapshot. The data mover always queries parent snapshot from Unified Repo together with the ChangeId. In this way, no mismatch would happen. Inside the uploader, the upper layer (DataUpload controller) could also provide the ChangeId as a mechanism of double confirmation. The received ChangeId would be re-evaluated against the one in the provided snapshot. +For Kubernetes API, changeId is represented by `BaseSnapshotId`. +changeId retrieval is storage specific, generally, it is retrieved from the `SnapshotHandle` of the VolumeSnapshotContent object; however, storages may also refer to other places to retrieve the changeId. +That is, `SnapshotHandle` and changeId may be two different values, in this case, the both values need to be preserved. + +#### Volume Snapshot retention +Storages/CSI drivers may support the changeId differently based on the storage's capabilities: +1. In order to calculate the changes, some storages require the parent snapshot mapping to the changeId always exists at the time of `GetMetadataDelta` is called, then the parent snapshot can NOT be deleted as long as there are incremental backups based on it. +2. Some storages don't require the parent snapshot itself at the time of calculating changes, then parent snapshot could be deleted immediately after the parent backup completes. + +The existing exposer works perfectly with Case 1, that is, the snapshot is always deleted when the backup completes. +However, for Case 2, since the snapshot must be retained, the exposer needs changes as below: +- At the end of each backup, keep the current VolumeSnapshot's `deletionPolicy` as `Retain`, then when the VolumeSnapshot is deleted at the end of the backup, the cureent snapshot is retained in the storage +- `GetMetadataDelta` is called with `BaseSnapshotId` set as the preserved changeId +- When deleting a backup, a VolumeSnapshot-VolumeSnapshotContent pair is rebuilt with `deletionPolicy` as `delete` and `snapshotHandle` as the preserved one +- Then the rebuilt VolumeSnapshot is deleted so that the volume snapshot is deleted from the storage + +There is no way to automatically detect which way a specific volume support, so an interface is exposed to users to set the volume snapshot retention method. +The interface could be added to the `Action.Parameters` of Volume Policy. By default, Velero block data mover takes Way 1, so volume snapshot is never retained; if users specify `RetainSnapshot` parameter, Way 2 will be taken. +```go +type Action struct { + Type VolumeActionType `yaml:"type"` + Parameters map[string]any `yaml:"parameters,omitempty"` +} +``` +In this way, users could specify --- for storage class "xxx" or CSI driver "yyy", backup through CSI snapshot with Velero block data mover and retain the snapshot. + #### Incremental Size By the end of the backup, incremental size is also returned by the uploader, as same as Velero file system uploader. The size indicates how much data are unquie so processed by the uploader, based on the provided CBT. @@ -293,8 +381,9 @@ There are some occasions that the incremental backup won't continue, so the data Incremental backup could continue when volume is resized. Block uploader supports to write disk with arbibrary size. When volume resize happens, block uploader needs to handle it appropriately in below ways: -- The new boundary should always be Max(oldSize, newSize) -- Always rewrite the tail between RoundDownTo1M(newSize) and newSize +- Loop with CBT to the boundary of RoundDownTo1M(newSize) +- Read data between RoundDownTo1M(newSize) and newSize to get the tail data +- Call `WriteAt` from offset RoundDownTo1M(newSize) with the tail data That is to say, the tail must be rewrite since Incremental Aware Object Extension cannot copy BAT entries halfly for the incremental backup. @@ -309,7 +398,7 @@ Sequaltial read/write of the volume is always optimized, there is no prove that ### Progress Report Progress report outside of the data mover will reuse the existing mechanism. -Innside the data mover, progress update is embedded to the uploader writer. +Inside the data mover, progress update is embedded to the uploader writer. The progress struct is kept as is, Velero block data mover still supports `TotalBytes` and `BytesDone`: ```go type Progress struct { @@ -325,7 +414,7 @@ For many reasons, a periodical full backup is required: Therefore, backup type (full/incremental) should be supported in Velero's manual backup and backup schedule. Backup type will also be added to `volumeInfo.json` to support observability purposes. -Backup TTL is still used for users to specify a backup's retention time. By default, both full and incremetnal backups are with 30 days retention, even though this is not so reasonable for the full backups. This could be enhanced when Velero supports sophisticated retention policy. +Backup TTL is still used for users to specify a backup's retention time. By default, both full and incremental backups are with 30 days retention, even though this is not so reasonable for the full backups. This could be enhanced when Velero supports sophisticated retention policy. As a workaround, users could create two schedules for the same scope of backup, one is for full backups, with less frequency and longer backup TTL; the other one is for incremental backups, with normal frequency and shorter backup TTL. #### File System Data Mover @@ -336,14 +425,6 @@ Therefore, to solve this problem and to make it align with Velero block data mov At present, the data path for Velero file system data mover has already supported it, we only need to expose this functionality to users. -### Data Mover Selection -At present, in the Backup CRD, there is a `DataMover` field for users to specify the data mover to be used. This field will be kept, once it is set, all the data movements in the backup will use the specified data mover. - -However, this is not enough. In one backup, users may include volumes backed by both block storage and file system storage. -To meet this requirement, VolumePolicy will be enhanced to support the `DataMover` action. - -The selected data mover for each volume should be updated to `volumeInfo.json`. - ### Backup Describe Backup type should be added to backup description, this value could be retrieved from `volumeInfo.json`. The `DataMover` item in the existing backup description should be updated to reflect the actual data mover completing the backup, this information could be retrieved from `volumeInfo.json`. @@ -426,7 +507,7 @@ When the parameter is not specified, by default, Velero goes with incremental ba -[1]: Implemented/unified-repo-and-kopia-integration/unified-repo-and-kopia-integration.md -[2]: Implemented/volume-snapshot-data-movement/volume-snapshot-data-movement.md -[3]: Implemented/vgdp-micro-service/vgdp-micro-service.md +[1]: ../Implemented/unified-repo-and-kopia-integration/unified-repo-and-kopia-integration.md +[2]: ../Implemented/volume-snapshot-data-movement/volume-snapshot-data-movement.md +[3]: ../Implemented/vgdp-micro-service/vgdp-micro-service.md [4]: https://kubernetes.io/blog/2025/09/25/csi-changed-block-tracking/ \ No newline at end of file From 81029d64ff9d635f00ab4a0e8a50f014f83f7f70 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Fri, 27 Feb 2026 16:06:34 +0800 Subject: [PATCH 03/90] irregular volume size Signed-off-by: Lyndon-Li --- design/block-data-mover/block-data-mover.md | 24 +++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/design/block-data-mover/block-data-mover.md b/design/block-data-mover/block-data-mover.md index 28bdc7b11b..e33761e358 100644 --- a/design/block-data-mover/block-data-mover.md +++ b/design/block-data-mover/block-data-mover.md @@ -377,15 +377,31 @@ There are some occasions that the incremental backup won't continue, so the data - ChangeId is missing - Parent snapshot is missing +### Irregular Volume Size +As mentioned above, during incremental backup, block uploader IO should be restricted to be aligned to the deduplication chunk size (1MB); on the other hand, there is no hard limit for users' volume size to be aligned. +To support volumes with irregular size, below measures are taken: +- Volume objects in the repository is always aligned to 1MB +- If the volume size is irregular, zero bytes will be padded to the tail of the volume object +- A real size is recorded in the repository snapshot +- During restore, the real size of data is restored + +The padding must be always with zero bytes. + ### Volume Size Change Incremental backup could continue when volume is resized. Block uploader supports to write disk with arbibrary size. -When volume resize happens, block uploader needs to handle it appropriately in below ways: -- Loop with CBT to the boundary of RoundDownTo1M(newSize) +The volume resize cases don't need to be handled case by case. + +Instead, when volume resize happens, block uploader needs to handle it appropriately in below ways: +- Loop with CBT - Read data between RoundDownTo1M(newSize) and newSize to get the tail data -- Call `WriteAt` from offset RoundDownTo1M(newSize) with the tail data +- If there is no tail data, which means the volume size is aligned to 1MB, then call `WriteAt(newSize, nil)` +- Otherwise, call `WriteAt(RoundDownTo1M(newSize), taildata)`, `taildata` is also padded to 1MB -That is to say, the tail must be rewrite since Incremental Aware Object Extension cannot copy BAT entries halfly for the incremental backup. +That is to day: +- If CBT covers the tail of the volume, loop with CBT is enough for both shink and expand case +- Otherwise, if volume is expanded, `WriteAt` guarantees to clone appropriate objects entries from the parent object and append zero data for the expanded areas. Particularly, if the parent volume is not in regular size, the zero padding bytes is also reused. Therefore, the parent object's padding bytes must be zero +- In the case the volume is shrunk, writing the tail data makes sure zero bytes are padding to the new volume object instead of inheriting non-zero data from the parent object ### Cancellation The existing Cancellation mechanism is reused, so there is no change outside of the block uploader. From 1c9c669fa08915c05dcd6f348c4fab5a26e91472 Mon Sep 17 00:00:00 2001 From: dongqingcc Date: Thu, 26 Feb 2026 18:40:56 +0800 Subject: [PATCH 04/90] Add e2e test case for PR 9452 Signed-off-by: dongqingcc --- test/e2e/nodeagentconfig/node-agent-config.go | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/e2e/nodeagentconfig/node-agent-config.go b/test/e2e/nodeagentconfig/node-agent-config.go index 01cc6e38c5..bd1729e4e1 100644 --- a/test/e2e/nodeagentconfig/node-agent-config.go +++ b/test/e2e/nodeagentconfig/node-agent-config.go @@ -78,6 +78,14 @@ var LoadAffinities func() = TestFunc(&NodeAgentConfigTestCase{ IgnoreDelayBinding: true, }, PriorityClassName: test.PriorityClassNameForDataMover, + // Explicitly add custom labels and annotations to be tested + PodLabels: map[string]string{ + "spectrocloud.com/connection": "proxy", // Tests appending custom labels (Issue #9435) + "azure.workload.identity/use": "true", // Tests overwriting built-in labels + }, + PodAnnotations: map[string]string{ + "test-data-mover-annotation": "true", + }, }, nodeAgentConfigMapName: "node-agent-config", }) @@ -244,6 +252,16 @@ func (n *NodeAgentConfigTestCase) Backup() error { Expect(backupPodList.Items[0].Spec.Affinity).To(Equal(expectedAffinity)) + // Verify PodLabels + for k, v := range n.nodeAgentConfigs.PodLabels { + Expect(backupPodList.Items[0].Labels[k]).To(Equal(v)) + } + + // Verify PodAnnotations + for k, v := range n.nodeAgentConfigs.PodAnnotations { + Expect(backupPodList.Items[0].Annotations[k]).To(Equal(v)) + } + fmt.Println("backupPod content verification completed successfully.") wait.PollUntilContextTimeout(n.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) { @@ -321,6 +339,16 @@ func (n *NodeAgentConfigTestCase) Restore() error { Expect(restorePodList.Items[0].Spec.Affinity).To(Equal(expectedAffinity)) + // Verify PodLabels + for k, v := range n.nodeAgentConfigs.PodLabels { + Expect(restorePodList.Items[0].Labels[k]).To(Equal(v)) + } + + // Verify PodAnnotations + for k, v := range n.nodeAgentConfigs.PodAnnotations { + Expect(restorePodList.Items[0].Annotations[k]).To(Equal(v)) + } + fmt.Println("restorePod content verification completed successfully.") wait.PollUntilContextTimeout(n.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) { From 206219db6281379e2067b465a1b8823983dc9982 Mon Sep 17 00:00:00 2001 From: dongqingcc Date: Fri, 27 Feb 2026 14:37:47 +0800 Subject: [PATCH 05/90] Add e2e test case for issue 7725 Signed-off-by: dongqingcc --- test/e2e/e2e_suite_test.go | 6 + test/e2e/nodeagentconfig/cache_pvc.go | 253 ++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 test/e2e/nodeagentconfig/cache_pvc.go diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index f0d1c9c2e9..b60fee3616 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -674,6 +674,12 @@ var _ = Describe( LoadAffinities, ) +var _ = Describe( + "Test data mover dynamic Cache PVC injection", + Label("NodeAgentConfig", "CachePVC"), + CachePVCTest, +) + func GetKubeConfigContext() error { var err error var tcDefault, tcStandby k8s.TestClient diff --git a/test/e2e/nodeagentconfig/cache_pvc.go b/test/e2e/nodeagentconfig/cache_pvc.go new file mode 100644 index 0000000000..9104946c79 --- /dev/null +++ b/test/e2e/nodeagentconfig/cache_pvc.go @@ -0,0 +1,253 @@ +/* +Copyright the Velero contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package nodeagentconfig + +import ( + "context" + "fmt" + "strings" + "time" + + . "github.com/onsi/gomega" + "github.com/pkg/errors" + corev1api "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" + "sigs.k8s.io/controller-runtime/pkg/client" + + velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1" + "github.com/vmware-tanzu/velero/pkg/builder" + "github.com/vmware-tanzu/velero/test" + . "github.com/vmware-tanzu/velero/test/e2e/test" + k8sutil "github.com/vmware-tanzu/velero/test/util/k8s" + veleroutil "github.com/vmware-tanzu/velero/test/util/velero" +) + +type CachePVCTestCase struct { + TestCase + nodeAgentConfigMapName string + repoConfigMapName string +} + +var CachePVCTest func() = TestFunc(&CachePVCTestCase{ + nodeAgentConfigMapName: "node-agent-config-cache", + repoConfigMapName: "backup-repo-config-cache", +}) + +func (c *CachePVCTestCase) Init() error { + c.TestCase.Init() + c.CaseBaseName = "cache-pvc-" + c.UUIDgen + c.BackupName = "backup-" + c.CaseBaseName + c.RestoreName = "restore-" + c.CaseBaseName + c.NamespacesTotal = 1 + c.NSIncluded = &[]string{} + for nsNum := 0; nsNum < c.NamespacesTotal; nsNum++ { + createNSName := fmt.Sprintf("%s-%00000d", c.CaseBaseName, nsNum) + *c.NSIncluded = append(*c.NSIncluded, createNSName) + } + + c.VeleroCfg.UseNodeAgent = true + c.VeleroCfg.UseNodeAgentWindows = true + + // Ensure Data Mover is used to trigger DataUpload/DataDownload pods + c.BackupArgs = []string{ + "create", "--namespace", c.VeleroCfg.VeleroNamespace, "backup", c.BackupName, + "--include-namespaces", strings.Join(*c.NSIncluded, ","), + "--snapshot-volumes=true", "--snapshot-move-data", + } + + c.RestoreArgs = []string{ + "create", "--namespace", c.VeleroCfg.VeleroNamespace, "restore", c.RestoreName, + "--from-backup", c.BackupName, + } + + c.TestMsg = &TestMSG{ + Desc: "Validate dynamically provisioned Cache PVC for data mover pods", + FailedMSG: "Failed to apply and validate cache PVC configuration in data mover pods.", + Text: "Should dynamically provision a Cache PVC for data mover restore pods to avoid node root FS exhaustion.", + } + return nil +} + +func (c *CachePVCTestCase) InstallVelero() error { + fmt.Println("Start to uninstall Velero") + if err := veleroutil.VeleroUninstall(c.Ctx, c.VeleroCfg); err != nil { + fmt.Printf("Fail to uninstall Velero: %s\n", err.Error()) + return err + } + + // 1. Construct node-agent ConfigMap (Define Cache PVC StorageClass and trigger threshold) + // Set residentThresholdInMB to 0 to force Velero to create a PVC even for tiny E2E test data. + nodeAgentConfigJSON := fmt.Sprintf(`{"cachePVC": {"residentThresholdInMB": 0, "storageClass": "%s"}}`, test.StorageClassName) + nodeAgentConfig := builder.ForConfigMap(c.VeleroCfg.VeleroNamespace, c.nodeAgentConfigMapName). + Data("node-agent-config", nodeAgentConfigJSON).Result() + + // 2. Construct backup repository ConfigMap (Define cacheLimitMB) + repoConfigJSON := `{"cacheLimitMB": 2048}` // Set 2GB cache limit + repoConfig := builder.ForConfigMap(c.VeleroCfg.VeleroNamespace, c.repoConfigMapName). + Data(test.UploaderTypeKopia, repoConfigJSON).Result() + + c.VeleroCfg.NodeAgentConfigMap = c.nodeAgentConfigMapName + c.VeleroCfg.BackupRepoConfigMap = c.repoConfigMapName + + // Deploy Velero with the two Cache configuration ConfigMaps + return veleroutil.PrepareVelero(c.Ctx, c.CaseBaseName, c.VeleroCfg, nodeAgentConfig, repoConfig) +} + +func (c *CachePVCTestCase) CreateResources() error { + for _, ns := range *c.NSIncluded { + if err := k8sutil.CreateNamespace(c.Ctx, c.Client, ns); err != nil { + return err + } + + pvc, err := k8sutil.CreatePVC(c.Client, ns, "volume-1", test.StorageClassName, nil) + if err != nil { + return err + } + + vols := k8sutil.CreateVolumes(pvc.Name, []string{"volume-1"}) + + deployment := k8sutil.NewDeployment( + c.CaseBaseName, + ns, + 1, + map[string]string{"app": "test"}, + c.VeleroCfg.ImageRegistryProxy, + c.VeleroCfg.WorkerOS, + ).WithVolume(vols).Result() + + deployment, err = k8sutil.CreateDeployment(c.Client.ClientGo, ns, deployment) + if err != nil { + return errors.Wrap(err, "failed to create deployment") + } + + if err := k8sutil.WaitForReadyDeployment(c.Client.ClientGo, deployment.Namespace, deployment.Name); err != nil { + return err + } + } + return nil +} + +// verifyCacheVolumeInPod correctly verifies that the Pod mounted a dynamic PVC instead of an emptyDir +func (c *CachePVCTestCase) verifyCacheVolumeInPod(pod corev1api.Pod) error { + for _, vol := range pod.Spec.Volumes { + if vol.PersistentVolumeClaim != nil { + // Velero dynamically provisioned cache volumes typically have 'cache' in the name + if strings.Contains(vol.PersistentVolumeClaim.ClaimName, "cache") || strings.Contains(vol.Name, "cache") { + return nil // Success: Found the dynamically provisioned Cache PVC + } + } + } + return fmt.Errorf("Dynamically provisioned Cache PVC not found in pod %s, feature failed!", pod.Name) +} + +func (c *CachePVCTestCase) Backup() error { + if err := veleroutil.VeleroCmdExec(c.Ctx, c.VeleroCfg.VeleroCLI, c.BackupArgs); err != nil { + return err + } + + fmt.Println("Waiting for backup to complete...") + + // Wait for backup completion + wait.PollUntilContextTimeout(c.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) { + backup := new(velerov1api.Backup) + if err := c.VeleroCfg.ClientToInstallVelero.Kubebuilder.Get( + c.Ctx, + client.ObjectKey{Namespace: c.VeleroCfg.VeleroNamespace, Name: c.BackupName}, + backup, + ); err != nil { + return false, err + } + + if backup.Status.Phase != velerov1api.BackupPhaseCompleted && + backup.Status.Phase != velerov1api.BackupPhaseFailed && + backup.Status.Phase != velerov1api.BackupPhasePartiallyFailed { + return false, nil + } + + return true, nil + }) + + return nil +} + +func (c *CachePVCTestCase) Restore() error { + if err := veleroutil.VeleroCmdExec(c.Ctx, c.VeleroCfg.VeleroCLI, c.RestoreArgs); err != nil { + return err + } + + restorePodList := new(corev1api.PodList) + + wait.PollUntilContextTimeout(c.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) { + ddList := new(velerov2alpha1api.DataDownloadList) + if err := c.VeleroCfg.ClientToInstallVelero.Kubebuilder.List( + c.Ctx, + ddList, + &client.ListOptions{Namespace: c.VeleroCfg.VeleroNamespace}, + ); err != nil { + return false, err + } else if len(ddList.Items) <= 0 { + return false, nil + } + + if err := c.VeleroCfg.ClientToInstallVelero.Kubebuilder.List( + c.Ctx, + restorePodList, + &client.ListOptions{ + LabelSelector: labels.SelectorFromSet(map[string]string{ + velerov1api.DataDownloadLabel: ddList.Items[0].Name, + }), + }); err != nil { + return false, err + } else if len(restorePodList.Items) <= 0 { + return false, nil + } + + return true, nil + }) + + fmt.Println("Start to verify restore data mover pod content.") + Expect(restorePodList.Items).ToNot(BeEmpty()) + + // Ensure the Data Mover pod is using a true PVC for caching + err := c.verifyCacheVolumeInPod(restorePodList.Items[0]) + Expect(err).To(Succeed(), "Injected Cache PVC should exist in DataDownload Pod") + fmt.Println("Restore data mover pod content verification completed successfully.") + + // Wait for restore completion + wait.PollUntilContextTimeout(c.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) { + restore := new(velerov1api.Restore) + if err := c.VeleroCfg.ClientToInstallVelero.Kubebuilder.Get( + c.Ctx, + client.ObjectKey{Namespace: c.VeleroCfg.VeleroNamespace, Name: c.RestoreName}, + restore, + ); err != nil { + return false, err + } + + if restore.Status.Phase != velerov1api.RestorePhaseCompleted && + restore.Status.Phase != velerov1api.RestorePhaseFailed && + restore.Status.Phase != velerov1api.RestorePhasePartiallyFailed { + return false, nil + } + + return true, nil + }) + + return nil +} From dd8264590919be418a3773b53b8f0febfd73bde6 Mon Sep 17 00:00:00 2001 From: Adam Zhang Date: Wed, 8 Apr 2026 15:02:27 +0800 Subject: [PATCH 06/90] Fix PodVolumeBackup list scope during restore Restrict the listing of PodVolumeBackup resources to the specific restore namespace in both the core restore controller and the pod volume restore action plugin. This prevents "Forbidden" errors when Velero is configured with namespace-scoped minimum privileges, avoiding the need for cluster-scoped list permissions for PodVolumeBackups. Fixes: #9681 Signed-off-by: Adam Zhang --- changelogs/unreleased/9682-adam-jian-zhang | 1 + pkg/controller/restore_controller.go | 1 + pkg/controller/restore_controller_test.go | 35 +++++++++++++++++-- .../actions/pod_volume_restore_action.go | 1 + .../actions/pod_volume_restore_action_test.go | 22 ++++++++++++ 5 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/9682-adam-jian-zhang diff --git a/changelogs/unreleased/9682-adam-jian-zhang b/changelogs/unreleased/9682-adam-jian-zhang new file mode 100644 index 0000000000..0cb724f5b9 --- /dev/null +++ b/changelogs/unreleased/9682-adam-jian-zhang @@ -0,0 +1 @@ +Fix issue #9681, fix restores and podvolumerestores list options to only list in installed namespace diff --git a/pkg/controller/restore_controller.go b/pkg/controller/restore_controller.go index 208a3ddca8..469951f273 100644 --- a/pkg/controller/restore_controller.go +++ b/pkg/controller/restore_controller.go @@ -529,6 +529,7 @@ func (r *restoreReconciler) runValidatedRestore(restore *api.Restore, info backu LabelSelector: labels.Set(map[string]string{ api.BackupNameLabel: label.GetValidName(restore.Spec.BackupName), }).AsSelector(), + Namespace: restore.Namespace, } podVolumeBackupList := &api.PodVolumeBackupList{} diff --git a/pkg/controller/restore_controller_test.go b/pkg/controller/restore_controller_test.go index 3acc03d2a8..b013ee64db 100644 --- a/pkg/controller/restore_controller_test.go +++ b/pkg/controller/restore_controller_test.go @@ -238,6 +238,8 @@ func TestRestoreReconcile(t *testing.T) { expectedFinalPhase string addValidFinalizer bool emptyVolumeInfo bool + podVolumeBackups []*velerov1api.PodVolumeBackup + expectedPVBCount int }{ { name: "restore with both namespace in both includedNamespaces and excludedNamespaces fails validation", @@ -357,6 +359,22 @@ func TestRestoreReconcile(t *testing.T) { expectedCompletedTime: ×tamp, expectedRestorerCall: NewRestore("foo", "bar", "backup-1", "ns-1", "", velerov1api.RestorePhaseInProgress).Result(), }, + { + name: "valid restore gets executed and only includes pod volume backups from restore namespace", + location: defaultStorageLocation, + restore: NewRestore("foo", "bar2", "backup-1", "ns-1", "", velerov1api.RestorePhaseNew).Result(), + backup: defaultBackup().StorageLocation("default").Result(), + podVolumeBackups: []*velerov1api.PodVolumeBackup{ + builder.ForPodVolumeBackup("foo", "pvb-1").ObjectMeta(builder.WithLabels(velerov1api.BackupNameLabel, "backup-1")).Result(), + builder.ForPodVolumeBackup("other-ns", "pvb-2").ObjectMeta(builder.WithLabels(velerov1api.BackupNameLabel, "backup-1")).Result(), + }, + expectedPVBCount: 1, + expectedErr: false, + expectedPhase: string(velerov1api.RestorePhaseInProgress), + expectedStartTime: ×tamp, + expectedCompletedTime: ×tamp, + expectedRestorerCall: NewRestore("foo", "bar2", "backup-1", "ns-1", "", velerov1api.RestorePhaseInProgress).Result(), + }, { name: "restoration of nodes is not supported", location: defaultStorageLocation, @@ -501,6 +519,13 @@ func TestRestoreReconcile(t *testing.T) { defaultStorageLocation.ObjectMeta.ResourceVersion = "" }() + if test.podVolumeBackups != nil { + for _, pvb := range test.podVolumeBackups { + err := fakeClient.Create(t.Context(), pvb) + require.NoError(t, err) + } + } + r := NewRestoreReconciler( t.Context(), velerov1api.DefaultNamespace, @@ -670,6 +695,10 @@ func TestRestoreReconcile(t *testing.T) { // the mock stores the pointer, which gets modified after assert.Equal(t, test.expectedRestorerCall.Spec, restorer.calledWithArg.Spec) assert.Equal(t, test.expectedRestorerCall.Status.Phase, restorer.calledWithArg.Status.Phase) + + if test.podVolumeBackups != nil { + assert.Len(t, restorer.calledWithPVBs, test.expectedPVBCount) + } }) } } @@ -1021,8 +1050,9 @@ func NewRestore(ns, name, backup, includeNS, includeResource string, phase veler type fakeRestorer struct { mock.Mock - calledWithArg velerov1api.Restore - kbClient client.Client + calledWithArg velerov1api.Restore + calledWithPVBs []*velerov1api.PodVolumeBackup + kbClient client.Client } func (r *fakeRestorer) Restore( @@ -1045,6 +1075,7 @@ func (r *fakeRestorer) RestoreWithResolvers(req *pkgrestore.Request, r.kbClient, volumeSnapshotterGetter) r.calledWithArg = *req.Restore + r.calledWithPVBs = req.PodVolumeBackups return res.Get(0).(results.Result), res.Get(1).(results.Result) } diff --git a/pkg/restore/actions/pod_volume_restore_action.go b/pkg/restore/actions/pod_volume_restore_action.go index 4e3180fef7..e26a530347 100644 --- a/pkg/restore/actions/pod_volume_restore_action.go +++ b/pkg/restore/actions/pod_volume_restore_action.go @@ -101,6 +101,7 @@ func (a *PodVolumeRestoreAction) Execute(input *velero.RestoreItemActionExecuteI opts := &ctrlclient.ListOptions{ LabelSelector: label.NewSelectorForBackup(input.Restore.Spec.BackupName), + Namespace: input.Restore.Namespace, } podVolumeBackupList := new(velerov1api.PodVolumeBackupList) if err := a.crClient.List(context.TODO(), podVolumeBackupList, opts); err != nil { diff --git a/pkg/restore/actions/pod_volume_restore_action_test.go b/pkg/restore/actions/pod_volume_restore_action_test.go index 70911ca377..bc9662ab7d 100644 --- a/pkg/restore/actions/pod_volume_restore_action_test.go +++ b/pkg/restore/actions/pod_volume_restore_action_test.go @@ -350,6 +350,28 @@ func TestPodVolumeRestoreActionExecute(t *testing.T) { VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()). Command([]string{"/velero-restore-helper"}).Result()).Result(), }, + { + name: "pod volume backups in a different namespace are ignored when looking for matches due to namespace scoping", + pod: builder.ForPod("ns-1", "my-pod"). + Volumes( + builder.ForVolume("myvol").PersistentVolumeClaimSource("pvc-1").Result(), + ). + Result(), + podVolumeBackups: []runtime.Object{ + builder.ForPodVolumeBackup("other-ns", "pvb-1"). + PodName("my-pod"). + PodNamespace("ns-1"). + Volume("myvol"). + ObjectMeta(builder.WithLabels(velerov1api.BackupNameLabel, backupName)). + SnapshotID("foo"). + Result(), + }, + want: builder.ForPod("ns-1", "my-pod"). + Volumes( + builder.ForVolume("myvol").PersistentVolumeClaimSource("pvc-1").Result(), + ). + Result(), + }, } veleroDeployment := &appsv1api.Deployment{ From 1b5503e20bf255bd16a7777e983716d076168a25 Mon Sep 17 00:00:00 2001 From: Shubham Pampattiwar Date: Wed, 8 Apr 2026 15:46:06 -0700 Subject: [PATCH 07/90] Bump external-snapshotter to v8.4.0 for VGS v1beta2 support Kubernetes 1.34 introduced VolumeGroupSnapshot v1beta2 API and deprecated v1beta1. Distributions running K8s 1.34+ (e.g. OpenShift 4.21+) have removed v1beta1 VGS CRDs entirely, breaking Velero's VGS functionality on those clusters. This change bumps external-snapshotter/client/v8 from v8.2.0 to v8.4.0 and migrates all VGS API usage from v1beta1 to v1beta2. The v1beta2 API is structurally compatible - the Spec-level types (GroupSnapshotHandles, VolumeGroupSnapshotContentSource) are unchanged. The Status-level change (VolumeSnapshotHandlePairList replaced by VolumeSnapshotInfoList) does not affect Velero as it does not directly consume that type. Fixes #9694 Signed-off-by: Shubham Pampattiwar --- go.mod | 2 +- go.sum | 4 +- pkg/backup/actions/csi/pvc_action.go | 38 +++++------ pkg/backup/actions/csi/pvc_action_test.go | 68 +++++++++---------- pkg/client/factory.go | 6 +- pkg/cmd/server/server.go | 4 +- .../restore_finalizer_controller.go | 4 +- .../restore_finalizer_controller_test.go | 44 ++++++------ .../actions/csi/volumesnapshot_action.go | 24 +++---- .../actions/csi/volumesnapshot_action_test.go | 30 ++++---- pkg/test/fake_controller_runtime_client.go | 6 +- 11 files changed, 115 insertions(+), 115 deletions(-) diff --git a/go.mod b/go.mod index d33e6f2fe9..e80bfbcf9b 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/hashicorp/go-plugin v1.6.0 github.com/joho/godotenv v1.3.0 github.com/kopia/kopia v0.16.0 - github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0 + github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 diff --git a/go.sum b/go.sum index 5ee1c4bf39..d8ee0cab0a 100644 --- a/go.sum +++ b/go.sum @@ -507,8 +507,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0 h1:Q3jQ1NkFqv5o+F8dMmHd8SfEmlcwNeo1immFApntEwE= -github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0/go.mod h1:E3vdYxHj2C2q6qo8/Da4g7P+IcwqRZyy3gJBzYybV9Y= +github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 h1:bMqrb3UHgHbP+PW9VwiejfDJU1R0PpXVZNMdeH8WYKI= +github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0/go.mod h1:E3vdYxHj2C2q6qo8/Da4g7P+IcwqRZyy3gJBzYybV9Y= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= diff --git a/pkg/backup/actions/csi/pvc_action.go b/pkg/backup/actions/csi/pvc_action.go index ac5f71a98e..dbd60892d2 100644 --- a/pkg/backup/actions/csi/pvc_action.go +++ b/pkg/backup/actions/csi/pvc_action.go @@ -24,7 +24,7 @@ import ( "k8s.io/client-go/util/retry" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -765,7 +765,7 @@ func (p *pvcBackupItemAction) getVolumeSnapshotReference( } // Re-fetch latest VGS to ensure status is populated after VGSC binding - latestVGS := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{} + latestVGS := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{} if err := p.crClient.Get(ctx, crclient.ObjectKeyFromObject(newVGS), latestVGS); err != nil { return nil, errors.Wrapf(err, "failed to re-fetch VolumeGroupSnapshot %s after VGSC binding wait", newVGS.Name) } @@ -913,7 +913,7 @@ func (p *pvcBackupItemAction) determineVGSClass( } // 3. Fallback to label-based default - vgsClassList := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotClassList{} + vgsClassList := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotClassList{} if err := p.crClient.List(ctx, vgsClassList); err != nil { return "", errors.Wrap(err, "failed to list VolumeGroupSnapshotClasses") } @@ -942,22 +942,22 @@ func (p *pvcBackupItemAction) createVolumeGroupSnapshot( backup *velerov1api.Backup, pvc corev1api.PersistentVolumeClaim, vgsLabelKey, vgsLabelValue, vgsClassName string, -) (*volumegroupsnapshotv1beta1.VolumeGroupSnapshot, error) { +) (*volumegroupsnapshotv1beta2.VolumeGroupSnapshot, error) { vgsLabels := map[string]string{ velerov1api.BackupNameLabel: label.GetValidName(backup.Name), velerov1api.BackupUIDLabel: string(backup.UID), vgsLabelKey: vgsLabelValue, } - vgs := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{ + vgs := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{ ObjectMeta: metav1.ObjectMeta{ GenerateName: fmt.Sprintf("velero-%s-", vgsLabelValue), Namespace: pvc.Namespace, Labels: vgsLabels, }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotSpec{ VolumeGroupSnapshotClassName: &vgsClassName, - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotSource{ + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotSource{ Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ vgsLabelKey: vgsLabelValue, @@ -985,7 +985,7 @@ func (p *pvcBackupItemAction) createVolumeGroupSnapshot( func (p *pvcBackupItemAction) waitForVGSAssociatedVS( ctx context.Context, groupedPVCs []corev1api.PersistentVolumeClaim, - vgs *volumegroupsnapshotv1beta1.VolumeGroupSnapshot, + vgs *volumegroupsnapshotv1beta2.VolumeGroupSnapshot, timeout time.Duration, ) (map[string]*snapshotv1api.VolumeSnapshot, error) { expected := len(groupedPVCs) @@ -1028,10 +1028,10 @@ func (p *pvcBackupItemAction) waitForVGSAssociatedVS( return vsMap, nil } -func hasOwnerReference(obj metav1.Object, vgs *volumegroupsnapshotv1beta1.VolumeGroupSnapshot) bool { +func hasOwnerReference(obj metav1.Object, vgs *volumegroupsnapshotv1beta2.VolumeGroupSnapshot) bool { for _, ref := range obj.GetOwnerReferences() { if ref.Kind == kuberesource.VGSKind && - ref.APIVersion == volumegroupsnapshotv1beta1.GroupName+"/"+volumegroupsnapshotv1beta1.SchemeGroupVersion.Version && + ref.APIVersion == volumegroupsnapshotv1beta2.GroupName+"/"+volumegroupsnapshotv1beta2.SchemeGroupVersion.Version && ref.UID == vgs.UID { return true } @@ -1042,7 +1042,7 @@ func hasOwnerReference(obj metav1.Object, vgs *volumegroupsnapshotv1beta1.Volume func (p *pvcBackupItemAction) updateVGSCreatedVS( ctx context.Context, vsMap map[string]*snapshotv1api.VolumeSnapshot, - vgs *volumegroupsnapshotv1beta1.VolumeGroupSnapshot, + vgs *volumegroupsnapshotv1beta2.VolumeGroupSnapshot, backup *velerov1api.Backup, ) error { for pvcName, vs := range vsMap { @@ -1085,7 +1085,7 @@ func (p *pvcBackupItemAction) updateVGSCreatedVS( return nil } -func (p *pvcBackupItemAction) patchVGSCDeletionPolicy(ctx context.Context, vgs *volumegroupsnapshotv1beta1.VolumeGroupSnapshot) error { +func (p *pvcBackupItemAction) patchVGSCDeletionPolicy(ctx context.Context, vgs *volumegroupsnapshotv1beta2.VolumeGroupSnapshot) error { if vgs == nil || vgs.Status == nil || vgs.Status.BoundVolumeGroupSnapshotContentName == nil { return errors.New("VolumeGroupSnapshotContent name not found in VGS status") } @@ -1093,7 +1093,7 @@ func (p *pvcBackupItemAction) patchVGSCDeletionPolicy(ctx context.Context, vgs * vgscName := vgs.Status.BoundVolumeGroupSnapshotContentName return retry.RetryOnConflict(retry.DefaultBackoff, func() error { - vgsc := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + vgsc := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} if err := p.crClient.Get(ctx, crclient.ObjectKey{Name: *vgscName}, vgsc); err != nil { return errors.Wrapf(err, "failed to get VolumeGroupSnapshotContent %s for VolumeGroupSnapshot %s/%s", *vgscName, vgs.Namespace, vgs.Name) } @@ -1112,9 +1112,9 @@ func (p *pvcBackupItemAction) patchVGSCDeletionPolicy(ctx context.Context, vgs * }) } -func (p *pvcBackupItemAction) deleteVGSAndVGSC(ctx context.Context, vgs *volumegroupsnapshotv1beta1.VolumeGroupSnapshot) error { +func (p *pvcBackupItemAction) deleteVGSAndVGSC(ctx context.Context, vgs *volumegroupsnapshotv1beta2.VolumeGroupSnapshot) error { if vgs.Status != nil && vgs.Status.BoundVolumeGroupSnapshotContentName != nil { - vgsc := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + vgsc := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ ObjectMeta: metav1.ObjectMeta{ Name: *vgs.Status.BoundVolumeGroupSnapshotContentName, }, @@ -1139,11 +1139,11 @@ func (p *pvcBackupItemAction) deleteVGSAndVGSC(ctx context.Context, vgs *volumeg func (p *pvcBackupItemAction) waitForVGSCBinding( ctx context.Context, - vgs *volumegroupsnapshotv1beta1.VolumeGroupSnapshot, + vgs *volumegroupsnapshotv1beta2.VolumeGroupSnapshot, timeout time.Duration, ) error { return wait.PollUntilContextTimeout(ctx, time.Second, timeout, true, func(ctx context.Context) (bool, error) { - vgsRef := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{} + vgsRef := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{} if err := p.crClient.Get(ctx, crclient.ObjectKeyFromObject(vgs), vgsRef); err != nil { return false, err } @@ -1156,8 +1156,8 @@ func (p *pvcBackupItemAction) waitForVGSCBinding( }) } -func (p *pvcBackupItemAction) getVGSByLabels(ctx context.Context, namespace string, labels map[string]string) (*volumegroupsnapshotv1beta1.VolumeGroupSnapshot, error) { - vgsList := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotList{} +func (p *pvcBackupItemAction) getVGSByLabels(ctx context.Context, namespace string, labels map[string]string) (*volumegroupsnapshotv1beta2.VolumeGroupSnapshot, error) { + vgsList := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotList{} if err := p.crClient.List(ctx, vgsList, crclient.InNamespace(namespace), crclient.MatchingLabels(labels), diff --git a/pkg/backup/actions/csi/pvc_action_test.go b/pkg/backup/actions/csi/pvc_action_test.go index efcb0b0abf..33116d5c82 100644 --- a/pkg/backup/actions/csi/pvc_action_test.go +++ b/pkg/backup/actions/csi/pvc_action_test.go @@ -25,7 +25,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/kuberesource" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" "github.com/stretchr/testify/assert" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" @@ -1121,7 +1121,7 @@ func TestDetermineVGSClass(t *testing.T) { name string backup *velerov1api.Backup pvc *corev1api.PersistentVolumeClaim - existingVGSClass []volumegroupsnapshotv1beta1.VolumeGroupSnapshotClass + existingVGSClass []volumegroupsnapshotv1beta2.VolumeGroupSnapshotClass expectError bool expectResult string }{ @@ -1153,7 +1153,7 @@ func TestDetermineVGSClass(t *testing.T) { name: "Default label-based match", pvc: &corev1api.PersistentVolumeClaim{}, backup: &velerov1api.Backup{}, - existingVGSClass: []volumegroupsnapshotv1beta1.VolumeGroupSnapshotClass{ + existingVGSClass: []volumegroupsnapshotv1beta2.VolumeGroupSnapshotClass{ { ObjectMeta: metav1.ObjectMeta{ Name: "default-class", @@ -1174,7 +1174,7 @@ func TestDetermineVGSClass(t *testing.T) { name: "Multiple matching VGS classes", pvc: &corev1api.PersistentVolumeClaim{}, backup: &velerov1api.Backup{}, - existingVGSClass: []volumegroupsnapshotv1beta1.VolumeGroupSnapshotClass{ + existingVGSClass: []volumegroupsnapshotv1beta2.VolumeGroupSnapshotClass{ { ObjectMeta: metav1.ObjectMeta{ Name: "class1", @@ -1204,7 +1204,7 @@ func TestDetermineVGSClass(t *testing.T) { client := velerotest.NewFakeControllerRuntimeClient(t, initObjs...) logger := logrus.New() - require.NoError(t, volumegroupsnapshotv1beta1.AddToScheme(client.Scheme())) + require.NoError(t, volumegroupsnapshotv1beta2.AddToScheme(client.Scheme())) action := &pvcBackupItemAction{crClient: client, log: logger} @@ -1263,13 +1263,13 @@ func TestCreateVolumeGroupSnapshot(t *testing.T) { assert.Equal(t, string(testBackup.UID), vgs.Labels[velerov1api.BackupUIDLabel]) // Check that it exists in fake client - retrieved := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{} + retrieved := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{} err = crClient.Get(t.Context(), crclient.ObjectKey{Name: vgs.Name, Namespace: vgs.Namespace}, retrieved) require.NoError(t, err) } func TestWaitForVGSAssociatedVS(t *testing.T) { - vgs := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{ + vgs := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{ ObjectMeta: metav1.ObjectMeta{ Name: "test-vgs", Namespace: "test-ns", @@ -1282,7 +1282,7 @@ func TestWaitForVGSAssociatedVS(t *testing.T) { if owned { refs = []metav1.OwnerReference{ { - APIVersion: "groupsnapshot.storage.k8s.io/v1beta1", + APIVersion: "groupsnapshot.storage.k8s.io/v1beta2", Kind: "VolumeGroupSnapshot", Name: vgs.Name, UID: vgs.UID, @@ -1429,7 +1429,7 @@ func TestUpdateVGSCreatedVS(t *testing.T) { }, } - vgs := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{ + vgs := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{ ObjectMeta: metav1.ObjectMeta{ Name: "test-vgs", Namespace: "ns", @@ -1442,7 +1442,7 @@ func TestUpdateVGSCreatedVS(t *testing.T) { if withVGSOwner { refs = []metav1.OwnerReference{ { - APIVersion: "groupsnapshot.storage.k8s.io/v1beta1", + APIVersion: "groupsnapshot.storage.k8s.io/v1beta2", Kind: "VolumeGroupSnapshot", Name: vgs.Name, UID: vgs.UID, @@ -1561,18 +1561,18 @@ func TestPatchVGSCDeletionPolicy(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - vgsc := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + vgsc := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ ObjectMeta: metav1.ObjectMeta{Name: "test-vgsc"}, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ DeletionPolicy: tt.initialPolicy, }, } - vgs := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{ + vgs := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{ ObjectMeta: metav1.ObjectMeta{ Name: "test-vgs", Namespace: "ns", }, - Status: &volumegroupsnapshotv1beta1.VolumeGroupSnapshotStatus{ + Status: &volumegroupsnapshotv1beta2.VolumeGroupSnapshotStatus{ BoundVolumeGroupSnapshotContentName: pointer.String("test-vgsc"), }, } @@ -1590,7 +1590,7 @@ func TestPatchVGSCDeletionPolicy(t *testing.T) { } require.NoError(t, err) - updated := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + updated := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} err = client.Get(t.Context(), crclient.ObjectKey{Name: "test-vgsc"}, updated) require.NoError(t, err) require.Equal(t, tt.expectedPolicy, updated.Spec.DeletionPolicy) @@ -1599,20 +1599,20 @@ func TestPatchVGSCDeletionPolicy(t *testing.T) { } func TestDeleteVGSAndVGSC(t *testing.T) { - makeVGS := func(name, namespace string, boundVGSCName *string) *volumegroupsnapshotv1beta1.VolumeGroupSnapshot { - return &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{ + makeVGS := func(name, namespace string, boundVGSCName *string) *volumegroupsnapshotv1beta2.VolumeGroupSnapshot { + return &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, }, - Status: &volumegroupsnapshotv1beta1.VolumeGroupSnapshotStatus{ + Status: &volumegroupsnapshotv1beta2.VolumeGroupSnapshotStatus{ BoundVolumeGroupSnapshotContentName: boundVGSCName, }, } } - makeVGSC := func(name string) *volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent { - return &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + makeVGSC := func(name string) *volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent { + return &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, @@ -1621,8 +1621,8 @@ func TestDeleteVGSAndVGSC(t *testing.T) { tests := []struct { name string - vgs *volumegroupsnapshotv1beta1.VolumeGroupSnapshot - existingVGSC *volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent + vgs *volumegroupsnapshotv1beta2.VolumeGroupSnapshot + existingVGSC *volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent expectVGSCDelete bool expectVGSDelete bool }{ @@ -1668,13 +1668,13 @@ func TestDeleteVGSAndVGSC(t *testing.T) { // Check VGSC is deleted if tt.expectVGSCDelete { - got := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + got := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} err = client.Get(t.Context(), crclient.ObjectKey{Name: "test-vgsc"}, got) assert.True(t, apierrors.IsNotFound(err), "expected VGSC to be deleted") } // Check VGS is deleted - gotVGS := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{} + gotVGS := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{} err = client.Get(t.Context(), crclient.ObjectKey{Name: "test-vgs", Namespace: "ns"}, gotVGS) assert.True(t, apierrors.IsNotFound(err), "expected VGS to be deleted") }) @@ -1769,8 +1769,8 @@ func TestFindExistingVSForBackup(t *testing.T) { } func TestWaitForVGSCBinding(t *testing.T) { - makeVGS := func(name string, withStatus bool) *volumegroupsnapshotv1beta1.VolumeGroupSnapshot { - vgs := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{ + makeVGS := func(name string, withStatus bool) *volumegroupsnapshotv1beta2.VolumeGroupSnapshot { + vgs := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: "ns", @@ -1778,7 +1778,7 @@ func TestWaitForVGSCBinding(t *testing.T) { } if withStatus { contentName := "vgsc-123" - vgs.Status = &volumegroupsnapshotv1beta1.VolumeGroupSnapshotStatus{ + vgs.Status = &volumegroupsnapshotv1beta2.VolumeGroupSnapshotStatus{ BoundVolumeGroupSnapshotContentName: &contentName, } } @@ -1787,7 +1787,7 @@ func TestWaitForVGSCBinding(t *testing.T) { tests := []struct { name string - vgs *volumegroupsnapshotv1beta1.VolumeGroupSnapshot + vgs *volumegroupsnapshotv1beta2.VolumeGroupSnapshot expectErr bool }{ { @@ -1830,8 +1830,8 @@ func TestGetVGSByLabels(t *testing.T) { labelVal := "backup-123" testLabels := map[string]string{labelKey: labelVal} - makeVGS := func(name string, labels map[string]string) *volumegroupsnapshotv1beta1.VolumeGroupSnapshot { - return &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{ + makeVGS := func(name string, labels map[string]string) *volumegroupsnapshotv1beta2.VolumeGroupSnapshot { + return &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: "test-ns", @@ -1916,7 +1916,7 @@ func (f *failingClient) List(ctx context.Context, list crclient.ObjectList, opts } func TestHasOwnerReference(t *testing.T) { - vgs := &volumegroupsnapshotv1beta1.VolumeGroupSnapshot{ + vgs := &volumegroupsnapshotv1beta2.VolumeGroupSnapshot{ ObjectMeta: metav1.ObjectMeta{ Name: "test-vgs", Namespace: "test-ns", @@ -1933,7 +1933,7 @@ func TestHasOwnerReference(t *testing.T) { name: "match kind, apiversion, uid", ownerRef: metav1.OwnerReference{ Kind: kuberesource.VGSKind, - APIVersion: volumegroupsnapshotv1beta1.GroupName + "/" + volumegroupsnapshotv1beta1.SchemeGroupVersion.Version, + APIVersion: volumegroupsnapshotv1beta2.GroupName + "/" + volumegroupsnapshotv1beta2.SchemeGroupVersion.Version, UID: vgs.UID, }, expect: true, @@ -1942,7 +1942,7 @@ func TestHasOwnerReference(t *testing.T) { name: "mismatch kind", ownerRef: metav1.OwnerReference{ Kind: "other-kind", - APIVersion: volumegroupsnapshotv1beta1.GroupName + "/" + volumegroupsnapshotv1beta1.SchemeGroupVersion.Version, + APIVersion: volumegroupsnapshotv1beta2.GroupName + "/" + volumegroupsnapshotv1beta2.SchemeGroupVersion.Version, UID: vgs.UID, }, expect: false, @@ -1960,7 +1960,7 @@ func TestHasOwnerReference(t *testing.T) { name: "mismatch uid", ownerRef: metav1.OwnerReference{ Kind: kuberesource.VGSKind, - APIVersion: volumegroupsnapshotv1beta1.GroupName + "/" + volumegroupsnapshotv1beta1.SchemeGroupVersion.Version, + APIVersion: volumegroupsnapshotv1beta2.GroupName + "/" + volumegroupsnapshotv1beta2.SchemeGroupVersion.Version, UID: "wrong-uid", }, expect: false, diff --git a/pkg/client/factory.go b/pkg/client/factory.go index 4b3c8941e8..51dfb62c3c 100644 --- a/pkg/client/factory.go +++ b/pkg/client/factory.go @@ -19,7 +19,7 @@ package client import ( "os" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" @@ -168,7 +168,7 @@ func (f *factory) KubebuilderClient() (kbclient.Client, error) { if err := snapshotv1api.AddToScheme(scheme); err != nil { return nil, err } - if err := volumegroupsnapshotv1beta1.AddToScheme(scheme); err != nil { + if err := volumegroupsnapshotv1beta2.AddToScheme(scheme); err != nil { return nil, err } kubebuilderClient, err := kbclient.New(clientConfig, kbclient.Options{ @@ -207,7 +207,7 @@ func (f *factory) KubebuilderWatchClient() (kbclient.WithWatch, error) { if err := snapshotv1api.AddToScheme(scheme); err != nil { return nil, err } - if err := volumegroupsnapshotv1beta1.AddToScheme(scheme); err != nil { + if err := volumegroupsnapshotv1beta2.AddToScheme(scheme); err != nil { return nil, err } kubebuilderWatchClient, err := kbclient.NewWithWatch(clientConfig, kbclient.Options{ diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go index e744013e85..cb38a40d0f 100644 --- a/pkg/cmd/server/server.go +++ b/pkg/cmd/server/server.go @@ -27,7 +27,7 @@ import ( "time" logrusr "github.com/bombsimon/logrusr/v3" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -247,7 +247,7 @@ func newServer(f client.Factory, config *config.Config, logger *logrus.Logger) ( cancelFunc() return nil, err } - if err := volumegroupsnapshotv1beta1.AddToScheme(scheme); err != nil { + if err := volumegroupsnapshotv1beta2.AddToScheme(scheme); err != nil { cancelFunc() return nil, err } diff --git a/pkg/controller/restore_finalizer_controller.go b/pkg/controller/restore_finalizer_controller.go index 6ff7f8cb0d..f82216bc3b 100644 --- a/pkg/controller/restore_finalizer_controller.go +++ b/pkg/controller/restore_finalizer_controller.go @@ -22,7 +22,7 @@ import ( "sync" "time" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -457,7 +457,7 @@ func (ctx *finalizerContext) patchDynamicPVWithVolumeInfo() (errs results.Result func (ctx *finalizerContext) cleanupStubVGSC() (warnings results.Result) { ctx.logger.Info("cleaning up stub VolumeGroupSnapshotContents") - vgscList := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentList{} + vgscList := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentList{} err := ctx.crClient.List( context.Background(), vgscList, diff --git a/pkg/controller/restore_finalizer_controller_test.go b/pkg/controller/restore_finalizer_controller_test.go index 0f1cc340dd..6fb5ba303b 100644 --- a/pkg/controller/restore_finalizer_controller_test.go +++ b/pkg/controller/restore_finalizer_controller_test.go @@ -22,7 +22,7 @@ import ( "testing" "time" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" @@ -750,7 +750,7 @@ func TestCleanupStubVGSC(t *testing.T) { tests := []struct { name string restore *velerov1api.Restore - existingVGSCs []*volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent + existingVGSCs []*volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent existingVSCs []*snapshotv1api.VolumeSnapshotContent expectedRemaining int expectedWarnings bool @@ -765,7 +765,7 @@ func TestCleanupStubVGSC(t *testing.T) { { name: "single stub VGSC deleted after VSCs are ready", restore: builder.ForRestore(velerov1api.DefaultNamespace, "restore-1").Result(), - existingVGSCs: []*volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + existingVGSCs: []*volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ { ObjectMeta: metav1.ObjectMeta{ Name: "vgsc-stub-1", @@ -773,10 +773,10 @@ func TestCleanupStubVGSC(t *testing.T) { velerov1api.RestoreNameLabel: "restore-1", }, }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ Driver: "rbd.csi.ceph.com", - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{ - GroupSnapshotHandles: &volumegroupsnapshotv1beta1.GroupSnapshotHandles{ + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{ + GroupSnapshotHandles: &volumegroupsnapshotv1beta2.GroupSnapshotHandles{ VolumeGroupSnapshotHandle: "vgs-handle-1", VolumeSnapshotHandles: []string{snapshotHandle1}, }, @@ -814,7 +814,7 @@ func TestCleanupStubVGSC(t *testing.T) { { name: "multiple stub VGSCs deleted", restore: builder.ForRestore(velerov1api.DefaultNamespace, "restore-1").Result(), - existingVGSCs: []*volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + existingVGSCs: []*volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ { ObjectMeta: metav1.ObjectMeta{ Name: "vgsc-stub-1", @@ -822,10 +822,10 @@ func TestCleanupStubVGSC(t *testing.T) { velerov1api.RestoreNameLabel: "restore-1", }, }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ Driver: "rbd.csi.ceph.com", - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{ - GroupSnapshotHandles: &volumegroupsnapshotv1beta1.GroupSnapshotHandles{ + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{ + GroupSnapshotHandles: &volumegroupsnapshotv1beta2.GroupSnapshotHandles{ VolumeGroupSnapshotHandle: "vgs-handle-1", VolumeSnapshotHandles: []string{snapshotHandle1}, }, @@ -839,10 +839,10 @@ func TestCleanupStubVGSC(t *testing.T) { velerov1api.RestoreNameLabel: "restore-1", }, }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ Driver: "rbd.csi.ceph.com", - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{ - GroupSnapshotHandles: &volumegroupsnapshotv1beta1.GroupSnapshotHandles{ + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{ + GroupSnapshotHandles: &volumegroupsnapshotv1beta2.GroupSnapshotHandles{ VolumeGroupSnapshotHandle: "vgs-handle-2", VolumeSnapshotHandles: []string{snapshotHandle2}, }, @@ -902,7 +902,7 @@ func TestCleanupStubVGSC(t *testing.T) { { name: "VGSCs from different restore are not deleted", restore: builder.ForRestore(velerov1api.DefaultNamespace, "restore-1").Result(), - existingVGSCs: []*volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + existingVGSCs: []*volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ { ObjectMeta: metav1.ObjectMeta{ Name: "vgsc-stub-mine", @@ -910,9 +910,9 @@ func TestCleanupStubVGSC(t *testing.T) { velerov1api.RestoreNameLabel: "restore-1", }, }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ Driver: "rbd.csi.ceph.com", - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{}, + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{}, }, }, { @@ -922,9 +922,9 @@ func TestCleanupStubVGSC(t *testing.T) { velerov1api.RestoreNameLabel: "restore-2", }, }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ Driver: "rbd.csi.ceph.com", - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{}, + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{}, }, }, }, @@ -934,7 +934,7 @@ func TestCleanupStubVGSC(t *testing.T) { { name: "VGSC deleted even when no snapshot handles in spec", restore: builder.ForRestore(velerov1api.DefaultNamespace, "restore-1").Result(), - existingVGSCs: []*volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + existingVGSCs: []*volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ { ObjectMeta: metav1.ObjectMeta{ Name: "vgsc-stub-empty", @@ -942,9 +942,9 @@ func TestCleanupStubVGSC(t *testing.T) { velerov1api.RestoreNameLabel: "restore-1", }, }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ Driver: "rbd.csi.ceph.com", - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{}, + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{}, }, }, }, @@ -980,7 +980,7 @@ func TestCleanupStubVGSC(t *testing.T) { assert.True(t, warnings.IsEmpty(), "expected no warnings") } - remainingList := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentList{} + remainingList := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentList{} require.NoError(t, fakeClient.List(t.Context(), remainingList)) assert.Len(t, remainingList.Items, tc.expectedRemaining) diff --git a/pkg/restore/actions/csi/volumesnapshot_action.go b/pkg/restore/actions/csi/volumesnapshot_action.go index 708b406814..dec33d4efe 100644 --- a/pkg/restore/actions/csi/volumesnapshot_action.go +++ b/pkg/restore/actions/csi/volumesnapshot_action.go @@ -20,7 +20,7 @@ import ( "context" "fmt" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -103,7 +103,7 @@ func (p *volumeSnapshotRestoreItemAction) ensureStubVGSCExists( vgscName := util.GenerateSha256FromRestoreUIDAndVsName(string(restore.UID), vgsh) // Check if VGSC already exists - existingVGSC := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + existingVGSC := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} err := p.crClient.Get(ctx, crclient.ObjectKey{Name: vgscName}, existingVGSC) if err == nil { // VGSC already exists, add this snapshot handle if not already present @@ -119,7 +119,7 @@ func (p *volumeSnapshotRestoreItemAction) ensureStubVGSCExists( // Look up VolumeGroupSnapshotClass to get secret annotations vgscAnnotations := map[string]string{} - vgscList := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotClassList{} + vgscList := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotClassList{} if err := p.crClient.List(ctx, vgscList); err == nil { for _, vgsClass := range vgscList.Items { if vgsClass.Driver == driver { @@ -135,7 +135,7 @@ func (p *volumeSnapshotRestoreItemAction) ensureStubVGSCExists( } } - vgsc := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + vgsc := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ ObjectMeta: metav1.ObjectMeta{ Name: vgscName, Labels: map[string]string{ @@ -143,11 +143,11 @@ func (p *volumeSnapshotRestoreItemAction) ensureStubVGSCExists( }, Annotations: vgscAnnotations, }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ DeletionPolicy: snapshotv1api.VolumeSnapshotContentRetain, Driver: driver, - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{ - GroupSnapshotHandles: &volumegroupsnapshotv1beta1.GroupSnapshotHandles{ + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{ + GroupSnapshotHandles: &volumegroupsnapshotv1beta2.GroupSnapshotHandles{ VolumeGroupSnapshotHandle: vgsh, VolumeSnapshotHandles: []string{snapshotHandle}, }, @@ -164,7 +164,7 @@ func (p *volumeSnapshotRestoreItemAction) ensureStubVGSCExists( // Another VS restore created the VGSC between our Get and Create. // Re-fetch and add our snapshot handle. p.log.Infof("Stub VGSC %s was created by another VS restore, adding our handle", vgscName) - raceVGSC := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + raceVGSC := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} if getErr := p.crClient.Get(ctx, crclient.ObjectKey{Name: vgscName}, raceVGSC); getErr != nil { return errors.Wrapf(getErr, "failed to get VGSC %s after race", vgscName) } @@ -174,7 +174,7 @@ func (p *volumeSnapshotRestoreItemAction) ensureStubVGSCExists( } // Re-fetch to get server-assigned metadata (resourceVersion) needed for patching - createdVGSC := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + createdVGSC := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} if err := p.crClient.Get(ctx, crclient.ObjectKey{Name: vgscName}, createdVGSC); err != nil { p.log.Warnf("Failed to fetch stub VGSC %s for status patch: %v", vgscName, err) return nil @@ -183,7 +183,7 @@ func (p *volumeSnapshotRestoreItemAction) ensureStubVGSCExists( // Set volumeGroupSnapshotHandle in status using Patch to avoid conflicts with the CSI controller. patchBase := createdVGSC.DeepCopy() if createdVGSC.Status == nil { - createdVGSC.Status = &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentStatus{} + createdVGSC.Status = &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentStatus{} } createdVGSC.Status.VolumeGroupSnapshotHandle = &vgsh if err := p.crClient.Status().Patch(ctx, createdVGSC, crclient.MergeFrom(patchBase)); err != nil { @@ -198,7 +198,7 @@ func (p *volumeSnapshotRestoreItemAction) ensureStubVGSCExists( // This is needed when multiple VolumeSnapshots from the same VolumeGroupSnapshot are restored. func (p *volumeSnapshotRestoreItemAction) addSnapshotHandleToVGSC( ctx context.Context, - vgsc *volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent, + vgsc *volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent, snapshotHandle string, ) error { // Check if handle is already in the list @@ -214,7 +214,7 @@ func (p *volumeSnapshotRestoreItemAction) addSnapshotHandleToVGSC( // Add the snapshot handle to the list patchBase := vgsc.DeepCopy() if vgsc.Spec.Source.GroupSnapshotHandles == nil { - vgsc.Spec.Source.GroupSnapshotHandles = &volumegroupsnapshotv1beta1.GroupSnapshotHandles{} + vgsc.Spec.Source.GroupSnapshotHandles = &volumegroupsnapshotv1beta2.GroupSnapshotHandles{} } vgsc.Spec.Source.GroupSnapshotHandles.VolumeSnapshotHandles = append( vgsc.Spec.Source.GroupSnapshotHandles.VolumeSnapshotHandles, diff --git a/pkg/restore/actions/csi/volumesnapshot_action_test.go b/pkg/restore/actions/csi/volumesnapshot_action_test.go index 9e548b59d0..de3e592c03 100644 --- a/pkg/restore/actions/csi/volumesnapshot_action_test.go +++ b/pkg/restore/actions/csi/volumesnapshot_action_test.go @@ -21,7 +21,7 @@ import ( "fmt" "testing" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" @@ -232,7 +232,7 @@ func TestEnsureStubVGSCExists(t *testing.T) { name string vs *snapshotv1api.VolumeSnapshot restore *velerov1api.Restore - existingVGSC *volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent + existingVGSC *volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent expectVGSC bool expectErr bool expectedHandle string @@ -317,15 +317,15 @@ func TestEnsureStubVGSCExists(t *testing.T) { }, }, restore: builder.ForRestore("velero", "restore").ObjectMeta(builder.WithUID("restore-uid")).Result(), - existingVGSC: &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + existingVGSC: &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ ObjectMeta: metav1.ObjectMeta{ Name: util.GenerateSha256FromRestoreUIDAndVsName("restore-uid", testVGSHandle), }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ Driver: testDriver, DeletionPolicy: snapshotv1api.VolumeSnapshotContentRetain, - Source: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{ - GroupSnapshotHandles: &volumegroupsnapshotv1beta1.GroupSnapshotHandles{ + Source: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{ + GroupSnapshotHandles: &volumegroupsnapshotv1beta2.GroupSnapshotHandles{ VolumeGroupSnapshotHandle: testVGSHandle, VolumeSnapshotHandles: []string{testSnapshotHandle}, }, @@ -362,7 +362,7 @@ func TestEnsureStubVGSCExists(t *testing.T) { // Check if VGSC was created/updated vgscName := util.GenerateSha256FromRestoreUIDAndVsName(string(tc.restore.UID), tc.vs.Annotations[velerov1api.VolumeGroupSnapshotHandleAnnotation]) - vgsc := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + vgsc := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} getErr := crClient.Get(context.Background(), crclient.ObjectKey{Name: vgscName}, vgsc) if tc.expectVGSC { @@ -420,23 +420,23 @@ func TestAddSnapshotHandleToVGSC(t *testing.T) { t.Run(tc.name, func(t *testing.T) { crClient := velerotest.NewFakeControllerRuntimeClient(t) - var source volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource + var source volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource if tc.nilGroupSnapshotHandles { - source = volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{} + source = volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{} } else { - source = volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSource{ - GroupSnapshotHandles: &volumegroupsnapshotv1beta1.GroupSnapshotHandles{ + source = volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSource{ + GroupSnapshotHandles: &volumegroupsnapshotv1beta2.GroupSnapshotHandles{ VolumeGroupSnapshotHandle: testVGSHandle, VolumeSnapshotHandles: tc.existingHandles, }, } } - existingVGSC := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{ + existingVGSC := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{ ObjectMeta: metav1.ObjectMeta{ Name: "test-vgsc", }, - Spec: volumegroupsnapshotv1beta1.VolumeGroupSnapshotContentSpec{ + Spec: volumegroupsnapshotv1beta2.VolumeGroupSnapshotContentSpec{ Driver: testDriver, DeletionPolicy: snapshotv1api.VolumeSnapshotContentRetain, Source: source, @@ -445,7 +445,7 @@ func TestAddSnapshotHandleToVGSC(t *testing.T) { require.NoError(t, crClient.Create(context.Background(), existingVGSC)) // Re-fetch to get the created object with proper metadata - fetchedVGSC := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + fetchedVGSC := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} require.NoError(t, crClient.Get(context.Background(), crclient.ObjectKey{Name: "test-vgsc"}, fetchedVGSC)) p := &volumeSnapshotRestoreItemAction{ @@ -457,7 +457,7 @@ func TestAddSnapshotHandleToVGSC(t *testing.T) { require.NoError(t, err) // Verify the VGSC has expected handles - updatedVGSC := &volumegroupsnapshotv1beta1.VolumeGroupSnapshotContent{} + updatedVGSC := &volumegroupsnapshotv1beta2.VolumeGroupSnapshotContent{} require.NoError(t, crClient.Get(context.Background(), crclient.ObjectKey{Name: "test-vgsc"}, updatedVGSC)) require.ElementsMatch(t, tc.expectedHandles, updatedVGSC.Spec.Source.GroupSnapshotHandles.VolumeSnapshotHandles) }) diff --git a/pkg/test/fake_controller_runtime_client.go b/pkg/test/fake_controller_runtime_client.go index ec22a3dc6a..90ee95d11d 100644 --- a/pkg/test/fake_controller_runtime_client.go +++ b/pkg/test/fake_controller_runtime_client.go @@ -19,7 +19,7 @@ package test import ( "testing" - volumegroupsnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1" + volumegroupsnapshotv1beta2 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta2" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" "github.com/stretchr/testify/require" @@ -45,7 +45,7 @@ func NewFakeControllerRuntimeClientBuilder(t *testing.T) *k8sfake.ClientBuilder require.NoError(t, appsv1api.AddToScheme(scheme)) require.NoError(t, snapshotv1api.AddToScheme(scheme)) require.NoError(t, storagev1api.AddToScheme(scheme)) - require.NoError(t, volumegroupsnapshotv1beta1.AddToScheme(scheme)) + require.NoError(t, volumegroupsnapshotv1beta2.AddToScheme(scheme)) return k8sfake.NewClientBuilder().WithScheme(scheme) } @@ -61,7 +61,7 @@ func NewFakeControllerRuntimeClient(t *testing.T, initObjs ...runtime.Object) cl require.NoError(t, snapshotv1api.AddToScheme(scheme)) require.NoError(t, storagev1api.AddToScheme(scheme)) require.NoError(t, batchv1api.AddToScheme(scheme)) - require.NoError(t, volumegroupsnapshotv1beta1.AddToScheme(scheme)) + require.NoError(t, volumegroupsnapshotv1beta2.AddToScheme(scheme)) return k8sfake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjs...).Build() } From 0cf8f94268a78b4531220515b1a28ac2e6e54473 Mon Sep 17 00:00:00 2001 From: Shubham Pampattiwar Date: Wed, 8 Apr 2026 15:47:06 -0700 Subject: [PATCH 08/90] Add changelog for PR #9695 Signed-off-by: Shubham Pampattiwar --- changelogs/unreleased/9695-shubham-pampattiwar | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/9695-shubham-pampattiwar diff --git a/changelogs/unreleased/9695-shubham-pampattiwar b/changelogs/unreleased/9695-shubham-pampattiwar new file mode 100644 index 0000000000..53deadee32 --- /dev/null +++ b/changelogs/unreleased/9695-shubham-pampattiwar @@ -0,0 +1 @@ +Bump external-snapshotter to v8.4.0 and migrate VolumeGroupSnapshot API from v1beta1 to v1beta2 for Kubernetes 1.34+ compatibility From 1730b7f41410c8e2a0e385ae65e73c8512e6993d Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Wed, 8 Apr 2026 15:19:38 +0800 Subject: [PATCH 09/90] issue 9428: incremental repo maintenance history queue length Signed-off-by: Lyndon-Li --- .../9683-Lyndon-Li\342\200\216\342\200\216" | 1 + pkg/controller/backup_repository_controller.go | 12 +++++++----- pkg/controller/backup_repository_controller_test.go | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 "changelogs/unreleased/9683-Lyndon-Li\342\200\216\342\200\216" diff --git "a/changelogs/unreleased/9683-Lyndon-Li\342\200\216\342\200\216" "b/changelogs/unreleased/9683-Lyndon-Li\342\200\216\342\200\216" new file mode 100644 index 0000000000..25b247bc19 --- /dev/null +++ "b/changelogs/unreleased/9683-Lyndon-Li\342\200\216\342\200\216" @@ -0,0 +1 @@ +Fix issue #9428, increase repo maintenance history queue length from 3 to 25 \ No newline at end of file diff --git a/pkg/controller/backup_repository_controller.go b/pkg/controller/backup_repository_controller.go index eb90660f49..11ebb5aec2 100644 --- a/pkg/controller/backup_repository_controller.go +++ b/pkg/controller/backup_repository_controller.go @@ -52,9 +52,11 @@ import ( const ( repoSyncPeriod = 5 * time.Minute defaultMaintainFrequency = 7 * 24 * time.Hour - defaultMaintenanceStatusQueueLength = 3 + defaultMaintenanceStatusQueueLength = 25 ) +var maintenanceStatusQueueLength = defaultMaintenanceStatusQueueLength + type BackupRepoReconciler struct { client.Client namespace string @@ -369,7 +371,7 @@ func ensureRepo(repo *velerov1api.BackupRepository, repoManager repomanager.Mana } func (r *BackupRepoReconciler) recallMaintenance(ctx context.Context, req *velerov1api.BackupRepository, log logrus.FieldLogger) error { - history, err := maintenance.WaitAllJobsComplete(ctx, r.Client, req, defaultMaintenanceStatusQueueLength, log) + history, err := maintenance.WaitAllJobsComplete(ctx, r.Client, req, maintenanceStatusQueueLength, log) if err != nil { return errors.Wrapf(err, "error waiting incomplete repo maintenance job for repo %s", req.Name) } @@ -427,7 +429,7 @@ func consolidateHistory(coming, cur []velerov1api.BackupRepositoryMaintenanceSta truncated := []velerov1api.BackupRepositoryMaintenanceStatus{} for consolidator.Len() > 0 { - if len(truncated) == defaultMaintenanceStatusQueueLength { + if len(truncated) == maintenanceStatusQueueLength { break } @@ -537,8 +539,8 @@ func updateRepoMaintenanceHistory(repo *velerov1api.BackupRepository, result vel } startingPos := 0 - if len(repo.Status.RecentMaintenance) >= defaultMaintenanceStatusQueueLength { - startingPos = len(repo.Status.RecentMaintenance) - defaultMaintenanceStatusQueueLength + 1 + if len(repo.Status.RecentMaintenance) >= maintenanceStatusQueueLength { + startingPos = len(repo.Status.RecentMaintenance) - maintenanceStatusQueueLength + 1 } repo.Status.RecentMaintenance = append(repo.Status.RecentMaintenance[startingPos:], latest) diff --git a/pkg/controller/backup_repository_controller_test.go b/pkg/controller/backup_repository_controller_test.go index 8a458033f4..ed952f4aee 100644 --- a/pkg/controller/backup_repository_controller_test.go +++ b/pkg/controller/backup_repository_controller_test.go @@ -929,6 +929,8 @@ func TestUpdateRepoMaintenanceHistory(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { + maintenanceStatusQueueLength = 3 + updateRepoMaintenanceHistory(test.backupRepo, test.result, &metav1.Time{Time: standardTime}, &metav1.Time{Time: standardTime.Add(time.Hour)}, "fake-message-0") for at := range test.backupRepo.Status.RecentMaintenance { From 7562011b795353f317d894d432643dcf94850960 Mon Sep 17 00:00:00 2001 From: Adam Zhang Date: Fri, 10 Apr 2026 15:40:03 +0800 Subject: [PATCH 10/90] Fix DataUpload list scope in CSI PVC backup plugin The `getDataUpload` function in the CSI PVC backup plugin was previously making a cluster-scoped list query to retrieve DataUpload CRs. In environments with strict minimum-privilege RBAC, this would fail with forbidden errors. This explicitly passes the backup namespace into the `ListOptions` when calling `crClient.List`, correctly scoping the queries to the backup's namespace. Unit tests have also been updated to ensure cross-namespace queries are rejected appropriately. Signed-off-by: Adam Zhang --- changelogs/unreleased/9704-adam-jian-zhang | 1 + pkg/backup/actions/csi/pvc_action.go | 6 +- pkg/backup/actions/csi/pvc_action_test.go | 75 ++++++++++++++++++---- 3 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 changelogs/unreleased/9704-adam-jian-zhang diff --git a/changelogs/unreleased/9704-adam-jian-zhang b/changelogs/unreleased/9704-adam-jian-zhang new file mode 100644 index 0000000000..59ae81e9a4 --- /dev/null +++ b/changelogs/unreleased/9704-adam-jian-zhang @@ -0,0 +1 @@ +Fix issue #9703, fix CSI PVC Backup Plugin list options to only list in installed namespace diff --git a/pkg/backup/actions/csi/pvc_action.go b/pkg/backup/actions/csi/pvc_action.go index dbd60892d2..7f5fd2afa9 100644 --- a/pkg/backup/actions/csi/pvc_action.go +++ b/pkg/backup/actions/csi/pvc_action.go @@ -467,7 +467,7 @@ func (p *pvcBackupItemAction) Progress( return progress, biav2.InvalidOperationIDError(operationID) } - dataUpload, err := getDataUpload(context.Background(), p.crClient, operationID) + dataUpload, err := getDataUpload(context.Background(), p.crClient, backup.Namespace, operationID) if err != nil { p.log.Errorf( "fail to get DataUpload for backup %s/%s by operation ID %s: %s", @@ -512,7 +512,7 @@ func (p *pvcBackupItemAction) Cancel(operationID string, backup *velerov1api.Bac return biav2.InvalidOperationIDError(operationID) } - dataUpload, err := getDataUpload(context.Background(), p.crClient, operationID) + dataUpload, err := getDataUpload(context.Background(), p.crClient, backup.Namespace, operationID) if err != nil { p.log.Errorf( "fail to get DataUpload for backup %s/%s: %s", @@ -605,10 +605,12 @@ func createDataUpload( func getDataUpload( ctx context.Context, crClient crclient.Client, + namespace string, operationID string, ) (*velerov2alpha1.DataUpload, error) { dataUploadList := new(velerov2alpha1.DataUploadList) err := crClient.List(ctx, dataUploadList, &crclient.ListOptions{ + Namespace: namespace, LabelSelector: labels.SelectorFromSet( map[string]string{velerov1api.AsyncOperationIDLabel: operationID}, ), diff --git a/pkg/backup/actions/csi/pvc_action_test.go b/pkg/backup/actions/csi/pvc_action_test.go index 33116d5c82..9ffe20be51 100644 --- a/pkg/backup/actions/csi/pvc_action_test.go +++ b/pkg/backup/actions/csi/pvc_action_test.go @@ -307,6 +307,28 @@ func TestProgress(t *testing.T) { operationID: "testing", expectedErr: "not found DataUpload for operationID testing", }, + { + name: "DataUpload in different namespace is not found", + backup: builder.ForBackup("velero", "test").Result(), + dataUpload: &velerov2alpha1.DataUpload{ + TypeMeta: metav1.TypeMeta{ + Kind: "DataUpload", + APIVersion: "v2alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "other-namespace", + Name: "testing", + Labels: map[string]string{ + velerov1api.AsyncOperationIDLabel: "testing", + }, + }, + Status: velerov2alpha1.DataUploadStatus{ + Phase: velerov2alpha1.DataUploadPhaseFailed, + }, + }, + operationID: "testing", + expectedErr: "not found DataUpload for operationID testing", + }, { name: "DataUpload is found", backup: builder.ForBackup("velero", "test").Result(), @@ -375,15 +397,15 @@ func TestCancel(t *testing.T) { tests := []struct { name string backup *velerov1api.Backup - dataUpload velerov2alpha1.DataUpload + dataUpload *velerov2alpha1.DataUpload operationID string - expectedErr error + expectedErr string expectedDataUpload velerov2alpha1.DataUpload }{ { name: "Cancel DataUpload", backup: builder.ForBackup("velero", "test").Result(), - dataUpload: velerov2alpha1.DataUpload{ + dataUpload: &velerov2alpha1.DataUpload{ TypeMeta: metav1.TypeMeta{ Kind: "DataUpload", APIVersion: velerov2alpha1.SchemeGroupVersion.String(), @@ -414,6 +436,31 @@ func TestCancel(t *testing.T) { }, }, }, + { + name: "DataUpload cannot be found", + backup: builder.ForBackup("velero", "test").Result(), + operationID: "testing", + expectedErr: "not found DataUpload for operationID testing", + }, + { + name: "DataUpload in different namespace is not found", + backup: builder.ForBackup("velero", "test").Result(), + dataUpload: &velerov2alpha1.DataUpload{ + TypeMeta: metav1.TypeMeta{ + Kind: "DataUpload", + APIVersion: velerov2alpha1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "other-namespace", + Name: "testing", + Labels: map[string]string{ + velerov1api.AsyncOperationIDLabel: "testing", + }, + }, + }, + operationID: "testing", + expectedErr: "not found DataUpload for operationID testing", + }, } for _, tc := range tests { @@ -426,17 +473,23 @@ func TestCancel(t *testing.T) { crClient: crClient, } - err := crClient.Create(t.Context(), &tc.dataUpload) - require.NoError(t, err) + if tc.dataUpload != nil { + err := crClient.Create(t.Context(), tc.dataUpload) + require.NoError(t, err) + } - err = pvcBIA.Cancel(tc.operationID, tc.backup) - require.NoError(t, err) + err := pvcBIA.Cancel(tc.operationID, tc.backup) + if tc.expectedErr != "" { + require.EqualError(t, err, tc.expectedErr) + } else { + require.NoError(t, err) - du := new(velerov2alpha1.DataUpload) - err = crClient.Get(t.Context(), crclient.ObjectKey{Namespace: tc.dataUpload.Namespace, Name: tc.dataUpload.Name}, du) - require.NoError(t, err) + du := new(velerov2alpha1.DataUpload) + err = crClient.Get(t.Context(), crclient.ObjectKey{Namespace: tc.dataUpload.Namespace, Name: tc.dataUpload.Name}, du) + require.NoError(t, err) - require.True(t, cmp.Equal(tc.expectedDataUpload, *du, cmpopts.IgnoreFields(velerov2alpha1.DataUpload{}, "ResourceVersion"))) + require.True(t, cmp.Equal(tc.expectedDataUpload, *du, cmpopts.IgnoreFields(velerov2alpha1.DataUpload{}, "ResourceVersion"))) + } }) } } From eb0a1814c60e1d24d3e777bffe357db4d12205bf Mon Sep 17 00:00:00 2001 From: emirot Date: Thu, 9 Apr 2026 18:55:24 -0700 Subject: [PATCH 11/90] chore: update base image to newer debian image Signed-off-by: emirot --- Dockerfile | 4 ++-- Dockerfile-Windows | 2 +- hack/build-image/Dockerfile | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6ce46ca3b4..da23551668 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ # limitations under the License. # Velero binary build section -FROM --platform=$BUILDPLATFORM golang:1.25-bookworm AS velero-builder +FROM --platform=$BUILDPLATFORM golang:1.25-trixie AS velero-builder ARG GOPROXY ARG BIN @@ -49,7 +49,7 @@ RUN mkdir -p /output/usr/bin && \ go clean -modcache -cache # Restic binary build section -FROM --platform=$BUILDPLATFORM golang:1.25-bookworm AS restic-builder +FROM --platform=$BUILDPLATFORM golang:1.25-trixie AS restic-builder ARG GOPROXY ARG BIN diff --git a/Dockerfile-Windows b/Dockerfile-Windows index ac22531dc1..757da8f80a 100644 --- a/Dockerfile-Windows +++ b/Dockerfile-Windows @@ -15,7 +15,7 @@ ARG OS_VERSION=1809 # Velero binary build section -FROM --platform=$BUILDPLATFORM golang:1.25-bookworm AS velero-builder +FROM --platform=$BUILDPLATFORM golang:1.25-trixie AS velero-builder ARG GOPROXY ARG BIN diff --git a/hack/build-image/Dockerfile b/hack/build-image/Dockerfile index 0a60e6a165..25a162a826 100644 --- a/hack/build-image/Dockerfile +++ b/hack/build-image/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=$TARGETPLATFORM golang:1.25-bookworm +FROM --platform=$TARGETPLATFORM golang:1.25-trixie ARG GOPROXY From cd89c0ffa713e10a062307ea6e4c1b11045e6317 Mon Sep 17 00:00:00 2001 From: emirot Date: Fri, 10 Apr 2026 07:45:03 -0700 Subject: [PATCH 12/90] chore: update base image to newer debian image Signed-off-by: emirot --- changelogs/unreleased/9701-emirot | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/9701-emirot diff --git a/changelogs/unreleased/9701-emirot b/changelogs/unreleased/9701-emirot new file mode 100644 index 0000000000..585c1c42a4 --- /dev/null +++ b/changelogs/unreleased/9701-emirot @@ -0,0 +1 @@ +Update Debian base image from bookworm to trixie \ No newline at end of file From 97ffb9eaaf2c6239ee898095b6966cacc41c17e1 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Mon, 13 Apr 2026 16:28:28 +0800 Subject: [PATCH 13/90] add cbt interfaces Signed-off-by: Lyndon-Li --- .../9716-Lyndon-Li\342\200\216\342\200\216" | 1 + pkg/cbtservice/service.go | 34 ++++++++++++++ pkg/uploader/cbt/bitmap.go | 46 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 "changelogs/unreleased/9716-Lyndon-Li\342\200\216\342\200\216" create mode 100644 pkg/cbtservice/service.go create mode 100644 pkg/uploader/cbt/bitmap.go diff --git "a/changelogs/unreleased/9716-Lyndon-Li\342\200\216\342\200\216" "b/changelogs/unreleased/9716-Lyndon-Li\342\200\216\342\200\216" new file mode 100644 index 0000000000..5e51e7aaf8 --- /dev/null +++ "b/changelogs/unreleased/9716-Lyndon-Li\342\200\216\342\200\216" @@ -0,0 +1 @@ +Fix issue #9709, add interfaces for CBT service and CBT bitmap \ No newline at end of file diff --git a/pkg/cbtservice/service.go b/pkg/cbtservice/service.go new file mode 100644 index 0000000000..3c9344fbe7 --- /dev/null +++ b/pkg/cbtservice/service.go @@ -0,0 +1,34 @@ +/* +Copyright The Velero Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cbtservice + +import "context" + +// Range defines the range of a change +type Range struct { + Offset int64 + Length int64 +} + +// Service defines the methods for CBT service which could be implemented by Kubernetes SnapshotMetadataService or other customized services +type Service interface { + // GetAllocatedBlocks enumerates the allocated blocks of the snapshot and call the record callback + GetAllocatedBlocks(ctx context.Context, snapshot string, record func([]Range) error) error + + // GetChangedBlocks enumerates the changed blocks of the snapshot since PIT of changeID and call the record callback + GetChangedBlocks(ctx context.Context, snapshot string, changeID string, record func([]Range) error) error +} diff --git a/pkg/uploader/cbt/bitmap.go b/pkg/uploader/cbt/bitmap.go new file mode 100644 index 0000000000..8e027cba65 --- /dev/null +++ b/pkg/uploader/cbt/bitmap.go @@ -0,0 +1,46 @@ +/* +Copyright The Velero Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cbt + +import "github.com/vmware-tanzu/velero/pkg/cbtservice" + +// Bitmap defines the methods to store and iterate the CBT bitmap +type Bitmap interface { + // Set sets bits within the provided range + Set(cbtservice.Range) + + // Iterator returns the iterator for the CBT Bitmap + Iterator() Iterator +} + +// Iterator defines the methods to iterate the CBT bitmap and query the associated information +type Iterator interface { + // ChangeID returns the changeID of the bitmap + ChangeID() string + + // SnapshotID returns snapshotID of the bitmap + SnapshotID() string + + // BlockSize returns the granularity of the bitmap + BlockSize() int + + // Count returns the toal number of count in the bitmap + Count() uint64 + + // Next returns the offset of the next set block and whether it comes to the end of the iteration + Next() (int64, bool) +} From cf605c948eaf7e78372a73df4af79c6d700596c3 Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Mon, 13 Apr 2026 14:52:42 -0400 Subject: [PATCH 14/90] Add CI check for invalid characters in file paths (#9553) * Add CI check for invalid characters in file paths Go's module zip rejects filenames containing certain characters (shell special chars like " ' * < > ? ` |, path separators : \, and non-letter Unicode such as control/format characters). This caused a build failure when a changelog file contained an invisible U+200E LEFT-TO-RIGHT MARK (see PR #9552). Add a GitHub Actions workflow that validates all tracked file paths on every PR to catch these issues before they reach downstream consumers. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Tiger Kaovilai * Fix changelog filenames containing invisible U+200E characters Remove LEFT-TO-RIGHT MARK unicode characters from changelog filenames that would cause Go module zip failures. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy Signed-off-by: Tiger Kaovilai --------- Signed-off-by: Tiger Kaovilai Co-authored-by: Claude Opus 4.6 Co-authored-by: Happy --- .github/workflows/pr-filepath-check.yml | 93 +++++++++++++++++++ .../unreleased/9533-Lyndon-Li | 0 .../unreleased/9560-Lyndon-Li | 0 .../unreleased/9561-Lyndon-Li | 0 .../unreleased/9634-Lyndon-Li | 0 .../unreleased/9663-Lyndon-Li | 0 .../unreleased/9676-Lyndon-Li | 0 .../unreleased/9677-Lyndon-Li | 0 8 files changed, 93 insertions(+) create mode 100644 .github/workflows/pr-filepath-check.yml rename "changelogs/unreleased/9533-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9533-Lyndon-Li (100%) rename "changelogs/unreleased/9560-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9560-Lyndon-Li (100%) rename "changelogs/unreleased/9561-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9561-Lyndon-Li (100%) rename "changelogs/unreleased/9634-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9634-Lyndon-Li (100%) rename "changelogs/unreleased/9663-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9663-Lyndon-Li (100%) rename "changelogs/unreleased/9676-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9676-Lyndon-Li (100%) rename "changelogs/unreleased/9677-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9677-Lyndon-Li (100%) diff --git a/.github/workflows/pr-filepath-check.yml b/.github/workflows/pr-filepath-check.yml new file mode 100644 index 0000000000..2e4b3d6eab --- /dev/null +++ b/.github/workflows/pr-filepath-check.yml @@ -0,0 +1,93 @@ +name: Pull Request File Path Check +on: [pull_request] +jobs: + + filepath-check: + name: Check for invalid characters in file paths + runs-on: ubuntu-latest + steps: + + - name: Check out the code + uses: actions/checkout@v6 + + - name: Validate file paths for Go module compatibility + run: | + # Go's module zip rejects filenames containing certain characters. + # See golang.org/x/mod/module fileNameOK() for the full specification. + # + # Allowed ASCII: letters, digits, and: !#$%&()+,-.=@[]^_{}~ and space + # Allowed non-ASCII: unicode letters only + # Rejected: " ' * < > ? ` | / \ : and any non-letter unicode (control + # chars, format chars like U+200E LEFT-TO-RIGHT MARK, etc.) + # + # This check catches issues like the U+200E incident in PR #9552. + + EXIT_STATUS=0 + + git ls-files -z | python3 -c " + import sys, unicodedata + + data = sys.stdin.buffer.read() + files = data.split(b'\x00') + + # Characters explicitly rejected by Go's fileNameOK + # (path separators / and \ are inherent to paths so we check per-element) + bad_ascii = set('\"' + \"'\" + '*<>?\`|:') + + allowed_ascii = set('!#$%&()+,-.=@[]^_{}~ ') + + def is_ok(ch): + if ch.isascii(): + return ch.isalnum() or ch in allowed_ascii + return ch.isalpha() + + bad_files = [] # list of (original_path, clean_path, char_desc) + for f in files: + if not f: + continue + try: + name = f.decode('utf-8') + except UnicodeDecodeError: + print(f'::error::Non-UTF-8 bytes in filename: {f!r}') + bad_files.append((repr(f), None, 'non-UTF-8 bytes')) + continue + + # Check each path element (split on /) + for element in name.split('/'): + for ch in element: + if not is_ok(ch): + cp = ord(ch) + char_name = unicodedata.name(ch, f'U+{cp:04X}') + char_desc = f'U+{cp:04X} ({char_name})' + # Build cleaned path by stripping invalid chars + clean = '/'.join( + ''.join(c for c in elem if is_ok(c)) + for elem in name.split('/') + ) + print(f'::error file={name}::File \"{name}\" contains invalid char {char_desc}') + bad_files.append((name, clean, char_desc)) + break + + if bad_files: + print() + print('The following files have characters that are invalid in Go module zip archives:') + print() + for original, clean, desc in bad_files: + print(f' {original} — {desc}') + print() + print('To fix, rename the files to remove the problematic characters:') + print() + for original, clean, desc in bad_files: + if clean: + print(f' mv \"{original}\" \"{clean}\" && git add \"{clean}\"') + print(f' # or: git mv \"{original}\" \"{clean}\"') + else: + print(f' # {original} — cannot auto-suggest rename (non-UTF-8)') + print() + print('See https://github.com/vmware-tanzu/velero/pull/9552 for context.') + sys.exit(1) + else: + print('All file paths are valid for Go module zip.') + " || EXIT_STATUS=1 + + exit $EXIT_STATUS diff --git "a/changelogs/unreleased/9533-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9533-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9533-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9533-Lyndon-Li diff --git "a/changelogs/unreleased/9560-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9560-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9560-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9560-Lyndon-Li diff --git "a/changelogs/unreleased/9561-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9561-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9561-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9561-Lyndon-Li diff --git "a/changelogs/unreleased/9634-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9634-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9634-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9634-Lyndon-Li diff --git "a/changelogs/unreleased/9663-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9663-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9663-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9663-Lyndon-Li diff --git "a/changelogs/unreleased/9676-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9676-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9676-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9676-Lyndon-Li diff --git "a/changelogs/unreleased/9677-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9677-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9677-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9677-Lyndon-Li From 5b9bcc99f15e6c0dd889c299f6086870bf4571cb Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Tue, 3 Mar 2026 14:59:35 +0800 Subject: [PATCH 15/90] block data mover design Signed-off-by: Lyndon-Li --- design/block-data-mover/block-data-mover.md | 74 +++++++++++++-------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/design/block-data-mover/block-data-mover.md b/design/block-data-mover/block-data-mover.md index e33761e358..bc386a3a2b 100644 --- a/design/block-data-mover/block-data-mover.md +++ b/design/block-data-mover/block-data-mover.md @@ -7,8 +7,10 @@ **Velero Generic Data Path (VGDP)**: VGDP is the collective of modules that is introduced in [Unified Repository design][1]. Velero uses these modules to finish data transfer for various purposes (i.e., PodVolume backup/restore, Volume Snapshot Data Movement). VGDP modules include uploaders and the backup repository. **Velero Built-in Data Mover (VBDM)**: VBDM, which is introduced in [Volume Snapshot Data Movement design][2] and [Unified Repository design][1], is the built-in data mover shipped along with Velero, it includes Velero data mover controllers and VGDP. **Data Mover Pods**: Intermediate pods which hold VGDP and complete the data transfer. See [VGDP Micro Service for Volume Snapshot Data Movement][3] for details. -**Change Block Tracking (CBT)**: CBT is the mechanism to track changed blocks, so that backups could back up the changed data only. CBT usually provides by the comupting/storage platform. +**Change Block Tracking (CBT)**: CBT is the mechanism to track changed blocks, so that backups could back up the changed data only. CBT usually provides by the computing/storage platform. **TCO**: Total Cost of Ownership. This is a general criteria for products/solutions, but also means a lot for BR solutions. For example, this means what kind of backup storage (and its cost) it requires, the retention policy of backup copies, the ways to remove backup data redundancy, etc. +**PodVolume Backup**: This is the Velero backup method which accesses the data from live file system, see [Kopia Integration design][1] for how it works. +**CAOS and CABS**: Content-Addressable Object Storage and Content-Addressable Block Storage, they are the parts from Kopia repository, see [Kopia Architecture][5]. ## Background Kubernetes supports two kinds of volume mode, `FileSystem` and `Block`, for persistent volumes. Underlyingly, the storage could use a block storage to provision either `FileSystem` mode or `Block` mode volumes; and the storage could use a file storage to provision `FileSystem` mode volumes. @@ -32,7 +34,7 @@ Therefore, it is very important for Velero to deliver the block level backup/res Meanwhile, file system level backup/restore is still valuable for below scenarios: - The volume is backed by file storage, e.g., AWS EFS, Azure File, CephFS, VKS File Volume, etc. - The volume is backed by block storage but CBT is not available -- The volume doesn't support CSI snapshot, so Velero fs-backup method is used +- The volume doesn't support CSI snapshot, so Velero PodVolume Backup method is used There are rich features delivered with VGDP, VBDM and [VGDP micro service][3], to reuse these features, block data mover should be built based on these modules. @@ -46,13 +48,13 @@ Add a block data mover to VBDM and support block level backup/restore for [CSI S - Support block level full backup for both `FileSystem` and `Block` mode volumes - Support block level incremental backup for both `FileSystem` and `Block` mode volumes - Support block level restore from full/incremental backup for both `FileSystem` and `Block` mode volumes -- Support block level backup/restore for both linux and Windows workloads +- Support block level backup/restore for both linux and Windows workloads from linux cluster nodes - Support all existing features, i.e., load concurrency, node selection, cache volume, deduplication, compression, encryption, etc. for the block data mover - Support volumes processed from file system level and block level in the same backup/restore ## Non-Goals -- fs-backup does the backup/restore from file system level only, so block level backup/restore is not supported +- PodVolume Backup does the backup/restore from file system level only, so block level backup/restore is not supported - Volumes that are backed by file system storages, can only be backed up/restored from file system level, so block level backup/restore is not supported - Backing up/restoring from Windows nodes is not supported - Block level incremental backup requires special capabilities of the backup repository, and Velero [Unified Repository][1] supports multiple kinds of backup repositories. The current design focus on Kopia repository only, block level incremental backup support of other repositories will be considered when the specific backup repository is integrated to [Velero Unified Repository][1] @@ -67,17 +69,19 @@ Unified Repo interface and the backup repository needs to be enhanced to support ![Data path overview](data-path-overview.png) +For more details of VGDP architecture, see [Unified Repository design][1], [Volume Snapshot Data Movement design][2] and [VGDP Micro Service for Volume Snapshot Data Movement][3]. + ### Backup Below is the architecture for block data mover backup which is developed based on the existing VBDM: ![Backup architecture](backup-architecture.png) -Below are the major changes based on the existing VBDM: +The existing VBDM is reused, below are the major changes based on the existing VBDM: **Exposer**: Exposer needs to create block mode backupPVC all the time regardless of the sourcePVC mode. **CBT**: This is a new layer to retrieve, transform and store the changed blocks, it interacts with CSI SnapshotMetadataService through gRPC. **Uploader**: A new block uploader is added. It interacts with CBT layer, holds special logics to make performant data read from block devices and holds special logics to write incremental data to Unified Repository. -**Extended Kopia repo**: A new Incremental Aware Object Extension is added to Kopia's CAOS, so as to support incremental data write. +**Extended Kopia repo**: A new Incremental Aware Object Extension is added to Kopia's CAOS, so as to support incremental data write. Other parts of Kopia repository, including the existing CAOS and CABS, are not changed. ### Restore @@ -85,10 +89,12 @@ Below is architecture for block data mover restore which is developed based on t ![Restore architecture](restore-architecture.png) -Below are the major changes based on the existing VBDM: +The existing VBDM is reused, below are the major changes based on the existing VBDM: **Exposer**: While the restorePV is in block mode, exposer needs to rebind the restorePV to a targetPVC in either file system mode or block mode. **Uploader**: The same block uploader holds special logics to make performant data write to block devices and holds special logics to read data from the backup chain in Unified repository. +For more details of VBDM, see [Volume Snapshot Data Movement design][2]. + ## Detailed Design ### Selectable Data Mover Type @@ -139,7 +145,7 @@ const ( ) ``` -`action.parameters` is used to provide extra information of the action. This is an ideal place to differentate Velero file system data mover and Velero block data mover. +`action.parameters` is used to provide extra information of the action. This is an ideal place to differentiate Velero file system data mover and Velero block data mover. Therefore, Velero built-in data mover will support `dataMover` key in `parameters`, with the value either `velero-fs` or `velero-block`. While `velero-fs` and `velero-block` are with the same meaning with Per Backup Selection. As an example, here is how a user might use both `velero-block` and `velero-fs` in a single backup: @@ -259,7 +265,7 @@ To support non-Kopia uploader to save metadata, which is used to describe the ba kopia-lib for Unified Repo will implement these interfaces by calling the corresponding Kopia repository functions. ### Kopia Repository -CAOS of Kopia repository implements Unfied Repo's Objects. However, CAOS supports full and sequential write only. +CAOS of Kopia repository implements Unified Repo's Objects. However, CAOS supports full and sequential write only. To make it support skippable write, a new Incremental Aware Object Extension is created based on the existing CAOS. #### Block Address Table @@ -290,7 +296,7 @@ Since the existing block address table(BAT) of CAOS is reused and kept as is, it - The objects written by Velero block uploader is still recognizable by Kopia, for both full backup and incremental backup - The existing data management in Kopia repository still works for objects generated by Velero block uploader, e.g., snapshot GC, repository maintenance, etc. -Most importantly, this solution is super perfromant: +Most importantly, this solution is super performant: - During incremental write, it doesn't copy any data from the parent object, instead, it only clones object block address entries - During backup deletion, it doesn't need to move any data, it only deletes the BAT for the object @@ -304,8 +310,8 @@ CBT provides below functionalities: 1. For a full backup, it provides the allocated data ranges. E.g., for a 1TB volume, there may be only 1MB of files, with this functionality, the uploader could skip the ranges without real data 2. For an incremental backup, it provides the changed data ranges based on the provided parent snapshot. In this way, the uploader could skip the unchanged data and achieves an incremental backup -For case 1, the uploader calls Unfied Repo Object's `WriteAt` method with the offset for the allocated data, ranges ahead of the offset will be filled as ZERO by unified repository. -For case 2, the uploader calls Unfied Repo Object's `WriteAt` method with the offset for the changed data, ranges ahead of the offset will be cloned from the parent object unified repository. +For case 1, the uploader calls Unified Repo Object's `WriteAt` method with the offset for the allocated data, ranges ahead of the offset will be filled as ZERO by unified repository. +For case 2, the uploader calls Unified Repo Object's `WriteAt` method with the offset for the changed data, ranges ahead of the offset will be cloned from the parent object unified repository. A changeId is stored with each backup, the next backup will retrieve the parent snapshot's changeId and use it to retrieve the CBT. @@ -330,10 +336,16 @@ In this way, CBT layer and uploader are decoupled and CBT bitmap plays as a nort Block uploader consists of the reader and writer which are running asynchronously. During backup, reader reads data from the block device and also refers to CBT Bitmap for allocated/changed blocks; writer writes data to the Unified Repo. During restore, reader reads data from the Unified Repo; writer writes data to the block device. -Reader and writer connects by a ring buffer, that is, reader pushs the block data to the ring buffer and writer gets data from the ring buffer and write to the target. + +Reader and writer connects by a ring buffer, that is, reader pushes the block data to the ring buffer and writer gets data from the ring buffer and write to the target. To improve performance, block device is opened with direct IO, so that no data is going through the system cache unnecessarily. +During restore, to optimize the write throughput and storage usage, zero blocks should be either skipped (for restoring to a new volume) or unmapped (for restoring to an existing volume). To cover the both cases in a unified way, the SCSI command `WRITE_SAME` is used. Logics are as below: +- Detect if a block read from the backup is with all zero data +- If true, the uploader sends `WRITE_SAME` SCSI command by calling `BLKZEROOUT` ioctl +- If the call fails, the uploader fallbaks to use the conservative way to write all zero bytes to the disk + Uploader implementation is OS dependent, but since Windows container doesn't support block volumes, the current implementation is for linux only. #### ChangeId @@ -346,14 +358,14 @@ For Kubernetes API, changeId is represented by `BaseSnapshotId`. changeId retrieval is storage specific, generally, it is retrieved from the `SnapshotHandle` of the VolumeSnapshotContent object; however, storages may also refer to other places to retrieve the changeId. That is, `SnapshotHandle` and changeId may be two different values, in this case, the both values need to be preserved. -#### Volume Snapshot retention +#### Volume Snapshot Retention Storages/CSI drivers may support the changeId differently based on the storage's capabilities: 1. In order to calculate the changes, some storages require the parent snapshot mapping to the changeId always exists at the time of `GetMetadataDelta` is called, then the parent snapshot can NOT be deleted as long as there are incremental backups based on it. 2. Some storages don't require the parent snapshot itself at the time of calculating changes, then parent snapshot could be deleted immediately after the parent backup completes. The existing exposer works perfectly with Case 1, that is, the snapshot is always deleted when the backup completes. However, for Case 2, since the snapshot must be retained, the exposer needs changes as below: -- At the end of each backup, keep the current VolumeSnapshot's `deletionPolicy` as `Retain`, then when the VolumeSnapshot is deleted at the end of the backup, the cureent snapshot is retained in the storage +- At the end of each backup, keep the current VolumeSnapshot's `deletionPolicy` as `Retain`, then when the VolumeSnapshot is deleted at the end of the backup, the current snapshot is retained in the storage - `GetMetadataDelta` is called with `BaseSnapshotId` set as the preserved changeId - When deleting a backup, a VolumeSnapshot-VolumeSnapshotContent pair is rebuilt with `deletionPolicy` as `delete` and `snapshotHandle` as the preserved one - Then the rebuilt VolumeSnapshot is deleted so that the volume snapshot is deleted from the storage @@ -369,7 +381,7 @@ type Action struct { In this way, users could specify --- for storage class "xxx" or CSI driver "yyy", backup through CSI snapshot with Velero block data mover and retain the snapshot. #### Incremental Size -By the end of the backup, incremental size is also returned by the uploader, as same as Velero file system uploader. The size indicates how much data are unquie so processed by the uploader, based on the provided CBT. +By the end of the backup, incremental size is also returned by the uploader, as same as Velero file system uploader. The size indicates how much data are unique so processed by the uploader, based on the provided CBT. ### Fallback to Full Backup There are some occasions that the incremental backup won't continue, so the data mover fallbacks to full backup: @@ -377,6 +389,11 @@ There are some occasions that the incremental backup won't continue, so the data - ChangeId is missing - Parent snapshot is missing +When the fallback happens, the volume will be fully backed up from block level, but since because of the data deduplication from the backup repository, the unallocated/unchanged data would be probably deduplicated. +During restore, the volume will also be fully restored. The zero blocks handling as mentioned above is still working, so that write IO for unallocated data would be probably eliminated. + +Fallback is to handle the exceptional cases, for most of the backups/restores, fallback is never expected. + ### Irregular Volume Size As mentioned above, during incremental backup, block uploader IO should be restricted to be aligned to the deduplication chunk size (1MB); on the other hand, there is no hard limit for users' volume size to be aligned. To support volumes with irregular size, below measures are taken: @@ -389,7 +406,7 @@ The padding must be always with zero bytes. ### Volume Size Change Incremental backup could continue when volume is resized. -Block uploader supports to write disk with arbibrary size. +Block uploader supports to write disk with arbitrary size. The volume resize cases don't need to be handled case by case. Instead, when volume resize happens, block uploader needs to handle it appropriately in below ways: @@ -398,8 +415,8 @@ Instead, when volume resize happens, block uploader needs to handle it appropria - If there is no tail data, which means the volume size is aligned to 1MB, then call `WriteAt(newSize, nil)` - Otherwise, call `WriteAt(RoundDownTo1M(newSize), taildata)`, `taildata` is also padded to 1MB -That is to day: -- If CBT covers the tail of the volume, loop with CBT is enough for both shink and expand case +That is to say: +- If CBT covers the tail of the volume, loop with CBT is enough for both shrink and expand case - Otherwise, if volume is expanded, `WriteAt` guarantees to clone appropriate objects entries from the parent object and append zero data for the expanded areas. Particularly, if the parent volume is not in regular size, the zero padding bytes is also reused. Therefore, the parent object's padding bytes must be zero - In the case the volume is shrunk, writing the tail data makes sure zero bytes are padding to the new volume object instead of inheriting non-zero data from the parent object @@ -410,7 +427,7 @@ Inside the uploader, cancellation checkpoints are embedded to the uploader reade ### Parallelism Parallelism among data movers will reuse the existing mechanism --- load concurrency. Inside the data mover, uploader reader and writer are always running in parallel. The number of reader and writer is always 1. -Sequaltial read/write of the volume is always optimized, there is no prove that multiple readers/writers are beneficial. +Sequential read/write of the volume is always optimized, there is no prove that multiple readers/writers are beneficial. ### Progress Report Progress report outside of the data mover will reuse the existing mechanism. @@ -422,6 +439,7 @@ type Progress struct { BytesDone int64 `json:"doneBytes,omitempty"` } ``` +By the end of the backup, the progress for block data mover provides the same `GetIncrementalSize` which reports the incremental size of the backup, so that the incremental size is reported to users in the same way as the file system data mover. ### Selectable Backup Type For many reasons, a periodical full backup is required: @@ -442,14 +460,18 @@ Therefore, to solve this problem and to make it align with Velero block data mov At present, the data path for Velero file system data mover has already supported it, we only need to expose this functionality to users. ### Backup Describe -Backup type should be added to backup description, this value could be retrieved from `volumeInfo.json`. +Backup type should be added to backup description, there are two appearances: +- The `backupType` in the Backup CR. This is the selected backup type by users +- The backup type recorded in `volumeInfo.json`, which is the actual type taken by the backup +With these two values, users are able to know the actual backup type and also whether a fallback happens. + The `DataMover` item in the existing backup description should be updated to reflect the actual data mover completing the backup, this information could be retrieved from `volumeInfo.json`. ### Backup Sync No more data is required for sync, so Backup Sync is kept as is. ### Backup Deletion -As mentioned above, no data is moved when deleting a repo snapshot for Velero block data mover, so Backup Deletion is kept as is. +As mentioned above, no data is moved when deleting a repo snapshot for Velero block data mover, so Backup Deletion is kept as is regarding to repo snapshot; and for volume snapshot retention case, backup deletion logics will be modified accordingly to delete the retained snapshots. ### Restarts Restarts mechanism is reused without any change. @@ -458,9 +480,9 @@ Restarts mechanism is reused without any change. Logging mechanism is not changed. ### Backup CRD -A `backupType` field is added to Backup CRD, three values are supported `""`, `full` or `incremental`. +A `backupType` field is added to Backup CRD, two values are supported `full` or `incremental`. `full` indicates the data mover to take a full backup. -`""` fallbacks to `incremental` which indicates the data mover to take an incremental backup. +`incremental` which is the default value, indicates the data mover to take an incremental backup. ```yaml spec: @@ -471,7 +493,6 @@ A `backupType` field is added to Backup CRD, three values are supported `""`, `f enum: - full - incremental - - "" type: string ``` @@ -526,4 +547,5 @@ When the parameter is not specified, by default, Velero goes with incremental ba [1]: ../Implemented/unified-repo-and-kopia-integration/unified-repo-and-kopia-integration.md [2]: ../Implemented/volume-snapshot-data-movement/volume-snapshot-data-movement.md [3]: ../Implemented/vgdp-micro-service/vgdp-micro-service.md -[4]: https://kubernetes.io/blog/2025/09/25/csi-changed-block-tracking/ \ No newline at end of file +[4]: https://kubernetes.io/blog/2025/09/25/csi-changed-block-tracking/ +[5]: https://kopia.io/docs/advanced/architecture/ \ No newline at end of file From 1b4c7fe4bec11bbd5f7c128a2ccb5fb4a54ac804 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Tue, 14 Apr 2026 15:07:49 +0800 Subject: [PATCH 16/90] fix change log path error for 9683 Signed-off-by: Lyndon-Li --- .../unreleased/9683-Lyndon-Li | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "changelogs/unreleased/9683-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9683-Lyndon-Li (100%) diff --git "a/changelogs/unreleased/9683-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9683-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9683-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9683-Lyndon-Li From 8a6ac7af1c1436a20ef2117edeebe7ede4ae6804 Mon Sep 17 00:00:00 2001 From: Priyansh Choudhary Date: Wed, 15 Apr 2026 02:06:40 +0530 Subject: [PATCH 17/90] fix: backup deletion silently succeeds when tarball download fails (#9693) * Enhance backup deletion logic to handle tarball download failures and clean up associated CSI VolumeSnapshotContents Signed-off-by: Priyansh Choudhary * added changelog Signed-off-by: Priyansh Choudhary * Refactor error handling in backup deletion Signed-off-by: Priyansh Choudhary * Refactor backup deletion logic to skip CSI snapshot cleanup on tarball download failure Signed-off-by: Priyansh Choudhary * prevent backup deletion when errors occur Signed-off-by: Priyansh Choudhary * added logger Signed-off-by: Priyansh Choudhary --- changelogs/unreleased/9693-priyansh17 | 1 + pkg/controller/backup_deletion_controller.go | 39 ++++++- .../backup_deletion_controller_test.go | 108 ++++++++++++++---- 3 files changed, 127 insertions(+), 21 deletions(-) create mode 100644 changelogs/unreleased/9693-priyansh17 diff --git a/changelogs/unreleased/9693-priyansh17 b/changelogs/unreleased/9693-priyansh17 new file mode 100644 index 0000000000..0023a3c18b --- /dev/null +++ b/changelogs/unreleased/9693-priyansh17 @@ -0,0 +1 @@ +Enhance backup deletion logic to handle tarball download failures \ No newline at end of file diff --git a/pkg/controller/backup_deletion_controller.go b/pkg/controller/backup_deletion_controller.go index 5a791999c8..5fe29c5f11 100644 --- a/pkg/controller/backup_deletion_controller.go +++ b/pkg/controller/backup_deletion_controller.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "strings" "time" jsonpatch "github.com/evanphx/json-patch/v5" @@ -267,8 +268,17 @@ func (r *backupDeletionReconciler) Reconcile(ctx context.Context, req ctrl.Reque if err != nil { log.WithError(err).Errorf("Unable to download tarball for backup %s, skipping associated DeleteItemAction plugins", backup.Name) + // for backups which failed before tarball object could be uploaded we do offline cleanup log.Info("Cleaning up CSI volumesnapshots") r.deleteCSIVolumeSnapshotsIfAny(ctx, backup, log) + + // If the tarball simply does not exist (HTTP 404 / not found), the download + // failure is permanent and not retryable, so we let deletion proceed. + // For transient errors (throttling, auth failures, network issues), record + // the error to fail the deletion so it can be retried later. + if !isTarballNotFoundError(err) { + errs = append(errs, errors.Wrapf(err, "error downloading backup tarball, CSI snapshot cleanup was skipped").Error()) + } } else { defer closeAndRemoveFile(backupFile, r.logger) deleteCtx := &delete.Context{ @@ -351,11 +361,13 @@ func (r *backupDeletionReconciler) Reconcile(ctx context.Context, req ctrl.Reque } } - if backupStore != nil { + if backupStore != nil && len(errs) == 0 { log.Info("Removing backup from backup storage") if err := backupStore.DeleteBackup(backup.Name); err != nil { errs = append(errs, err.Error()) } + } else if len(errs) > 0 { + log.Info("Skipping removal of backup from backup storage due to previous errors") } log.Info("Removing restores") @@ -691,3 +703,28 @@ func batchDeleteSnapshots(ctx context.Context, repoEnsurer *repository.Ensurer, return errs } + +// isTarballNotFoundError reports whether err indicates that the backup tarball +// does not exist in object storage (e.g. HTTP 404 / not-found). Such errors are +// permanent and not retryable, so callers should let deletion proceed (skipping +// DeleteItemAction plugins) rather than failing the entire deletion. +// +// Transient errors (throttling, auth failures, network timeouts) return false so +// the deletion is failed and can be retried once the storage is reachable again. +func isTarballNotFoundError(err error) bool { + if err == nil { + return false + } + // Lower-case once for all comparisons. + msg := strings.ToLower(err.Error()) + // Common "not found" indicators across cloud providers: + // - "not found" / "does not exist": generic, in-memory object store + // - "nosuchkey": AWS S3 + // - "blobnotfound": Azure Blob Storage + // - "objectnotexist": GCS + return strings.Contains(msg, "not found") || + strings.Contains(msg, "does not exist") || + strings.Contains(msg, "nosuchkey") || + strings.Contains(msg, "blobnotfound") || + strings.Contains(msg, "objectnotexist") +} diff --git a/pkg/controller/backup_deletion_controller_test.go b/pkg/controller/backup_deletion_controller_test.go index 58d9b04207..24cc658464 100644 --- a/pkg/controller/backup_deletion_controller_test.go +++ b/pkg/controller/backup_deletion_controller_test.go @@ -25,8 +25,6 @@ import ( "reflect" "time" - snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" - "context" "github.com/sirupsen/logrus" @@ -606,7 +604,7 @@ func TestBackupDeletionControllerReconcile(t *testing.T) { // Make sure snapshot was deleted assert.Equal(t, 0, td.volumeSnapshotter.SnapshotsTaken.Len()) }) - t.Run("backup is still deleted if downloading tarball fails for DeleteItemAction plugins", func(t *testing.T) { + t.Run("backup deletion fails with error when downloading tarball fails for DeleteItemAction plugins", func(t *testing.T) { backup := builder.ForBackup(velerov1api.DefaultNamespace, "foo").Result() backup.UID = "uid" backup.Spec.StorageLocation = "primary" @@ -672,38 +670,108 @@ func TestBackupDeletionControllerReconcile(t *testing.T) { td.backupStore.On("GetBackupVolumeSnapshots", input.Spec.BackupName).Return(snapshots, nil) td.backupStore.On("GetBackupContents", input.Spec.BackupName).Return(nil, fmt.Errorf("error downloading tarball")) - td.backupStore.On("DeleteBackup", input.Spec.BackupName).Return(nil) _, err := td.controller.Reconcile(t.Context(), td.req) require.NoError(t, err) td.backupStore.AssertCalled(t, "GetBackupContents", input.Spec.BackupName) - td.backupStore.AssertCalled(t, "DeleteBackup", input.Spec.BackupName) + // DeleteBackup (removing backup data from object storage) must NOT be called + // when there are errors, so that the deletion can be retried later. + td.backupStore.AssertNotCalled(t, "DeleteBackup", input.Spec.BackupName) - // the dbr should be deleted + // the dbr should still exist and be marked Processed with errors res := &velerov1api.DeleteBackupRequest{} err = td.fakeClient.Get(ctx, td.req.NamespacedName, res) - assert.True(t, apierrors.IsNotFound(err), "Expected not found error, but actual value of error: %v", err) - if err == nil { - t.Logf("status of the dbr: %s, errors in dbr: %v", res.Status.Phase, res.Status.Errors) - } + require.NoError(t, err, "Expected DBR to still exist after tarball download failure") + assert.Equal(t, velerov1api.DeleteBackupRequestPhaseProcessed, res.Status.Phase) + require.Len(t, res.Status.Errors, 1) + assert.Contains(t, res.Status.Errors[0], "error downloading backup tarball, CSI snapshot cleanup was skipped") - // backup CR should be deleted + // backup CR should NOT be deleted err = td.fakeClient.Get(t.Context(), types.NamespacedName{ Namespace: velerov1api.DefaultNamespace, Name: backup.Name, }, &velerov1api.Backup{}) - assert.True(t, apierrors.IsNotFound(err), "Expected not found error, but actual value of error: %v", err) + require.NoError(t, err, "Expected backup CR to still exist after tarball download failure") + }) + t.Run("backup is still deleted if downloading tarball returns a not-found error", func(t *testing.T) { + backup := builder.ForBackup(velerov1api.DefaultNamespace, "foo").Result() + backup.UID = "uid" + backup.Spec.StorageLocation = "primary" - // leaked CSI snapshot should be deleted - err = td.fakeClient.Get(t.Context(), types.NamespacedName{ - Namespace: "user-ns", - Name: "vs-1", - }, &snapshotv1api.VolumeSnapshot{}) - assert.True(t, apierrors.IsNotFound(err), "Expected not found error for the leaked CSI snapshot, but actual value of error: %v", err) + input := defaultTestDbr() + input.Labels = nil - // Make sure snapshot was deleted - assert.Equal(t, 0, td.volumeSnapshotter.SnapshotsTaken.Len()) + location := &velerov1api.BackupStorageLocation{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: backup.Namespace, + Name: backup.Spec.StorageLocation, + }, + Spec: velerov1api.BackupStorageLocationSpec{ + Provider: "objStoreProvider", + StorageType: velerov1api.StorageType{ + ObjectStorage: &velerov1api.ObjectStorageLocation{ + Bucket: "bucket", + }, + }, + }, + Status: velerov1api.BackupStorageLocationStatus{ + Phase: velerov1api.BackupStorageLocationPhaseAvailable, + }, + } + + snapshotLocation := &velerov1api.VolumeSnapshotLocation{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: backup.Namespace, + Name: "vsl-1", + }, + Spec: velerov1api.VolumeSnapshotLocationSpec{ + Provider: "provider-1", + }, + } + + td := setupBackupDeletionControllerTest(t, defaultTestDbr(), backup, location, snapshotLocation) + td.volumeSnapshotter.SnapshotsTaken.Insert("snap-1") + + snapshots := []*volume.Snapshot{ + { + Spec: volume.SnapshotSpec{ + Location: "vsl-1", + }, + Status: volume.SnapshotStatus{ + ProviderSnapshotID: "snap-1", + }, + }, + } + + pluginManager := &pluginmocks.Manager{} + pluginManager.On("GetVolumeSnapshotter", "provider-1").Return(td.volumeSnapshotter, nil) + pluginManager.On("GetDeleteItemActions").Return([]velero.DeleteItemAction{new(mocks.DeleteItemAction)}, nil) + pluginManager.On("CleanupClients") + td.controller.newPluginManager = func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager } + + td.backupStore.On("GetBackupVolumeSnapshots", input.Spec.BackupName).Return(snapshots, nil) + // Simulate a 404/not-found error (tarball has already been removed from storage) + td.backupStore.On("GetBackupContents", input.Spec.BackupName).Return(nil, fmt.Errorf("key not found")) + td.backupStore.On("DeleteBackup", input.Spec.BackupName).Return(nil) + + _, err := td.controller.Reconcile(t.Context(), td.req) + require.NoError(t, err) + + td.backupStore.AssertCalled(t, "GetBackupContents", input.Spec.BackupName) + td.backupStore.AssertCalled(t, "DeleteBackup", input.Spec.BackupName) + + // the dbr should be deleted (not-found is treated as permanent, deletion proceeds) + res := &velerov1api.DeleteBackupRequest{} + err = td.fakeClient.Get(ctx, td.req.NamespacedName, res) + assert.True(t, apierrors.IsNotFound(err), "Expected DBR to be deleted after not-found tarball error, but actual error: %v", err) + + // backup CR should be deleted because there are no errors in errs + err = td.fakeClient.Get(t.Context(), types.NamespacedName{ + Namespace: velerov1api.DefaultNamespace, + Name: backup.Name, + }, &velerov1api.Backup{}) + assert.True(t, apierrors.IsNotFound(err), "Expected backup CR to be deleted after not-found tarball error, but actual error: %v", err) }) t.Run("Expired request will be deleted if the status is processed", func(t *testing.T) { expired := time.Date(2018, 4, 3, 12, 0, 0, 0, time.UTC) From df2686c14669b63f07c5713f559507504e0c1c5b Mon Sep 17 00:00:00 2001 From: Priyansh Choudhary Date: Wed, 15 Apr 2026 03:56:49 +0530 Subject: [PATCH 18/90] Add delay to avoid race conditions during VolumeSnapshotContent deletion (#9700) * Add delay to avoid race conditions during VolumeSnapshotContent deletion Signed-off-by: Priyansh Choudhary * updated changelog Signed-off-by: Priyansh Choudhary * Updated Changelog Signed-off-by: Priyansh Choudhary --- changelogs/unreleased/9700-priyansh17 | 1 + .../csi/volumesnapshotcontent_action.go | 8 +++ .../csi/volumesnapshotcontent_action_test.go | 49 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 changelogs/unreleased/9700-priyansh17 diff --git a/changelogs/unreleased/9700-priyansh17 b/changelogs/unreleased/9700-priyansh17 new file mode 100644 index 0000000000..b3cb5af680 --- /dev/null +++ b/changelogs/unreleased/9700-priyansh17 @@ -0,0 +1 @@ +Fix issue #9699, add a 2-second gap between temporary CSI VolumeSnapshotContent create and delete operations \ No newline at end of file diff --git a/internal/delete/actions/csi/volumesnapshotcontent_action.go b/internal/delete/actions/csi/volumesnapshotcontent_action.go index 98e0fc03bc..9473686e05 100644 --- a/internal/delete/actions/csi/volumesnapshotcontent_action.go +++ b/internal/delete/actions/csi/volumesnapshotcontent_action.go @@ -18,6 +18,7 @@ package csi import ( "context" + "time" "github.com/google/uuid" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" @@ -40,6 +41,10 @@ type volumeSnapshotContentDeleteItemAction struct { crClient crclient.Client } +const tempVSCCreateDeleteGap = 2 * time.Second + +var sleepBetweenTempVSCCreateAndDelete = time.Sleep + // AppliesTo returns information indicating // VolumeSnapshotContentRestoreItemAction action should be invoked // while restoring VolumeSnapshotContent.snapshot.storage.k8s.io resources @@ -123,6 +128,9 @@ func (p *volumeSnapshotContentDeleteItemAction) Execute( } p.log.Infof("Created temp VolumeSnapshotContent %s with DeletionPolicy=Delete to trigger cloud snapshot cleanup", snapCont.Name) + // Add a small delay before delete to avoid create/delete race conditions in CSI controllers. + sleepBetweenTempVSCCreateAndDelete(tempVSCCreateDeleteGap) + // Delete the temp VSC immediately to trigger cloud snapshot removal. // The CSI driver will handle the actual cloud snapshot deletion. if err := p.crClient.Delete( diff --git a/internal/delete/actions/csi/volumesnapshotcontent_action_test.go b/internal/delete/actions/csi/volumesnapshotcontent_action_test.go index 114bd752f3..e8a0b58654 100644 --- a/internal/delete/actions/csi/volumesnapshotcontent_action_test.go +++ b/internal/delete/actions/csi/volumesnapshotcontent_action_test.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "testing" + "time" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" "github.com/sirupsen/logrus" @@ -46,6 +47,21 @@ type fakeClientWithErrors struct { deleteError error } +type fakeClientWithCallTracking struct { + crclient.Client + events *[]string +} + +func (c *fakeClientWithCallTracking) Create(ctx context.Context, obj crclient.Object, opts ...crclient.CreateOption) error { + *c.events = append(*c.events, "create") + return c.Client.Create(ctx, obj, opts...) +} + +func (c *fakeClientWithCallTracking) Delete(ctx context.Context, obj crclient.Object, opts ...crclient.DeleteOption) error { + *c.events = append(*c.events, "delete") + return c.Client.Delete(ctx, obj, opts...) +} + func (c *fakeClientWithErrors) Get(ctx context.Context, key crclient.ObjectKey, obj crclient.Object, opts ...crclient.GetOption) error { if c.getError != nil { return c.getError @@ -325,6 +341,39 @@ func TestTryDeleteOriginalVSC(t *testing.T) { }) } +func TestVSCExecute_CreateSleepDeleteOrder(t *testing.T) { + snapshotHandleStr := "test" + vsc := builder.ForVolumeSnapshotContent("bar"). + ObjectMeta(builder.WithLabelsMap(map[string]string{velerov1api.BackupNameLabel: "backup"})). + Status(&snapshotv1api.VolumeSnapshotContentStatus{SnapshotHandle: &snapshotHandleStr}). + Result() + + vscMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(vsc) + require.NoError(t, err) + + events := make([]string, 0, 3) + realClient := velerotest.NewFakeControllerRuntimeClient(t) + trackingClient := &fakeClientWithCallTracking{Client: realClient, events: &events} + + originalSleep := sleepBetweenTempVSCCreateAndDelete + t.Cleanup(func() { + sleepBetweenTempVSCCreateAndDelete = originalSleep + }) + + sleepBetweenTempVSCCreateAndDelete = func(d time.Duration) { + require.Equal(t, tempVSCCreateDeleteGap, d) + events = append(events, "sleep") + } + + p := volumeSnapshotContentDeleteItemAction{log: logrus.StandardLogger(), crClient: trackingClient} + err = p.Execute(&velero.DeleteItemActionExecuteInput{ + Item: &unstructured.Unstructured{Object: vscMap}, + Backup: builder.ForBackup("velero", "backup").Result(), + }) + require.NoError(t, err) + require.Equal(t, []string{"create", "sleep", "delete"}, events) +} + func boolPtr(b bool) *bool { return &b } From 4d9bd912001b1b1abcbcab6867a227951aeb92b6 Mon Sep 17 00:00:00 2001 From: Daniel Jiang Date: Wed, 15 Apr 2026 23:15:57 +0800 Subject: [PATCH 19/90] Update the "community" page of website (#9722) Update the community page to add the correct links to community meeting and meeting notes. I also removed the referece of google group as I confirmed the last message was sent 2 years ago. Signed-off-by: Daniel Jiang --- site/content/community/_index.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/site/content/community/_index.md b/site/content/community/_index.md index c9eebef314..70e31c8690 100644 --- a/site/content/community/_index.md +++ b/site/content/community/_index.md @@ -13,11 +13,10 @@ You can follow the work we do, see our milestones, and our backlog on our [GitHu * Follow us on Twitter at [@projectvelero](https://twitter.com/projectvelero) * Join our Kubernetes Slack channel and talk to over 800 other community members: [#velero-users](https://kubernetes.slack.com/messages/velero-users) -* Join our [Google Group](https://groups.google.com/forum/#!forum/projectvelero) to get updates on the project and invites to community meetings. -* Join the Velero community meetings - [Zoom link](https://broadcom.zoom.us/j/94416678753?pwd=YkptN1k4M2lrUTdGbitNTmorODcvUT09) +* Join the Velero community meetings Bi-weekly community meeting alternating every week between Beijing Friendly timezone and EST/Europe Friendly Timezone - * Beijing/US friendly - we start at 8am Beijing Time(bound to CST) / 8pm EDT(7pm EST) / 5pm PDT(4pm PST) / 2am CEST(1am CET) - [Convert to your time zone](https://dateful.com/convert/beijing-china?t=8am) - * US/Europe friendly - we start at 10am ET(bound to ET) / 7am PT / 3pm CET / 10pm(11pm) CST - [Convert to your time zone](https://dateful.com/convert/est-edt-eastern-time?t=10) -* Read and comment on the [meeting notes](https://hackmd.io/bxrvgewUQ5ORH10BKUFpxw) + * Beijing/US friendly - we start at 8am Beijing Time(bound to CST) / 8pm EDT(7pm EST) / 5pm PDT(4pm PST) / 2am CEST(1am CET) - [Convert to your time zone](https://dateful.com/convert/beijing-china?t=8am) - [Zoom Link](https://broadcom.zoom.us/j/93945566592?pwd=rovF20vuI73kR6v67QBMpQuJOtM6sr.1&jst=2) + * US/Europe friendly - we start at 10am ET(bound to ET) / 7am PT / 3pm CET / 10pm(11pm) CST - [Convert to your time zone](https://dateful.com/convert/est-edt-eastern-time?t=10) - [Google meet link](https://meet.google.com/dyr-djtj-sko) +* Read and comment on the [meeting notes](https://hackmd.io/fCDVjqGuTG23CoOWQpoEVg) * See previous community meetings on our [YouTube Channel](https://www.youtube.com/playlist?list=PL7bmigfV0EqQRysvqvqOtRNk4L5S7uqwM) * Have a question to discuss in the community meeting? Please add it to our [Q&A Discussion board](https://github.com/vmware-tanzu/velero/discussions/categories/community-support-q-a) From 39db9f9c1eab7241ccb4057bf6e369b20b9c7bff Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 15 Apr 2026 23:21:42 +0800 Subject: [PATCH 20/90] Remove Restic build from Dockerfile, Makefile and Tiltfile. Delete Restic-build-related scripts. Signed-off-by: Xun Jiang --- Dockerfile | 27 --- Makefile | 3 - Tiltfile | 6 - changelogs/unreleased/9728-blackpiglet | 1 + hack/build-restic.sh | 56 ----- hack/fix_restic_cve.txt | 274 ------------------------- 6 files changed, 1 insertion(+), 366 deletions(-) create mode 100644 changelogs/unreleased/9728-blackpiglet delete mode 100755 hack/build-restic.sh delete mode 100644 hack/fix_restic_cve.txt diff --git a/Dockerfile b/Dockerfile index da23551668..9b1e04a201 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,30 +48,6 @@ RUN mkdir -p /output/usr/bin && \ -ldflags "${LDFLAGS}" ${PKG}/cmd/velero-helper && \ go clean -modcache -cache -# Restic binary build section -FROM --platform=$BUILDPLATFORM golang:1.25-trixie AS restic-builder - -ARG GOPROXY -ARG BIN -ARG TARGETOS -ARG TARGETARCH -ARG TARGETVARIANT -ARG RESTIC_VERSION - -ENV CGO_ENABLED=0 \ - GO111MODULE=on \ - GOPROXY=${GOPROXY} \ - GOOS=${TARGETOS} \ - GOARCH=${TARGETARCH} \ - GOARM=${TARGETVARIANT} - -COPY . /go/src/github.com/vmware-tanzu/velero - -RUN mkdir -p /output/usr/bin && \ - export GOARM=$(echo "${GOARM}" | cut -c2-) && \ - /go/src/github.com/vmware-tanzu/velero/hack/build-restic.sh && \ - go clean -modcache -cache - # Velero image packing section FROM paketobuildpacks/run-jammy-tiny:latest @@ -79,7 +55,4 @@ LABEL maintainer="Xun Jiang " COPY --from=velero-builder /output / -COPY --from=restic-builder /output / - USER cnb:cnb - diff --git a/Makefile b/Makefile index 82129623d4..59f767afc2 100644 --- a/Makefile +++ b/Makefile @@ -105,8 +105,6 @@ see: https://velero.io/docs/main/build-from-source/#making-images-and-updating-v endef # comma cannot be escaped and can only be used in Make function arguments by putting into variable comma=, -# The version of restic binary to be downloaded -RESTIC_VERSION ?= 0.15.0 CLI_PLATFORMS ?= linux-amd64 linux-arm linux-arm64 darwin-amd64 darwin-arm64 windows-amd64 linux-ppc64le linux-s390x BUILD_OUTPUT_TYPE ?= docker @@ -260,7 +258,6 @@ container-linux: --build-arg=GIT_SHA=$(GIT_SHA) \ --build-arg=GIT_TREE_STATE=$(GIT_TREE_STATE) \ --build-arg=REGISTRY=$(REGISTRY) \ - --build-arg=RESTIC_VERSION=$(RESTIC_VERSION) \ --provenance=false \ --sbom=false \ -f $(VELERO_DOCKERFILE) . diff --git a/Tiltfile b/Tiltfile index 7f2029f6d2..8bfa2ac2f6 100644 --- a/Tiltfile +++ b/Tiltfile @@ -103,11 +103,6 @@ local_resource( deps = ["internal", "pkg/cmd"], ) -local_resource( - "restic_binary", - cmd = 'cd ' + '.' + ';mkdir -p _tiltbuild/restic; BIN=velero GOOS=linux GOARCH=amd64 GOARM="" RESTIC_VERSION=0.13.1 OUTPUT_DIR=_tiltbuild/restic ./hack/build-restic.sh', -) - # Note: we need a distro with a bash shell to exec into the Velero container tilt_dockerfile_header = """ FROM ubuntu:22.04 as tilt @@ -118,7 +113,6 @@ WORKDIR / COPY --from=tilt-helper /start.sh . COPY --from=tilt-helper /restart.sh . COPY velero . -COPY restic/restic /usr/bin/restic """ dockerfile_contents = "\n".join([ diff --git a/changelogs/unreleased/9728-blackpiglet b/changelogs/unreleased/9728-blackpiglet new file mode 100644 index 0000000000..a0a9c897f4 --- /dev/null +++ b/changelogs/unreleased/9728-blackpiglet @@ -0,0 +1 @@ +Remove Restic build from Dockerfile, Makefile and Tiltfile. \ No newline at end of file diff --git a/hack/build-restic.sh b/hack/build-restic.sh deleted file mode 100755 index d6a233f4a5..0000000000 --- a/hack/build-restic.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash - -# Copyright 2020 the Velero contributors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail - -# Use /output/usr/bin/ as the default output directory as this -# is the path expected by the Velero Dockerfile. -output_dir=${OUTPUT_DIR:-/output/usr/bin} -restic_bin=${output_dir}/restic -build_path=$(dirname "$PWD") - -if [[ -z "${BIN}" ]]; then - echo "BIN must be set" - exit 1 -fi - -if [[ "${BIN}" != "velero" ]]; then - echo "${BIN} does not need the restic binary" - exit 0 -fi - -if [[ -z "${GOOS}" ]]; then - echo "GOOS must be set" - exit 1 -fi -if [[ -z "${GOARCH}" ]]; then - echo "GOARCH must be set" - exit 1 -fi -if [[ -z "${RESTIC_VERSION}" ]]; then - echo "RESTIC_VERSION must be set" - exit 1 -fi - -mkdir ${build_path}/restic -git clone -b v${RESTIC_VERSION} https://github.com/restic/restic.git ${build_path}/restic -pushd ${build_path}/restic -git apply /go/src/github.com/vmware-tanzu/velero/hack/fix_restic_cve.txt -go run build.go --goos "${GOOS}" --goarch "${GOARCH}" --goarm "${GOARM}" -o ${restic_bin} -chmod +x ${restic_bin} -popd diff --git a/hack/fix_restic_cve.txt b/hack/fix_restic_cve.txt deleted file mode 100644 index eeee2ecc61..0000000000 --- a/hack/fix_restic_cve.txt +++ /dev/null @@ -1,274 +0,0 @@ -diff --git a/go.mod b/go.mod -index 5f939c481..f6205aa3c 100644 ---- a/go.mod -+++ b/go.mod -@@ -24,32 +24,31 @@ require ( - github.com/restic/chunker v0.4.0 - github.com/spf13/cobra v1.6.1 - github.com/spf13/pflag v1.0.5 -- golang.org/x/crypto v0.5.0 -- golang.org/x/net v0.5.0 -- golang.org/x/oauth2 v0.4.0 -- golang.org/x/sync v0.1.0 -- golang.org/x/sys v0.4.0 -- golang.org/x/term v0.4.0 -- golang.org/x/text v0.6.0 -- google.golang.org/api v0.106.0 -+ golang.org/x/crypto v0.45.0 -+ golang.org/x/net v0.47.0 -+ golang.org/x/oauth2 v0.28.0 -+ golang.org/x/sync v0.18.0 -+ golang.org/x/sys v0.38.0 -+ golang.org/x/term v0.37.0 -+ golang.org/x/text v0.31.0 -+ google.golang.org/api v0.114.0 - ) - - require ( -- cloud.google.com/go v0.108.0 // indirect -- cloud.google.com/go/compute v1.15.1 // indirect -- cloud.google.com/go/compute/metadata v0.2.3 // indirect -- cloud.google.com/go/iam v0.10.0 // indirect -+ cloud.google.com/go v0.110.0 // indirect -+ cloud.google.com/go/compute/metadata v0.3.0 // indirect -+ cloud.google.com/go/iam v0.13.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/dnaeon/go-vcr v1.2.0 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect - github.com/felixge/fgprof v0.9.3 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect -- github.com/golang/protobuf v1.5.2 // indirect -+ github.com/golang/protobuf v1.5.3 // indirect - github.com/google/pprof v0.0.0-20230111200839-76d1ae5aea2b // indirect - github.com/google/uuid v1.3.0 // indirect -- github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect -- github.com/googleapis/gax-go/v2 v2.7.0 // indirect -+ github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect -+ github.com/googleapis/gax-go/v2 v2.7.1 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.3 // indirect -@@ -63,11 +62,13 @@ require ( - go.opencensus.io v0.24.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/appengine v1.6.7 // indirect -- google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect -- google.golang.org/grpc v1.52.0 // indirect -- google.golang.org/protobuf v1.28.1 // indirect -+ google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect -+ google.golang.org/grpc v1.56.3 // indirect -+ google.golang.org/protobuf v1.33.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - ) - --go 1.18 -+go 1.24.0 -+ -+toolchain go1.24.11 -diff --git a/go.sum b/go.sum -index 026e1d2fa..4a37e7ac7 100644 ---- a/go.sum -+++ b/go.sum -@@ -1,23 +1,24 @@ - cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= --cloud.google.com/go v0.108.0 h1:xntQwnfn8oHGX0crLVinvHM+AhXvi3QHQIEcX/2hiWk= --cloud.google.com/go v0.108.0/go.mod h1:lNUfQqusBJp0bgAg6qrHgYFYbTB+dOiob1itwnlD33Q= --cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE= --cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= --cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= --cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= --cloud.google.com/go/iam v0.10.0 h1:fpP/gByFs6US1ma53v7VxhvbJpO2Aapng6wabJ99MuI= --cloud.google.com/go/iam v0.10.0/go.mod h1:nXAECrMt2qHpF6RZUZseteD6QyanL68reN4OXPw0UWM= --cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= -+cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= -+cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -+cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -+cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -+cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= -+cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -+cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= -+cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= - cloud.google.com/go/storage v1.28.1 h1:F5QDG5ChchaAVQhINh24U99OWHURqrW8OmQcGKXcbgI= - cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.0 h1:VuHAcMq8pU1IWNT/m5yRaGqbK0BiQKHT8X4DTp9CHdI= - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.0/go.mod h1:tZoQYdDZNOiIjdSn0dVWVfl0NEPGOJqVLzSrcFk4Is0= - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8= -+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= - github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8= - github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= - github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1 h1:BMTdr+ib5ljLa9MxTJK8x/Ds0MbBb4MfuW5BL0zMJnI= - github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1/go.mod h1:c6WvOhtmjNUWbLfOG1qxM/q0SPvQNSVJvolm+C52dIU= - github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 h1:BWe8a+f/t+7KY7zH2mqygeUD0t8hNFXe08p1Pb3/jKE= -+github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= - github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= - github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74= - github.com/anacrolix/fuse v0.2.0 h1:pc+To78kI2d/WUjIyrsdqeJQAesuwpGxlI3h1nAv3Do= -@@ -54,6 +55,7 @@ github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNu - github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= - github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= - github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= -+github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= - github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -@@ -70,8 +72,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq - github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= - github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= - github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= --github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= --github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= - github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= - github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= - github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -@@ -82,17 +84,18 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ - github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= - github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= - github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= --github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= -+github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= -+github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= - github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= - github.com/google/pprof v0.0.0-20230111200839-76d1ae5aea2b h1:8htHrh2bw9c7Idkb7YNac+ZpTqLMjRpI+FWu51ltaQc= - github.com/google/pprof v0.0.0-20230111200839-76d1ae5aea2b/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= - github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= - github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= - github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= --github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg= --github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= --github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= --github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -+github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -+github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -+github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= -+github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= - github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= - github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= - github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= -@@ -114,6 +117,7 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= - github.com/kurin/blazer v0.5.4-0.20211030221322-ba894c124ac6 h1:nz7i1au+nDzgExfqW5Zl6q85XNTvYoGnM5DHiQC0yYs= - github.com/kurin/blazer v0.5.4-0.20211030221322-ba894c124ac6/go.mod h1:4FCXMUWo9DllR2Do4TtBd377ezyAJ51vB5uTBjt0pGU= - github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= - github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= - github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= - github.com/minio/minio-go/v7 v7.0.46 h1:Vo3tNmNXuj7ME5qrvN4iadO7b4mzu/RSFdUkUhaPldk= -@@ -129,6 +133,7 @@ github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3P - github.com/ncw/swift/v2 v2.0.1 h1:q1IN8hNViXEv8Zvg3Xdis4a3c4IlIGezkYz09zQL5J0= - github.com/ncw/swift/v2 v2.0.1/go.mod h1:z0A9RVdYPjNjXVo2pDOPxZ4eu3oarO1P91fTItcb+Kg= - github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI= -+github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= - github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= - github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= - github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= -@@ -172,8 +177,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk - golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= - golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= --golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= --golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -+golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -+golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= - golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= - golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= - golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -@@ -189,17 +194,17 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL - golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= - golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= --golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= --golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -+golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -+golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= - golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= --golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= --golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= -+golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= -+golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= - golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= - golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= - golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= - golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= --golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= --golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -+golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -+golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= - golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= - golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= - golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -@@ -214,17 +219,17 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc - golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= - golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= --golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= --golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -+golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -+golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= - golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= --golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= --golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -+golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -+golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= - golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= - golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= - golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= - golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= --golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= --golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -+golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -+golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= - golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= - golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= - golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -@@ -237,8 +242,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T - golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= --google.golang.org/api v0.106.0 h1:ffmW0faWCwKkpbbtvlY/K/8fUl+JKvNS5CVzRoyfCv8= --google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -+google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= -+google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= - google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= - google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= - google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -@@ -246,15 +251,15 @@ google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID - google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= - google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= - google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= --google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= --google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= - google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= - google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= - google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= - google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= - google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= --google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= --google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= -+google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= -+google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= - google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= - google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= - google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -@@ -266,14 +271,15 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD - google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= - google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= - google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= --google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= --google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= - gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= - gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= - gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= - gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= - gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= - gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= - gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= - gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From fc6361ba0693e8d3a576923b45ad32bf389d4227 Mon Sep 17 00:00:00 2001 From: Nolan Emirot Date: Wed, 15 Apr 2026 23:56:25 -0700 Subject: [PATCH 21/90] perf: better string concatenation (#9705) * perf: better string concatenation Signed-off-by: emirot Signed-off-by: nolanemirot Signed-off-by: emirot * fix: backup deletion silently succeeds when tarball download fails (#9693) * Enhance backup deletion logic to handle tarball download failures and clean up associated CSI VolumeSnapshotContents Signed-off-by: Priyansh Choudhary * added changelog Signed-off-by: Priyansh Choudhary * Refactor error handling in backup deletion Signed-off-by: Priyansh Choudhary * Refactor backup deletion logic to skip CSI snapshot cleanup on tarball download failure Signed-off-by: Priyansh Choudhary * prevent backup deletion when errors occur Signed-off-by: Priyansh Choudhary * added logger Signed-off-by: Priyansh Choudhary Signed-off-by: emirot * perf: better string concatenation Signed-off-by: emirot * Add delay to avoid race conditions during VolumeSnapshotContent deletion (#9700) * Add delay to avoid race conditions during VolumeSnapshotContent deletion Signed-off-by: Priyansh Choudhary * updated changelog Signed-off-by: Priyansh Choudhary * Updated Changelog Signed-off-by: Priyansh Choudhary Signed-off-by: emirot * block data mover design Signed-off-by: Lyndon-Li Signed-off-by: emirot * block data mover design Signed-off-by: Lyndon-Li Signed-off-by: emirot * irregular volume size Signed-off-by: Lyndon-Li Signed-off-by: emirot * block data mover design Signed-off-by: Lyndon-Li Signed-off-by: emirot * Update the "community" page of website (#9722) Update the community page to add the correct links to community meeting and meeting notes. I also removed the referece of google group as I confirmed the last message was sent 2 years ago. Signed-off-by: Daniel Jiang Signed-off-by: emirot * perf: better string concatenation Signed-off-by: emirot --------- Signed-off-by: emirot Signed-off-by: nolanemirot Signed-off-by: Priyansh Choudhary Signed-off-by: Lyndon-Li Signed-off-by: Daniel Jiang Co-authored-by: Priyansh Choudhary Co-authored-by: nolanemirot Co-authored-by: Lyndon-Li Co-authored-by: Daniel Jiang --- changelogs/unreleased/9705-emirot | 1 + pkg/util/csi/volume_snapshot.go | 7 ++++--- pkg/util/kube/pod.go | 16 +++++++++------- pkg/util/kube/pvc_pv.go | 7 ++++--- 4 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 changelogs/unreleased/9705-emirot diff --git a/changelogs/unreleased/9705-emirot b/changelogs/unreleased/9705-emirot new file mode 100644 index 0000000000..3bd8117bcf --- /dev/null +++ b/changelogs/unreleased/9705-emirot @@ -0,0 +1 @@ +perf: better string concatenation diff --git a/pkg/util/csi/volume_snapshot.go b/pkg/util/csi/volume_snapshot.go index 57e6f2e1d2..ed6371f7b5 100644 --- a/pkg/util/csi/volume_snapshot.go +++ b/pkg/util/csi/volume_snapshot.go @@ -708,17 +708,18 @@ func DiagnoseVS(vs *snapshotv1api.VolumeSnapshot, events *corev1api.EventList) s } } - diag := fmt.Sprintf("VS %s/%s, bind to %s, readyToUse %v, errMessage %s\n", vs.Namespace, vs.Name, vscName, readyToUse, errMessage) + var diag strings.Builder + _, _ = fmt.Fprintf(&diag, "VS %s/%s, bind to %s, readyToUse %v, errMessage %s\n", vs.Namespace, vs.Name, vscName, readyToUse, errMessage) if events != nil { for _, e := range events.Items { if e.InvolvedObject.UID == vs.UID && e.Type == corev1api.EventTypeWarning { - diag += fmt.Sprintf("VS event reason %s, message %s\n", e.Reason, e.Message) + _, _ = fmt.Fprintf(&diag, "VS event reason %s, message %s\n", e.Reason, e.Message) } } } - return diag + return diag.String() } func DiagnoseVSC(vsc *snapshotv1api.VolumeSnapshotContent) string { diff --git a/pkg/util/kube/pod.go b/pkg/util/kube/pod.go index 4ff05b43ee..4dc423272a 100644 --- a/pkg/util/kube/pod.go +++ b/pkg/util/kube/pod.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "os" + "strings" "time" "github.com/pkg/errors" @@ -183,16 +184,16 @@ func GetPodContainerTerminateMessage(pod *corev1api.Pod, container string) strin // GetPodTerminateMessage returns the terminate message for all containers of a pod func GetPodTerminateMessage(pod *corev1api.Pod) string { - message := "" + var message strings.Builder for _, containerStatus := range pod.Status.ContainerStatuses { if containerStatus.State.Terminated != nil { if containerStatus.State.Terminated.Message != "" { - message += containerStatus.State.Terminated.Message + "/" + message.WriteString(containerStatus.State.Terminated.Message + "/") } } } - return message + return message.String() } func getPodLogReader(ctx context.Context, podGetter corev1client.CoreV1Interface, pod string, namespace string, logOptions *corev1api.PodLogOptions) (io.ReadCloser, error) { @@ -272,21 +273,22 @@ func ToSystemAffinity(loadAffinity *LoadAffinity, volumeTopology *corev1api.Node } func DiagnosePod(pod *corev1api.Pod, events *corev1api.EventList) string { - diag := fmt.Sprintf("Pod %s/%s, phase %s, node name %s, message %s\n", pod.Namespace, pod.Name, pod.Status.Phase, pod.Spec.NodeName, pod.Status.Message) + var diag strings.Builder + _, _ = fmt.Fprintf(&diag, "Pod %s/%s, phase %s, node name %s, message %s\n", pod.Namespace, pod.Name, pod.Status.Phase, pod.Spec.NodeName, pod.Status.Message) for _, condition := range pod.Status.Conditions { - diag += fmt.Sprintf("Pod condition %s, status %s, reason %s, message %s\n", condition.Type, condition.Status, condition.Reason, condition.Message) + _, _ = fmt.Fprintf(&diag, "Pod condition %s, status %s, reason %s, message %s\n", condition.Type, condition.Status, condition.Reason, condition.Message) } if events != nil { for _, e := range events.Items { if e.InvolvedObject.UID == pod.UID && e.Type == corev1api.EventTypeWarning { - diag += fmt.Sprintf("Pod event reason %s, message %s\n", e.Reason, e.Message) + _, _ = fmt.Fprintf(&diag, "Pod event reason %s, message %s\n", e.Reason, e.Message) } } } - return diag + return diag.String() } var funcExit = os.Exit diff --git a/pkg/util/kube/pvc_pv.go b/pkg/util/kube/pvc_pv.go index d5d2e20416..fa886bf604 100644 --- a/pkg/util/kube/pvc_pv.go +++ b/pkg/util/kube/pvc_pv.go @@ -464,17 +464,18 @@ func GetPVCForPodVolume(vol *corev1api.Volume, pod *corev1api.Pod, crClient crcl } func DiagnosePVC(pvc *corev1api.PersistentVolumeClaim, events *corev1api.EventList) string { - diag := fmt.Sprintf("PVC %s/%s, phase %s, binding to %s\n", pvc.Namespace, pvc.Name, pvc.Status.Phase, pvc.Spec.VolumeName) + var diag strings.Builder + _, _ = fmt.Fprintf(&diag, "PVC %s/%s, phase %s, binding to %s\n", pvc.Namespace, pvc.Name, pvc.Status.Phase, pvc.Spec.VolumeName) if events != nil { for _, e := range events.Items { if e.InvolvedObject.UID == pvc.UID && e.Type == corev1api.EventTypeWarning { - diag += fmt.Sprintf("PVC event reason %s, message %s\n", e.Reason, e.Message) + _, _ = fmt.Fprintf(&diag, "PVC event reason %s, message %s\n", e.Reason, e.Message) } } } - return diag + return diag.String() } func DiagnosePV(pv *corev1api.PersistentVolume) string { From 455f3ba3054a5861192a46f1b57aa782579ba207 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Wed, 15 Apr 2026 17:43:34 +0800 Subject: [PATCH 22/90] unified repo interface extension for block data mover Signed-off-by: Lyndon-Li --- changelogs/unreleased/9724-Lyndon-Li | 1 + pkg/repository/udmrepo/kopialib/lib_repo.go | 38 +- .../udmrepo/kopialib/lib_repo_test.go | 18 +- pkg/repository/udmrepo/mocks/BackupRepo.go | 936 ++++++++++++++++-- pkg/repository/udmrepo/mocks/ObjectWriter.go | 288 ++++-- pkg/repository/udmrepo/repo.go | 58 +- pkg/uploader/kopia/shim.go | 4 +- pkg/uploader/kopia/shim_test.go | 2 +- 8 files changed, 1157 insertions(+), 188 deletions(-) create mode 100644 changelogs/unreleased/9724-Lyndon-Li diff --git a/changelogs/unreleased/9724-Lyndon-Li b/changelogs/unreleased/9724-Lyndon-Li new file mode 100644 index 0000000000..5eea82187e --- /dev/null +++ b/changelogs/unreleased/9724-Lyndon-Li @@ -0,0 +1 @@ +Fix issue #9723, extend Unified Repo Interface to support block uploader \ No newline at end of file diff --git a/pkg/repository/udmrepo/kopialib/lib_repo.go b/pkg/repository/udmrepo/kopialib/lib_repo.go index e6c46ae66f..34559baf7e 100644 --- a/pkg/repository/udmrepo/kopialib/lib_repo.go +++ b/pkg/repository/udmrepo/kopialib/lib_repo.go @@ -388,9 +388,9 @@ func (kr *kopiaRepository) Close(ctx context.Context) error { return nil } -func (kr *kopiaRepository) NewObjectWriter(ctx context.Context, opt udmrepo.ObjectWriteOptions) udmrepo.ObjectWriter { +func (kr *kopiaRepository) NewObjectWriter(ctx context.Context, opt udmrepo.ObjectWriteOptions) (udmrepo.ObjectWriter, error) { if kr.rawWriter == nil { - return nil + return nil, errors.New("repo writer is closed or not open") } writer := kr.rawWriter.NewObjectWriter(kopia.SetupKopiaLog(ctx, kr.logger), object.WriterOptions{ @@ -402,12 +402,22 @@ func (kr *kopiaRepository) NewObjectWriter(ctx context.Context, opt udmrepo.Obje }) if writer == nil { - return nil + return nil, errors.Errorf("error creating writer for object %s", opt.Description) } return &kopiaObjectWriter{ rawWriter: writer, - } + }, nil +} + +// TODO add implementation in following PRs +func (kr *kopiaRepository) WriteMetadata(ctx context.Context, meta *udmrepo.Metadata, opt udmrepo.ObjectWriteOptions) (udmrepo.ID, error) { + return "", errors.New("not supported") +} + +// TODO add implementation in following PRs +func (kr *kopiaRepository) ReadMetadata(ctx context.Context, id udmrepo.ID) (*udmrepo.Metadata, error) { + return nil, errors.New("not supported") } func (kr *kopiaRepository) PutManifest(ctx context.Context, manifest udmrepo.RepoManifest) (udmrepo.ID, error) { @@ -436,6 +446,21 @@ func (kr *kopiaRepository) DeleteManifest(ctx context.Context, id udmrepo.ID) er return nil } +// TODO add implementation in following PRs +func (kr *kopiaRepository) SaveSnapshot(ctx context.Context, snap udmrepo.Snapshot) (udmrepo.ID, error) { + return "", errors.New("not supported") +} + +// TODO add implementation in following PRs +func (kr *kopiaRepository) GetSnapshot(ctx context.Context, id udmrepo.ID) (udmrepo.Snapshot, error) { + return udmrepo.Snapshot{}, errors.New("not supported") +} + +// TODO add implementation in following PRs +func (kr *kopiaRepository) DeleteSnapshot(ctx context.Context, id udmrepo.ID) error { + return errors.New("not supported") +} + func (kr *kopiaRepository) Flush(ctx context.Context) error { if kr.rawWriter == nil { return errors.New("repo writer is closed or not open") @@ -546,8 +571,9 @@ func (kow *kopiaObjectWriter) Write(p []byte) (int, error) { return kow.rawWriter.Write(p) } -func (kow *kopiaObjectWriter) Seek(offset int64, whence int) (int64, error) { - return -1, errors.New("not supported") +// TODO add implementation in following PRs +func (kow *kopiaObjectWriter) WriteAt(p []byte, offset int64) (int, error) { + return 0, errors.New("not supported") } func (kow *kopiaObjectWriter) Checkpoint() (udmrepo.ID, error) { diff --git a/pkg/repository/udmrepo/kopialib/lib_repo_test.go b/pkg/repository/udmrepo/kopialib/lib_repo_test.go index 2feabaeca3..36e331bef7 100644 --- a/pkg/repository/udmrepo/kopialib/lib_repo_test.go +++ b/pkg/repository/udmrepo/kopialib/lib_repo_test.go @@ -663,13 +663,16 @@ func TestNewObjectWriter(t *testing.T) { rawWriter *repomocks.MockRepositoryWriter rawWriterRet object.Writer expectedRet udmrepo.ObjectWriter + expectedErr string }{ { - name: "raw writer is nil", + name: "raw writer is nil", + expectedErr: "repo writer is closed or not open", }, { - name: "new object writer fail", - rawWriter: repomocks.NewMockRepositoryWriter(t), + name: "new object writer fail", + rawWriter: repomocks.NewMockRepositoryWriter(t), + expectedErr: "error creating writer for object ", }, { name: "succeed", @@ -688,9 +691,14 @@ func TestNewObjectWriter(t *testing.T) { kr.rawWriter = tc.rawWriter } - ret := kr.NewObjectWriter(t.Context(), udmrepo.ObjectWriteOptions{}) + ret, err := kr.NewObjectWriter(t.Context(), udmrepo.ObjectWriteOptions{}) - assert.Equal(t, tc.expectedRet, ret) + if tc.expectedErr == "" { + require.NoError(t, err) + require.Equal(t, tc.expectedRet, ret) + } else { + require.EqualError(t, err, tc.expectedErr) + } }) } } diff --git a/pkg/repository/udmrepo/mocks/BackupRepo.go b/pkg/repository/udmrepo/mocks/BackupRepo.go index 7d044356d5..e495b6b00f 100644 --- a/pkg/repository/udmrepo/mocks/BackupRepo.go +++ b/pkg/repository/udmrepo/mocks/BackupRepo.go @@ -1,42 +1,98 @@ -// Code generated by mockery v2.39.1. DO NOT EDIT. +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify package mocks import ( - context "context" - time "time" + "context" + "time" mock "github.com/stretchr/testify/mock" - - udmrepo "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" + "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" ) +// NewBackupRepo creates a new instance of BackupRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewBackupRepo(t interface { + mock.TestingT + Cleanup(func()) +}) *BackupRepo { + mock := &BackupRepo{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + // BackupRepo is an autogenerated mock type for the BackupRepo type type BackupRepo struct { mock.Mock } -// Close provides a mock function with given fields: ctx -func (_m *BackupRepo) Close(ctx context.Context) error { - ret := _m.Called(ctx) +type BackupRepo_Expecter struct { + mock *mock.Mock +} + +func (_m *BackupRepo) EXPECT() *BackupRepo_Expecter { + return &BackupRepo_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function for the type BackupRepo +func (_mock *BackupRepo) Close(ctx context.Context) error { + ret := _mock.Called(ctx) if len(ret) == 0 { panic("no return value specified for Close") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) + if returnFunc, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = returnFunc(ctx) } else { r0 = ret.Error(0) } - return r0 } -// ConcatenateObjects provides a mock function with given fields: ctx, objectIDs -func (_m *BackupRepo) ConcatenateObjects(ctx context.Context, objectIDs []udmrepo.ID) (udmrepo.ID, error) { - ret := _m.Called(ctx, objectIDs) +// BackupRepo_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type BackupRepo_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +// - ctx context.Context +func (_e *BackupRepo_Expecter) Close(ctx interface{}) *BackupRepo_Close_Call { + return &BackupRepo_Close_Call{Call: _e.mock.On("Close", ctx)} +} + +func (_c *BackupRepo_Close_Call) Run(run func(ctx context.Context)) *BackupRepo_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *BackupRepo_Close_Call) Return(err error) *BackupRepo_Close_Call { + _c.Call.Return(err) + return _c +} + +func (_c *BackupRepo_Close_Call) RunAndReturn(run func(ctx context.Context) error) *BackupRepo_Close_Call { + _c.Call.Return(run) + return _c +} + +// ConcatenateObjects provides a mock function for the type BackupRepo +func (_mock *BackupRepo) ConcatenateObjects(ctx context.Context, objectIDs []udmrepo.ID) (udmrepo.ID, error) { + ret := _mock.Called(ctx, objectIDs) if len(ret) == 0 { panic("no return value specified for ConcatenateObjects") @@ -44,45 +100,179 @@ func (_m *BackupRepo) ConcatenateObjects(ctx context.Context, objectIDs []udmrep var r0 udmrepo.ID var r1 error - if rf, ok := ret.Get(0).(func(context.Context, []udmrepo.ID) (udmrepo.ID, error)); ok { - return rf(ctx, objectIDs) + if returnFunc, ok := ret.Get(0).(func(context.Context, []udmrepo.ID) (udmrepo.ID, error)); ok { + return returnFunc(ctx, objectIDs) } - if rf, ok := ret.Get(0).(func(context.Context, []udmrepo.ID) udmrepo.ID); ok { - r0 = rf(ctx, objectIDs) + if returnFunc, ok := ret.Get(0).(func(context.Context, []udmrepo.ID) udmrepo.ID); ok { + r0 = returnFunc(ctx, objectIDs) } else { r0 = ret.Get(0).(udmrepo.ID) } - - if rf, ok := ret.Get(1).(func(context.Context, []udmrepo.ID) error); ok { - r1 = rf(ctx, objectIDs) + if returnFunc, ok := ret.Get(1).(func(context.Context, []udmrepo.ID) error); ok { + r1 = returnFunc(ctx, objectIDs) } else { r1 = ret.Error(1) } - return r0, r1 } -// DeleteManifest provides a mock function with given fields: ctx, id -func (_m *BackupRepo) DeleteManifest(ctx context.Context, id udmrepo.ID) error { - ret := _m.Called(ctx, id) +// BackupRepo_ConcatenateObjects_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConcatenateObjects' +type BackupRepo_ConcatenateObjects_Call struct { + *mock.Call +} + +// ConcatenateObjects is a helper method to define mock.On call +// - ctx context.Context +// - objectIDs []udmrepo.ID +func (_e *BackupRepo_Expecter) ConcatenateObjects(ctx interface{}, objectIDs interface{}) *BackupRepo_ConcatenateObjects_Call { + return &BackupRepo_ConcatenateObjects_Call{Call: _e.mock.On("ConcatenateObjects", ctx, objectIDs)} +} + +func (_c *BackupRepo_ConcatenateObjects_Call) Run(run func(ctx context.Context, objectIDs []udmrepo.ID)) *BackupRepo_ConcatenateObjects_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 []udmrepo.ID + if args[1] != nil { + arg1 = args[1].([]udmrepo.ID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_ConcatenateObjects_Call) Return(iD udmrepo.ID, err error) *BackupRepo_ConcatenateObjects_Call { + _c.Call.Return(iD, err) + return _c +} + +func (_c *BackupRepo_ConcatenateObjects_Call) RunAndReturn(run func(ctx context.Context, objectIDs []udmrepo.ID) (udmrepo.ID, error)) *BackupRepo_ConcatenateObjects_Call { + _c.Call.Return(run) + return _c +} + +// DeleteManifest provides a mock function for the type BackupRepo +func (_mock *BackupRepo) DeleteManifest(ctx context.Context, id udmrepo.ID) error { + ret := _mock.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for DeleteManifest") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.ID) error); ok { - r0 = rf(ctx, id) + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID) error); ok { + r0 = returnFunc(ctx, id) } else { r0 = ret.Error(0) } + return r0 +} + +// BackupRepo_DeleteManifest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteManifest' +type BackupRepo_DeleteManifest_Call struct { + *mock.Call +} + +// DeleteManifest is a helper method to define mock.On call +// - ctx context.Context +// - id udmrepo.ID +func (_e *BackupRepo_Expecter) DeleteManifest(ctx interface{}, id interface{}) *BackupRepo_DeleteManifest_Call { + return &BackupRepo_DeleteManifest_Call{Call: _e.mock.On("DeleteManifest", ctx, id)} +} + +func (_c *BackupRepo_DeleteManifest_Call) Run(run func(ctx context.Context, id udmrepo.ID)) *BackupRepo_DeleteManifest_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.ID + if args[1] != nil { + arg1 = args[1].(udmrepo.ID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_DeleteManifest_Call) Return(err error) *BackupRepo_DeleteManifest_Call { + _c.Call.Return(err) + return _c +} +func (_c *BackupRepo_DeleteManifest_Call) RunAndReturn(run func(ctx context.Context, id udmrepo.ID) error) *BackupRepo_DeleteManifest_Call { + _c.Call.Return(run) + return _c +} + +// DeleteSnapshot provides a mock function for the type BackupRepo +func (_mock *BackupRepo) DeleteSnapshot(ctx context.Context, id udmrepo.ID) error { + ret := _mock.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for DeleteSnapshot") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID) error); ok { + r0 = returnFunc(ctx, id) + } else { + r0 = ret.Error(0) + } return r0 } -// FindManifests provides a mock function with given fields: ctx, filter -func (_m *BackupRepo) FindManifests(ctx context.Context, filter udmrepo.ManifestFilter) ([]*udmrepo.ManifestEntryMetadata, error) { - ret := _m.Called(ctx, filter) +// BackupRepo_DeleteSnapshot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteSnapshot' +type BackupRepo_DeleteSnapshot_Call struct { + *mock.Call +} + +// DeleteSnapshot is a helper method to define mock.On call +// - ctx context.Context +// - id udmrepo.ID +func (_e *BackupRepo_Expecter) DeleteSnapshot(ctx interface{}, id interface{}) *BackupRepo_DeleteSnapshot_Call { + return &BackupRepo_DeleteSnapshot_Call{Call: _e.mock.On("DeleteSnapshot", ctx, id)} +} + +func (_c *BackupRepo_DeleteSnapshot_Call) Run(run func(ctx context.Context, id udmrepo.ID)) *BackupRepo_DeleteSnapshot_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.ID + if args[1] != nil { + arg1 = args[1].(udmrepo.ID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_DeleteSnapshot_Call) Return(err error) *BackupRepo_DeleteSnapshot_Call { + _c.Call.Return(err) + return _c +} + +func (_c *BackupRepo_DeleteSnapshot_Call) RunAndReturn(run func(ctx context.Context, id udmrepo.ID) error) *BackupRepo_DeleteSnapshot_Call { + _c.Call.Return(run) + return _c +} + +// FindManifests provides a mock function for the type BackupRepo +func (_mock *BackupRepo) FindManifests(ctx context.Context, filter udmrepo.ManifestFilter) ([]*udmrepo.ManifestEntryMetadata, error) { + ret := _mock.Called(ctx, filter) if len(ret) == 0 { panic("no return value specified for FindManifests") @@ -90,103 +280,359 @@ func (_m *BackupRepo) FindManifests(ctx context.Context, filter udmrepo.Manifest var r0 []*udmrepo.ManifestEntryMetadata var r1 error - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.ManifestFilter) ([]*udmrepo.ManifestEntryMetadata, error)); ok { - return rf(ctx, filter) + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ManifestFilter) ([]*udmrepo.ManifestEntryMetadata, error)); ok { + return returnFunc(ctx, filter) } - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.ManifestFilter) []*udmrepo.ManifestEntryMetadata); ok { - r0 = rf(ctx, filter) + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ManifestFilter) []*udmrepo.ManifestEntryMetadata); ok { + r0 = returnFunc(ctx, filter) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*udmrepo.ManifestEntryMetadata) } } - - if rf, ok := ret.Get(1).(func(context.Context, udmrepo.ManifestFilter) error); ok { - r1 = rf(ctx, filter) + if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.ManifestFilter) error); ok { + r1 = returnFunc(ctx, filter) } else { r1 = ret.Error(1) } - return r0, r1 } -// Flush provides a mock function with given fields: ctx -func (_m *BackupRepo) Flush(ctx context.Context) error { - ret := _m.Called(ctx) +// BackupRepo_FindManifests_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindManifests' +type BackupRepo_FindManifests_Call struct { + *mock.Call +} + +// FindManifests is a helper method to define mock.On call +// - ctx context.Context +// - filter udmrepo.ManifestFilter +func (_e *BackupRepo_Expecter) FindManifests(ctx interface{}, filter interface{}) *BackupRepo_FindManifests_Call { + return &BackupRepo_FindManifests_Call{Call: _e.mock.On("FindManifests", ctx, filter)} +} + +func (_c *BackupRepo_FindManifests_Call) Run(run func(ctx context.Context, filter udmrepo.ManifestFilter)) *BackupRepo_FindManifests_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.ManifestFilter + if args[1] != nil { + arg1 = args[1].(udmrepo.ManifestFilter) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_FindManifests_Call) Return(manifestEntryMetadatas []*udmrepo.ManifestEntryMetadata, err error) *BackupRepo_FindManifests_Call { + _c.Call.Return(manifestEntryMetadatas, err) + return _c +} + +func (_c *BackupRepo_FindManifests_Call) RunAndReturn(run func(ctx context.Context, filter udmrepo.ManifestFilter) ([]*udmrepo.ManifestEntryMetadata, error)) *BackupRepo_FindManifests_Call { + _c.Call.Return(run) + return _c +} + +// Flush provides a mock function for the type BackupRepo +func (_mock *BackupRepo) Flush(ctx context.Context) error { + ret := _mock.Called(ctx) if len(ret) == 0 { panic("no return value specified for Flush") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) + if returnFunc, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = returnFunc(ctx) } else { r0 = ret.Error(0) } - return r0 } -// GetAdvancedFeatures provides a mock function with given fields: -func (_m *BackupRepo) GetAdvancedFeatures() udmrepo.AdvancedFeatureInfo { - ret := _m.Called() +// BackupRepo_Flush_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Flush' +type BackupRepo_Flush_Call struct { + *mock.Call +} + +// Flush is a helper method to define mock.On call +// - ctx context.Context +func (_e *BackupRepo_Expecter) Flush(ctx interface{}) *BackupRepo_Flush_Call { + return &BackupRepo_Flush_Call{Call: _e.mock.On("Flush", ctx)} +} + +func (_c *BackupRepo_Flush_Call) Run(run func(ctx context.Context)) *BackupRepo_Flush_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *BackupRepo_Flush_Call) Return(err error) *BackupRepo_Flush_Call { + _c.Call.Return(err) + return _c +} + +func (_c *BackupRepo_Flush_Call) RunAndReturn(run func(ctx context.Context) error) *BackupRepo_Flush_Call { + _c.Call.Return(run) + return _c +} + +// GetAdvancedFeatures provides a mock function for the type BackupRepo +func (_mock *BackupRepo) GetAdvancedFeatures() udmrepo.AdvancedFeatureInfo { + ret := _mock.Called() if len(ret) == 0 { panic("no return value specified for GetAdvancedFeatures") } var r0 udmrepo.AdvancedFeatureInfo - if rf, ok := ret.Get(0).(func() udmrepo.AdvancedFeatureInfo); ok { - r0 = rf() + if returnFunc, ok := ret.Get(0).(func() udmrepo.AdvancedFeatureInfo); ok { + r0 = returnFunc() } else { r0 = ret.Get(0).(udmrepo.AdvancedFeatureInfo) } - return r0 } -// GetManifest provides a mock function with given fields: ctx, id, mani -func (_m *BackupRepo) GetManifest(ctx context.Context, id udmrepo.ID, mani *udmrepo.RepoManifest) error { - ret := _m.Called(ctx, id, mani) +// BackupRepo_GetAdvancedFeatures_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAdvancedFeatures' +type BackupRepo_GetAdvancedFeatures_Call struct { + *mock.Call +} + +// GetAdvancedFeatures is a helper method to define mock.On call +func (_e *BackupRepo_Expecter) GetAdvancedFeatures() *BackupRepo_GetAdvancedFeatures_Call { + return &BackupRepo_GetAdvancedFeatures_Call{Call: _e.mock.On("GetAdvancedFeatures")} +} + +func (_c *BackupRepo_GetAdvancedFeatures_Call) Run(run func()) *BackupRepo_GetAdvancedFeatures_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *BackupRepo_GetAdvancedFeatures_Call) Return(advancedFeatureInfo udmrepo.AdvancedFeatureInfo) *BackupRepo_GetAdvancedFeatures_Call { + _c.Call.Return(advancedFeatureInfo) + return _c +} + +func (_c *BackupRepo_GetAdvancedFeatures_Call) RunAndReturn(run func() udmrepo.AdvancedFeatureInfo) *BackupRepo_GetAdvancedFeatures_Call { + _c.Call.Return(run) + return _c +} + +// GetManifest provides a mock function for the type BackupRepo +func (_mock *BackupRepo) GetManifest(ctx context.Context, id udmrepo.ID, mani *udmrepo.RepoManifest) error { + ret := _mock.Called(ctx, id, mani) if len(ret) == 0 { panic("no return value specified for GetManifest") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.ID, *udmrepo.RepoManifest) error); ok { - r0 = rf(ctx, id, mani) + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID, *udmrepo.RepoManifest) error); ok { + r0 = returnFunc(ctx, id, mani) } else { r0 = ret.Error(0) } - return r0 } -// NewObjectWriter provides a mock function with given fields: ctx, opt -func (_m *BackupRepo) NewObjectWriter(ctx context.Context, opt udmrepo.ObjectWriteOptions) udmrepo.ObjectWriter { - ret := _m.Called(ctx, opt) +// BackupRepo_GetManifest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetManifest' +type BackupRepo_GetManifest_Call struct { + *mock.Call +} + +// GetManifest is a helper method to define mock.On call +// - ctx context.Context +// - id udmrepo.ID +// - mani *udmrepo.RepoManifest +func (_e *BackupRepo_Expecter) GetManifest(ctx interface{}, id interface{}, mani interface{}) *BackupRepo_GetManifest_Call { + return &BackupRepo_GetManifest_Call{Call: _e.mock.On("GetManifest", ctx, id, mani)} +} + +func (_c *BackupRepo_GetManifest_Call) Run(run func(ctx context.Context, id udmrepo.ID, mani *udmrepo.RepoManifest)) *BackupRepo_GetManifest_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.ID + if args[1] != nil { + arg1 = args[1].(udmrepo.ID) + } + var arg2 *udmrepo.RepoManifest + if args[2] != nil { + arg2 = args[2].(*udmrepo.RepoManifest) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *BackupRepo_GetManifest_Call) Return(err error) *BackupRepo_GetManifest_Call { + _c.Call.Return(err) + return _c +} + +func (_c *BackupRepo_GetManifest_Call) RunAndReturn(run func(ctx context.Context, id udmrepo.ID, mani *udmrepo.RepoManifest) error) *BackupRepo_GetManifest_Call { + _c.Call.Return(run) + return _c +} + +// GetSnapshot provides a mock function for the type BackupRepo +func (_mock *BackupRepo) GetSnapshot(ctx context.Context, id udmrepo.ID) (udmrepo.Snapshot, error) { + ret := _mock.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for GetSnapshot") + } + + var r0 udmrepo.Snapshot + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID) (udmrepo.Snapshot, error)); ok { + return returnFunc(ctx, id) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID) udmrepo.Snapshot); ok { + r0 = returnFunc(ctx, id) + } else { + r0 = ret.Get(0).(udmrepo.Snapshot) + } + if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.ID) error); ok { + r1 = returnFunc(ctx, id) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// BackupRepo_GetSnapshot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSnapshot' +type BackupRepo_GetSnapshot_Call struct { + *mock.Call +} + +// GetSnapshot is a helper method to define mock.On call +// - ctx context.Context +// - id udmrepo.ID +func (_e *BackupRepo_Expecter) GetSnapshot(ctx interface{}, id interface{}) *BackupRepo_GetSnapshot_Call { + return &BackupRepo_GetSnapshot_Call{Call: _e.mock.On("GetSnapshot", ctx, id)} +} + +func (_c *BackupRepo_GetSnapshot_Call) Run(run func(ctx context.Context, id udmrepo.ID)) *BackupRepo_GetSnapshot_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.ID + if args[1] != nil { + arg1 = args[1].(udmrepo.ID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_GetSnapshot_Call) Return(snapshot udmrepo.Snapshot, err error) *BackupRepo_GetSnapshot_Call { + _c.Call.Return(snapshot, err) + return _c +} + +func (_c *BackupRepo_GetSnapshot_Call) RunAndReturn(run func(ctx context.Context, id udmrepo.ID) (udmrepo.Snapshot, error)) *BackupRepo_GetSnapshot_Call { + _c.Call.Return(run) + return _c +} + +// NewObjectWriter provides a mock function for the type BackupRepo +func (_mock *BackupRepo) NewObjectWriter(ctx context.Context, opt udmrepo.ObjectWriteOptions) (udmrepo.ObjectWriter, error) { + ret := _mock.Called(ctx, opt) if len(ret) == 0 { panic("no return value specified for NewObjectWriter") } var r0 udmrepo.ObjectWriter - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.ObjectWriteOptions) udmrepo.ObjectWriter); ok { - r0 = rf(ctx, opt) + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ObjectWriteOptions) (udmrepo.ObjectWriter, error)); ok { + return returnFunc(ctx, opt) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ObjectWriteOptions) udmrepo.ObjectWriter); ok { + r0 = returnFunc(ctx, opt) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(udmrepo.ObjectWriter) } } + if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.ObjectWriteOptions) error); ok { + r1 = returnFunc(ctx, opt) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} - return r0 +// BackupRepo_NewObjectWriter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewObjectWriter' +type BackupRepo_NewObjectWriter_Call struct { + *mock.Call +} + +// NewObjectWriter is a helper method to define mock.On call +// - ctx context.Context +// - opt udmrepo.ObjectWriteOptions +func (_e *BackupRepo_Expecter) NewObjectWriter(ctx interface{}, opt interface{}) *BackupRepo_NewObjectWriter_Call { + return &BackupRepo_NewObjectWriter_Call{Call: _e.mock.On("NewObjectWriter", ctx, opt)} +} + +func (_c *BackupRepo_NewObjectWriter_Call) Run(run func(ctx context.Context, opt udmrepo.ObjectWriteOptions)) *BackupRepo_NewObjectWriter_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.ObjectWriteOptions + if args[1] != nil { + arg1 = args[1].(udmrepo.ObjectWriteOptions) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_NewObjectWriter_Call) Return(objectWriter udmrepo.ObjectWriter, err error) *BackupRepo_NewObjectWriter_Call { + _c.Call.Return(objectWriter, err) + return _c +} + +func (_c *BackupRepo_NewObjectWriter_Call) RunAndReturn(run func(ctx context.Context, opt udmrepo.ObjectWriteOptions) (udmrepo.ObjectWriter, error)) *BackupRepo_NewObjectWriter_Call { + _c.Call.Return(run) + return _c } -// OpenObject provides a mock function with given fields: ctx, id -func (_m *BackupRepo) OpenObject(ctx context.Context, id udmrepo.ID) (udmrepo.ObjectReader, error) { - ret := _m.Called(ctx, id) +// OpenObject provides a mock function for the type BackupRepo +func (_mock *BackupRepo) OpenObject(ctx context.Context, id udmrepo.ID) (udmrepo.ObjectReader, error) { + ret := _mock.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for OpenObject") @@ -194,29 +640,67 @@ func (_m *BackupRepo) OpenObject(ctx context.Context, id udmrepo.ID) (udmrepo.Ob var r0 udmrepo.ObjectReader var r1 error - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.ID) (udmrepo.ObjectReader, error)); ok { - return rf(ctx, id) + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID) (udmrepo.ObjectReader, error)); ok { + return returnFunc(ctx, id) } - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.ID) udmrepo.ObjectReader); ok { - r0 = rf(ctx, id) + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID) udmrepo.ObjectReader); ok { + r0 = returnFunc(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(udmrepo.ObjectReader) } } - - if rf, ok := ret.Get(1).(func(context.Context, udmrepo.ID) error); ok { - r1 = rf(ctx, id) + if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.ID) error); ok { + r1 = returnFunc(ctx, id) } else { r1 = ret.Error(1) } - return r0, r1 } -// PutManifest provides a mock function with given fields: ctx, mani -func (_m *BackupRepo) PutManifest(ctx context.Context, mani udmrepo.RepoManifest) (udmrepo.ID, error) { - ret := _m.Called(ctx, mani) +// BackupRepo_OpenObject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OpenObject' +type BackupRepo_OpenObject_Call struct { + *mock.Call +} + +// OpenObject is a helper method to define mock.On call +// - ctx context.Context +// - id udmrepo.ID +func (_e *BackupRepo_Expecter) OpenObject(ctx interface{}, id interface{}) *BackupRepo_OpenObject_Call { + return &BackupRepo_OpenObject_Call{Call: _e.mock.On("OpenObject", ctx, id)} +} + +func (_c *BackupRepo_OpenObject_Call) Run(run func(ctx context.Context, id udmrepo.ID)) *BackupRepo_OpenObject_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.ID + if args[1] != nil { + arg1 = args[1].(udmrepo.ID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_OpenObject_Call) Return(objectReader udmrepo.ObjectReader, err error) *BackupRepo_OpenObject_Call { + _c.Call.Return(objectReader, err) + return _c +} + +func (_c *BackupRepo_OpenObject_Call) RunAndReturn(run func(ctx context.Context, id udmrepo.ID) (udmrepo.ObjectReader, error)) *BackupRepo_OpenObject_Call { + _c.Call.Return(run) + return _c +} + +// PutManifest provides a mock function for the type BackupRepo +func (_mock *BackupRepo) PutManifest(ctx context.Context, mani udmrepo.RepoManifest) (udmrepo.ID, error) { + ret := _mock.Called(ctx, mani) if len(ret) == 0 { panic("no return value specified for PutManifest") @@ -224,52 +708,308 @@ func (_m *BackupRepo) PutManifest(ctx context.Context, mani udmrepo.RepoManifest var r0 udmrepo.ID var r1 error - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoManifest) (udmrepo.ID, error)); ok { - return rf(ctx, mani) + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoManifest) (udmrepo.ID, error)); ok { + return returnFunc(ctx, mani) } - if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoManifest) udmrepo.ID); ok { - r0 = rf(ctx, mani) + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoManifest) udmrepo.ID); ok { + r0 = returnFunc(ctx, mani) } else { r0 = ret.Get(0).(udmrepo.ID) } + if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.RepoManifest) error); ok { + r1 = returnFunc(ctx, mani) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} - if rf, ok := ret.Get(1).(func(context.Context, udmrepo.RepoManifest) error); ok { - r1 = rf(ctx, mani) +// BackupRepo_PutManifest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PutManifest' +type BackupRepo_PutManifest_Call struct { + *mock.Call +} + +// PutManifest is a helper method to define mock.On call +// - ctx context.Context +// - mani udmrepo.RepoManifest +func (_e *BackupRepo_Expecter) PutManifest(ctx interface{}, mani interface{}) *BackupRepo_PutManifest_Call { + return &BackupRepo_PutManifest_Call{Call: _e.mock.On("PutManifest", ctx, mani)} +} + +func (_c *BackupRepo_PutManifest_Call) Run(run func(ctx context.Context, mani udmrepo.RepoManifest)) *BackupRepo_PutManifest_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.RepoManifest + if args[1] != nil { + arg1 = args[1].(udmrepo.RepoManifest) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_PutManifest_Call) Return(iD udmrepo.ID, err error) *BackupRepo_PutManifest_Call { + _c.Call.Return(iD, err) + return _c +} + +func (_c *BackupRepo_PutManifest_Call) RunAndReturn(run func(ctx context.Context, mani udmrepo.RepoManifest) (udmrepo.ID, error)) *BackupRepo_PutManifest_Call { + _c.Call.Return(run) + return _c +} + +// ReadMetadata provides a mock function for the type BackupRepo +func (_mock *BackupRepo) ReadMetadata(ctx context.Context, id udmrepo.ID) (*udmrepo.Metadata, error) { + ret := _mock.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for ReadMetadata") + } + + var r0 *udmrepo.Metadata + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID) (*udmrepo.Metadata, error)); ok { + return returnFunc(ctx, id) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.ID) *udmrepo.Metadata); ok { + r0 = returnFunc(ctx, id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*udmrepo.Metadata) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.ID) error); ok { + r1 = returnFunc(ctx, id) } else { r1 = ret.Error(1) } + return r0, r1 +} + +// BackupRepo_ReadMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadMetadata' +type BackupRepo_ReadMetadata_Call struct { + *mock.Call +} + +// ReadMetadata is a helper method to define mock.On call +// - ctx context.Context +// - id udmrepo.ID +func (_e *BackupRepo_Expecter) ReadMetadata(ctx interface{}, id interface{}) *BackupRepo_ReadMetadata_Call { + return &BackupRepo_ReadMetadata_Call{Call: _e.mock.On("ReadMetadata", ctx, id)} +} + +func (_c *BackupRepo_ReadMetadata_Call) Run(run func(ctx context.Context, id udmrepo.ID)) *BackupRepo_ReadMetadata_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.ID + if args[1] != nil { + arg1 = args[1].(udmrepo.ID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_ReadMetadata_Call) Return(metadata *udmrepo.Metadata, err error) *BackupRepo_ReadMetadata_Call { + _c.Call.Return(metadata, err) + return _c +} + +func (_c *BackupRepo_ReadMetadata_Call) RunAndReturn(run func(ctx context.Context, id udmrepo.ID) (*udmrepo.Metadata, error)) *BackupRepo_ReadMetadata_Call { + _c.Call.Return(run) + return _c +} + +// SaveSnapshot provides a mock function for the type BackupRepo +func (_mock *BackupRepo) SaveSnapshot(ctx context.Context, snapshot udmrepo.Snapshot) (udmrepo.ID, error) { + ret := _mock.Called(ctx, snapshot) + + if len(ret) == 0 { + panic("no return value specified for SaveSnapshot") + } + var r0 udmrepo.ID + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.Snapshot) (udmrepo.ID, error)); ok { + return returnFunc(ctx, snapshot) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.Snapshot) udmrepo.ID); ok { + r0 = returnFunc(ctx, snapshot) + } else { + r0 = ret.Get(0).(udmrepo.ID) + } + if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.Snapshot) error); ok { + r1 = returnFunc(ctx, snapshot) + } else { + r1 = ret.Error(1) + } return r0, r1 } -// Time provides a mock function with given fields: -func (_m *BackupRepo) Time() time.Time { - ret := _m.Called() +// BackupRepo_SaveSnapshot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveSnapshot' +type BackupRepo_SaveSnapshot_Call struct { + *mock.Call +} + +// SaveSnapshot is a helper method to define mock.On call +// - ctx context.Context +// - snapshot udmrepo.Snapshot +func (_e *BackupRepo_Expecter) SaveSnapshot(ctx interface{}, snapshot interface{}) *BackupRepo_SaveSnapshot_Call { + return &BackupRepo_SaveSnapshot_Call{Call: _e.mock.On("SaveSnapshot", ctx, snapshot)} +} + +func (_c *BackupRepo_SaveSnapshot_Call) Run(run func(ctx context.Context, snapshot udmrepo.Snapshot)) *BackupRepo_SaveSnapshot_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 udmrepo.Snapshot + if args[1] != nil { + arg1 = args[1].(udmrepo.Snapshot) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BackupRepo_SaveSnapshot_Call) Return(iD udmrepo.ID, err error) *BackupRepo_SaveSnapshot_Call { + _c.Call.Return(iD, err) + return _c +} + +func (_c *BackupRepo_SaveSnapshot_Call) RunAndReturn(run func(ctx context.Context, snapshot udmrepo.Snapshot) (udmrepo.ID, error)) *BackupRepo_SaveSnapshot_Call { + _c.Call.Return(run) + return _c +} + +// Time provides a mock function for the type BackupRepo +func (_mock *BackupRepo) Time() time.Time { + ret := _mock.Called() if len(ret) == 0 { panic("no return value specified for Time") } var r0 time.Time - if rf, ok := ret.Get(0).(func() time.Time); ok { - r0 = rf() + if returnFunc, ok := ret.Get(0).(func() time.Time); ok { + r0 = returnFunc() } else { r0 = ret.Get(0).(time.Time) } - return r0 } -// NewBackupRepo creates a new instance of BackupRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewBackupRepo(t interface { - mock.TestingT - Cleanup(func()) -}) *BackupRepo { - mock := &BackupRepo{} - mock.Mock.Test(t) +// BackupRepo_Time_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Time' +type BackupRepo_Time_Call struct { + *mock.Call +} - t.Cleanup(func() { mock.AssertExpectations(t) }) +// Time is a helper method to define mock.On call +func (_e *BackupRepo_Expecter) Time() *BackupRepo_Time_Call { + return &BackupRepo_Time_Call{Call: _e.mock.On("Time")} +} - return mock +func (_c *BackupRepo_Time_Call) Run(run func()) *BackupRepo_Time_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *BackupRepo_Time_Call) Return(time1 time.Time) *BackupRepo_Time_Call { + _c.Call.Return(time1) + return _c +} + +func (_c *BackupRepo_Time_Call) RunAndReturn(run func() time.Time) *BackupRepo_Time_Call { + _c.Call.Return(run) + return _c +} + +// WriteMetadata provides a mock function for the type BackupRepo +func (_mock *BackupRepo) WriteMetadata(ctx context.Context, meta *udmrepo.Metadata, opt udmrepo.ObjectWriteOptions) (udmrepo.ID, error) { + ret := _mock.Called(ctx, meta, opt) + + if len(ret) == 0 { + panic("no return value specified for WriteMetadata") + } + + var r0 udmrepo.ID + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, *udmrepo.Metadata, udmrepo.ObjectWriteOptions) (udmrepo.ID, error)); ok { + return returnFunc(ctx, meta, opt) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, *udmrepo.Metadata, udmrepo.ObjectWriteOptions) udmrepo.ID); ok { + r0 = returnFunc(ctx, meta, opt) + } else { + r0 = ret.Get(0).(udmrepo.ID) + } + if returnFunc, ok := ret.Get(1).(func(context.Context, *udmrepo.Metadata, udmrepo.ObjectWriteOptions) error); ok { + r1 = returnFunc(ctx, meta, opt) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// BackupRepo_WriteMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteMetadata' +type BackupRepo_WriteMetadata_Call struct { + *mock.Call +} + +// WriteMetadata is a helper method to define mock.On call +// - ctx context.Context +// - meta *udmrepo.Metadata +// - opt udmrepo.ObjectWriteOptions +func (_e *BackupRepo_Expecter) WriteMetadata(ctx interface{}, meta interface{}, opt interface{}) *BackupRepo_WriteMetadata_Call { + return &BackupRepo_WriteMetadata_Call{Call: _e.mock.On("WriteMetadata", ctx, meta, opt)} +} + +func (_c *BackupRepo_WriteMetadata_Call) Run(run func(ctx context.Context, meta *udmrepo.Metadata, opt udmrepo.ObjectWriteOptions)) *BackupRepo_WriteMetadata_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 *udmrepo.Metadata + if args[1] != nil { + arg1 = args[1].(*udmrepo.Metadata) + } + var arg2 udmrepo.ObjectWriteOptions + if args[2] != nil { + arg2 = args[2].(udmrepo.ObjectWriteOptions) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *BackupRepo_WriteMetadata_Call) Return(iD udmrepo.ID, err error) *BackupRepo_WriteMetadata_Call { + _c.Call.Return(iD, err) + return _c +} + +func (_c *BackupRepo_WriteMetadata_Call) RunAndReturn(run func(ctx context.Context, meta *udmrepo.Metadata, opt udmrepo.ObjectWriteOptions) (udmrepo.ID, error)) *BackupRepo_WriteMetadata_Call { + _c.Call.Return(run) + return _c } diff --git a/pkg/repository/udmrepo/mocks/ObjectWriter.go b/pkg/repository/udmrepo/mocks/ObjectWriter.go index 4bc21f8b79..d50a3ce768 100644 --- a/pkg/repository/udmrepo/mocks/ObjectWriter.go +++ b/pkg/repository/udmrepo/mocks/ObjectWriter.go @@ -1,20 +1,44 @@ -// Code generated by mockery v2.39.1. DO NOT EDIT. +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify package mocks import ( mock "github.com/stretchr/testify/mock" - udmrepo "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" + "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" ) +// NewObjectWriter creates a new instance of ObjectWriter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewObjectWriter(t interface { + mock.TestingT + Cleanup(func()) +}) *ObjectWriter { + mock := &ObjectWriter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + // ObjectWriter is an autogenerated mock type for the ObjectWriter type type ObjectWriter struct { mock.Mock } -// Checkpoint provides a mock function with given fields: -func (_m *ObjectWriter) Checkpoint() (udmrepo.ID, error) { - ret := _m.Called() +type ObjectWriter_Expecter struct { + mock *mock.Mock +} + +func (_m *ObjectWriter) EXPECT() *ObjectWriter_Expecter { + return &ObjectWriter_Expecter{mock: &_m.Mock} +} + +// Checkpoint provides a mock function for the type ObjectWriter +func (_mock *ObjectWriter) Checkpoint() (udmrepo.ID, error) { + ret := _mock.Called() if len(ret) == 0 { panic("no return value specified for Checkpoint") @@ -22,45 +46,96 @@ func (_m *ObjectWriter) Checkpoint() (udmrepo.ID, error) { var r0 udmrepo.ID var r1 error - if rf, ok := ret.Get(0).(func() (udmrepo.ID, error)); ok { - return rf() + if returnFunc, ok := ret.Get(0).(func() (udmrepo.ID, error)); ok { + return returnFunc() } - if rf, ok := ret.Get(0).(func() udmrepo.ID); ok { - r0 = rf() + if returnFunc, ok := ret.Get(0).(func() udmrepo.ID); ok { + r0 = returnFunc() } else { r0 = ret.Get(0).(udmrepo.ID) } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if returnFunc, ok := ret.Get(1).(func() error); ok { + r1 = returnFunc() } else { r1 = ret.Error(1) } - return r0, r1 } -// Close provides a mock function with given fields: -func (_m *ObjectWriter) Close() error { - ret := _m.Called() +// ObjectWriter_Checkpoint_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Checkpoint' +type ObjectWriter_Checkpoint_Call struct { + *mock.Call +} + +// Checkpoint is a helper method to define mock.On call +func (_e *ObjectWriter_Expecter) Checkpoint() *ObjectWriter_Checkpoint_Call { + return &ObjectWriter_Checkpoint_Call{Call: _e.mock.On("Checkpoint")} +} + +func (_c *ObjectWriter_Checkpoint_Call) Run(run func()) *ObjectWriter_Checkpoint_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ObjectWriter_Checkpoint_Call) Return(iD udmrepo.ID, err error) *ObjectWriter_Checkpoint_Call { + _c.Call.Return(iD, err) + return _c +} + +func (_c *ObjectWriter_Checkpoint_Call) RunAndReturn(run func() (udmrepo.ID, error)) *ObjectWriter_Checkpoint_Call { + _c.Call.Return(run) + return _c +} + +// Close provides a mock function for the type ObjectWriter +func (_mock *ObjectWriter) Close() error { + ret := _mock.Called() if len(ret) == 0 { panic("no return value specified for Close") } var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() + if returnFunc, ok := ret.Get(0).(func() error); ok { + r0 = returnFunc() } else { r0 = ret.Error(0) } - return r0 } -// Result provides a mock function with given fields: -func (_m *ObjectWriter) Result() (udmrepo.ID, error) { - ret := _m.Called() +// ObjectWriter_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type ObjectWriter_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *ObjectWriter_Expecter) Close() *ObjectWriter_Close_Call { + return &ObjectWriter_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *ObjectWriter_Close_Call) Run(run func()) *ObjectWriter_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ObjectWriter_Close_Call) Return(err error) *ObjectWriter_Close_Call { + _c.Call.Return(err) + return _c +} + +func (_c *ObjectWriter_Close_Call) RunAndReturn(run func() error) *ObjectWriter_Close_Call { + _c.Call.Return(run) + return _c +} + +// Result provides a mock function for the type ObjectWriter +func (_mock *ObjectWriter) Result() (udmrepo.ID, error) { + ret := _mock.Called() if len(ret) == 0 { panic("no return value specified for Result") @@ -68,90 +143,171 @@ func (_m *ObjectWriter) Result() (udmrepo.ID, error) { var r0 udmrepo.ID var r1 error - if rf, ok := ret.Get(0).(func() (udmrepo.ID, error)); ok { - return rf() + if returnFunc, ok := ret.Get(0).(func() (udmrepo.ID, error)); ok { + return returnFunc() } - if rf, ok := ret.Get(0).(func() udmrepo.ID); ok { - r0 = rf() + if returnFunc, ok := ret.Get(0).(func() udmrepo.ID); ok { + r0 = returnFunc() } else { r0 = ret.Get(0).(udmrepo.ID) } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if returnFunc, ok := ret.Get(1).(func() error); ok { + r1 = returnFunc() } else { r1 = ret.Error(1) } - return r0, r1 } -// Seek provides a mock function with given fields: offset, whence -func (_m *ObjectWriter) Seek(offset int64, whence int) (int64, error) { - ret := _m.Called(offset, whence) +// ObjectWriter_Result_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Result' +type ObjectWriter_Result_Call struct { + *mock.Call +} + +// Result is a helper method to define mock.On call +func (_e *ObjectWriter_Expecter) Result() *ObjectWriter_Result_Call { + return &ObjectWriter_Result_Call{Call: _e.mock.On("Result")} +} + +func (_c *ObjectWriter_Result_Call) Run(run func()) *ObjectWriter_Result_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ObjectWriter_Result_Call) Return(iD udmrepo.ID, err error) *ObjectWriter_Result_Call { + _c.Call.Return(iD, err) + return _c +} + +func (_c *ObjectWriter_Result_Call) RunAndReturn(run func() (udmrepo.ID, error)) *ObjectWriter_Result_Call { + _c.Call.Return(run) + return _c +} + +// Write provides a mock function for the type ObjectWriter +func (_mock *ObjectWriter) Write(p []byte) (int, error) { + ret := _mock.Called(p) if len(ret) == 0 { - panic("no return value specified for Seek") + panic("no return value specified for Write") } - var r0 int64 + var r0 int var r1 error - if rf, ok := ret.Get(0).(func(int64, int) (int64, error)); ok { - return rf(offset, whence) + if returnFunc, ok := ret.Get(0).(func([]byte) (int, error)); ok { + return returnFunc(p) } - if rf, ok := ret.Get(0).(func(int64, int) int64); ok { - r0 = rf(offset, whence) + if returnFunc, ok := ret.Get(0).(func([]byte) int); ok { + r0 = returnFunc(p) } else { - r0 = ret.Get(0).(int64) + r0 = ret.Get(0).(int) } - - if rf, ok := ret.Get(1).(func(int64, int) error); ok { - r1 = rf(offset, whence) + if returnFunc, ok := ret.Get(1).(func([]byte) error); ok { + r1 = returnFunc(p) } else { r1 = ret.Error(1) } - return r0, r1 } -// Write provides a mock function with given fields: p -func (_m *ObjectWriter) Write(p []byte) (int, error) { - ret := _m.Called(p) +// ObjectWriter_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write' +type ObjectWriter_Write_Call struct { + *mock.Call +} + +// Write is a helper method to define mock.On call +// - p []byte +func (_e *ObjectWriter_Expecter) Write(p interface{}) *ObjectWriter_Write_Call { + return &ObjectWriter_Write_Call{Call: _e.mock.On("Write", p)} +} + +func (_c *ObjectWriter_Write_Call) Run(run func(p []byte)) *ObjectWriter_Write_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 []byte + if args[0] != nil { + arg0 = args[0].([]byte) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *ObjectWriter_Write_Call) Return(n int, err error) *ObjectWriter_Write_Call { + _c.Call.Return(n, err) + return _c +} + +func (_c *ObjectWriter_Write_Call) RunAndReturn(run func(p []byte) (int, error)) *ObjectWriter_Write_Call { + _c.Call.Return(run) + return _c +} + +// WriteAt provides a mock function for the type ObjectWriter +func (_mock *ObjectWriter) WriteAt(p []byte, off int64) (int, error) { + ret := _mock.Called(p, off) if len(ret) == 0 { - panic("no return value specified for Write") + panic("no return value specified for WriteAt") } var r0 int var r1 error - if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok { - return rf(p) + if returnFunc, ok := ret.Get(0).(func([]byte, int64) (int, error)); ok { + return returnFunc(p, off) } - if rf, ok := ret.Get(0).(func([]byte) int); ok { - r0 = rf(p) + if returnFunc, ok := ret.Get(0).(func([]byte, int64) int); ok { + r0 = returnFunc(p, off) } else { r0 = ret.Get(0).(int) } - - if rf, ok := ret.Get(1).(func([]byte) error); ok { - r1 = rf(p) + if returnFunc, ok := ret.Get(1).(func([]byte, int64) error); ok { + r1 = returnFunc(p, off) } else { r1 = ret.Error(1) } - return r0, r1 } -// NewObjectWriter creates a new instance of ObjectWriter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewObjectWriter(t interface { - mock.TestingT - Cleanup(func()) -}) *ObjectWriter { - mock := &ObjectWriter{} - mock.Mock.Test(t) +// ObjectWriter_WriteAt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteAt' +type ObjectWriter_WriteAt_Call struct { + *mock.Call +} - t.Cleanup(func() { mock.AssertExpectations(t) }) +// WriteAt is a helper method to define mock.On call +// - p []byte +// - off int64 +func (_e *ObjectWriter_Expecter) WriteAt(p interface{}, off interface{}) *ObjectWriter_WriteAt_Call { + return &ObjectWriter_WriteAt_Call{Call: _e.mock.On("WriteAt", p, off)} +} - return mock +func (_c *ObjectWriter_WriteAt_Call) Run(run func(p []byte, off int64)) *ObjectWriter_WriteAt_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 []byte + if args[0] != nil { + arg0 = args[0].([]byte) + } + var arg1 int64 + if args[1] != nil { + arg1 = args[1].(int64) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *ObjectWriter_WriteAt_Call) Return(n int, err error) *ObjectWriter_WriteAt_Call { + _c.Call.Return(n, err) + return _c +} + +func (_c *ObjectWriter_WriteAt_Call) RunAndReturn(run func(p []byte, off int64) (int, error)) *ObjectWriter_WriteAt_Call { + _c.Call.Return(run) + return _c } diff --git a/pkg/repository/udmrepo/repo.go b/pkg/repository/udmrepo/repo.go index 1e7e4d0117..095d18973f 100644 --- a/pkg/repository/udmrepo/repo.go +++ b/pkg/repository/udmrepo/repo.go @@ -62,19 +62,41 @@ const ( // ObjectWriteOptions defines the options when creating an object for write type ObjectWriteOptions struct { - FullPath string // Full logical path of the object - DataType int // OBJECT_DATA_TYPE_* - Description string // A description of the object, could be empty - Prefix ID // A prefix of the name used to save the object - AccessMode int // OBJECT_DATA_ACCESS_* - BackupMode int // OBJECT_DATA_BACKUP_* - AsyncWrites int // Num of async writes for the object, 0 means no async write + FullPath string // Full logical path of the object + DataType int // OBJECT_DATA_TYPE_* + Description string // A description of the object, could be empty + Prefix ID // A prefix of the name used to save the object + AccessMode int // OBJECT_DATA_ACCESS_* + BackupMode int // OBJECT_DATA_BACKUP_* + AsyncWrites int // Num of async writes for the object, 0 means no async write + ParentObject ID // The object in the previous snapshot, for incremental backup } type AdvancedFeatureInfo struct { MultiPartBackup bool // if set to true, it means the repo supports multiple-part backup } +type ObjectMetadata struct { + ID ID + Type int // OBJECT_DATA_TYPE_* + Size int64 +} + +type Metadata struct { + SubObjects []ObjectMetadata // For dir metadata only, the sub objects in this dir. + ExtraDataLen int // Extra data associated to this metadata. + ExtraData []byte +} + +type Snapshot struct { + Source string + Description string + StartTime time.Time + EndTime time.Time + Tags map[string]string + RootObject ID +} + // BackupRepoService is used to initialize, open or maintain a backup repository type BackupRepoService interface { // Create creates a new backup repository. @@ -119,7 +141,14 @@ type BackupRepo interface { // NewObjectWriter creates a new object and return the object's writer interface. // return: A unified identifier of the object on success. - NewObjectWriter(ctx context.Context, opt ObjectWriteOptions) ObjectWriter + NewObjectWriter(ctx context.Context, opt ObjectWriteOptions) (ObjectWriter, error) + + // WriteMetadata writes metadata to the repo, metadata is used to describe data, e.g., file system + // dirs are saved as metadata + WriteMetadata(ctx context.Context, meta *Metadata, opt ObjectWriteOptions) (ID, error) + + // ReadMetadata reads a metadata from repo by the metadata's object ID + ReadMetadata(ctx context.Context, id ID) (*Metadata, error) // PutManifest saves a manifest object into the backup repository. PutManifest(ctx context.Context, mani RepoManifest) (ID, error) @@ -139,6 +168,15 @@ type BackupRepo interface { // Time returns the local time of the backup repository. It may be different from the time of the caller Time() time.Time + // SaveSnapshot saves a repo snapshot + SaveSnapshot(ctx context.Context, snapshot Snapshot) (ID, error) + + // GetSnapshot returns a repo snapshot from snapshot ID + GetSnapshot(ctx context.Context, id ID) (Snapshot, error) + + // DeleteSnapshot deletes a repo snapshot + DeleteSnapshot(ctx context.Context, id ID) error + // Close closes the backup repository Close(ctx context.Context) error } @@ -154,8 +192,8 @@ type ObjectReader interface { type ObjectWriter interface { io.WriteCloser - // Seeker is used in the cases that the object is not written sequentially - io.Seeker + // WriterAt is used in the cases that the object is not written sequentially + io.WriterAt // Checkpoint is periodically called to preserve the state of data written to the repo so far. // Checkpoint returns a unified identifier that represent the current state. diff --git a/pkg/uploader/kopia/shim.go b/pkg/uploader/kopia/shim.go index 1b9812d487..f146348fad 100644 --- a/pkg/uploader/kopia/shim.go +++ b/pkg/uploader/kopia/shim.go @@ -183,8 +183,8 @@ func (sr *shimRepository) NewObjectWriter(ctx context.Context, option object.Wri opt.DataType = udmrepo.ObjectDataTypeData } - writer := sr.udmRepo.NewObjectWriter(ctx, opt) - if writer == nil { + writer, err := sr.udmRepo.NewObjectWriter(ctx, opt) + if err != nil || writer == nil { return nil } diff --git a/pkg/uploader/kopia/shim_test.go b/pkg/uploader/kopia/shim_test.go index 69d1605a6c..7933ec6b8f 100644 --- a/pkg/uploader/kopia/shim_test.go +++ b/pkg/uploader/kopia/shim_test.go @@ -66,7 +66,7 @@ func TestShimRepo(t *testing.T) { backupRepo.On("Flush", mock.Anything).Return(nil) NewShimRepo(backupRepo).Flush(ctx) - backupRepo.On("NewObjectWriter", mock.Anything, mock.Anything).Return(nil) + backupRepo.On("NewObjectWriter", mock.Anything, mock.Anything).Return(nil, nil) NewShimRepo(backupRepo).NewObjectWriter(ctx, object.WriterOptions{}) } From 8e9e6b4d3615547973702f5fd78524d15416f547 Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Thu, 16 Apr 2026 14:42:48 -0400 Subject: [PATCH 23/90] added parallel backup configuration to install docs (#9729) * added parallel backup configuration to install docs Signed-off-by: Scott Seago * Update site/content/docs/main/customize-installation.md Co-authored-by: Tiger Kaovilai Signed-off-by: Scott Seago --------- Signed-off-by: Scott Seago Co-authored-by: Tiger Kaovilai --- site/content/docs/main/customize-installation.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/site/content/docs/main/customize-installation.md b/site/content/docs/main/customize-installation.md index c73142fdf5..7774565f18 100644 --- a/site/content/docs/main/customize-installation.md +++ b/site/content/docs/main/customize-installation.md @@ -342,6 +342,12 @@ If you are installing Velero in Kubernetes 1.14.x or earlier, you need to use `k If you intend to use Velero with a storage provider that is secured by a self-signed certificate, you may need to instruct Velero to trust that certificate. See [use Velero with a storage provider secured by a self-signed certificate][9] for details. +## Enabling parallel/concurrent backup processing + +By default, only one backup is processed in the `InProgress` phase at a time. The install flag `concurrent-backups`, which takes an integer argument, configures Velero to process multiple backups at the same time, up to a max of `concurrent-backups`. The other restriction on parallel backup processing is that two backups which have any included namespaces in common may not run at the same time. For example, if `concurrent-backups` is set to 2 and two backups for "namespace1" are submitted at the same time, only one of those will be processed at the same time. On the other hand, if a backup for "namespace1" and another for "namespace2" are submitted, then both can be processed in parallel. Note that a whole-cluster backup (one which does not restrict to a set list of namespaces) includes all namespaces, and therefore it will not run in parallel with any other backup. + +Enabling parallel backups can provide a significant performance benefit for backups which contain a large number of Kubernetes resources or ones which contain a large number of smaller volumes. Backups dominated by large volumes will not see as much benefit, since the majority of time for those backups is spent waiting for the async phase to complete. A larger `concurrent-backups` configuration may require additional memory and CPU resources for the velero container. + ## Additional options Run `velero install --help` or see the [Helm chart documentation](https://vmware-tanzu.github.io/helm-charts/) for the full set of installation options. From 2ca4e46327301b7df03f1f95c9225471dde197aa Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Tue, 14 Apr 2026 15:42:24 +0800 Subject: [PATCH 24/90] add cbt interfaces Signed-off-by: Lyndon-Li --- .../unreleased/9716-Lyndon-Li | 0 pkg/cbtservice/service.go | 12 +++++ pkg/uploader/cbt/bitmap.go | 13 ++++- pkg/uploader/cbt/set.go | 49 +++++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) rename "changelogs/unreleased/9716-Lyndon-Li\342\200\216\342\200\216" => changelogs/unreleased/9716-Lyndon-Li (100%) create mode 100644 pkg/uploader/cbt/set.go diff --git "a/changelogs/unreleased/9716-Lyndon-Li\342\200\216\342\200\216" b/changelogs/unreleased/9716-Lyndon-Li similarity index 100% rename from "changelogs/unreleased/9716-Lyndon-Li\342\200\216\342\200\216" rename to changelogs/unreleased/9716-Lyndon-Li diff --git a/pkg/cbtservice/service.go b/pkg/cbtservice/service.go index 3c9344fbe7..96e43b2c47 100644 --- a/pkg/cbtservice/service.go +++ b/pkg/cbtservice/service.go @@ -24,6 +24,18 @@ type Range struct { Length int64 } +// SourceInfo is the information provided to the uploader, the uploader calls CBT service with this information +type SourceInfo struct { + // Snapshot is the identifier of the current snapshot + Snapshot string + + // ChangeID is the identifier associated to the current snapshot that is used as changeID for following backups + ChangeID string + + // VolumeID is the identifier uniquely identifier a volume in the storage to which the CBT is associated + VolumeID string +} + // Service defines the methods for CBT service which could be implemented by Kubernetes SnapshotMetadataService or other customized services type Service interface { // GetAllocatedBlocks enumerates the allocated blocks of the snapshot and call the record callback diff --git a/pkg/uploader/cbt/bitmap.go b/pkg/uploader/cbt/bitmap.go index 8e027cba65..6cf6e61e0b 100644 --- a/pkg/uploader/cbt/bitmap.go +++ b/pkg/uploader/cbt/bitmap.go @@ -23,6 +23,15 @@ type Bitmap interface { // Set sets bits within the provided range Set(cbtservice.Range) + // SetFull sets all bits to the bitmap + SetFull() + + // Snapshot returns snapshot of the bitmap + SourceID() string + + // ChangeID returns the changeID of the bitmap + ChangeID() string + // Iterator returns the iterator for the CBT Bitmap Iterator() Iterator } @@ -32,8 +41,8 @@ type Iterator interface { // ChangeID returns the changeID of the bitmap ChangeID() string - // SnapshotID returns snapshotID of the bitmap - SnapshotID() string + // Snapshot returns snapshot of the bitmap + Snapshot() string // BlockSize returns the granularity of the bitmap BlockSize() int diff --git a/pkg/uploader/cbt/set.go b/pkg/uploader/cbt/set.go new file mode 100644 index 0000000000..40e6e331cf --- /dev/null +++ b/pkg/uploader/cbt/set.go @@ -0,0 +1,49 @@ +/* +Copyright The Velero Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cbt + +import ( + "context" + + "github.com/vmware-tanzu/velero/pkg/cbtservice" +) + +// SetBitmapOrFull translates the allocated/changed blocks from CBT service to the given bitmap or set the bitmap to full when error happens +func SetBitmapOrFull(ctx context.Context, service cbtservice.Service, bitmap Bitmap) error { + var err error + if bitmap.ChangeID() == "" { + err = setFromAllocatedBlocks(ctx, service, bitmap) + } else { + err = setFromChangedBlocks(ctx, service, bitmap) + } + + if err != nil { + bitmap.SetFull() + } + + return err +} + +// TODO implement in following PRs +func setFromAllocatedBlocks(_ context.Context, _ cbtservice.Service, _ Bitmap) error { + return nil +} + +// TODO implement in following PRs +func setFromChangedBlocks(_ context.Context, _ cbtservice.Service, _ Bitmap) error { + return nil +} From a96a73d0d73ab87e4c9d0ae0db3819fbcdfce2ff Mon Sep 17 00:00:00 2001 From: Daniel Jiang Date: Tue, 21 Apr 2026 17:26:57 +0800 Subject: [PATCH 25/90] Set permissions to the actions This commit update the actions "Auto Assign Author", "Auto Label PRs", and "Auto Request Review" Signed-off-by: Daniel Jiang --- .github/workflows/auto_assign_prs.yml | 5 ++++- .github/workflows/auto_label_prs.yml | 5 ++++- .github/workflows/auto_request_review.yml | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/auto_assign_prs.yml b/.github/workflows/auto_assign_prs.yml index d827b697ad..9b915533c4 100644 --- a/.github/workflows/auto_assign_prs.yml +++ b/.github/workflows/auto_assign_prs.yml @@ -7,6 +7,10 @@ on: pull_request_target: types: [opened, reopened, ready_for_review] +permissions: + contents: read + pull-requests: write + jobs: # Automatically assigns reviewers and owner add-reviews: @@ -16,4 +20,3 @@ jobs: uses: kentaro-m/auto-assign-action@v2.0.0 with: configuration-path: ".github/auto-assignees.yml" - repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/auto_label_prs.yml b/.github/workflows/auto_label_prs.yml index a5d912af8d..042cc7e95d 100644 --- a/.github/workflows/auto_label_prs.yml +++ b/.github/workflows/auto_label_prs.yml @@ -8,6 +8,10 @@ on: pull_request_target: types: [opened, reopened, synchronize, ready_for_review] +permissions: + contents: read + pull-requests: write + jobs: # Automatically labels PRs based on file globs in the change. triage: @@ -15,5 +19,4 @@ jobs: steps: - uses: actions/labeler@v5 with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/labeler.yml diff --git a/.github/workflows/auto_request_review.yml b/.github/workflows/auto_request_review.yml index 83e7032ab2..ba64d151dc 100644 --- a/.github/workflows/auto_request_review.yml +++ b/.github/workflows/auto_request_review.yml @@ -5,6 +5,10 @@ on: pull_request_target: types: [opened, ready_for_review, reopened] +permissions: + contents: read + pull-requests: write + jobs: auto-request-review: name: Auto Request Review @@ -13,5 +17,4 @@ jobs: - name: Request a PR review based on files types/paths, and/or groups the author belongs to uses: necojackarc/auto-request-review@v0.13.0 with: - token: ${{ secrets.GITHUB_TOKEN }} config: .github/auto-assignees.yml From da3e7cfaaf61b52a8a497fba101966f7d03f1222 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 21 Apr 2026 16:15:09 +0800 Subject: [PATCH 26/90] Remove Restic code path from PodVolumeRestore. Signed-off-by: Xun Jiang --- changelogs/unreleased/9732-blackpiglet | 1 + .../velero-restore-helper.go | 2 +- .../resourcepolicies/resource_policies.go | 2 +- pkg/cmd/cli/nodeagent/server.go | 48 --- pkg/cmd/server/server.go | 4 +- .../pod_volume_restore_controller.go | 14 +- .../pod_volume_restore_controller_legacy.go | 364 ------------------ ...d_volume_restore_controller_legacy_test.go | 93 ----- .../pod_volume_restore_controller_test.go | 39 +- 9 files changed, 43 insertions(+), 524 deletions(-) create mode 100644 changelogs/unreleased/9732-blackpiglet delete mode 100644 pkg/controller/pod_volume_restore_controller_legacy.go delete mode 100644 pkg/controller/pod_volume_restore_controller_legacy_test.go diff --git a/changelogs/unreleased/9732-blackpiglet b/changelogs/unreleased/9732-blackpiglet new file mode 100644 index 0000000000..d110fa2d6f --- /dev/null +++ b/changelogs/unreleased/9732-blackpiglet @@ -0,0 +1 @@ +Remove Restic code path from PodVolumeRestore. \ No newline at end of file diff --git a/cmd/velero-restore-helper/velero-restore-helper.go b/cmd/velero-restore-helper/velero-restore-helper.go index d310f807e9..40a9421371 100644 --- a/cmd/velero-restore-helper/velero-restore-helper.go +++ b/cmd/velero-restore-helper/velero-restore-helper.go @@ -35,7 +35,7 @@ func main() { for { <-ticker.C if done() { - fmt.Println("All restic restores are done") + fmt.Println("All PodVolumeRestores are done") err := removeFolder() if err != nil { fmt.Println(err) diff --git a/internal/resourcepolicies/resource_policies.go b/internal/resourcepolicies/resource_policies.go index 6b5046e57b..3a173fce1e 100644 --- a/internal/resourcepolicies/resource_policies.go +++ b/internal/resourcepolicies/resource_policies.go @@ -38,7 +38,7 @@ const ( ConfigmapRefType string = "configmap" // skip action implies the volume would be skipped from the backup operation Skip VolumeActionType = "skip" - // fs-backup action implies that the volume would be backed up via file system copy method using the uploader(kopia/restic) configured by the user + // fs-backup action implies that the volume would be backed up via file system copy method using the uploader(kopia) configured by the user FSBackup VolumeActionType = "fs-backup" // snapshot action can have 3 different meaning based on velero configuration and backup spec - cloud provider based snapshots, local csi snapshots and datamover snapshots Snapshot VolumeActionType = "snapshot" diff --git a/pkg/cmd/cli/nodeagent/server.go b/pkg/cmd/cli/nodeagent/server.go index 7e7c86e6c0..bb1764cb32 100644 --- a/pkg/cmd/cli/nodeagent/server.go +++ b/pkg/cmd/cli/nodeagent/server.go @@ -37,7 +37,6 @@ import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/kubernetes" cacheutil "k8s.io/client-go/tools/cache" @@ -430,10 +429,6 @@ func (s *nodeAgentServer) run() { s.logger.WithError(err).Fatal("Unable to create the pod volume restore controller") } - if err := controller.InitLegacyPodVolumeRestoreReconciler(s.mgr.GetClient(), s.mgr, s.kubeClient, s.dataPathMgr, s.namespace, s.config.resourceTimeout, s.logger); err != nil { - s.logger.WithError(err).Fatal("Unable to create the legacy pod volume restore controller") - } - dataUploadReconciler := controller.NewDataUploadReconciler( s.mgr.GetClient(), s.mgr, @@ -509,8 +504,6 @@ func (s *nodeAgentServer) run() { if err := pvrReconciler.AttemptPVRResume(s.ctx, s.logger.WithField("node", s.nodeName), s.namespace); err != nil { s.logger.WithError(errors.WithStack(err)).Error("Failed to attempt PVR resume") } - - s.markLegacyPVRsFailed(s.mgr.GetClient()) }() s.logger.Info("Controllers starting...") @@ -604,47 +597,6 @@ func (s *nodeAgentServer) validatePodVolumesHostPath(client kubernetes.Interface return nil } -func (s *nodeAgentServer) markLegacyPVRsFailed(client ctrlclient.Client) { - pvrs := &velerov1api.PodVolumeRestoreList{} - if err := client.List(s.ctx, pvrs, &ctrlclient.ListOptions{Namespace: s.namespace}); err != nil { - s.logger.WithError(errors.WithStack(err)).Error("failed to list podvolumerestores") - return - } - - for i, pvr := range pvrs.Items { - if !controller.IsLegacyPVR(&pvr) { - continue - } - - if pvr.Status.Phase != velerov1api.PodVolumeRestorePhaseInProgress { - s.logger.Debugf("the status of podvolumerestore %q is %q, skip", pvr.GetName(), pvr.Status.Phase) - continue - } - - pod := &corev1api.Pod{} - if err := client.Get(s.ctx, types.NamespacedName{ - Namespace: pvr.Spec.Pod.Namespace, - Name: pvr.Spec.Pod.Name, - }, pod); err != nil { - s.logger.WithError(errors.WithStack(err)).Errorf("failed to get pod \"%s/%s\" of podvolumerestore %q", - pvr.Spec.Pod.Namespace, pvr.Spec.Pod.Name, pvr.GetName()) - continue - } - if pod.Spec.NodeName != s.nodeName { - s.logger.Debugf("the node of pod referenced by podvolumerestore %q is %q, not %q, skip", pvr.GetName(), pod.Spec.NodeName, s.nodeName) - continue - } - - if err := controller.UpdatePVRStatusToFailed(s.ctx, client, &pvrs.Items[i], errors.New("cannot survive from node-agent restart"), - fmt.Sprintf("get a legacy podvolumerestore with status %q during the server starting, mark it as %q", velerov1api.PodVolumeRestorePhaseInProgress, velerov1api.PodVolumeRestorePhaseFailed), - time.Now(), s.logger); err != nil { - s.logger.WithError(errors.WithStack(err)).Errorf("failed to patch podvolumerestore %q", pvr.GetName()) - continue - } - s.logger.WithField("podvolumerestore", pvr.GetName()).Warn(pvr.Status.Message) - } -} - var getConfigsFunc = nodeagent.GetConfigs func (s *nodeAgentServer) getDataPathConfigs() error { diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go index cb38a40d0f..44c88b9800 100644 --- a/pkg/cmd/server/server.go +++ b/pkg/cmd/server/server.go @@ -1164,8 +1164,8 @@ func markPodVolumeRestoresCancel(ctx context.Context, client ctrlclient.Client, for i := range pvrs.Items { pvr := pvrs.Items[i] - if controller.IsLegacyPVR(&pvr) { - log.WithField("PVR", pvr.GetName()).Warn("Found a legacy PVR during velero server restart, cannot stop it") + if _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType); err != nil { + log.WithField("PVR", pvr.Name).Warnf("invalid uploader type %s, skip marking cancel for this PVR", pvr.Spec.UploaderType) continue } diff --git a/pkg/controller/pod_volume_restore_controller.go b/pkg/controller/pod_volume_restore_controller.go index 0af0d8c868..f40de528b2 100644 --- a/pkg/controller/pod_volume_restore_controller.go +++ b/pkg/controller/pod_volume_restore_controller.go @@ -603,7 +603,7 @@ func (r *PodVolumeRestoreReconciler) closeDataPath(ctx context.Context, pvrName func (r *PodVolumeRestoreReconciler) SetupWithManager(mgr ctrl.Manager) error { gp := kube.NewGenericEventPredicate(func(object client.Object) bool { pvr := object.(*velerov1api.PodVolumeRestore) - if IsLegacyPVR(pvr) { + if _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType); err != nil { return false } @@ -628,7 +628,8 @@ func (r *PodVolumeRestoreReconciler) SetupWithManager(mgr ctrl.Manager) error { pred := kube.NewAllEventPredicate(func(obj client.Object) bool { pvr := obj.(*velerov1api.PodVolumeRestore) - return !IsLegacyPVR(pvr) + _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType) + return err == nil }) return ctrl.NewControllerManagedBy(mgr). @@ -678,7 +679,7 @@ func (r *PodVolumeRestoreReconciler) findPVRForTargetPod(ctx context.Context, po requests := []reconcile.Request{} for _, item := range list.Items { - if IsLegacyPVR(&item) { + if _, err := uploader.ValidateUploaderType(item.Spec.UploaderType); err != nil { continue } @@ -708,6 +709,11 @@ func (r *PodVolumeRestoreReconciler) findPVRForRestorePod(ctx context.Context, p "PVR": pvr.Name, }) + if _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType); err != nil { + log.WithField("uploaderType", pvr.Spec.UploaderType).Debug("skip PVR with invalid uploader type") + return []reconcile.Request{} + } + if pvr.Status.Phase != velerov1api.PodVolumeRestorePhaseAccepted { return []reconcile.Request{} } @@ -1029,7 +1035,7 @@ func (r *PodVolumeRestoreReconciler) AttemptPVRResume(ctx context.Context, logge for i := range pvrs.Items { pvr := &pvrs.Items[i] - if IsLegacyPVR(pvr) { + if _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType); err != nil { continue } diff --git a/pkg/controller/pod_volume_restore_controller_legacy.go b/pkg/controller/pod_volume_restore_controller_legacy.go deleted file mode 100644 index 9ddececf58..0000000000 --- a/pkg/controller/pod_volume_restore_controller_legacy.go +++ /dev/null @@ -1,364 +0,0 @@ -/* -Copyright The Velero Contributors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - "fmt" - "os" - "path/filepath" - "time" - - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - corev1api "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes" - clocks "k8s.io/utils/clock" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - "github.com/vmware-tanzu/velero/internal/credentials" - veleroapishared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" - velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - "github.com/vmware-tanzu/velero/pkg/datapath" - "github.com/vmware-tanzu/velero/pkg/exposer" - "github.com/vmware-tanzu/velero/pkg/podvolume" - "github.com/vmware-tanzu/velero/pkg/repository" - "github.com/vmware-tanzu/velero/pkg/restorehelper" - "github.com/vmware-tanzu/velero/pkg/uploader" - "github.com/vmware-tanzu/velero/pkg/util/boolptr" - "github.com/vmware-tanzu/velero/pkg/util/filesystem" - "github.com/vmware-tanzu/velero/pkg/util/kube" -) - -func InitLegacyPodVolumeRestoreReconciler(client client.Client, mgr manager.Manager, kubeClient kubernetes.Interface, dataPathMgr *datapath.Manager, namespace string, - resourceTimeout time.Duration, logger logrus.FieldLogger) error { - log := logger.WithField("controller", "PodVolumeRestoreLegacy") - - credentialFileStore, err := credentials.NewNamespacedFileStore(client, namespace, credentials.DefaultStoreDirectory(), filesystem.NewFileSystem()) - if err != nil { - return errors.Wrapf(err, "error creating credentials file store") - } - - credSecretStore, err := credentials.NewNamespacedSecretStore(client, namespace) - if err != nil { - return errors.Wrapf(err, "error creating secret file store") - } - - credentialGetter := &credentials.CredentialGetter{FromFile: credentialFileStore, FromSecret: credSecretStore} - ensurer := repository.NewEnsurer(client, log, resourceTimeout) - - reconciler := &PodVolumeRestoreReconcilerLegacy{ - Client: client, - kubeClient: kubeClient, - logger: log, - repositoryEnsurer: ensurer, - credentialGetter: credentialGetter, - fileSystem: filesystem.NewFileSystem(), - clock: &clocks.RealClock{}, - dataPathMgr: dataPathMgr, - } - - if err = reconciler.SetupWithManager(mgr); err != nil { - return errors.Wrapf(err, "error setup controller manager") - } - - return nil -} - -type PodVolumeRestoreReconcilerLegacy struct { - client.Client - kubeClient kubernetes.Interface - logger logrus.FieldLogger - repositoryEnsurer *repository.Ensurer - credentialGetter *credentials.CredentialGetter - fileSystem filesystem.Interface - clock clocks.WithTickerAndDelayedExecution - dataPathMgr *datapath.Manager -} - -// +kubebuilder:rbac:groups=velero.io,resources=podvolumerestores,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=velero.io,resources=podvolumerestores/status,verbs=get;update;patch -// +kubebuilder:rbac:groups="",resources=pods,verbs=get -// +kubebuilder:rbac:groups="",resources=persistentvolumes,verbs=get -// +kubebuilder:rbac:groups="",resources=persistentvolumerclaims,verbs=get - -func (c *PodVolumeRestoreReconcilerLegacy) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := c.logger.WithField("PodVolumeRestore", req.NamespacedName.String()) - log.Info("Reconciling PVR by legacy controller") - - pvr := &velerov1api.PodVolumeRestore{} - if err := c.Get(ctx, types.NamespacedName{Namespace: req.Namespace, Name: req.Name}, pvr); err != nil { - if apierrors.IsNotFound(err) { - log.Warn("PodVolumeRestore not found, skip") - return ctrl.Result{}, nil - } - log.WithError(err).Error("Unable to get the PodVolumeRestore") - return ctrl.Result{}, err - } - - log = log.WithField("pod", fmt.Sprintf("%s/%s", pvr.Spec.Pod.Namespace, pvr.Spec.Pod.Name)) - if len(pvr.OwnerReferences) == 1 { - log = log.WithField("restore", fmt.Sprintf("%s/%s", pvr.Namespace, pvr.OwnerReferences[0].Name)) - } - - shouldProcess, pod, err := shouldProcess(ctx, c.Client, log, pvr) - if err != nil { - return ctrl.Result{}, err - } - if !shouldProcess { - return ctrl.Result{}, nil - } - - initContainerIndex := getInitContainerIndex(pod) - if initContainerIndex > 0 { - log.Warnf(`Init containers before the %s container may cause issues - if they interfere with volumes being restored: %s index %d`, restorehelper.WaitInitContainer, restorehelper.WaitInitContainer, initContainerIndex) - } - - log.Info("Restore starting") - - callbacks := datapath.Callbacks{ - OnCompleted: c.OnDataPathCompleted, - OnFailed: c.OnDataPathFailed, - OnCancelled: c.OnDataPathCancelled, - OnProgress: c.OnDataPathProgress, - } - - fsRestore, err := c.dataPathMgr.CreateFileSystemBR(pvr.Name, pVBRRequestor, ctx, c.Client, pvr.Namespace, callbacks, log) - if err != nil { - if err == datapath.ConcurrentLimitExceed { - return ctrl.Result{Requeue: true, RequeueAfter: time.Second * 5}, nil - } else { - return c.errorOut(ctx, pvr, err, "error to create data path", log) - } - } - - original := pvr.DeepCopy() - pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseInProgress - pvr.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()} - if err = c.Patch(ctx, pvr, client.MergeFrom(original)); err != nil { - c.closeDataPath(ctx, pvr.Name) - return c.errorOut(ctx, pvr, err, "error to update status to in progress", log) - } - - volumePath, err := exposer.GetPodVolumeHostPath(ctx, pod, pvr.Spec.Volume, c.kubeClient, c.fileSystem, log) - if err != nil { - c.closeDataPath(ctx, pvr.Name) - return c.errorOut(ctx, pvr, err, "error exposing host path for pod volume", log) - } - - log.WithField("path", volumePath.ByPath).Debugf("Found host path") - - if err := fsRestore.Init(ctx, &datapath.FSBRInitParam{ - BSLName: pvr.Spec.BackupStorageLocation, - SourceNamespace: pvr.Spec.SourceNamespace, - UploaderType: pvr.Spec.UploaderType, - RepositoryType: podvolume.GetPvrRepositoryType(pvr), - RepoIdentifier: pvr.Spec.RepoIdentifier, - RepositoryEnsurer: c.repositoryEnsurer, - CredentialGetter: c.credentialGetter, - }); err != nil { - c.closeDataPath(ctx, pvr.Name) - return c.errorOut(ctx, pvr, err, "error to initialize data path", log) - } - - if err := fsRestore.StartRestore(pvr.Spec.SnapshotID, volumePath, pvr.Spec.UploaderSettings); err != nil { - c.closeDataPath(ctx, pvr.Name) - return c.errorOut(ctx, pvr, err, "error starting data path restore", log) - } - - log.WithField("path", volumePath.ByPath).Info("Async fs restore data path started") - - return ctrl.Result{}, nil -} - -func (c *PodVolumeRestoreReconcilerLegacy) errorOut(ctx context.Context, pvr *velerov1api.PodVolumeRestore, err error, msg string, log logrus.FieldLogger) (ctrl.Result, error) { - _ = UpdatePVRStatusToFailed(ctx, c.Client, pvr, err, msg, c.clock.Now(), log) - return ctrl.Result{}, err -} - -func (c *PodVolumeRestoreReconcilerLegacy) SetupWithManager(mgr ctrl.Manager) error { - // The pod may not being scheduled at the point when its PVRs are initially reconciled. - // By watching the pods, we can trigger the PVR reconciliation again once the pod is finally scheduled on the node. - pred := kube.NewAllEventPredicate(func(obj client.Object) bool { - pvr := obj.(*velerov1api.PodVolumeRestore) - return IsLegacyPVR(pvr) - }) - - return ctrl.NewControllerManagedBy(mgr).Named("podvolumerestorelegacy"). - For(&velerov1api.PodVolumeRestore{}, builder.WithPredicates(pred)). - Watches(&corev1api.Pod{}, handler.EnqueueRequestsFromMapFunc(c.findVolumeRestoresForPod)). - Complete(c) -} - -func (c *PodVolumeRestoreReconcilerLegacy) findVolumeRestoresForPod(ctx context.Context, pod client.Object) []reconcile.Request { - list := &velerov1api.PodVolumeRestoreList{} - options := &client.ListOptions{ - LabelSelector: labels.Set(map[string]string{ - velerov1api.PodUIDLabel: string(pod.GetUID()), - }).AsSelector(), - } - if err := c.Client.List(context.TODO(), list, options); err != nil { - c.logger.WithField("pod", fmt.Sprintf("%s/%s", pod.GetNamespace(), pod.GetName())).WithError(err). - Error("unable to list PodVolumeRestores") - return []reconcile.Request{} - } - - requests := []reconcile.Request{} - for _, item := range list.Items { - if !IsLegacyPVR(&item) { - continue - } - - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: item.GetNamespace(), - Name: item.GetName(), - }, - }) - } - return requests -} - -func (c *PodVolumeRestoreReconcilerLegacy) OnDataPathCompleted(ctx context.Context, namespace string, pvrName string, result datapath.Result) { - defer c.dataPathMgr.RemoveAsyncBR(pvrName) - - log := c.logger.WithField("pvr", pvrName) - - log.WithField("PVR", pvrName).Info("Async fs restore data path completed") - - var pvr velerov1api.PodVolumeRestore - if err := c.Client.Get(ctx, types.NamespacedName{Name: pvrName, Namespace: namespace}, &pvr); err != nil { - log.WithError(err).Warn("Failed to get PVR on completion") - return - } - - volumePath := result.Restore.Target.ByPath - if volumePath == "" { - _, _ = c.errorOut(ctx, &pvr, errors.New("path is empty"), "invalid restore target", log) - return - } - - // Remove the .velero directory from the restored volume (it may contain done files from previous restores - // of this volume, which we don't want to carry over). If this fails for any reason, log and continue, since - // this is non-essential cleanup (the done files are named based on restore UID and the init container looks - // for the one specific to the restore being executed). - if err := os.RemoveAll(filepath.Join(volumePath, ".velero")); err != nil { - log.WithError(err).Warnf("error removing .velero directory from directory %s", volumePath) - } - - var restoreUID types.UID - for _, owner := range pvr.OwnerReferences { - if boolptr.IsSetToTrue(owner.Controller) { - restoreUID = owner.UID - break - } - } - - // Create the .velero directory within the volume dir so we can write a done file - // for this restore. - if err := os.MkdirAll(filepath.Join(volumePath, ".velero"), 0755); err != nil { - _, _ = c.errorOut(ctx, &pvr, err, "error creating .velero directory for done file", log) - return - } - - // Write a done file with name= into the just-created .velero dir - // within the volume. The velero init container on the pod is waiting - // for this file to exist in each restored volume before completing. - if err := os.WriteFile(filepath.Join(volumePath, ".velero", string(restoreUID)), nil, 0644); err != nil { //nolint:gosec // Internal usage. No need to check. - _, _ = c.errorOut(ctx, &pvr, err, "error writing done file", log) - return - } - - original := pvr.DeepCopy() - pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseCompleted - pvr.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()} - if err := c.Patch(ctx, &pvr, client.MergeFrom(original)); err != nil { - log.WithError(err).Error("error updating PodVolumeRestore status") - } - - log.Info("Restore completed") -} - -func (c *PodVolumeRestoreReconcilerLegacy) OnDataPathFailed(ctx context.Context, namespace string, pvrName string, err error) { - defer c.dataPathMgr.RemoveAsyncBR(pvrName) - - log := c.logger.WithField("pvr", pvrName) - - log.WithError(err).Error("Async fs restore data path failed") - - var pvr velerov1api.PodVolumeRestore - if getErr := c.Client.Get(ctx, types.NamespacedName{Name: pvrName, Namespace: namespace}, &pvr); getErr != nil { - log.WithError(getErr).Warn("Failed to get PVR on failure") - } else { - _, _ = c.errorOut(ctx, &pvr, err, "data path restore failed", log) - } -} - -func (c *PodVolumeRestoreReconcilerLegacy) OnDataPathCancelled(ctx context.Context, namespace string, pvrName string) { - defer c.dataPathMgr.RemoveAsyncBR(pvrName) - - log := c.logger.WithField("pvr", pvrName) - - log.Warn("Async fs restore data path canceled") - - var pvr velerov1api.PodVolumeRestore - if getErr := c.Client.Get(ctx, types.NamespacedName{Name: pvrName, Namespace: namespace}, &pvr); getErr != nil { - log.WithError(getErr).Warn("Failed to get PVR on cancel") - } else { - _, _ = c.errorOut(ctx, &pvr, errors.New("PVR is canceled"), "data path restore canceled", log) - } -} - -func (c *PodVolumeRestoreReconcilerLegacy) OnDataPathProgress(ctx context.Context, namespace string, pvrName string, progress *uploader.Progress) { - log := c.logger.WithField("pvr", pvrName) - - var pvr velerov1api.PodVolumeRestore - if err := c.Client.Get(ctx, types.NamespacedName{Name: pvrName, Namespace: namespace}, &pvr); err != nil { - log.WithError(err).Warn("Failed to get PVB on progress") - return - } - - original := pvr.DeepCopy() - pvr.Status.Progress = veleroapishared.DataMoveOperationProgress{TotalBytes: progress.TotalBytes, BytesDone: progress.BytesDone} - - if err := c.Client.Patch(ctx, &pvr, client.MergeFrom(original)); err != nil { - log.WithError(err).Error("Failed to update progress") - } -} - -func (c *PodVolumeRestoreReconcilerLegacy) closeDataPath(ctx context.Context, pvbName string) { - fsRestore := c.dataPathMgr.GetAsyncBR(pvbName) - if fsRestore != nil { - fsRestore.Close(ctx) - } - - c.dataPathMgr.RemoveAsyncBR(pvbName) -} - -func IsLegacyPVR(pvr *velerov1api.PodVolumeRestore) bool { - return pvr.Spec.UploaderType == "restic" -} diff --git a/pkg/controller/pod_volume_restore_controller_legacy_test.go b/pkg/controller/pod_volume_restore_controller_legacy_test.go deleted file mode 100644 index a107603e0e..0000000000 --- a/pkg/controller/pod_volume_restore_controller_legacy_test.go +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright The Velero Contributors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "testing" - - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" - corev1api "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" -) - -func TestFindVolumeRestoresForPodLegacy(t *testing.T) { - pod := &corev1api.Pod{} - pod.UID = "uid" - - scheme := runtime.NewScheme() - scheme.AddKnownTypes(velerov1api.SchemeGroupVersion, &velerov1api.PodVolumeRestore{}, &velerov1api.PodVolumeRestoreList{}) - clientBuilder := fake.NewClientBuilder().WithScheme(scheme) - - // no matching PVR - reconciler := &PodVolumeRestoreReconcilerLegacy{ - Client: clientBuilder.Build(), - logger: logrus.New(), - } - requests := reconciler.findVolumeRestoresForPod(t.Context(), pod) - assert.Empty(t, requests) - - // contain one matching PVR - reconciler.Client = clientBuilder.WithLists(&velerov1api.PodVolumeRestoreList{ - Items: []velerov1api.PodVolumeRestore{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "pvr1", - Labels: map[string]string{ - velerov1api.PodUIDLabel: string(pod.GetUID()), - }, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "pvr2", - Labels: map[string]string{ - velerov1api.PodUIDLabel: "non-matching-uid", - }, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "pvr3", - Labels: map[string]string{ - velerov1api.PodUIDLabel: string(pod.GetUID()), - }, - }, - Spec: velerov1api.PodVolumeRestoreSpec{ - UploaderType: "kopia", - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "pvr4", - Labels: map[string]string{ - velerov1api.PodUIDLabel: string(pod.GetUID()), - }, - }, - Spec: velerov1api.PodVolumeRestoreSpec{ - UploaderType: "restic", - }, - }, - }, - }).Build() - requests = reconciler.findVolumeRestoresForPod(t.Context(), pod) - assert.Len(t, requests, 1) -} diff --git a/pkg/controller/pod_volume_restore_controller_test.go b/pkg/controller/pod_volume_restore_controller_test.go index 9f2fe7a7f7..8999543d7f 100644 --- a/pkg/controller/pod_volume_restore_controller_test.go +++ b/pkg/controller/pod_volume_restore_controller_test.go @@ -526,6 +526,7 @@ func TestFindPVRForTargetPod(t *testing.T) { velerov1api.PodUIDLabel: string(pod.GetUID()), }, }, + Spec: velerov1api.PodVolumeRestoreSpec{UploaderType: uploader.KopiaType}, }, { ObjectMeta: metav1.ObjectMeta{ @@ -688,6 +689,7 @@ func TestPodVolumeRestoreReconcile(t *testing.T) { mockClose bool needExclusiveUpdateError error constrained bool + preserveEmptyUploader bool expected *velerov1api.PodVolumeRestore expectDeleted bool expectCancelRecord bool @@ -939,6 +941,13 @@ func TestPodVolumeRestoreReconcile(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { + if !test.preserveEmptyUploader && test.pvr != nil && test.pvr.Spec.UploaderType == "" { + test.pvr.Spec.UploaderType = uploader.KopiaType + } + if !test.preserveEmptyUploader && test.expected != nil && test.expected.Spec.UploaderType == "" { + test.expected.Spec.UploaderType = uploader.KopiaType + } + objs := []runtime.Object{daemonSet, node} ctlObj := []client.Object{} @@ -1396,7 +1405,7 @@ func TestFindPVBForRestorePod(t *testing.T) { }{ { name: "find pvr for pod", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Labels(map[string]string{velerov1api.PVRLabel: pvrName}).Status(corev1api.PodStatus{Phase: corev1api.PodRunning}).Result(), checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) { // Assert that the function returns a single request @@ -1407,7 +1416,7 @@ func TestFindPVBForRestorePod(t *testing.T) { }, }, { name: "no selected label found for pod", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Result(), checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) { // Assert that the function returns a single request @@ -1415,7 +1424,7 @@ func TestFindPVBForRestorePod(t *testing.T) { }, }, { name: "no matched pod", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Labels(map[string]string{velerov1api.PVRLabel: "non-existing-pvr"}).Result(), checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) { assert.Empty(t, requests) @@ -1423,12 +1432,20 @@ func TestFindPVBForRestorePod(t *testing.T) { }, { name: "pvr not accept", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Result(), pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Labels(map[string]string{velerov1api.PVRLabel: pvrName}).Result(), checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) { assert.Empty(t, requests) }, }, + { + name: "invalid uploader type", + pvr: pvrBuilder().UploaderType("restic").Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), + pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Labels(map[string]string{velerov1api.PVRLabel: pvrName}).Status(corev1api.PodStatus{Phase: corev1api.PodRunning}).Result(), + checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) { + assert.Empty(t, requests) + }, + }, } for _, test := range tests { ctx := t.Context() @@ -1613,32 +1630,32 @@ func TestAttemptPVRResume(t *testing.T) { }{ { name: "Other pvr", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhasePrepared).Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhasePrepared).Result(), }, { name: "Other pvr", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(), }, { name: "InProgress pvr, not the current node", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Result(), inProgressPvrs: []string{pvrName}, }, { name: "InProgress pvr, no resume error", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(), inProgressPvrs: []string{pvrName}, }, { name: "InProgress pvr, resume error, cancel error", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(), resumeErr: errors.New("fake-resume-error"), needErrs: []bool{false, false, true, false, false, false}, inProgressPvrs: []string{pvrName}, }, { name: "InProgress pvr, resume error, cancel succeed", - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(), resumeErr: errors.New("fake-resume-error"), cancelledPvrs: []string{pvrName}, inProgressPvrs: []string{pvrName}, @@ -1646,7 +1663,7 @@ func TestAttemptPVRResume(t *testing.T) { { name: "Error", needErrs: []bool{false, false, false, false, false, true}, - pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhasePrepared).Result(), + pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhasePrepared).Result(), expectedError: "error to list PVRs: List error", }, } From 0fa1910afba37c4d367c4679355a2f672cec5003 Mon Sep 17 00:00:00 2001 From: Pierluigi Lenoci Date: Wed, 22 Apr 2026 09:44:47 +0200 Subject: [PATCH 27/90] fix: honor -stderrthreshold when -logtostderr is true (default) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit klog v2 defaults -logtostderr to true, which silently ignores the -stderrthreshold flag — all log levels are unconditionally sent to stderr. This makes it impossible for log-aggregation systems to filter by severity. Bump klog to v2.140.0 and opt into the fixed behavior by setting legacy_stderr_threshold_behavior=false and stderrthreshold=INFO (which preserves current output while letting users override via CLI flags). Ref: kubernetes/klog#212, kubernetes/klog#432 Signed-off-by: Pierluigi Lenoci --- go.mod | 2 +- go.sum | 4 ++-- pkg/cmd/velero/velero.go | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e80bfbcf9b..d277791db8 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,7 @@ require ( k8s.io/apimachinery v0.33.3 k8s.io/cli-runtime v0.33.3 k8s.io/client-go v0.33.3 - k8s.io/klog/v2 v2.130.1 + k8s.io/klog/v2 v2.140.0 k8s.io/kube-aggregator v0.33.3 k8s.io/metrics v0.33.3 k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 diff --git a/go.sum b/go.sum index d8ee0cab0a..4acfe045a4 100644 --- a/go.sum +++ b/go.sum @@ -1232,8 +1232,8 @@ k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= +k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-aggregator v0.33.3 h1:Pa6hQpKJMX0p0D2wwcxXJgu02++gYcGWXoW1z1ZJDfo= k8s.io/kube-aggregator v0.33.3/go.mod h1:hwvkUoQ8q6gv0+SgNnlmQ3eUue1zHhJKTHsX7BwxwSE= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= diff --git a/pkg/cmd/velero/velero.go b/pkg/cmd/velero/velero.go index a74c68fbcb..d5392a92fc 100644 --- a/pkg/cmd/velero/velero.go +++ b/pkg/cmd/velero/velero.go @@ -132,6 +132,11 @@ operations can also be performed as 'velero backup get' and 'velero schedule cre // init and add the klog flags klog.InitFlags(flag.CommandLine) + // Opt into the new klog behavior so that -stderrthreshold is honored even + // when -logtostderr=true (the default). + // Ref: kubernetes/klog#212, kubernetes/klog#432 + flag.CommandLine.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck + flag.CommandLine.Set("stderrthreshold", "INFO") //nolint:errcheck c.PersistentFlags().AddGoFlagSet(flag.CommandLine) return c From 4d23571c180d35524678b70698157133bd05bda6 Mon Sep 17 00:00:00 2001 From: Pierluigi Lenoci Date: Wed, 22 Apr 2026 16:10:46 +0200 Subject: [PATCH 28/90] fix: add changelog and nolint explanation for CI Add missing changelog entry for PR 9654 (fixes Changelog Check). Add explanation to //nolint:errcheck directives (fixes nolintlint). Signed-off-by: Pierluigi Lenoci --- changelogs/unreleased/9654-pierluigilenoci | 1 + pkg/cmd/velero/velero.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/9654-pierluigilenoci diff --git a/changelogs/unreleased/9654-pierluigilenoci b/changelogs/unreleased/9654-pierluigilenoci new file mode 100644 index 0000000000..d31a764272 --- /dev/null +++ b/changelogs/unreleased/9654-pierluigilenoci @@ -0,0 +1 @@ +Fix issue #9658, Honor --stderrthreshold when --logtostderr is enabled diff --git a/pkg/cmd/velero/velero.go b/pkg/cmd/velero/velero.go index d5392a92fc..42f07b03a3 100644 --- a/pkg/cmd/velero/velero.go +++ b/pkg/cmd/velero/velero.go @@ -135,8 +135,8 @@ operations can also be performed as 'velero backup get' and 'velero schedule cre // Opt into the new klog behavior so that -stderrthreshold is honored even // when -logtostderr=true (the default). // Ref: kubernetes/klog#212, kubernetes/klog#432 - flag.CommandLine.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck - flag.CommandLine.Set("stderrthreshold", "INFO") //nolint:errcheck + flag.CommandLine.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck // flag is registered by klog.InitFlags above + flag.CommandLine.Set("stderrthreshold", "INFO") //nolint:errcheck // flag is registered by klog.InitFlags above c.PersistentFlags().AddGoFlagSet(flag.CommandLine) return c From 3b34fb8effcd12ae0fd42cef0e29a0a64c7a9972 Mon Sep 17 00:00:00 2001 From: Joseph Antony Vaikath Date: Wed, 22 Apr 2026 16:24:22 -0400 Subject: [PATCH 29/90] Fix wildcard expansion when includes is empty and excludes has wildcards (#9684) * Fix wildcard expansion when includes is empty and excludes has wildcards When a Backup CR is applied via kubectl with empty includedNamespaces and a wildcard in excludedNamespaces, ShouldExpandWildcards triggers expansion. The empty includes expands to nil, but wildcardExpanded is set to true, causing ShouldInclude to return false for all namespaces. Populate expanded includes with all active namespaces when the original includes was empty (meaning "include all") so that the wildcardExpanded check does not falsely reject everything. Signed-off-by: Joseph * Changelog Signed-off-by: Joseph * Normalize empty includes to * instead of active namespaces list This ensures consistent behavior between CLI and kubectl-apply paths for Namespace CR inclusion when excludes contain wildcards. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joseph * Move empty includes normalization to backup controller Instead of normalizing empty IncludedNamespaces to ["*"] in the collections layer's ExpandIncludesExcludes, do it earlier in prepareBackupRequest. This ensures the spec is correct before any downstream processing. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joseph * Update TestProcessBackupCompletions for wildcard normalization Add IncludedNamespaces: []string{"*"} to all expected BackupSpec structs, reflecting the new prepareBackupRequest normalization. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joseph * Add checks around empty includenamespaces Signed-off-by: Joseph * gofmt Signed-off-by: Joseph --------- Signed-off-by: Joseph Co-authored-by: Claude Opus 4.6 (1M context) --- changelogs/unreleased/9684-Joeavaikath | 1 + pkg/controller/backup_controller.go | 7 ++++ pkg/controller/backup_controller_test.go | 47 ++++++++++++++++++++++++ pkg/util/wildcard/expand.go | 5 +++ pkg/util/wildcard/expand_test.go | 6 +++ 5 files changed, 66 insertions(+) create mode 100644 changelogs/unreleased/9684-Joeavaikath diff --git a/changelogs/unreleased/9684-Joeavaikath b/changelogs/unreleased/9684-Joeavaikath new file mode 100644 index 0000000000..d5f5d6e762 --- /dev/null +++ b/changelogs/unreleased/9684-Joeavaikath @@ -0,0 +1 @@ +Fix wildcard expansion when includes is empty and excludes has wildcards diff --git a/pkg/controller/backup_controller.go b/pkg/controller/backup_controller.go index 496308a6e0..496875bbfe 100644 --- a/pkg/controller/backup_controller.go +++ b/pkg/controller/backup_controller.go @@ -570,6 +570,13 @@ func (b *backupReconciler) prepareBackupRequest(ctx context.Context, backup *vel } } + // Empty IncludedNamespaces means "include all namespaces". Normalize + // to ["*"] so that downstream wildcard expansion does not collapse + // an empty-includes + wildcard-excludes combination into "back up nothing". + if len(request.Spec.IncludedNamespaces) == 0 { + request.Spec.IncludedNamespaces = []string{"*"} + } + // validate the included/excluded namespaces for _, err := range collections.ValidateNamespaceIncludesExcludes(request.Spec.IncludedNamespaces, request.Spec.ExcludedNamespaces) { request.Status.ValidationErrors = append(request.Status.ValidationErrors, fmt.Sprintf("Invalid included/excluded namespace lists: %v", err)) diff --git a/pkg/controller/backup_controller_test.go b/pkg/controller/backup_controller_test.go index 3864989002..c65f1d15d2 100644 --- a/pkg/controller/backup_controller_test.go +++ b/pkg/controller/backup_controller_test.go @@ -320,6 +320,34 @@ func TestBackupLocationLabel(t *testing.T) { } } +func TestPrepareBackupRequest_EmptyIncludedNamespacesNormalizedToWildcard(t *testing.T) { + formatFlag := logging.FormatText + logger := logging.DefaultLogger(logrus.DebugLevel, formatFlag) + + apiServer := velerotest.NewAPIServer(t) + discoveryHelper, err := discovery.NewHelper(apiServer.DiscoveryClient, logger) + require.NoError(t, err) + + backupLocation := builder.ForBackupStorageLocation("velero", "loc-1").Result() + fakeClient := velerotest.NewFakeControllerRuntimeClient(t, backupLocation) + + c := &backupReconciler{ + discoveryHelper: discoveryHelper, + kbClient: fakeClient, + defaultBackupLocation: backupLocation.Name, + clock: &clock.RealClock{}, + formatFlag: formatFlag, + } + + backup := defaultBackup().Result() + backup.Spec.IncludedNamespaces = nil + + res := c.prepareBackupRequest(ctx, backup, logger) + defer res.WorkerPool.Stop() + + assert.Equal(t, []string{"*"}, res.Spec.IncludedNamespaces) +} + func Test_prepareBackupRequest_BackupStorageLocation(t *testing.T) { var ( defaultBackupTTL = metav1.Duration{Duration: 24 * 30 * time.Hour} @@ -709,6 +737,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.True(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -748,6 +777,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: "alt-loc", + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -791,6 +821,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: "read-write", + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.True(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -831,6 +862,7 @@ func TestProcessBackupCompletions(t *testing.T) { Spec: velerov1api.BackupSpec{ TTL: metav1.Duration{Duration: 10 * time.Minute}, StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -871,6 +903,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.True(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -912,6 +945,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -953,6 +987,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.True(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -994,6 +1029,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.True(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1035,6 +1071,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1077,6 +1114,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.True(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1119,6 +1157,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.True(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1161,6 +1200,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.True(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1204,6 +1244,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1247,6 +1288,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1290,6 +1332,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.True(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1334,6 +1377,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.False(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1377,6 +1421,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.True(), ExcludedClusterScopedResources: autoExcludeClusterScopedResources, @@ -1424,6 +1469,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.True(), IncludedClusterScopedResources: []string{"storageclasses"}, @@ -1473,6 +1519,7 @@ func TestProcessBackupCompletions(t *testing.T) { }, Spec: velerov1api.BackupSpec{ StorageLocation: defaultBackupLocation.Name, + IncludedNamespaces: []string{"*"}, DefaultVolumesToFsBackup: boolptr.False(), SnapshotMoveData: boolptr.True(), IncludedClusterScopedResources: []string{"storageclasses"}, diff --git a/pkg/util/wildcard/expand.go b/pkg/util/wildcard/expand.go index 8767c8ed37..4a88f14640 100644 --- a/pkg/util/wildcard/expand.go +++ b/pkg/util/wildcard/expand.go @@ -9,6 +9,11 @@ import ( ) func ShouldExpandWildcards(includes []string, excludes []string) bool { + // Empty includes is equivalent to * (match all) - don't expand + if len(includes) == 0 { + return false + } + wildcardFound := false for _, include := range includes { // Special case: "*" alone means "match all" - don't expand diff --git a/pkg/util/wildcard/expand_test.go b/pkg/util/wildcard/expand_test.go index 3170206489..5730956cf5 100644 --- a/pkg/util/wildcard/expand_test.go +++ b/pkg/util/wildcard/expand_test.go @@ -68,6 +68,12 @@ func TestShouldExpandWildcards(t *testing.T) { excludes: []string{}, expected: false, }, + { + name: "empty includes with wildcard excludes - should not expand", + includes: []string{}, + excludes: []string{"ns*"}, + expected: false, + }, { name: "complex wildcard patterns", includes: []string{"*-prod"}, From 7549408e210529a7dc81dd2c097734ee8cf257ba Mon Sep 17 00:00:00 2001 From: peter woodman Date: Thu, 23 Apr 2026 00:20:05 -0400 Subject: [PATCH 30/90] update hashicorp/go-hclog and go-plugin to current version (#9613) Signed-off-by: Peter Woodman --- changelogs/unreleased/9613-pjjw | 1 + go.mod | 9 ++--- go.sum | 39 ++++++++++--------- .../clientmgmt/process/logrus_adapter.go | 18 +++++++++ 4 files changed, 44 insertions(+), 23 deletions(-) create mode 100644 changelogs/unreleased/9613-pjjw diff --git a/changelogs/unreleased/9613-pjjw b/changelogs/unreleased/9613-pjjw new file mode 100644 index 0000000000..3f8c6faaee --- /dev/null +++ b/changelogs/unreleased/9613-pjjw @@ -0,0 +1 @@ +update go-hclog to current version diff --git a/go.mod b/go.mod index e80bfbcf9b..fe23ce9abc 100644 --- a/go.mod +++ b/go.mod @@ -22,8 +22,8 @@ require ( github.com/gobwas/glob v0.2.3 github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 - github.com/hashicorp/go-hclog v0.14.1 - github.com/hashicorp/go-plugin v1.6.0 + github.com/hashicorp/go-hclog v1.6.3 + github.com/hashicorp/go-plugin v1.7.0 github.com/joho/godotenv v1.3.0 github.com/kopia/kopia v0.16.0 github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 @@ -125,7 +125,7 @@ require ( github.com/googleapis/gax-go/v2 v2.15.0 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/hashicorp/cronexpr v1.1.3 // indirect - github.com/hashicorp/yamux v0.1.1 // indirect + github.com/hashicorp/yamux v0.1.2 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -143,7 +143,6 @@ require ( github.com/minio/crc64nvme v1.1.0 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/minio-go/v7 v7.0.97 // indirect - github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/moby/spdystream v0.5.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -153,7 +152,7 @@ require ( github.com/mxk/go-vss v1.2.0 // indirect github.com/natefinch/atomic v1.0.1 // indirect github.com/nxadm/tail v1.4.8 // indirect - github.com/oklog/run v1.0.0 // indirect + github.com/oklog/run v1.1.0 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect diff --git a/go.sum b/go.sum index d8ee0cab0a..808fe52155 100644 --- a/go.sum +++ b/go.sum @@ -174,8 +174,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bombsimon/logrusr/v3 v3.0.0 h1:tcAoLfuAhKP9npBxWzSdpsvKPQt1XV02nSf2lZA82TQ= github.com/bombsimon/logrusr/v3 v3.0.0/go.mod h1:PksPPgSFEL2I52pla2glgCyyd2OqOHAnFF5E+g8Ixco= -github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= -github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -242,6 +242,7 @@ github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -428,13 +429,13 @@ github.com/hashicorp/cronexpr v1.1.3 h1:rl5IkxXN2m681EfivTlccqIryzYJSXRGRNa0xeG7 github.com/hashicorp/cronexpr v1.1.3/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= -github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= -github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= +github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= +github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= @@ -448,8 +449,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= -github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -458,8 +459,8 @@ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -523,12 +524,13 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -542,7 +544,6 @@ github.com/minio/minio-go/v7 v7.0.97/go.mod h1:re5VXuo0pwEtoNLsNuSr0RrLfT/MBtohw github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= @@ -576,8 +577,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -696,6 +697,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= @@ -914,7 +916,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -926,12 +927,12 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -965,7 +966,9 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/pkg/plugin/clientmgmt/process/logrus_adapter.go b/pkg/plugin/clientmgmt/process/logrus_adapter.go index da573284a7..8a790aacec 100644 --- a/pkg/plugin/clientmgmt/process/logrus_adapter.go +++ b/pkg/plugin/clientmgmt/process/logrus_adapter.go @@ -196,3 +196,21 @@ func (l *logrusAdapter) Name() string { func (l *logrusAdapter) StandardWriter(opts *hclog.StandardLoggerOptions) io.Writer { panic("not implemented") } + +// GetLevel returns the current level +func (l *logrusAdapter) GetLevel() hclog.Level { + switch l.level { + case logrus.TraceLevel: + return hclog.Trace + case logrus.DebugLevel: + return hclog.Debug + case logrus.InfoLevel: + return hclog.Info + case logrus.WarnLevel: + return hclog.Warn + case logrus.ErrorLevel: + return hclog.Error + default: + return hclog.NoLevel + } +} From f494e1064ec9af446cc1078614f94a4c59bf3ac4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 20:52:14 +0000 Subject: [PATCH 31/90] Bump go.opentelemetry.io/otel from 1.40.0 to 1.41.0 Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.40.0 to 1.41.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.40.0...v1.41.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-version: 1.41.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 23d1413822..f5c6769e1a 100644 --- a/go.mod +++ b/go.mod @@ -171,11 +171,11 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel v1.41.0 // indirect + go.opentelemetry.io/otel/metric v1.41.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.41.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect diff --git a/go.sum b/go.sum index 48111a58c6..7183495065 100644 --- a/go.sum +++ b/go.sum @@ -750,18 +750,18 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= +go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= +go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= +go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20201006213952-227f4aabceb5/go.mod h1:f0znQkUKRrkk36XxWbGjMqQM8wGv/xHBVE2qc3B5oFU= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= From b3c178b9a1bddbe7b83fea11ba012c2fc9d49707 Mon Sep 17 00:00:00 2001 From: Daniel Jiang Date: Mon, 27 Apr 2026 15:47:17 +0800 Subject: [PATCH 32/90] Fix error in auto-request-review action Per action.yml of the action, the token is required. https://github.com/necojackarc/auto-request-review/blob/e89da1a8cd7c8c16d9de9c6e763290b6b0e3d424/action.yml#L8 Signed-off-by: Daniel Jiang --- .github/workflows/auto_request_review.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/auto_request_review.yml b/.github/workflows/auto_request_review.yml index ba64d151dc..47844bc6c1 100644 --- a/.github/workflows/auto_request_review.yml +++ b/.github/workflows/auto_request_review.yml @@ -18,3 +18,4 @@ jobs: uses: necojackarc/auto-request-review@v0.13.0 with: config: .github/auto-assignees.yml + token: ${{ secrets.GITHUB_TOKEN }} From 16ca7739ceec92e8f6b530052f7290d208311cfd Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Mon, 27 Apr 2026 17:15:52 +0800 Subject: [PATCH 33/90] add concurrency limit to go-releaser Signed-off-by: Lyndon-Li --- hack/release-tools/goreleaser.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hack/release-tools/goreleaser.sh b/hack/release-tools/goreleaser.sh index 79f9a4fc52..b8a1807540 100755 --- a/hack/release-tools/goreleaser.sh +++ b/hack/release-tools/goreleaser.sh @@ -51,11 +51,13 @@ if [[ "${PUBLISH:-}" != "TRUE" ]]; then echo "Not set to publish" goreleaser release \ --clean \ + --parallelism 2 \ --release-notes="${RELEASE_NOTES_FILE}" \ --snapshot # Generate an unversioned snapshot release, skipping all validations and without publishing any artifacts (implies --skip-publish, --skip-announce and --skip-validate) else echo "Getting ready to publish" goreleaser release \ --clean \ + --parallelism 2 \ --release-notes="${RELEASE_NOTES_FILE}" fi From 36dde0f88e182815e8cebba9110124dfdf8d295e Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Mon, 27 Apr 2026 18:23:39 +0800 Subject: [PATCH 34/90] fix go-releaser upload error Signed-off-by: Lyndon-Li --- .goreleaser.yml | 2 +- hack/release-tools/tag-release.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 0ff87e36a9..f206d3f9c3 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -55,7 +55,7 @@ checksum: name_template: 'CHECKSUM' release: github: - owner: vmware-tanzu + owner: velero-io name: velero draft: true prerelease: auto diff --git a/hack/release-tools/tag-release.sh b/hack/release-tools/tag-release.sh index 4fbfa933e7..7a993c03b0 100755 --- a/hack/release-tools/tag-release.sh +++ b/hack/release-tools/tag-release.sh @@ -24,7 +24,7 @@ # The following variables are needed: -# - $VELERO_VERSION: defines the tag of Velero that any https://github.com/vmware-tanzu/velero/... +# - $VELERO_VERSION: defines the tag of Velero that any https://github.com/velero-io/velero/... # links in the docs should redirect to. # - $REMOTE: defines the remote that should be used when pushing tags and branches. Defaults to "upstream" # - $publish: TRUE/FALSE value where FALSE (or not including it) will indicate a dry-run, and TRUE, or simply adding 'publish', From 79faa5ff967eb92e17f98e00e528ce95a921d36e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 11:58:24 -0400 Subject: [PATCH 35/90] Bump go.opentelemetry.io/otel/sdk from 1.40.0 to 1.43.0 (#9692) Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.40.0 to 1.43.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.40.0...v1.43.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/sdk dependency-version: 1.43.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index f5c6769e1a..13e456d671 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( go.uber.org/zap v1.27.1 golang.org/x/mod v0.30.0 golang.org/x/oauth2 v0.34.0 - golang.org/x/sys v0.40.0 + golang.org/x/sys v0.42.0 golang.org/x/text v0.32.0 google.golang.org/api v0.256.0 google.golang.org/grpc v1.79.3 @@ -171,11 +171,11 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.41.0 // indirect - go.opentelemetry.io/otel/metric v1.41.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.41.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect diff --git a/go.sum b/go.sum index 7183495065..80d6ea3ace 100644 --- a/go.sum +++ b/go.sum @@ -750,18 +750,18 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= -go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= -go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= -go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20201006213952-227f4aabceb5/go.mod h1:f0znQkUKRrkk36XxWbGjMqQM8wGv/xHBVE2qc3B5oFU= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= @@ -972,8 +972,8 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= From 76197d78923d472241df3b529b83bfd7740d838d Mon Sep 17 00:00:00 2001 From: Nolan Emirot Date: Tue, 28 Apr 2026 03:11:49 -0400 Subject: [PATCH 36/90] fix: lint permission issue (#9740) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: lint permission issue Signed-off-by: emirot * fix: lint permission issue Signed-off-by: emirot * Set permissions to the actions This commit update the actions "Auto Assign Author", "Auto Label PRs", and "Auto Request Review" Signed-off-by: Daniel Jiang Signed-off-by: emirot * Fix wildcard expansion when includes is empty and excludes has wildcards (#9684) * Fix wildcard expansion when includes is empty and excludes has wildcards When a Backup CR is applied via kubectl with empty includedNamespaces and a wildcard in excludedNamespaces, ShouldExpandWildcards triggers expansion. The empty includes expands to nil, but wildcardExpanded is set to true, causing ShouldInclude to return false for all namespaces. Populate expanded includes with all active namespaces when the original includes was empty (meaning "include all") so that the wildcardExpanded check does not falsely reject everything. Signed-off-by: Joseph * Changelog Signed-off-by: Joseph * Normalize empty includes to * instead of active namespaces list This ensures consistent behavior between CLI and kubectl-apply paths for Namespace CR inclusion when excludes contain wildcards. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joseph * Move empty includes normalization to backup controller Instead of normalizing empty IncludedNamespaces to ["*"] in the collections layer's ExpandIncludesExcludes, do it earlier in prepareBackupRequest. This ensures the spec is correct before any downstream processing. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joseph * Update TestProcessBackupCompletions for wildcard normalization Add IncludedNamespaces: []string{"*"} to all expected BackupSpec structs, reflecting the new prepareBackupRequest normalization. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joseph * Add checks around empty includenamespaces Signed-off-by: Joseph * gofmt Signed-off-by: Joseph --------- Signed-off-by: Joseph Co-authored-by: Claude Opus 4.6 (1M context) Signed-off-by: emirot * update hashicorp/go-hclog and go-plugin to current version (#9613) Signed-off-by: Peter Woodman Signed-off-by: emirot * fix: honor -stderrthreshold when -logtostderr is true (default) klog v2 defaults -logtostderr to true, which silently ignores the -stderrthreshold flag — all log levels are unconditionally sent to stderr. This makes it impossible for log-aggregation systems to filter by severity. Bump klog to v2.140.0 and opt into the fixed behavior by setting legacy_stderr_threshold_behavior=false and stderrthreshold=INFO (which preserves current output while letting users override via CLI flags). Ref: kubernetes/klog#212, kubernetes/klog#432 Signed-off-by: Pierluigi Lenoci Signed-off-by: emirot * fix: add changelog and nolint explanation for CI Add missing changelog entry for PR 9654 (fixes Changelog Check). Add explanation to //nolint:errcheck directives (fixes nolintlint). Signed-off-by: Pierluigi Lenoci Signed-off-by: emirot * Remove Restic code path from PodVolumeRestore. Signed-off-by: Xun Jiang Signed-off-by: emirot * Bump go.opentelemetry.io/otel from 1.40.0 to 1.41.0 Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.40.0 to 1.41.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.40.0...v1.41.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-version: 1.41.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: emirot * Fix error in auto-request-review action Per action.yml of the action, the token is required. https://github.com/necojackarc/auto-request-review/blob/e89da1a8cd7c8c16d9de9c6e763290b6b0e3d424/action.yml#L8 Signed-off-by: Daniel Jiang Signed-off-by: emirot * fix go-releaser upload error Signed-off-by: Lyndon-Li Signed-off-by: emirot * add concurrency limit to go-releaser Signed-off-by: Lyndon-Li Signed-off-by: emirot * Bump go.opentelemetry.io/otel/sdk from 1.40.0 to 1.43.0 (#9692) Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.40.0 to 1.43.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.40.0...v1.43.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/sdk dependency-version: 1.43.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: emirot * fix(lint): fix lint local Signed-off-by: emirot * Apply suggestion from @blackpiglet https://github.com/velero-io/velero/pull/9740/changes#r3151366281 Signed-off-by: Tiger Kaovilai --------- Signed-off-by: emirot Signed-off-by: Daniel Jiang Signed-off-by: Joseph Signed-off-by: Peter Woodman Signed-off-by: Pierluigi Lenoci Signed-off-by: Xun Jiang Signed-off-by: dependabot[bot] Signed-off-by: Lyndon-Li Signed-off-by: Tiger Kaovilai Co-authored-by: Daniel Jiang Co-authored-by: Joseph Antony Vaikath Co-authored-by: Claude Opus 4.6 (1M context) Co-authored-by: peter woodman Co-authored-by: Pierluigi Lenoci Co-authored-by: Xun Jiang Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lyndon-Li Co-authored-by: Tiger Kaovilai --- Makefile | 3 ++- changelogs/unreleased/9740-emirot | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/9740-emirot diff --git a/Makefile b/Makefile index 59f767afc2..80db72e3a2 100644 --- a/Makefile +++ b/Makefile @@ -211,6 +211,7 @@ shell: build-dirs build-env -v "$$(pwd)/.go/std/$(GOOS)/$(GOARCH):/usr/local/go/pkg/$(GOOS)_$(GOARCH)_static:delegated" \ -v "$$(pwd)/.go/go-build:/.cache/go-build:delegated" \ -v "$$(pwd)/.go/golangci-lint:/.cache/golangci-lint:delegated" \ + -v "$$(pwd)/.go/goimports:/.cache/goimports:delegated" \ -w /github.com/vmware-tanzu/velero \ $(BUILDER_IMAGE) \ /bin/sh $(CMD) @@ -342,7 +343,7 @@ update-crd: build-dirs: @mkdir -p _output/bin/$(GOOS)/$(GOARCH) - @mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build .go/golangci-lint + @mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build .go/golangci-lint .go/goimports build-env: @# if we have overridden the value for the build-image Dockerfile, diff --git a/changelogs/unreleased/9740-emirot b/changelogs/unreleased/9740-emirot new file mode 100644 index 0000000000..dee2611c1d --- /dev/null +++ b/changelogs/unreleased/9740-emirot @@ -0,0 +1 @@ +fix: lint permission issue From f72c57b185280b1ddb196831a65a085e338e1aab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 22:39:18 -0400 Subject: [PATCH 37/90] Bump github.com/moby/spdystream from 0.5.0 to 0.5.1 (#9734) * Bump github.com/moby/spdystream from 0.5.0 to 0.5.1 Bumps [github.com/moby/spdystream](https://github.com/moby/spdystream) from 0.5.0 to 0.5.1. - [Release notes](https://github.com/moby/spdystream/releases) - [Commits](https://github.com/moby/spdystream/compare/v0.5.0...v0.5.1) --- updated-dependencies: - dependency-name: github.com/moby/spdystream dependency-version: 0.5.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] * fix: run go mod tidy to update module files Agent-Logs-Url: https://github.com/velero-io/velero/sessions/3537c5cb-5e31-405c-a79f-878bd146efa8 Co-authored-by: blackpiglet <59276555+blackpiglet@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: Xun Jiang/Bruce Jiang <59276555+blackpiglet@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Jiang Co-authored-by: Xun Jiang/Bruce Jiang <59276555+blackpiglet@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 13e456d671..5bcbc11ef0 100644 --- a/go.mod +++ b/go.mod @@ -143,7 +143,7 @@ require ( github.com/minio/crc64nvme v1.1.0 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/minio-go/v7 v7.0.97 // indirect - github.com/moby/spdystream v0.5.0 // indirect + github.com/moby/spdystream v0.5.1 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect diff --git a/go.sum b/go.sum index 80d6ea3ace..bbdb665677 100644 --- a/go.sum +++ b/go.sum @@ -551,8 +551,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= -github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/spdystream v0.5.1 h1:9sNYeYZUcci9R6/w7KDaFWEWeV4LStVG78Mpyq/Zm/Y= +github.com/moby/spdystream v0.5.1/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= From 7918cb35dd9ade02ed57d36a7addbad7407e01a6 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Thu, 30 Apr 2026 14:17:42 +0800 Subject: [PATCH 38/90] fix docker hub push error Signed-off-by: Lyndon-Li --- .github/workflows/pr-containers.yml | 2 +- .github/workflows/pr-filepath-check.yml | 2 +- .github/workflows/pr-goreleaser.yml | 2 +- .github/workflows/push-builder.yml | 2 +- .github/workflows/push.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr-containers.yml b/.github/workflows/pr-containers.yml index 6f839a1661..2df7e0fabb 100644 --- a/.github/workflows/pr-containers.yml +++ b/.github/workflows/pr-containers.yml @@ -32,6 +32,6 @@ jobs: # by push, so BRANCH and TAG are empty by default. docker-push.sh will # only build Velero image without pushing. - name: Make Velero container without pushing to registry. - if: github.repository == 'vmware-tanzu/velero' + if: github.repository == 'velero-io/velero' run: | ./hack/docker-push.sh \ No newline at end of file diff --git a/.github/workflows/pr-filepath-check.yml b/.github/workflows/pr-filepath-check.yml index 2e4b3d6eab..260a09dc4a 100644 --- a/.github/workflows/pr-filepath-check.yml +++ b/.github/workflows/pr-filepath-check.yml @@ -84,7 +84,7 @@ jobs: else: print(f' # {original} — cannot auto-suggest rename (non-UTF-8)') print() - print('See https://github.com/vmware-tanzu/velero/pull/9552 for context.') + print('See https://github.com/velero-io/velero/pull/9552 for context.') sys.exit(1) else: print('All file paths are valid for Go module zip.') diff --git a/.github/workflows/pr-goreleaser.yml b/.github/workflows/pr-goreleaser.yml index 5215a5bfbc..802080cb57 100644 --- a/.github/workflows/pr-goreleaser.yml +++ b/.github/workflows/pr-goreleaser.yml @@ -18,7 +18,7 @@ jobs: name: Checkout - name: Verify .goreleaser.yml and try a dryrun release. - if: github.repository == 'vmware-tanzu/velero' + if: github.repository == 'velero-io/velero' run: | CHANGELOG=$(ls changelogs | sort -V -r | head -n 1) GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} \ diff --git a/.github/workflows/push-builder.yml b/.github/workflows/push-builder.yml index 2272ee3f1d..8e3e59c15c 100644 --- a/.github/workflows/push-builder.yml +++ b/.github/workflows/push-builder.yml @@ -28,7 +28,7 @@ jobs: # Only try to publish the container image from the root repo; forks don't have permission to do so and will always get failures. - name: Publish container image - if: github.repository == 'vmware-tanzu/velero' + if: github.repository == 'velero-io/velero' run: | docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index e0c32e1890..10b191630c 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -52,7 +52,7 @@ jobs: verbose: true # Only try to publish the container image from the root repo; forks don't have permission to do so and will always get failures. - name: Publish container image - if: github.repository == 'vmware-tanzu/velero' + if: github.repository == 'velero-io/velero' run: | sudo swapoff -a sudo rm -f /mnt/swapfile From 360095a2e76105e33b45aecd7f6834169c8e70aa Mon Sep 17 00:00:00 2001 From: Joseph Antony Vaikath Date: Wed, 6 May 2026 04:30:36 -0400 Subject: [PATCH 39/90] Merge pull request #9558 from Joeavaikath/wildcard-ns-bugfix Wildcard namespaces: Log warning on empty resolution --- changelogs/unreleased/9558-Joeavaikath | 1 + pkg/backup/backup.go | 41 ++++++++++++++----- pkg/util/collections/includes_excludes.go | 1 - .../docs/main/namespace-glob-patterns.md | 2 + 4 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 changelogs/unreleased/9558-Joeavaikath diff --git a/changelogs/unreleased/9558-Joeavaikath b/changelogs/unreleased/9558-Joeavaikath new file mode 100644 index 0000000000..c9be4839e9 --- /dev/null +++ b/changelogs/unreleased/9558-Joeavaikath @@ -0,0 +1 @@ +Wildcard namespaces: Log warning on empty resolution diff --git a/pkg/backup/backup.go b/pkg/backup/backup.go index 1a1c54247f..9edaf6a855 100644 --- a/pkg/backup/backup.go +++ b/pkg/backup/backup.go @@ -167,15 +167,15 @@ func NewKubernetesBackupper( }, nil } -// getNamespaceIncludesExcludesAndArgoCDNamespaces returns an IncludesExcludes list containing which namespaces to -// include and exclude from the backup and a list of namespaces managed by ArgoCD. -func getNamespaceIncludesExcludesAndArgoCDNamespaces(backup *velerov1api.Backup, kbClient kbclient.Client) (*collections.NamespaceIncludesExcludes, []string, error) { +// getNamespaceIncludesExcludes returns an IncludesExcludes list containing which namespaces to +// include and exclude from the backup. +func getNamespaceIncludesExcludes(backup *velerov1api.Backup, kbClient kbclient.Client) (*collections.NamespaceIncludesExcludes, error) { nsList := corev1api.NamespaceList{} - activeNamespaces := []string{} - nsManagedByArgoCD := []string{} if err := kbClient.List(context.Background(), &nsList); err != nil { - return nil, nsManagedByArgoCD, err + return nil, err } + + activeNamespaces := []string{} for _, ns := range nsList.Items { activeNamespaces = append(activeNamespaces, ns.Name) } @@ -188,10 +188,20 @@ func getNamespaceIncludesExcludesAndArgoCDNamespaces(backup *velerov1api.Backup, // Expand wildcards if needed if err := includesExcludes.ExpandIncludesExcludes(); err != nil { - return nil, []string{}, err + return nil, err } - // Check for ArgoCD managed namespaces in the namespaces that will be included + return includesExcludes, nil +} + +// getArgoCDManagedNamespaces returns a list of namespaces managed by ArgoCD that should be included in the backup. +func getArgoCDManagedNamespaces(kbClient kbclient.Client, includesExcludes *collections.NamespaceIncludesExcludes) ([]string, error) { + nsList := corev1api.NamespaceList{} + if err := kbClient.List(context.Background(), &nsList); err != nil { + return nil, err + } + + nsManagedByArgoCD := []string{} for _, ns := range nsList.Items { nsLabels := ns.GetLabels() if len(nsLabels[ArgoCDManagedByNamespaceLabel]) > 0 && includesExcludes.ShouldInclude(ns.Name) { @@ -199,7 +209,7 @@ func getNamespaceIncludesExcludesAndArgoCDNamespaces(backup *velerov1api.Backup, } } - return includesExcludes, nsManagedByArgoCD, nil + return nsManagedByArgoCD, nil } func getResourceHooks(hookSpecs []velerov1api.BackupResourceHookSpec, discoveryHelper discovery.Helper) ([]hook.ResourceHook, error) { @@ -274,13 +284,18 @@ func (kb *kubernetesBackupper) BackupWithResolvers( return errors.WithStack(err) } var err error - var nsManagedByArgoCD []string - backupRequest.NamespaceIncludesExcludes, nsManagedByArgoCD, err = getNamespaceIncludesExcludesAndArgoCDNamespaces(backupRequest.Backup, kb.kbClient) + backupRequest.NamespaceIncludesExcludes, err = getNamespaceIncludesExcludes(backupRequest.Backup, kb.kbClient) if err != nil { log.WithError(err).Errorf("error getting namespace includes/excludes") return err } + nsManagedByArgoCD, err := getArgoCDManagedNamespaces(kb.kbClient, backupRequest.NamespaceIncludesExcludes) + if err != nil { + log.WithError(err).Errorf("error getting ArgoCD managed namespaces") + return err + } + if backupRequest.NamespaceIncludesExcludes.IsWildcardExpanded() { expandedIncludes := backupRequest.NamespaceIncludesExcludes.GetIncludes() expandedExcludes := backupRequest.NamespaceIncludesExcludes.GetExcludes() @@ -292,6 +307,10 @@ func (kb *kubernetesBackupper) BackupWithResolvers( return err } + if len(wildcardResult) == 0 { + log.Warnf("no namespaces matched the resolution of wildcard patterns ") + } + log.WithFields(logrus.Fields{ "expandedIncludes": expandedIncludes, "expandedExcludes": expandedExcludes, diff --git a/pkg/util/collections/includes_excludes.go b/pkg/util/collections/includes_excludes.go index ab63eaa720..f326a4124c 100644 --- a/pkg/util/collections/includes_excludes.go +++ b/pkg/util/collections/includes_excludes.go @@ -173,7 +173,6 @@ func (nie *NamespaceIncludesExcludes) ExpandIncludesExcludes() error { } // ResolveNamespaceList returns a list of all namespaces which will be backed up. -// The second return value indicates whether wildcard expansion was performed. func (nie *NamespaceIncludesExcludes) ResolveNamespaceList() ([]string, error) { // Check if this is being called by non-backup processing e.g. backup queue controller if !nie.wildcardExpanded { diff --git a/site/content/docs/main/namespace-glob-patterns.md b/site/content/docs/main/namespace-glob-patterns.md index 4695124eae..c4cea9195a 100644 --- a/site/content/docs/main/namespace-glob-patterns.md +++ b/site/content/docs/main/namespace-glob-patterns.md @@ -5,6 +5,8 @@ layout: docs When using `--include-namespaces` and `--exclude-namespaces` flags with backup and restore commands, you can use glob patterns to match multiple namespaces. +Note: If the resolution of namespace patterns results in no namespaces, the backup will succeed with a warning. + ## Supported Patterns Velero supports the following glob pattern characters: From e6d928cdfe06635347c564a7b03a5f5bf1156a57 Mon Sep 17 00:00:00 2001 From: Xun Jiang/Bruce Jiang <59276555+blackpiglet@users.noreply.github.com> Date: Thu, 7 May 2026 00:10:23 +0800 Subject: [PATCH 40/90] Some updates for actions on main branch. (#9775) * Add Windows dockerfile in the Dockerfile change action. * Update Bitnami MinIO Dockerfile directory. Signed-off-by: Xun Jiang --- .github/workflows/e2e-test-kind.yaml | 2 +- .github/workflows/pr-containers.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e-test-kind.yaml b/.github/workflows/e2e-test-kind.yaml index 033e93370d..37bf720926 100644 --- a/.github/workflows/e2e-test-kind.yaml +++ b/.github/workflows/e2e-test-kind.yaml @@ -71,7 +71,7 @@ jobs: run: | echo "Building MinIO image from Bitnami Dockerfile..." git clone --depth 1 https://github.com/bitnami/containers.git /tmp/bitnami-containers - cd /tmp/bitnami-containers/bitnami/minio/2025/debian-12 + cd /tmp/bitnami-containers/bitnami/minio/2026/debian-12 docker build -t bitnami/minio:local . docker save bitnami/minio:local > ${{ github.workspace }}/minio-image.tar # Create json of k8s versions to test diff --git a/.github/workflows/pr-containers.yml b/.github/workflows/pr-containers.yml index 2df7e0fabb..c2fea13863 100644 --- a/.github/workflows/pr-containers.yml +++ b/.github/workflows/pr-containers.yml @@ -7,6 +7,7 @@ on: - 'release-**' paths: - 'Dockerfile' + - 'Dockerfile-Windows' jobs: build: From 878091d080517c0a2e380612d7adcdf9557b5f13 Mon Sep 17 00:00:00 2001 From: Daniel Jiang Date: Wed, 23 Aug 2023 15:13:34 +0800 Subject: [PATCH 41/90] skip subresource in resource discovery (#6688) Signed-off-by: lou Co-authored-by: lou --- changelogs/unreleased/6688-27149chen | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6688-27149chen diff --git a/changelogs/unreleased/6688-27149chen b/changelogs/unreleased/6688-27149chen new file mode 100644 index 0000000000..229d6e075a --- /dev/null +++ b/changelogs/unreleased/6688-27149chen @@ -0,0 +1 @@ +Fixes #6636, skip subresource in resource discovery \ No newline at end of file From 8450d946335ad2b071f52dcf5759e94ffe033018 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Tue, 5 Sep 2023 10:38:39 +0800 Subject: [PATCH 42/90] fix issue 6753 Signed-off-by: Lyndon-Li --- changelogs/unreleased/6758-Lyndon-Li | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6758-Lyndon-Li diff --git a/changelogs/unreleased/6758-Lyndon-Li b/changelogs/unreleased/6758-Lyndon-Li new file mode 100644 index 0000000000..1e095ee673 --- /dev/null +++ b/changelogs/unreleased/6758-Lyndon-Li @@ -0,0 +1 @@ +Fix issue #6753, remove the check for read-only BSL in restore async operation controller since Velero cannot fully support read-only mode BSL in restore at present \ No newline at end of file From 9349ce908259eca6fb3a6838ef43c10fa37175ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wenkai=20Yin=28=E5=B0=B9=E6=96=87=E5=BC=80=29?= Date: Wed, 6 Sep 2023 08:38:45 +0800 Subject: [PATCH 43/90] Update restore controller logic for restore deletion (#6761) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Skip deleting the restore files from storage if the backup/BSL is not found 2. Allow deleting the restore files from storage even though the BSL is readonly Signed-off-by: Wenkai Yin(尹文开) --- changelogs/unreleased/6761-ywk253100 | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6761-ywk253100 diff --git a/changelogs/unreleased/6761-ywk253100 b/changelogs/unreleased/6761-ywk253100 new file mode 100644 index 0000000000..6e55ffcd49 --- /dev/null +++ b/changelogs/unreleased/6761-ywk253100 @@ -0,0 +1 @@ +Update restore controller logic for restore deletion \ No newline at end of file From 2570fb1b707eb101f3db5cca0c899f4def1853ba Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 5 Sep 2023 10:50:20 +0800 Subject: [PATCH 44/90] Fix #6752: add namespace exclude check. Add PSA audit and warn labels. Signed-off-by: Xun Jiang --- changelogs/unreleased/6762-blackpiglet | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6762-blackpiglet diff --git a/changelogs/unreleased/6762-blackpiglet b/changelogs/unreleased/6762-blackpiglet new file mode 100644 index 0000000000..db9b5a118c --- /dev/null +++ b/changelogs/unreleased/6762-blackpiglet @@ -0,0 +1 @@ +Fix #6752: add namespace exclude check. \ No newline at end of file From 85f2ac22d17dd9e12115e3ff9b810a3722577285 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Fri, 8 Sep 2023 17:49:42 +0800 Subject: [PATCH 45/90] add csi snapshot data movement doc Signed-off-by: Lyndon-Li --- changelogs/unreleased/6793-Lyndon-Li | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6793-Lyndon-Li diff --git a/changelogs/unreleased/6793-Lyndon-Li b/changelogs/unreleased/6793-Lyndon-Li new file mode 100644 index 0000000000..b816b976bc --- /dev/null +++ b/changelogs/unreleased/6793-Lyndon-Li @@ -0,0 +1 @@ +Add CSI snapshot data movement doc \ No newline at end of file From 69ce3cd930fc110c8ff13470c72ccf242cddd75c Mon Sep 17 00:00:00 2001 From: allenxu404 Date: Tue, 19 Sep 2023 17:21:35 +0800 Subject: [PATCH 46/90] Modify changelogs for v1.12 Signed-off-by: allenxu404 --- changelogs/CHANGELOG-1.12.md | 8 ++++++++ changelogs/unreleased/6688-27149chen | 1 - changelogs/unreleased/6758-Lyndon-Li | 1 - changelogs/unreleased/6761-ywk253100 | 1 - changelogs/unreleased/6762-blackpiglet | 1 - changelogs/unreleased/6793-Lyndon-Li | 1 - 6 files changed, 8 insertions(+), 5 deletions(-) delete mode 100644 changelogs/unreleased/6688-27149chen delete mode 100644 changelogs/unreleased/6758-Lyndon-Li delete mode 100644 changelogs/unreleased/6761-ywk253100 delete mode 100644 changelogs/unreleased/6762-blackpiglet delete mode 100644 changelogs/unreleased/6793-Lyndon-Li diff --git a/changelogs/CHANGELOG-1.12.md b/changelogs/CHANGELOG-1.12.md index 4b980641ae..4472cc77d2 100644 --- a/changelogs/CHANGELOG-1.12.md +++ b/changelogs/CHANGELOG-1.12.md @@ -51,6 +51,7 @@ To fix CVEs and keep pace with Golang, Velero made changes as follows: * Prior to v1.12, the parameter `uploader-type` for Velero installation had a default value of "restic". However, starting from this version, the default value has been changed to "kopia". This means that Velero will now use Kopia as the default path for file system backup. * The ways of setting CSI snapshot time have changed in v1.12. First, the sync waiting time for creating a snapshot handle in the CSI plugin is changed from the fixed 10 minutes into backup.Spec.CSISnapshotTimeout. The second, the async waiting time for VolumeSnapshot and VolumeSnapshotContent's status turning into `ReadyToUse` in operation uses the operation's timeout. The default value is 4 hours. * As from [Velero helm chart v4.0.0](https://github.com/vmware-tanzu/helm-charts/releases/tag/velero-4.0.0), it supports multiple BSL and VSL, and the BSL and VSL have changed from the map into a slice, and[ this breaking change](https://github.com/vmware-tanzu/helm-charts/pull/413) is not backward compatible. So it would be best to change the BSL and VSL configuration into slices before the Upgrade. +* Prior to v1.12, deleting the Velero namespace would easily remove all the resources within it. However, with the introduction of finalizers attached to the Velero CR including `restore`, `dataupload`, and `datadownload` in this version, directly deleting Velero namespace may get stuck indefinitely because the pods responsible for handling the finalizers might be deleted before the resources attached to the finalizers. To avoid this issue, please use the command `velero uninstall` to delete all the Velero resources or ensure that you handle the finalizer appropriately before deleting the Velero namespace. ### Limitations/Known issues @@ -132,3 +133,10 @@ prior PVC restores with CSI (#6111, @eemcmullan) * Make GetPluginConfig accessible from other packages. (#6151, @tkaovila) * Ignore not found error during patching managedFields (#6136, @ywk253100) * Fix the goreleaser issues and add a new goreleaser action (#6109, @blackpiglet) +* Add CSI snapshot data movement doc (#6793, @Lyndon-Li) +* Use old(origin) namespace in resource modifier conditions in case namespace may change during restore (#6724, @27149chen) +* Fix #6752: add namespace exclude check. (#6762, @blackpiglet) +* Update restore controller logic for restore deletion (#6761, @ywk253100) +* Fix issue #6753, remove the check for read-only BSL in restore async operation controller since Velero cannot fully support read-only mode BSL in restore at present (#6758, @Lyndon-Li) +* Fixes #6636, skip subresource in resource discovery (#6688, @27149chen) +* This pr made some improvements in Resource Modifiers:1. add label selector 2. change the field name from groupKind to groupResource (#6704, @27149chen) diff --git a/changelogs/unreleased/6688-27149chen b/changelogs/unreleased/6688-27149chen deleted file mode 100644 index 229d6e075a..0000000000 --- a/changelogs/unreleased/6688-27149chen +++ /dev/null @@ -1 +0,0 @@ -Fixes #6636, skip subresource in resource discovery \ No newline at end of file diff --git a/changelogs/unreleased/6758-Lyndon-Li b/changelogs/unreleased/6758-Lyndon-Li deleted file mode 100644 index 1e095ee673..0000000000 --- a/changelogs/unreleased/6758-Lyndon-Li +++ /dev/null @@ -1 +0,0 @@ -Fix issue #6753, remove the check for read-only BSL in restore async operation controller since Velero cannot fully support read-only mode BSL in restore at present \ No newline at end of file diff --git a/changelogs/unreleased/6761-ywk253100 b/changelogs/unreleased/6761-ywk253100 deleted file mode 100644 index 6e55ffcd49..0000000000 --- a/changelogs/unreleased/6761-ywk253100 +++ /dev/null @@ -1 +0,0 @@ -Update restore controller logic for restore deletion \ No newline at end of file diff --git a/changelogs/unreleased/6762-blackpiglet b/changelogs/unreleased/6762-blackpiglet deleted file mode 100644 index db9b5a118c..0000000000 --- a/changelogs/unreleased/6762-blackpiglet +++ /dev/null @@ -1 +0,0 @@ -Fix #6752: add namespace exclude check. \ No newline at end of file diff --git a/changelogs/unreleased/6793-Lyndon-Li b/changelogs/unreleased/6793-Lyndon-Li deleted file mode 100644 index b816b976bc..0000000000 --- a/changelogs/unreleased/6793-Lyndon-Li +++ /dev/null @@ -1 +0,0 @@ -Add CSI snapshot data movement doc \ No newline at end of file From 075149e9ea231a5e29f9ae1bc5869d5f4100a90c Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Wed, 13 Sep 2023 16:11:35 +0800 Subject: [PATCH 47/90] issue 6786:always delete VSC regardless of the deletion policy Signed-off-by: Lyndon-Li --- changelogs/unreleased/6873-Lyndon-Li | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6873-Lyndon-Li diff --git a/changelogs/unreleased/6873-Lyndon-Li b/changelogs/unreleased/6873-Lyndon-Li new file mode 100644 index 0000000000..1aac387e08 --- /dev/null +++ b/changelogs/unreleased/6873-Lyndon-Li @@ -0,0 +1 @@ +Fix issue #6786, always delete VSC regardless of the deletion policy \ No newline at end of file From 2817a347d9711afd86268ee33595c4b4b6edcb7c Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Tue, 26 Sep 2023 16:21:46 +0800 Subject: [PATCH 48/90] issue: move plugin depdending podvolume functions to util pkg Signed-off-by: Lyndon-Li --- changelogs/unreleased/6877-Lyndon-Li | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6877-Lyndon-Li diff --git a/changelogs/unreleased/6877-Lyndon-Li b/changelogs/unreleased/6877-Lyndon-Li new file mode 100644 index 0000000000..8d11bca2c9 --- /dev/null +++ b/changelogs/unreleased/6877-Lyndon-Li @@ -0,0 +1 @@ +Fix issue #6859, move plugin depending podvolume functions to util pkg, so as to remove the dependencies to unnecessary repository packages like kopia, azure, etc. \ No newline at end of file From e8c87878e4e00a491419a68a5644a3a26f332742 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Thu, 28 Sep 2023 10:28:49 +0800 Subject: [PATCH 49/90] issue 6880: set ParallelUploadAboveSize as MaxInt64 Signed-off-by: Lyndon-Li --- changelogs/unreleased/6886-Lyndon-Li | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6886-Lyndon-Li diff --git a/changelogs/unreleased/6886-Lyndon-Li b/changelogs/unreleased/6886-Lyndon-Li new file mode 100644 index 0000000000..f879897c0e --- /dev/null +++ b/changelogs/unreleased/6886-Lyndon-Li @@ -0,0 +1 @@ +Set ParallelUploadAboveSize as MaxInt64 and flush repo after setting up policy so that policy is retrieved correctly by TreeForSource \ No newline at end of file From aaa3a5af3afe2c693b0e9a43e03c42e2e8f60eff Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Mon, 28 Aug 2023 10:45:55 -0400 Subject: [PATCH 50/90] changelog Signed-off-by: Tiger Kaovilai --- changelogs/unreleased/6713-kaovilai | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6713-kaovilai diff --git a/changelogs/unreleased/6713-kaovilai b/changelogs/unreleased/6713-kaovilai new file mode 100644 index 0000000000..e597187560 --- /dev/null +++ b/changelogs/unreleased/6713-kaovilai @@ -0,0 +1 @@ +Kubernetes 1.27 new job label batch.kubernetes.io/controller-uid are deleted during restore per https://github.com/kubernetes/kubernetes/pull/114930 \ No newline at end of file From 81c151a6851b8a6e1b0e1a0fe54b2d7b1aa1142c Mon Sep 17 00:00:00 2001 From: David Zaninovic <74072514+dzaninovic@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:28:35 -0400 Subject: [PATCH 51/90] Add support for block volumes (#6680) (#6897) (cherry picked from commit 8e01d1b9be31d30f88e90003af6c4ce15c64ee65) Signed-off-by: David Zaninovic --- changelogs/unreleased/6897-dzaninovic | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6897-dzaninovic diff --git a/changelogs/unreleased/6897-dzaninovic b/changelogs/unreleased/6897-dzaninovic new file mode 100644 index 0000000000..b4d735d145 --- /dev/null +++ b/changelogs/unreleased/6897-dzaninovic @@ -0,0 +1 @@ +Add support for block volumes with Kopia \ No newline at end of file From c0444dfe3d4d99b0d9c0db294570eea42a5ca8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wenkai=20Yin=28=E5=B0=B9=E6=96=87=E5=BC=80=29?= Date: Wed, 27 Sep 2023 20:09:51 +0800 Subject: [PATCH 52/90] Replace the base image with paketobuildpacks image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the base image with paketobuildpacks image Fixes #6851 Signed-off-by: Wenkai Yin(尹文开) --- changelogs/unreleased/6934-ywk253100 | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6934-ywk253100 diff --git a/changelogs/unreleased/6934-ywk253100 b/changelogs/unreleased/6934-ywk253100 new file mode 100644 index 0000000000..bc8d80b92e --- /dev/null +++ b/changelogs/unreleased/6934-ywk253100 @@ -0,0 +1 @@ +Replace the base image with paketobuildpacks image \ No newline at end of file From 6e1a61da520f4feb7c8a106362828631642b79c2 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Tue, 10 Oct 2023 11:04:04 +0800 Subject: [PATCH 53/90] issue 6734: spread backup pod evenly Signed-off-by: Lyndon-Li --- changelogs/unreleased/6935-Lyndon-Li | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6935-Lyndon-Li diff --git a/changelogs/unreleased/6935-Lyndon-Li b/changelogs/unreleased/6935-Lyndon-Li new file mode 100644 index 0000000000..b14c4f3cce --- /dev/null +++ b/changelogs/unreleased/6935-Lyndon-Li @@ -0,0 +1 @@ +Partially fix #6734, guide Kubernetes' scheduler to spread backup pods evenly across nodes as much as possible, so that data mover backup could achieve better parallelism \ No newline at end of file From 40a75b20be1993f33724607d118a55e2972619f1 Mon Sep 17 00:00:00 2001 From: allenxu404 Date: Thu, 28 Sep 2023 14:27:20 +0800 Subject: [PATCH 54/90] Add doc links for new features to release note Signed-off-by: allenxu404 --- changelogs/CHANGELOG-1.12.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/changelogs/CHANGELOG-1.12.md b/changelogs/CHANGELOG-1.12.md index 4472cc77d2..a987cb405e 100644 --- a/changelogs/CHANGELOG-1.12.md +++ b/changelogs/CHANGELOG-1.12.md @@ -23,17 +23,17 @@ CSI Snapshot Data Movement is useful in below scenarios: * For on-premises users, the storage usually doesn't support durable snapshots, so it is impossible/less efficient/cost ineffective to keep volume snapshots by the storage This feature helps to move the snapshot data to a storage with lower cost and larger scale for long time preservation. * For public cloud users, this feature helps users to fulfill the multiple cloud strategy. It allows users to back up volume snapshots from one cloud provider and preserve or restore the data to another cloud provider. Then users will be free to flow their business data across cloud providers based on Velero backup and restore -CSI Snapshot Data Movement is built according to the Volume Snapshot Data Movement design ([Volume Snapshot Data Movement](https://github.com/vmware-tanzu/velero/blob/main/design/Implemented/unified-repo-and-kopia-integration/unified-repo-and-kopia-integration.md)). More details can be found in the design. +CSI Snapshot Data Movement is built according to the Volume Snapshot Data Movement design ([Volume Snapshot Data Movement design](https://github.com/vmware-tanzu/velero/blob/main/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md)). Additionally, guidance on how to use the feature can be found in the Volume Snapshot Data Movement doc([Volume Snapshot Data Movement doc](https://velero.io/docs/v1.12/csi-snapshot-data-movement)). #### Resource Modifiers In many use cases, customers often need to substitute specific values in Kubernetes resources during the restoration process like changing the namespace, changing the storage class, etc. -To address this need, Resource Modifiers (also known as JSON Substitutions) offer a generic solution in the restore workflow. It allows the user to define filters for specific resources and then specify a JSON patch (operator, path, value) to apply to the resource. This feature simplifies the process of making substitutions without requiring the implementation of a new RestoreItemAction plugin. More details can be found in Volume Snapshot Resource Modifiers design ([Resource Modifiers](https://github.com/vmware-tanzu/velero/blob/main/design/Implemented/json-substitution-action-design.md)). +To address this need, Resource Modifiers (also known as JSON Substitutions) offer a generic solution in the restore workflow. It allows the user to define filters for specific resources and then specify a JSON patch (operator, path, value) to apply to the resource. This feature simplifies the process of making substitutions without requiring the implementation of a new RestoreItemAction plugin. More design details can be found in Resource Modifiers design ([Resource Modifiers design](https://github.com/vmware-tanzu/velero/blob/main/design/Implemented/json-substitution-action-design.md)). For instructions on how to use the feature, please refer to Resource Modifiers doc([Resource Modifiers doc](https://velero.io/docs/v1.12/restore-resource-modifiers)). #### Multiple VolumeSnapshotClasses Prior to version 1.12, the Velero CSI plugin would choose the VolumeSnapshotClass in the cluster based on matching driver names and the presence of the "velero.io/csi-volumesnapshot-class" label. However, this approach proved inadequate for many user scenarios. -With the introduction of version 1.12, Velero now offers support for multiple VolumeSnapshotClasses in the CSI Plugin, enabling users to select a specific class for a particular backup. More details can be found in Multiple VolumeSnapshotClasses design ([Multiple VolumeSnapshotClasses](https://github.com/vmware-tanzu/velero/blob/main/design/Implemented/multiple-csi-volumesnapshotclass-support.md)). +With the introduction of version 1.12, Velero now offers support for multiple VolumeSnapshotClasses in the CSI Plugin, enabling users to select a specific class for a particular backup. More design details can be found in Multiple VolumeSnapshotClasses design ([Multiple VolumeSnapshotClasses design](https://github.com/vmware-tanzu/velero/blob/main/design/Implemented/multiple-csi-volumesnapshotclass-support.md)). For instructions on how to use the feature, please refer to Multiple VolumeSnapshotClasses doc ([Multiple VolumeSnapshotClasses doc](https://velero.io/docs/v1.12/csi/#implementation-choices)). #### Restore Finalizer Before v1.12, the restore controller would only delete restore resources but wouldn’t delete restore data from the backup storage location when the command `velero restore delete` was executed. The only chance Velero deletes restores data from the backup storage location is when the associated backup is deleted. @@ -56,6 +56,7 @@ To fix CVEs and keep pace with Golang, Velero made changes as follows: ### Limitations/Known issues * The Azure plugin supports Azure AD Workload identity way, but it only works for Velero native snapshots. It cannot support filesystem backup and snapshot data mover scenarios. +* File System backup under Kopia path and CSI Snapshot Data Movement backup fail to back up files that are large the 2GiB due to issue https://github.com/vmware-tanzu/velero/issues/6668. ### All Changes From e8b36b7a912c19550ad96b9e0d20ffe9ae5c0e08 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Mon, 28 Aug 2023 10:56:56 +0800 Subject: [PATCH 55/90] fix issue 6647 Signed-off-by: Lyndon-Li --- changelogs/unreleased/6940-Lyndon-Li | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6940-Lyndon-Li diff --git a/changelogs/unreleased/6940-Lyndon-Li b/changelogs/unreleased/6940-Lyndon-Li new file mode 100644 index 0000000000..6f614cb681 --- /dev/null +++ b/changelogs/unreleased/6940-Lyndon-Li @@ -0,0 +1 @@ +Fix issue #6647, add the --default-snapshot-move-data parameter to Velero install, so that users don't need to specify --snapshot-move-data per backup when they want to move snapshot data for all backups \ No newline at end of file From 6f8ad046774089b16ab20f325fac5e60d1658d7d Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Mon, 21 Aug 2023 11:36:46 -0400 Subject: [PATCH 56/90] Perf improvements for existing resource restore Use informer cache with dynamic client for Get calls on restore When enabled, also make the Get call before create. Add server and install parameter to allow disabling this feature, but enable by default Signed-off-by: Scott Seago --- changelogs/unreleased/6948-sseago | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6948-sseago diff --git a/changelogs/unreleased/6948-sseago b/changelogs/unreleased/6948-sseago new file mode 100644 index 0000000000..c971d27dcc --- /dev/null +++ b/changelogs/unreleased/6948-sseago @@ -0,0 +1 @@ +Perf improvements for existing resource restore From c7913bbdfb773da19d08c9d796285e4ac3976acd Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Wed, 13 Sep 2023 13:24:09 -0400 Subject: [PATCH 57/90] issue #6807: Retry failed create when using generateName When creating resources with generateName, apimachinery does not guarantee uniqueness when it appends the random suffix to the generateName stub, so if it fails with already exists error, we need to retry. Signed-off-by: Scott Seago --- changelogs/unreleased/6943-sseago | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6943-sseago diff --git a/changelogs/unreleased/6943-sseago b/changelogs/unreleased/6943-sseago new file mode 100644 index 0000000000..2055df15a2 --- /dev/null +++ b/changelogs/unreleased/6943-sseago @@ -0,0 +1 @@ +Retry failed create when using generateName From 45d5a40cd43f16719b05deb780d6ed9914f865d9 Mon Sep 17 00:00:00 2001 From: Sebastian Glab Date: Thu, 12 Oct 2023 15:40:29 +0200 Subject: [PATCH 58/90] Import auth provider plugins Signed-off-by: Sebastian Glab --- changelogs/unreleased/6970-0x113 | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6970-0x113 diff --git a/changelogs/unreleased/6970-0x113 b/changelogs/unreleased/6970-0x113 new file mode 100644 index 0000000000..1cf76eb51a --- /dev/null +++ b/changelogs/unreleased/6970-0x113 @@ -0,0 +1 @@ +Import auth provider plugins From c3b9fa610cd496b8627fa788560fbe368f67f449 Mon Sep 17 00:00:00 2001 From: allenxu404 Date: Fri, 20 Oct 2023 11:15:25 +0800 Subject: [PATCH 59/90] Add v1.12.1 changelog Signed-off-by: allenxu404 --- changelogs/CHANGELOG-1.12.md | 29 +++++++++++++++++++++++++++ changelogs/unreleased/6713-kaovilai | 1 - changelogs/unreleased/6873-Lyndon-Li | 1 - changelogs/unreleased/6877-Lyndon-Li | 1 - changelogs/unreleased/6886-Lyndon-Li | 1 - changelogs/unreleased/6897-dzaninovic | 1 - changelogs/unreleased/6934-ywk253100 | 1 - changelogs/unreleased/6935-Lyndon-Li | 1 - changelogs/unreleased/6940-Lyndon-Li | 1 - changelogs/unreleased/6943-sseago | 1 - changelogs/unreleased/6948-sseago | 1 - changelogs/unreleased/6970-0x113 | 1 - 12 files changed, 29 insertions(+), 11 deletions(-) delete mode 100644 changelogs/unreleased/6713-kaovilai delete mode 100644 changelogs/unreleased/6873-Lyndon-Li delete mode 100644 changelogs/unreleased/6877-Lyndon-Li delete mode 100644 changelogs/unreleased/6886-Lyndon-Li delete mode 100644 changelogs/unreleased/6897-dzaninovic delete mode 100644 changelogs/unreleased/6934-ywk253100 delete mode 100644 changelogs/unreleased/6935-Lyndon-Li delete mode 100644 changelogs/unreleased/6940-Lyndon-Li delete mode 100644 changelogs/unreleased/6943-sseago delete mode 100644 changelogs/unreleased/6948-sseago delete mode 100644 changelogs/unreleased/6970-0x113 diff --git a/changelogs/CHANGELOG-1.12.md b/changelogs/CHANGELOG-1.12.md index a987cb405e..16b5cdaef6 100644 --- a/changelogs/CHANGELOG-1.12.md +++ b/changelogs/CHANGELOG-1.12.md @@ -1,3 +1,32 @@ +## v1.12.1 +### 2023-10-20 + +### Download +https://github.com/vmware-tanzu/velero/releases/tag/v1.12.1 + +### Container Image +`velero/velero:v1.12.1` + +### Documentation +https://velero.io/docs/v1.12/ + +### Upgrading +https://velero.io/docs/v1.12/upgrade-to-1.12/ + +### All changes +* Import auth provider plugins (#6970, @0x113) +* Perf improvements for existing resource restore (#6948, @sseago) +* Retry failed create when using generateName (#6943, @sseago) +* Fix issue #6647, add the --default-snapshot-move-data parameter to Velero install, so that users don't need to specify --snapshot-move-data per backup when they want to move snapshot data for all backups (#6940, @Lyndon-Li) +* Partially fix #6734, guide Kubernetes' scheduler to spread backup pods evenly across nodes as much as possible, so that data mover backup could achieve better parallelism (#6935, @Lyndon-Li) +* Replace the base image with paketobuildpacks image (#6934, @ywk253100) +* Add support for block volumes with Kopia (#6897, @dzaninovic) +* Set ParallelUploadAboveSize as MaxInt64 and flush repo after setting up policy so that policy is retrieved correctly by TreeForSource (#6886, @Lyndon-Li) +* Kubernetes 1.27 new job label batch.kubernetes.io/controller-uid are deleted during restore per https://github.com/kubernetes/kubernetes/pull/114930 (#6713, @kaovilai) +* Add `orLabelSelectors` for backup, restore commands (#6881, @nilesh-akhade) +* Fix issue #6859, move plugin depending podvolume functions to util pkg, so as to remove the dependencies to unnecessary repository packages like kopia, azure, etc. (#6877, @Lyndon-Li) +* Fix issue #6786, always delete VSC regardless of the deletion policy (#6873, @Lyndon-Li) + ## v1.12 ### 2023-08-18 diff --git a/changelogs/unreleased/6713-kaovilai b/changelogs/unreleased/6713-kaovilai deleted file mode 100644 index e597187560..0000000000 --- a/changelogs/unreleased/6713-kaovilai +++ /dev/null @@ -1 +0,0 @@ -Kubernetes 1.27 new job label batch.kubernetes.io/controller-uid are deleted during restore per https://github.com/kubernetes/kubernetes/pull/114930 \ No newline at end of file diff --git a/changelogs/unreleased/6873-Lyndon-Li b/changelogs/unreleased/6873-Lyndon-Li deleted file mode 100644 index 1aac387e08..0000000000 --- a/changelogs/unreleased/6873-Lyndon-Li +++ /dev/null @@ -1 +0,0 @@ -Fix issue #6786, always delete VSC regardless of the deletion policy \ No newline at end of file diff --git a/changelogs/unreleased/6877-Lyndon-Li b/changelogs/unreleased/6877-Lyndon-Li deleted file mode 100644 index 8d11bca2c9..0000000000 --- a/changelogs/unreleased/6877-Lyndon-Li +++ /dev/null @@ -1 +0,0 @@ -Fix issue #6859, move plugin depending podvolume functions to util pkg, so as to remove the dependencies to unnecessary repository packages like kopia, azure, etc. \ No newline at end of file diff --git a/changelogs/unreleased/6886-Lyndon-Li b/changelogs/unreleased/6886-Lyndon-Li deleted file mode 100644 index f879897c0e..0000000000 --- a/changelogs/unreleased/6886-Lyndon-Li +++ /dev/null @@ -1 +0,0 @@ -Set ParallelUploadAboveSize as MaxInt64 and flush repo after setting up policy so that policy is retrieved correctly by TreeForSource \ No newline at end of file diff --git a/changelogs/unreleased/6897-dzaninovic b/changelogs/unreleased/6897-dzaninovic deleted file mode 100644 index b4d735d145..0000000000 --- a/changelogs/unreleased/6897-dzaninovic +++ /dev/null @@ -1 +0,0 @@ -Add support for block volumes with Kopia \ No newline at end of file diff --git a/changelogs/unreleased/6934-ywk253100 b/changelogs/unreleased/6934-ywk253100 deleted file mode 100644 index bc8d80b92e..0000000000 --- a/changelogs/unreleased/6934-ywk253100 +++ /dev/null @@ -1 +0,0 @@ -Replace the base image with paketobuildpacks image \ No newline at end of file diff --git a/changelogs/unreleased/6935-Lyndon-Li b/changelogs/unreleased/6935-Lyndon-Li deleted file mode 100644 index b14c4f3cce..0000000000 --- a/changelogs/unreleased/6935-Lyndon-Li +++ /dev/null @@ -1 +0,0 @@ -Partially fix #6734, guide Kubernetes' scheduler to spread backup pods evenly across nodes as much as possible, so that data mover backup could achieve better parallelism \ No newline at end of file diff --git a/changelogs/unreleased/6940-Lyndon-Li b/changelogs/unreleased/6940-Lyndon-Li deleted file mode 100644 index 6f614cb681..0000000000 --- a/changelogs/unreleased/6940-Lyndon-Li +++ /dev/null @@ -1 +0,0 @@ -Fix issue #6647, add the --default-snapshot-move-data parameter to Velero install, so that users don't need to specify --snapshot-move-data per backup when they want to move snapshot data for all backups \ No newline at end of file diff --git a/changelogs/unreleased/6943-sseago b/changelogs/unreleased/6943-sseago deleted file mode 100644 index 2055df15a2..0000000000 --- a/changelogs/unreleased/6943-sseago +++ /dev/null @@ -1 +0,0 @@ -Retry failed create when using generateName diff --git a/changelogs/unreleased/6948-sseago b/changelogs/unreleased/6948-sseago deleted file mode 100644 index c971d27dcc..0000000000 --- a/changelogs/unreleased/6948-sseago +++ /dev/null @@ -1 +0,0 @@ -Perf improvements for existing resource restore diff --git a/changelogs/unreleased/6970-0x113 b/changelogs/unreleased/6970-0x113 deleted file mode 100644 index 1cf76eb51a..0000000000 --- a/changelogs/unreleased/6970-0x113 +++ /dev/null @@ -1 +0,0 @@ -Import auth provider plugins From a1bc9ebc7af8fd8bb9268b82c91dcf0f4d5cef27 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 20 Oct 2023 15:43:42 +0800 Subject: [PATCH 60/90] Make Windows build skip BlockMode code. PVC block mode backup and restore introduced some OS specific system calls. Those calls are not available for Windows, so add both non Windows version and Windows version code, and return error for block mode on the Windows platform. Signed-off-by: Xun Jiang --- changelogs/unreleased/6986-blackpiglet | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6986-blackpiglet diff --git a/changelogs/unreleased/6986-blackpiglet b/changelogs/unreleased/6986-blackpiglet new file mode 100644 index 0000000000..4eae63eaee --- /dev/null +++ b/changelogs/unreleased/6986-blackpiglet @@ -0,0 +1 @@ +Add both non-Windows version and Windows version code for PVC block mode logic. \ No newline at end of file From e4167d8521d7905dc6d3da4e40711dc106c04042 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Fri, 20 Oct 2023 18:37:07 +0800 Subject: [PATCH 61/90] udmrepo use region specified in BSL when s3URL is empty Signed-off-by: Lyndon-Li --- changelogs/unreleased/6991-Lyndon-Li | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6991-Lyndon-Li diff --git a/changelogs/unreleased/6991-Lyndon-Li b/changelogs/unreleased/6991-Lyndon-Li new file mode 100644 index 0000000000..6f79e1c9d2 --- /dev/null +++ b/changelogs/unreleased/6991-Lyndon-Li @@ -0,0 +1 @@ +Fix #6988, always get region from BSL if it is not empty \ No newline at end of file From 83edcf38a247c909b3bfe5831786bd093200b6ec Mon Sep 17 00:00:00 2001 From: allenxu404 Date: Fri, 20 Oct 2023 20:47:00 +0800 Subject: [PATCH 62/90] Change v1.12.1 changelog Signed-off-by: allenxu404 --- changelogs/CHANGELOG-1.12.md | 16 ++++++++++++++++ changelogs/unreleased/6986-blackpiglet | 1 - changelogs/unreleased/6991-Lyndon-Li | 1 - 3 files changed, 16 insertions(+), 2 deletions(-) delete mode 100644 changelogs/unreleased/6986-blackpiglet delete mode 100644 changelogs/unreleased/6991-Lyndon-Li diff --git a/changelogs/CHANGELOG-1.12.md b/changelogs/CHANGELOG-1.12.md index 16b5cdaef6..8182b3e8af 100644 --- a/changelogs/CHANGELOG-1.12.md +++ b/changelogs/CHANGELOG-1.12.md @@ -13,6 +13,20 @@ https://velero.io/docs/v1.12/ ### Upgrading https://velero.io/docs/v1.12/upgrade-to-1.12/ +### Highlights + +#### Data Mover Adds Support for Block Mode Volumes +For PersistentVolumes with volumeMode set as Block, the volumes are mounted as raw block devices in pods, in 1.12.1, Velero CSI snapshot data movement supports to backup and restore this kind of volumes under linux based Kubernetes clusters. + +#### New Parameter in Installation to Enable Data Mover +The `velero install` sub-command now includes a new parameter,`--default-snapshot-move-data`, which configures Velero server to move data by default for all snapshots supporting data movement. This feature is useful for users who will always want to use VBDM for backups instead of plain CSI , as they no longer need to specify the `--snapshot-move-data` flag for each individual backup. + +#### Velero Base Image change +The base image previously used by Velero was `distroless`, which contains several CVEs cannot be addressed quickly. As a result, Velero will now use `paketobuildpacks` image starting from this new version. + +### Limitations/Known issues +* The data mover's support for block mode volumes is currently only applicable to Linux environments. + ### All changes * Import auth provider plugins (#6970, @0x113) * Perf improvements for existing resource restore (#6948, @sseago) @@ -26,6 +40,8 @@ https://velero.io/docs/v1.12/upgrade-to-1.12/ * Add `orLabelSelectors` for backup, restore commands (#6881, @nilesh-akhade) * Fix issue #6859, move plugin depending podvolume functions to util pkg, so as to remove the dependencies to unnecessary repository packages like kopia, azure, etc. (#6877, @Lyndon-Li) * Fix issue #6786, always delete VSC regardless of the deletion policy (#6873, @Lyndon-Li) +* Fix #6988, always get region from BSL if it is not empty (#6991, @Lyndon-Li) +* Add both non-Windows version and Windows version code for PVC block mode logic. (#6986, @blackpiglet) ## v1.12 ### 2023-08-18 diff --git a/changelogs/unreleased/6986-blackpiglet b/changelogs/unreleased/6986-blackpiglet deleted file mode 100644 index 4eae63eaee..0000000000 --- a/changelogs/unreleased/6986-blackpiglet +++ /dev/null @@ -1 +0,0 @@ -Add both non-Windows version and Windows version code for PVC block mode logic. \ No newline at end of file diff --git a/changelogs/unreleased/6991-Lyndon-Li b/changelogs/unreleased/6991-Lyndon-Li deleted file mode 100644 index 6f79e1c9d2..0000000000 --- a/changelogs/unreleased/6991-Lyndon-Li +++ /dev/null @@ -1 +0,0 @@ -Fix #6988, always get region from BSL if it is not empty \ No newline at end of file From e3705a621973ed382a72911d9e6c611a03493b85 Mon Sep 17 00:00:00 2001 From: Dylan Murray Date: Mon, 29 Jun 2020 13:49:38 -0400 Subject: [PATCH 63/90] Dockerfile.ubi/travis local files add UBI dockerfiles Use numeric user for velero-restic-restore-helper Enable multiarch builds (#135) Use arm64-graviton2 for arm builds (#137) Add required keys for arm builds (#139) Update Travis build job to work w/o changes on new branches Use a full VM for arm Use numeric non-root user for nonroot SCC compatibility --- .travis.yml | 78 ++++++++++++++++++++++++++++ Dockerfile-velero-restore-helper.ubi | 14 +++++ Dockerfile.ubi | 23 ++++++++ 3 files changed, 115 insertions(+) create mode 100644 .travis.yml create mode 100644 Dockerfile-velero-restore-helper.ubi create mode 100644 Dockerfile.ubi diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..13365b48a5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,78 @@ +os: linux +services: docker +dist: focal +language: go +go: stable + +env: + global: + - IMAGE1: quay.io/konveyor/velero + - IMAGE2: quay.io/konveyor/velero-restore-helper + - DEFAULT_BRANCH: konveyor-dev + - DOCKERFILE1: Dockerfile.ubi + - DOCKERFILE2: Dockerfile-velero-restore-helper.ubi + - DOCKER_CLI_EXPERIMENTAL: enabled + - GOPROXY: https://goproxy.io,direct + +before_install: +- | + if [ "${TRAVIS_BRANCH}" == "${DEFAULT_BRANCH}" ]; then + export TAG=latest + else + export TAG="${TRAVIS_BRANCH}" + fi + +# Builds routinely fail due to download failures inside alternate arch docker containers +# Here we are downloading outside the docker container and copying the deps in +# Also use -v for downloads/builds to stop no output failures from lxd env buffering. +before_script: +- go mod vendor -v +- git clone https://github.com/konveyor/restic -b ${TRAVIS_BRANCH} +- pushd restic; go mod vendor -v; popd +- sed -i 's|-mod=mod|-mod=vendor|g' ${DOCKERFILE1} +- sed -i 's|-mod=mod|-mod=vendor|g' ${DOCKERFILE2} +- sed -i 's|go build|go build -v|g' ${DOCKERFILE1} +- sed -i 's|go build|go build -v|g' ${DOCKERFILE2} +- sed -i 's|^RUN mkdir -p \$APP_ROOT/src/github.com/restic \\$|COPY --chown=1001 restic/ $APP_ROOT/src/github.com/restic/restic|g' ${DOCKERFILE1} +- sed -i 's|&& cd \$APP_ROOT/src/github.com/restic \\$||g' ${DOCKERFILE1} +- sed -i 's|&& git clone https://github.com/konveyor/restic -b .*$||g' ${DOCKERFILE1} + +script: +- docker build -t ${IMAGE1}:${TAG}-${TRAVIS_ARCH} -f ${DOCKERFILE1} . +- docker build -t ${IMAGE2}:${TAG}-${TRAVIS_ARCH} -f ${DOCKERFILE2} . +- if [ -n "${QUAY_ROBOT}" ]; then docker login quay.io -u "${QUAY_ROBOT}" -p ${QUAY_TOKEN}; fi +- if [ -n "${QUAY_ROBOT}" ]; then docker push ${IMAGE1}:${TAG}-${TRAVIS_ARCH}; fi +- if [ -n "${QUAY_ROBOT}" ]; then docker push ${IMAGE2}:${TAG}-${TRAVIS_ARCH}; fi + +jobs: + include: + - stage: build images + arch: ppc64le + - arch: s390x + - arch: arm64-graviton2 + virt: vm + group: edge + - arch: amd64 + - stage: push manifest + language: shell + arch: amd64 + before_script: [] + script: + - | + if [ -n "${QUAY_ROBOT}" ]; then + docker login quay.io -u "${QUAY_ROBOT}" -p ${QUAY_TOKEN} + docker manifest create \ + ${IMAGE1}:${TAG} \ + ${IMAGE1}:${TAG}-amd64 \ + ${IMAGE1}:${TAG}-ppc64le \ + ${IMAGE1}:${TAG}-s390x \ + ${IMAGE1}:${TAG}-aarch64 + docker manifest create \ + ${IMAGE2}:${TAG} \ + ${IMAGE2}:${TAG}-amd64 \ + ${IMAGE2}:${TAG}-ppc64le \ + ${IMAGE2}:${TAG}-s390x \ + ${IMAGE2}:${TAG}-aarch64 + docker manifest push ${IMAGE1}:${TAG} + docker manifest push ${IMAGE2}:${TAG} + fi diff --git a/Dockerfile-velero-restore-helper.ubi b/Dockerfile-velero-restore-helper.ubi new file mode 100644 index 0000000000..6ba5c1c33d --- /dev/null +++ b/Dockerfile-velero-restore-helper.ubi @@ -0,0 +1,14 @@ +FROM quay.io/konveyor/builder:latest AS builder +ENV GOPATH=$APP_ROOT +COPY . $APP_ROOT/src/github.com/vmware-tanzu/velero +WORKDIR $APP_ROOT/src/github.com/vmware-tanzu/velero +RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o $APP_ROOT/src/velero-restore-helper github.com/vmware-tanzu/velero/cmd/velero-restore-helper + +FROM registry.access.redhat.com/ubi8-minimal +RUN microdnf -y update && microdnf clean all + +COPY --from=builder /opt/app-root/src/velero-restore-helper velero-restore-helper + +USER 65534:65534 + +ENTRYPOINT [ "/velero-restore-helper" ] diff --git a/Dockerfile.ubi b/Dockerfile.ubi new file mode 100644 index 0000000000..3f4999b7e6 --- /dev/null +++ b/Dockerfile.ubi @@ -0,0 +1,23 @@ +# TODO! Find a real ubi8 image for golang 1.16 +FROM quay.io/konveyor/builder:latest AS builder +ENV GOPATH=$APP_ROOT +COPY . /go/src/github.com/vmware-tanzu/velero +WORKDIR /go/src/github.com/vmware-tanzu/velero +RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static" -X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=konveyor-dev' -o /go/src/velero github.com/vmware-tanzu/velero/cmd/velero + +FROM quay.io/konveyor/builder:latest AS restic-builder +ENV GOPATH=$APP_ROOT +RUN mkdir -p $APP_ROOT/src/github.com/restic \ +&& cd $APP_ROOT/src/github.com/restic \ +&& git clone https://github.com/konveyor/restic -b konveyor-dev +WORKDIR $APP_ROOT/src/github.com/restic/restic +RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o $APP_ROOT/src/restic github.com/restic/restic/cmd/restic + +FROM registry.access.redhat.com/ubi8-minimal +RUN microdnf -y update && microdnf -y install nmap-ncat && microdnf clean all +COPY --from=builder /go/src/velero velero +COPY --from=restic-builder /opt/app-root/src/restic /usr/bin/restic + +USER 65534:65534 + +ENTRYPOINT ["/velero"] From b353f4ef0a7164ab9e94ab63f5036ac94114b2cc Mon Sep 17 00:00:00 2001 From: RayfordJ Date: Thu, 28 Jan 2021 14:24:08 -0600 Subject: [PATCH 64/90] Add BZ + Publish automation to repo (#82) (cherry picked from commit ccb545fbcf293e0e7595a91763481cf4fa7e0d45) Update PR-BZ automation mapping (#84) (cherry picked from commit aa2b019366b98b64c46244e0a697540e7c4d5d2b) Update PR-BZ automation (#92) Co-authored-by: Rayford Johnson (cherry picked from commit ecc563f90324d9924318618f7a4a167f6ea231bf) Add publish workflow (#108) (cherry picked from commit f87b779eb243fa5b37731761613ea962103a5956) --- .github/workflows/bz-pr-action.yml | 38 +++++++++++++++++++ .github/workflows/pr-merge.yml | 37 ++++++++++++++++++ .github/workflows/publish.yml | 61 ++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 .github/workflows/bz-pr-action.yml create mode 100644 .github/workflows/pr-merge.yml create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/bz-pr-action.yml b/.github/workflows/bz-pr-action.yml new file mode 100644 index 0000000000..c1558ca482 --- /dev/null +++ b/.github/workflows/bz-pr-action.yml @@ -0,0 +1,38 @@ +# This is a basic workflow to help you get started with Actions + +name: BZ PR Creation + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + pull_request_target: + branches: + - "*" + types: + - opened + - edited + - reopened + - synchronize + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + bz-on-pr-create: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: docker://quay.io/konveyor/pr-bz-github-action + name: update bugzilla with posted pr + with: + org_repo: ${{ github.repository }} + pr_number: ${{ github.event.pull_request.number }} + bz_product: "Migration Toolkit for Containers" + title: ${{ github.event.pull_request.title }} + github_token: ${{ secrets.GITHUB_TOKEN }} + bugzilla_token: ${{ secrets.BUGZILLA_TOKEN }} diff --git a/.github/workflows/pr-merge.yml b/.github/workflows/pr-merge.yml new file mode 100644 index 0000000000..3c4ae6ee0f --- /dev/null +++ b/.github/workflows/pr-merge.yml @@ -0,0 +1,37 @@ +# This is a basic workflow to help you get started with Actions + +name: BZ Merge + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + pull_request_target: + branches: + - "*" + types: + - closed + + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in pnamearallel +jobs: + # This workflow contains a single job called "build" + bz-on-pr-merge: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: docker://quay.io/konveyor/pr-merge-github-action + name: update bugzilla to modified + with: + bugzilla_token: ${{ secrets.BUGZILLA_TOKEN }} + org_repo: ${{ github.repository }} + pr_number: ${{ github.event.pull_request.number }} + bz_product: "Migration Toolkit for Containers" + title: ${{ github.event.pull_request.title }} + github_token: ${{ secrets.GITHUB_TOKEN }} + branch_to_release: "release-1.4.4:1.4.4,release-1.4.3:1.4.3,konveyor-1.5.2:1.4.0,release-1.4.5:1.4.5,release-1.5.0:1.5.0,konveyor-dev:1.5.z" + base_branch: ${{ github.base_ref }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000000..f5817915f5 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,61 @@ +name: Publish Images + +on: + push: + branches: + - konveyor-dev + - 'release-*.*.*' + - 'sprint-*' + tags: + - 'release-*.*.*' + workflow_dispatch: + +env: + REGISTRY: quay.io + IMAGE_NAME: konveyor/velero + HELPER_IMAGE_NAME: konveyor/velero-restore-helper +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Extract branch name + shell: bash + run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" + id: extract_branch + + - name: Build container image + run: docker build . --file Dockerfile.ubi --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.extract_branch.outputs.branch }} + + - name: Build helper image + run: docker build . --file Dockerfile-velero-restore-helper.ubi --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.extract_branch.outputs.branch }} + + - name: Log into registry + run: echo "${{ secrets.QUAY_PUBLISH_TOKEN }}" | docker login quay.io -u ${{ secrets.QUAY_PUBLISH_ROBOT }} --password-stdin + + - name: Push container image + run: docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.extract_branch.outputs.branch }} + + - name: Push helper image + run: docker push ${{ env.REGISTRY }}/${{ env.HELPER_IMAGE_NAME }}:${{ steps.extract_branch.outputs.branch }} + + - name: Retag container image + run: docker tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.extract_branch.outputs.branch }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + if: ${{ github.ref == 'refs/heads/konveyor-dev' }} + + - name: Retag helper image + run: docker tag ${{ env.REGISTRY }}/${{ env.HELPER_IMAGE_NAME }}:${{ steps.extract_branch.outputs.branch }} ${{ env.REGISTRY }}/${{ env.HELPER_IMAGE_NAME }}:latest + if: ${{ github.ref == 'refs/heads/konveyor-dev' }} + + - name: push retagged container image + run: docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + if: ${{ github.ref == 'refs/heads/konveyor-dev' }} + + - name: push retagged helper image + run: docker push ${{ env.REGISTRY }}/${{ env.HELPER_IMAGE_NAME }}:latest + if: ${{ github.ref == 'refs/heads/konveyor-dev' }} From 6c07e146dfe9616b2a97553b7652999dd8da12c2 Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Fri, 4 Nov 2022 10:30:32 -0400 Subject: [PATCH 65/90] remove dependabot config from fork --- .github/dependabot.yml | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 45332806b9..0000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: 2 -updates: - # Dependencies listed in .github/workflows - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - labels: - - "Dependencies" - - "github_actions" - - "kind/changelog-not-required" - # Dependencies listed in go.mod - - package-ecosystem: "gomod" - directory: "/" # Location of package manifests - schedule: - interval: "weekly" - labels: - - "kind/changelog-not-required" - ignore: - - dependency-name: "*" - update-types: ["version-update:semver-major", "version-update:semver-minor", "version-update:semver-patch"] From 9c370680835af11968a4c87863cd4b696e7c456a Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Wed, 5 Apr 2023 11:22:54 -0400 Subject: [PATCH 66/90] Create Makefile.prow Code-gen no longer required on verify due to https://github.com/vmware-tanzu/velero/pull/6039 Signed-off-by: Tiger Kaovilai oadp-1.2: Update Makefile.prow to velero-restore-helper --- Makefile.prow | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Makefile.prow diff --git a/Makefile.prow b/Makefile.prow new file mode 100644 index 0000000000..b29dfc1d99 --- /dev/null +++ b/Makefile.prow @@ -0,0 +1,92 @@ +# warning: verify this inside a container with following: +# docker run -it --rm -v `pwd`:`pwd` -w `pwd` golang:1.18 bash -c "make -f Makefile.prow ci" +# +# otherwise unintended system changes may include, replacing your currently installed kubectl, binaries in GOBIN, files in GOPATH/src +# +# If formatting needs updating you can run +# GOFLAGS=-mod=mod make update + +GOFLAGS=-mod=mod +CONGEN_VERSION=0.7.0 +CODEGEN_VERSION=0.22.2 +PROWBIN=/tmp/prowbin +# Name of this Makefile +MAKEFILE=Makefile.prow +# emulate as close as possible upstream ci target +# upstream ci target: verify-modules verify all test +# we only need to modify verify, test, all to avoid docker usage +.PHONY: ci +ci: + @echo "go version is: $(shell go version)" + GOFLAGS=$(GOFLAGS) make verify-modules + make -f $(MAKEFILE) verify all test + +.PHONY: verify +verify: goimports controller-gen kubectl #code-generator +# add PROWBIN to PATH + @echo Verifying with PATH=$(PROWBIN):$(PATH) +# Per +# https://github.com/vmware-tanzu/velero/blob/dd660882d0db96d430547f39dc3694d1c1bc19f3/Makefile#L160-L163 +# code-generator tools require project to be in heirarchy such as github.com/vmware-tanzu/velero +# so we need to copy the project to GOPATH/src/github.com/vmware-tanzu/velero +# and then run verify from there +# otherwise the code-generator tools will fail + mkdir -p $(GOSRC)/github.com/vmware-tanzu/ + cp -r . $(GOSRC)/github.com/vmware-tanzu/velero + cd $(GOSRC)/github.com/vmware-tanzu/velero && \ + PATH=$(PROWBIN):$(PATH) GOFLAGS=$(GOFLAGS) hack/verify-all.sh + +.PHONY: all +all: + GOFLAGS=$(GOFLAGS) make local + GOFLAGS=$(GOFLAGS) BIN=velero-restore-helper make local + +.PHONY: test +# our test is modified to avoid docker usage +test: envtest + @echo Testing with KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) + KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) GOFLAGS=$(GOFLAGS) hack/test.sh + +GOPATH:=$(shell go env GOPATH) +GOBIN:=$(GOPATH)/bin +GOSRC:=$(GOPATH)/src +# if KUBEBUILDER_ASSETS contains space, escape it +KUBEBUILDER_ASSETS=$(shell echo $(shell $(GOBIN)/setup-envtest use -p path) | sed 's/ /\\ /g') +.PHONY: envtest +envtest: $(GOBIN)/setup-envtest + $(GOBIN)/setup-envtest use -p path + +$(GOBIN)/setup-envtest: + @echo Installing envtest tools + GOFLAGS= go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + @echo Installed envtest tools + +.PHONY: goimports +goimports: $(GOBIN)/goimports + +$(GOBIN)/goimports: + @echo Installing goimports + go install golang.org/x/tools/cmd/goimports@latest + @echo Installed goimports + +.PHONY: code-generator +code-generator: $(GOSRC)/k8s.io/code-generator + +$(GOSRC)/k8s.io/code-generator: + mkdir -p $(GOSRC)/k8s.io/ + cd $(GOSRC)/k8s.io/ && git clone -b v$(CODEGEN_VERSION) https://github.com/kubernetes/code-generator + +.PHONY: controller-gen +controller-gen: $(GOBIN)/controller-gen + +$(GOBIN)/controller-gen: + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v$(CONGEN_VERSION) + +.PHONY: kubectl +kubectl: $(PROWBIN)/kubectl + +$(PROWBIN)/kubectl: + curl -LO "https://dl.k8s.io/release/$(shell curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + chmod +x ./kubectl + mkdir -p $(PROWBIN) + mv ./kubectl $(PROWBIN) From e3b1a8afcb2059ee863514b777907329c0653898 Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Tue, 25 Jul 2023 16:57:14 -0400 Subject: [PATCH 67/90] set HOME in velero image for kopia, update controller-gen for CI (#280) Signed-off-by: Scott Seago --- Dockerfile.ubi | 4 ++++ Makefile.prow | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Dockerfile.ubi b/Dockerfile.ubi index 3f4999b7e6..f250eb5cfa 100644 --- a/Dockerfile.ubi +++ b/Dockerfile.ubi @@ -18,6 +18,10 @@ RUN microdnf -y update && microdnf -y install nmap-ncat && microdnf clean all COPY --from=builder /go/src/velero velero COPY --from=restic-builder /opt/app-root/src/restic /usr/bin/restic +RUN mkdir -p /home/velero +RUN chmod -R 777 /home/velero + USER 65534:65534 +ENV HOME=/home/velero ENTRYPOINT ["/velero"] diff --git a/Makefile.prow b/Makefile.prow index b29dfc1d99..7e43d0b8c2 100644 --- a/Makefile.prow +++ b/Makefile.prow @@ -7,7 +7,7 @@ # GOFLAGS=-mod=mod make update GOFLAGS=-mod=mod -CONGEN_VERSION=0.7.0 +CONGEN_VERSION=0.12.0 CODEGEN_VERSION=0.22.2 PROWBIN=/tmp/prowbin # Name of this Makefile From 0e910298eb4ad9326c46d4e5d1a19b8b8a3862fe Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Wed, 16 Aug 2023 10:56:28 -0400 Subject: [PATCH 68/90] build velero-helper binary for datamover pod --- Dockerfile.ubi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile.ubi b/Dockerfile.ubi index f250eb5cfa..602dd61b35 100644 --- a/Dockerfile.ubi +++ b/Dockerfile.ubi @@ -4,6 +4,7 @@ ENV GOPATH=$APP_ROOT COPY . /go/src/github.com/vmware-tanzu/velero WORKDIR /go/src/github.com/vmware-tanzu/velero RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static" -X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=konveyor-dev' -o /go/src/velero github.com/vmware-tanzu/velero/cmd/velero +RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o /go/src/velero-helper github.com/vmware-tanzu/velero/cmd/velero-helper FROM quay.io/konveyor/builder:latest AS restic-builder ENV GOPATH=$APP_ROOT @@ -16,6 +17,7 @@ RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static FROM registry.access.redhat.com/ubi8-minimal RUN microdnf -y update && microdnf -y install nmap-ncat && microdnf clean all COPY --from=builder /go/src/velero velero +COPY --from=builder /go/src/velero-helper velero-helper COPY --from=restic-builder /opt/app-root/src/restic /usr/bin/restic RUN mkdir -p /home/velero From 35a79ef467734cb4fe5a1204a396cbcad1850df5 Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Mon, 23 Oct 2023 13:29:17 -0400 Subject: [PATCH 69/90] restore: Use warning when Create IsAlreadyExist and Get error Signed-off-by: Tiger Kaovilai --- changelogs/unreleased/7004-kaovilai | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/7004-kaovilai diff --git a/changelogs/unreleased/7004-kaovilai b/changelogs/unreleased/7004-kaovilai new file mode 100644 index 0000000000..3b85df1962 --- /dev/null +++ b/changelogs/unreleased/7004-kaovilai @@ -0,0 +1 @@ +restore: Use warning when Create IsAlreadyExist and Get error \ No newline at end of file From d8fd9888f1b08f62ae636727b1d9e233447398ca Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Fri, 20 Oct 2023 14:01:26 -0400 Subject: [PATCH 70/90] kopia/repository/config/aws.go: Set session.Options profile from config Signed-off-by: Tiger Kaovilai --- changelogs/unreleased/6997-kaovilai | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/6997-kaovilai diff --git a/changelogs/unreleased/6997-kaovilai b/changelogs/unreleased/6997-kaovilai new file mode 100644 index 0000000000..ef3ab94066 --- /dev/null +++ b/changelogs/unreleased/6997-kaovilai @@ -0,0 +1 @@ +Fix unified repository (kopia) s3 credentials profile selection \ No newline at end of file From 96f14bae9f0a12a98e90e126781683b73bf69c99 Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Thu, 23 May 2024 11:40:40 -0400 Subject: [PATCH 71/90] use ubi9-latest to build --- Dockerfile.ubi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile.ubi b/Dockerfile.ubi index 602dd61b35..24ad19abc8 100644 --- a/Dockerfile.ubi +++ b/Dockerfile.ubi @@ -1,12 +1,12 @@ # TODO! Find a real ubi8 image for golang 1.16 -FROM quay.io/konveyor/builder:latest AS builder +FROM quay.io/konveyor/builder:ubi9-latest AS builder ENV GOPATH=$APP_ROOT COPY . /go/src/github.com/vmware-tanzu/velero WORKDIR /go/src/github.com/vmware-tanzu/velero RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static" -X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=konveyor-dev' -o /go/src/velero github.com/vmware-tanzu/velero/cmd/velero RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o /go/src/velero-helper github.com/vmware-tanzu/velero/cmd/velero-helper -FROM quay.io/konveyor/builder:latest AS restic-builder +FROM quay.io/konveyor/builder:ubi9-latest AS restic-builder ENV GOPATH=$APP_ROOT RUN mkdir -p $APP_ROOT/src/github.com/restic \ && cd $APP_ROOT/src/github.com/restic \ @@ -14,7 +14,7 @@ RUN mkdir -p $APP_ROOT/src/github.com/restic \ WORKDIR $APP_ROOT/src/github.com/restic/restic RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o $APP_ROOT/src/restic github.com/restic/restic/cmd/restic -FROM registry.access.redhat.com/ubi8-minimal +FROM registry.access.redhat.com/ubi9-minimal RUN microdnf -y update && microdnf -y install nmap-ncat && microdnf clean all COPY --from=builder /go/src/velero velero COPY --from=builder /go/src/velero-helper velero-helper From 3e97737d242b4ba55277d4574bea127735031c23 Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Wed, 5 Jun 2024 10:28:00 -0400 Subject: [PATCH 72/90] OADP-4225: add tzdata to Dockerfile.ubi --- Dockerfile.ubi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.ubi b/Dockerfile.ubi index 24ad19abc8..18e5dfad04 100644 --- a/Dockerfile.ubi +++ b/Dockerfile.ubi @@ -15,7 +15,7 @@ WORKDIR $APP_ROOT/src/github.com/restic/restic RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o $APP_ROOT/src/restic github.com/restic/restic/cmd/restic FROM registry.access.redhat.com/ubi9-minimal -RUN microdnf -y update && microdnf -y install nmap-ncat && microdnf clean all +RUN microdnf -y update && microdnf -y install nmap-ncat && microdnf -y reinstall tzdata && microdnf clean all COPY --from=builder /go/src/velero velero COPY --from=builder /go/src/velero-helper velero-helper COPY --from=restic-builder /opt/app-root/src/restic /usr/bin/restic From 0c50c4c71c2c267ce7c3d8f24467f588a28c7512 Mon Sep 17 00:00:00 2001 From: Mateus Oliveira Date: Mon, 17 Jun 2024 16:51:47 -0300 Subject: [PATCH 73/90] fix: CI (#316) Signed-off-by: Mateus Oliveira --- Makefile.prow | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.prow b/Makefile.prow index 7e43d0b8c2..a658fe2981 100644 --- a/Makefile.prow +++ b/Makefile.prow @@ -7,7 +7,7 @@ # GOFLAGS=-mod=mod make update GOFLAGS=-mod=mod -CONGEN_VERSION=0.12.0 +CONGEN_VERSION=0.14.0 CODEGEN_VERSION=0.22.2 PROWBIN=/tmp/prowbin # Name of this Makefile From 0f79b106874332be874dca8de6087dcfd4f83bb0 Mon Sep 17 00:00:00 2001 From: Mateus Oliveira Date: Tue, 6 Aug 2024 14:11:15 -0300 Subject: [PATCH 74/90] fix: ARM images (#332) * fix: ARM images Signed-off-by: Mateus Oliveira * fixup! fix: ARM images Signed-off-by: Mateus Oliveira --------- Signed-off-by: Mateus Oliveira --- Dockerfile-velero-restore-helper.ubi | 12 +++++++++--- Dockerfile.ubi | 23 +++++++++++++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Dockerfile-velero-restore-helper.ubi b/Dockerfile-velero-restore-helper.ubi index 6ba5c1c33d..7c168c05ed 100644 --- a/Dockerfile-velero-restore-helper.ubi +++ b/Dockerfile-velero-restore-helper.ubi @@ -1,10 +1,16 @@ -FROM quay.io/konveyor/builder:latest AS builder +FROM quay.io/konveyor/builder:ubi9-latest AS builder +ARG TARGETOS +ARG TARGETARCH + ENV GOPATH=$APP_ROOT + COPY . $APP_ROOT/src/github.com/vmware-tanzu/velero + WORKDIR $APP_ROOT/src/github.com/vmware-tanzu/velero -RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o $APP_ROOT/src/velero-restore-helper github.com/vmware-tanzu/velero/cmd/velero-restore-helper -FROM registry.access.redhat.com/ubi8-minimal +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static"' -o $APP_ROOT/src/velero-restore-helper github.com/vmware-tanzu/velero/cmd/velero-restore-helper + +FROM registry.access.redhat.com/ubi9-minimal RUN microdnf -y update && microdnf clean all COPY --from=builder /opt/app-root/src/velero-restore-helper velero-restore-helper diff --git a/Dockerfile.ubi b/Dockerfile.ubi index 18e5dfad04..74a1899240 100644 --- a/Dockerfile.ubi +++ b/Dockerfile.ubi @@ -1,18 +1,29 @@ -# TODO! Find a real ubi8 image for golang 1.16 FROM quay.io/konveyor/builder:ubi9-latest AS builder +ARG TARGETOS +ARG TARGETARCH + ENV GOPATH=$APP_ROOT + COPY . /go/src/github.com/vmware-tanzu/velero + WORKDIR /go/src/github.com/vmware-tanzu/velero -RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static" -X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=konveyor-dev' -o /go/src/velero github.com/vmware-tanzu/velero/cmd/velero -RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o /go/src/velero-helper github.com/vmware-tanzu/velero/cmd/velero-helper + +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static" -X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=konveyor-dev' -o /go/src/velero github.com/vmware-tanzu/velero/cmd/velero +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static"' -o /go/src/velero-helper github.com/vmware-tanzu/velero/cmd/velero-helper FROM quay.io/konveyor/builder:ubi9-latest AS restic-builder +ARG TARGETOS +ARG TARGETARCH + ENV GOPATH=$APP_ROOT + RUN mkdir -p $APP_ROOT/src/github.com/restic \ -&& cd $APP_ROOT/src/github.com/restic \ -&& git clone https://github.com/konveyor/restic -b konveyor-dev + && cd $APP_ROOT/src/github.com/restic \ + && git clone https://github.com/konveyor/restic -b konveyor-dev + WORKDIR $APP_ROOT/src/github.com/restic/restic -RUN CGO_ENABLED=0 GOOS=linux go build -a -mod=mod -ldflags '-extldflags "-static"' -o $APP_ROOT/src/restic github.com/restic/restic/cmd/restic + +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static"' -o $APP_ROOT/src/restic github.com/restic/restic/cmd/restic FROM registry.access.redhat.com/ubi9-minimal RUN microdnf -y update && microdnf -y install nmap-ncat && microdnf -y reinstall tzdata && microdnf clean all From 95d19a4622719bf48ac9347022047ac1ac449cda Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Mon, 12 Aug 2024 17:44:49 -0400 Subject: [PATCH 75/90] ubi: BUILDPLATFORM to build stage to enable cross compile. (#336) Signed-off-by: Tiger Kaovilai --- Dockerfile-velero-restore-helper.ubi | 3 ++- Dockerfile.ubi | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Dockerfile-velero-restore-helper.ubi b/Dockerfile-velero-restore-helper.ubi index 7c168c05ed..9470ed75db 100644 --- a/Dockerfile-velero-restore-helper.ubi +++ b/Dockerfile-velero-restore-helper.ubi @@ -1,4 +1,5 @@ -FROM quay.io/konveyor/builder:ubi9-latest AS builder +FROM --platform=$BUILDPLATFORM quay.io/konveyor/builder:ubi9-latest AS builder +ARG BUILDPLATFORM ARG TARGETOS ARG TARGETARCH diff --git a/Dockerfile.ubi b/Dockerfile.ubi index 74a1899240..4b2f524849 100644 --- a/Dockerfile.ubi +++ b/Dockerfile.ubi @@ -1,4 +1,5 @@ -FROM quay.io/konveyor/builder:ubi9-latest AS builder +FROM --platform=$BUILDPLATFORM quay.io/konveyor/builder:ubi9-latest AS builder +ARG BUILDPLATFORM ARG TARGETOS ARG TARGETARCH @@ -11,7 +12,8 @@ WORKDIR /go/src/github.com/vmware-tanzu/velero RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static" -X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=konveyor-dev' -o /go/src/velero github.com/vmware-tanzu/velero/cmd/velero RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static"' -o /go/src/velero-helper github.com/vmware-tanzu/velero/cmd/velero-helper -FROM quay.io/konveyor/builder:ubi9-latest AS restic-builder +FROM --platform=$BUILDPLATFORM quay.io/konveyor/builder:ubi9-latest AS restic-builder +ARG BUILDPLATFORM ARG TARGETOS ARG TARGETARCH From b28fa42daca1852274997333ee42a78e9fca25fb Mon Sep 17 00:00:00 2001 From: Michal Pryc Date: Fri, 16 Aug 2024 19:34:39 +0200 Subject: [PATCH 76/90] OADP-4640: Downstream only to allow override kopia default algorithms (#334) (#338) add missing unit test for kopia hashing algo (#337) Introduction of downstream only option to override Kopia default: - hashing algorithm - splitting algorithm - encryption algorithm With introduction of 3 environment variables it is possible to override Kopia algorithms used by Velero: KOPIA_HASHING_ALGORITHM KOPIA_SPLITTER_ALGORITHM KOPIA_ENCRYPTION_ALGORITHM If the env algorithms are not set or they are not within Kopia SupportedAlgorithms, the default algorithm will be used. This behavior is consistent with current behavior without this change. Signed-off-by: Michal Pryc Signed-off-by: Shubham Pampattiwar --- .../udmrepo/kopialib/backend/common.go | 20 ++- .../backend/common_kopia_algorithms_test.go | 160 ++++++++++++++++++ 2 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go diff --git a/pkg/repository/udmrepo/kopialib/backend/common.go b/pkg/repository/udmrepo/kopialib/backend/common.go index 7af0612049..f2693330b5 100644 --- a/pkg/repository/udmrepo/kopialib/backend/common.go +++ b/pkg/repository/udmrepo/kopialib/backend/common.go @@ -18,6 +18,8 @@ package backend import ( "context" + "os" + "slices" "time" "github.com/kopia/kopia/repo" @@ -47,16 +49,28 @@ func setupLimits(ctx context.Context, flags map[string]string) throttling.Limits } } +// Helper function to choose between environment variable and default kopia algorithm value +func getKopiaAlgorithm(key, envKey string, flags map[string]string, supportedAlgorithms []string, defaultValue string) string { + algorithm := os.Getenv(envKey) + if len(algorithm) > 0 { + if slices.Contains(supportedAlgorithms, algorithm) { + return algorithm + } + } + + return optionalHaveStringWithDefault(key, flags, defaultValue) +} + // SetupNewRepositoryOptions setups the options when creating a new Kopia repository func SetupNewRepositoryOptions(ctx context.Context, flags map[string]string) repo.NewRepositoryOptions { return repo.NewRepositoryOptions{ BlockFormat: format.ContentFormat{ - Hash: optionalHaveStringWithDefault(udmrepo.StoreOptionGenHashAlgo, flags, hashing.DefaultAlgorithm), - Encryption: optionalHaveStringWithDefault(udmrepo.StoreOptionGenEncryptAlgo, flags, encryption.DefaultAlgorithm), + Hash: getKopiaAlgorithm(udmrepo.StoreOptionGenHashAlgo, "KOPIA_HASHING_ALGORITHM", flags, hashing.SupportedAlgorithms(), hashing.DefaultAlgorithm), + Encryption: getKopiaAlgorithm(udmrepo.StoreOptionGenEncryptAlgo, "KOPIA_ENCRYPTION_ALGORITHM", flags, encryption.SupportedAlgorithms(false), encryption.DefaultAlgorithm), }, ObjectFormat: format.ObjectFormat{ - Splitter: optionalHaveStringWithDefault(udmrepo.StoreOptionGenSplitAlgo, flags, splitter.DefaultAlgorithm), + Splitter: getKopiaAlgorithm(udmrepo.StoreOptionGenSplitAlgo, "KOPIA_SPLITTER_ALGORITHM", flags, splitter.SupportedAlgorithms(), splitter.DefaultAlgorithm), }, RetentionMode: blob.RetentionMode(optionalHaveString(udmrepo.StoreOptionGenRetentionMode, flags)), diff --git a/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go b/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go new file mode 100644 index 0000000000..969ea111d1 --- /dev/null +++ b/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go @@ -0,0 +1,160 @@ +/* +Copyright the Velero contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package backend + +import ( + "context" + "testing" + + "github.com/kopia/kopia/repo" + "github.com/kopia/kopia/repo/encryption" + "github.com/kopia/kopia/repo/format" + "github.com/kopia/kopia/repo/hashing" + "github.com/kopia/kopia/repo/splitter" + "github.com/stretchr/testify/assert" + + "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" +) + +func TestSetupNewRepoAlgorithms(t *testing.T) { + + testCases := []struct { + name string + envVars map[string]string + flags map[string]string + expected repo.NewRepositoryOptions + }{ + { + name: "with valid non-default hash algo from env", + envVars: map[string]string{ + "KOPIA_HASHING_ALGORITHM": "HMAC-SHA3-224", + }, + flags: map[string]string{}, + expected: repo.NewRepositoryOptions{ + BlockFormat: format.ContentFormat{ + Hash: "HMAC-SHA3-224", + Encryption: encryption.DefaultAlgorithm, + }, + ObjectFormat: format.ObjectFormat{ + Splitter: splitter.DefaultAlgorithm, + }, + }, + }, + { + name: "with valid non-default encryption algo from env", + envVars: map[string]string{ + "KOPIA_HASHING_ALGORITHM": "", + "KOPIA_SPLITTER_ALGORITHM": "", + "KOPIA_ENCRYPTION_ALGORITHM": "CHACHA20-POLY1305-HMAC-SHA256", + }, + flags: map[string]string{}, + expected: repo.NewRepositoryOptions{ + BlockFormat: format.ContentFormat{ + Hash: hashing.DefaultAlgorithm, + Encryption: "CHACHA20-POLY1305-HMAC-SHA256", + }, + ObjectFormat: format.ObjectFormat{ + Splitter: splitter.DefaultAlgorithm, + }, + }, + }, + { + name: "with valid non-default splitter algo from env", + envVars: map[string]string{"KOPIA_SPLITTER_ALGORITHM": "FIXED-512K"}, + flags: map[string]string{}, + expected: repo.NewRepositoryOptions{ + BlockFormat: format.ContentFormat{ + Hash: hashing.DefaultAlgorithm, + Encryption: encryption.DefaultAlgorithm, + }, + ObjectFormat: format.ObjectFormat{ + Splitter: "FIXED-512K", + }, + }, + }, + { + name: "with valid non-default splitter and hashing algo from env, invalid encryption from env", + envVars: map[string]string{"KOPIA_SPLITTER_ALGORITHM": "FIXED-512K", "KOPIA_HASHING_ALGORITHM": "HMAC-SHA3-224", "KOPIA_ENCRYPTION_ALGORITHM": "NON-EXISTING-SHA256"}, + flags: map[string]string{}, + expected: repo.NewRepositoryOptions{ + BlockFormat: format.ContentFormat{ + Hash: "HMAC-SHA3-224", + Encryption: encryption.DefaultAlgorithm, + }, + ObjectFormat: format.ObjectFormat{ + Splitter: "FIXED-512K", + }, + }, + }, + { + name: "with unsupported hash algo in env, fallback to default", + envVars: map[string]string{"KOPIA_HASHING_ALGORITHM": "unsupported-hash"}, + flags: map[string]string{}, + expected: repo.NewRepositoryOptions{ + BlockFormat: format.ContentFormat{ + Hash: hashing.DefaultAlgorithm, + Encryption: encryption.DefaultAlgorithm, + }, + ObjectFormat: format.ObjectFormat{ + Splitter: splitter.DefaultAlgorithm, + }, + }, + }, + { + name: "hash in StoreOptionGenHashAlgo and env, env wins", + envVars: map[string]string{"KOPIA_HASHING_ALGORITHM": "HMAC-SHA3-224"}, + flags: map[string]string{ + udmrepo.StoreOptionGenHashAlgo: "HMAC-SHA3-256", + }, + expected: repo.NewRepositoryOptions{ + BlockFormat: format.ContentFormat{ + Hash: "HMAC-SHA3-224", + Encryption: encryption.DefaultAlgorithm, + }, + ObjectFormat: format.ObjectFormat{ + Splitter: splitter.DefaultAlgorithm, + }, + }, + }, + { + name: "hash in StoreOptionGenHashAlgo and invalid in env, StoreOptionGenHashAlgo takes precedence", + envVars: map[string]string{"KOPIA_HASHING_ALGORITHM": "INVALID"}, + flags: map[string]string{ + udmrepo.StoreOptionGenHashAlgo: "HMAC-SHA3-256", + }, + expected: repo.NewRepositoryOptions{ + BlockFormat: format.ContentFormat{ + Hash: "HMAC-SHA3-256", + Encryption: encryption.DefaultAlgorithm, + }, + ObjectFormat: format.ObjectFormat{ + Splitter: splitter.DefaultAlgorithm, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + for key, value := range tc.envVars { + t.Setenv(key, value) + } + ret := SetupNewRepositoryOptions(context.Background(), tc.flags) + assert.Equal(t, tc.expected, ret) + }) + } +} From 1f2255906d23c4f9f83d2676d827798ef833a5de Mon Sep 17 00:00:00 2001 From: Michal Pryc Date: Wed, 4 Sep 2024 09:35:32 +0200 Subject: [PATCH 77/90] Downstream only: Rework of Makefile and incusion of lint The rework of Makefile to make it more readable and inclusion of lint as a target as well extract golangci-lint version from the upstream Dockerfile, so we test in PROW or locally on the same version as upstream. Signed-off-by: Michal Pryc --- Makefile.prow | 132 +++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 67 deletions(-) diff --git a/Makefile.prow b/Makefile.prow index a658fe2981..1b00872675 100644 --- a/Makefile.prow +++ b/Makefile.prow @@ -1,92 +1,90 @@ -# warning: verify this inside a container with following: -# docker run -it --rm -v `pwd`:`pwd` -w `pwd` golang:1.18 bash -c "make -f Makefile.prow ci" -# -# otherwise unintended system changes may include, replacing your currently installed kubectl, binaries in GOBIN, files in GOPATH/src -# -# If formatting needs updating you can run +# Warning: Verify this inside a container with the following command: +# podman run -it --rm -v `pwd`:`pwd`:Z -w `pwd` quay.io/konveyor/builder:ubi9-v1.22.2 bash -c "make -f Makefile.prow ci" +# podman run -it --rm -v `pwd`:`pwd`:Z -w `pwd` quay.io/konveyor/builder:ubi9-v1.22.2 bash -c "make -f Makefile.prow lint" +# +# Otherwise, unintended system changes may occur, including replacing your +# currently installed binaries in GOBIN, files in GOPATH/src +# +# To update formatting, run: # GOFLAGS=-mod=mod make update -GOFLAGS=-mod=mod -CONGEN_VERSION=0.14.0 -CODEGEN_VERSION=0.22.2 -PROWBIN=/tmp/prowbin -# Name of this Makefile -MAKEFILE=Makefile.prow -# emulate as close as possible upstream ci target +# Configuration Variables +GOFLAGS := -mod=mod +CONGEN_VERSION := 0.14.0 +CODEGEN_VERSION := 0.22.2 +PROWBIN := /tmp/prowbin + +# GOPATH Setup +GOPATH := $(shell go env GOPATH) +GOBIN := $(GOPATH)/bin +GOSRC := $(GOPATH)/src + + # upstream ci target: verify-modules verify all test -# we only need to modify verify, test, all to avoid docker usage +# we need to modify verify, test, all to avoid usage of docker CLI .PHONY: ci -ci: - @echo "go version is: $(shell go version)" - GOFLAGS=$(GOFLAGS) make verify-modules - make -f $(MAKEFILE) verify all test +ci: verify-modules verify all test + +.PHONY: verify-modules +verify-modules: + @echo "verify-modules target: calls upstream Makefile verify-modules" + PATH=$(PROWBIN):$(PATH) GOFLAGS=$(GOFLAGS) make verify-modules .PHONY: verify -verify: goimports controller-gen kubectl #code-generator -# add PROWBIN to PATH - @echo Verifying with PATH=$(PROWBIN):$(PATH) -# Per -# https://github.com/vmware-tanzu/velero/blob/dd660882d0db96d430547f39dc3694d1c1bc19f3/Makefile#L160-L163 -# code-generator tools require project to be in heirarchy such as github.com/vmware-tanzu/velero -# so we need to copy the project to GOPATH/src/github.com/vmware-tanzu/velero -# and then run verify from there -# otherwise the code-generator tools will fail - mkdir -p $(GOSRC)/github.com/vmware-tanzu/ - cp -r . $(GOSRC)/github.com/vmware-tanzu/velero - cd $(GOSRC)/github.com/vmware-tanzu/velero && \ +verify: setup-env goimports controller-gen + @echo "Running verification scripts" PATH=$(PROWBIN):$(PATH) GOFLAGS=$(GOFLAGS) hack/verify-all.sh +# Build targets .PHONY: all all: - GOFLAGS=$(GOFLAGS) make local - GOFLAGS=$(GOFLAGS) BIN=velero-restore-helper make local + @echo "Running all targets" + PATH=$(PROWBIN):$(PATH) GOFLAGS=$(GOFLAGS) make local + PATH=$(PROWBIN):$(PATH) GOFLAGS=$(GOFLAGS) BIN=velero-restore-helper make local .PHONY: test -# our test is modified to avoid docker usage -test: envtest - @echo Testing with KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) +test: setup-env + # Kubebuilder Setup + @echo "Setting up Kubebuilder assets..." + $(eval KUBEBUILDER_ASSETS := $(shell $(GOBIN)/setup-envtest use -p path | sed 's/ /\\ /g')) + @echo "KUBEBUILDER_ASSETS is set to $(KUBEBUILDER_ASSETS)" + @echo "Running tests..." KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) GOFLAGS=$(GOFLAGS) hack/test.sh -GOPATH:=$(shell go env GOPATH) -GOBIN:=$(GOPATH)/bin -GOSRC:=$(GOPATH)/src -# if KUBEBUILDER_ASSETS contains space, escape it -KUBEBUILDER_ASSETS=$(shell echo $(shell $(GOBIN)/setup-envtest use -p path) | sed 's/ /\\ /g') -.PHONY: envtest -envtest: $(GOBIN)/setup-envtest +.PHONY: lint +lint: golangci-lint + @echo "Running lint" + PATH=$(PROWBIN):$(PATH) GOFLAGS=$(GOFLAGS) hack/lint.sh + +# Setup the environment for testing +.PHONY: setup-env +setup-env: setup-envtest + @echo "Setting up envtest tools" $(GOBIN)/setup-envtest use -p path -$(GOBIN)/setup-envtest: - @echo Installing envtest tools - GOFLAGS= go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest - @echo Installed envtest tools +# Installations of dependencies +.PHONY: goimports controller-gen golangci-lint kubectl setup-envtest -.PHONY: goimports -goimports: $(GOBIN)/goimports +goimports: $(GOBIN)/goimports +controller-gen: $(GOBIN)/controller-gen +golangci-lint: $(GOBIN)/golangci-lint +kubectl: $(PROWBIN)/kubectl +setup-envtest: $(GOBIN)/setup-envtest $(GOBIN)/goimports: - @echo Installing goimports + @echo "Installing goimports" go install golang.org/x/tools/cmd/goimports@latest - @echo Installed goimports - -.PHONY: code-generator -code-generator: $(GOSRC)/k8s.io/code-generator - -$(GOSRC)/k8s.io/code-generator: - mkdir -p $(GOSRC)/k8s.io/ - cd $(GOSRC)/k8s.io/ && git clone -b v$(CODEGEN_VERSION) https://github.com/kubernetes/code-generator - -.PHONY: controller-gen -controller-gen: $(GOBIN)/controller-gen $(GOBIN)/controller-gen: + @echo "Installing controller-gen" go install sigs.k8s.io/controller-tools/cmd/controller-gen@v$(CONGEN_VERSION) -.PHONY: kubectl -kubectl: $(PROWBIN)/kubectl +$(GOBIN)/golangci-lint: + @echo "Extracting golangci-lint version from hack/build-image/Dockerfile" + GOLANGCI_VERSION=$$(grep -oP 'golangci-lint/master/install.sh.*\Kv[0-9]+\.[0-9]+\.[0-9]+' hack/build-image/Dockerfile); \ + echo "Installing golangci-lint version: $$GOLANGCI_VERSION"; \ + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOBIN) $$GOLANGCI_VERSION -$(PROWBIN)/kubectl: - curl -LO "https://dl.k8s.io/release/$(shell curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" - chmod +x ./kubectl - mkdir -p $(PROWBIN) - mv ./kubectl $(PROWBIN) +$(GOBIN)/setup-envtest: + @echo "Installing envtest tools" + go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest From 8c22ea6ff526bfdf51d09c131a77d4cc36609f7a Mon Sep 17 00:00:00 2001 From: Michal Pryc Date: Thu, 5 Sep 2024 16:15:42 +0200 Subject: [PATCH 78/90] Downstream only - fix lint error in downtream change (#343) This fixes the PR #334 where one additional line was in the code. This was not exposed previously as we did not had downstream CI Lint jobs. Signed-off-by: Michal Pryc --- .../udmrepo/kopialib/backend/common_kopia_algorithms_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go b/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go index 969ea111d1..8c11961633 100644 --- a/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go +++ b/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go @@ -31,7 +31,6 @@ import ( ) func TestSetupNewRepoAlgorithms(t *testing.T) { - testCases := []struct { name string envVars map[string]string From 0b3787e686083eda84e93b3452f2c4311a8ac1ad Mon Sep 17 00:00:00 2001 From: Wesley Hayutin <138787+weshayutin@users.noreply.github.com> Date: Thu, 17 Oct 2024 05:39:22 -0600 Subject: [PATCH 79/90] run oadp-operator e2e test from the velero repo (#353) * run oadp-operator e2e test from the velero repo execute openshift/oadp-operator e2e tests directly against the velero repo locally or via prow ci Signed-off-by: Wesley Hayutin * update variable names, add a cleanup * make sure env variable overrides default velero_image Signed-off-by: Wesley Hayutin * add options to build, push, and only test Signed-off-by: Wesley Hayutin * add arch to name Signed-off-by: Wesley Hayutin * remove duplicated clean/rm operator checkout * simplify by dropping export var and use a oneliner Co-authored-by: Tiger Kaovilai * drop export and use oneliner Co-authored-by: Tiger Kaovilai * just in case, allow oadp to be deployed from makefile Signed-off-by: Wesley Hayutin * Update Makefile.prow Co-authored-by: Tiger Kaovilai --------- Signed-off-by: Wesley Hayutin Co-authored-by: Tiger Kaovilai --- Makefile.prow | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Makefile.prow b/Makefile.prow index 1b00872675..88aa9d5715 100644 --- a/Makefile.prow +++ b/Makefile.prow @@ -19,6 +19,17 @@ GOPATH := $(shell go env GOPATH) GOBIN := $(GOPATH)/bin GOSRC := $(GOPATH)/src +# Prow settings for e2e tests +OADP_E2E_DIR := /tmp/oadp-operator +OADP_E2E_BRANCH := master +VELERO_IMAGE ?= quay.io/konveyor/velero:latest +CLUSTER_ARCH ?= $(shell oc get nodes -o jsonpath='{.items[0].status.nodeInfo.architecture}') +CLUSTER_OS ?= $(shell oc get node -o jsonpath='{.items[0].status.nodeInfo.operatingSystem}') +DOCKER_BUILD_ARGS = --platform=$(CLUSTER_OS)/$(CLUSTER_ARCH) +GINKGO_ARGS ?= "" # by default (empty) run all tests, otherwise specify a test to run +LOCAL_BUILT_IMAGE=ttl.sh/velero-$(CLUSTER_ARCH)-$(shell git rev-parse --short HEAD):1h + + # upstream ci target: verify-modules verify all test # we need to modify verify, test, all to avoid usage of docker CLI @@ -88,3 +99,50 @@ $(GOBIN)/golangci-lint: $(GOBIN)/setup-envtest: @echo "Installing envtest tools" go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + +.PHONY: clone-oadp-operator +clone-oadp-operator: clean-oadp-operator + @echo "Cloning oadp-operator" + git clone --depth 1 --single-branch --branch $(OADP_E2E_BRANCH) https://github.com/openshift/oadp-operator.git $(OADP_E2E_DIR) + +.PHONY: clean-oadp-operator +clean-oadp-operator: + @echo "Cleaning oadp-operator" + rm -rf $(OADP_E2E_DIR) + +# build the Dockerfile.ubi +.PHONY: build +build: + @echo "Building Dockerfile.ubi with tag: $(LOCAL_BUILT_IMAGE)" + docker build -t $(LOCAL_BUILT_IMAGE) -f Dockerfile.ubi . $(DOCKER_BUILD_ARGS) + +# push the image to ttl.sh +.PHONY: push +push: + @echo "Pushing image: $(LOCAL_BUILT_IMAGE)" + docker push $(LOCAL_BUILT_IMAGE) + +# deploy oadp-operator, potentially used by prow jobs +.PHONY: deploy-olm +deploy-olm: clone-oadp-operator + @echo "Deploying oadp-operator" + pushd $(OADP_E2E_DIR) && make deploy-olm && popd + +# test-e2e is to be used by prow. +.PHONY: test-e2e +test-e2e: clone-oadp-operator + @echo "Running oadp-operator e2e tests" + pushd $(OADP_E2E_DIR) && VELERO_IMAGE=$(VELERO_IMAGE) make test-e2e && popd + +# build and test locally +.PHONY: local-build-test-e2e +local-build-test-e2e: build push clone-oadp-operator + @echo "Building Velero and Running oadp-operator e2e tests locally" + pushd $(OADP_E2E_DIR) && VELERO_IMAGE=$(LOCAL_BUILT_IMAGE) OPENSHIFT_CI=false make test-e2e && popd + +# to run just one test, export GINKGO_ARGS="--ginkgo.focus='MySQL application CSI'" +# do NOT build, test locally +.PHONY: local-test-e2e +local-test-e2e: clone-oadp-operator + @echo "Running oadp-operator e2e tests locally" + pushd $(OADP_E2E_DIR) && VELERO_IMAGE=$(LOCAL_BUILT_IMAGE) OPENSHIFT_CI=false GINKGO_ARGS=$(GINKGO_ARGS) make test-e2e && popd \ No newline at end of file From b2235e2039ddb08acfe1baebb586e8aa0593c89d Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Thu, 13 Mar 2025 09:53:47 -0500 Subject: [PATCH 80/90] DS Owners --- DOWNSTREAM_OWNERS | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 DOWNSTREAM_OWNERS diff --git a/DOWNSTREAM_OWNERS b/DOWNSTREAM_OWNERS new file mode 100644 index 0000000000..e812b19e6d --- /dev/null +++ b/DOWNSTREAM_OWNERS @@ -0,0 +1,17 @@ +approvers: + - jwmatthews + - sseago + - jmontleon + - shawn-hurley + - rayfordj + - dymurray + - shubham-pampattiwar + - kaovilai + - eemcmullan + - savitharaghunathan +reviewers: + - sseago + - shubham-pampattiwar + - kaovilai + - eemcmullan + - savitharaghunathan From 8cf74a77a7f7109ac8ea274e7aa93908e78b1f0e Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Thu, 13 Mar 2025 12:03:06 -0400 Subject: [PATCH 81/90] updated controller-gen version --- Makefile.prow | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.prow b/Makefile.prow index 88aa9d5715..dcdbae18c4 100644 --- a/Makefile.prow +++ b/Makefile.prow @@ -10,7 +10,7 @@ # Configuration Variables GOFLAGS := -mod=mod -CONGEN_VERSION := 0.14.0 +CONGEN_VERSION := 0.16.5 CODEGEN_VERSION := 0.22.2 PROWBIN := /tmp/prowbin @@ -145,4 +145,4 @@ local-build-test-e2e: build push clone-oadp-operator .PHONY: local-test-e2e local-test-e2e: clone-oadp-operator @echo "Running oadp-operator e2e tests locally" - pushd $(OADP_E2E_DIR) && VELERO_IMAGE=$(LOCAL_BUILT_IMAGE) OPENSHIFT_CI=false GINKGO_ARGS=$(GINKGO_ARGS) make test-e2e && popd \ No newline at end of file + pushd $(OADP_E2E_DIR) && VELERO_IMAGE=$(LOCAL_BUILT_IMAGE) OPENSHIFT_CI=false GINKGO_ARGS=$(GINKGO_ARGS) make test-e2e && popd From 99e85cddc21efb8b6451b711bc151ccdfba41ddc Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Tue, 1 Apr 2025 15:11:50 -0400 Subject: [PATCH 82/90] Include velero-restore-helper binary in velero image (#374) --- Dockerfile.ubi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile.ubi b/Dockerfile.ubi index 4b2f524849..45f8eeae1f 100644 --- a/Dockerfile.ubi +++ b/Dockerfile.ubi @@ -10,6 +10,7 @@ COPY . /go/src/github.com/vmware-tanzu/velero WORKDIR /go/src/github.com/vmware-tanzu/velero RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static" -X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=konveyor-dev' -o /go/src/velero github.com/vmware-tanzu/velero/cmd/velero +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static"' -o /go/src/velero-restore-helper github.com/vmware-tanzu/velero/cmd/velero-restore-helper RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod=mod -ldflags '-extldflags "-static"' -o /go/src/velero-helper github.com/vmware-tanzu/velero/cmd/velero-helper FROM --platform=$BUILDPLATFORM quay.io/konveyor/builder:ubi9-latest AS restic-builder @@ -30,6 +31,7 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -mod= FROM registry.access.redhat.com/ubi9-minimal RUN microdnf -y update && microdnf -y install nmap-ncat && microdnf -y reinstall tzdata && microdnf clean all COPY --from=builder /go/src/velero velero +COPY --from=builder /go/src/velero-restore-helper velero-restore-helper COPY --from=builder /go/src/velero-helper velero-helper COPY --from=restic-builder /opt/app-root/src/restic /usr/bin/restic From b3c86e8d3543fb28061c14a262d0b8c3dbda9df8 Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Tue, 19 Aug 2025 17:30:17 -0400 Subject: [PATCH 83/90] Fix restic checkout in Dockerfile.ubi to get default branch (#436) Signed-off-by: Scott Seago --- Dockerfile.ubi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.ubi b/Dockerfile.ubi index 45f8eeae1f..fadb930fb3 100644 --- a/Dockerfile.ubi +++ b/Dockerfile.ubi @@ -22,7 +22,7 @@ ENV GOPATH=$APP_ROOT RUN mkdir -p $APP_ROOT/src/github.com/restic \ && cd $APP_ROOT/src/github.com/restic \ - && git clone https://github.com/konveyor/restic -b konveyor-dev + && git clone https://github.com/openshift/restic WORKDIR $APP_ROOT/src/github.com/restic/restic From 7ff6ce390eb26d9505a2bc0944e51c0d2d717fc5 Mon Sep 17 00:00:00 2001 From: oadp-team-rebase-bot Date: Fri, 12 Sep 2025 12:55:57 +0200 Subject: [PATCH 84/90] UPSTREAM: : Updating go modules --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 5bcbc11ef0..8ec7367573 100644 --- a/go.mod +++ b/go.mod @@ -197,4 +197,4 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect ) -replace github.com/kopia/kopia => github.com/project-velero/kopia v0.0.0-20251230033609-d946b1e75197 +replace github.com/kopia/kopia => github.com/migtools/kopia v0.0.0-20250814081930-848859b500ac diff --git a/go.sum b/go.sum index bbdb665677..d3797911d7 100644 --- a/go.sum +++ b/go.sum @@ -535,8 +535,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/minio/crc64nvme v1.1.0 h1:e/tAguZ+4cw32D+IO/8GSf5UVr9y+3eJcxZI2WOO/7Q= -github.com/minio/crc64nvme v1.1.0/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= +github.com/migtools/kopia v0.0.0-20250814081930-848859b500ac h1:vKTxg91LDteSvyGRA67Yd+n9nj9mknFX7KgDSs+eZrk= +github.com/migtools/kopia v0.0.0-20250814081930-848859b500ac/go.mod h1:qlSnPHrsV8eEeU4l4zqEw8mJ5CUeXr7PDiJNI4r4Bus= +github.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY= +github.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v7 v7.0.97 h1:lqhREPyfgHTB/ciX8k2r8k0D93WaFqxbJX36UZq5occ= @@ -616,8 +618,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/project-velero/kopia v0.0.0-20251230033609-d946b1e75197 h1:iGkfuELGvFCqW+zcrhf2GsOwNH1nWYBsC69IOc57KJk= -github.com/project-velero/kopia v0.0.0-20251230033609-d946b1e75197/go.mod h1:RL4KehCNKEIDNltN7oruSa3ldwBNVPmQbwmN3Schbjc= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= From 41d8a68a737bf0decc578b2ecae7dfac0b41c274 Mon Sep 17 00:00:00 2001 From: oadp-team-rebase-bot Date: Fri, 12 Sep 2025 12:56:03 +0200 Subject: [PATCH 85/90] UPSTREAM: : update restic @ 8c4c3fbfe (branch oadp-dev) --- .gitmodules | 4 ++++ restic | 1 + 2 files changed, 5 insertions(+) create mode 100644 .gitmodules create mode 160000 restic diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..421c20dea9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "restic"] + path = restic + url = https://github.com/openshift/restic + branch = oadp-dev diff --git a/restic b/restic new file mode 160000 index 0000000000..8c4c3fbfe0 --- /dev/null +++ b/restic @@ -0,0 +1 @@ +Subproject commit 8c4c3fbfe03e831fe1e81bb8ec486aae94bfeabb From a1b5ec70b8a1e916399d6fb683475fe1009ee567 Mon Sep 17 00:00:00 2001 From: oadp-team-rebase-bot Date: Fri, 12 Sep 2025 13:01:11 +0200 Subject: [PATCH 86/90] UPSTREAM: Use context from test for the kopia algorithms Fixes linting error. Signed-off-by: oadp-team-rebase-bot --- .../udmrepo/kopialib/backend/common_kopia_algorithms_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go b/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go index 8c11961633..7dddf0e43f 100644 --- a/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go +++ b/pkg/repository/udmrepo/kopialib/backend/common_kopia_algorithms_test.go @@ -17,7 +17,6 @@ limitations under the License. package backend import ( - "context" "testing" "github.com/kopia/kopia/repo" @@ -152,7 +151,7 @@ func TestSetupNewRepoAlgorithms(t *testing.T) { for key, value := range tc.envVars { t.Setenv(key, value) } - ret := SetupNewRepositoryOptions(context.Background(), tc.flags) + ret := SetupNewRepositoryOptions(t.Context(), tc.flags) assert.Equal(t, tc.expected, ret) }) } From f872f0f0ecbcdbfff86244d11483c60f6f24b7b0 Mon Sep 17 00:00:00 2001 From: oadp-team-rebase-bot Date: Thu, 12 Feb 2026 02:12:14 +0000 Subject: [PATCH 87/90] UPSTREAM: : Updating go modules --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 8ec7367573..47f2ef93e3 100644 --- a/go.mod +++ b/go.mod @@ -197,4 +197,4 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect ) -replace github.com/kopia/kopia => github.com/migtools/kopia v0.0.0-20250814081930-848859b500ac +replace github.com/kopia/kopia => github.com/migtools/kopia v0.0.0-20260211121325-b68c22afd36d diff --git a/go.sum b/go.sum index d3797911d7..b1a708dfc3 100644 --- a/go.sum +++ b/go.sum @@ -535,10 +535,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/migtools/kopia v0.0.0-20250814081930-848859b500ac h1:vKTxg91LDteSvyGRA67Yd+n9nj9mknFX7KgDSs+eZrk= -github.com/migtools/kopia v0.0.0-20250814081930-848859b500ac/go.mod h1:qlSnPHrsV8eEeU4l4zqEw8mJ5CUeXr7PDiJNI4r4Bus= -github.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY= -github.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= +github.com/migtools/kopia v0.0.0-20260211121325-b68c22afd36d h1:kkllNsWVL/W60AYZDV8V0yLMBQtZJZNTmAeiIXPRCYs= +github.com/migtools/kopia v0.0.0-20260211121325-b68c22afd36d/go.mod h1:RL4KehCNKEIDNltN7oruSa3ldwBNVPmQbwmN3Schbjc= +github.com/minio/crc64nvme v1.1.0 h1:e/tAguZ+4cw32D+IO/8GSf5UVr9y+3eJcxZI2WOO/7Q= +github.com/minio/crc64nvme v1.1.0/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v7 v7.0.97 h1:lqhREPyfgHTB/ciX8k2r8k0D93WaFqxbJX36UZq5occ= From 6158c201e0347fa71449b41f4c69721621f80ca9 Mon Sep 17 00:00:00 2001 From: Michal Pryc Date: Thu, 12 Feb 2026 11:55:26 +0100 Subject: [PATCH 88/90] UPSTREAM: : Fix golangci-lint configuration for v2.x Fix golangci-lint version extraction and disable concat-loop check. Signed-off-by: Michal Pryc --- .golangci.yaml | 1 + Makefile.prow | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.golangci.yaml b/.golangci.yaml index 7ab8bdeaf4..505f1e01aa 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -196,6 +196,7 @@ linters: sprintf1: false errorf: false int-conversion: true + concat-loop: false revive: rules: diff --git a/Makefile.prow b/Makefile.prow index dcdbae18c4..4697b22db7 100644 --- a/Makefile.prow +++ b/Makefile.prow @@ -92,7 +92,7 @@ $(GOBIN)/controller-gen: $(GOBIN)/golangci-lint: @echo "Extracting golangci-lint version from hack/build-image/Dockerfile" - GOLANGCI_VERSION=$$(grep -oP 'golangci-lint/master/install.sh.*\Kv[0-9]+\.[0-9]+\.[0-9]+' hack/build-image/Dockerfile); \ + GOLANGCI_VERSION=$$(grep -oP 'golangci-lint/(master|HEAD)/install.sh.*\Kv[0-9]+\.[0-9]+\.[0-9]+' hack/build-image/Dockerfile); \ echo "Installing golangci-lint version: $$GOLANGCI_VERSION"; \ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOBIN) $$GOLANGCI_VERSION From 484c1724f03bd611f8729ee3f0173f3c1ed643dc Mon Sep 17 00:00:00 2001 From: Wesley Hayutin Date: Mon, 23 Mar 2026 10:07:44 -0600 Subject: [PATCH 89/90] add konfluxdockerfile for future --- konflux.Dockerfile | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 konflux.Dockerfile diff --git a/konflux.Dockerfile b/konflux.Dockerfile new file mode 100644 index 0000000000..600c9834d9 --- /dev/null +++ b/konflux.Dockerfile @@ -0,0 +1,57 @@ +FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_9_golang_1.25 AS builder +COPY . /workspace + +####################################################################### +####################################################################### +# # +# W W AA RRRR N N III N N GGG # +# W W A A R R NN N I NN N G # +# W W W AAAA RRRR N N N I N N N G GG # +# W W W A A R R N NN I N NN G G # +# W W A A R RR N N III N N GGG # +# # +# Any changes to the `velero` and `restic` sections below must also # +# be reconciled in oadp-mustgather/Dockerfile.in for consistency. # +####################################################################### +# BEGIN # +####################################################################### + +# velero +WORKDIR /workspace/ +ENV GOEXPERIMENT strictfipsruntime +RUN CGO_ENABLED=1 GOOS=linux go build -a -mod=readonly -ldflags '-X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=v1.16.1-OADP' -tags strictfipsruntime -o ./bin/velero ./cmd/velero +RUN CGO_ENABLED=1 GOOS=linux go build -a -mod=readonly -tags strictfipsruntime -o ./bin/velero-restore-helper ./cmd/velero-restore-helper +RUN CGO_ENABLED=1 GOOS=linux go build -a -mod=readonly -tags strictfipsruntime -o ./bin/velero-helper ./cmd/velero-helper + +# restic +WORKDIR /workspace/restic/ +ENV GOEXPERIMENT strictfipsruntime +RUN CGO_ENABLED=1 GOOS=linux go build -a -mod=readonly -tags strictfipsruntime -o ./bin/restic ./cmd/restic +USER 65534:65534 + +####################################################################### +# END # +####################################################################### + +FROM registry.redhat.io/ubi9/ubi:latest +RUN dnf -y reinstall tzdata && dnf clean all +RUN dnf -y install less nmap-ncat openssl && dnf clean all +COPY --from=builder /workspace/bin/velero velero +COPY --from=builder /workspace/bin/velero-restore-helper velero-restore-helper +COPY --from=builder /workspace/bin/velero-helper velero-helper +COPY --from=builder /workspace/restic/bin/restic /usr/bin/restic +COPY --from=builder /workspace/LICENSE /licenses/ + +RUN mkdir -p /home/velero +RUN chmod -R 777 /home/velero + +USER 65534:65534 +ENV HOME=/home/velero + +ENTRYPOINT ["/velero"] + +LABEL description="OpenShift API for Data Protection - Velero" +LABEL io.k8s.description="OpenShift API for Data Protection - Velero" +LABEL io.k8s.display-name="OADP Velero" +LABEL io.openshift.tags="migration" +LABEL summary="OpenShift API for Data Protection - Velero" From 3aba53fdc87e9cbd310d12263e61e7945704dcf5 Mon Sep 17 00:00:00 2001 From: oadp-team-rebase-bot Date: Wed, 8 Apr 2026 17:17:30 -0400 Subject: [PATCH 90/90] UPSTREAM: : Updating go modules --- go.mod | 34 ++++++++++++++--------------- go.sum | 68 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/go.mod b/go.mod index 47f2ef93e3..058ce94f1e 100644 --- a/go.mod +++ b/go.mod @@ -41,13 +41,13 @@ require ( github.com/stretchr/testify v1.11.1 github.com/vmware-tanzu/crash-diagnostics v0.3.7 go.uber.org/zap v1.27.1 - golang.org/x/mod v0.30.0 - golang.org/x/oauth2 v0.34.0 + golang.org/x/mod v0.33.0 + golang.org/x/oauth2 v0.35.0 golang.org/x/sys v0.42.0 - golang.org/x/text v0.32.0 + golang.org/x/text v0.35.0 google.golang.org/api v0.256.0 google.golang.org/grpc v1.79.3 - google.golang.org/protobuf v1.36.10 + google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.33.3 k8s.io/apiextensions-apiserver v0.33.3 @@ -171,25 +171,25 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.43.0 // indirect - go.opentelemetry.io/otel/metric v1.43.0 // indirect - go.opentelemetry.io/otel/sdk v1.43.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect - go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect - golang.org/x/crypto v0.46.0 // indirect + golang.org/x/crypto v0.49.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/term v0.38.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/term v0.41.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.42.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect @@ -197,4 +197,4 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect ) -replace github.com/kopia/kopia => github.com/migtools/kopia v0.0.0-20260211121325-b68c22afd36d +replace github.com/kopia/kopia => github.com/migtools/kopia v0.0.0-20260402180147-13b9de8884d2 diff --git a/go.sum b/go.sum index b1a708dfc3..f5b5de932a 100644 --- a/go.sum +++ b/go.sum @@ -535,8 +535,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/migtools/kopia v0.0.0-20260211121325-b68c22afd36d h1:kkllNsWVL/W60AYZDV8V0yLMBQtZJZNTmAeiIXPRCYs= -github.com/migtools/kopia v0.0.0-20260211121325-b68c22afd36d/go.mod h1:RL4KehCNKEIDNltN7oruSa3ldwBNVPmQbwmN3Schbjc= +github.com/migtools/kopia v0.0.0-20260402180147-13b9de8884d2 h1:c8NGn3mVMSdbRkvZQMesn4/CJIab5/SR6E6gB2FMwao= +github.com/migtools/kopia v0.0.0-20260402180147-13b9de8884d2/go.mod h1:HsrGo+L4fKfBaFatWz91l9L1eOaq4WmWZKwk9No4bhQ= github.com/minio/crc64nvme v1.1.0 h1:e/tAguZ+4cw32D+IO/8GSf5UVr9y+3eJcxZI2WOO/7Q= github.com/minio/crc64nvme v1.1.0/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= @@ -750,18 +750,18 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= -go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= -go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= -go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= -go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= -go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= -go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= -go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= -go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20201006213952-227f4aabceb5/go.mod h1:f0znQkUKRrkk36XxWbGjMqQM8wGv/xHBVE2qc3B5oFU= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= @@ -792,8 +792,8 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -831,8 +831,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -878,8 +878,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -893,8 +893,8 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= -golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -906,8 +906,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -978,8 +978,8 @@ golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXR golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= -golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -989,8 +989,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= -golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1050,8 +1050,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1137,10 +1137,10 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1177,8 +1177,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

1LtLS5*)ba|9;NwOp__|2ntGN6Z2L%*XM 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 literal 0 HcmV?d00001 diff --git a/design/block-data-mover/vgdp-restore.png b/design/block-data-mover/vgdp-restore.png new file mode 100644 index 0000000000000000000000000000000000000000..fefb40dbe417f6d61f2f78ff4bc39108e591484b GIT binary patch literal 516403 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

k1oQ~?5NI|6S|TIqi94!s7OQu3)Ol?miH)yjRx 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 literal 0 HcmV?d00001 diff --git a/design/block-data-mover/restore-architecture.png b/design/block-data-mover/restore-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..c0b2590283ebc9ec91dd81a0ef9d6247feab3eaa GIT binary patch literal 487646 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%0AI21=~SDEX>N%qez z7X>L8Bh{zLsQuN}FRaTe-UXbQ%R6o>%tgk$6Z#S2rr$F-S z*HVbQTGrA4ek^U@uH00M1ca~UYZi<%rxV8I3Li(a+WE#Y?5k=usp8Dq{tWY@Y)&pq z2xCT53Xfv>aR|sLQ?s;H7wnYen^AX_7MetH-|$O_4ACr;A*dlz*{6p|3$&ymtDc_(<1Yl*s)E zTr~d@{Ykaw4Kl>xJia%+XpWwVc{f1%ew;#Lcae+C?|t7gWmE7T(F%Y5SGCjl0kXI) zTh09*HH$X>4=dy(z>* zB&y0Lm^_%p5;6whUrY9IR<#(-pnZ`7U=^})N_H6;3KD0vU{9qt_7$BRS10J`MDV_{ zX1N93^Nr(8^w*6JXUZOuj;1pYqR#%ZYW@dklpYI^p*a%D6UGQr-r4cL4ml-%W3MP9 zx#hq#|8p%baywoqQ(eNlfO83QMrR9Mf3SDwZBxu18s;)fnf9YU#p80WlM-|~tbOOh zmYKNT_y8$dazvvgg;!m8qA+>{DIjWzmd^Jw-@LU`oN9iambpH4U^{8^S_;s8?g2R| zsc-aILaNk}I=hiq{1pw$tbrfS-t!;B_rD$_=mUh*Y59zFd!9Fne248lBQ z?gVmK7E5?}^_=;cc zf`9$=Sw`1b9I@MMh z6Iou031vcqJ<8tip0BMji6(D?%ndINA!+Gvr?cI`^Q_*?am?4iyO!;wT}L8FrA7GK z_ZKl(b;`uGvbMS%O56)~|U5X)+L4 z+CSh#8wd~i67BTo`dsmyki(=i<3OXb7QaV5(5W6Q~rrOqR`Yq4G8dv8RaceM# zP+&8E?Ika#`^rWyUTE{RSbZL|d$T90SXZ-7+=vHZRbkG@m{UOytj<3sG;kx$UGY|u z5$kr6MH#sxELV4%?xWn-p8cayI~+$99J>W9%qX+{{3u0I)h^TAbwv(=r$0|LZ8)mx z0-#|X9VJ~;Dn=E@H$T>?ADz9-!TCLOW!s;JZFv3TC8HhB`01Eb{5fk@#Z|-oyZJWL z8HwTu4!Hq-ivTaT=k`=xyfkC7;aP+C9AdQ`Duex``*mkq$cvwM+{O8}n$zf9gguXy z0dc;_?KQb%S;U-Rv}42m17BLBn72Mag&@O&T@d7N&1y3>0uz^41eDF8ouB!{NyQ z-XaO^?vWW@qy`S>3!{>3%C9Mj^G1>t5tt`TQAtaCflTzRgYNNj779p7_Vh z=Gw$sT$Pn7`Iac(6OB%Nl7P=omycflJi)(R>9RHs@wF_}Sr`!Qoo7nsFgkA792u%`23&$rKG|y>ZLxe~^CZq-4!42~M z9rB&g{sNm&N1eic@P(i6-*_v@e{%<+R^4Xgn%@0iYCob&tQRdP1H6Gv*4@WZSxiyH zrR-Q{vfU@jJ_ocSQgKZor3!`F*TH>Gi$F_@)n!VGRoM-x8>fp;xny^Z>Ky=0S zQ8;~63th~F2e280?jWjGeIRqfTHQ(@6a`0~Jd^{=fWT`iBAq=a9S!&eY@a6rQzrOb z+`tMey>a`uyu%HU0v?cy?j5<;B7hm`ZVfp%;vvuz07} zh1Ol5B*4*?JaWa*MxgPR8X{8NzfU!XF@5O0&#PM-9c&mic7Hylr51fs^QNds{pDM) z2Gxr%991)&GSK99?XLwM@N|-IFy2tU2S|m6ApD3kAGpo@Dtu=j&w6<~z%l4DU#Mj5 z^*plwo-EL1|Iqt8D+fiw8=zr6G)LQ*TtwZV1Rh>zfn&uDV>-N3oKe{QJ|)DUI|Pq92Fy;=_;K>4gA9kE(FulAT@a z*ut${_t?T)e{M3BZ;d3U@?w5d&v-6+(gy*Tu&s)$l(espNG@#_>QK(jO6Mf8k{6xu zBqhIItbMyWHuNw84Ss{d)427TX<_|~?g6JXs(9+WzK$ujBBipV8zU>WIMW2xdEe9h4h)gOFux zx<|GRf@PK;58uQ_sDCnO@HvQ}NL^LWocZ5>DU$>$M}Y2mUOCGo-pH|q61vPWpxspd zR>BEf{(g7U!i?6w_45MsffmVsw5(42PsuLyyy{f394=vq(E;^<(&0*(IfJY7&+!Sb z&d&D$pC;l}adG@kVpctODg9?W-Ql)bZ?VGs{Y*d_yEWpc=*?~SG2H4td@|jM{zZpf zm&~!ORa~}f@7~7lOy1ZrlzqJZ}JOaf+z<#XShrbdrC6=f(6Z#9-gkaBJCg|Lg)yelie>4-S4K89AWo*rh%cDvE znC*0GA`V>?j?R0o&d-0Jwnb*KHi7~AoSpn7*6%R?KbG#C$|w+-5v7IAAxG@~u0k6{ z#II7pV}iuIa>u1Jofi(JK zhs;ov5Ey4uUOfV+gtk2&A!W{_vkmjI(46TcM=rej?_NFpl80M7N5}Ld%g;mq2b~@g z3a-xdV{f~`bSe9U|9)WRF-#ql(GpWaENWs?|GtFIbMO;`U_8fo5>v(g@Ix^nRS}?w z{znql7f#M>kc%1}%3`qf4fZ;GhHZ|l1L6zIp-_ThO*huI@b^I!D z+K3+?vSmUP!=nSm`FFj?u=UddQx*6^+y~75%c_M1$#tURH*!i??XcfB1>CyuoZ|j- zAh~S`4P-atKzbAk(v&zs5mG50RR}Ca&a2$84?6tL-NFA|2o(|+1ym7#KpuSHg+KEJ zUjIDq!#@g3W57z6f*zIIAbDj1)Va}s-YDG|#e5n_Z?#F8Wn9);Sv1mL5dV+@4^#Gd z^DJMUZso*0paFLr2o4xF===S5n`BC2Kz;xlxTm(R=Rs2;F$A<0W&)a25nyuA1VkZB z(15;75r}AA2Kqi7*(CWR*#M|-5|pH2O-gO!0$x4i)`>pRzpwrgCw%qe=L)#tf2m~i zSKS3h%SJNyL46qsBzUh~7N9j&1@i7E05=_N?3=gy5Q$(bb^{R?vCd>9#;B;Z101|3l3w+6+aucS;#epHnx|-}&zoD5Qh8N%cm1 z0@st_PqFp(v4wQjMlfWx4H0Oae8QYwvwdtOMemI|mKZ z?iy9StsN>OJ3pOAdiMgmx$vPG4l&6yUXX@L%Bmo@C6f)0BoxRdfzEZP4k93{d~eN@ z^fxv2@Su`D47qnz-Fhw<(C`mYAMRuLgg`NJ_tEjGK>=sR*IkzD@K^PSH{wu0MxI(+ zvv>ISfHDUf49IW`TYP>TMWYS=e7If?Kf)6lT^GkSk{@+HpH;Ra|3ALo1e)sZ`vc~> zM94KHO6I62A}Pcbl1!=0LS)D+QZil=lA)B8aMS!`o)XbD7eYjtN+e{KDdW4(y{O;+ zUGKY|wOUVc@ArGo*=L`9_Wtb8r)FvV^Xpv(tD0Q!kY7hEt3d3`DeYO|{<7m}EpsVR zIlM%dFz8jJrufKyPgwO>WCxakRY2gpe;;CvMq==>I4eCX?ZpNHW~k2k>@{HG)L;KK zKqf$sVlbFf1J@qP_^zms$ac-4ivL*5-)I0dXg~Iy3AwNy&;m!0m(w5M3U1Hpm;tJy zwMP=E(T++P_!_vS9ZKue^k1-R`*MBUK+%#Mc=$HH0|}hMn~k`NQFCbUL;QPl@K!>g^8huq+AJ?g>LqsmIDhouZa?SP{`ChD zQW%io4eUIOZ&f)vj z$IM7V=Q3Pgd!aiwWB&CoHTR^ZGHjIGujlt?b$~|U*q#$)6KGEgq*`BQk}4)_=q=C> zS^>~J5}|G38$#`P8TgBE_A6>b+O|l54<%sW=>MSpev) zhRVAy>0{ZjK;HIX030~aD2ob$$rNHJ|m3*Fvj&eP0_eADHa0Romv z(BHo4U;lbGe8_p=mpRglw1(HafdKt8z^Q2jbaKsw8NdvA^3Ks;(4e+-mmqPuKS61u_#)b6#tsN1Bj*(@6i4x#aJQOQ9R#Ga?!~Rdyzu%$Yy^6b3hX;5PuwbOs3@UlN`(E-7!#G3Ft)(gNVt> z3q<_pY79$m&2Zgh8=3_vghS@Qr?`L9XMWU&i3I02U&nmPBJkaaRNTy z7dw6d&q=~{E69jg|=26xAk`pX0!nmv7bD&>e z-S&+9zFl&f)=#N0yn?a@oxne0xI4(hoD;W6BN-xvlZ>v|0r5274({1W-{JBrP{Gw~ z6MDn09uJ__CkT4$OcZ(v{XtYR27dgh@7qPYe8 zNo6u~ur=A4I3jruU$NR1yAl9BvBCZxZ{e)oe_n8;pBE7^pORIXdNH}|4ejD58U1aU znC@Q=_`Q_;`pMvc9O7n<9`hUX8C-l3+>b{G@l=Ba zYKI1h!A*ocws!~WnRcI|iw6kRv++aUbC?z;FDr)nCi{*!T4*ZO`u@zBsxQ%fS5E9j zVlrms4^=`D|HU2u=zRsMSL|kg0U1)K7VQOaxYk0%W? z+1`+(dGTy^_cs||mS#FdrKtp|g$o%M{Oy)RyH4;RmW|JEvJY(Oa;$I0tern=M-CqI zqLz7)yLb0vwrUiyTn8$PpR&!5Q9mk@aYJ%(WQLWrMAk}NC~oIOawMq$QKg;@-Od?i z*`y zL#g?P#`)eyCR>9A5m(mlTq~9jMjqz#`Gd3Twm*9Tp-GkU2JbN%zp!am{Xk$d_p=-Ft#3PB#~-;e)xg2X zJ4nLKGLEElPLcvEz(luqisjO3UTWh05qJjVM@}i{FD`#y?voQTvWjf*u1i7eaEJ1K zU97TU36|OBl&Q?W@waj5VR{?)CZyL4l%{%DzDZIAQXz7lINz%tS^-?gz888#+fBQd zoMofFI*mjvxatx(*at7+J_i6*QA0`-_x?IJOUbYXmcdRjUyGO*Ib-ZiuVvpaAX0?* z$Wp&DnTkFGJ1`m_sPSq8m&!K=#bh(bQ3kp*&y$sf+E0#{KlutwIMRs7V`_n|GtsKp()!-y7B$x^setR1+>iT5`oBk8M%kg`UsT>SMy zbInQhP0u5;&j!a|!-eN5(C|IBAy9|Vh+Hpbx?;&3ZW;w6qsy?Q584nN#fJf+U>UE1fooe|&w^t+uI6P}~b#Ral>y{N-|nA@8e(qw;i0T=Zqv zA4~#U#fX_is^4q6I?KSW2LG9yPkT0bi;eO9>Q$_~ko-FnS2fAAk0Zjfe%IUjDeejO zTE9_uI*-i9{pM!_2@MgV_q6_xkF87}51$tF2yN!~^%49(Q3`iV<7Xp2+X@u|9u9!lR3e7^G)Q_4ASxp~F+O>Gx4y02d!+p6kYQY2So z$Onmm?kmklOCsiYEpZ_;o)%Ix^fx~;AkBVzQ&M=ikWl;Jcl6HSb z6lRnM#h!Ssnn_Fj>tgIztHfPEkL#TmP3h+3?k8c{+bee0S1wTp?Vz6E%#x|S=5q@P zY8*Zn!EcbJkZSZomJyX*nmv{QMNON+8XpG;ucX12@b09l`d;2NFNT;SY(I zg`?eZ2_BFm&H}xwXxcGVAHI)glTGI{q}7MNO_bQ%%3NulgqmD<;UQ8e8D*{Y`?(m3Wf6l!xdE30Y z+@EgUZp8|Rq`6_9SF!YN%*NX=`|h`~)TMMwEA6`2WI?AsC%$jnRcdD24#_zw_?K^! zL;H3;9eQgfcHyFDhKL4R-PCt^x|Ojy6H+D9pFn4>gPTFiBIUXdyct_AczxBFL5R!N?FmtaYB{HTTz!~TG7CbGzA5W{2 zQ!wh1b*}2tJ{Otnz+}f%y&}`2aV#Gd#Dez-N@BQzc8>0FTewMk)mgmTT_A*3epDgT zzM;nIW1Um7XX-812iXOaQ{sC&nnY(N3oM9} znIn-7TkhFktCag_a+%01e5nFr$Ei3E^&6_hA8+b0pCc**YWF;N-{4nC)O!-Ivvqa` zv1Z+K+%n2=^+eOVQ`~OWK^=lz-Bs6oqM)(&G2=@qOZ{cz(kD!V*!gJ39h@e8yaMAs zD%=Hl0o~anK0l7AR?}{#;FFSmzqTaO8S2#0ofTm?;&*FtO!}m^&ZVf=20w-d%=-$n zN3o;N5Yyr(t3=0I($@ZqoG71JcZ)QA+FOxsLmbf3K7SMXKIeeeiM3on`I6C8@$usA z)5-f)exnr5vZFoA{V+T)qx62gS?B-OZf?ap8jtj!6&RG(V?1-Bs7U~*%P{-4%regv zA62c~BIlpZdWuz&wQpk2jlP{duC{uSCzODFj->13Il=P%hB*BPr&rJ&hNpiE43;O| z83Y)_K1QYfcj%b{zm~vhJLg@x)_f~J>1_-Ax(_lInBZ}094cQ@T&MW&wKFm3* zdsaQ6n^iNQHOMnszEDTpV6_Br;EJ=mJS)#bR#Gc%X5vnRMnN0t7SAO$9*+@d`Rkn| zP1{geL43PO{Jn;CV~{cJc)eN4iKAXC-R0Z!JEecvxiNfJ>Wuy&lrGi%JK;*$v&Fh; z=FeD*-;(9?+(YvyNm8)kohIo*0{0e#P$1oE;E5|2r#imvy><70r#32@U%P zJ42b?A@!e9yQqUT&p#Kp>#v+o1}|J5%97z7a;oKxDkG#R+ph&~|6e4BoJin`B~}OP zCcewPD-aisiw|!MBm8&`vY02oeFmc1Wh!cJ<$~TO(I-eFjF2aM@vL8z>t$a_A*1hC zX!da=cg*cg_B`4jFfn*T=E9TbNr@qSVg~JP?)jC6>$*#WPi>LTO;GFtniOS)BfB{B zDq{IK3q(rQrI&1|jVsKWn=Bx9ENwPO+A-EKm z?&tkAY4nm;h7_ZH-yOqEbmMb%(g$CoED#_k?iw_=71#Kc71vx6o28oFPP6PQA!Qky zrx^0-xA~Lh`gz?#SXHQGYw0^}N!7-TXa{bHhi3D!wYbUt62>T^b>QCfF1_{@5rM!H zQxNT8Bk(<=R6|{?LPu3!N1wkcoa!|Z5jhtnBb&m0MiqZ_s;uyVHO64F;qWX^(RtER z8C-+7!(OR&pQLe*znog9t{C0ToRzfPVnTKHcYCVfkU!kM{*reHNiFyKUN5 zUtbXWR*Ijk*&O&1vq0VFD{?<*x zU00ebIDysHY5Wj=(S}dcYm}AqWM7h%+tuGMk{v7i2cZ1L49abyA0)%6ID452+$t<- zXZdEis#K0j zIy0Rt$MiuPGTyHmrCNA@`Z%}-bqmHXvM z&IHmonh~)EwWoO1S2!WZi*Ib8W36fCCX#v{T&V4B8xv<{v`A<9L%*~z%aU5~XqeA8 zN6oZ0<=K}J=1aeNO#}u$R`1%lBqgYEi=Tya-r^{&)y^P6D^E^!?nL*X?XBe+Qco;g z(&azz5qo(dqKLIUFhp@AU8}!fa=EnT@{>CT*Xy<>DJ0S=G8#>s+VW?Br61xOqrP4f zdf6jk%S=7ljS_#d@e8lV?Cm)F^Ifq8(8_-9iDbuP*>9)X{Y`O`-JPO=+rlQTXUUtF*pJP;RavwBl3HKu*kOqm-u0xBCLnF(Ezm8i zR&wOye)Jih<^9M~*9Ml&^lr2HNYviMz&+43@q*UWLD#z-1j?HH$ ztYVr_^f_ignu7 zVHYUr@2i3TxTJ}5xpIs&Tr7xcGsO;JqN~_BKw-$Sa!Fd^=d@0X&KbaZqb3{$1fa!7 ztk!`lUAO)-dXt-h2(Y?dPC%Bzh}`tf!p}W5K;A0CIxy)9F_)+Di@$POcp6qN&<>l^ z`h?$7@svC~yes`>r0zw~Vc1!C>3X#)!>2ejYYrVpG}quYL~n-uy0z+2JZ%b*c~AaX zu07iPEWtRn*|-v$;Ro2Qfq~k8Gkoj6Mx18&qQbC$7bUPyn6k}m`#`Q|dECkb;&;j* za-~uEydZPb^d{Cpxf?>cI=k#sKDM6!2ya1qqC3VfSmLhH|E>#JeOxFK55}5N&hp=0EZH> z?EPorkz_YayPap(aUvDQTfFWBJ}2!6rV^J)L5tZlVn9@Z5rADiCp$FOjp{@qep|)v z!dIng`4N#Sr~nq(EN{AI#GqBAj_kCn)_yMo$1&1>YY(*7r9AFcfAP5tib)=#|8ji& zYyX<<1ylrel2D!H@v;BNX77#xF;P>Vdx(dZ{AJJq$OBT|d%lPj2@?#2EtA(CF~AIE zgs&%l^Ds=o24a++%HBm$Pw{5>ase#!1p^b8B;XPperei+NXhCx!E3ITQjfk0t6bkX ze>V|gb$>{HaxN!ApmB7W4)JEmGVAb1hj4FwQ+oiEc)%F03s~-9v){TpW%qwxXgl$D zYy@-M3C}Uw{knsDsekLUy|XSnzFOlTn-Srts3fQ(9d%6^ArBH@Q<6Ezwtw!32~`eD z@%jCgCEsk_Wg$ex8fIdB>_G_eaeed*Ue*|sCrk=0i0d={iwy#GN02vhlRnUKV6{|v zMU_+syL5pKZaUu_T^ok*Xgt3fnP09|>0$SLD((ZmbOeL)=XUyM*OKm1%C0MH>Dypp zld!4(Q)Z`Z4vO<>yiD;>u5X5%B241Zy5vgkEn3r1#51y?oxQ&ku2UECHP^Nkti!Yr zall+@rnU1Lb}~M_=^9tZ(^{|7lt}=<+)>!o|DDOPSpNjE8msWIgz~VAF_}ECztc}% z%*bP;1ApCCK0pIerQNhs&MRAw{s(Ze-7aa{#J~Z1P82KKOpmNAt&w?Q%~D_jVzv=} z?loEuC1BGuo}+h4U)yNTI#A%G1|U_!H|&Q_zm7HKTzu`SjrF;(%TthPBS%Tg|68yo zkEBr^ZId563TM+plXeg|MUltd6ID05_UesR*s92FTfjSfQOlDb(IG9b)t*l%LyUt7 z3uSv3iyYykQ-%%tk-a$v*^d1=jF5Vi(~qBR2mVeB;ea5;z;4RMTwHs?Kg0cN`}>(! z-Qds3jz$Ai&Meqm@MQz}t9D)s%mbt#dA=f>I66S`WPKlj)Zz)xj6)|GhXn}vHAyfS zXWGW~N`2$hs;iS(vdN`kvlqi~=|X3!hSjlKiu+<7E;{(L0H&%Stt5KbNfA4jlyUJr zRPaR{yw_J9WV=;KPgf@r=(_m7Uj^*x2?d&p(?P=#cHgw>0N~Xcr9^s)_|oUn$81|& z>`r-(9oQ{>oH&LpES6OH_A(ox8J79fZ>{A5R;?^%b*g24Jjv1{KN4E$SKM z<)7DI$B{kr(%N&65!+S)A;XtKMqGEJ)1&b;l~XFk4I-!3NWvm9CWvzg5;59qz8jD~ zD#Wv<{|$W2yjyiGPmrMS^kuG~=)xLW6Yt1=5JMROJ*^cVP+%a7(P-!fwuG+i3Gshd|9 zZUlj164Uej(&Wi==JSl~@xTXL0uF^Bhoj8d=?&us{{&#rGEVlp`g)(Gn+n$tmA}5y z-VZZFfl+KFP{t7HX5*{^Jq7^S$tT#UQ_eypQ%HEgfB+%jKI&uknE#!AVmd76(DiRM zMVdtY$v&_*{V!iw*7jI?D2YMzL8D?~-ZS#@G_E4ePwc0hRuLuFTmMF%!i`Q?C)ChJ zo-111Wk6!er#{Ka-J~mpTKqt9jS?p^kK5kFr_q0!Q89aIV2mOy%C6oSM*_y$h_uFb z^1l$jGrR%CfGiMXtpu$GUO;tty(k`T0KCTet=`8Oob#;hVD@amnSXUMteZI?gC^JB zf&akT0AYd~YvX2t%NyW5I~2&+=*BWEB8Wk?@Lr^Xb>>o+3=(PBpSe;mKlb?i4~7-w zt)B0rI3-8lo8mg~R|#szf7I?MN9#{vH)tt&%$zKF_J}V)RnA)`zY~x23&!$W#=!W< zuqN}DFRc%OL=bwlfunhA3UlDZm{qz#0Okg#zlZ}@{Q)w3Q<{x*%dbV>FfnDY;^qOh zAXYT%TW<%Z_yn7CCA8cppH}xD59>QK7~Q8#8!?Oi0ia(ZTlh^WwC~I+#QSOspfUDU zawJE9&E5%jAJef|z~;5aijN3A)O#@pEW*)cxAUiUr8`IxuE62T@#v6)U5pl%&R@)tGM zMge`J9mRFb{>e64wSJ;L{a-WP&F}^!TyF}8E7N_Y0TMo4#Xsk8w<;PeZoT8zI2R*a zDH-qm^PX71M$_ekEWt5VTe?h_v)fC($XAY$iiVOkKLy3GRmbut!@6jiEVs(QF2Xfw zYx(D^^;a77-^Jn$kninqQJQ!?ZTRu9Y%ZrbG@5{?wy80>K?ds)OxQBT!Bfs)b->}Y zZ*d4;_ibpNX(@Zh$6a7+H%G#n5B$5UWAH=lnW5y5#7I-7-=oByQ-W{-MXR;7msat5 zWS}7a8$Fvl|EO0smSBfp|N8*pM&H%gt7L)1DGQqg%o`K>eto3GhxDrs zN97FLHi~JcDU-~R;UjNI*n3U;ydTC}%kaFP!>Sh}N2Mo<`$QkO9ht^j|LgHiNK$5v zu_Vj@JkEY9>i_SVLz@j5Z4vcXakl51(S0<}A))VY+>k<^v*-V9&F0LetJLxs$ytHXyJKDyJnTJUQ;3X$Oe7SjD05} zV)1rlH(>1dH%=!U6$T$5y5A}Xq~x|n1v3A)hX8h4fn?Z_z^(#R%231Mr~DwfxT?UP zfNpNLVYD0vG*&f`QtHV_Xdwy2|ISZeUj&R&@PSLGl~$pF&6nd#(-lt36Fk4@YYw?| zf)nQC^PAGUl=JM5{kOk}z@zhENXT8FTMWfrkmsne2@BWYHD_Zlhe6;Ragf-WK==nT zz7Mox5GpAO=o$)b{a!Cl*7m}?rfPTtO3JX)e_^C+_YjgRqo$#&00#C?Hp_5FtwJY) zMDf(gmNx;*zmu&&vE}7`gN%1bn#S2feHsaPXOS?Bp0_*CFCu{@z_VHVPQSF!E~gOQ zXCgorq*(7I0qSw=sqYHB&y(unC67|tEfo$g(^^NGk)Tf{DB$q|*zLkFP$mv8Er4c` zWD>Lxo#f7Y(|67V49dGdTc`#Ma2{EBh95^zT(Flp@9!-wMhFE4KaC1e|4N!R zvAH`aTH?q6}rA*Sn?s8gs;l10CW>d?sm&N#6}<`RfPOrAwzZ2E9K)Sz(La z1NWn^bQA!7XN8h+2quHR#3j-C=?bf*q%Dx!C?g4=;04+^bsqPM6{*c{$Qsqxwz+U2 zj!Cx+!CYz0U}^$VcY4zLX);M{^Dj7mPq1TP%a_^Q8jAq_kv0>s~HVA24^yP>SWzqw{_69ufKm#yd(T?_?mN`H$a;n?8deQEBW%?JpmMm|OlBb^hr+ zk;o*M!oePdTZCOK+g&;R-k zf%mc{S=0>)5+Tu6kh`?{l}&5$HSE8+mMSTKB=`$;6>(g0+l5gOhPrt@6=`|`<&4~m zod9ip`P85WsQ?6D#yVW}oV3nEf^N^^CJ@?}|0`-qd2u58V99WH?b9O)E^6<->CL@e zS$KPT5kXtF(<2R@<#Wc+aIgY$8p| zFy54P(7jFNOsvg=%cNqe9MryYQM-b~AkCIN$y&)QD^K( zAMZo)U-I37G(9O1dykK?&{5g{21*xG6Ba^mQsz^wVC>eLRKa$6E_YY6cya=6z?5+D zmIGW^P$)utLjQ%E;q;Eci%AWt`X9OAI`RWgrRkFD&MGD^#>;rN!c6=dYcZ=1>$WVD zy{|U)FED0pq2{`|48-vo5j&Jprey)ZP1+rwoq77`rwS=9y@hI}Wq1Ca&qTErgIzDG zdSJa%lYm*j-IHJ_UNND!oR{IZ$H2mGI{c9QasVI&DmKXv$Jl-W9Op^G0(b_yD>rm6 zTy^b3z>+2GYH}%b$89Mhqt{Dn1Sgy5LmMXZ*EnIdh$)^W|Y%h)9BQ9M<;a=Z>aUr!g@`LGS%RZMvvIcEN+ySgdnC zwno{AcfUO@^!!d;QHKrk*RX!(Y`yEu+hWo^;p)+;utEWnpu z*v@EK(R*RvokjX0ryNizmOfXM=)$VTdOfS6zDzJeoNX?=L1);-7}BI+GOb3BI1u)g zlRzscxVua|-H4vY0th*ji(cGa7WzrvUi$MD+VcR=`P>{Vv2yzvyV|zF4GY-$J9j?( z!Ct-Ct}bWrtswlnLh3JfjacKam*TEnJY=v`aJjVR!9D8RccBX(GxTdXezHyX7PQeX zVB16Q98|16zm1yC=mNWLQVlQ;#2m#lJ@fY+5o(q0)=NrWczlanAzR^7v}N*kLzjDg zftrG&dG(#f-8EsxxCad~XCOg#+~p!}^yQxA4*iauj4pkjV~weiM$@lX$;u+50+Xzk z^z8ND<4-LAA!a;|WvRcKZglFJGDssM{Y@Fy*3&W)9|0?kI%y^ZMl-W{h2w!df_(p` zX5i4Eil`DC%7GRjVlhLv6z$s%BcZ#oq)BeRQKJXF^|YFHzHxTm;|-B_(9U|GcF`wd zdWtM+c;G!|Ipf94ju78_tYq9%&tZ*%gQZ*KM)BDst9xPDa6*_$ehJjvEZ+WJmp^e2 z!Bf0E%l2pdiKKdW8={5LmF6gM{(|0M9z#Wxn6P}m1deWBcLXDcS(<0uwE)k~x7{wZ zmkt4YqNxG^pPo0fa9Vw658fGhS<5H;U_MW8YiOlX&Wu2JInyP@AA>r?5i=##xyi*& zQKR(cByrx7un&(*Z}*BbD<@TYPORv5O4W+T&Znt=sxIWIz1$;4^VtRw6N}f^HWvio zhIhSENb>tNmg@XN;C3kR*Kcr%c5}VDZQH?{Nx~YEmSuKN7o`cB+)WI5R@%mN47q}k zW;A&7-^`1%44wyWb!A58pIw{QW5jD%oaFALa0duj(d{Mv7S&!&q@PVP;d0-4lY0X9 zZG`?;Si+oMb>apx5NYM2>LEaelQ<baueZrMp=v`Xo=K{R*X400FH&kZ&8X}1(91OqoL55*mkhiP z82?j`uSepRbAzH14`oviAwCJpT|!oKtwjpjhG!^J!fOu2o)%M}^%~~nq|%qLA)}2F zuR1U61G!XM&hG{9@b4#O^>ucfkkeB_(@h_xf4;Q5EWEU zsARi!+T$~u~^Rh=xi*F5v&Q(bgTBT-S`Q9F~fY{~s0=sEby zfJO^C0i3s3t(a1kHsjJ9!WPdkt_+DQYVw$6N!lqJwue|oI`VLN#vSFYFyr*-yWgF$ zJt{Xg`*{G=D>sR^oDKhWh4YVUqez+pf0;)YeF35L;>Hx2vdi8jlS`;IxLXV9j5mi^ ze~%uz1C1ul61Lizjbe+qx$x@$lJ=Czo@erHG^g8NU@*R;Siy2IigDZI?dlxew!3B* zG`edOsTs{$Pw;Y%GhHEt`;t#lp#U4p7_8W(#ldpMl@;-?*NK|~IA7X4Y(pIP6K0w< zq`N+@MjkHKbfzt%ST3iRGBm4zS!$J|mte{?&Y^1-*FsUV+% zmuH3A;`~57!A&d$9?xY9C}$6>)=z zGjIX)={SwrJzQ+$XgG|@X7@8IjTWT5uPNWo-P+Z*&s4k?MF%+@=ikjgVCYM<9aR&I zNVve~uB0!YSYnxGz9&u8y&&KrOPz3_dY;E?^#RwoR{f4_-?lg({})f=kke+OJL%REJl-H4iAk{3XWMy|lHv<7lM}m15=Kcy(L2KyaD@6}Qz?zP zSB?h`E*?HyP3cGm+vm`vnmvx#+`2^=?jA~Y4;(jl5(DI0q$+X286YBxVjjn#DR|N- z{$WF8Hr4vY@dQ70=N15P@VmWqSS?oI>#-2KZPB>(!z`jw6P`(i=VW}F&b6g{3}4HZ zX}x|F!TOO8dx9-gRh5s)hmU@6i*&Y*U_S`bP9|?cy(lGeBE+q3kncVY4+a`&^8Y$r`$%v5k1)|2x-+ z-tBLlX4@`;FRJ&}KYJ2KQBP+>1v-x550X6yC9$bVbK0X48% zf7LT=xFRfh6J;B<#Pj1uOj z3RV0$oUFNo^Ud`<;lKluKqya>H{Gcs4U&@@>*bZDSs@L!V5T=4DF2zv^P-%7#Qb^Z zKUW}Y3lun|N6Gp8$WKZgf`r?F0jo=yh(oQZWp*h#RQEo)VL|)!X}sjwpw&_VO2|M{ z_3=?!kJ*L#u?5I1dab-FP`f|@WeLiLcC9VQx+T(cuZ@MDkhGf76*VM*(1s8>d1f7} z0PGFq$~F2702->I`Jl+*$58&S!0}7gV+)T4lB~v~p|TlM?Rm$_#AVOlIrhRHy}_kd zR3;AXS_5>{Icv{sWTjZ9e2O#WRslcw!?y7@|d+ z{NTSYe15gMxBu?jB<4Jq|JVDhHu1yb8_}i*WSQ&Rg?GH4$(H#kOWt6Wbc(!VI1qXYg5BdxWa~-whzC2wfcB`G<`g{ zG<)Y&fY8ig>#?;h4(nhg3qZ>PkRu9oMC|LX8CZAwotOhh*Ka$2hl!wf34p{vqyrzkCBFO;A(z&)ub0`b zm)4%HTHWR=6KPt1zk_HAFG)-Ds&EG0(euuXh{IUI-M~HM+9ttEL=q%ry+%v?{?6Kr)fv!K<*ZdcJEVst2Hk4MU}r`3O$|`-Kon&0jYi_y_w1Rb6(;zqf0& z&I1o9R+cC&tB;W(TbYcr<-QQ(RW1uW##w9i4B7ULYL&I7Jv`9w4!#4yzdAHstA~`) z2{JtpdU5?YfEF~gQ7v@FdS554A(_ZKU>Y`%IJ6(t=gwR5+uvo&hCN=flKIl5ttxt zU1Iun3XCTG?x&jdgxi``?PK_|8@}ooCZlBD!55kyqqPsT2_uH~lPw@EXqO7|ds$Um z9S4$9RV#rhiij*4Tw_Mx=4^2WPnfw7?!xCy=inzT^k4YU-qY6UeiW^^F**GHqF}o( z`jHmc zk(+-VhlR{><{Z>7HPr+QS)eLTrfmX%2tNQsm<-<^$Y(;wnLYQxRh~TuO;QtLJadD~ zfnKmVPXa0i0|U)%(;}e)>psPn(=~?7Zs(nXuqJ^2J(}(Bm^VDq6u&*^FB1;hXq2_i zRV0*5N#=MZgND0`*lbD6lo@;(nbHaZ_W*ft=)oVHg5i*@aK|U|OEN{8YlL`Pa`yYIQ^5&vgxg zcbLo`mh(}Fw@o<-h)7-;BXz!xe?l8@rFV^I6wobjKZ12oV8uq!h$@1L~OMgmZcsj(}t>z{v32{|aiOd6>D zp;Ou5&8gv7IDu2J!~YZfuDaATT@o*+2F1|}W)Lst9VV~0&vVS`8Uaq19+j8i27l^I z_KHmF;lGC&sPh4imQzGpgLnYl5>6(>8DGcVUq2gv3ZX3_Yw^hWU*+>N3_tX}$p-Iz zW>4+E-kI#p3`8wg*8M%;HxK|$_K)`2-w6?j^y#Odr6c4vSE+#rRU(o=TUO;lO#6#z z11sU9=MXKNeRwlzH^Be`#WJR}vMPUAC$i-=@{+Gp5RFym<==G%+PbxK5ZVh7l0(~* z<}Z)v6@A*ycnT?}++BjdY*? z;#|$Zf7Jyn+aO8Ul3OnbrNX5-po`&+K0IS&*QSLgyYVz&KN5ajX!~L-+87FOnc|`R zzr0wFSLgW2&P6nC0L|&h4L*){uj1}Sgf&|sG0#OKdJXMalvv4ihD@k7q$e?h{)PcM zho?V%0cxG1nghmi{p8v=W} zq_nJ^WN0@K|ImN2BAczf8U}F=-Pk6(mzghM(Y+H&Agu)Lc8~mG?07e)+3@6<)sS5DEDGo!C(q8L-4>6J5jmCBIY(7b_p`QBB+dt zXc>Efo@j6Q^0~{X;caLI7_yXFO&rq-Afp;~fJ2)!FWh(z*}`y8Tjx&^#JBWwG!RkC zuI^(Qe&h!}6K~INIm?LtZNEG<_BS9Pf71K>KTy+Lkl>LD}HRX*Y|DE&9E2rY;(4lh7`@7d0k#fBW5_ z#8;4dXtbcWM_p;2Rd3J>m=oNg99<3g%H|Q!t+@A8prl#!mn}ZN^ctWb6*J33X+|FH z6(2=(F;89G4nRh^0F-!+As)&-M*suuBU&Fp?o)<>u zZ7ky7S^M3oW1k4v2TZ;fCAewx1RXAuU$}~h0VV+0lx-@5YWgpZtw7&s1uXXMO;kJ= z-U;XrJ)>$5+*$9>Xcu}_XG^L@n2|7J9h7QbJP$z9jNifiAZ9f|?b&E_1C4?^#U<6M%TV@5vF8Q* zr)tNE)AU~`ja&9yn5Fq?%`WEsTER|X==TqZKv~e?d{mw{V$>0vy(y&rl<~eI(8R^w z`~#KYZ9x7%cFw)P?w)u`4^{Gr#;wy8I&yCi$O~l6by;xvtQ8Z_q8zz8E4!5xwZ#{j z6A#>uST3k2ja~ql?md%K>k*y9#y1Nhxk2&4E8eAc!{%`@M3_3xGI6*&^q6R&fW0l5<$x{0L@7K`#YiBTu0~)trlEetMf`L0^IeWs!`$o(y3A86~ zE&{MeObro$MI%VfF`-G|EU`MZ5fR>rzZoxk(mT0byaU|Tz~pmJKE7YW=UN9KSAPW| zRE8zHnyy9tBFW0PPB^JY^KM68)$(4la4a3>C*V_d&8sfwc83SVGf**_eLZ&;xYn4> zdbPA>-oopkn<9`wwmIOc*Kz@_HxtTT_HQ5`#8F8d(8)xkX80nEy#7Uj)wB4bvMagm z>?wbs={;z`k)#j%Os^}hB?kZ@()=5c5i7_U-yM;}*6@1nc=ZLI2(KQa7!FNutjA*I z%Ajt*bx7TZJl<6XXzJL#$F6_#tP!N?w{$Q3bW-z)V&}s2kh-TNj#LlDJIKVlt1B$e z_3~83@3TJnc6jchuF&pfE%}k$7Z#V=Rhoc9?!nK7C;(xV6LrH@=3GP*XJYPBG5#t< zJOp?58~tp)2Ho~I&LP%ZsO0XCANYD!UONV_iR=FUaEF|g==%CVu!BMdzk?m8ATVm> zx0KjQAR$DUSZd~xtp?`aeFuSF4Wl$<2>;9Rp?voukT-_`L6k%uh)w3VH7OVcK9gq$ zK7d3Iz=ySRftGk`UaLtKoOrrg_a;~1*u6P_Olh1%V~vR4YD~e4Hv4tfEh_n3!nn44 zT5(@|<@zE__};U+o_!&8w~cwHj;UU&lNNY!`jzP}VX21RM@-(hp7$IzT2)H-wuPyl z)bLnYIMd#LXx3|VasI{KnURhT1bF;a`xuC|YTI+qTYpH9l|7@{`0dB9F~ErpgMZ)m;oN66 z>=}i|to`}0r5Y9^=uMQC?>nYv=_JbCi%a|{?wi+^=lIzsN{t#ruWHC2#vp+0dbHqA z?5F1sq{5K@2-)0iPx)KLQM{~p%l&@;rupGQfnN|4I4(yX>&SO@gnOf=Lmha86zxR0 zmTN40E^u&$6hp}JbX&%MWpJcAflB@T^BUY;G5R@QfqIC#*~!DX;dbH0p`YzO05cp3 z*V{v#Y_=EmQ zV37F3VXnj@=x;{pfwoUxIkhz%_+lBnd&q(AbY!1*L#L*sIWZ=D5}Y(=ack=nC=t`^0n}7CzJ*^< zeI$pL49}0*_|@^JZ-#ksXZ8V;P3oF0r}H-X@h1}Xu(+LtcwFo`hQcjNxlL$XM*e3!m)~e`b>Szs2&OeEdj`=PSh!>!xFWho6!Fq>zpcv>* zF>-JRmJ5*$4Y!H#GQDs&&-RB~)`o@`r{y}m7o)62FEEf)%T3(7_7sX`;y+-&Fs`r9 zL&~s1$5or3%x%O@2t;LY3aJn!F+8;BcZlPduEL9Ai^_)t*S`gyLc8(M<)G1!Pd|;q zx6t=gF@>wsqUA+XA-DsAP@3LLDaR6} zb+fF$yA(Dk9>=1Xk3g!C=@eFkdvJG>IJ8ebpeCLmGrEaJE zgue%a?Go~bJ3uZrXs+;hE_PrKyfE$z^_3_p%pZ0xIM0^1KH9Nrmgr3#1Xh>ipn$-a zJA2pn?fR=Mf*K+kG#(Fgd27c2Z{zzEW2_VdOj5lkPYuPucix~tGx{5Akv_%bv z{2dP-i={7A?-u@8$wPa@>~PpN>8qCuJek*K-smV1?%!2osm&?>3_rX>A{k0k(9-!HmJIbh?2D8s2$wv)#E z;Xun`JQMA(KAN4_pC1zJ7IiqTpHddZLA-$h@NC*1N2mz@!2k?*s2svj(+_O9Ms@#*#@h7p|G;c6l6C7QU8j9R-r1C00I4^!)tNtz zeSek}&yU4;u6qK?Z@~C^BuMnE&yVtlX=G!&UQ*k!WBzc`_ozG=Q*7d0voTyQes;7g zSW#8D{aNhV5U4N{9Q*^k4ZmxiAK8toh~z#Zce-#hWrfi)5i!$4pJn|;H{On~THBih zC+zc_)0Ai3?V0>P=61q~Ix2c?ia87@Zk*9)(;<^G+Mt4cDrFknikJ}A?w#aU@Me#f zbxoR(*ZX?#JpI}-;`x&?-VPB&pCtbCbnrA}drp3enuN#(5by%H>(6{kZhQ+tJ zMEloTr`Oj6w=-tdy$$@>{9BS|+xqZe!N^Y|uNwOO3-C%u=#^(X8)$s^PgoQ9UFuHs z)@KS)UY$Hyr*W$jMayRXcUx6x1rmMgbas}%Hy|FIM)Tx;v`lY(q3$y>@f^(jDW4-s z`KCh*C*X*|JvXOJ)Js`Av43Xg&laNEnlYkRqz_s3V?Cdm!XMM4E&6P`Gi5$tQbKS8 zUyFSNHkI#NojT%1>g!;jMle&Q^G$M?%~-VFAvEKdwUN`m#zXX-2LAZSSC7KbH7nuA zsT24`-m`f|_sWOt1J}$;Yrk>rGwbvD|FHMw@lb!!|2UJ0XrV}2r&7sUWT`AevTubj z){=cISwfc4UZPc@m=LlJF=VW5k|kpgSz7E{S&QU*?hNw&e7}GG9*^(i_jr8&=^fk)>mRzUb?trVQnS3=cTmzyur~0F>_vf z%%nI~2DWpv4G~wAzSd^V^wxhW?!p4m596q|W?o_lCd;-;yn0M+!;h`kKKS7S6@+}Y z#yC~KDH+@Mqu}d?^ADju%#EzpJjuCEiH&--Yp{0BQmNsYKx4z7XO#=4e7d_! zlm4h0KRmPdF8S6!t)+grts}$;2|LlTxseR+-j2u%Q?nUJ6r>4CIoh<8hV9;;5gZ$yN3|Dtc#z12g;faR{85 zj7?R!VD+-@m7n2cBQwb{&I^(NoEJA=e^f-P)MR+q@xx2dL}D*H?Hmgy92PjXe^!U> zk`hA)kDPTpLR&#ySipau_{nQ^iT*!OBl;nS*)PV)2KHpl*$lY^PsWJZca|KxyNg!n zH+6c|qnbrEVB^<-eG#i8eX;5oZlvKNsA2nI^@|G+#|JG~HO@x~^v&Y9qePw!ciW1g zhPppC-FP~G#=?{@nFJLrYCSvyPh(i*t>Y$f{w%e0Ehmg!{@~8NAV$)9%vg7oM8KY8 zEH0lhDm?+_(2GnM$@REi3+qE($~bSNig*3QJ}q02zCd~jRQ5Q1X7*D4w<2H)8BRyF zgt93N(SW)1*5bZdkQ$QJer_;p!irNHijHkKejW>|bk#e1eC5K!%Y>1XDmMwFJ!Q)O zH=9f9AgD(lm-}BYq`L)j8<&O9Z5sL>?jqW*w>qwim*_28d1XV~*V)zdS6wUK+bh4s zfPidDUSRGonx|$qmi^l=k^H1a>lJ~J9@$M@^Ef_m{Lldpb6hL7&#he+9GkbrtC$uy z`Y92;Q|kwQ?w4Uv+JzKJNfLhuM8{aY)7$p}jexM@F>s|u#qc-h*Hq60sZ*r~IknPh zeiZ~#nN*K35tX45`eD*fapQ%>VIrR4VC(~)p2w$Hf;r)!+^nqNux?&d$-Ivwox**h zRg;NC*Z4z$e=iI=TJ`u8^vJGRhAhFTQ>RZh^of!(M*@@q>IFW_5y;jV$6RFHy za95C*^TB6sUo9v7#hfc|&U;~c8<<1aaxjaCycto>lzFgn(J14=ZU+w=mgt3mvB|6F z_&Ok%w>gG7FW4ab209JF6;~Q7INrQ#YGGRV&THS~L7583s zTZjcLtQ<~{gR#BH?^c{NVsYm|4vNz@cKw*RMU64!81Jo#>%ZkZZq_vcw<5&I_nszvLAcp0pb?$k?oKBV%bhR}w3T zp}A}>6sN36f+*Ip-rfF7OeskP2ITa%REO=mKt{GN z2+FwSfbQZ%_*wcJQjjx$UH|BwC8q-CL5A9feQpg}t!j=RQ1*$oi|#Red3{4yV2sJ; zGc>uIg`NJJwadVZK_dz$ep5nkwmFZ=O4>?jJBRD*IOV9c7=7J2vaQ^=Ag_Wqp-g~j&^oO8}cQpID<~NTKY^NPlacEh+FL$j$3;KWi7t#{tnwn3DTTk!U^nXd^)+_Jm z-FivTW%2k0^ND|e4!k6H(=SqI_?I{*!CVko2oXv{pOsu^CAQ>G49kxEmJkZu&5UC# zmjAmA2H}6PKw6ZmNT+7!o|0vYhb4XpB6dyfx7X9Z9n3?bUjm35Rv-tUtzxIjkyDJI z0^Owl=DMaW#L{McPLPjn@ez#k_Al0+YvFh-(*_6F)uNtpN5XB!j3dYBT2jfM-(zX1 zslu^^iLDDq1bkcA5=T~?>e?2%amg=nw>{8d#{VSf=T1%^=H&}+xgiIq2f5{n$oxk+ zMVNhW(ns*`AAAkWi8X*-=HIX2r+DNB?VR1^10uui#;jyq5s1a`*}0*T`LF;u1G>yA zm+@uvbL-i&XWIvO+LqkqaDi~#joGPd9%R$wS(xsklRY1MAo8#q zgFhGjP=|o((Lv^`^Vdi8h<}&+r4LoRQWC_x?CyR&704CBbMPw6><|bThWCF9xWcz> ziTIn@^jMdUWpoF4c48q1f|)RiD`*Q*)wjCn`2M+xd*^&0j7V6KA%Qu&78EKm>x1zU z#{fbKg}xK1+1Ura7ixKitz7c1gCPFuh>$JtY2qo4GZ+5P`j-s)mlS<)dcgxj<7Ziz zKG)zubDb5p|4B9J1gHx|)|u{BT)V+E%lIJ_2_Ux4#P`PHI&umU1w5{h{J1}^UFw7& zKZY%f$$vih%FJ>cq@>S%dVWVlF?~ZXd%c$yry6#~E5zd8RSkEWmH3*qZH(p+xwwjG zYWD0%|1~r<d;f1P(t}Qx^p{_6bZ$(vS+Z<5 zgu&}B+XHd>+i^?{i$hT3NX>Z7eu6;Q*tegC_6$gn9apj)#{C+kyYs?mFFhGCzc&Ap zNDLP@Ll(wavF_AixawO5ZJjr5_|q)wg^jIX58UY!+cFVpJ3~j0$4+ zST)L~tY`J%?k*LL97P^C(;FQ8B|TzAF~yj|%Q8zfnGFX^I=Sj8e2Fufo4R-xhX*~z zB00&d3Cldlyp^FupcCKG$`9w+eFvf9M_D%Pr*F#|>wnh?$A<}7JO8V@+hNvxJrT!ta9%6<`tGL7$HxbGYJ;&H?(&VPCRu~z z;=jr63NEHE&zyYFn$o%tF3wT=tyLZvhBpNck-ynF;{9v?66y}ud6jdPT@8}g_lzo$-{NukfW-4^+vFgSg|Y^IF8#rS2S<~u zJ=XslB+-mTX`@HA4O{(D*yJlf356OnP9AXr*q>mZCj?>Az>tKy=nY<4r;~yBS;|ii zLK8DD;HWmpE2ORhmW~37ea#MQ9_&m*2jZ$|2<$>I7{C7KiJ#@AJ1%5Nx_e*JvEEmy4gkGPnN zOdUp8#-i^@65v5ttz=i2~>pLau9DxWh0|KzPlx1Ny1LISzC;cIO%3 z^j1mC8s}za!K^3EtMu1BumAx)_qn#~ogo5Vs)n0izjm-5nyWUZQ~L#Z@fE6e+%gJ4 zl`~djP%0IDVf2H+9I!+iIW?s}*#catp&mcykP!92Dt z;Fsb%lRZ^MhWm6C3jx?%-e}?Hau`zTLjV&@qm_b4Z6S?(^NB~TI#0O|5x<=Unou0g zhdyIfV+HInSwO>4htjLi@Th7KK(3VLEW1SN7$CD+03u@z?Zy&jJ_9G)Vb>^8VMw@s zFc-*&u(yHY$YuK|`%jO`(}wTZnO5Q+iWN zf{n#$nNFq|ph-^Ed?@O=;s$^o%%a>i;KLbF=6+?{ufCkEFAA?chO6bduORSa3K}lG z@%nV~>Zs8loZfjN^o1+a(9qD*r1bUzZt9-rKx37^<~K;Ud&DTt$)yJ6i5eqBLV}xp zZ(+(!>qtpdl1sR^Tl;g*ao$Gz=5qz>!lrZemny5C~W`3gAHsUSr97^%Gup z7RldBJ|g&%iB%aY%ci9?9UL4iT4K4DoJy|+U|)vVU6${{;T!g`3EW+82$XHYq}yLrc-KFwFCg zdX}o>Iy2rY?dQL(+9d7zxDbfw5^kzYrw#+8!VAC#Z^|kJebV#qh zBl=hlc8jaZA1D|VtGjy)x|U}8jCJQd?cd5u(6ty!1sFtvTU^o>|3;|X#^nQ&z#M1E zoAG%y-`4EY_vFuMMD8cMCE5%3=UbY;@)X$<$KfcbUj&UeCIRfJF9t{Ff~mN^)(VBE z@E$1h+hbOv&!Qwmig+HGmmdF2Fk3dnRe2h8G+$n*Gtq{Sp4Yu`potu#N#*+rMs*mp z_?5EUjC$7hx`&BBD<)Dmsr8$vzw*I;=hnLbI7DY?7%7Dv&enE-`n)E6ih7oVce4$z ze(lC)_T`T2GmGmqgwno;SLku-+kiucnrc>6jW;;0#VB(0mOh`p@LPRE-#>wyt*LSx z_{v^R#Rrf5wbNqu5qTJ29pQRBnM9R83^1PXTO0Pj#tt<>b7~vvUobKeqVmt&>h4NX z_rI8nIFa8MBjR5wSA8zVW$qVBxNh-_SSBn&JAQn+a_?SR0H9v;I9LdW>>PN!zvyJO zdj7=QOs{lo-b6`j;%8CXew(J#J6A~UOyj7zyyF+(=7fZ!43oaOZ(gFM?mXbRrEHks zx)y|gnxBMgM?e@2$O%YQxjq3{%I}Kz_6OP1?xa7n`V)`ORahslAINilOjfLJcU_Lw zrurP)wgk7j7kqtWi7wBlcnQx32Q-Z(S}D$|zUEag!4ep0JCzFkNc8OE`JqcbvXw|; z8J9;|H=S@bxRw33(<%@DQV-{<^G!V^x`acvb=uONPQ}I0h)?QFCq7En=SBVqG5pan z|DlJ`2W}RQ_Ncw0j31g_*)K8luk`BA6<#N& zq!XS-ipDzp-rT0IsHx>Jd)|M&kil0h3MH#0INC(CvD^9woZ5}zf%Ny*(#ijud@5A>YyxL5|~d6T&wP3t@+ zu)!fSjT1u{IEKu0<D2cqPbDJ6e|BXn?lQH2+xH<0>STp+-O-v&CQcBrJf2lihIc@o3 z_E(@b^#j!G+Gf{`Zaq{AVc`d7XGYlpa_Qq#6Z>v7IkPYv!;XPop>v+E0mk(hw;%3)>&_)}Nb8C0A(=b~s9hz>^QZpS+yRN? z9Jyn7Ri_O?`z%{?J{5amST~;u>f6N1e#XeP56)Ui5x%%xd$ZHPkx7^e4$q-gZJl8C z0~aj&LtFh%fV`gxJm3U&fs#OOP995BC^0ngnI)zb+-+y=zlgc)n^saJTG=Zz{ieu> zYypRSheMsX`YW}e0kOJFt;-r%a2s!Ja`Qd&^!S6a!uU5|c!55-c&1x5A^KyqT^98ifEX~ppPt5CH2pnM?vKnplz+d&uJ6yGUQ3x zHl5l{{cd15bPP~klDxFs(;hKck=ghY&`?`u>UUGF**MiO^_6W9*iD+D(%=hgB}FBKkh zuhei6u1-qFsDQKUS+V;9;N!cV*-pRF47|3tHx75lwKQ?!1|>Yx^=~3ma=CfeC@VJf zz(qn<<^g>T#iygE0&d_)QT)Sj2TK^c-}fWBCr^PU=_g$`>0EI@!V4(fl1HzkH0KNm}1svp6`T{mw9S$npm_)`23uK*G0Rndw=zX^O0Q3ZvP(^BXa< zuwUDp+Ro??IBkP=rHyf_YxMV7R=21I7VJGk{^pQC308yCF;D6a>>r{aiva!ANgDVL zgSw+0RccMS*5iJU!=IK z$X06xsxOHq5I3^~r)bdRWLoj2jYghw)e_Ylx}&VA&yHkUisVy$ zseI2$N#vD6kJ6*Y9cHURe~qKesX(Bp<;3PR0~c+Fb-T6prM(}PI^jzryq%64f-9IL zc3?IN>v(-#)uY z=^SWiE!GfH^cyjRN4ai%BFKLc{~5bsA=0UA0Z~F_-7k>KZfmI}e3KIXkXXNxf0nsx zPg++IyrUH=Gt6QPbq7}aMcbi*gk2&|KcJGwDNB>RC130J#YVx#yZqB{QvP&_D-bkZ ziPeuTC-|z6Csd;*CoawkwnACd#P{RIgN`k0q}jG|3h*ZN`CXe0e;N4Dv0qOo=Fzt0 zC=zKel^;OXm@Cv2B(&&uDE|T9I_{yXPc9rU&0Q0uXUk`s{*IpbTNucl(Ih1z7DuHf zz6EFEl!R^NzN!mNg(l;EPr^%Ty#NZg=#L-cyyi}mV=uZs7-yRb$m)09i2#-@$2KZV z_wMwzR(Ps~kh)LJ3kTJ~@sb(IoTZjeJEvKYe`Avq?b#b6#UoW`Sis~OLHtpLK!d~uVJu^9^-Jw(;IrP9X#<&0Z@Tndsd9opdnGaA> zEUKgBwC{o)nW+)Iy+jg=`cen>`^5==g3+9w3Xho%!w0-B**m8`TX+JPf3?FBvwb`J(j$PdEKMM~I(Ry{eK+d@w3sZbh8R)*V(5-8ZQ_rP7fewa(qsbB~uy?pU(WFqck126ZDNtxX?rIto0(i!yaCcpOq z4(3k~7;u2=Z~{jqDw#+yIo7Ax4grnQfImM~r8j9vx7McaN$cy|SU&m%T~LP*ag^(t zv~ANsCj0Wj@olHm-L|7h4hkvMy$fA0LU=T%>hw_5e6u!OCABSodWqfm@dFOUh$4%v z-=Dq@-QomK0JgeTmu|}q)?7?}wzn7L%slpE7-V+$YY86e^>5IvK27xy$g*MA@AK;5HP zm!Pdr{y^8{)0`wa+!U7$PQnpC$FB{U4^9w1Y=pZ)K#8gJ;fBZ|s7Ozoam*}oya0Eb zsPaE|wn4Na2Vx{tK3x_({+z`3yxk=cQ!`?bW34EV`Ry)qYgwKEW7nJ^q zV|xu1rEMCt*YMn)8Uv!OOsPB%0fiT7k2%)tA9k(5o>!EAegQCI$jZ*>H zjme_&gU~W_*mQa1EA!*WPoYqTcC>7>M*tLFMAsbYI7G|kk^*vL2rGN~0zxE{FC8I<3%* zTdQK_6Id44zz0I8rUxROVa-54?LZA8kt3bvkVhIR>C`RSi|S^RBQ+je9G>>N+^*?p z$x9rU*EH0r0IvCZZ~zY1rOKt9oPmq@GZ)F8PX#{b>Wq3Jz~Vdu@i#%|DNFkhAm9v{ z1(W+CU-^FhQ$?xN7ihlwWK#q zr}mGLtMe@GEd=9X)0M?BX`|ETDP&K!-l)6%Sx3M)3t}Sq&4Ur#+>e{Yu>|&A$PYn| zaxjI;=ae(^HnSZLK701%PR^*zhT_uNI4;6s{=*mwDnD;bA&?DQ>+WG34(U=i#6Al^ zH8;q`f;&>4Bg6?~@{^uYPVg9S+JEZO^XSlL6UGxQhQfh*7K-Q7`YhW5RJZ!X_c`^* z`Ht@^Tm#(8y9XN6qD&)|h<(s|;O%(T<Bu_y#XDbA>Y^Y&Dm=J;` zp_T4jl}}Wyz;aYrMuu;##j^Ty;CWYZa~8w2D9@FAzh2)n2wV%fH$|ys*uTPaRCr&^%P-aZ}pQ!SMSwT!fnG$oAt^?wx1|! zADH$&GUDyOPM!A$aJe!M)FtXpKm9DXW87t}xpQ65@l6mm={WVZP;}LCca{yH3ZgB2 za~Jz;zAwG!-h+Ft%oFX>;1YM119hfZC59+|{32Y$l)4LesH+1bi-(JH40Q;xc96?( z^&vrHi_h7zmu&9}Wu#L<~Y3BK? z07Yb4n*1Mhc!g{$A3d!S1#jLnfrFLW_qZtY3wy;jsDC|I_l{{I|IaQ3wt50?R$@dt zJZy?ubUFT}288SOV;d;W4=}@h9Ug?2XP$cY(q8#nt229v8;Lm=(j457|oc}HKaQ}yAyR{=9g(v(hZX>xJ?)~Lz{rgB4DL?$?v3)Nt+?%N} zKA_oAXgp179!0@l$LBkFz^9_(NnPUW#ViJkL`YTzIeQ&;BX-7!X{oEO;mNxW8mPWE z*rMQIvWfE4=IkHwXs)DNLGs)FUY07}QaIu`V_|g0T*7cdezLUzD?L}VMX>Iuxc|p& z;Rc8`CC3`n`kBvNiDxf^sN@dph678Sqq7iX+u9^i@scx%pJbKZnB8=1rH~6@xB>#v zQMPG9XNLDw8K64y&qcs*f5{)*#{^Ptqj{6~UiKSK-=ImrkZX7fW#+*FA+uL!TvA*W zT&C`Yk_&<_{QWtR$~Q#Vt=f8Du)1+-*>FpEG`E&fR3G!3XRZ3WElpzu^-ea~lho-9 zsB{~!5&UpMY}|#(1+@{F5Vx*9NEk8#Pbgzy3`jQ7;(l-?DAZ9wy#>B+LeR-wY{Qkm) zV8&Mv@d(CHuKA7ak}AF;?|@57J>rFYe3$~2`B9VGWY1^(Rv)-8RF+6cMg`V*2NGFQ7hH^!Fgc%5%omHSjd@v;jILp@#=)1+@gDVvI>-y6*kB9Fdr$T7QX z+u^u(WA#k_wwByc!X!}hhUcG5$@#4=t>g0fWoG`0G|Pk@@XV_l8k{X$nw%a8?JWre z3Aa{8NKDio*koK${TOmXUQoav*;wJdseGHqMN90UXLPyc=tX=Q%XmbC-}6yB`E4Vf zZI6vBr-^Xmxo(Vn0+le=Cf1Y%Mrr-EQMkjZB?Lj$VRzX>X~&#@ zsr9#ta1w9+xWgKc(1H2^&{!Hqs*ydzY<|rL{fwe0^y}!YCA8M7dTb z;a|3t@9MKnLIJeP<|u}xkF)%SVyVyF*l!yp8T?gpGN^cEnXKYusQXx^COg6Nx9#Dd zZ`Tb$hT&{QUs4P;Gu3v}%&Y;!?Kk9_`4})Q(`=j2S&pj7{Ryz*o>k!xezfqtbjM6Wmz7g$NA7I^c1#m~nnL zFcxDf>PH~Kjvu&h6g?5CO-6OexhMP*b)I~7UyI^dD7({0aWcxyZxm>97pF2O+eSO} z-5+kt&v)_F^RHs+0J>M_hvr_#?r1g)CGN7%7R_&rJ`rRp%|8n%0PTvFRLD?CIe*$$ zS7ktHlML^=hzX7CgGbMt_;f^yy_5_oA6MI9Xvkp~dCTJI@!uTS4-j$lG=&Jgmc)-% zijy6o+G19)!#T2x{1*-gLV}Hbw(A5uoUF}rw?)sq>T}cdrpQshY{axE{^D-Bb zg#x<`Pqa=^A! zXzeo67?!8gYT;^yuSa*3p^zF&KTRo~ML1g76zHIi-NaKBeRK(V!V0?6srm3&`= zTgrtzp?Wj`lDlJeULA1BN|21AXfr!jc^GE+16P8S>t~s|m8LHGqq5c9x0^N&`VJ+6 zG7Wl(DDL;{H>i6d!hXhSFGp2+Ac`7z{-1=;1Nu4#cTEsp4US9Jp~Ov{`v&%K zr_B(A(QYUNb_8wd^9^^!A@`iQci&vevNfOBg;G2F<4x`JLV>Y4KVmMjFolv<7nX99 zBeFpOcz5)zj`=r)SV{6{4W#Gmm^}2@+5CH~#}pFt+7g45KcNcN?S`G(D=~L^O}jwT zItHlt_@E;B5$elvxLice-C7N0!*ZK0#D95nHQ%lIfIY3m<4zxndx`LN(FA}nfyg^2FKk+RhwU3>u6v7VrQYx2|{2zkc`*;+c~^tt4=orwD@ z^efGZY70?6{Hq*r23o+6H#m7O_$+&XkXrO!l37E5v#{HYHjuM5BWib@4q+y8| zIC^`0a{3aYB7^&yC-$kN!>y0kr>khEAG#QA z=e*`mlVd6MU?%FVuvdW{IHUQ7rR|`I(9>O}Ejccm#-HwJD|(#0{z5#fV$YGidcD;b zJlUwa7sHQ1ygfPPy%dPJ7!Onm-xSo)1hBlFK|c|0i#+zho>MIn9I<%F&;t%m@MGiT zLM(tjl*`A&QIO<{+B3YWDVJ0Sulo+uczMc;L$1D*% zT)@G3Eh8vkg}QHTpC*-9D#m*J3-)wOJpUK|TSnFmkJOpjXs2Vb{f%i(fUCPMW%YwT zmI_|l2o#Bm6z`BkkqSZG;f{3( zh|qCLZ&9JsQ{6r9A#rs9##5cR`(K3~ya)f6g;5HC%S6#|zkWU$OeVU8+^j3ZK`HWW z%;tqhJMN)n*;ThlmbBBym&psCn$h2Uow-(>#ZeG|R|)QeOF)`Tn1dYXnh(IUbM0YU zj$=+EnJ7b8LHDhL?QOQV2r1{RE3ynB-Pre*WG=Z6!3X~U?5jFvm&o?pmdu0-75J=_ z#(yf&hy`rIW-n>w<>jNb>u=$1uLTSmCUYGODqp`mh*Rx8NJ{yM>vB4xQcsOJlwKx$ z+k_N2_cuaXj{(FhIS!c@&F$x*@K%k@V3=QVs(eSmVoY^@M7U{82>cx_(Rg3n7#lx| z-hJ)BFfn3Y3(tNuG1$CrIpb_g20zb2WX&c(IerJZdIm$Z33ku?KYE-*;1VDJQa~~E zogxy84U53F5EyXTW5Gi(vVTg=7=l1N)BArVze#{6D2!z#!`VrIhsSvqu{WDCrpI^( zz;xC#6vxNy;c~hk<|xcrz6DB-Mzd*q;l6nsW)QAtun02bL~po}Mc8A3-slKtGb8mXPL-&ZF~f*H!ic_I@Z$SdR*O$%`6~V> zTF$T3Mj(WaRK?-o$;_{6g&_m03?or|bdU{`x!&r`f{^fy7&uZWwY9aW1Nw9*E-nI| zd&H-`j~l~wdT(d&Foarr?#x$QLG5MlhTe`t)i-ql<-&@5w=R$7)m|p=RwL^cty(Mx zg;zJTn61YcHCT*V&0iZn1LVRB+H5k_QShrkK`t!wJbd+GGd}R}!`|}k4%bfx zF^>@Ki&)3km~U^}#1)Sgxe!)|9H}$eNs=f6FH2GOS)<;MTdOIB+ZQ zFtb(WTZqIU90#d6IyrMAPutgSzWAr0Mrwq-a)epB&OA_gX#@atKnb<1E9ShaKE8j0 zEHX=;%-C|d>YLO1dKDmgV*r9u(v^LKwDSgl7nfXL;mfJW48Bv|#qwJ4_OAdg58Xee zOiW8wid_h8UOE7?ljS^oK>)!jYnx-qU{Our(KcKb3cfn!zP!E+5YqMExWo^jkpiplAa^OSf05MVaF{@gZ@^2HJD+rj?|H(P`(YA@AJnw4)XtJ$E0KA{3a_s zdHd-?;5H%AuI}lzus<6L7VS5jvC+EPE&p~PeYcSCz|xQgz~W%J#0t9RUWN}^sJWmA z|AsowXt!f6M@n!@!MI33OvDy8<(<72QCu&?Kn_UwkE=zk|LsM!XndJ!!I>{gLPA0u zK4N|J3VnPg2%mRmC4wm@-Ga%s^k%}>PmACeg;YXM6UKC*5^i`)2+UOCg>vj|ogG0z ze2U)f*oEzdb~mRtb1B_gbMA-D$aVOn2QM>=Aglnn1GM&!zuqNx=PBXAHpzfO%d{HS%C3-e-cl1lx6Z-tEV1 zR3L7U1W&?Zr<50CsTLl7?IGQ;N#a!Km1noTkzw2OOc4wl314+_7(2*+_21&ouNQI0 ziZjNr)4*#LKW4HSU7SOc}cZAcN2&PRXcZ^ZoN5X;BIbK(SRi|6I-ezflFIz9B51FII&LNmk|Hxmbj^lG-Edmy!O)1KwK9uG#lpdbEc;t@x>SuzjuVgGTo3o}=2|0J^mMkj8o02FKuMyig~%m>;YDIH2U+Q$bo!u> zCbP%jivwm~H|=FGgK!GM7@i*5;sNOZccl6|H#BgS-D9d+a)O~p!>aON_Onxs_A8;X z{{P+Z!#Re%Vfrb>i2T(nD2~3dE}^5dSC?yxG82@u1JlLDH@jgKGMKK;t3UA*M?Hk& z!D+Bo&{+=tA(*GbFdoVn$85U?C-D(Fg@3QGJ-<|!Z$Dw8&}IA@nHt%i;Aj{dsxCMu zZH;R07xVx&h4BhuLUtKA4W}e`FK1{&AUyuJ^s{%s6!B^UvWhhyP75q~Jk$zW76+hO zK@SYzCz&wspl-!tvv(*Q)W6}!=xwS5dI7+HPigcrG}wtgn=@>u#W-ss0cr00wO49k zY2iu7czPRBj12O1in-39XXAgspf5^yv%&sEoCKZD4)dE?iT#W)%mlX<hI|+&W=&Q@hU3 zdppEmEB5Vx&Ge)s_UO%2C~WbVjXi=M_8E&fOwM&zevr|6FwoHxvgx6|3h5UM zjto^(;=7x?V)`eCKj-B@Wq?ijO%u}JWXpGh%iaT+!yc@P*lVA!x0eW&-vkL&eXG1R z&||Qyxa5!oediuaI)9=e)<5>P+Lk^+#H1*A-)`nBMA>s8O?29{P^r+=t*~KYZ`})P zz$j#Z$Caftn{06bA|{j2Pr`t5(5>sp)zuWa$xl1ohH5xr0~mqEU8ok>xoBU-SLo6G z8xYPhJO8Vt|`5yQa# z`sa;LkFd77SBMNjd^Z;W$J;5|5eT#0lI!NS$@S$^z&9X3vl>t0vm4D2X{Z2FK;gqc z0I8idEaW=dk&@iv4;e6RiLM6KDy3owqowI5>O9{9q?l5zkT27&7)bg7jBi;d(g+cy z&zm9(iy+cu0#O*V-w-#5KlM-tnh5&=W#UjUhiHb^P)pv6@vFdF`O+U4n^VS5jlwL0 zxIB8ak&-QLeeAj<{lrj?Q0~E?&5Q)uE`D6y7rsCPGYLnNlt-FRdnk zN8`AsxQz!nY@~Ru9d)qQifW^d7*bjx9dmfJY^MvfHOYi(XVgm178t5DtGa<%?L7i| zPeP)>t-z)Bg?9{b#mIn>2qm&Y;SC=AZhGKq@t?B95^(dJ5u_=~Bpv7L+Y0E`6a?w@ zg3Mqm^m+JddltB*-z0RILOWAQKkz!WCEoG8lm`#d?6#TW`QlYWhn*UQ{Q$6RMzYW> zdJMR7QKpfm596spzX3%*g82nNOHyZvnyQ zMzW>C!vjvTQ4=j;2fH`ucbaB>)L$i9^}QDLva^TwuMZ1tVgZf=P|&e_)yC6=eE;(Md!Il317kf=9N?cD?w6b) z`>py~%zo=DX|Tp!yXIybAl=^oZoIEfyW-mO=opk%$rZhjd|Z-GL_JQjUNTO;kdQuv zx(rSNRQ+YV$uQxKx#D?jbA#*6^&*2%Uy_aGST8KGH83?fG2Y~t@8rG4&?a#y_gcbe zz`<%oHrj4X4ayp{ol~t|;$`7UG|Xl+fos=;!u^{8Q}tO}X?D9yc8$vLl{i9Hn^@EV zhr6?|zg*MC!2;zq53-+_X{DImjA;@+FES(!Skv$CPGA?mAPi+9qSjyNx?UcT19NoQ*@a z=mj6CZ`DvmG7|o(<|s#7w&6gLU8))|dhruLnPPPnE`qs#$+mAb!zYU6r-64M;Q6o! z9c7t3w2j?_z_x9jkb!kVN#OkE-bO??vj!98_AX5tjWVmbzltS0>j;rEU)nM;(_rHGK*;Bl4TYp{T4r@l z5Y#K4q=6mJfm7p=ZC$QY(?_83bgc{VbFs8IuF&Drvt>+7Nti6(3OnH-@+Hru^X&yY ze|sPEmH*VB7L`Dqz)6V3hs}vkq~h{yDcgYNFP#@pc1lzO&Glx#$fmJ+$gT`&iF@^G&Lzym%H z{seH#Axaw63-L;OTN_U}H5eLs&h(xlhL@fdE8iyivJ=x}I~_R==O+as$x*gF&`$YV z0_B_T!LIwGErD~rDyfkl{!R&vRLSNDeqA5O}ToBPhEw2!D*_wKwhV56|mc z>3;G2frdB3W`D+m!)$i-{Y%bYF-!+pb_kQY%(?Yk+Y9odzF7DO5IFq7e2Q0TkPEcQ zJipo@Ff1%rk~Z3s(BCov!Eph=6y5889-~2|0NxUW4I%l_US|UwMG=KWk3Y=$XUI~fh(qsE8eAdiY7M!*P`Qa;3kU-`sH?W_ah96bC4QhZi za`A9}y+`lf)(PP3*qxubhQ1WR@Ton$rzH$nPN9;VD|;Sn-yRgCxG?tZJjl0s5FUOd z+nW(k#R-Gx-?;Bq>R5B=8eRb1VHp9m#h1)8yrH8d4aVBS{sLk(-1;EH{Sya~tN$+! zfoEeuPAr6TxA(3vXDo6Sd}m+Gmg)7r%!iCUz{fbMfc02(EI@Xr=`A`;mf2?O1R;JM z94~w*&;A%()?cIhsI%RrzjR&Z{?96a-mzi1J;e5IcjkGmf8-(OwPd{FOjWT3wyS$F zp@fzU?5`LnC%$CG50HZ43W45X9}B~%y$}XxQ4)dY*C$^6$XHxG7UtEce49l;FHvU; z6p60-!FGUN6wQeOg=b}MhA=~2sq*gL=+F9Z%l@q}V@1?LnRXtDoVEfnZX488433cv`mZ9~KaSX=%A`9lf5BThaCM zD34nEs}@pQ7ribv5`wqU+IhL}2N`1+cMyuZi>j+bf4LVb@!vr<{KPu@{A5 z`tnXGz;W)CqYebZE1p}FVuI{YLwA0fw+uR_?(TlfFkgzp#$n;UTh** zb35k9g^Tr9wsEL(kYVjkq7UW{B43Em=eZsV;d^#i>O$IAx}NCq&u^%iGYI z0sfPc7|3)y@!D$iQbzm(jf+K$mhU~%x#l$&eXVyO#i>mU`>3iEq_Z61lGV&xmIl>{ z?3i7|JnI@VE3!rLgc_w$iiseoD=O;X9Qg5 z2Mq@yz+RjYb;Cg^R=WRwEfn7#JY2&kE(Zt4{~-cW!>Q&g1_0YA4-5lRn6ViKUcr0{ z_^U1wzw=89zXScoqw|-f~t}k;t?x7-`}SB${;NPK%!m zk(SKCCZDSg1_>(b!js28^2xzbGavmx-z-bPtE*oJBi&8W-bmN&YcU{^Ur*|2VW5|{ zRbgm8Z{znaz5~4tNb<5#`Ue;eNPfqwWxuK5wt{rNo!!a@RbWeP^eybXbR^qjw$K&f zt5Al0O>BK98#Pg&45z2X9BR&}O173>`i`UsJQNu_P=N*9wh`brGk|9tiod6me71EE9o^pzaW_lhNF*xrEFBqeevPyjjx}u%fx~WH zCo?gL1F?}(y+>SO7fwRk+kBG|{RFK{lPue2V79ggFt2U>RW-N`;S@ni>pWiY&66h2 z53fWV!=7+IJX};?2dKEwxF1^hJ_oRb|K@Qk563S-t0~GL0S}xxD*8KZUoFf058k3 z0gG9|ORM?`8+>hg$q)J}C9mzReWrO?+X%|AFE60u=94zSbP5C}icpBpp$jpCdd2PsGYBY;G_s zy?}|_a`r73)JlXI@F7?WP6GrM=aJLvwDglfcuu6}t7A=Cv@%M73!!pMcJ1;4)>ETf z?Lix6dlcp}K}RU~p8J6c^Es_x30lt~_2Ohmm)17hrv95i4c9dXT}=%QL}`)`XKnnB z+t}uTp);^V@UKKfft_+CenC_Cvi4;Xb{~bi$!xICA$gZ^PLCy42>+ieBz-5&bEY|p z!V%EzHOOFSLAnQPb#TFux_=fje6o~r;wj4hPU|bPf|C5fj4xDGxpVbGS`Qjbo zl5&tM4g$1_Q-hC_=qcDm9k`?)WU=IoMVaa(9o8qvlz-h>qQ)>1NgC+rHFSxkbLXKE zZ`>^JvJeZv<4$2byiJffiqu24a^A|J{LuaT_mQuQPpcEgFtQNzzvF9QRe5hkFQcC> z{JKG0^dA<#h?e;?RzrAr=jjXo9tRHmMj`|`P2sL!KYc_M<(DtgttaS7Fx$SmLR{r$ z7G!H+h{uaN{)}kEfKfSdK;$o=ylJo?_jFNINz+YZ~ z^_?2tGQuo=XmN8BmBHHUj`vlc{b8`gtdhbPj@OD4pXkIYkXG18|3K0MSO~(;%thuw zsP$!G?1V+(abiK7$7D3e_g7-Z|M@03R&-G?hWW4do97E6>ao#QAgy^a znPjX`&QgHA;M3kKxj0!k3R&8+&c#Ch@B0qC`Qk+8=W0|j`0$X2saA0GL^U>XEq3y+lZ?Ba_#h zW;D5z*0wK~Oa!N=3?e-Gwg=c_&My*>vmhUY&9H@$t|4_}{<}Nr-{)FiCf>XC3sXJJ~?7H!)X_!41t>XV0>KZd4hv zp35|Hj@HjRkPB-BYx|31pAzG3?kN9pbG_$+?@Ro_Mq39CTn6wFLWuC@>5jgo@YiN= z2dY)BA6iNd1<&gT-^^&_%?WrWZX;%#PAEeXB(f_`L6EJYyE5XQ2E@ve9TmzK-UEYS zi(!)cZ_@6Du-^9GqKQV+R>73iQ@1usx|52e;%>b3QG(wBnVpN|MgiV_JddE+y-u?AoFmB+D+m z&O_HNANUQtzTZ)$l4hW)%pM{fajk!VYvL1>oVr9gzqpS0VbIBMT5vwI)eBRmn79Yd`>_w9gnI$2XBNzU$Q9ZQQQWdi4dZ5>d)JCx-VVq zqJ0u19ctgAVg=T%=Se7fiTEDs8qK}U>t09*8f{Ss3WT6oGZdQiglF_Mq&!5#39flv z>zyE8!|}^0FA5R@#sC`DdM^VJ^P$+AqA$QX`Ott0&4v(<&ifN{DBdq!@i!?h)ZK>4 zwhyu_b%TBro$o1U-ts9)mX;?yxF*ftcdNAhe}=2&Eg2b9K536nZ9L*eBXlT*dz< z2W4|;3>5H9wXOUO#V96_c{Zy(^b@K!qyxPQEFan}?h3R&a9=Ph7pxWhZw->UC8SXF zGyGBQx&Iaq2=rwEfUyEX++DW$-o3P^<>?pT@i{=JL)~SK+{(t_rs<)-s}}(EIZ!k} zwfc+dRZv*7_~67J&$q+A%7xY~(+vw5Ub?*@ zVh}PCAPSeNPLA%x3oU3mJ`_{I(w3+d@f9%DlMrXG@$Dyvv$mjiQTYkbdJJ1P=#Kqn zNZJ(XXzn#fDMx%qV-MYq`9BZ=6kb|f0HCv}E&;QU1uF->eEY}`>ArwCl7cKqK}(JE z^ucr8z0Xh;$(7Yx`fbxw@X}UKAlmLw=vA2h7<#E$A+n$}z~)Jv>()Z43sXxAX^)1= z+42b=2K64^fTef7Pr<^d!DqRoZxunBL1A>rT|jlLt&qJOY-nT-Hobyun~h6L_F1y$ zx;lCP>6a$oA^+*FS(bDhuCu`2Sef=E0P1t7yBwfHo=BbV5TSY&`tErSymG4Y?4mrb zqzv%e?U{;F*T6by!&*Pz@$KL(*9~$z%-Vpk{RvghBVCxiS1||H!E_~KH2ZTAz z!>Fy1>3e@T`p!YgcNm{UY3Z#^b_5BFRWLLFy?;#5dE&@Ua#DYUBI+%5&Yo$_0Z`PJ zl&rbUfBX)rq!S%c=q*jVx95MgcIM$ww{6^KGNsX?B9cnG6e?TEnj%G#P{X8>!Hgx+ z6tcCKNJJTh>`Q|zW6Nl}5y?LGC}gMX+wh*(OzOFx=l$nBj`yGYaHE;=`~9x#I+ySF zbLz>LGUwU@^!lI~iTc@-A>6 zzS!D=&r)ZPuhv0$3jJ{)~P zY50^rqvO(?Fw~<3L4XbXeMt#NFLnH$;PEGFg*fro{6qlWU4n5Axe}$q|9)w}rXM)!hQ{X23IT080pH97aAEH4XC}(qYEg4)U@QP#b zisl{<)`-o&GrUHLkod)=oMAtIANAX4Gyq4Dmd$$t3c&N>!|$)yz{Gnfz(4)sI7i#U z37*v^uo0Ix*Zef8)cEsnyncexWqHf~ms;=!YNHq%PA&sH#L&()>f^j&YB}?N)$LWS zM;@b+e7%8IAtwNf3x3=FDZmzd1jx})4|6MRq3!$nN?%06p@4fFoqUM%D-zy^G*A zi~>9T7qGDDr}?IWm=Hd!IJOH!pubOO_~;&USc2O+IwyJJr*Ka_Rc}RmHUxV0C^|XN z9Ti~H`Qj=aI^p#|*E1Fp_JHO-5?G}9$Tt)rq8uW(^&{y4Xc!v4x{VXi32ieq(k*{= zz!XJWfaCv&s`sFSd2L-4Qx7k0ZU5%i9caawQ-DTOhis;(S1m`XE`r9}PS;kiMW*~` zy(Yn`TnKP13oxxEArJEy44kV6c&y9_74$aua)Gh(O*6qkwd60comWR}<!7w5!n=k^;-rfa}DUUOFaQOUSoT6seGJc%(Q`? zvIW`%N}unqf?jr%{Af>DKVh80LQI+Q7LOJrM}p~@fe6sH^Ks(+`C5S8evwkY z+La2(xUBnZ_e*hBd-(igGQX^=jlx@@OGA0a;ylPla^9MCyc>a?uCP=GwZhrhJLD6d zof+1HZ+8M!LhACdqFc?{lE2R%~w4CAg0DS>v~Dr@82+A<6yW)sXK> zDj2rgUAi`Z>EZfgkQiRrR%)pMXR`p33LIV+@j(`_iBc3~)&b7VI&TC3ipF^cOX%s) zB*r#h0l|yi$D?;$!kFLdZHs}YKKswvf*foszw9+6H_y#;F)*~B&@ zkOr{PvEJl-6tO^|i}-k*o~|Ne@<&LnT+8<3&#iEb-tRYwA8Ml{$KnrqUf{ur|4tQm zwyxO!cUePs0V(KD+xrIHz`&sg)LwrU>`6_lsJ zJk5%DSVqz-{HZ|7hs~_=4fWE_r$lLaT&x)=(H`QuESq#li`N+o>yum126!n|J?7TpomWbYp$h#ez#a#i~QV;pTS$;&!XqHsX0*hAz zXpx9HgQbWII1RROgTh*62ME(Ls(a%s1bAUYZW>$GrLkPOx;+;toxwrts_SNcJ-_sR zF;Y`aOFwn~iq>fhxFGj-WUuaeRx*4l3?>z>%M|?%uBpMVW@y0UZH;&zIAUU?1p2Z& zLt|=#D<^)nH8ZASVjG4%2Ag37v5q{{N1Ym3cSqWKueQOU-NL+15T>0&_D2LUx?F}& zs%Ys1XoVBQg~sI;;~w|f?CVJ(S0@`c$_T9rO|nG1KT?@j!?ulnsD7iZ)ccUF*92+= z95|ufLhX?MD5twEF(?EBr!{p_Ds%U!H$x0sN=i#n0as750##N0@;qb_6W$BP7D@|)YFg5V1@R%JAqri!k+nR*wr>0jx3UHv^Pvc~sD?GUUuq__V^Tlg= zT_`PQ_Suyt%mQW91}YI0a5&V%1vRHmhL%1H1@AMtk!~w*m`Dro=|npia;32;my)IX zP>4%l6JNfyDt#Rpz+A&CszCsc~gwev$(*?0M5_7X5?$>p{S7cfuXcKOx zH{>OrF$8XSSweVxlIoPwseuxxNi<2p_|oXSpYQp`-~eiXZNwfSdFs0^D2|&t9#TR* zxvtO%WZBUd3~%B6c(@f<3y6}6ww>>Lqi#GjFY?G>P&Hm`|?j5#Y*z4VebT3cJ;5#2I%;h5$f)Q%Y+6<79pNhgUJ42cmde+?Z2-qA z?#Fav`%9HxQIsqWn8cC}1jOd+O{EPS*rJ-R({jChpJ3Ej$zJ7JkX`rGCgxF5Vjr zLEiab#)NI0Dzy|T4Pz-aI^)n`YH=f;yv^ z-f~HU$_K?w7^~oI&{yE~N=;1_qe>cuh{6H3X;XN|J}`}w4Jz?nLIkJBd{z=&w2k6w zF7*~qk^YTHUGg$oH~rQ9eEJxaUYhrAr&=VPX~!F|pzK$hBtdA*In3cUg0AmHKE2Z4#KM z*>&wj*{`-jazMzlZ^;%(!7Zpfmdh_@3FV_9sacATcIO0;Nhog2!5{#w)K|%wcAp0w zPRy@N+eZ0}!|z=ClkHy{on57D7_St`DA}wW|LS@`x2gC~cC=yPIK$}KbpH#jM?881 z6i-^N3W>p?dcZcp?^KMpgo~L`o!{6&A*;&ih&LW*ue>`b6fr_u;Zr-<3AICVsxJA? zF3f$TZkWjA;(|&O%pDLs%*}cosd_J>Zv4Xd8L}zqj^XR+cfa7a9^l4qOik35M61~Y zgO}HkNe&c9uTB-F8YTsQSA1}z3UBwr|Cp3RNv-u*7N*yo%eYZMt>&R4)*VQ+UY8|Z zBUpjy7kvf}L0EK9=RDi56B*l^j143Pxn?bxo3mDYN zq;uI{I+iLlwKAoQTV|$a)28C&=V&~n*rgnNGXuUFf%@_S%EPALv` zckM3A@k{|1aE^KGQ?j)%HmkCxCgf_O_67&!z|H zmYE%US9GL9P8;_lcKq-p(gDjw^Bs42v@<37%t+3qmwf9UDGlB0ZpuBXB%to8aYrAb zH{mjz8@qmfhX3s3lQ72OgwBW{^_zuw08b%)kc+#V$ zKD&%w`|^f1YTm0>hFMH~wL3$Rk8rE}CucWkHU=A=)f;q}x1T{sSxz^UCbu ztL0cM;nq(xC`Ln}gJ`;waEz<_!cAgZ?|ZEnd0Fzz-0a}oE@kWPP5DVuKfCf0yalEx zUQ#06CQGS=fm&@<24k`Qi?Dn>!!l}j*jJ&BQFnbesP+q8yDmczE#Ku%NU69jS_6tR zkgY&gL}}$18@Vy(*GF_ZC%NY6KPma?7r9rB7<*%Z7Kki5|OJ($ftk?qXr5+AsL` znk^UiAx}f0@fjCH3e_dI#crqNB`Z!*?i3`xVd~eeRCBTK&Wq3Jm9y4rtb8OL0vP3I zH@*Sg1d3Um16tu*gDOj^hN<~}PQsbat_W{T>N>}`;v;Ki^Ax0jE5eoGC^ zT+PdYv#PQ{lv7gnlI3Q-dot#46NJgKSbSKH=isLBwG+3ab~-IUij!CTIIABSMBPL( zK(`@>|Dtg$Q~X-IW7)6`h*RaTJ%Z;>1^W{Xc6QM+zK`N%A~WD=GO117G;3pyEvvfO z2S`1~Y8CgRX2UFq=4A7}!U;T68gE(3ROxtPprbx{>b$dNiJujd5)+;jMAdIKQm-0H z7|?1vA!gcWsvdo}XIJ{y9O5UkkCTUjm|C_ z0m0w8TYy$^);X8xx|3hh+#`fx+uAw$if>hLU$u1UN@I_iD9_v*@Mmat9%7I*w1pJX zWAcY;w)RKzttRCrxZt%2ou|}$6M8O6)PAN&dK);0%tYm~ZJmAO~#how(O8yk8!eID66^an5YkbQB*PGNGojm{qscog|<^`qe;aZdck zdr~d!hM>4nrAQq<7yr(e%uVfNHHgGN2z#tU7l-ervqbRF%npf-Pv z)8A}M_xI1&*afo$uBux~nnf(7?oc9r79O?_O`s?zf7h|WX4j|&GN(qgqr#U3okK(pn?PW^V+>knCHAWYORD4g;nXkB@#77BnA<;bx6N`Nq_(prq+i!!hXC_H{$)l23Nx>?FJAUOS+i2?L)XaOT z^AyXvg^@R0?x+Slr96|^v+vAD&j_7$GRMnp+CHig>hdDgX(rNFQ6kSO_>Gi&(Xm1^ zqPZLvPd{8T($%ewJtMa|)I7Hq#!w;tVNa%@1e6 z7LOXIm+!ZYYLyffnH(P~cdl@#d@7ufvPzo&NZi|&IW6AC)^4^&7I~t|Yi}jz^d#K! zWe`6EJ#8Y<6YT^*jm#lSf3i- zhLHf~XQPx;{iOTC8NG{!S&A-3FQ5%sogS1+{7TMVi*=G~Ji|?pTpHnmUu2qAFK1M$ zlMgv%ALNk={mHZOzEiQCI`N8pl2wuQUvRUeJ6Q!Ci?TCm`LE`FL=j zrwS`?Kia5qX9AK*=3Zq*1?ol=tcKiZp$0NOEIW{OW#Wpc$996!3I9SQ%g^zA>6vag zrB~8uwK^-vwPNpHT+>c28VmyNdwF+#DlE$nPDui{P<&B3H)oh*8BNq3$Vt)9eltWS z9I1npZl{p(G&<2JI$X0U*ZK#Y4i{);W8*h-}<8-PGk^lz{q0qe01A_M(aq53k>zQ-5-5!&ZG! zt(Q}~wmW~43@eO+0E^d1O=jeVGKM`6UJx4!)aa^LrmEIIMxf3~0=V0e(kVkgS!HHy zn+BR7jCPRIAiQ(Vfc@x3GfLPbS46gE5w*x6LH$_+IlWJ=Xp;%O!qgQ>VtIC&lZeq6 zYhV)lH#GGERpV*stl@5J>sEXt2ogf*cJ(u%7BQsv(;jxHjnBEkG2$akm_ft9dPpBNNF%DtQCg( zq~SE2%{ql>JcfLBlvwKZChsN7sVkDbH%@7KeF-4O_MXO#O_y+6D-gC+;J@Q3npdE9 zd_J|7UaalqB3T>Z;3K-fQZ^(HjVK}Es!PuHhL#)`Qm8D9+}k3PVc@J8Dv3`QFJldA zbsqXLw{y?9F0Wgox;u4$vTe?U-z-D_Oh*(~&X*TsZeUJC?YhfCchgOMdx(k*=9k)O zo%JG*f?6x46U_^K8@2`_MC@>3)KyUpu zA*R9OSOBcY4GoOdk>*2w-q+i=BwrZW>|A*9BX7GND(g*>9|obTb&pTnGdcK^zDNPI z4BCU7D=MX_GvTdv&jwycdUNBG329$6zeWujg&4Ov1_E$x;0PlSxdV8&FZ>HY(cMcsP&Aa zpVsXMppf(`T5Q$dQgns7j8mcJSK&qm@QrA5sa&Oz$vLs(c7?AML~$j%kOPUT9XJr5 zB9#Wn9b^$c5@|^yX2PbD9juf@o)*M9klu)77HsJFRdE$24yVjKPK}u!@&QTweA9-X z0JX9T<*Uds@3&9D_s6#NO!VBHigb_n=!u<5bWfZU zxmytFP}Aet2LkMutB-uw89x!mugI1PvD9wJ60$8M_<~U*_>P7omxN?idVYhxE6KROcb{UYZ(>{GhMq@L(X;Vk zJ;_tFS>t{D((rlcm?;G@`c3mc9uOF%*ro4<6!pT-KXCRIm_&|!4HY|&-pXii<%!mt z$g9~1PV44M8C01>rCB4Oq9L;!+D#WOUys^rp=>2=s>QKJD6Te9f1&=8zyHdstBjR< zGnl5ez`}Ivk7dC*Z;(qeE38<#S24*q**#9R=jqf_d+(7D8HqvX(B90U+1F3Tm5LoE zrq``lcsJj5XxvDlA1|MNh~xB_L~vWq zWun>_Sb*&h07R0!PZ;L`y+;U2TWeU+8H}J31LEo5V znP-$uPYmrLcMJC?Q>sH745t-+eT~JLBlT&;iDgHNr`=AV@vR1ok8YbWcfaqS7;|B| zo*dNu|1ofr?NQ|vI=Q?ea6H#80Vn5s<)3CVr=JTW{QmZTBakIys?%=;ryhMkT`vhk>U4!Lx--B-px96UMGicv;Sijy}10ZhTp=3hW zxa{F{KbqJEKs<}4A3|TA?fHNx%}D%U_VKUIl?$_igFaB(2jZu@ZA#@pIf;9z1`y%L zyYH2_hTqw66PNqq+V}hH#~t5;aI0rv7 zj7t_m-4&$5leZ`q$aAs=4HE(r<<3C8;s^cFdgTURrJ*B@7rZ5#4)3lpR+X_u8BWHSri*#PCu1w4o`p&%6r6<2slwXL@>uqMOq?11d1{L>irHg6o9f z)3FiM{a%L_?>_w>d-sK%CssB--m@F+oR-`aH85%55B`7#0v);ll}o#TJnrBeI0s!G z3aa`e*}+{=$9oy1n&S2D6X#uF7wUsX3E_DVl*QEd z^>{Z_Q`YGfs&<9n?1R0Y4o%UlHu8Z#6Vcf>S^OcFmipgurtI~C6{>^DZ%vhZsHI6a zd!1oeTsk5IUuo_v3mYUpBZpLiUWg38LigFAdRF@Kaccd*V3gPt_af2O{B)>SgxGya zz|iDip92YubRd-5?E$r)E&p#46x_6Xw~>tFx#mK2YJ#Aoq+%7ccxhDw$-PNiFUpn> zHcvv8R@cjp){#`}j)z8J7;UV6d3dZb9;gacW({DSKm9FZ?gB^{V%p-Cs#<5Sk<@Lg z{l>wGu%BP_pYVMcQMvg!u$(=i`gHh^OOKqLRktrLb*^QO71mu43(B|*zW3xR;2*Zb z0G+8G7n-bf<(6q^@1eFrRmrK!sX>=LAeKr$$@ z5W3f17kPIdoxkbO2L~$3)#9$*Xwj?v!Va}8C>us=MjkjPZ)6$&tTw5G4i`zt^paOU zEXSC0xguX7&$11%rN0KbYUzyH9H{?&y%o&%W>lH5&$8(UZ5U>-vo&-(BelT)0HI)%WFfkki0NL}sdaaYmCM zYk2emC54c_Pu<@y$NuO1NEqj^Kj7g4FEJjgRq)X^ zrhuxp0V%W4w&fh!Nn}8Oi3z90`UkVvn#DePZPlMCfLDOzmwZMKWUm_aN<3~h^~b)`YTYRNR`jRWY#*w%SSVcny(L+ zvZugS#rQy&S_D(xUPO$`ge;5W1j}Smkw*p5zjkmX{~}hczVe?>4VRY^u3P{khqQR+ zij?2Zj0sH6oSP6)I70(1p2=SEQ%9`yr3RaS=7Wg&88BYj2M z|2?-5jE)qAxvu=Yd0gu_uaBO1-ds2lQo=S)p?iKv-Babx!E;cC&VcG*vE7?rnrlJK z!-7H>xN1od?J|5IZ1|!)Zi?8&Ho%O@Kzap5N}m<#J3{RX+O{8bWJ=gl5+oRaK9;zSCgOu68C=M|0S>BEXm*N>-|p-?x^9tNoHiF)_3yWwSQ+!B zoP7>)^IX`%-|*5V<=sNI?tbz1=jTAxmrZ~ORUW($Yvo8!Ol}ZoCVq{9yrB-dQfQzt z;H@z8dO*l)iZckKr_7EOT6ttdj#Vc$)H*o5DZfyTa=(9F6VmpS&tG|(pKg5luW!R| zfg7{je=nO${i=-j zg?szN58?UM3|o`UUuzHhquqN9?VkZuqn-A9->gzO9xtJw zBg5}NO)p1?m->P8D}LIZd;j+nJynYV;F4yM)&Jg)04|H)ug>oYADQcf_55i@+WeOB zUvJEN2rX3^-s&uj$fsa|JOB5~+dxX~y4(3r zRd`T-SsDPLb_qU{Bd_+TEf{IhF7xipp9?L_`b%KFwpNx@ZPh(T3m6`m979kE|v?j6zpM9=|%=Sv-YP+PLqqK|#k0f`Vrn<8i)EV(cC z{k+&*%|pz4%*|v0xxfNYARqz-0u;aBf7_x+f<$GlT)8qU^Z&Yh|K@-E_y6O+|K~sd z`5$L*Pp|&-pa1p${Lg>>x90!;-{_J5<^TJ?8~^!l|L^~^eD!sC|9Cr|IRAOkJn{ea z!ZPmM#qve-^o3>Fv)Rkx*dER8`^C$tv!sXU_x8w{@)IuHf5(%F{la?PereFJ{q&rk~HIOJ_oV)5G-N4+HwoSNea`_{VJj)BP{{=h197alSa$@5c1*uiMS; z%Vvij{^Q--j~C}JtP}e8Wcc5eA zU=X{%;?XbT;gW1c7+bH+A5T2~))|lPaAnir-`v}HGC#1mvxn}3|9bBsd5Qe{h`Tv= zU3x!h1?6AkN%xN@&O{h2?jv7^?CR;S4erJ~*e`kB?yryc!>h}Wf4x6hK=<%&fo76HE%inC)ou4al2fSZ27M@WEV>VkeGA!Dx_&xn= zB%b%#nK*Nop7D7wyL0AZ3!d6b+Uv%JOB+l4;)4G3$7DQRJ<`7PFH3jIzq0=({>NK? z2y5=Hrb9>A3+o<^6(LU z_~E51o(~gS-(|k>;^_`Hjd<4P)nD7d8;9^^IsZ-Hj$hvC^UCp#Yw;x>*5=!7@l)<3 z)9sl2pv_xm6uh2(hlP7A zIT#bqk-G7$>=0UJY41Q&wmOU9sdBxdy@lqM9J zAau2yAqfclqdQ;Txg&RKPhPDbJr2i}>*t)iB1rV2$?wi``J2@cd$n}Ku_ndn^WR_j zsooFY=m+Cvo1W(Vcq(E+5w!Y0i5ngKbm`2;6f$~hk@w)^cq!hCUrs-XHxu;Kp?|O6 zN&J8}^4Du-$Ku$9yPA6eGCe~X(luHBS=#dviFBTtqJAP9g}9ym(>#x|Ij~g5#dBw3 zFUP;+cOhX=5#(lh@AVZfT~ZIpYB}ug!;y)5MBlz`u?NJJ{9D7X66T&BQR8A>TpdLE zn?GigWXNKpaCr7S{xAvg-XEV12Be)DEYtXEB>hYZ?gRPCL?HC>aX9`(&+sH5JQG?H zltf5H1l#y0UJ||dy*(v4@1FKd<_|#kTJaea4?W>yy>*vILt+RCE+BX~bQNJxl5{0@ z&AEL|Vysf6x}onV03aq)-H(Sup}`%`9g^MbYfq08C@~Y(?(LcO@r(8;Jrc(N^*&~V zj451}!I~{!h2GEG@|(>YTY?1VK%T-DY!HO?dVD?2yPkKs)$jWE0lVD2y>g8O*SHlj?8fYEd%FS$#hSO{v5g7zm&q%54s2uhf@+gL zc?2o6)0N?oNX3w2oVrtiE(>!1%h!~SqlW~#B(7pApWyA6N+*yyE0IoQ@$kiaYrY{m zob`G$e)%GgL@t5sYI0%;F-f!$rHV47_ zybY>O7EdZ20=e<;f01TfC+lO^u8L@{mjPF zBzi6w`aa>z>;CNHpMU-}HLZ);{n6>?uP4{-27gZ-MC5!-vG6o807?zSGbrSrW zHqhidqGN|6Fi+N|E5E@bk$KDFa7#@N*70EQwc7AG}>G%Ec?(JZB_wn{~^Wtr5 zd4D~+YVg-d-N_b9-}}FlHD--3H{_S9zK4SYVCQP8vhj-2m^ z&Yhf0$x~ITt;yeN@kdgnN7l{RPg%LTB0d6Driu#uPF5mmfwF@loLl#?@8;Q z$TSK}}?7`kd*aur$I?afk{~$zsi!74JG^& z{Yz>g2okTU{P)>Jvdx{S93`wEj@s>g1cS6#9`}%RVEg3wW1?qBja@Qi*w3anbMMHR zEm}EUIpSz|KuE)mD0p~Nm?9RtA_u>CU&R;~8SC|$bMK%?bxgLy6Xe-7 zNyj>m{nHtSpK#YyrH}LM>4zB;!8T@_S<0zJ_p12e!!Gi29FFzb0wuC-B4U%-Hezv@ z((dDK_zfL~F<9Eup*<&%Gd>@kUM6B))r0ToYFntBPg`!7Ky{Y8MfY0VZXL`0>X9nc zL<>F3c<0W>q9NavGowa*fiDZYxID`aIM{guzCPBNkw8_Z)54k35ES5r6*3M^d?}10 zw+44Y=l)25YtUhLI&Hr2j)7C-)$8w~k0*6WrA8>E&`GvZoIVFzsfO$5w^*ZPgJ~IY z-(huFrVkkmD}WWU7gqA5IJ}f}(RN3{5_v&t7~RU6Mru8m$}Zdy9Z10lK~P}d&qzI; zUN6L7il4o9vUKh@3>Ch&$qiUn&Tu>@aEc<8=jFWS&1=6F{s2YzwQ6FO>hM@iu&S-f zFGW_W1n|lMLL6bIYI$u|NB3U|g60r!Ws-aMtLX|N-Dk{J6p?NVl3cafN}G1O*zh5r zRVM^M(moXd(9L=85de22w4??3{|kFMzV*f=Jfq;mw2*z>5S^H9=KU4l?;KZ^8=d5E z@L9`FpU?K*Nqo8e3W9m10(6@L%6$Up;lIt1`Mvdcclp=*_otsf{OZ1Wz(EQHKKoK& zj-sw(ZOLBr-&*mCY@ zgW`(oXC;D~Mo%KZSSNOY1otTOABQ zGO*krwR{Xf{ZTpwFfZMI3}BgF2L=p&jAt`WTz#3-B*U!xUEK9*1V`8yG3+QlIHH0= zlm#=ZXzi4YIQwSiF;kCl{tuy&%ntwD{l#oiC!M1$B275r3B5Sx<{YqD3= znN;+QNJT<8t9?R3Ww(uL9R`(x1MU`?CvK+b} zKK80S;EY;qndz4y5_v|DFufb*w4ReL8rJJe-rhkPAJf}=J-*IidVBmn;%+9azyE7IDK-F` zt(tVZl-b{k;o0mZ8l77Lf40-x**GL?P)^FUU^XB@rApgMYv2<1JZvWEjAnc= z_j8`D+ir1HlhcBL`wq>?nqNIbcxkSZgw#iXi4iB3N9sJvfI##ULgRzI<3qIG<7J98rh zPg{%Dko+*II!QBvC`959>q2SIjLApJl}J7fl{*5D&Q3oJZf_pfc5u7Wco-kc$+nk0 zx4mgZ_ISl}>dF;@^UcF{lREf(wC5u+$9}&Cx5tCtpa@hBY^oRYVmNTwMPaGq<cOkx)SYWZ))BDT-{2-ohM}m$c_cpqqfx6To`Q3JguRa)! zv#;*?ZS$r#82;`2qch!feDnoz%an;huSQ2_Bga2lcUO*tB?OXs&;Q-PY0_ z^DWZrjyH_P@kP*3cS!%C+^3Ol#}jAqo5oGvQ;2fyH}~`3ntl$qItd;QeGUPtlJBZq zRSDX0v9SlrrYv%y`mW+kp@2kN5-AMi@qsfZ6v_&rm0NAA$56`49jH_Ca)Vu0e7QMi zCT%X^u?BhvDF!l@R7?9!l-8oo_EZ!yuYVHv+5ahxP;ReJq1*l5k-QdWEwQz>07P(> zbs%|aMpHm4FA1xz{K7X8!EWO+a|>h}U8eu;m^4yPm)VSD4V6CAQlt$l7+tfpErDp* zXKgb*V2cP>AFMuodVq4nqCy}QV-Y-*7)XoHmR>tqw8V}v33WA{kYU6RJa`k6pE^J_ zr|Ga$*niWBXCU*V&bE47>~K?b^F8qc=-&2ZE;G zOy-@BDYU17Y5@^Z@sm(I?>`eHDZ`wLPqU%D;m~Pt<OM>-?uKD45z`F=dj*bBHIY%`pfae|s-Fa6v6v%K zuo5H?&p#f`=k5b(8&g+I`8$sJ%$Qfr;StHAgi)nZZ;OMOz2{Fz*6G;eAA|Jw=R~(y z`7Is^&|4PQKgwIY9sxQ=!Irzl^@Za(U?6K19!_5GKMe34(E$USq{F&x|8|dgT@ANC z16SGGKboxAqTz>H3*qn~)t94{-TrT41XLOt_lKGtsFKy!bMo<{r9V-`n;;U3Lc_6c z0rTjCU{@7plRz1|dLEb&l_EPDLysZS9A0!VXj%pzJPv{kG$l&-CJ|L12rhQ8TrqwykxK@S-~2@HS_G8Oau(GpF zq7ah(laB;N=}Am}V9DOAyvQiohw?$&hbfTdQyI>)2~(QPz9rKsL8U5T1#vEH?>TBy zV|#+vtBIKZUH#6S%6JC0T|#B@VbnL3IpB|?6_k2?G}c*R0NQgJ^$q^QdGEh`6&v;4Ev&0FtH9+z9YYr);BZ?}orY*=7-BtU7@KdXkhI7;I1Q!P^hp8@>KpEDP3U1;M=1 zSMb?{Xvs=nZh$5-_RK~TQ-6p^2}4`aBe^c{tWoC+Ca{C3XB$oIn}&<;!RTfl=5)Um99cw{h7#pSh93q!p#Ktp6ug}gyOe?ieja#(LRnQjysNE zGK&NORUA#MjO5!pIcZnEp1PghR%u~qn5(lFxlLunin;fSd}18v6byDXSn@jzc8%XhzuvZaQv1QKzivi@_g~y2^WPt@U;Vhb>)v!;>Fl%}^ou%anMggY_5^dvx?wDvp zKBjobGM?4EPFMsRNRTX$T!}IlW#NU@L677#Wo}pUJSQ@?QJg0kgVL1*J@2by44jyh zWlm&Nx?Y^Tl~YyfC$c;gk&u!i9Y5Yd)UyK}XfGx*Dp!J&s0tk@ zH{Km4GEx_xpDUO9_;~$%YCDlpX*?+0psqd+lpH^Zym6;f=VobNPgwl*a?@MvZ+=@k zWnK0}M$_UlVfdqpx1Ck45N5{c*x#SW^X1B(T-Y~vW9l}#J}c)VM-kOCzA?pwUDBwD*V5TZ z`GquD%y-RyINyW--NgA!HsM+hUEH{2THs3r?3?;&`f^{W_gz6nM%R&nbz#5^WX8~? z^Qer8dqy9O2I5Z*VN`WIsGyY(5)ic?SjQL%$p=J3UT!>Aaj(hQgR;FQ`L?fO3Y}k< z5lkvBXJDNgZOb2BlFRS4Fkz34FsRl5W3NMX#>SP<;rC7kXXN-k4{A%;n~{8k($&-i zd*bJsc2w}C3yq%MzEQa$1ossTD3!bKYahR8pL&h{g?p2g&W&3)7PwnR(USXN&YRe8_@n4-s$3xP0cL?U4EyKE*)Xmd2wK{*uL=B0{WNN{Y0$wcp6?(S)8s&y4W!*=PsY=sGjCFKlhP#R+Fj8z zhv(N5dYy>##d)%kr%8NRE$MB<`-#UF{$Ov?{hP;$F@7vI%EA-W5Yoi*Z?KTc4GL27 zxWk|z-(FG$Am}=&N;7CyZ3u6Vp^R<0Yw*v2vD#+KFzuz>3~nO+6lY?nr!LXNcB3&C zG07A(<+B#A27; zN<{55PzVz(wk%$3JWNr7&`29FtJVltrGxdM!S!>RqJ*fQ9V7~arD$MhJs*4>Ifldb4@I0p|MPNczxmvv`O6u*yC%8k#BC?Kk5n<4lAa(zvm;e6n|Kz-J z?)|T33P6QtOcWGBX7#2hsSyC`kW4IVg#di;CmjKJW9&Zy@Er+(x-VMhMu2BJMJbYE zRs{yi)<_^@)d?g~xmOnl58i&*-e{~@;VDXL55u}v`U)%Ijf1GxH zy!tu)apSgL>uil0Ov-uhEFawY4^n<7e&?Fk;p6EF7hg)cDpuB!l!eMrM(^*0?dw9Q zHog}@c8-TM_a%orsADf01X4QK1w|6iYy_CmtLF$XHPUMosRLj`l=;j@fLT$y=_1=9 zB|4Saji3z@P-yqrjn*?!tI?DyoeJ^!qkW=6O31(+QFxQwoeQO;=ROVri@T1x3;|PH z0#mPY15>R-z?9z;h}(#z_uL)rrhmqme+TMYE=B?LEJadUt!&&YTa)k(#Ap2sxjW%K{ZB9 zHe(>UG&M|lb8sFi6$)`MW}l#N`slp7Ia>a#3ojWNFA*Z*~l(^C&_yA=d2`cH-TF@x?Sq+l1 zIvfEoT3|kugci*>tef~k%%Z~}BkYEPv{jVa+3C&pz3NcluGNh(nRN(!ZX2O|Gh z9O#S;^Vo|~W6G7#*hlm*YHY2l(ZA|FYD{T7C=e;76+!8v#!TKD@JAId?^3Q1VzxZd zP?7@75;R4~hiPM!k0A-A)Y2REdLvmA==zrMu>;-HQL|4QdtwTUx`|5zS?DK``a;+7 zb>2%f9T(AuXgZ#$2ax*iae6PEzwi_5!e2~i>>Q!hvahOo$uw3QTsha&EHA6>Cv2hg z5(D);VGt;x#K3rI^)cN8(Z9d{4mH=pBdFJh(L;w*{%Frfj!>;XZ#_vb_o=e$$Rs`g z4KaGOu6beKtl7u|ZBtS;c9s=>ng(iWOqm1%dF?0Zg(dGmo069s+*(#NtCtSJIJO;$ zSW=bJH|A$v1=E_kMM{>^m}Cxi$LjyyvAdSZ-;BYjmLvDnp0a?1O;Y%JCB9$hzW{#u^m2MK^Z^dzwGeHt=hBN!_e0k@N+^Ib|cikCBrQe<9^7p`RP-?H1 zE`_6a%X@UtcD9ISw=HRp*Lg-~cs+dzpmL958`q|mIh@z|aQ`|djD!hjz-c8jR(IdvbV6W7ix7>9v9rBF1{$;Qkr2YZKB zz;UFBDJu0-JunAEqF}-s4D{x~JcfNVpSuqf4oqD!A?G;Cy5oE*acSk56-vmlcvq%U zZ-iVWdc-VdxE3xW^)@Z59XW=xKN%}5nhqEW)c?!RS<_b4L!pROj_&!+0&Mo;ZXjMw z43;8e!A_?EDt$FhM<;H`ZS+J$_D?PqPRp_cN~I{*;i?-><%m)n5fzA18}X~4?j|G~ zZBJ?ty{D6!^7X`gqz0!Q818C0>rHLjJE=M=!NgF|ULtSajqZp^lsZW1>(xXIVXJ<> zmW{R@i?fqDU1q@ub@uEqZ;hNg{wT(3sn>_SfDX$=EBxm)Zw(bJ?4;ncWJ(U%SteX~ z83e-JmqG)(br{Cp%v-~<@oLv&-kKT*3OM(jR4O919(+dg*3hvIwxNj5l^scUJ8w;G z9LaS=xrG?@6qR765*pmDJ9if+(x7|94XHrXprUy!NXq!eo*YfaqbbE`_v7JkB2?%^ zt{kH^+tZhRmt8R%jB2bx^#&=a?Im9PQ$qS++ftvz#Z65hsKzmjbL41LZ$jfRQD2aWBdIN`j@J;;r!U%3n928I`+SsDF79oF;P$i znbn)Oru2&~9JP}(e6>OV`mo~jrXv6+UiKdW_>Sm6fM+^yt;Kop4S|8OKNP^YI-(M0 z#Y$PcN;~)_^Y+8`MvKuFAAhXN3W9m1ui$eD(Qrp}05p-YXEw5mj<&{1?cy~Sb%AG% zI^SVr6-^T$rpOiH{fIo=MS+WyDN@SA!7=#?dG%)^_ko9{`Vy#M`%m_hD>QTWkCw7V z`#7*F?l|f)uu2`tvzAvbFWiCTpY_ZDz+&$)0FF$-Cv#%}*FIf2*^dQ@`(2GbQkdfy z%MofReL9S)+ICcx{pDTz&))l+?tJ=ddiurresN(nSjCdyEL{Jer`$MqQy109sR+)5 z2S%g7RGLAh{MP)uRD$DoOxYsWo%y(>_Bzf@-(LY`xwDttFXhse4>%TA%izn<3aE*V zBHLosIA&>KbOB0Q3`L~7tLnCrW;-37{r&T1cyzO{Z>)d*JvZOpT=Pwc%yzOG*Y?ei z)vPh{=b%_G;y2!_W1ZWxy9+vvB#L~8e5cLWR43EQG1iGc;nH;{%kgYMl`Uj0{NRl{ zojNy5|1sYGwm5^yPveJf-N`WYoEaUS3cZndU_iw){3yRpJo;rkT;BQ5?SUZ=Ni@PT0p- z#yEO6=He)sd}FtIyWd@N_~YX4^xwDh;rValPxGDAX{gfV{xP`R1S>YA$M|D1o~|D0 z!+)XXon!_7C7qA+FNaQqBJY*xA5+d_qx7n3gL@j-7Lp8Owo$q#SL_Bo?RTQXDD4Cv zQ{lcc8%pAQ7R>*8X0v-3gV^JlNU6!@VJT10;lT=-2Sc(B^Z4S*5AvEFW>$>zr~zL$$5+D zaiF)m2hPNz`}{XzOKE3flTnSN%mbo&;O( z|Ia6heA1`1p>f9rvD`my#}jAqo5oPy6S2J({k4;6t$$5=Ug(qLA-lT(r!Jr8ksT3I zjFkZ=wH+QBY)hf5`lxF_Il)W8Hs$3;I8gEBWgRCYUPOYX$$BB+PW`}s1_$p(blqwz>>=NvzyLy5tD=;-6)xC zgF0x}XS_6wNXtHxVkzd(>+X6Ug%$|zQ|PpaZ##jKSo@_jACp!rT1a@8D#4H}j+#ph z9mSGr9R{MrAoMuZK~oMr`jdO~s~3ZJb&P2hPxy_OhaUZ&fI_!iRJOzlPt*&=F2|cVi=18 z|GOyHknz6*tp|!f@3o!hBjG*!bD}b*CD%V z^@IQM_hb`mA~OriscnwTN*0Vml@j5a4S$v=F~*-OQJQ^BXpMi;zeeJrv+2#;xu^V> zElS`wp7qL9n^BzviG}m@(IT|s;YnzTbeKm&iUe!UO(U0(LxMXL%dKG?%UikW!1HXA+%(NBfkO3KajLgGtF7e*3fs&3;PHnYj;V5jGaXrj(FdKeJ*QiOTE%cg??0@ln9LoA9W9sk&7CAAgmb*X=Lua~ zkwvIRa|vwS5^$H!nl;`V3z0V{5@SPRTGl)wmf7Hkm^3$nAb5+e`Gp5pNrA#8QEClhLKF@wrK4 zskAONDr%Y{3J&V+sJ!s~>jC}ugMMPNbIMrrihte{HUUwOFJvUs!YWcw?v zf!0GTiDLI>rl?7SG?4i}nXITEHJQXS8<@anznDw*`yA`aMuJH|a>fK4v^qATQ8pJx z^A}539MccT!~O#X_3&cjkc|P^Y1tTp9xc_e1~%ie<&J1ivn^x`B>=K|BkRS==bjkcg!vvo6xXhl4N;p( z2HK{sXE_M~!<45reo@cpV1hy7!pq>a33Oy|Qf>*e{PLZG(W%Sd0O;i3ni`@LIHC@C zifL#Y!z7v{I}_t+Z+_E|)1fmLJ%dwJ_iJ}W&m5j#PuQr%RNs*&+<#at>21XO31j!G zp-yQ;O7l3;ybHuN(`1nXxMnG458~jn%)Ib4*j1@wt8!28{=3MG{*If*KWrWwx&RZl@wI&+2t9SaN@W`A0;n>AkO=U3aRw0F*c z$_TG~9&hNqk8?C;gzKCmiWU{tBuS(+k_n#wyfbq7BerGoE=4i8>qiWb|z zHFn)>$vRf}`D)P}gBek+VtOUOBUw>)OusqDmI>k2$CtBa^O?Nt6G>Cc4g5v-Wq~n` zR`%h_FV0(Z{}-5@_`WPKDymW!n0NX_Th3Q0Z&GG#_Vz-Sg8WEtgUsfuy@Y7f_s_%KlMeczeT{|#$G!n5a4BX2TdWu( zLiCtV6STSt2N9c8w)1-KQo(2Z3wpo1e|$5yXLlFw&>@2J>V+Zt$%sGRZ---hG`H^~ zzrdrGff={vhs)L9ulf_`!>K(q{(STBadhS1`>9QhM!cOio7mHa)tEcp`SQkSMgI`b zkuQo%hdz~M3<16!^gbUl{`Pt-294(UEF9E`2bdpoQ=72L?Ab^`VvFMm+juJY3%SkM=;`#p7?C@#qd$ z4q~)>8&BqMLY28gkEYVM^B#)dN8HVX_4j{`C*40r<`(mH$bJ+{l=9l(%ddep&)a=; zPQJQ><;~IK-~V2`eVkt2nt>Rr1CipLGX9|RHmgUv7hmZ34p~7mb&HU+a43^<=yTP45SZOg@h} zgt$(1Yy;N7#?fUvkc}g#te1_WgJ)L9IGDZX!H}c?^9v2vnYcD-?9a#xYTSp*PRmVCCkROsb??-z+a)|yImu}`P%#&P+kIgZfOF$S+oh0#wsEdE&xc3eP zX7r(%jz!WVO?VA?snJ+RUTOfyPFA|}*#G;ueg03+`19mV=kfR1Pc!Jry{ixyx!i9= z2QwU}q4Vrt*UzM%#OpR6d(RdrE6ha>jFtYCQ)IGeseB$5Jra#?VSUw!l$Ewr0O3eN zjVtGx=x0{0u@ikzc}qAPh(S+*XH6NBX!o?+Tt~njh*3PV)nu_q9~*^&gH|tmv3kjY z%8kk!Iu9pGvfs7W+f9?~+wsI%{HErI_Y}$PWykD@OKu@ZtF%j2nxW2eX~b7S(1hMcfj6PGenzIBuGCAS7|AwS7+&>=^>6j)untTNZ zenr8j8C5mO~P4SIY?l?-KbZTVEpyTdGqtwd2O_A zXJ@B0>FeYHm3oDu?pFSKb1_!P>&i6;ofc5s2VbI2X(RG>gTI)|xc~U8G4K>^%}?Ej zsV~R}SQv)LJgJ&QM;rsN?dg6K5}Kd{bU~}fcdUkVAKl07$%-@MaE`ePeWz5)(4agz zRrss}yL#332D55-rRyBnF@4k_Ck6S}&x6^WGbi$6h>cEvUASIcuPwV$nPe=DHHnVG z30f9Ou%MiN(t$LvlRS)?_Aw8WXoc{51HH9~iQt_YjpLL~YBY{n&Lw*BERH6wV>3nV zS!7qOe(=9Y)hlF0SdRbwtKA`3X>dqcD&Q#;DEX8DO+z=lGasNEnFnkJa8rRg$>dtN+#%TsfedZw1|2!4^6!OxO?z0H zT8dewYjY_sT&otO^!v>yU2mZnPJ$Gx&5?b`X1LC>LMFqCxwMr_VC%Aq2hGmY@bJSr ze-d=W5DAnVET2~+mF1&hN{K9A07-g*K0Sx)`!`1gBF`K-2B2md$y!}*usECE%$<8$ zWm^#FqX#;yC4+_MYZhZy&ZaykxIpMtL%2|tbSQ$I>PGvDj%Ld3(PXZ*|2Uvg$5oRC z#39d`Gqe?9NDGDc73T~pJ-AjNz#>RG8Q{IK{~!QaC@wqXCIc7tbbRX_6g8gDjyJ82 zV!*xPm=!{YYHxWQ0Vy|3$U*lx57dR?k{HaIP>pyoxWF0BibDB{B<6>wIyj4kx_xqRYGl?}y)C7;K2bO__7Yuwg3CA) znaW!`)JU?pWLF}IjXAaLeG*Nhk3m2ar9lz|Sgk%CQSfqza=Za{50|q0OjeUWWw~s% zd=SW7d<3-Ee-Kb9%;D0VtqUNypy$dFEj_a3wM(P8@-ag-IwD^aZT_I8at9^rV7Ls; zni(!vuCW*uxi-+LmV}pu#9iST@~Yp&Nwjsh#)LGhzD^S`t5njnk4M&ib>E(^UjGOU*7^$5Nxyb|7#!Ma}<*>+hn~u~$j>{`G)r z1y9bzU%{>~&K4?GjT^7v?nBO!3@5-586!+Qu|gohHm}8Ugo7XxiA|a<&Nj+$2{h3w zT7O+ug4iAY5yw^&srvjb`{$H1*o4% z-HegsKbfqklMUI#Giz$h#aGNE`z8kivX!7PTlNywYlq%~BB22@#NqqJ(iQdk0e9Gc z$e`{)@zOjcW(2`Tbua@T{kiKM9cJCB+H!~e!`|y1xFZTSnVVc}QaOmk%0td7A8Phd zJtO&oV57^v05N=pHa`apWpDn?ExQuqfYfdr*qiB_m@|_5zlj;G^lV}+Za#7O3oLmF zB6{X?rh(jI4L7mI!lziYzmd(+M5>u+=5_O%h9yyp2+=1sJRN%cEaoKpAO4F`D(w2;_L}R+k@@5MQwf;=>DygIbox9S_Z4XJsKX;>}*=YQ6`sU;EcGUaoe*AO_bJM{o z-nvWb5t5Zxh>cx(oyVpf7;`|ym)B8WEVIuV4zm|#@tTV~(7Twg#@B9O1OfbA#S82@ zi{InF+kYtPJCSJ)s9WY&HR^2jpH955nEa2nxY zgbXdiR~sjyITQCzrii_C)InLaflGg}0Z& z|H>tuqc*1k7!;(+1O>jTI`~pRjapKR@_?VzeXJ)|7mNc{WU@O^(b4LyHbbSfwS*Qm z&^yi}u8>7%aVEM6Sp`!tb2nTZA@#b0Q3`W(}u>!J=$* zLA(R#@V{}jM|>z(V#g=?aD?xh(013y`?gefOR!v^NQsuKUC~t;2wH)9J=d<`HfL_J3S<1D8i^?MbB~h%C!5R6F z&x1sIU3DVejHo#+3>m5)w>peW_nl!nXX7|Gm9z2l_TKTCjB*k!4@bQ2e0k@N+^Ib| zcikCR;(T|O%ijZk^qIX{x9B7u)O19B!&i?U8`Qvr$1wYR*`$#wX>*yQWnj^052lH7GKq|$dR%GzuqpPitn;HdjL~kd1v(UX({2=zu zD$Ul~YGj0(ni8-!uGrFkPYo#{_0(alQ+Mbz>=Cu3l~%f5ojO|LZVEMlH6hjco4Twt z)HDr8?t`4y=fUjGnTyH`f#>wsg-bba`uoz&Tu&bk0#lA|Ri=YSx6_ICbWs_L@;?JgmgfCRawR*CM-W^@IQME@nJxB1sF& zscn7?K&x;>p&E&Bc}9j9DLlw?W8>_)#Y;#X>5rEhbl?XXHC&;;Sv5ybu+KV%XvHZb0>%pk~%1masc*Bhd6bcyD%s9zi3*ps8lcr+!!>V7;N(h%)( z4nuc)F%N4YODyM2fF#w9u#jxjVI0z=kazBEEO?kdCq$!-?7W3qzaKM?Ak8M3N6>U3 zWFD{?z|HOn7>0N&>?3zzrk-gVG~j$jbEoJOYm~LO6{?NZX5}knG#naM$Yxm0mhip= z(yn#njFQ7+oK$Km6`QC;vM-S2^^47v-#ZM*Bkt3l$xpM4@sJ!YajuPbLh09b7z@Wzc z#{i8|u9`6b8J;&`Pz|bVp&ehv34=-#t`!Qf1d@sZ7H^LIM*)aJahX4N+;Cyj+({Y| zLh8!XtDnwpc0(@ZJE0mV(?=;o7vY?iC`ID=Hm?~A{5$IDYRE^bE(Eil-8G0 z%Y!)s%qkiT(3)#`7}S{OMy?HvswM4ZadB6uhO=qkywhvJA;$HYvM06fO>}IjM_f^j zlZtxgb2(quR0-?_p&n;nvQeAT0{nEOLz+rI($OieW}6^ipg!P+qmXi-4#0|wGtSl; z>lnUwg>~!RH6Gdl`l^d{EtYHdp5X!g72;2Bh8K*CJ~Z=NItUI0ux%e(wh>1%IMuiZ z3AUKR@^a@qCCig!gyO2464_RPGD38zYkXc2IU=n~jpX(-pGzMvsP1>!nMv}qvY#+2^_W^2KV+x|~tyW?Ev8W@dK4*)-lQDt?In4?j0LkA#fSEdG7qF2P#5K3BGML)4 z#hts9LfehUhxci?ax;3My~e(asczZ63mp@o!hXw`fKqfdj5p9M%n>s4OLc_UXnXGn z;qi4K%Jb#I9fOG!Tu*)Rq{B?9Y&_A$g&`29LI8F~i4c&5NUdwcBJ(mjk@`^6zyn}B z{#UNyzzj??tCkIJTTkk}?$Vi$slrdRQpp?K`Ls6Go}qfw#h%Sbx_+PRc}E;g7p9^` zXu1uSfAlgJrbcHF?UN1ews<4lRUJWtqI9F#U6*-8K@)w{d5RIWOBYcGx~i|=EZj$Z z^DYRr^50%^Ly9SNOYDGV2ntbtUlNQP)e&jDb(crO%w0u=2dqY^FZzz_l-jsNgbLug zur-cK%2D6s5|yC#4pqmXrWF_CUVs1dYCivdI{5azb3T5&ezey3d;XklFs)zj zxuGX!a4h(#{hCw7z@XGLbahc(DUtNb9ioX$Eo}-U6rWkjP?Bd4g4{DirdTEfu% z{M|YEy*U2y?c(~|+t*tOu}Av#K~8M&o5y^!*Du zc+1PaQ(RE5di+#f7=^c)q!o-q0#6q-JHzNu;@w}@&n$$V=V0VnwSOGgD^V!X&d3+m z_tx~USCb!u{`j9SUq1bP^W$p~1SZjk9DhvABc`&J44u6H7+qbS{8!2)D9YKyPD%>{ z6fWz=olc#brFT%#Yvsu9Lw02w_IDOhqj_@w7(Yf#-MgDcKb)N?Ck}u|4g1Mz5Pz== z=iH^_cl^$Bht4;1dvx2Jug9sJ(Hsp#xj;)iz;hJoDwseqT8)R!!v9qK#HH&_mg8CYLAK@46Ycrj zeF#78)}3(MQhu`;&4UTONIWp0mg4b8zl?{=JO8;o_-66!x6XKUM~fzI92FY!Cc3xr zWPX536^8DE|1|F*c?JD-#A+rOLHJ3rMy!0DEV4@MwZYw(Q({2+jN+2%DoyO|tT(^D zziR#c>-Oj0=YPKX@V9aIk6Q%NCk@~oNCq0Pzm0_>VLnpaP!|Qv%5du4=cI*?u5TPT zLG^eu;YT@gY{LL$irB-0JBbXG*1&kLBX$g?|2(Ux(LxC;8waFL**Jpd$i~sZGpl19 zd?;3naa@qc3_``{B`idxR}@0aCIVxSEhGp#t79R_xC78G}l&msq8=6A#oa7y~c8X9q7$8mpDp7Er~9x;_7$z1DT2 za8Kyjp23M9#MTb1FIo=hgG{-0WNypLs%}Ue)#TBEk|g8v@nY%7gTlgcaS{2!Pcte@ zNN)BU2-S7Y4=QoZ2Y@YrjnhU{CTOB6F|&zgx!js-BQoGCqLc~Vw~nC!S|1b&yIVQz zCloiYWtNxiP75&Zqc5FbOM`XA!OdL&aC2Whc>zLv5&(;qHK*>wbmH2XMUyZAP08Ao zLHC1+zJe3b1ue+u^`rY{vZS87RBuWp3k^z@Q*L?P`o8GuJiUQk8?2UBy2gQ>PZuc? z)*vDUas21O?9Q2s4(MW|(_a^^7uOq?uAc3V@vIpJf9tiBZpVmrEmIkbvQbqBRt6%n zdl>-d>LglGLi(jhFV3=6YB=soFj;uyw()qD_fF)fy%yP3s~`N2zZTDQF zErT+RnmNWDf0_vntw}V8Tg^K4T(fWO#eFO4o@B}`KvanR)mGR|me_R=F=-IhJ9jn~ z49p)x6#!gV@XAxp0vp*m_3HOy<`E=hB=b5bf5*OMt~1T5BA)fZRq)##n_coDa9!}HGm4l zU6OyP3sk7o-3Sk;SEz5XhMA559`o8m4A3azsu=^2;dv8=wju~=q4izG2?Li`hulWJ zQGknl(^0_NEqjOp$yLs|Nj&y@ULC%b-L_-wY#m!Mmm5bL0#S_;f+g3mY&Q10%o zfQHlLg3nY`@U@QpLj~M`5E&0AI=618CuIaa5r-Rl@{OMpFwUmb1^U*$Nv>9nLF{x|84M{arvVoU`<0K?c*LBQWEdk6w5U9KPy z;2MZ4CwtMQu)0z@)hbfQTc1?*ch45Ku`YH%dsyZZn4O+E3y|gFB2ysxH{Cx*3euS! zMy?HXs$(TYlcmXBks4&8ytLH%C|N>cD%%#=6MWYK?9zx$X+x)_~^W z8^Eqc=(evNM*#0S(Cx}^&`2EO(5^uoF7bOXinu8Y`BIm;Mh|*4(Wq1kB7=HYm6V!E#&g^-kj;_b{WNMxYRo3Wc%jFY9`SJ9Kfiyzw&rr6}P{}11hm? zztI%Ro#m|;G1?aA7}!GkD9e@{1Uf~@91>+@6><+uEXodSH}{b6QNI}ZjWDhmzV*Fn|9kxQ&G4T&X3a>9AzZMuO$SPDh4$nQkzYxc4%$V26F;nzH3|6{ ze`m=KSb4{^6H@K|chlm<1f1>XEj;-cp@z;#G#i@cX)T0l1`=sJ9*%{jTewd-pahwd z;!YDmCc8Nk{c7Q3Tf7tD=t@mwC=K0Y{3!$*xVoxPYzVs3BJo=2KHs{ZX6DFqHyfQ- zVox_Z(Zz~y^j`HgI-5ix8$DidmY)P{xzQ2-KZQJGBmsWg*Dc&c#leABZ%@I2?7Z6G z(6p)t4*rhVY!OT6k?KH>@0Ry8BlT45H;})C?nL+F;ZRKbJXW=n4FiUMeI0o-<9}Kg zB{M^uc#xPOgjOboZ3biT!ZvTo>hMBVWcJY_tc(BIs(?wL5fYmOa>p=(w|5XWpzm9rq$c*Fv3n>MGF+{B6Bl4 zjna}Jl`pI&9b9T2SDjzBs;4q>$;M8MLnwg*F1t!jKR&r2&k*n1c;E^3qHI%)pYyEa z=gJjCne1dF{{GvUyOPbs3-l_WOtz{gSO_R27HSmYTjFO(!ceqL)}n%fh37(REm$ah z3$NZz;6qcJ%}ct}M%H5kjm;VH^6^8QuMMo}NNkBqGi>-$f2NO$-LB zP<+8YpjPX=^Xx>*I$PEA^%$^Lt99PF(44Z)6^sKg39DA?ymSAYvd$HB&zNjft92%p zxmzBVvd*1W2mO_*EM~c>-j3+0qIyFd7#jK%v3N-o&7vd}w9chcpPgTcR>_I`T(pg~ns)Y>x5g21l zK(O<@%=N+>>nrlsW@|+q^O|i*($O~3N>KsRke186d5U^FZyN) zL+e%Xgr(TYuFqE0@?;2zSG7#t`MpgA-y85@=K^_JtXV;Y90lRU&+BX7w$VC~zrPR8XA1Mizw&T-p)Iv4RLfy&1Xh;xA_W&W&Sl-czU@Rq%VffVv3#XN+-N>DqKbDxYpaH-Vw3nqj^Q!y^TMQjXPfjMQ#nPG6yT5mb&Vv5_V=|tu z9%%)>jHg5QVewz35}3ZKXdoC-%(&J>ogU=bKHJSsG#90z(0Yj_E6`Ae_TtVN@`+cR z#@1{#RzeN>XJ_KIPcz;RO0|xzKN%pT+?y6mhOMIwEuXEU4Qr{6bua_pQ|tIbgT5xN zJrtl)u6>vQ0+|%S8~`5O@QAH0UQ-?O$fVaki6;AKq{D#>+|~TXp{2fbX~Bc=S3mz% zR2rJd;$W#G)6{zSeRY=mSEJjLuxvrIdcn=~lDuRkRxPUYh@YLU9M>V(P4 z@0Ce`4KG|ulw8L4|9q0T{e4szj(^cJJk=G?^id+mVYokT#}jAqnqgN><+ zE+%YDeMo^YraH9$Q6dgY^|iJ^ItTHU&Fu+&sS2V*{>har)>SV`1VAY;V%EorP6lTb z4}C5-^v&ReI*5dU8`Yy6XgOO90>lHNFk8tH?mTUGh7otve7E#@qW^8=iolG%%r|H2X@ zanred?TBU{lI(^APCb_<6IPyshqY)vN+FS>G~=adZaRyY#rzXPzy^Ce zM11b;?ZR353z?og$J^2~?;qbde0Y2F2lC1~IA5Rk%vf4qZR~Z@IZy4S{b}ZBwE~+8 zn_5{yVnkYsvictC{a_oVj2=5(=d!xI3s@k%}3*ka?J7m`1<(vd^@WjipmP2LJ+GNQ5N{s{{l~ zW+vWupgGUIj=|apxUz^i{%4g_4)*HiSQJxIS~){tgG7;T7y;Q26}JuWPIU~k0GApZ zb-MVFNZw$D4BBK@9O8>#G%~b7hLiS#vI=DUvGd`Xshd^QGk4pStMSk{aAij{?$skn zPD84cwv2b~Y%Cbul{1rPJ(m!+!x$v$)&hrzfi$g{f%Nb?0M71XcZ^@D7JTH6{V@KO zyQzEnsAYV({!Y3rSTT%->d7NO`>qHLT)AUC07C*hX%+2s7cM2YW6`-UGPse9mI*%BhaZ0!AMlO)G>K zED#ri7aW{MLNLwxKs?S@?t6?U2pz>xoktZ+ApEChKv29ATm>Ld^9BSX6`>8S7W>~# zw81p0M;nT)|HN6JO2UA}yJPQR0IRTP;lqVJ9p5^O3WW+LiaW9AJC<38P+{ANZA$No zV70<~e*Y*x=ByP$-oTG4xq?1%-oq8-Z1dJx512q?)pnKj$Sp35UKm8b-#g0(I?FDp zKzgLZP3a9PG&j)Wjni$M|5SxV;LMI_5rrCVR#{DBPg-a#ay2 zW6Yz~YrRAS!nS0Zy~;%!%_2q0=3a`F-j~XPDfQAOuvi7cg1$tjl+XG^LC4t3Z21{2 z<7`T`_qVp_zY!$h^|+{%HlP2q@6f)2 z08232lU_ER$ZFS?^bUTEXERQOewmLq9I7a(tf$FxAajVu1_qJEMx9n4}@^`btgAKo7I*t8 zH2M$a&M05Fs}1K4f{zorbQ!oy$JUydEd=0=95$1SlCtcOMBoLY<2n(5uOsrdxc0OV zF?83+y9V2DK}&+CoHO1EdHtT%S?sE2$jiY&ErL#eBnD|rm%C}}c3tI8Zjr-UeVn&p z7^`3>H}ruo!}fA}M#=UhSz{;VRA$OjSMdlYs=EqY>nar91Xh6>o2D2>9aP}aQTF$* z2lU^QGx1lzpY)qe&~)~Rwcch6=lfKN9Ko4hE5;P~TndcJJHUV9i2io3HjPOYp3-}o zWsF4&aZ)RlT2D(~(bkSm1Hf9=7NK7s4Nya}i0Hx1=2|diw_&zW!BHK1fL^;9OBQ$b zOf)*V`Awq(hR$3xq)9pIdri>~ozXbI7M&SIM;kGtW8|F{{;*oo+lcoQkNYQqPHAGR z&ORld-O1{{ToE0kS|l5Z^s#SI0S~9BU?P+X4ku;hP;57lffEXa1UwiW77-V;OHGBe zqwaW%wHb&3+}oYu-O&njYIAGJ2qqF))!Ir%CliZKn=LAerA*Iv^rG#Q3I#NJhvF9#j<4t-n2U{G!-Rg z^rS|^ioSjE7Li*?cmCeXf?tIUlHqGfkgMGge|8HcqgPhaY%n@Q#M~no+_Ly7xi8z!dd-DpEj~!^Ck#2nD<2kxy79_xu9Pk%e5m?dffFfbO-KW;SD}y0Yy~i zq$h0P5xlg`n_cx?Mw(%3Jr7;2Bix|2dfw4;Y2Vyw7gChuf>|k5U3C#<>eBf5Qjt?$ zIDZSXuA}DH<)W+2n%|Rp(S`sH`ESiR%%o|{en;xl`PlD6TlP#{l#ogEG>I5UKz`d?haUXs5uo{cCKA5M3;dLNsccJD%%W{3i=9z-hHFgH*>WOQ(e4K zP)GB*`#?{hii8v;%ZY=@;|`xL>o%-^u3FRS)tk@ryT|rwc6D>~UVm@m9U%hi_FMCy zF58x54#Lc8%Y#N&m->euY+^yw%D2-*TO!63zQ-y=$wl|k78jR^T&I>ah@EgTShphq z5LvBtJnP{hz)=zVilIg!y7qL~Q^u>NcL%Z<*|sX;j&P4xwhSiZr=+D;{ZDT5Om$(a znfBOBPD!bVPoxewI&-Is->YCs`zkA)Hq+gwVuA9#;&VO3+iKQfGpb5Hj@NpZZo20M zZc;?CyX>QSa{N)+%ex6;#C{a9DF-p8qEUONym!IFe zP50OIqy3LPIX|^7{k<`@sT|rnCor4X(}vZcDU#F@-D#|5i{;#*_ogkR`fOC#y8d96 zF@#b8foRBlyVqkDGMeK=0&h9-zyQNZEI8KDYCLqjsg)LHv@BhBvK-IC4{|W)e|BtQ z5haJ8cI!^~90WgSCc3?QUs!rzaARYFr}XHT@o;(PKevY?9OC6~o$=_7R!p3(pd$c` zGWRx~%nwkR(9jFo>1p0W@!KdKCsuosU;+NG@ub+v4!%x$IzrIa$f=OvYtF?~H1DhA zdAqh_4!RGggSS)b=*Rc#*5u*m+?Ny5imAf7O3G;hcs9-YY|`MclgWz4oX%;@MBlgt z{rv}>U|2oU3Vfjh5oCM+B{@C)Rhq##CRw@*jt;=>8Nz^sALJcLk+=WzPB^U6QkcUQ z=<`BxVo7F`B)$7Ej(_uM5&DKl92-oPpG-;wPAIRO>7QpGfwS zj(l-`4-JXs?5&wREK!0TVU)G4@H!t8wULKZhQ(;VdNtH?)PD%_2GTO9;-I~Sf6~83 zlrcE|G^2vml%UfBsQTz@hz?ZV6V~|amFE@#z)g=DXR*MVd2-$s zwTL}WsnGt^eVF>9djM2nh%5@Jo>*{ZHlfoBb0c)@by;Ns;*@&ALd~>F)Z6{ap&WIE zQ_9pfC~3c;2luX)x`oJ{m%4(X9jZAB+}9-~W0P|DLA=lX;0=KW#7Zt)|IpQ?t6u?? zF`)zMDdlCNJtR$fAUfi+i@K8v;R5UF#qbIiks^$Ipm)Sh#yHAv{;t!FXL;{Ll4|xW zvX@pr_#fX(xD?>`BfWj_dQ`kEsh;AqDTv6@`dy*}4H#rrPRrdX1V$!_BckXN~NSHtE zFo38MA~G0*#J&Pr4g=|TV+K;eA}D+l4F-|}K61xzCj>JTyfu!7Ln=*Q@YuRw96-G7 z`%cc9SZFpE*i63}W$dO=y~;|I*cU?C1*!^QjgTqLlwH>Hpxk|vb0rBfUPh|#Z>ub9 zq+W_07HiMo;%s^|ckan1Y(a&O9_%@#DAve;D9Z*fTzGVNb`mbflF?Kt=YviSskO=V?M$uNI*KYpuoXdDdVm>H7UW zzlW5c1;#>F5d5f;E9mFY_izPS1l&5`VX3ofyUKUu7MI02Y=ZXp&hmjyQSSQaN)u&g zoZdhORu$RLVw^&I5bXi(A8~d?oj0jtwgdRFXMBSKjOz+>4YO&!M9cwOval2?GZiLS z{=q!-DlW!T?WHW~eW@%UQZHGu$%|DWEclULD1Zy6*0)Y=N*SzA6lRPaDjhQX9F}oL zX^Z)-9qQ$)Kc9uIETyxo^#EE#910W&W}8$*pNF zCOt)hliJc;uI#yTZ2iTFDJ4A3@agOZFO>>5vKVHZ;xb5WzDz9{Z;`Dl{DTC$%e96w zt?MI_3Axs%H|kZF`+0XTi&@o-^sx52J>KnECkjr}BoqSq4~Oa(3nFwEG_9Vb;*Hm( zcqnvfQSqSrNSi2~q!K%y$?6stqN+tLv9?IDde>OHhSzTy>RJlITHnv_A=VaOWveg1 zyz-l|62e?=(B(Y9A^Y8ft;34l@yBFe{Pa4Jp;Y^n9Cf9H`r4+=LKA^W|` z9i0PvE<@hPz525C!6{zP>0jRY?=;&e$}h@R03?>JKtvGYT7eZ{)uC@TF@;qXqwGfC zgf$mv234rJIp!G-L8`qeP6h>a zM~$?_nOm>Tyo3V!#qoeJNG1_GY8&mAZMI=Z6@q|FXMw2y{7kgEzxho~%IV;hXjha1 z1lJV*4xQooHO(406-|k*3DHL$mV8((>21XOiO2nOU#E0Dym_369=WsoG1Sm+BRHZV znMf}}Fxu21#A6&F7;RK^RmVb5GFnUmmCa3ZFXDZ*=T0^^bn(|f?p>?Y3|roZ*BQrV zdGAD-o8TpCO=wICYpU((Y|Pdv#0dQ(_d653BhBBo>Jfx)Z%^w(xOo?Z+8R}6OYA19 zYE$SSqKBmdDyr@p98ydQ0L_WW}Y!)l4R{{|$TVRCf-%%Y^Q-Q1)2tfL2Jz_YC)(6ob z^q*+wwQi471pp8kskD1I^&kdL6hDK0i z>&M~|Tun8M)a+oM)nOXxbDBo_Zh7_VV%0vr zKC`dhSl>q-$5{Xl3v`f3xo%9NC?#JP!+X%Yc$ffU23 z;b-<~&7HO%QLZ6N2L-Mnk&VfTJ8|bkLSIWk>FU)-5-whn~wKC`V9?S9*&8) zO24~qivOeE#e$~SG-iktsR2(KGEOhzgvYai#=1S8kg$p!%(rXfpHPuWy4s|?qe^TOdO6<5%ew!`;WLVfRDs>i+S>p>ExqzmRZL-qS2&JoE^vrL@Z@93N7? zUM&QdjjtXLekpJjk&vGtSWAP^XLy~?=e~6o!I)D}xZ6V!f^HOM$Iq8xW&ks-BMLvE zPk)6iRB9&XPYo%_{Tmi46WAiyK41~~y+7WmjJkrtD@s9npJ`XzsDUuk`P5@fmocnhT1h-po+e(QQC}EJNu=RR)sfz1LTW zgzQb!NwO(6drX6HrLE~);w6JF@3^FRrq~U*WNjmK9E{jHMCV<%;}AVc5EH~!iDZ^Z zA!#sa%L>aps9A#n$?%zLci@fLQX3fLh6~lv(VHwz)Z9pe^KhkdNYiL-C}-Nv)@p4` z%%N+{6Sga82&yruiT4xKq!1~Yy5b}dQQ$Qr@tDLkC{|z7mUY#p5T1O0nVNafFC_`r zT|PMlp{!2^({rhflcNs`B|{ z4O=S5)3dIdoeup*kv-{mhelVFFmMQBPgbH41^tBnGNP_h2(d-G9Jmw7%T<#y0-oWM69O{jITy%ZyP68cQ|4~OjAe+VCA{I4HnV877K z!awO>-qw*Wc4W$L)GS?Z}TJt}VWkrKG-pVCo&EtYe)#&b5C2oo;5k{>7tAl-Vv z+Q3=jy$Hcnz?KibD~p|U9Mt42kS-EbXLRI%uNI<#r;i!u_HRM|6WBpf?igW#kVdyq z34+(aHe?6Ao3Iku*+Lv4@2ChmRzoN7vVvJiP-SZrlnyOZDjS`u@0>?_PeaecsqV{h6A6!udB{N8cdk#Z|$M{-F-Y>-rKWMw>Pp3a%KW5 zGe^?RrbXS5WCGsAtE#iXIU8OJC`Yzw-K(S8cpjYI(Yf3urJ}yxd|I}8t;M_JkMonx zyARVp&%XP%y-r2_8VzR+(XxI;dr>8_9#T?wq+$woa7amcx8c_ZWBT*+Y0KNixJcI!4>~l2 z;3I8e%&yy%kD46%zY@XOQDSj;9#nNkcSdE*I4&jk;7&*+}g`}$i{;d%W& zj!6=`Bz(76-Nwb}vYzyYWE`p6>wH{*$Nt+x1k=H<+h`vkdtgD5#l_%(aqI@l)K2}c z(%9+KiVrONU*+@SN!h#QJ&q#I{9Zh?rP{~zM_7ma|LqrT!kiQS4ZTzF+s67=^26fA z;or!=^t)nU; zKxd9tb<$-&GbxB@q_d0C*!eri#;$x`Jdbxk=Tn^|Mh7|vlg2_O8zK~uVL>q9>KH70 zkAuOkLxMe~6Ub3yH`pE{T6HXzQ)aTo9{7Z)ny6H?x0c)tv}`DoO#}tJvZY6Yy)J^g zfKD*msE)03dRex0C7p<;kq>mDc66eT*iE+CFafT7uxGNn$dvvIk~kIwDPJO63j^m= zDn;?Wkk-CC%jIuQ5!tJyOAkplF7;O8P6i+ED1s6F5{6O>Cc({g=IpY(_d1}6mNz!T z6$D+ZHt?wU21&h$-W9uK9nRh<5fNW3OJ$Dw4cL++$>;i(=Fn0uDYB1w<8YNuQE^gA zp`pbd3$E7>nqcU18AGlu)d1n;>onM*;zAX#G*lX<#cX$n5XwUVGx%4 z&Uk4OdvQkz3Ln`0rB`Gea#y2WIW~>aCYwKT?`IRLPLLF>sMTjNvn-VyoJbJk0a^xI z8;pDdz07j?xZ}uU#_@OKk4{H!{UyQ2HluU(iuXh9Na3*=yJl@2k;v8vP~G8n4R6Nv zu0^Fy7URoe`!L7C;5%xHU3hg|Nxvn=E?HkgWX*YNMg&XVH%0_E5$F?9-%!jk^#db< z%b|o4XHzyKPu8RhGDrJj+3|CIimLhelXi1v$ly4M*#h%=0Cav=fOo1TRew@7ZKSF} zs;E6wCQ*Em7$@YeOp>(fm@gW#;Ixi`i27EPF_q(g<(37@>B%VlFb4%Mez()P7 zD5(V6A_u-X{7K~fJI$@$-#h5#--zsATJ>=vdFkNm zVxfvxVa>=TgFApr)>ef@uahTYS{RhpK=jNCB*K}gR-gAFtfF{BY<9zOckGh&HAJEv zf_ZE$n!=JLq9}~IwgnPWYpC>IR7G*NLs9@H}B41|@Du6JQXonm^SphVZ%X*$r4kT7S%Np;f1|gi_YPXn-!&3E=j@Tt@ zOFB?mv^^;E&EFT&;dLlc9EXnv^2O-)o7jfvVAgDhE07xzQ!fmZ!&@qPnQa1pFW8lY zjLmq$&-PAqrad#;!B2$fnNta`=k~p5@0-#bJ%p(-J&E*i$0h-&D3>kwBQtSWQBn|t z8NRGkphBH}Ypb)tUssD?aT4MQMrcURc60gDDP6%OWW$b^GM#&Pm&mvGbt0``tei=Z+4hnemaGB+J-Ut_)#*z^-$>lH2A@1 zjipMW_|`|x@M-U_3*LgSi-jsaSd5}ua0hV7+Jam2fNn{>)I^yg;o8vw(86@hBSD%O zTR8XIM+o#Zz}Wz3;rFNFP-aX|yFhV>7M28p?+bX*foS1Nu5SUZSzk!w^7sQ`ixIW~ zmEsVjAsVFv{#5Qq#X85U+govnv%DIY1977Wv4h#7h)fM=w@<^NWT1;(0HNX2E>IlM zwZfrz@P&aoI*=}UP22-qv$jb0q&WcVMj$m1-f|x|Ve$r~yPdoDNmv&xaNev{ulL#; z$E9xk^WXHon>2spW%z`8L%f5KqhNl|AVTf6!xCJtyOlt;zW0%0zUce+t*zd_D46RZ zKxSMIzAl!$c$AA?GPnb{WNkqXlcW!HE=K1*%p7VU8_>CulM4q5Cny|Bvw5p`dn~9t zjbJ4rTlD>V5Nw|I{zV~MyB7`{gRcviDIVFPmkjOzE?HY-YY__&MBs_Yb|_P(+ZOY8 z(R5SshG-g)p?I(Nqt~pjC2~o@)+IwQ<$Wm`@*22pRDSgr3sJ2Q&Iv*vC^~T93X^^8 z;MU@(e_u>G-iqYVuf*CWCF@b49Tu^nTmAkNu>}({r6RUA&h(&&4O$gKVpKtb#mOp& zV8i8Cv9*}m?vRctE54sl|OmwQ6^?KBSLg=d>nhAc+MK_ zJ-j}$j%(JJvu;QNv1``X5;@_#J=J7W-k0c!bxFUGjPc?6 zyBN2aoLoMHQb}F}vLMl+T{2cqVC{>2A3`aq9R?7;j-eE?ihIo1i#xOlt*5?C(|hPa zix|@2hz&Me0&D3-uUT8x(&ie-9d4f5_DqjvA50US5K1(~_(kh$i<}ADnqk10_k}^@ z+~9#iTh>0zlWFHouvN^!4-|S|C^T!5J7fX6MehTJCW)Haf0RO-W}97asl+9E(fSgX z-RF#IOQNIwC#`N|u0;vqTSoj13FI)jRs z^?^9=3vuS8$bmT1f@VAlRqKJB;o=Re&;GVV-WahM7s%gSj`^8e0n2^ z0E>cu$a)ypO-A3p)!gd+i)zD0L&W@6K+&(OQBR9pGPnb{WNkr>OY@%yYDE%)y%E!z zrEt@T?MJU!TSH_aEQ{ix^v-O^`y!-q0q3PXcc#L*9um@_w$a;UXiDsTrL@o|XvNCc zSIfc=l3M*FHKkeY{t(AO5>T>laLaA5&VNG{m&X`ckY}`!z}2(}YV6#Tu2~1ta&dI? z(H=qc7J?y>aBCob=adIBU$E#nPQq zv90QevhZAQ)}O{QhB(7(GL0VcI`^PykLLIYjLPDH!T4VqfiA9zl^LzZLubK{`5$cQ zx|8L27JiTe(a;m^`P_X7Kke3?@E7N+&g>Dc=)b#oU~pqk;*WkA50`iT1%eqa;@NMV z@#v10$@|zeo6diqdmB&Y2Nrks(0%Zq<~b86O>(jEq8$NR{;q&pWGZ{~5A&zIxd`$C;XzW|_ zbixl`t{*#oxEn8>!OXr9tM(v#S@T$O+hiO|o8C#h+@xO(=kDyIJs*({-aMr-*~d5T zWI`3><7;o(#Upd)W;I`oe>qpq!Z%9ssJmKoqTA;0s_FPcYm&rjA5K(-4%qkBrP^=<5z zJz24xLdDNLjOx^0+QbAd++SkIo^e6n3GYpo6`em-%#qYPX$J*KFsVUvu&JPMn;46> z_8$Hnf%7P}L$j%}cIMC_YgaulE)z(GJ9EjRJOpbWzi1x|^N|0){i02vbHcx&JskYD zvHq3(uy}F!H}Y@&7tvdWHyoMwojY=;_C(%t%B|r0&%vEN^DujLKan?aHTDVR1r4(8 zr2}IUmXn0VQOK1J56VW{?9rVSZyYjO{~^8%TB)H@9d0h$O(s!J!hkTPWJDmuY?LfQZaI&u0!Bkk5fC)(-g92xHwFy!j+iQU&O zrj;sKhR;{YI}jcyS-dY_Y{3qdQ+8F0ljXgk3&anrSuKv-8M#^}-*#L|Lw=x-0cuIt ztdNSfzHPo?d_|$oxqU4ZI$4mgC*#qS%-lmVOkXJ zd-WexmO7ZK#+#VDqmdEfhadhVzD>GQci-PZsATi5tr*Y&-A=eH5Ga4FKSV!7`{QA`>j zbR0;>5A_2?Q4){Wx5WQPz5kB{a z$3)-VLhw^!qOHQqUq!Ni5j?*lcy2`v0wUj4S$;}E-CDyprgqb%ePvXCrMds)y7^aW z?%&1B|AsWT^p=$Ty)?J9#8wu0%Zvk(*|*T>YZQj_@IUl(jsJF}`hTrL;x+p#75J6t z{^=6kl6aQm*JAr^appfi(Jk_;4*5d`Zxdqw)5NATw$|sZaeOP`%@3;jg4}<+b^e>2 zCVU8mFG5P;UgB#UvV?OFY^3f(sCO-aD0_RRQPYE z{JvClq`;X!G*RTG63?TJ~2H2=dZEnRMI|{s?lfh+Uapr2v&wW`i{;YmL zg7$Y~;`abQ=1-fT#Y@XC^Y$A{UUaiEy?M#Zt7%y zZ|b(99J~PjH<~&Lyy^QiMe`tVznRSy9{T5SwSuozx`~d6r z{g_|&06*qWi{r$$5}W@|9QSRy|F`;pnw_0JC?Mc2thiv|=;*d}If{uBKtbPhlYCWw z_<4D|;u2fFVN3TU@JItM7C%4~C8httm_M&5{k6RFROOph)d<H`W|KQ3ha}x)v4gLVm{r`>v z02oXbCXQP_{uke6Bl0&mc~bZW0DKWwOzPVru7vpCsb}Hv@V}o*iqA~^iD>KxG(B!2 z5&#Qv@yg%200MvE-j5)R;EBz@x+6gv@^An5HTeXuETUpt9(cM zv!#&#+n7HuwB0Iw{E2$~*NL*k{|z5*{C$-5yD@)WQQQLbe;k!=$?{iF;irzWwvw2e z1Z!bU(+jv;GJm`7>HBi@uc+&Pb0hc^A^=W*X4JLixBe>f{VVGFi$q=cXyZ@B06zfR ze*@Y7(4C}zF99VWEGYctqujSpA^u_*JP`fQU?Kj#Zt{IaRQ%s?zsT=k%lBjcw6Fz# zamt^lJ%1epErq`g4X;B#Aej4J6n{77&nt>sk?yM zGK(*Nei`$-%I422vs<)~KaRDxg#NFBwZF+$|F1n$f2AZf{x-%f*%tUd|MN#&&Y#V| z5Z|hy{8hyI7sCDuVQ+Z?QT!#YTY~#t55`X^wp+EsKM_Iv0Q|k_9RD6YWlLLs<+^eF zk*{I@7tr$^TSOFpxiB7I{Rq(WU6<4E#{6kPkHl7#^Czm=KLYAM5B~l_D*BP4_#G$z zcVqs%qWI5pnDMgwSHa)k=DPnY0J!M44JUtv4;R5-(D{e)_kWmJ|H9vY1ApV&C;mG4 zTVgAQ_!EJ_55V8QVD+Vi_He_rkR^K(Bxb5QziXNwrFLIr3<|JDz9`hLuxR}}wQiZ}ksjK4}y zx_N7;wylZ1gOwdyn+sgTxb z1zj=u{#X5H1`^-Kc%?il9uQvVMfpI=$d6PDYdh>-aZdB(yW@jabx0E0Ga&l>OrIJH zg*`&O*>ijMyWSR#h!f=wh23b|Dn$2mw{zHPwhx3NpEBRm>#DV$_O5(3^ZgBcgV^?X zG-chB3_E%$ohZm2OKpe5Dkto^urL3hN{RW^ z8!4F6tX?0st6}*1Hw@5>JjlGDG3wsi(6CYM-=2XXkJ3C2rr^=yCM068@O2cU-~sE| z`bUeLu<)S|B$Hb!0;U{kamylwKb_4_$K(Flf!ZC5bB#j7Id!Z-mPwukwiL~>{zR*gAoFPB0PVXcSzb z%g~`Y+WC#OS?{I7n?j|F_fl$BXR4^p?gelMN(~_LbVnD*;_Qav9ac=sNCFfxs{o! zoYl|0QjYVA>noTZ@cZHWp$Zqq-Su3-UZQFtQ|EB|iBcw}I-OsSEQqD(d{!>jDo1A) zEON9-dN_DenMK$b7VkdsP{gVYB|aS@J9Xox)LUt&7^9vsl3Ci`_+tsCrON3A_**g4 z7hF-n4^v|Kx{O@v3E2T-1rOouFTf%wtLLO<;!K0{oGki zZniq7?GR-$?1aHgZ~93hN_T#tTJLMBvEa8HK1cJRY=3jX5pdrC|JXLR(r z1i_cC>#GZNP(nX}f*uZaI;x_vSR2#q=bu%qZ%TCCC|h5hzKk7>N*$Hzvp@V1oHuWD zc?tNRY{BdEaj4#%JExwa6ZO1T=l$48jYLY9r=Bf#B(2dau71*{;L9j{>z-535mfz3 z7tWH`EP3|L_C~#^{6@iN#H0JjX2zE={Bttu1{R2CE6pYdLt} z^MLpI_&}NW%BYa{32Z^H?Xzf;YdhQXsVR8cAP}9CTaxe21>{=yV%7s6$S7m9P1e() z;tyFtCy%j6fK9v8dBG$l=6s-8sJtYUU~biOd9sjq;6i$4WaP^?L+?|QG=j*FuT0u` z2Z1A!U^KL^kRAy;JOmaM!~{o(2%t@>wn2-+A zShV!Jt90#i$x-JH$^%g!nte8~DyY5;^zJ#6z513)TiGIux1Y9uSs|3+|B&(e@bYw- zX4xla$sxtj;h~3&77j@i;&%x8`KG{HU8kQf47IBYsb^AK$>+2j{E)BfP)WW&*g7R9 zWmUpRdM<~JOtkI!(1SY~D#HeC2EM^S_{B7NU&eB%=gYS}8CfV>_bdUb`!J$rk3-WA zOpB}?#St2DlP0RUd<*q;u(YX9O;zCWT~xU*#0e=4ROrVNEEC;^uCsX^N7Bqi(_0Y` z2BqN*N2fo`h?MWG`-jZVi|+B4YsqPwi|SZh`Z_-?z4e$D*ck?cG?#dIpncBh8c9U> z!S!UP!r>;?Z;V{ub&7;$0~Pi_re_uNjcX{ioZybxcau{|DzJ)LQSRmer9$dRkq~HW z4Q>CSBJKJFm$xwn=8tXb5dIa!kvpoHEy7Q>3xrRD<3lOe_S%&teAZl`u8m=53n){P zyOYa5%*$2#Xwa7HeT^M;0#wrb>_=@?ay|X6P1k}U6UjQAP#oE0Wslo6<0&a(?Hzh6 zEh6=~=b^0_$9cn$9Scv3o_@@2JleBub#SMg-BoA{c#4(0&39dscu$J7lA-;mtw!9S$Hx!iGamPP|d%hw6bJ0zSe5I?e1vbgWgld#DoT| zj2?;(A(%uq6Mv2KVNnj*cWOLin+tXdJ=ENdy<}1FDyP)VNH#L5>}0~K`tXW5)-G=T z1hSaEexSF8qRu03;c|`z3;I^}@bW4+ffJb*V_N4zK7`N3I%K7{+BDS5oQ+m_Z7Ywq zz5!F-%if&n^2Rz9#VhSugRwBY*k&0I*S3Ds%n*E~!qeY^8lAp5W-a@pZWOsuO=fkLmjm=tv_SGRk{pnC(4RFWe^cNjnQ= zq@HO&(fgFRb_8n?ne1FWXU8DYP*0@w0W6P9IE>3o+1_^Udc6C~T;%1wReyK=TM>kOj|3`4h_O+jXc*shg>Xg*q*sQiI8*5WHfJT&d&O)CG2{>_+Z|Dy5VCuE3KOf;U$@I9qmy#)`bvVa zFL`^y%;Idu@aJ9coT{LFS58AnS8kz)lH7;|-?|Rpl*TlPbr879bx_4i8P@Gsc=k+; zp!Y-c_?1eSD>3(+1-0UeePGD!STlM@$>7aOW!mO0*^o8GH&*v+YM9{hmed9}>`iC< zBk24t&88@fhHIMweW0GY5a#{DqOGh$Lsr15MZ>dKYUnCNogG#lQX#aH?2cl7u(HVV z$2`)Gc-7?7w`9HAVtogRj6}#j@3@MB>Xa(L#jQunuLwSB0e0`xvDNj}vUMg*tD^Tz zO>iXh$GD)XQ-WSa416xw9+T@Vrzj~JTGp7!!qEUZB%QsR0<(DNWFmhDa+43%mN3W` z&?-q1B|mh7bEs%I#HN!^-xg}1VT|+iz(#u)xvvkbufk_`Hae6J4u>j+M4fZzU0jQ6 zJ%HdYx|OuNGTz-w`K0pF!A#h53P(g)he1^95id1#vGDqiOxjVjh6`e9?7iYTR`bm^ z^!a2jp5wAt?NtOW$k+EE2f8FnZiCA3JR)4 zE$u#aG|i@S(WJZDMkoYnE=Jx4&oO( ziLMR0zjMaO)g-=$)WDun>BMV7(jwTu9OK7)&*`(NdCxn4j|O{?7%h*aA--lq{jan>neZ1s);=A%OQP zLal4MhB0Y+2m0jfECsG%MycgLX)Wy;jvwHHdLj4x69I7-PYdP3pBem&5J2cTmmQhK7}?zb;ypurS8K=Su(eVh&2~~qbva( zYgzFZDKZl9L#{+^zP^enM;L*eHzpccOaSsUDqBbT*KjIX`l< zHoM&4?b+_tBmxR}xhv6QR%GBd$sV5%E+9IdCm-yNv>ay7J@(MAz?Zn?=oVxGoV!uanL5AC(8Y?=N(8tISs*x;Sk5Q z1u4%u@<4}oCyNBpT+<+YHU|hBSK>K^(0oeUOVL*}=9*lNMb3JLV{S}N<+UnQ zxM;Q5Mc$G=ruX)>TdmuR0b;M&(PiEb^xTjD{YYij8-t|85RR4cqsF%=h2|V`lwr3} zYB`voX>@!QVk#@Qfv;j9*>j;^YLRuITQt}E4&)U*yK$XNJ$icp`@q2Z+QOh%)RmEG zmnpuwC&STZAu*7hh?dK&_ETZm&lVKW+-NaxqCn4cc{itM`)^}!C3NkHPZ~knXh0peCwFULki!>?hr-fgQd zUb&2}3|}5HN?*7EcF(9Ph0*q>G#u1Pmx;BCC>hK0g|qdBNRi5n`umO>mN&_u z5g$+Wac46e^`1+bC6VT1}WVRMhQU4?C9 zvPDeg1y@UA1z~L|d0hd?U4D}>^y4=Prsn}Fld*bwBz?axg`4hMghxpfIir2c%Ss=e z;(XJ4$_!=hwBejqt=I~Wcw-2!BGcmT3iK`|)z8P+k>y6Et5YpvbF=c%)Axwk-Hf7p zB+WEu5~8sA_tVc2Ksghe=5TLZ2@aV{<`rJ?2%#(UwlVx9xm=M%jjnz0f^ z&(uX*lyK9kkHiaIT`@^zfMR53R^Bx1R?s~1+-j-eigpx4@HFZyVQhj!i&NZ7DvEF= zpR(nP*9Hk&S+q;zu?U5cBxp&BGHflKG8%{Lxha0wj998yWHw;@ww#e8-VgCpIkh-kGB9m_RNA$C(3kyz6_0De0MPMl9j_ zkxvR)&Ebx(n$FV9HHxebTASnoN1Y14Kc{mWkuv8dV?PL!j5uWy(<2#4Y}X?gFo*6v z?|Bi;EtEh%vcQ!*{ZK zk1_d*z` z+74rw*VsFvq6nvN(Ci3+_#J0BX-VUzKCt)RF|5sYG7R=!r5F|iBFM?b;no#7#f}6n zU%FO><%=}>6FrlDPI?-uK>+6Lr!JeJ;pJpL$y{+h79K!Wsl^CkMeyV(cBQLd$=*nC zJ>M~?TgTtXVaIAzw5|3mYNwS#_RJxFHw4LyevPBaP*g*Rz|O^$Mhp!BI!Gml(J#Mq zIEb-qZUl?vZ%!pY-Zpdtu3oRop*UEgEh?GV(;R!{ z$hptTPhTHPESh<7mbcy0Ur;cZv#N*Dan@L#7Aw2UF@w}%A3SkU$rm24pLF_ye7(&n zcBaAj$&ZLJdEK6gC*cmo&oD8R+=9%~Nmg7(gng#{-P~NgU0ehmof2~rDn&8HW*k~d z?7lg|i@oJ;Cs&m-x!D&5{RY>oB7u@8nw? z;HPw_JzFj*c*`!AOkFHPoSS>9YFffu{9uMiCaEH$N&zc}HayR^@3Z!zjAm(N89aWV zX;}7zi+5hVZc8T(GBC67?Ln&{70gZpm_5jn>}x}lQpFYuhnCu{1d6)O40fho6FMT! zGI~?l!N9=yF)Q51O1&amVgmpX=-WXR0Jh%2^Ywk{g(#Rx~t?#OMoj9T*-*B)gO z<*+s9;HeM`xRMPZZbh7bISJ`fjYBe^cX zFTunnUKS4m_BWPdK4+GL3djw}G^F|+FKJh;qaFMSiz(2w)vXxkSEgZ%WW?`ZBxNUs zMpfH*u?(5sD4jx_zePr4f2-A!&CNZ|elW@mB7V`&b2iptI_My{BilkGdI|vJ&X^{yee7P~ zX{2nmCUF^c@=DB&uLe-8H&C}##w z-Up#uX&$OmD!nttWVK>-oaSm4Uq0lnjRP+Ts#4R-pe&dr1EdPY4EBzNzT-;M*h=yf zVzjr+!oVw!B!{>%$`$$g1$|drG)BcOC7Ek<|6sX-DmETHeWvu%+M2mOV?M?3^r^Zs zned$9fdWK-sY16C3PQCe&Bz^FCPKzdh^%brcn}Uhw>Wo3Q>!rw~{0*oe?HuUA+?Y>ShpaB=M; z_ZYE=r#OcRI_4E(Ujgqi4ZF-y6wN_Uj;*z%A|&kMoPB-Vezol|^)>@V;rjha$+|{P zXYAi;CYJ7t^~*CVQ2KDqdkvFR!NgiBmqT5wb7jp^pOM&28hw9~O?~j`aZY$|W4XWe zQBAZ&+4$J1o!g}kN9ffeXa?oX%5_WAXU*u!R7Aaq2VO~cQ!c#lh{VJ$$T4A8q-#S> z{oNLG0vFsYGwo%PWOUui@>mBHWd<ZQvERwV;}|;zY+8g(%)O zHOLWj8F&B(rY6IzfALV=l~Q_VL!FNjOhOBN4w^a2T+N)Y7btkLdCCAQ(cZ}0-Ex^+ z<;GF@f%o4_CQ+^!rFxJsjjd3`*t8A#7?T(=Gb2J7J;eK)qR_1f6AtN?C}yvI)Dt46 z#ZQO1G<5|?o-U^L4)wbXuzb9Zf*S3JX)Q*4)*_)D9SPF++FLtU%5B@Nn&b@O6&D-r z);FMS_YFJ9;x=;2nnt(<^L*j0EHlrYRxN|Wtd4C;ysk=gI$qVrv{e{kVqD)B<8**x~A3A}eJj1?eoJ|;*_N~WBTrEm zn4CgI6ZmP)y&Z`pHeeeE zo?nT$bt#U1Je?quqzIKdPdJ=wza680JSqUuOH76}d;!NaC3wtXvSwB_P`Bb>Vb`le z4fZFxa@?_=xzG~SqCom=xkO_(uPf@95~~(Zbiy^wLAg;oTFkShcuSdpgEOA~j0P(+ zb)h6pt+^SE)9fR>mZIPg)p3XD$vDV#&MSwnk4C-P+M=4Nq!PPwaxBVn%}2CS#9K?> z>(k3)q{D4(`ywcJjlFCNA44Es-eVgA>6zVzAHlXoaVsDeE#k)V5%$80nh5d{(|}tE zSZEZCtTEbq5J^hXU%!}qW9)Minh9Q7a+$E+**dWip>0D!<7ga~zH+Zj3~F$~5s}2y z*cjy*YldkwuNx(X6kiaj7vfqmJ$=!rAVR2B=s~pZ!)k1`t6I%OQ?_n=D7JLxKma@k z)16Tz^a7F7gl151*ik*O&FiIL{B%BKlxDEf0%T98bI;OGs~a44EL1c&`_jO#HP_V5 zjoRgvY4oU3L~=SNqi2mzUZ^p*lOx$)abBmkGFPUb9b&=Hjhif1Y0GTm`#8mN_V&qO2&l|M}-P2Ua2K zZ0oq%gTVcC@-pH)b+3R?RZeVsWdW&Ijs+s_1$P|3Rj%gM_|oNIsq!c-FO%VW7X~~R z)OTFDH@kAGIeRQT!9u)_>t26>%=!W0cmnv1qH$K+6d_P#G=VPqCKV1^_o(REL%rx` z9y$>(-t{Yk>whjoB5m|Nh!~!9x(rb82>TM0(PA2T{rYpm&bx>ohI`Jxx<7L$sp3Tu z5w!r5)v3lFh9mLTN9%-Ck01k1iJ8ju-sL^0K4RSuQza!42l(lLKE3#f{q_|K@0q;E zVk}9JLHUm-ky-nRxtaIegnL_0H3$v&Dc=}`mT7b#B8*AAM|k&p`oH%+?nT07x=cmV zw>9}p535zNJ~cR~BUVwg30!TBxt0my=4(F7TBs@F#WgiblhTf^!|x0PwJL;C#R)CV zXH7|cUPkGkTePvwL10Vl%2p*+n&YyE^B@$Cf?*c=Z8!ZQ$wuxm5LZx=&<;B#jyEP* z=+h9_)2Y8s1gRgnM*CJOtK%K7tG3JXGZ)#R6I`~}R#mxxgI`#_}+6eJR683e_y!b#OjpJpu%YUa1pr|#6ck;83u zODQ}CUT&G-)P8;kRGOfztXtf_^UM{l2%BK;5?#)qAY&j5T4!B7GgJ z$3+}!C9-gCY9xpXzS_i7+s9$Mv41z~bK%Q_JBl9olL$PTb9&mVq|khjYEN~2U4A{P zhV;I)ZekD{|^$Bv!LL7~`gISbr?7ob&#B_Q>Z`N{z zQZQ##cZ3d35R~H77 zUVP5te(w*e#-PL+L2LhPcCR4uv<3D6?x_b^Ze?4`xPTuW_aH^4WbCVCBeeP~4^z(gp?FLf_fFt`&Ma`rZu#{~Qo!TgG-`X~ zE#_=r9cq^WPbnd@B+t($GTEm<^}`hu)BU=b>`Jlc;{hYV8k-VlyDPsOb%wr>bJRHn zum}tcYNhG=p7@pTTbB8dk>{(!AXGAQNLXWA|DpQErQr}+TbeMGVW0BVmv_kB+x%-7 zbpkp_0kMN;&}OS9%dCN0lfKTI1gQH#cg3=|W0m5%mX8%}v!h!v`h?Ji1LbbD(Tu}@ zgh95OJ6fbgdN{u|wT8%Lrrwe!qlt*K$!s?$N@=!5_;s_;4Z|PbL?|q$sFG*r@ds62 zx*XRIl6V5+B$abst4q*KnP^F%=1#f^3sX)|~2UI6ETW5#!f%KZPCTsm`j3?G8jpuFxS_~DSN6vR*;wBOd{_o z6kRq;oSWf1oz3qspsyoC^!BCzQyQvWUOnXPfVK!m>Jb6*$(VZ8slmsOz4oM5c4rE! zC#a9oS@|!hnXueCfas^_=zQH756PTa6Ug8^mNVmYKusI)n<(-tmkS?BU4H4zIb%Szh!_a)&_V?e%UQ;b8yiGK(#@<~ zdV1K_Kkhh+p%qTVp#F)ZfRBqj`UKJ$NklF8*z*lJ5Uz9O4k;d-4m?`fki@cicXR$I zNIzx%5Y`5DZ+XFAMuk>*<0SBO2HfzTOlbxvjz&HyKC4KH*@6RFg{5Ve`g|eHd+kBh zRpOX(hCk#C?M(bb+WcoHQ4sK62AIbrs4AsZT5p{%X%zifQVMk zn-ZF!gUTT`m|c<3dZ{;kQZ@az!+?2G=!ivE4d%apH zNyx@x#w$EB8IGNuBn;JOu#yJLzb0$WSX2v^FQGs%RoVv;cp~3A5P7gqr{Klb_~v$| z>G$#Dcj}Zs-#m{tDctgBZ2s}`9nL^6@NX`jwdB1)j-3{@YttiG6}hX1RNvmbatTJO zE{BxbjHz?TM`W&RI{vQ{c(isPHxBIdNao1VO)j668zCW{?}t1`&YU(*c=o{2T=#GG zUIX&P1BhY5a}OO9PP{!C96g~I_Txt%Fu0um>T7|~c@23sZwr;PEanpRgE$=+#GWm@ zUhB)-mI*tMSVqEE?0Gg?X@e3c1j+jP6f^-t?h`Eix4lG?D5mai>4iv@g3}*nJ8aWd z493s&_?YQ7yro^F)4e($cXtx8=JB=JLu$b0r(c8Wpf2Eq@4oXfif|(!d>^2e2SYJpkCgCNvU*z2{;d)i)5i9nsy7USfD`{+wwhe(HIGO+gA6--gx2 zrhg9@zxnc>Ol2F2&9{+G&+F{D^n_HdIr7y~zK;*uk#diDx}FYUYfSEyViD*gz`i_t z#?~bTrVrhay^~#qVY@$^E8p{#q1~`XjyNu*L)?zY&UveJ&hW0CfRdH~-sf^iP}kTM zyziYnA{oX>?z$$~{xUa%f=X!f1l|o0ahCAKzYO&Bqxb+~qGs+vnf{B%I+sox0Hf4i zX$wa-fQNKix&#hrS>r^&h9NEOQ;y^E_cP$p@<6gimBW;&>%k_x+S=2^j%_aW{Ps7& zfnGom^gV}o(#)((5+$bdX_+BgS_gJ9W%xdm(t1hMx49AL&!FBB%cbs~3ez9lMd{ko zxkymt0bODr#P*WP>0XjY9!$TyAqNv5)vYdneFQM%dHTm16ybbeBThdoKx9h4xp4N$ zYBsEc0*LkG-6y6DID1Hw5qAbf0S@8}EURCz&*2VU6znFx5{17#?QMx4c(m9y^)@YZ zAu;)D36LPpNCy6)?WPYh(AI~7snB#^`r|c?18o-}i5<<(M=~{&!6xtteEiHX9tYF4 z@mOQ+h1>jbnAgbs3k4$?^Z$ae*S>%rN91C zB|mLb6AV5z+X8y&rX57Sp(t|M6v;qJ<}{wEQ;xR4sv6K&#!!d{071C3=Xm-_2_OiM zPA*(JmX!(HLD)LL!P9aIrL<*M{G==oeBL(ky&=l4qt*4_uit+~7PSBbjKv*kfjma#)T19-}g=n&Ud%9D-+1IZ$w-%ZvI;Q^XBreGVxr zDYhq(7jR;w`ev0!%WKoJIL;|FpWUn7=YVRyqrS^vWwQ17>@_yYi+YYx#d`h98^S41Bb@$~$0lP=gH-^W zB*5Fo!O2rNlJlfJVh50j;PkU+P`iLcywY-Jqd0wZ^E@Klgr1&(;&_C`4)dkaSr0*s z;o6e_R-~}DnG;B(TwQx?e&W_iOnchiWJt3^QbY(g=I*FXFwxc5K`1n;QRL^sA{i8= zax)fJbP95(C_3YC-)rW9@7)iSjh;kBK*8_aVl8UWQt1)M!1MCCU8>0KkkVk=x_A?{ zT?zDBgWiyMy8h(#QD+t4=T4xWIYf=lpFYJ~$F>rYS&P{1mFbF#4Xdu8s-0a7f=vPbHRpV`Dbo5*7U zzyOfUTf4A-}=n?CJ{&vJG&7%%W; zvB|g3ArmR0;lQ$%l790#5m{EwSN8>>O)XHTg7XFbH?yX&)n+g{gp_psUX`L3WE#2pf3uIGMfeOAZ0_?ugr#e2bZnQXICgDg1Y9%90YCNzjsp#)0_%@w_FkDa1EjE!g#mBH%vNVyz#R=H zGTdVps-7w7n!p&jI0Gnx)lS_;Q3mcK=`=;`gSjBNQv-HArr`Pd+Hz`*-Sc@Jz&GBh zBs}!EYI_iibI;z-;Q1mzne3PY#BlBcAT&MJsR^f4Z^l?A%0MkAOoBsB!*F3V5bCts zKvMaXp6%Y!igANMKyV925|KJb@}@+a1}-jr$kw*^Rm->9XkK`j92p3tPvSgC=t!@A z>d+52FmB^OmX{~3eM&{m*AUaG(E$3NwLwc2UwQ`Zu|1cMWIP><Pd1baP^&_z&nIvGMLvuiOu^JG(;~)&-x28DEm)>1x8_I1I zR8?Yt(BjT?c;t@e`I9syAg>_cdt}i6pt|UbeUnZqF^ElbfP&)s7|N9j0ymY?QBX@! z6|@_a2ogcrJU^XWMn#6l24THcy;k`^1+fY6BPaW1S;1L=9L;u_k+9F=IBF)yKeRsL zZI+!bc^`BA#r`BYFTl!N1Y^7Ei|2S2hlO>W^O)2FKO6>pAeTNsc;;1H-UIlt!(C_X zE)AeLL*-~e)V?|4t{;~v;e|ixd?9d9PmF@0rz{x*HK_$FsQ5u%D3oG6V*h~R{q8#!97m2qo z(g!Qv+V4v*)-0}Va4v+@mjg6KT-1^*s8iS}wvk~mQs@!#^Q1M5vAP#fPn!@CBe)Ob zIL^r}4*K!J*UI}f=MIiy5Sz9gw7gKA7GK^`;Dxg`){wDNs4<9Pm{{}(Xis5IjlZIT zvtJd_+i^rg{+w!Br7#oFf?_9x23Zqk$4nF#)TP~Z@=3SplUF*bjiA+|Y7wot9wWG- zukqpflP-e;2W>KM=}gpA>6zVRpnCM;Q6qnz+OBvED58QozMKO{9BB|nmIP54scIa2 z|9}|)0~)=%+kL%J$_absNOA~ zXJ>HidtsjuLef1n`A4G7Z=W!25~)*jDUAk6`eDGDqptO-FO&kd$QY((aNr}T=2etO z2Xj`;;aWGgxxYwI7`IjO83u=^hS58hB|ckCx6%0n7z8T8z%XA1B;5zqZ zB87OI&-_UkGKC&BN?3?_Kne9zZD;Uhr0nCp@4dcO^~w!2c^vN-Br_J)<0@Qg5~FDw z+|CBrkQ(;Sv<#$h{Xy6vW1j|)pUGI2=$Et_Esv&~6!VTVjwg@I1dT6c&Da4t!U)hJ zAUJ0X88$8f9ZO0!0ifZ6dkQQX*JQLzK`h4VwfN3>P`yFT*zCcrqbiN$MH~JU81`fx z=3uvzdbQy%KrRhu2@GH$P{74HX)sOVCR`ZT=|@n3#HGH9@<^4gw=^6v_UpYZdhSS$ zTwk-Ftc~#6;hfQk=(>L8F<@V#0iohx|H?FIJ{r$Z%dZ~%oGQ=qF|Q-x>E_nh5|e3l zaOK!ioKA&`Xq`+Ytu>WM@L|~4IG+2UUgvz#p@D5)8^N0H$Vg`i}`S!2{q