Skip to content

api/types/build: move build cache prune options from api to client#50772

Merged
thaJeztah merged 2 commits intomoby:masterfrom
austinvazquez:move-build-cache-prune-options-from-api-to-client
Sep 5, 2025
Merged

api/types/build: move build cache prune options from api to client#50772
thaJeztah merged 2 commits intomoby:masterfrom
austinvazquez:move-build-cache-prune-options-from-api-to-client

Conversation

@austinvazquez
Copy link
Contributor

@austinvazquez austinvazquez commented Aug 20, 2025

- What I did
Partial for #50740

This change moves the cache prune options to the client module.

- How I did it

- How to verify it

- Human readable description for the release notes

api/types/build: move `CachePruneOptions` type to `client.BuildCachePruneOptions`

- A picture of a cute animal (not mandatory but encouraged)

@austinvazquez austinvazquez force-pushed the move-build-cache-prune-options-from-api-to-client branch from d5de104 to 63f159d Compare August 20, 2025 12:46
@austinvazquez austinvazquez marked this pull request as ready for review August 20, 2025 14:05
@thaJeztah thaJeztah added this to the 29.0.0 milestone Aug 20, 2025
MinFreeSpace int64
Filters filters.Args

KeepStorage int64 // Deprecated: deprecated in API 1.48.
Copy link
Member

@thaJeztah thaJeztah Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if there's any mapping possible from the above options to the old option.

i.e., thinking if we can somehow keep the KeepStorage an internal implementation detail and set it automatically based on the other options when talking to an older API.

Actually, I"m not even sure now if we even use any of these (bear with me);

When running with buildx installed, docker builder prune is executed by buildx;

docker builder prune --help
Usage:  docker buildx prune

Remove build cache

Options:
  -a, --all                    Include internal/frontend images
      --builder string         Override the configured builder instance (default "desktop-linux")
  -D, --debug                  Enable debug logging
      --filter filter          Provide filter values (e.g., "until=24h")
  -f, --force                  Do not prompt for confirmation
      --max-used-space bytes   Maximum amount of disk space allowed to keep for cache
      --min-free-space bytes   Target amount of free disk space after pruning
      --reserved-space bytes   Amount of disk space always allowed to keep for cache
      --verbose                Provide a more verbose output

When buildx is missing, or explicitly disabled, only then we get the docker builder prune command from the CLI itself;

DOCKER_BUILDKIT=0 docker builder prune --help
DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
            BuildKit is currently disabled; enable it by removing the DOCKER_BUILDKIT=0
            environment-variable.

Usage:  docker builder prune

Remove build cache

Options:
  -a, --all                  Remove all unused build cache, not just dangling ones
      --filter filter        Provide filter values (e.g. "until=24h")
  -f, --force                Do not prompt for confirmation
      --keep-storage bytes   Amount of disk space to keep for cache

But I don't think "pruning build cache" makes sense if you don't have buildkit 🤔

so are we never using it?

Well, we are, but only as part of docker system prune, because that also calls the "builder prune" endpoint through the REST API;

https://github.com/docker/cli/blob/v28.3.3/cli/command/system/prune.go#L44-L45
https://github.com/docker/cli/blob/v28.3.3/cli/command/system/prune.go#L96-L98

But honestly, not even sure if that should be called if BuildKit is disabled (only if enabled), and it does not allow options to be passed, or only very limited.

When running docker buildx prune (or the docker builder prune alias) with BuildKit enabled (so now docker buildx is executed), I don't think we even hit the REST API. This could also mean that running docker buildx prune won't trigger docker daemon events 🤔 https://github.com/docker/buildx/blob/v0.27.0/commands/prune.go#L43-L47

(thinking about #50725 where Docker Desktop didn't receive some events)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOL, maybe @crazy-max or @jsternberg has some ideas on this; basically: does the docker builder prune command (i.e., the one in the docker CLI that's only available with either buildx missing or DOCKER_BUILDKIT=0 have any purpose?

We should probably keep the client part to back the docker system prune command, but even for that ... maybe we can make docker system prune shell out to docker buildx prune as one of the steps and skip the REST API - but we'd miss the daemon events (on the /events endpoint) 🤔

@austinvazquez austinvazquez force-pushed the move-build-cache-prune-options-from-api-to-client branch 2 times, most recently from 51702ef to d01ecdb Compare August 26, 2025 12:32
Comment on lines -699 to -701
if opts.ReservedSpace == 0 && opts.KeepStorage != 0 {
opts.ReservedSpace = opts.KeepStorage
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to account for old clients setting that option?

@crazy-max if you have time to look along (also see my comment further up, which made my head spin a little 😅)

Copy link
Contributor Author

@austinvazquez austinvazquez Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that is covered in the router code. Ref:

opts.ReservedSpace = bs

From what I see KeepStorage was not being set server side.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah; derp; missed that one. It was late 😂

@austinvazquez austinvazquez added the release-blocker PRs we want to block a release on label Aug 28, 2025
@austinvazquez austinvazquez self-assigned this Aug 28, 2025
@austinvazquez austinvazquez force-pushed the move-build-cache-prune-options-from-api-to-client branch from d01ecdb to 3e8a7d6 Compare September 3, 2025 22:24
@austinvazquez
Copy link
Contributor Author

Okay, I improved my understanding for the state of keep-storage query parameter support. Here goes. The keep-storage query parameter was renamed in API v1.48 to reserved-space. i.e. keep-storage was deprecated and targeted for removal in API v1.49 and support for reserved-space was added. The engine has carried server-side logic if API v1.48 or greater check reserved-space else fallback to keep-storage.

I have updated the API documentation to correctly reflect keep-storage will be removed in API v1.52 and also removed it from the client and backend options. For backwards compatability with older clients, the server will continue to read keep-storage on API versions prior to v1.48 and have the fallback from v[1.48,1.52).

Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
@austinvazquez austinvazquez force-pushed the move-build-cache-prune-options-from-api-to-client branch from 3e8a7d6 to 7e2ee18 Compare September 4, 2025 16:29
@austinvazquez
Copy link
Contributor Author

Rebased to resolve vendor conflicts.

@thaJeztah
Copy link
Member

Had another peek at the CLI, but it looks like the deprecated KeepStorage is the ONLY option currently used there; https://github.com/docker/cli/blob/1f12d795db568a9a5068b49de3ead38aa4eb3e5d/cli/command/builder/prune.go#L92

Which means that;

  • Any existing CLI will send the keep-storage option, and no other options, so we need to have the API endpoint convert the keep-storage query parameter to whatever the replacement is for API < 1.52
  • The client must continue sending the keep-storage option when communicating with API < 1.52 and/or convert the options to what's supported by the API version used.
  • For the Client Go Code, we could remove the field from the options, as long as we would use one of the new fields that is a direct replacement and use that field to set keep-storage for older API versions, and the new field for newer API versions.

I'm not exactly sure what new options are equivalent of the old options though, which I think was the reason I didn't update the CLI code I linked above 😂 🙈

Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
@austinvazquez austinvazquez force-pushed the move-build-cache-prune-options-from-api-to-client branch from 7e2ee18 to 26e335b Compare September 4, 2025 21:34
@austinvazquez
Copy link
Contributor Author

Had another peek at the CLI, but it looks like the deprecated KeepStorage is the ONLY option currently used there; https://github.com/docker/cli/blob/1f12d795db568a9a5068b49de3ead38aa4eb3e5d/cli/command/builder/prune.go#L92

@thaJeztah, I can help follow-up on that.

Any existing CLI will send the keep-storage option, and no other options, so we need to have the API endpoint convert the keep-storage query parameter to whatever the replacement is for API < 1.52

The daemon backend has this logic in place now. Anything prior to API 1.48 will parse keep-storage; after (inclusive) API 1.48 first tries reserved-space before falling back to keep-storage.

The client must continue sending the keep-storage option when communicating with API < 1.52 and/or convert the options to what's supported by the API version used.
For the Client Go Code, we could remove the field from the options, as long as we would use one of the new fields that is a direct replacement and use that field to set keep-storage for older API versions, and the new field for newer API versions.

Makes sense, pushed that change to the client and added a task when it can be removed.

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can help follow-up on that.

Thanks! I think at the time I wasn't 100% sure what the replacement was, so jotted down that "TODO"; looks like it's just swapping for ReservedSpace, correct?

Makes sense, pushed that change to the client and added a task when it can be removed.

Thanks!

LGTM

if opts.ReservedSpace != 0 {
query.Set("reserved-space", strconv.Itoa(int(opts.ReservedSpace)))
// Prior to API v1.48, 'keep-storage' was used to set the reserved space for the build cache.
// TODO(austinvazquez): remove once API v1.47 is no longer supported. See https://github.com/moby/moby/issues/50902
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for these version-specific constraints we don't have to keep separate tracking tickets; the version-gate itself is an implicit "remove once we drop this version".

Definitely fine for a follow-up, or when we rewrite these to functional args; for the functional args, perhaps we can even use our own struct tags on options for checking the API version 🤔

Comment on lines -699 to -701
if opts.ReservedSpace == 0 && opts.KeepStorage != 0 {
opts.ReservedSpace = opts.KeepStorage
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah; derp; missed that one. It was late 😂

@thaJeztah
Copy link
Member

We can cherry-pick the first commit to the 28.x branch in case we do more (patch) releases from that branch

@thaJeztah thaJeztah merged commit 432c9e8 into moby:master Sep 5, 2025
187 of 202 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api API area/go-sdk impact/api impact/changelog kind/refactor PR's that refactor, or clean-up code release-blocker PRs we want to block a release on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants