Runtime¶
Runtime 用统一接口启动、操作、保存和关闭沙箱,支持 Docker、QEMU 及自定义后端,可用于 Data Pipeline、Training、Evaluation。
一个 Runtime 可以创建和操作多个沙箱。
Runtime:沙箱管理器¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path | None
|
环境记录存储目录;省略时不写记录。 |
None
|
host
|
str | None
|
后端服务地址;Docker、QEMU 填 ssh://服务器,不填则使用当前机器。自定义后端决定地址格式。 |
None
|
ssh
|
dict | None
|
沙箱服务器的 SSH 配置,字段见SSH 配置。新建环境时不填则使用系统默认配置;connect 时不填沿用连接记录,{} 使用系统默认配置,非空字典与记录递归合并。 |
None
|
from envweaver import Runtime
runtime = Runtime(root="./storage/runtimes")
SSH 配置
Runtime(ssh=...) 配置沙箱服务器连接。SSH 文件地址统一使用系统默认配置。
短暂连接故障最多尝试 3 次,重试间隔为 0.5 秒、1 秒;认证和主机密钥错误不重试。执行命令时,仅确认尚未连接到目标才自动重连;命令可能已执行但回复丢失时,不重复执行。
重新连接实例时,ssh=None 沿用连接记录,ssh={} 使用系统默认配置,非空字典与记录递归合并,同名值以本次为准。
| 字段 | 用法与默认值 |
|---|---|
config_file |
当前机器上的 SSH 配置文件路径;不填则使用 OpenSSH 配置 |
known_hosts_file |
当前机器上的主机身份记录文件路径;不填则使用 OpenSSH 配置 |
identity_file |
当前机器上的 SSH 私钥路径;不填则使用 OpenSSH 配置 |
host_key_alias |
在身份记录文件中查找虚拟机或服务器时使用的名称;默认不指定 |
runtime = Runtime(
root="./storage/runtimes",
host="ssh://worker@server",
ssh={
"config_file": "./experiment/ssh/config",
"known_hosts_file": "./experiment/ssh/known_hosts",
"identity_file": "./experiment/ssh/id_ed25519",
},
)
RuntimeRef:环境引用¶
Runtime.create 或 Runtime.save 返回的镜像和配置,可传给 Runtime.start。
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str | None
|
环境名称;不填时使用 image。 |
backend |
str
|
后端名称,例如 |
image |
str
|
Docker 镜像名或 QEMU 磁盘文件路径。 |
config |
dict[str, Any]
|
后端配置,见后端配置。 |
connection |
dict[str, Any]
|
SSH 用户名、Python 路径或 VNC 密码环境变量名,见连接配置。 |
metadata |
dict[str, Any]
|
自定义 JSON 字典,默认 {}。 |
Instance:运行实例¶
Runtime.start 或 Runtime.connect 返回的对象,代表已启动的容器或虚拟机。
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
容器或虚拟机的 ID。 |
backend |
str
|
管理实例的后端名称。 |
root |
str | None
|
环境记录的存储目录。 |
host |
str | None
|
实例所在的服务器地址;None 表示本地。 |
data |
dict[str, Any]
|
自动记录的实例信息,如镜像配置、磁盘路径和连接地址,无需手动填写。 |
Runtime.create:创建环境引用¶
检查现有镜像并创建引用。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
环境名称;不填时使用传入的 image。 |
None
|
backend
|
str
|
docker、qemu 或通过 register 注册的后端名称。 |
required |
image
|
str
|
Docker 镜像名/ID、QEMU 磁盘路径,或自定义后端的环境标识。 |
required |
config
|
dict | None
|
后端配置,默认 {},字段见后端配置。 |
None
|
connection
|
dict | None
|
SSH 用户名、Python 路径或 VNC 密码环境变量名,见连接配置。 |
None
|
metadata
|
dict | None
|
自定义 JSON 字典,默认 {}。 |
None
|
Returns:
| Type | Description |
|---|---|
RuntimeRef
|
可传给 start 的 RuntimeRef。 |
ref = runtime.create(
name="python-workspace",
backend="docker",
image="python:3.11-slim-bookworm",
config={"command": ["sleep", "infinity"]},
metadata={"tags": ["python"], "source": "my-pipeline"},
)
Runtime.start:启动环境¶
启动容器或虚拟机。
Docker 镜像缺少默认 python3 时自动安装;安装需能访问软件源,并具备容器内 root 或免密 sudo 权限。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ref
|
RuntimeRef
|
要启动的环境,包含镜像和启动配置。 |
required |
context
|
list[dict[str, str]] | None
|
启动后要复制进去的文件列表,不填则不复制。 |
None
|
setup
|
dict | None
|
复制 context 后执行的准备操作;command 为命令字符串或参数列表, timeout 为最长执行秒数,须大于 0。命令准备完成后以退出码 0 结束。 |
None
|
connection
|
dict | None
|
本次连接设置;重新填写的覆盖 ref.connection 中的值,没填的保留原值。 字段见连接配置。 |
None
|
Returns:
| Type | Description |
|---|---|
Instance
|
完成文件复制和准备操作后的 Instance。 |
instance = runtime.start(
ref=ref,
context=[{"source": "./prepare", "target": "/work/prepare"}],
setup={"command": ["python3", "/work/prepare/setup.py"], "timeout": 120},
)
连接配置
create(connection=...) 可填写 QEMU 的 SSH 用户名、Python 路径,或 Docker 的 VNC 密码环境变量名。其他连接设置传给 start(connection=...)。
start 中重新填写的设置会覆盖引用中的值,没填的保留原值。
save 保留实际使用的 SSH 用户名、Python 路径和 VNC 密码环境变量名;不保存服务器地址、端口、密码或私钥路径。
ref = runtime.create(
backend="qemu",
image="/images/windows.qcow2",
config={"disk_dir": "/data/vms"},
connection={"ssh": {"user": "worker", "python": "python"}},
)
instance = runtime.start(
ref=ref,
connection={"ssh": {
"config_file": "./experiment/ssh/config",
"known_hosts_file": "./experiment/ssh/known_hosts",
"identity_file": "./experiment/ssh/vm_key",
}},
)
| 字段 | 用法与默认值 |
|---|---|
ssh.user |
虚拟机中的 SSH 用户名,必填 |
ssh.python |
虚拟机内的 Python 程序,默认 python3 |
ssh.config_file、ssh.known_hosts_file、ssh.identity_file、ssh.host_key_alias |
与上面的 SSH 配置 相同,用于连接虚拟机 |
vnc.host |
Docker 桌面的 VNC 地址,截图时必填;需能从当前机器访问 |
vnc.port |
VNC 端口,默认 5900 |
vnc.password_env |
当前机器上保存 VNC 密码的环境变量名;默认不传密码 |
Runtime.exec:执行命令¶
在容器或虚拟机中执行命令。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instance
|
Instance
|
要操作的 Instance。 |
required |
command
|
str | list[str]
|
命令字符串,或程序及参数列表,如 ["python3", "-c", "print(1)"]。 |
required |
cwd
|
str | None
|
在容器或虚拟机内的哪个目录执行。 |
None
|
timeout
|
float | None
|
最长执行秒数,None 表示不限时。 |
300
|
Returns:
| Type | Description |
|---|---|
tuple[int, str, str]
|
退出码、标准输出、标准错误。命令执行失败时返回非零退出码。 |
code, stdout, stderr = runtime.exec(
instance=instance,
command="python3 --version",
timeout=30,
)
Runtime.upload:上传文件¶
上传文件或目录到容器或虚拟机。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instance
|
Instance
|
要操作的 Instance。 |
required |
source
|
str | Path
|
要上传的文件或目录路径。 |
required |
target
|
str
|
容器或虚拟机内的完整目标路径,包含文件名或目录名。 |
required |
Returns:
| Type | Description |
|---|---|
None
|
None。 |
runtime.upload(
instance=instance,
source="./input.txt",
target="/work/input.txt",
)
Runtime.download:下载文件¶
下载容器或虚拟机内的文件或目录。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instance
|
Instance
|
要下载文件的 Instance。 |
required |
source
|
str
|
容器或虚拟机内的文件或目录。 |
required |
target
|
str | Path
|
下载保存路径,包含文件名或目录名。 |
required |
Returns:
| Type | Description |
|---|---|
None
|
None。 |
runtime.download(
instance=instance,
source="/work/input.txt",
target="./downloaded.txt",
)
Runtime.screenshot:桌面截图¶
获取桌面截图。
Docker 使用 VNC,调用该接口的环境需要安装 envweaver[desktop];QEMU 使用 QMP。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instance
|
Instance
|
要截图的 Instance。 |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
PNG 图片字节。 |
from pathlib import Path
image = runtime.screenshot(instance=instance)
Path("screen.png").write_bytes(image)
Runtime.save:保存环境¶
将当前实例保存为可复用的环境。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instance
|
Instance
|
start 返回的 Instance;connect 返回的实例不能保存。 |
required |
Returns:
| Type | Description |
|---|---|
RuntimeRef
|
包含镜像、启动配置、连接配置和原引用 name、metadata 的 RuntimeRef。 |
saved_ref = runtime.save(instance=instance)
Runtime.close:释放实例¶
关闭并删除容器或虚拟机,保留已保存的环境。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instance
|
Instance
|
要关闭的 Instance。 |
required |
Returns:
| Type | Description |
|---|---|
None
|
None。 |
runtime.close(instance=instance)
后端配置¶
Docker config
| 字段 | 用法与默认值 |
|---|---|
command |
容器启动时执行的命令。 例如:["sleep", "infinity"];默认:[],沿用镜像默认命令 |
env |
向容器传入环境变量。 例如:{"LANG": "C.UTF-8"};默认:{} |
user |
容器运行用户。 例如:"1000:1000";默认:镜像默认用户 |
memory |
内存上限,使用 Docker 格式。 例如:"4g";默认:不额外指定 |
cpus |
可使用的 CPU 核数,可填小数。 例如:2;默认:不额外指定 |
network |
网络模式或网络名称。 例如:"bridge";默认:Docker 默认网络 |
shm_size |
共享内存大小。 例如:"1g";默认:Docker 默认值 |
gpus |
允许使用的 GPU。 例如:"all";默认:不请求 GPU |
python |
容器内执行命令所用的 Python。默认 "python3",缺少时自动安装 Python 和 CA 证书;自定义路径如 "/opt/venv/bin/python" 须已存在 |
python_prepare_command |
缺少默认 python3 时,在安装前执行一次的 shell 命令,例如配置软件源;默认不执行。例如:"sh /opt/configure-mirrors.sh";命令引用的文件须已在镜像中 |
python_install_command |
缺少默认 python3 时执行的 shell 安装命令;默认使用内置安装流程。自定义安装不自动接入缓存。例如:"sh /opt/install-python.sh";命令引用的文件须已在镜像中 |
python_install_timeout |
Python 准备与安装的总时间上限,包含索引更新、下载和安装;有限正数,单位秒,默认 300,例如 1200 |
startup_timeout |
docker run 的超时秒数。 例如:120;默认:120 秒 |
args |
额外的 docker run 参数列表,放在镜像名前。 例如:["--hostname", "desktop"];默认:[] |
QEMU config
ref = runtime.create(
backend="qemu",
image="/images/windows.qcow2",
config={
"disk_dir": "/data/envweaver/disks",
"save_mode": "incremental",
"memory": 8192,
"cpus": 4,
},
)
| 字段 | 用法与默认值 |
|---|---|
disk_dir |
必填。启动虚拟机的服务器上的绝对目录,保存运行中的磁盘、控制文件和已保存的差分磁盘。例如:"/data/envweaver/disks" |
save_mode |
保存方式:"incremental" 保留差分链(默认);"consolidated" 合并中间差分层。 |
remote_python |
远端已安装 EnvWeaver 的 Python 解释器,本地运行时忽略。 例如:"/opt/envweaver/.venv/bin/python";默认:"python3" |
memory |
虚拟机内存(MiB)。 例如:8192;默认:4096 MiB |
cpus |
虚拟 CPU 数量。 例如:4;默认:2 |
startup_timeout |
等待 SSH 就绪的最长时间。 例如:180;默认:180 秒 |
shutdown_timeout |
保存前等待虚拟机正常关机的最长时间。 例如:120;默认:120 秒 |
disk_interface |
磁盘接口,镜像内需要相应驱动。 例如:"virtio";默认:"virtio" |
network_device |
虚拟网卡型号,镜像内需要相应驱动。 例如:"virtio-net-pci";默认:"virtio-net-pci" |
format |
image 所指基础磁盘的格式。 例如:"raw";默认:"qcow2" |
machine |
QEMU 机器类型。 例如:"q35";默认:"q35" |
accel |
QEMU 加速方式。 例如:"kvm";默认:"kvm" |
firmware |
只读 UEFI 固件文件路径。 例如:"/images/OVMF_CODE.fd";默认:不额外配置 |
nvram |
UEFI 设置文件的模板路径。 例如:"/images/OVMF_VARS.fd";默认:不额外配置 |
binary |
QEMU 可执行程序。 例如:"/usr/bin/qemu-system-x86_64";默认:"qemu-system-x86_64" |
image_binary |
磁盘处理程序。 例如:"/usr/bin/qemu-img";默认:"qemu-img" |
args |
额外 QEMU 启动参数,不能覆盖磁盘、进程和 QMP 控制配置。 例如:["-vga", "std"];默认:[] |
扩展与连接¶
Runtime.register:添加后端
添加自定义后端。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
后端名称,之后填入 create 的 backend 参数。 |
required |
backend
|
type[RuntimeBackend]
|
自定义后端类,构造函数接受 root、host、ssh。方法见下方 RuntimeBackend。 |
required |
Returns:
| Type | Description |
|---|---|
None
|
None。 |
同名注册会替换原后端,仅对当前 Runtime 对象生效。 后端构造函数抛出的异常会直接传给调用者。
runtime.register(name="my_vm", backend=MyVMBackend)
MyVMBackend 是你编写的后端类,需要实现以下方法。将注册后的同一个 Runtime 传给 TaskPool 和 Verifier:
Runtime 后端需要提供的方法,无需继承。
- 构造函数须接受
root、host、ssh参数;未配置 SSH 时传入 None。 返回的Instance填入对应的root和host,后续操作使用Instance.host。host的地址格式和远程连接方式由后端决定。 Instance.backend和RuntimeRef.backend填register注册的名称。RuntimeRef保存镜像、启动配置和可随环境保存的连接设置。 Runtime 在调用 start 前合并 ref.connection 与本次 connection。 后端的 save 将实际使用的用户名、Python 路径等写入 RuntimeRef.connection, 不保存密码、私钥路径或服务器地址。exec的字符串通过 Shell 执行,列表按程序和参数直接执行。 Verifier 使用Instance.data["python"]指定的解释器,省略时为python3。root保存环境记录,支持本地目录或 SSH 目录地址;镜像和磁盘由后端存储。- 操作失败抛异常;
exec返回退出码、stdout、stderr,超时抛TimeoutError。
__init__(root: str | Path | None = None, *, host: str | None = None, ssh: dict | None = None)
¶
create(image: str, config: dict | None = None, connection: dict | None = None) -> RuntimeRef
¶
检查目标服务器上的镜像,返回 RuntimeRef,不启动环境。
start(ref: RuntimeRef, connection: dict | None = None) -> Instance
¶
启动独立实例,返回 Instance;不修改基础镜像。
connection 接收 Runtime 合并后的配置;None 使用 ref.connection。
connect(record: dict) -> Instance
¶
读取 describe 生成的记录,连接已有实例。字段与 describe 的输出一致。
describe(instance: Instance) -> dict
¶
返回 connect 所需的 JSON 字段;version、backend、host 由 Runtime 填写。
screenshot(instance: Instance) -> bytes
¶
返回 PNG 图片字节;不支持截图时抛 NotImplementedError。
exec(instance: Instance, command: str | list[str], cwd: str | None = None, timeout: float | None = 300) -> tuple[int, str, str]
¶
返回退出码、stdout、stderr;超时抛 TimeoutError,timeout=None 表示不限时。
upload(instance: Instance, source: str | Path, target: str) -> None
¶
source 是本地路径,target 是实例内路径;目录合并、同名覆盖。
Runtime 会先将 SSH 来源下载到本地,后端无需处理 SSH 文件地址。
download(instance: Instance, source: str, target: str | Path) -> None
¶
source 是实例内路径,target 是本地路径;目录合并、同名覆盖。
Runtime 会将下载结果传到 SSH 目的地,后端无需处理 SSH 文件地址。
save(instance: Instance) -> RuntimeRef
¶
保存环境,返回 RuntimeRef,保留启动引用的 metadata。
close(instance: Instance) -> None
¶
关闭并删除实例,保留已保存环境。
Runtime.describe:记录实例连接
保存实例的连接记录。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instance
|
Instance
|
要记录的 Instance。 |
required |
path
|
str | Path
|
JSON 文件的保存路径。 |
required |
Returns:
| Type | Description |
|---|---|
None
|
None。 |
runtime.describe(instance=instance, path="./instance.json")
Runtime.connect:连接已有实例
连接已经运行的环境。
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
instance.json 文件路径。 |
required |
Returns:
| Type | Description |
|---|---|
Instance
|
连接到的 Instance,不能用于 save。验证程序收到的连接支持 exec、upload、download 和 screenshot。 |
runtime = Runtime()
instance = runtime.connect(path="./instance.json")
DownloadCache:下载缓存¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path | None
|
当前机器上的缓存目录;默认 ENVWEAVER_CACHE_DIR,未设置时为 ~/.cache/envweaver/downloads。 |
None
|
max_bytes
|
int
|
缓存容量上限,默认 30 GiB;超限时清理最近未使用的文件。 |
30 * 1024 ** 3
|
from envweaver import DownloadCache
cache = DownloadCache(root="./download-cache")
DownloadCache.download:下载文件
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
HTTP 或 HTTPS 文件地址,不接受包含用户名或密码的地址。 |
required |
checksum
|
str
|
文件校验值,格式为 sha256:十六进制值或 sha512:十六进制值。 |
required |
target
|
str | Path
|
当前机器上的目标文件;成功后原子覆盖,不与缓存共享可写文件。 |
required |
proxies
|
dict[str, str] | None
|
HTTP、HTTPS 代理地址字典;默认 None,读取当前进程的代理配置。 |
None
|
Returns:
| Type | Description |
|---|---|
None
|
None。 |
cache.download(url=package_url, checksum=package_checksum, target="./materials/package.whl")