Last active
January 14, 2025 02:19
-
-
Save kkbruce/14163848c2ef1f91d5591dcfcb61a537 to your computer and use it in GitHub Desktop.
自動化刪除ACR Repository中過期的映像檔。Automatically delete expired images in the ACR Repository.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ############################################### | |
# First we need to login to Azure | |
# 1. az login --device-code | |
# or | |
# 2. az login --service-principal -u $ServicePrincipalId -p $ServicePrincipalSecret --tenant $TenantId | |
# 3. az account set --subscription $SubscriptionId | |
# Then we can run the script | |
# ############################################### | |
# az acr command reference: # https://learn.microsoft.com/zh-tw/cli/azure/acr?view=azure-cli-latest | |
# ############################################### | |
function Get-repositoryInfo { | |
param ( | |
[string]$registryName, | |
[string]$repository | |
) | |
$reposTags = az acr manifest list-metadata --name $repository --registry $registryName --orderby time_desc -o tsv --query "[*].tags" | |
$reposDigests = az acr manifest list-metadata --name $repository --registry $registryName --orderby time_desc -o tsv --query "[*].digest" | |
return @{ | |
tags = $reposTags | |
digests = $reposDigests | |
infoCount = $reposDigests.Count | |
} | |
} | |
function Remove-OldRepositoryImages { | |
param ( | |
[string]$registryName, | |
[string]$repository, | |
[object]$reposInfo, | |
[string]$deleteMethod = "byDigest" | |
) | |
### Deleting a tag does not necessarily delete the digest, but deleting the digest will also delete the tag. ### | |
if ($deleteMethod -eq "byDigest") { | |
Write-Output "Deleting repository $repository by digests" | |
### Keep the latest 2 digests ### | |
$tetainDigests = $reposInfo.digests | Select-Object -First 2 | |
$digestList = $reposInfo.digests | Select-String -Pattern $tetainDigests -NotMatch | |
Write-Output "deleting digest count: $($digestList.Count)" | |
foreach ($digest in $digestList) { | |
### 'name@digest' is the format of the --image parameter ### | |
Write-Output "az acr repository delete --name $registryName --image $($repository + '@' + $digest) --yes" | |
az acr repository delete --name $registryName --image $($repository + '@' + $digest) --yes | |
} | |
} | |
if ($deleteMethod -eq "byTag") { | |
Write-Output "Deleting repository $repository by tags" | |
### Keep the latest 2 tags ### | |
$tetainTags = $reposInfo.tags | Select-Object -First 2 | |
$tagList = $reposInfo.tags | Select-String -Pattern $tetainTags -NotMatch | |
Write-Output "deleting tag count: $($tagList.Count)" | |
foreach ($Tag in $tagList) { | |
### 'name:tag' is the format of the --image parameter ### | |
Write-Output "az acr repository delete --name $registryName --image $($repository + ':' + $tag) --yes" | |
az acr repository delete --name $registryName --image $($repository + ':' + $tag) --yes | |
} | |
} | |
} | |
function Invoke-ACRDeleteProcess { | |
param ( | |
[string]$registryName | |
) | |
### In my situation, "dev" and "doc" are limited to the ":latest" tag, no deletion operation is required. ### | |
$repositories = az acr repository list -n $registryName -o tsv ` | |
| Where-Object { $_ -like "*qas*" -or $_ -like "*release*" } ` | |
| Where-Object { $_ -notlike "*doc*" } | |
$repositories | ForEach-Object { | |
$repository = $_ | |
Write-Output "Processing repository $repository" | |
$reposInfo = Get-repositoryInfo -registryName $registryName -repository $repository | |
Write-Output "Repository information count: $($reposInfo.infoCount)" | |
if ($reposInfo.infoCount -gt 2) { | |
# Remove-OldRepositoryImages -registryName $registryName -repository $repository -reposInfo $reposInfo -deleteMethod "byTag" | |
Remove-OldRepositoryImages -registryName $registryName -repository $repository -reposInfo $reposInfo -deleteMethod "byDigest" | |
} | |
else { | |
Write-Output "No images to delete for $repository" | |
} | |
} | |
} | |
# Main | |
$registryName = "YourRegistryName" | |
Invoke-ACRDeleteProcess -registryName $registryName |
Revisions 2, fixed.
Revisions 3, refactor.
不需要登入 Azure (az login
)的版本,請參考:
https://blog.kkbruce.net/2025/01/automation-run-azure-acr-cli-methods.html
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
發現一個問題,有些 repository 裡的 image 真的很久很久沒更新,如果用程式跑(用日期判斷),會因為 image 刪光光,造成它會連整個 repository 被刪除。下一版進行改進。