Search code examples
bashazuresyntax-errortaskacr

ACR task for cleanup avoiding specific tags giving syntax error


I'm trying to create ACR tasks that would run acr purge command to cleanup of ACR registry.

Here is a command for ACR cleanup of 3 repositories, except those with the tag latest :

az acr run --cmd 'acr purge --filter '^dev\\/(repo1|repo2|repo_3)$:^((?!latest).)*$' --ago 5d --keep 4 --untagged --dry-run'  -c /dev/null -r acrregistry1

But the command is returning the error:

-bash: !latest: event not found

Then I tried changing the command to consider images with any tag:

az acr run --cmd 'acr purge --filter '^dev\\/(repo1|repo2|repo_3)$:.*' --ago 5d --keep 4 --untagged --dry-run'  -c /dev/null -r acrregistry1

That again returns an error:

-bash: syntax error near unexpected token `(' 

Is this a problem that I'm missing something very basic with bash?

Or is it something related to az that doesn't support negative lookahead in regex for tags?

Installed version of azure-cli : 2.53.1 *


Solution

  • Thanks @Imran, the solution you proposed worked well after also removing one \ from dev\\/ to make it dev\/.

    az acr run --cmd 'acr purge --filter '\''^dev\/(repo1|repo2|repo_3)$:^((?!latest).)*$'\'' --ago 5d --keep 4 --untagged --dry-run' -c /dev/null -r acrregistry1
    

    One extra backslash was required when Terraform was used to create ACR tasks that make use of the acr purge command. Terraform requires the \ of the cmd to be escaped using another \.

    Via the command line, you can create an ACR task that used acr purge command like this:

    az acr task create --cmd 'acr purge --filter '\''^dev\/(repo1|repo2|repo_3)$:^((?!latest).)*$'\'' --ago 5d --keep 4 --untagged --dry-run' -c /dev/null -r acrregistry1 --name testacrtask4
    

    Note: Try decoding the value of the encodedStep parameter found in the result JSON. Verify if the cmd is properly rendered or not.

    You can run the task as follows and verify the command is working as intended:

    az acr task run -r acrregistry1 --name testacrtask4
    

    If you are targeting a completely private ACR (accessible through private endpoints), you would need to follow the steps mentioned here (with ACR push role to the system-managed identity of the task) to make it work.

    Note:

    The regular expression ^((?!latest).)*$ matches string that doesn't contain latest. That means, when using this regexp for tags in the acr purge command, it will not remove images with latest, dev-latest, and latest-dev. If you want to avoid only the tags that are exactly equal to latest, use this regexp instead: ^((?!^latest$).)*$ or ^(?!^latest$).*$.