fix garageS3
This commit is contained in:
+124
-7
@@ -1,4 +1,4 @@
|
||||
module GarageS3
|
||||
module garageS3
|
||||
|
||||
export
|
||||
GarageStorage,
|
||||
@@ -7,8 +7,7 @@ export
|
||||
list_files,
|
||||
delete_file
|
||||
|
||||
using AWS
|
||||
using AWSS3
|
||||
using AWS, AWSS3
|
||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||
|
||||
# Garage uses Path-Style routing (https://s3-api.my-domain.com/bucket/key).
|
||||
@@ -64,10 +63,36 @@ AWS.check_credentials(c::SimpleCredentials) = c
|
||||
AWS.region(aws::GarageConfig) = aws.region
|
||||
AWS.credentials(aws::GarageConfig) = aws.credentials
|
||||
|
||||
""" Generate the base URL for a Garage S3 service request.
|
||||
|
||||
# Arguments
|
||||
- `aws::GarageConfig`
|
||||
The Garage configuration containing the endpoint.
|
||||
- `service::String`
|
||||
The AWS service name (e.g., `"s3"`).
|
||||
- `region::String`
|
||||
The AWS region string.
|
||||
|
||||
# Return
|
||||
- `String`: The stripped endpoint URL (trailing slashes removed).
|
||||
"""
|
||||
function AWS.generate_service_url(aws::GarageConfig, service::String, region::String)
|
||||
return strip(aws.endpoint, '/')
|
||||
end
|
||||
|
||||
""" Generate the full service URL including the resource path for a Garage S3 request.
|
||||
|
||||
# Arguments
|
||||
- `aws::GarageConfig`
|
||||
The Garage configuration containing the endpoint.
|
||||
- `service::String`
|
||||
The AWS service name (e.g., `"s3"`).
|
||||
- `resource::String`
|
||||
The S3 resource path (e.g., `"/bucket/key"`).
|
||||
|
||||
# Return
|
||||
- `String`: The full URL combining the endpoint and resource path.
|
||||
"""
|
||||
function AWS.generate_service_url(aws::GarageConfig, service::String, resource::String)
|
||||
endpoint = strip(aws.endpoint, '/')
|
||||
resource_path = startswith(resource, '/') ? resource : "/" * resource
|
||||
@@ -82,14 +107,61 @@ struct GarageStorage
|
||||
config::GarageConfig
|
||||
bucket::String
|
||||
end
|
||||
""" Create a thread-safe Garage S3 storage client.
|
||||
|
||||
# Arguments
|
||||
- `endpoint::String`
|
||||
The Garage S3 API endpoint URL (e.g., `"https://s3-api.yiem.cc"`).
|
||||
- `key::String`
|
||||
The Garage access key ID (created via garage-ui).
|
||||
- `secret::String`
|
||||
The secret key corresponding to the access key.
|
||||
- `bucket::String`
|
||||
The name of the S3 bucket to use.
|
||||
|
||||
# Keyword Arguments
|
||||
- `region::String = "garage"`
|
||||
The region identifier for the Garage instance.
|
||||
|
||||
# Return
|
||||
- `GarageStorage`: A thread-safe storage client instance.
|
||||
|
||||
# Examples
|
||||
```jldoctest
|
||||
julia> storage = GarageStorage("https://s3-api.yiem.cc", "GKb080154a2e5b19100b1b2c6e", "a2c6b1379c2f731d3e6e5a408dd4d6cffca7511717675f55114ff94828febca1", "sommpanion-s3")
|
||||
GarageStorage(GarageConfig(...), "sommpanion-s3")
|
||||
```
|
||||
"""
|
||||
function GarageStorage(endpoint::String, key::String, secret::String, bucket::String; region::String="garage")
|
||||
creds = SimpleCredentials(key, secret, "")
|
||||
config = GarageConfig(endpoint, region, creds)
|
||||
return GarageStorage(config, bucket)
|
||||
end
|
||||
|
||||
# Write object to Garage
|
||||
""" Upload an object to the Garage S3 bucket.
|
||||
|
||||
# Arguments
|
||||
- `storage::GarageStorage`
|
||||
The storage client instance.
|
||||
- `key::String`
|
||||
The object key (name) in the bucket. Must not contain slashes (`/`).
|
||||
- `data::Union{String, Vector{UInt8}}`
|
||||
The data to upload.
|
||||
|
||||
# Return
|
||||
- `Nothing` if the key contains slashes (upload aborted with warning).
|
||||
- Prints a success message if the upload completes.
|
||||
|
||||
# Notes
|
||||
- Slashes in keys are prohibited to prevent S3 listing issues. Use a flat naming
|
||||
convention (e.g., `"users-1002.json"` instead of `"users/1002.json"`).
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
julia> put_file(storage, "test.json", "{\"status\": \"active\"}")
|
||||
Successfully uploaded: test.json
|
||||
```
|
||||
"""
|
||||
function put_file(storage::GarageStorage, key::String, data::Union{String, Vector{UInt8}})
|
||||
# Check if the key contains a slash (virtual folder character)
|
||||
if occursin('/', key)
|
||||
@@ -102,19 +174,64 @@ function put_file(storage::GarageStorage, key::String, data::Union{String, Vecto
|
||||
println("Successfully uploaded: ", key)
|
||||
end
|
||||
|
||||
# Read object from Garage
|
||||
""" Download an object from the Garage S3 bucket.
|
||||
|
||||
# Arguments
|
||||
- `storage::GarageStorage`
|
||||
The storage client instance.
|
||||
- `key::String`
|
||||
The object key (name) in the bucket.
|
||||
|
||||
# Return
|
||||
- `Vector{UInt8}`: The raw bytes of the downloaded object.
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
julia> data = String(get_file(storage, "test.json"))
|
||||
"\"{\\\"status\\\": \\\"active\\\"}\""
|
||||
```
|
||||
"""
|
||||
function get_file(storage::GarageStorage, key::String)::Vector{UInt8}
|
||||
return s3_get(storage.config, storage.bucket, key)
|
||||
end
|
||||
|
||||
# List keys in bucket (Thread-safe & explicit credentials)
|
||||
""" List all object keys in the Garage S3 bucket.
|
||||
|
||||
# Arguments
|
||||
- `storage::GarageStorage`
|
||||
The storage client instance.
|
||||
|
||||
# Return
|
||||
- `Vector{String}`: A list of object keys (file names) in the bucket.
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
julia> keys = list_files(storage)
|
||||
3-element Vector{String}:
|
||||
"test1.json"
|
||||
"test2.json"
|
||||
"users-1002.json"
|
||||
```
|
||||
"""
|
||||
function list_files(storage::GarageStorage)
|
||||
# Approach 2: s3_list_objects returns a Vector of Dicts with object details
|
||||
objects = s3_list_objects(storage.config, storage.bucket)
|
||||
return [obj["Key"] for obj in objects]
|
||||
end
|
||||
|
||||
# Delete object from Garage
|
||||
""" Delete an object from the Garage S3 bucket.
|
||||
|
||||
# Arguments
|
||||
- `storage::GarageStorage`
|
||||
The storage client instance.
|
||||
- `key::String`
|
||||
The object key (name) to delete.
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
julia> delete_file(storage, "test.json")
|
||||
```
|
||||
"""
|
||||
function delete_file(storage::GarageStorage, key::String)
|
||||
s3_delete(storage.config, storage.bucket, key)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user