From af9e87a03dcc6b20a41a81491cd8fbf6e68be35f Mon Sep 17 00:00:00 2001 From: mattheweaid Date: Thu, 18 Sep 2025 11:48:49 +0000 Subject: [PATCH 1/2] added function to change access tier of blob --- src/AzStorage.jl | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/AzStorage.jl b/src/AzStorage.jl index 78b2469..f44fa47 100644 --- a/src/AzStorage.jl +++ b/src/AzStorage.jl @@ -1210,6 +1210,85 @@ function Base.cp(src::AzContainer, dst::AzContainer) nothing end +""" + list_extent_names(container) + +Return list of extents for `container::AzContainer` +""" +function list_extent_names(container::AzContainer) + marker = "" + extent_names = String[] + storage_account = container.storageaccount + + while true + url = "https://$storage_account.blob.core.windows.net/$(container.containername)?restype=container&comp=list&prefix=$(container.prefix)/extents/" + if !isempty(marker) + url *= "&marker=$marker" + end + + headers = [ + "Authorization" => "Bearer $(token(container.session))", + "x-ms-version" => API_VERSION, + ] + + response = HTTP.get(url, headers) + content = String(response.body) + + # Extract extent names + matches = collect(eachmatch(r"extent-\d{6}", content)) + append!(extent_names, [m.match for m in matches]) + + # Extract NextMarker + marker_match = match(r"(.*?)", content) + marker = marker_match !== nothing ? marker_match.captures[1] : "" + + if isempty(marker) + break + end + end + + @info "Total extents found: $(length(extent_names))" + return extent_names +end + +""" + rehydrate_blob(container,tier) + +Blobs that have changed to access level archive, are no longer readable. +This function rehyrates a blob (changes access tier) from archive to +`tier::String`. The options for `tier::String`` are Cold, Cool, Hot. +""" +function rehydrate_blob(container::AzContainer,tier::String) + + headers = [ + "Authorization" => "Bearer $(token(container.session))", + "x-ms-version" => API_VERSION, + "x-ms-access-tier" => tier, + "Content-Length" => "0" + ] + + storage_account = container.storageaccount + container_path = joinpath(container.containername,container.prefix) + + # Rehydrate description + file = container_path*"/description.json" + @info "Rehydrating file $file to tier $tier" + url = "https://$storage_account.blob.core.windows.net/$file?comp=tier" + + response = HTTP.request("PUT", url, headers) + + # Rehydrate extents + extent_names = list_extent_names(container) + for extent_name in extent_names + file = container_path*"/extents/"*extent_name + @info "Rehydrating file $file to tier $tier" + + url = "https://$storage_account.blob.core.windows.net/$file?comp=tier" + response = HTTP.request("PUT", url, headers) + end +end + + struct PerfCounters ms_wait_throttled::Clonglong ms_wait_timeouts::Clonglong From 2716b53b53915dbde42d04163640a76526e01e2c Mon Sep 17 00:00:00 2001 From: mattheweaid Date: Thu, 18 Sep 2025 17:26:54 +0000 Subject: [PATCH 2/2] update the regex in matches to be more flexible --- src/AzStorage.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AzStorage.jl b/src/AzStorage.jl index f44fa47..4832412 100644 --- a/src/AzStorage.jl +++ b/src/AzStorage.jl @@ -1235,7 +1235,7 @@ function list_extent_names(container::AzContainer) content = String(response.body) # Extract extent names - matches = collect(eachmatch(r"extent-\d{6}", content)) + matches = collect(eachmatch(r"extent-0*([1-9]\d*)", content)) append!(extent_names, [m.match for m in matches]) # Extract NextMarker