5

I want to delete all images in Azure Container Registry except the last two. I was looking for an script for do so but I only find to delete images older than X days. This is not possible for my situation because some days there are a lot of images created and other days only one.

Somebody has any idea?

silent
  • 14,494
  • 4
  • 46
  • 86
exitista
  • 563
  • 2
  • 10
  • 21

7 Answers7

11

Modify the values for $skipLastTags & $registryName to your choice and run this script on powershell.

Note: Please verify that you have az cli installed on your local system.

$registryName = 'registryName'
$doNotDeleteTags = ''
$skipLastTags = 4

$repoArray = (az acr repository list --name $registryName --output json | ConvertFrom-Json)

foreach ($repo in $repoArray)
{
    $tagsArray = (az acr repository show-tags --name $registryName --repository $repo --orderby time_asc --output json | ConvertFrom-Json ) | Select-Object -SkipLast $skipLastTags

    foreach($tag in $tagsArray)
    {

        if ($donotdeletetags -contains $tag)
        {
            Write-Output ("This tag is not deleted $tag")
        }
        else
        {
            az acr repository delete --name $registryName --image $repo":"$tag --yes
        }
 
    }
}
Manish Bhakuni
  • 199
  • 2
  • 4
4

If you need this in bash.

The variable delete_from is 1-index based, i.e. if you specify the value 1, all images will be deleted. A value of 3 keeps the 2 latest images.

#!/bin/bash -e

acr='your_acr'
repos=('repo1' 'repo2' 'repoN')
delete_from=3

for repo in "${repos[@]}"; do
    tags_to_delete=$(echo $(az acr repository show-tags -n ${acr} --repository ${repo} --orderby time_desc --output tsv) | cut -d ' ' -f${delete_from}-) 
    for tag_to_delete in ${tags_to_delete}; do
        az acr repository delete --yes -n ${acr} --image ${repo}:${tag_to_delete}
    done
done
1

I am unable to test it right now but this little PowerShell script should work:

$acrName = 'YourACRName'

$repo = az acr repository list --name $acrName
$repo | Convertfrom-json | Foreach-Object {
    $imageName = $_
    (az acr repository show-tags -n $acrName --repository $_ | 
        convertfrom-json )| Select-Object -SkipLast 2 | Foreach-Object {
        az acr repository delete --yes -n $acrName --image "$imageName:$_"
        }
}

It retrieves all tags for each repository, skips the last 2, then it iterates over each tag and deletes it.

Please test it in some kind of test environment first.

Martin Brandl
  • 56,134
  • 13
  • 133
  • 172
  • Hello Martin, sorry for my late reply. I have 6 repositories so I also want to set the repository. Is this possible? Thanks in advance – exitista Aug 30 '19 at 17:42
  • any idea? Thanks in advance! Regards – exitista Sep 02 '19 at 17:55
  • Your solution was really helpful. I have one condition to add which should skip few image and it should not be deleted, even it is coming in deletion list. For example i have some image like `abc:v1, def:v2,xyz:v4` which should not be deleted in any case which i can add as a hard code value so that system not delete that. In the below solution if we can add a condition to skip some hardcoded image given so that these will not be deleted. May be under forach block we can add a condition and add list of image which should be skipped? – Rajiv Mishra Sep 10 '20 at 08:30
  • @RajivMishra Thanks for the Feedback. I agree that this would be helpful but the question was about skipping the last two images so it would be a wrong answer to this question. In general, you just have to add a `| Where-Object {$_ -notin $yourListOfImagesToKeep}` after the `ConvertFrom-Json` – Martin Brandl Sep 10 '20 at 13:57
0

If with "the last two" you mean the newest two, then this should do the trick:

az acr repository show-manifests --name your_acr --repository your_repo --orderby time_desc -o tsv --query '[].digest' | sed -n '3,$ p' | xargs -I% az acr repository delete --name your_acr --image your_repo@% --yes
Harald
  • 13
  • 2
0

You can use the build in acr purge command:

Powershell

$subscription = "your-subscription-id"
$registry = "your-registry"
$PURGE_CMD = "acr purge --filter 'acs-weather-api:.*' --keep 2 --ago 0d --untagged"
az acr run --cmd $PURGE_CMD --registry $registry --subscription $subscription  /dev/null

Bash

SUBSCRIPTION="your-subscription-id"
REGISTRY="your-registry"
PURGE_CMD="acr purge --filter 'acs-weather-api:.*' --keep 2 --ago 0d --untagged"
az acr run --cmd "$PURGE_CMD" --registry "$REGISTRY" --subscription "$SUBSCRIPTION"  /dev/null

Docs

Preben Huybrechts
  • 5,853
  • 2
  • 27
  • 63
0

Based on the answer from @Christian Holm Jørgensen

Now you can have list to be saved (save_list).

#!/bin/bash -e

acr='MY_ACR_NAME'
repos=('MY_REPO') # 'repo2' 'repoN')

save_list="0.2.0-alpha.1 latest 1.0.0"

string_remove_pattern() {
      echo "${1//$2}"
    }

for repo in "${repos[@]}"; do
    tags_available=$(echo $(az acr repository show-tags -n "${acr}" --repository "${repo}" --orderby time_desc --output tsv)) 
    for to_save in $save_list; do
      tags_available=$(string_remove_pattern "$tags_available" "$to_save")
    done

    tags_to_delete=$tags_available
    echo -e "The follow image, from ACR $acr and repos $repos, will be deleted:\n$tags_to_delete"
    read -rp "Is the list of image to delete correct? (Y/N)" answer
    if [ "$answer" == "Y" ]; then
      for tag_to_delete in ${tags_to_delete}; do
          az acr repository delete --yes -n "${acr}" --image "${repo}":"${tag_to_delete}"
      done
    fi
done
Zioalex
  • 3,441
  • 2
  • 33
  • 30
0

You can use acr purge's --keep option to achieve that.

Please note that acr-cli is not a part of az-cli yet, you need to build it from the source or use from a docker image.

For example, to keep 3 images;

acr purge \
    --registry <Registry Name> \
    --filter <Repository Filter/Name>:<Regex Filter> \
    --keep 3

You can also combine this with days ago filter:

acr purge \
    --registry <Registry Name> \
    --filter <Repository Filter/Name>:<Regex Filter> \
    --ago 30d \
    --keep 3

For more information, please refer to the acr-cli repo.

Furkan Tektas
  • 309
  • 3
  • 6