Skip to content

feat: FUSE-mount pod volumes instead of one-time copying - #6

Merged
vercel-eddie merged 1 commit into
mainfrom
feat/fuse-mount
May 19, 2026
Merged

vercel-eddie merged 1 commit into
mainfrom
feat/fuse-mount

Conversation

@vercel-eddie

Copy link
Copy Markdown
Collaborator

Summary

  • Replace the one-shot CopyFiles RPC with a read-only FUSE mount backed by a new BridgeFileSystemService on the existing proxy gRPC connection.
  • Each VolumeMount on the source container is exposed at the same absolute path inside the devcontainer, so rotated tokens, updated ConfigMaps, and projected volumes (IRSA / workload identity) reflect the live pod state instead of a stale snapshot.
  • Devcontainer feature option renamed copyFiles → mountPaths; create now adds SYS_ADMIN, --device /dev/fuse, and apparmor:unconfined only when the source has VolumeMounts.

Design

  • Proto (proto/bridge/v1/filesystem.proto): BridgeFileSystemService with Stat, ReadDir, ReadFile (offset/size chunked at 1 MiB), ReadLink. Stateless — every RPC takes an absolute path.
  • Server (pkg/fsmount/server.go): registered on the same gRPC port as the proxy. Authorizes every path against the configured --mount-roots allowlist; returns PermissionDenied for anything outside.
  • Client (pkg/fsmount/client.go): go-fuse v2 nodes that proxy each VFS op to a gRPC call. 5 s attribute/entry cache, FOPEN_KEEP_CACHE. Writes return EROFS.
  • Wiring: injectProxyImage derives --mount-roots from the source container's VolumeMounts; GetMetadata advertises them; bridge intercept calls fsmount.Mount per path once the gRPC connection is up. Mount failures are non-fatal — network interception still works without /dev/fuse.
  • Removed: CopyFiles RPC, copyFilesFromProxy in intercept, the now-unused volumeMountPaths helper in bundle.go.

Test plan

  • go test ./... — all packages green
  • New unit tests for fsmount.Server: allowlist auth, Stat/ReadDir/ReadFile/ReadLink, error mapping
  • New unit tests for injectProxyImage: emits --mount-roots when source has VolumeMounts, omits it otherwise
  • New linux-tagged integration test that runs the gRPC server in-process and verifies the FUSE round trip (auto-skips when /dev/fuse is unavailable)
  • Manual: bridge create -c userservice and confirm /var/run/secrets/... and other source mounts are live inside the devcontainer
  • Manual: confirm rotated IRSA tokens become visible without restarting intercept

Notes

  • Also fixes a pre-existing build failure on main in pkg/k8s/resources/transforms_test.go (stale Resource slice / Transform method API).
  • pkg/mutagen is still in the tree but was already unreferenced — left alone to keep this PR focused.

🤖 Generated with Claude Code

Replace the one-shot CopyFiles RPC with a read-only FUSE mount backed by
a new BridgeFileSystemService over the existing proxy gRPC connection.
Each VolumeMount on the source container is exposed at the same absolute
path inside the devcontainer, so rotated tokens, updated ConfigMaps, and
projected volumes (IRSA / workload identity) reflect the live pod state
instead of a stale snapshot taken at intercept startup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedgolang/​github.com/​hanwen/​go-fuse/​v2@​v2.10.185100100100100

View full report

@vercel-eddie
vercel-eddie merged commit d56df8f into main May 19, 2026
5 checks passed
@vercel-eddie
vercel-eddie deleted the feat/fuse-mount branch May 19, 2026 18:03
vercel-eddie added a commit that referenced this pull request May 19, 2026
go-fuse (added by FUSE-mount feature in #6) only compiles on unix; the
windows builder fails with undefined symbols. Drop the windows entry
from both edge and tagged release matrices.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant