Created
November 5, 2020 16:15
-
-
Save tillig/51139dadc905231629555cae0ce92e52 to your computer and use it in GitHub Desktop.
Prunes the set of images in an Azure Container Registry.
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
<# | |
.SYNOPSIS | |
Trims down the set of images in an Azure Container Registry. | |
.DESCRIPTION | |
There isn't really a retention policy setting on ACR such that the last X | |
tags will be retained for a given repository. This script helps bridge that gap by | |
going through all the repositories in an ACR, selecting the latest X tags to ignore, | |
then removing tags that were created after that time. | |
.PARAMETER Registry | |
The name of the container registry with the images to prune. | |
.PARAMETER TagsToKeep | |
The number of recent tags to keep. | |
.PARAMETER RepositoryMatch | |
An optional filter regex that allows you to only prune repositories that match the expression. | |
.EXAMPLE | |
./Delete-AzureContainerImages.ps1 ` | |
-Registry "sourceacr" ` | |
-TagsToKeep 5 | |
This will prune every repository in the `sourceacr` registry. Each repository will | |
only keep the most recent five tags. | |
.EXAMPLE | |
./Delete-AzureContainerImages.ps1 ` | |
-Registry "sourceacr" ` | |
-TagsToKeep 5 ` | |
-RepositoryMatch 'services/accounts/.+' | |
This will prune every repository in the `sourceacr` registry that has a name | |
matching the regular expression 'services/accounts/.+' - so `services/accounts/test` | |
and `services/accounts/spec` will be pruned, but `services/balances/test` will not. | |
Only the most recent five tags will be kept. | |
#> | |
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')] | |
Param( | |
[Parameter(Mandatory = $True)] | |
[ValidateNotNullOrEmpty()] | |
[ValidateLength(5, 50)] | |
[ValidatePattern('[a-z0-9]+')] | |
[string] | |
$Registry, | |
[Parameter(Mandatory = $True)] | |
[ValidateRange(1, [System.Int32]::MaxValue)] | |
[int] | |
$TagsToKeep, | |
[Parameter(Mandatory = $False)] | |
[string] | |
$RepositoryMatch | |
) | |
Begin { | |
Write-Verbose "Checking for az CLI." | |
If ($null -eq (Get-Command "az")) { | |
Throw "The az CLI was not found. Install here: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli" | |
Exit 1 | |
} | |
} | |
Process { | |
Write-Progress -Activity "Pruning Azure Container Registry Images" -Status "Getting images from $Registry" -CurrentOperation "Retrieving repository list" -PercentComplete 1 | |
$RepoListJson = az acr repository list -n $Registry | |
If ($LASTEXITCODE -ne 0) { | |
Throw "Unable to read repository list from $Registry." | |
Exit 1 | |
} | |
$RepoList = $RepoListJson | ConvertFrom-Json -NoEnumerate | |
Write-Verbose "Found $($SourceRepoList.Length) repositories in $Registry." | |
$ImagesToPrune = @() | |
for ($i = 1; $i -le $RepoList.Length; $i++) { | |
$RepositoryName = $RepoList[$i - 1] | |
$PercentComplete = 25 * ($i / $RepoList.Length) | |
Write-Progress -Activity "Pruning Azure Container Registry Images" -Status "Getting image tags from $Registry" -CurrentOperation "Retrieving tags for $RepositoryName" -PercentComplete $PercentComplete | |
If ((-not [System.String]::IsNullOrWhiteSpace($RepositoryMatch)) -and (-not ($RepositoryName -match $RepositoryMatch))) { | |
Write-Verbose "$RepositoryName does not match against $RepositoryMatch; skipping." | |
Continue | |
} | |
$TagListJson = az acr repository show-tags -n $Registry --repository $RepositoryName --orderby time_desc | |
If ($LASTEXITCODE -ne 0) { | |
Throw "Unable to read repository tags for $RepositoryName from $Registry." | |
Exit 1 | |
} | |
$TagList = $TagListJson | ConvertFrom-Json -NoEnumerate | |
Write-Verbose "Found $($TagList.Length) tags for $RepositoryName." | |
for ($j = 0; $j -lt $TagList.Length; $j++) { | |
If ($j -lt $TagsToKeep) { | |
Continue | |
} | |
$Tag = $TagList[$j] | |
$ImagesToPrune += "$RepositoryName`:$Tag" | |
} | |
} | |
for ($i = 1; $i -le $ImagesToPrune.Length; $i++) { | |
$ImageName = $ImagesToPrune[$i - 1] | |
$PercentComplete = 25 + 75 * ($i / $ImagesToPrune.Length) | |
Write-Progress -Activity "Pruning Azure Container Registry Images" -Status "Pruning images" -CurrentOperation "Removing $ImageName" -PercentComplete $PercentComplete | |
If ($PSCmdlet.ShouldProcess($ImageName, "Prune image")) { | |
az acr repository delete -n $Registry --image $ImageName --only-show-errors -y | Out-Null | |
If ($LASTEXITCODE -ne 0) { | |
Throw "Failed to prune $ImageName." | |
Exit 1 | |
} | |
} | |
} | |
Write-Progress -Activity "Copying Azure Container Registry Images" -Completed | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment