Skip to content

Clean up manifests in batches - #2195

Open
lbussell wants to merge 18 commits into
mainfrom
lbussell/fix-acr-manifest-enumeration
Open

Clean up manifests in batches#2195
lbussell wants to merge 18 commits into
mainfrom
lbussell/fix-acr-manifest-enumeration

Conversation

@lbussell

@lbussell lbussell commented Jul 30, 2026

Copy link
Copy Markdown
Member

Problem: ACR cleanup currently happens in one shot. All manifests are queried from each repo all at once, and then they are deleted all at once. If there are too many manifests in a repo, then the cleanup pipeline can time out while listing the manifests before even deleting anything. As a result, manifests keep piling up and nothing gets deleted. This problem is exacerbated by recent ACR rate limiting changes.

This PR makes the following changes:

  • Manifests are queried and processed / deleted in batches of 250. This means that even if cleanup doesn't finish, progress will be made incrementally over multiple runs.
  • You can specify an overall time limit for the operation, after which the cleanup will stop gracefully, even if all repos/manifests were not processed.
  • Repos are processed sequentially rather than running them all in parallel. This is just to keep things simple / easier to understand after this refactor.

One could imagine running cleanup with less intensity and more frequency after these changes (perhaps running it for 30 minutes every hour?). We'll see after these changes.

This PR is part of #2056

lbussell and others added 17 commits July 27, 2026 15:41
Cleanup previously kicked off every matching repo in parallel via
Task.WhenAll, so a run was all-or-nothing: interrupting it left an
unpredictable slice of each repo half-processed. Enumerate and process
repos one at a time instead, which makes progress deterministic and is a
prerequisite for time-bounding a run.

Also drop the ExecuteWithCredentialsAsync wrapper and the associated
RegistryCredentialsOptions CLI arguments. It only performed a docker
login, which this command has no use for: IAcrClient and
IAcrContentClient authenticate through Azure credentials, and the
pipeline templates never passed credential args.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb10f0ed-33c3-4c35-9d73-88b928bd8e16
A pruneEol pass over public/dotnet/* enumerates every manifest in every
repo before deleting anything, so a run that exceeded the job timeout was
killed having deleted nothing. Stream manifests in batches of 250 and
delete each batch before fetching the next page, so an interrupted run
still leaves completed work behind.

Add --time-limit-minutes to stop cleanly at the next batch boundary and
wire it up for the public/dotnet/* pruneEol step, which is the step that
runs long. It is rejected for the delete action, which operates on whole
repositories rather than batches.

Batching also removes the "delete the whole repo when every manifest is
expired" shortcut, since completeness is no longer known up front.
Emptied repos are now reclaimed by the manifestCount == 0 path on the
next run.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb10f0ed-33c3-4c35-9d73-88b928bd8e16
Wrap long signatures and expressions, add blank lines between switch
cases, and rename the annotation digest constant in DeleteEolImages to
annotationDigest with a realistic sha256 value. No behavior change.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eb10f0ed-33c3-4c35-9d73-88b928bd8e16
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 66005c54-8aa6-432f-ae90-68ae43764f73
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e877a04f-8ec4-4024-8596-899e979b9064
@lbussell
lbussell requested a review from a team as a code owner July 30, 2026 16:42
Comment thread src/ImageBuilder/Commands/CleanAcrImagesOptions.cs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0e945098-1404-43ed-9c36-1cbee1ba37eb
@lbussell
lbussell enabled auto-merge (squash) July 31, 2026 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants