Skip to content

gateway: create interface for reading from container filesystem#6262

Merged
tonistiigi merged 1 commit into
moby:masterfrom
jsternberg:container-fs-requests
Jan 14, 2026
Merged

gateway: create interface for reading from container filesystem#6262
tonistiigi merged 1 commit into
moby:masterfrom
jsternberg:container-fs-requests

Conversation

@jsternberg

Copy link
Copy Markdown
Collaborator

This creates an interface that can be used to read the filesystem of a
new container created through the gateway API. These filesystem reading
methods are tied to a specific container that has been created, but
aren't tied to the container itself.

Due to being run inside of buildkit, these containers have access to the
same mounts that a container request would have. This is useful for
features like the file explorer in buildx dap because it can access
container filesystem state from stages that error along with ones that
have completed successfully.

Offers a more robust solution to docker/buildx#3410.

@tonistiigi tonistiigi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Needs integration test.

I'm not sure if the mount selection really is feasible this way.

Comment thread frontend/gateway/container/container.go Outdated

func (gwCtr *gatewayContainer) findMount(ctx context.Context, fullpath string) (m executor.Mount, path string) {
m = gwCtr.rootFS
path, _ = filepath.Rel("/", fullpath)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure what this is supposed to do. Also error ignore.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It's mostly to remove the leading slash. The fs.FS interface requires relative paths and doesn't work with absolute paths.

Comment thread frontend/gateway/container/container.go Outdated
}

for _, mount := range gwCtr.mounts {
if strings.HasPrefix(fullpath, mount.Dest) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There has been no cleanup of fullpath afaics.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This doesn't seem to check directory boundaries as well iiuc.

Comment thread frontend/gateway/container/container.go Outdated

for _, mount := range gwCtr.mounts {
if strings.HasPrefix(fullpath, mount.Dest) {
remainder, err := filepath.Rel(mount.Dest, fullpath)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What if this is a symlink. Or contains a symlink somewhere in the path.

@jsternberg jsternberg added this to the v0.26.0 milestone Oct 8, 2025
@jsternberg jsternberg marked this pull request as draft October 8, 2025 20:26
@jsternberg

Copy link
Copy Markdown
Collaborator Author

Talked with @tonistiigi about this and we're going to change the path parsing logic to instead include the index of the mount as a client parameter. This puts the onus on the client for determining which mount they're accessing instead of trying to get that logic correct on the server where there might be more security concerns regarding symlinks.

This will also be a little better from the DAP perspective because we can put an entry for each mount instead of putting everything into the filesystem tree. That will result in the mount roots being more easily visible in DAP.

@jsternberg jsternberg modified the milestones: v0.26.0, v0.future Nov 11, 2025
Comment thread frontend/gateway/container/container.go Outdated
Comment on lines +480 to +488
// Check if this mount has already been mounted.
if f, ok := gwCtr.localMounts[mount]; ok {
return f, path, nil
}

ref, err := mount.Src.Mount(ctx, true)
if err != nil {
return nil, "", err
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Was discussing with @tonistiigi, potentially this logic is worth extending to the existing ReadFile/StatFile/etc, not just for containers?

Don't want to step on your toes here @jsternberg, would it be reasonable if I cherry-picked that change out into a separate PR if this one is in the v0.future milestone?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It's fine if you want to cherry pick it. This PR is going to likely undergo some changes though so I can't promise it'll be compatible. I had to do some other work that was a bit of a prerequisite to this one and I'm likely going to pick this up again either now or soon.

@jsternberg jsternberg force-pushed the container-fs-requests branch from 5cd1eac to 7186b8a Compare January 8, 2026 16:37
@thompson-shaun thompson-shaun modified the milestones: v0.future, v0.27.0 Jan 8, 2026
@jsternberg jsternberg force-pushed the container-fs-requests branch from 7186b8a to b10815a Compare January 8, 2026 19:35
@jsternberg jsternberg force-pushed the container-fs-requests branch 2 times, most recently from ac6e7ea to d47b53f Compare January 8, 2026 21:25
@jsternberg jsternberg marked this pull request as ready for review January 8, 2026 22:04
Comment thread frontend/gateway/pb/gateway.proto Outdated
Comment thread frontend/gateway/container/container.go Outdated
@jsternberg jsternberg force-pushed the container-fs-requests branch 2 times, most recently from f1ea495 to 511424f Compare January 14, 2026 17:06
This creates an interface that can be used to read the filesystem of a
new container created through the gateway API. These filesystem reading
methods are tied to a specific container that has been created, but
aren't tied to the container itself.

Due to being run inside of buildkit, these containers have access to the
same mounts that a container request would have. This is useful for
features like the file explorer in `buildx dap` because it can access
container filesystem state from stages that error along with ones that
have completed successfully.

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
@jsternberg jsternberg force-pushed the container-fs-requests branch from 511424f to 2999fdc Compare January 14, 2026 17:52
localMounts[i].Src = p.Root.Src
continue
}
localMounts[i].Src = mountableByDest[m.Dest]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe error case could be added in here in follow-up? To catch if anything goes wrong between the mnts and PreparedMounts constency.

@tonistiigi tonistiigi merged commit 9512a2e into moby:master Jan 14, 2026
222 of 223 checks passed
@jsternberg jsternberg deleted the container-fs-requests branch January 14, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants