Skip to content

Conversation

@jsternberg
Copy link
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.

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 <[email protected]>
Copy link
Member

@tonistiigi tonistiigi left a comment

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.


func (gwCtr *gatewayContainer) findMount(ctx context.Context, fullpath string) (m executor.Mount, path string) {
m = gwCtr.rootFS
path, _ = filepath.Rel("/", fullpath)
Copy link
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
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.

}

for _, mount := range gwCtr.mounts {
if strings.HasPrefix(fullpath, mount.Dest) {
Copy link
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
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.


for _, mount := range gwCtr.mounts {
if strings.HasPrefix(fullpath, mount.Dest) {
remainder, err := filepath.Rel(mount.Dest, fullpath)
Copy link
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
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.

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.

2 participants