Fix the default one-shot install path so empty bundled profile directories no longer win over OCI-backed environment pulls or leave broken cached symlinks behind. Treat cached installs as valid only when the manifest and boot artifacts are all present, repair invalid installs on the next pull, and add human-mode phase markers for env pull and run without changing JSON output. Align the Python lifecycle example and public docs with the current exec_vm/vm_exec auto-clean semantics, and validate the slice with focused pytest coverage, make check, make dist-check, and a real default-path pull/inspect/run smoke.
189 lines
4.1 KiB
Markdown
189 lines
4.1 KiB
Markdown
# Install
|
|
|
|
## Support Matrix
|
|
|
|
Supported today:
|
|
|
|
- Linux x86_64
|
|
- Python 3.12+
|
|
- `uv`
|
|
- `/dev/kvm`
|
|
|
|
Optional for outbound guest networking:
|
|
|
|
- `ip`
|
|
- `nft` or `iptables`
|
|
- privilege to create TAP devices and configure NAT
|
|
|
|
Not supported today:
|
|
|
|
- macOS
|
|
- Windows
|
|
- Linux hosts without working KVM at `/dev/kvm`
|
|
|
|
If you do not already have `uv`, install it first:
|
|
|
|
```bash
|
|
python -m pip install uv
|
|
```
|
|
|
|
Use these command forms consistently:
|
|
|
|
- published package without install: `uvx --from pyro-mcp pyro ...`
|
|
- installed package: `pyro ...`
|
|
- source checkout: `uv run pyro ...`
|
|
|
|
## Fastest Evaluation Path
|
|
|
|
Use either of these equivalent evaluator paths:
|
|
|
|
```bash
|
|
# Package without install
|
|
uvx --from pyro-mcp pyro doctor
|
|
uvx --from pyro-mcp pyro env list
|
|
uvx --from pyro-mcp pyro env pull debian:12
|
|
uvx --from pyro-mcp pyro run debian:12 -- git --version
|
|
```
|
|
|
|
```bash
|
|
# Already installed
|
|
pyro doctor
|
|
pyro env list
|
|
pyro env pull debian:12
|
|
pyro run debian:12 -- git --version
|
|
```
|
|
|
|
If you are running from a repo checkout instead, replace `pyro` with `uv run pyro`.
|
|
|
|
### 1. Check the host first
|
|
|
|
```bash
|
|
uvx --from pyro-mcp pyro doctor
|
|
```
|
|
|
|
Expected success signals:
|
|
|
|
```bash
|
|
Platform: linux-x86_64
|
|
Runtime: PASS
|
|
KVM: exists=yes readable=yes writable=yes
|
|
Environment cache: /home/you/.cache/pyro-mcp/environments
|
|
Capabilities: vm_boot=yes guest_exec=yes guest_network=yes
|
|
Networking: tun=yes ip_forward=yes
|
|
```
|
|
|
|
If `Runtime: FAIL`, stop here and use [troubleshooting.md](troubleshooting.md).
|
|
|
|
### 2. Inspect the catalog
|
|
|
|
```bash
|
|
uvx --from pyro-mcp pyro env list
|
|
```
|
|
|
|
Expected output:
|
|
|
|
```bash
|
|
Catalog version: 2.0.0
|
|
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
|
|
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
|
|
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.
|
|
```
|
|
|
|
### 3. Pull the default environment
|
|
|
|
```bash
|
|
uvx --from pyro-mcp pyro env pull debian:12
|
|
```
|
|
|
|
The first pull downloads an OCI environment from public Docker Hub, requires outbound HTTPS
|
|
access to `registry-1.docker.io`, and needs local cache space for the guest image. See
|
|
[host-requirements.md](host-requirements.md) for the full host requirements.
|
|
|
|
Expected success signals:
|
|
|
|
```bash
|
|
[pull] phase=install environment=debian:12
|
|
[pull] phase=ready environment=debian:12
|
|
Pulled: debian:12
|
|
...
|
|
```
|
|
|
|
### 4. Run one command in a guest
|
|
|
|
```bash
|
|
uvx --from pyro-mcp pyro run debian:12 -- git --version
|
|
```
|
|
|
|
Expected success signals:
|
|
|
|
```bash
|
|
[run] phase=create environment=debian:12
|
|
[run] phase=start vm_id=...
|
|
[run] phase=execute vm_id=...
|
|
[run] environment=debian:12 execution_mode=guest_vsock exit_code=0 duration_ms=...
|
|
git version ...
|
|
```
|
|
|
|
The guest command output and the `[run] ...` summary are written to different streams, so they
|
|
may appear in either order in terminals or capture tools. Use `--json` if you need a
|
|
deterministic structured result.
|
|
|
|
If guest execution is unavailable, the command fails unless you explicitly pass
|
|
`--allow-host-compat`.
|
|
|
|
## 5. Optional demo proof point
|
|
|
|
```bash
|
|
uvx --from pyro-mcp pyro demo
|
|
```
|
|
|
|
`pyro demo` proves the one-shot create/start/exec/delete VM lifecycle works end to end.
|
|
|
|
Example output:
|
|
|
|
```json
|
|
{
|
|
"cleanup": {
|
|
"deleted": true,
|
|
"reason": "post_exec_cleanup",
|
|
"vm_id": "..."
|
|
},
|
|
"command": "git --version",
|
|
"environment": "debian:12",
|
|
"execution_mode": "guest_vsock",
|
|
"exit_code": 0,
|
|
"stdout": "git version ...\n"
|
|
}
|
|
```
|
|
|
|
For a fuller copy-pasteable transcript, see [first-run.md](first-run.md).
|
|
When you are done evaluating and want to remove stale cached environments, run `pyro env prune`.
|
|
|
|
## Installed CLI
|
|
|
|
If you already installed the package, the same evaluator path works with plain `pyro ...`:
|
|
|
|
```bash
|
|
uv tool install pyro-mcp
|
|
pyro --version
|
|
pyro doctor
|
|
pyro env list
|
|
pyro env pull debian:12
|
|
pyro run debian:12 -- git --version
|
|
```
|
|
|
|
After the CLI path works, you can move on to:
|
|
|
|
- MCP: `pyro mcp serve`
|
|
- Python SDK: `from pyro_mcp import Pyro`
|
|
- Demos: `pyro demo` or `pyro demo --network`
|
|
|
|
## Contributor Clone
|
|
|
|
```bash
|
|
git lfs install
|
|
git clone <repo>
|
|
cd pyro
|
|
git lfs pull
|
|
make setup
|
|
```
|