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

后端名称,例如 docker、qemu。

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

启动后要复制进去的文件列表,不填则不复制。
每项的 source 填文件或目录路径; target 填容器或虚拟机内的目标路径。

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")