Skip to content

feat(python): Pyodide python/python3 CLI + whole-VM-root filesystem + VFS-persistent pip#138

Merged
NathanFlurry merged 1 commit into
mainfrom
python-cli
Jun 27, 2026
Merged

feat(python): Pyodide python/python3 CLI + whole-VM-root filesystem + VFS-persistent pip#138
NathanFlurry merged 1 commit into
mainfrom
python-cli

Conversation

@NathanFlurry

Copy link
Copy Markdown
Member

Adds a first-class python / python3 CLI backed by the embedded Pyodide runtime, wires the whole VM filesystem into Python, and makes pip install persist across invocations.

What's here

CLIpython/python3 resolve as runtime commands (like node): is_python_runtime_command + resolve_python_command_execution handle -c, script.py (+ sys.argv), -m, -/stdin programs, the interactive REPL, and pip/python -m pip, on both the top-level execute path and nested child_process spawns. python3 is registered + /bin/python is kept (prune removed) so the guest shell resolves python on PATH (sh -c "python …", pipelines). TS GuestRuntimeKind includes "python".

Filesystem (whole VM root) — the kernel VFS is mounted over the VM's real top-level dirs (/tmp, /etc, /root, /usr, the workspace, …); Pyodide keeps its own runtime paths (/lib stdlib, /dev, /proc, /home) on the in-isolate MEMFS. The VFS-RPC guard widens /workspace/ — the kernel still enforces fs permissions and symlink/mount confinement on every op (parity with the JS/WASM runtimes; no new escape). Nested-python children that can't reach the VFS get a recoverable error and fall back to the in-isolate FS.

Persistent pip — a VFS-backed site-packages (/root/.agentos/site-packages, appended to sys.path); the pip shim copies micropip installs there so a package installed in one process imports in a later, separate python invocation. Wheel egress goes through the kernel network policy.

Tests

Wire tests in crates/sidecar/tests/python.rs: -c/script+argv/-m/stdin/REPL/nested-spawn/pip install, whole-root read+write with cross-process visibility, and pip-install-then-import-in-a-separate-interpreter. Full python_suite is green.

Known sharp edges

  • No unlink/rmdir/rename/symlink on the VFS yet (create/read/write/mkdir work; pip install is fine, pip uninstall/atomic-rename installs are not).
  • Nested-python children fall back to the in-isolate FS rather than the VFS root.
  • Each VFS op is a synchronous RPC (stdlib stays on fast MEMFS).

🤖 Generated with Claude Code

@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-138 June 27, 2026 21:52 Destroyed
@railway-app railway-app Bot temporarily deployed to rivet-frontend / secure-exec-pr-138 June 27, 2026 21:52 Destroyed
@railway-app

railway-app Bot commented Jun 27, 2026

Copy link
Copy Markdown

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

Service Status Web Updated (UTC)
secure-exec 😴 Sleeping (View Logs) Jun 27, 2026 at 10:03 pm

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

Service Status Web Updated (UTC)
secure-exec 😴 Sleeping (View Logs) Web Jun 27, 2026 at 10:01 pm

Wire os.remove/os.rmdir/os.rename/os.replace through to the kernel VFS:
- runner: implement the rename/unlink/rmdir node_ops (were ENOSYS stubs) + add
  fsUnlink/fsRmdir/fsRename to both RPC bridges
- execution: add Unlink/Rmdir/Rename to PythonVfsRpcMethod (+ wire destination
  field) and route them to the filesystem dispatcher
- filesystem: dispatch to kernel.remove_file/remove_dir/rename AND mirror into
  the host-side shadow (remove/rename_guest_shadow_path) so a later shadow->kernel
  sync can't resurrect a just-deleted entry

Test: python_runtime_supports_file_delete_and_rename verifies the ops in-isolate
and cross-checks the host kernel VFS.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@railway-app railway-app Bot temporarily deployed to rivet-frontend / secure-exec-pr-138 June 27, 2026 23:24 Destroyed
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-138 June 27, 2026 23:24 Destroyed
@NathanFlurry NathanFlurry merged commit a8b74a4 into main Jun 27, 2026
8 of 9 checks passed
NathanFlurry pushed a commit that referenced this pull request Jun 27, 2026
…name

#138 added Unlink/Rmdir/Rename to PythonVfsRpcMethod but left the rpc-bridge
test's match non-exhaustive (E0004), breaking clippy --all-targets. This test's
scenario doesn't mutate the FS, so treat those variants as unexpected.
NathanFlurry pushed a commit that referenced this pull request Jun 28, 2026
#138's runner sets up a kernel-VFS-backed site-packages on boot, emitting VFS
RPCs that the prewarm test's .wait() path could not service (PendingVfsRpcRequest).
Drive the event loop and reject VFS RPCs so the runner's best-effort setup
degrades; the execution still completes. Verified locally.
NathanFlurry pushed a commit that referenced this pull request Jun 28, 2026
#138's runner sets up a kernel-VFS-backed site-packages on boot, emitting VFS
RPCs that the prewarm test's .wait() path could not service (PendingVfsRpcRequest).
Drive the event loop and reject VFS RPCs so the runner's best-effort setup
degrades; the execution still completes. Verified locally.
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