Skip to content

feat(python): complete the Pyodide FS backend — symlink/readlink + setattr→host#141

Closed
NathanFlurry wants to merge 1 commit into
mainfrom
python-fs-hooks
Closed

feat(python): complete the Pyodide FS backend — symlink/readlink + setattr→host#141
NathanFlurry wants to merge 1 commit into
mainfrom
python-fs-hooks

Conversation

@NathanFlurry

Copy link
Copy Markdown
Member

Closes the remaining gaps in the Pyodide custom Emscripten FS backend so it implements every node_op / stream_op the FS layer can dispatch (verified against the authoritative MEMFS ops_table in current emscripten main).

Before this PR

  • symlink (dir node) was an ENOSYS stubos.symlink() failed
  • readlink (link node) was missing — host symlinks weren't representable, os.readlink() unwired
  • setattr updated the in-isolate node onlyos.chmod/os.chown/os.utime never reached the host VFS

(allocate/statfs/fsync/poll are not hooks the current FS layer dispatches — confirmed against emscripten source — so they're correctly absent.)

Changes

  • New RPC methods fsSymlink / fsReadlink / fsSetattr (+ target/mode/uid/gid/atimeMs/mtimeMs wire fields and a SymlinkTarget response payload). JS numbers cross the bridge as f64, so the wire fields are f64 and narrowed.
  • Dispatcher routes them to kernel.symlink / read_link / chmod+chown+utimes. Kernel-direct, no shadow mirror — guest Python writes/creates live only in the kernel VFS, so mirroring create/modify ops into the host-side shadow would leave empty stubs that a later shadow→kernel sync resurrects over real content. (Delete/rename still mirror, to remove stale wire-written entries.)
  • Runner: symlink/readlink node ops + a link-node ops table, createWorkspaceNode now routes symlink-mode nodes, and setattr propagates mode/uid/gid/atime/mtime to the host.

Test

python_runtime_supports_symlink_readlink_and_metadata: os.symlink+os.readlink (in-process and host cross-check), os.path.islink, os.chmod (reflected on the host VFS), os.utime. Full python_suite stays green (caught + fixed a content-resurrection regression from the initial shadow-mirroring approach).

🤖 Generated with Claude Code

@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-141 June 28, 2026 01:16 Destroyed
@railway-app railway-app Bot temporarily deployed to rivet-frontend / secure-exec-pr-141 June 28, 2026 01:16 Destroyed
@railway-app

railway-app Bot commented Jun 28, 2026

Copy link
Copy Markdown

🚅 Deployed to the secure-exec-pr-141 environment in rivet-frontend

Service Status Web Updated (UTC)
secure-exec 😴 Sleeping (View Logs) Jun 28, 2026 at 1:26 am

🚅 Deployed to the secure-exec-pr-141 environment in secure-exec

Service Status Web Updated (UTC)
secure-exec 😴 Sleeping (View Logs) Web Jun 28, 2026 at 1:24 am

@NathanFlurry

Copy link
Copy Markdown
Member Author

Superseded by #142 (combined with the sockets work).

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