diff options
| author | Dan Engelbrecht <[email protected]> | 2026-03-22 16:14:25 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-03-22 16:14:25 +0100 |
| commit | d2dadf70e42b972234aa5043d0e97c9bb0a8c874 (patch) | |
| tree | 4105bffeda7a22fb7b48f91d8916d8ab0fd08440 /src/zenutil/include | |
| parent | hub web UI improvements (#878) (diff) | |
| download | zen-d2dadf70e42b972234aa5043d0e97c9bb0a8c874.tar.xz zen-d2dadf70e42b972234aa5043d0e97c9bb0a8c874.zip | |
S3 hydration backend for hub mode (#873)
- Feature: Added S3 hydration backend for hub mode (`--hub-hydration-target-spec s3://<bucket>[/<prefix>]`)
- Credentials resolved from `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` env vars, falling back to EC2 instance profile via IMDS
- Each dehydration uploads to a new timestamped folder and commits a `current-state.json` pointer on success, so a failed upload never invalidates the previous state
- Hydration downloads to a temp directory first and only replaces the server state on full success; failures leave the existing state intact
Diffstat (limited to 'src/zenutil/include')
| -rw-r--r-- | src/zenutil/include/zenutil/cloud/s3client.h | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/zenutil/include/zenutil/cloud/s3client.h b/src/zenutil/include/zenutil/cloud/s3client.h index 47501c5b5..bd30aa8a2 100644 --- a/src/zenutil/include/zenutil/cloud/s3client.h +++ b/src/zenutil/include/zenutil/cloud/s3client.h @@ -11,6 +11,7 @@ #include <zencore/thread.h> +#include <functional> #include <string> #include <string_view> #include <vector> @@ -63,7 +64,7 @@ enum class HeadObjectResult Error, }; -/// Result of GetObject — carries the downloaded content. +/// Result of GetObject - carries the downloaded content. struct S3GetObjectResult : S3Result { IoBuffer Content; @@ -71,26 +72,26 @@ struct S3GetObjectResult : S3Result std::string_view AsText() const { return std::string_view(reinterpret_cast<const char*>(Content.GetData()), Content.GetSize()); } }; -/// Result of HeadObject — carries object metadata and existence status. +/// Result of HeadObject - carries object metadata and existence status. struct S3HeadObjectResult : S3Result { S3ObjectInfo Info; HeadObjectResult Status = HeadObjectResult::NotFound; }; -/// Result of ListObjects — carries the list of matching objects. +/// Result of ListObjects - carries the list of matching objects. struct S3ListObjectsResult : S3Result { std::vector<S3ObjectInfo> Objects; }; -/// Result of CreateMultipartUpload — carries the upload ID. +/// Result of CreateMultipartUpload - carries the upload ID. struct S3CreateMultipartUploadResult : S3Result { std::string UploadId; }; -/// Result of UploadPart — carries the part ETag. +/// Result of UploadPart - carries the part ETag. struct S3UploadPartResult : S3Result { std::string ETag; @@ -120,6 +121,11 @@ public: /// Download an object from S3 S3GetObjectResult GetObject(std::string_view Key); + /// Download a byte range of an object from S3 + /// @param RangeStart First byte offset (inclusive) + /// @param RangeSize Number of bytes to download + S3GetObjectResult GetObjectRange(std::string_view Key, uint64_t RangeStart, uint64_t RangeSize); + /// Delete an object from S3 S3Result DeleteObject(std::string_view Key); @@ -151,6 +157,16 @@ public: /// @param PartSize Size of each part in bytes (minimum 5 MB, default 8 MB) S3Result PutObjectMultipart(std::string_view Key, IoBuffer Content, uint64_t PartSize = 8 * 1024 * 1024); + /// High-level multipart upload: calls FetchRange(Offset, Size) to read each part on demand, + /// avoiding loading the full content into memory. + /// @param TotalSize Total object size in bytes + /// @param FetchRange Callback invoked once per part; must return exactly Size bytes + /// @param PartSize Size of each part in bytes (minimum 5 MB, default 8 MB) + S3Result PutObjectMultipart(std::string_view Key, + uint64_t TotalSize, + std::function<IoBuffer(uint64_t Offset, uint64_t Size)> FetchRange, + uint64_t PartSize = 8 * 1024 * 1024); + /// Generate a pre-signed URL for downloading an object (GET) /// @param Key The object key /// @param ExpiresIn URL validity duration (default 1 hour, max 7 days) |