feat(axvisor): axum management HTTP control plane with VM lifecycle API - #1909
feat(axvisor): axum management HTTP control plane with VM lifecycle API#1909aptacc2421 wants to merge 18 commits into
Conversation
为网络管理控制面铺路。启用 ax-std `net` feature 触发网络子系统初始化,defconfig
SMP 1→2(全局默认值,目前仅在 QEMU smoke 上验证:aarch64、x86_64 vmx/svm、
loongarch64);aarch64/riscv64/x86_64 VM 配置把 vCPU 显式绑到 Core 1(FDT 路径
phys_cpu_ids 生效,set_phys_cpu_sets 启动时重算),管理面留在 Core 0。main 的
start_default_vms/shell 任务拆分在此之前已存在,本提交仅在 main 补充核隔离说明
注释与 `shell task on CPU{}` 诊断日志,并让 vCPU 运行日志带 CPU id 便于核隔离
断言。另在 Cargo.toml 引入 axum/tokio/serde_json 可选依赖与 http-test/http-axum
feature,为后续只读/控制 HTTP API PR 预留基础设施(本期未启用)。
Changes:
- os/axvisor/Cargo.toml: ax-std 启用 net feature;新增 axum/tokio/serde_json 可选依赖 + http-test/http-axum feature
- os/axvisor/configs/defconfig.toml: smp 1→2(全局默认,仅 QEMU smoke 验证)
- os/axvisor/configs/vms/qemu/{aarch64,riscv64,x86_64}/arceos-smp1.toml 等: vCPU 绑 Core 1,注释英文化
- os/axvisor/src/main.rs: 核隔离说明注释 + `shell task on CPU{}` 诊断日志
- virtualization/axvm/src/runtime/vcpus.rs: vCPU 运行日志带 CPU id
- test-suit/axvisor/normal/qemu/smoke/qemu-x86_64-vmx.toml: -smp 2 + virtio-net + 网络/核隔离断言
- test-suit/axvisor/normal/qemu/smoke/qemu-{x86_64-svm,loongarch64}.toml: -smp 2
- docs/docs/architecture/axvisor.md: 同步退出日志字符串
There was a problem hiding this comment.
本 PR 启用 AxVisor 的 ArceOS 网络栈,将默认 SMP 调整为 2,并把部分 QEMU VM 的 vCPU 配置到 Core 1;同时新增了 HTTP/axum 的预留 Cargo feature。配置与运行时改动会影响 AxVisor 的宿主 CPU 拓扑、vCPU affinity 和默认 QEMU 启动契约,因而不是隔离的纯日志改动。
book/guideline/feature-development.md 适用:网络能力、SMP 默认和公开 feature 均扩展了行为边界。该变更属于共享、平台相关功能;PR 描述说明了管理控制面的方向,但 HTTP feature 缺少当前消费者、设计材料和可运行验证,见内联意见。
验证:工作区 HEAD 已确认是 b2e1d41a274472374172751217c8634af28d8a2b,git diff --check origin/dev...HEAD 通过;review helper 的 7 项自测与 prepared-clone 校验通过。组织 CI 中格式检查以及 AxVisor 的 aarch64/riscv64 smoke、aarch64 timer-stress/no-backtrace 等相关任务成功。当前 Starry riscv64 任务失败、Starry aarch64 任务取消,但它们不执行本 PR 的 AxVisor/axvm 变更;本结论不以这些任务为依据。由于相关 AxVisor CI 已通过,未重复本地 QEMU 测试。
测试覆盖仍不足:现有 x86 VMX smoke 仅证明 shell 在 CPU0,不能证明 vCPU affinity 到 CPU1;aarch64/riscv64 的配置改动也没有相应断言。请补充能在 affinity 回归时失败的 QEMU 或 axvm 确定性测试。
已检查历史审查与行级评论:当前没有先前 review/comment。已搜索 base 中既有 phys_cpu_ids/phys_cpu_sets 模式及相关开放 PR;未发现与本 PR 完全重复的开放实现。未发现 [patch.crates-io]。
审查清单已完成;以下两项为合入前必须解决的阻塞问题。
Powered by gpt-5.6-terra
| backtrace = ["ax-std/backtrace", "dep:axbacktrace"] | ||
| test-backtrace-panic = ["backtrace"] | ||
| test-panic-no-backtrace = ["dep:axbacktrace"] | ||
| # axum-based management HTTP server (see doc/plan/axum-implementation.md). |
There was a problem hiding this comment.
【阻塞|功能设计】这里新增了 http-test/http-axum 两个可由使用者启用的公开 feature,以及 axum、tokio、serde_json 依赖,但当前提交没有对应实现、调用方或测试;注释所指的 doc/plan/axum-implementation.md 也不存在。这样会把没有契约和消费者的配置入口长期暴露出来,且无法验证运行时、兼容性和依赖代价。请把这部分基础设施随实际 HTTP 管理面及其设计/验证一并提交,或在本 PR 完整实现并测试其明确行为;否则请移除这些预留 feature 和依赖。
There was a problem hiding this comment.
已解决。http-test/http-axum 现随只读管理 API 一并实现提交:
os/axvisor/src/http/{mod,server,vm}.rs:axum Router + tokio current_thread runtime(仅 enable_io())+ tower::ServiceExt::oneshot 自测;GET /api/vms、GET /api/vms/{id} 路由由 serde_json 构造响应http-test现在隐含http-axum并引入 tower 依赖,自测在http::serve内、bind 之前运行,断言GET /api/vms -> 200、GET /api/vms/999 -> 404(见 qemu-http-axum-readonly 双架构用例)- Cargo.toml 注释指向
doc/plan/axum-implementation.md的引用已改为src/http/(完整计划文档随文档 PR 合入)
验证:cargo xtask axvisor build --config qemu-http-axum-readonly 通过(http-test feature),cargo test -p axvm --features host-test 240 passed。
| # Host-side network subsystem init (enabled via the `net` feature on ax-std). | ||
| "Initialize network subsystem", | ||
| "use NIC 0:", | ||
| # Management console runs on the primary CPU while vCPUs are pinned to Core 1. |
There was a problem hiding this comment.
【阻塞|回归覆盖】shell task on CPU0 只能证明管理 shell 的起始 CPU,不能证明本 PR 的核心语义——vCPU 已被调度到 Core 1。即使 phys_cpu_* 映射回归为 Core 0,这个 case 仍会通过;新增的 vCPU CPU-id 日志也没有被 success regex 使用。请在每个改动的平台的 smoke 中匹配 vCPU 运行在 CPU1 的日志(同时保留 shell 在 CPU0 的断言),或补充 axvm 配置/调度层的确定性映射测试。
There was a problem hiding this comment.
已解决。补充 axvm 配置/调度层的确定性映射测试,直接覆盖 phys_cpu_* 到 vCPU 实际调度核心的映射:
virtualization/axvm/src/architecture/ops.rs:default_vcpu_affinities单测覆盖三种配置 ——phys_cpu_ids=[1](aarch64/riscv arceos-smp1.toml)→ vcpu0 的 pcpu_id=1;phys_cpu_sets=[2](x86_64 arceos-smp1.toml)→ affinity mask 0b10(Core 1);默认无配置 → vcpu id == phys id 回退virtualization/axvm/src/config.rs:PhysCpuList::get_vcpu_affinities_pcpu_ids端到端测试同一映射(经CurrentArch::vcpu_affinities公共路径)
验证:cargo test -p axvm --features host-test 240 passed,新增 3 个测试均通过。shell task on CPU0 断言保留,与上述映射单测共同覆盖管理面在 Core 0、vCPU 在 Core 1。
PR B 将管理面 HTTP 从手写 pilot 替换为 axum 正式实现。tokio current_thread
runtime 仅启用 IO driver(enable_io()),首次验证 axum in-hypervisor 真能运行:
eventfd/epoll syscall 已就绪,无需 timerfd,PR D 条件不触发。路由
GET /api/vms 与 GET /api/vms/{id} 镜像 pilot API,JSON 改用 serde_json 构造。
http-test 内建自测用 tower oneshot 直接驱动 router(不经 TCP),确定性断言
200/404。HTTP server 在 VMM 启动前 bind(对齐 pilot fix 307f30251:cooperative
FIFO 下 spawn 顺序即就绪队列顺序,先启动管理面才能控制默认 VM)。
Changes:
- os/axvisor/src/http/: 新增 mod.rs(serve 入口)、axum.rs(Router + enable_io
runtime + oneshot 自测)、vm.rs(serde_json handler);移除手写 pilot
- os/axvisor/src/main.rs: 追加 mod http,http::serve 独立线程在
launch_default_vms 之前 spawn,管理面先于 guest 启动
- os/axvisor/Cargo.toml: http-test 隐含 http-axum 并引入 tower 依赖
- test-suit/axvisor/normal/qemu-http-axum-readonly/: aarch64 + x86_64 双架构
运行验证,断言 GET /api/vms -> 200 与 /api/vms/999 -> 404;x86_64 构建
通过 [env] 禁用 httparse SIMD,规避裸机目标上的 rustc-LLVM 代码生成错误
…rver Address review items on the axum management plane. Changes: - os/axvisor/Cargo.toml: declare tower `util` explicitly. `ServiceExt::oneshot` is gated behind tower's `util` feature, which default features do not include; it only compiled via axum's transitive `util` enablement - os/axvisor/src/http/mod.rs: rename the `http::axum` submodule to `http::server` to avoid shadowing the external axum crate (mod.rs `axum::serve()` previously resolved to the submodule while server.rs `axum::serve()` resolved to the crate); drop the redundant `#[cfg(feature = "http-axum")]` on module items, already gated by `mod http` - os/axvisor/src/http/axum.rs -> os/axvisor/src/http/server.rs: file rename - os/axvisor/src/http/vm.rs: update doc reference `[super::axum]` -> `[super::server]` - os/axvisor/src/main.rs: correct the spawn-order comment. `ax_std::thread::spawn` only enqueues the task; the main task keeps running until it yields, so the HTTP server's bind is not guaranteed to precede `launch_default_vms`
The management control-plane smoke tests isolate the guest vCPU onto physical Core 1 so the HTTP task stays on Core 0. This mapping previously had no regression coverage; a reviewer asked for a deterministic mapping test at the axvm config/scheduling layer. Changes: - Add default_vcpu_affinities tests covering phys_cpu_ids=[1] (aarch64/riscv64 arceos-smp1.toml), phys_cpu_sets=[2] (x86_64 arceos-smp1.toml), and the vcpu-id fallback in architecture/ops.rs. - Add a PhysCpuList::get_vcpu_affinities_pcpu_ids test in config.rs exercising the public config path with the same three cases.
…omment The plan doc doc/plan/axum-implementation.md lands with the docs PR in the stack, so pr1's Cargo.toml comment must not point at a file absent from the tree it merges with. Point at the implementation module instead. Changes: - os/axvisor/Cargo.toml: http-axum comment now references src/http/.
There was a problem hiding this comment.
本 PR 将 AxVisor 默认 SMP 调整为 2,启用宿主网络栈,并加入基于 axum/tokio 的只读 VM 管理 HTTP API、vCPU affinity 配置与双架构 QEMU 用例。这是共享的平台功能扩展,不是 release 版本升级;book/guideline/feature-development.md 适用。HTTP 管理面会暴露 VM 状态并改变启动时的任务/网络行为,SMP 与 affinity 改动影响既有 QEMU 启动契约;不涉及 StarryOS syscall/Linux ABI 语义。
实现上,HTTP 线程在默认 VM 启动前创建,GET /api/vms 与详情路由通过 axum/serde_json 读取 AxVM 快照;新增 axvm 单测覆盖了 phys_cpu_ids 与 phys_cpu_sets 到 affinity 映射。历史意见中关于预留 HTTP feature 和 affinity 证明不足的问题已由当前提交补上实现与确定性映射测试,相关代码已复核。
验证:已确认工作区 HEAD 为 03f085311196a5298e572ecd65044e114aa79f52;git diff --check origin/dev...HEAD、cargo fmt --check 和 review helper 的 prepared-clone 校验通过。组织 CI 当前头共 success=35、skipped=34、failure=0,相关格式、clippy 和 AxVisor QEMU/板级任务均成功;跳过项符合 host/container 或路径矩阵。由于相关组织 CI 已通过,未重复完整本地 QEMU;本地执行了 test runner 的发现检查,暴露了下列 x86 用例不可发现的问题。
测试放置在 test-suit/axvisor/normal,aarch64 case 能被发现;但 x86_64 case 未被 runner 选择,且两个 HTTP 状态码没有形成“均须成功”的断言,故新增覆盖仍不完整。
重复/重叠分析:已对比 origin/dev 中既有 phys_cpu_ids/phys_cpu_sets、AxVisor 运行方式和近期相关提交;未发现 base 已具备同一 HTTP 管理面,也没有发现需要依赖或替代本实现的开放 PR。未发现 [patch.crates-io]。当前无未处理的合理历史审查问题;剩余阻塞项如下。
Powered by gpt-5.6-terra
| "(?i)\\bpanic(?:ked)?\\b", | ||
| "(?i)kernel panic", | ||
| ] | ||
| success_regex = [ |
There was a problem hiding this comment.
【阻塞|测试覆盖】这里的两个 success_regex 在 AxVisor runner 中是“任一匹配即成功”,不是两个都必须匹配:build_many 只要命中一个 marker 就结束。因此 /api/vms 或 /api/vms/999 任一端点回归时,另一个端点的日志仍会让 QEMU 用例通过,无法覆盖本 PR 声称的 200/404 契约。请在 self-test 确认两个状态码均正确后只打印一个最终成功标记(任一断言失败则失败),并在两个架构的配置中匹配该标记。
| @@ -0,0 +1,31 @@ | |||
| args = [ | |||
There was a problem hiding this comment.
【阻塞|测试发现】x86 用例无法由现有 AxVisor runner 发现:runner 只支持 x86_64-unknown-none,并按架构查找 qemu-x86_64.toml;这里却使用 build-x86_64-unknown-none-vmx.toml 和 qemu-x86_64-vmx.toml。在当前 HEAD 运行 cargo xtask axvisor test qemu --arch x86_64 --test-group normal --test-case http-axum-readonly --list 会报该 case unknown,而传入 --target x86_64-unknown-none-vmx 又会报 unsupported target。因此 PR 声称的 x86_64 VMX 覆盖实际上不可执行。请改为 runner 支持的 target/config 命名,或同步扩展 runner 并验证发现和运行。
管理面需要能通过 HTTP 控制 VM 生命周期,而不只是只读查询。此前
PR B 只提供 GET 只读路由;本 PR 新增 POST /api/vms/{id}/start|stop,
并引入 no-auto-start feature——默认 VM 创建后停留在 Ready,由管理
面按需启动/停止,从而让控制 API 可被确定性自测。stop 是请求语义:
vCPU 异步退出,因此自测先轮询 running_vcpu_count 确认 vCPU 已进入
guest 再发 stop,避免 vCPU 任务错过 Running 窗口而被永久挂起。
Changes:
- os/axvisor: 新增 no-auto-start feature,main.rs 门控 auto-start 路径
- os/axvisor: http/vm.rs 新增 vm_start/vm_stop handler 与 AxVmError→HTTP 状态码映射
- os/axvisor: http/axum.rs 新增 POST 路由与 start/409/stop/stopped/404 lifecycle 自测
- axvm: 新增 AxVM::running_vcpu_count() 公开方法
- test-suit: 新增 qemu-http-axum-control aarch64 用例
控制测试原本依赖 gitignored 的 os/axvisor/tmp/ 下 vmconfig 与 guest 内核, clean checkout / CI 上 build.rs include_bytes! 找不到内核镜像导致构建失败。 改为复用 timer-stress 的预置机制:vmconfig 入库到 test-suit,kernel_path 指向 cargo xtask image pull qemu-aarch64 --output-dir tmp/axbuild/images 产出的 arceos-qemu,CI 在测试前先执行 pull,无需提交 442KB 二进制。 Changes: - 新增 test-suit/axvisor/normal/qemu-http-axum-control/aarch64-arceos-http-control.toml - build config 的 vm_configs 指向入库的 vmconfig - CI 新增 http-axum-control 测试条目(image pull + test)
restart-after-stop 因调度限制(停掉的 VM 再 start,新 vCPU task 在已 idle 的 固定核上不被调度)会让 VM 永久卡在 Running,调用方无从感知。改为在 vm_action 的 Start 分支对 Stopped 状态显式返回 409 Conflict,把限制固化为契约而非隐式 挂起;同时 stop 响应增加 "async": true 字段,明确 stop 是异步请求、返回的 status 可能仍是 running/stopping。自测补充 start-after-stop -> 409 断言。 Changes: - os/axvisor/src/http/vm.rs: Start 分支对 Stopped 返回 409;stop 响应加 async 标记 - os/axvisor/src/http/axum.rs: lifecycle 自测断言 start-on-stopped -> 409
http-test 自测(tower oneshot)不经过真实 TCP,hostfwd + curl 才是管理 API 的真实网络路径。文档沉淀 aarch64/x86_64 从构建、to_bin、QEMU hostfwd 引导到 curl 全流程的完整步骤,并声明该 research/debug 接口的安全边界(EL2 内、 无认证、非生产级),便于后续开发与评审复现。 Changes: - 新增 doc/http-control-plane-quickstart.md:构建/引导/curl 全流程、安全边界、清理、FAQ
管理手册引用的 http-control-manual.toml 是本地 gitignore 文件,读者无法重建, 且排障表把缺少 use NIC 0: 日志归因于不存在的 net feature 开关,两条都妨碍复现 与排查。本变更把 config 内容内嵌进文档,并按 net 无条件启用的现状修正排障指引。 Changes: - 内嵌 http-control-manual.toml 完整内容,读者可直接复制重建 - 修正 troubleshooting 表:net 由 ax-std 无条件启用,缺 use NIC 0: 是 QEMU 未提供网卡
动态创建/删除 VM 需要在运行时验证完整 VM 生命周期(内存/vCPU/device 初始化、
remove 无 task 泄漏、失败回滚),而非仅 HTTP 包装。前置验证发现 guest 镜像只能
构建期内嵌(include_bytes!),运行时按 base.id 严格匹配内嵌镜像,而内嵌镜像与
VM 注册共用同一份 config 列表——新 id 无内嵌镜像、已有 id 已注册。因此 create
仅对「已内嵌镜像且当前未注册」的 id 有效(remove-then-recreate 默认 VM),
QEMU 实测全流程 PASSED。
Changes:
- http/vm.rs: 新增 POST /api/vms/create(Json body {"toml"})与 DELETE
/api/vms/{id} handler,错误映射 400/409/404/500;remove 显式两步
(先 destroy 检查返回值,再 remove_vm 移出注册表),避免 Drop 静默失败
- http/axum.rs: 注册 create/delete 路由(get(vm_detail).delete(vm_delete));
http-dynamic-test feature 下新增 dynamic 自测
(remove→create→ready→重复create 409→remove→404),单一 PASSED/FAILED sentinel
- Cargo.toml: 新增 http-dynamic-test feature(= http-test + no-auto-start)
- test-suit/axvisor/normal/qemu-http-axum-dynamic/: guest/build/qemu 三份配置,
复用构建期内嵌镜像(image_location=memory),success_regex 匹配 sentinel
- ci.yml: 新增 self-hosted qemu http-axum-dynamic job(先 image pull 再 test)
- doc/http-control-plane-quickstart.md: create/delete 端点 curl 流程、
内嵌镜像约束说明、新增 FAQ 行
dynamic 构建同时运行基础 control lifecycle 自测与 create/delete 自测, 两个自测各打印独立 FAILED 哨兵且互不影响结论。流式匹配器在首个匹配处停止 (fail 先于 success 检查),若只匹配 dynamic 的 FAILED,则 control 失败后 dynamic 通过会被误判为整体 PASS。补上 control 哨兵消除假阳性。 Changes: - qemu-http-axum-dynamic fail_regex 加入 "HTTP self-test: control lifecycle FAILED" - 更新注释说明两个自测各自的 FAILED 哨兵都必须被捕获
There was a problem hiding this comment.
本 PR 为 AxVisor 新增基于 axum/tokio 的 HTTP 管理控制面、VM 生命周期接口、SMP/affinity 调整以及对应 QEMU 用例和 quickstart;它扩展了共享的平台行为,book/guideline/feature-development.md 适用,属于共享且架构相关的功能。HTTP 路由与 VM 状态转换放在 AxVisor 编排层,axvm 仍提供底层生命周期原语;不涉及 StarryOS syscall/Linux ABI 语义。
已检查现有审查意见:此前关于未实现 HTTP feature 与 affinity 映射证明的问题已在当前提交通过 src/http 实现和 axvm 确定性测试处理;本次发现的是当前 head 仍存在的测试/可用性缺口。
验证:prepare-review 与 helper 自测通过;工作区 HEAD 为 1f863b2598f6b3358e7dd4d71c5e8b5c2c4de447;cargo fmt --check、git diff --check origin/dev...HEAD、新增 TOML 解析均通过。cargo xtask axvisor test qemu --arch aarch64 --test-case http-axum-readonly --list 能发现 case;x86 同名命令失败,见内联意见。组织 CI 的格式检查成功;新增的 aarch64 HTTP control/dynamic 任务在该 head 均为 cancelled,不能作为运行通过证据。由于已存在明确阻塞测试覆盖问题,未再运行长时间 QEMU。
重复/重叠分析:比对了 base 中 AxVM manager/lifecycle 与相关开放 PR 搜索结果,未发现与该 HTTP 控制面重复或需要依赖的开放实现;未发现 [patch.crates-io]。现有变更会影响 QEMU 的默认 SMP、vCPU affinity 和管理面网络暴露,因而不是隔离的日志改动。
审查清单:规范、实现、生命周期/并发、配置、runner 发现、CI、格式与重复分析均已完成;以下两个阻塞项必须修复后才能合入。后续仍建议由 AxVisor 与 CI/test 领域维护者复核真实 TCP QEMU 验证方案。
Powered by gpt-5.6-terra
| ] | ||
| success_regex = [ | ||
| "HTTP self-test: GET /api/vms -> 200", | ||
| "HTTP self-test: GET /api/vms/999 -> 404", |
There was a problem hiding this comment.
【阻塞|测试覆盖】这里的成功条件只匹配 tower::oneshot 在进程内调用 Router 的 200/404。server::serve() 会先运行该自测、之后才 TcpListener::bind,而本 case 也没有网卡、hostfwd 或真实 HTTP 客户端;因此 QEMU 可以在监听器绑定/接受任何 TCP 请求之前就判定成功。该 PR 新增的是对外 HTTP 管理面和网络栈集成,当前覆盖没有证明真实 TCP serving path 可用。请在 QEMU case 配置 virtio-net 与 hostfwd,并在 host 侧等待监听就绪后用 curl(或等价客户端)断言 list/detail 及控制路由;oneshot 可保留为 handler 单测,但不能作为唯一成功条件。
| ] | ||
| log = "Info" | ||
| target = "x86_64-unknown-none" | ||
| vm_configs = [] |
There was a problem hiding this comment.
【阻塞|测试发现】此文件把唯一的 x86_64 用例放在 VMX 专用 target 下,但当前 head 执行文档所写的 cargo xtask axvisor test qemu --arch x86_64 --test-case http-axum-readonly --list 会直接报 unknown Axvisor qemu test case;同一命令的 aarch64 变体可以发现用例。新增 CI 也只运行 aarch64,因此所谓双架构 HTTP 覆盖在 x86 上既不能按文档选择,也没有 CI 证据。请将 x86 配置放到默认 x86_64 选择可发现的 build group(或显式调整 runner/CI 以支持 VMX target),同步修正文档命令,并验证该命令确实能发现并执行用例。
b2e1d41 在 vcpu_run 日志里直接写 ax_hal::percpu::this_cpu_id(), 但代码库惯例是从不直接以 ax_hal 为 extern crate 访问(host/arceos.rs 走 ax_std::os::arceos::modules 模块树,main.rs 用 axvm::host::cpu::current_id)。 裸 ax_hal 引用在部分构建图里无法解析,导致 CI smoke-svm 构建 axvm (lib) 时报 E0433 cannot find module or crate ax_hal。改用 crate 自身 的 host::cpu::current_id() 抽象,与 main.rs 保持一致。 Changes: - vcpus.rs vcpu_run 日志 CPU 号改调 crate::host::cpu::current_id()
There was a problem hiding this comment.
本 PR 为 AxVisor 增加基于 axum/tokio 的 HTTP 管理控制面、VM 生命周期接口、默认双核与 vCPU affinity 调整,并新增 QEMU 用例、quickstart 和 CI job。它是共享且平台相关的功能扩展,book/guideline/feature-development.md 适用;HTTP 路由位于 AxVisor 编排层,axvm 仍承担底层生命周期原语。不涉及 StarryOS syscall/Linux ABI。
已复核此前意见:早期“预留 HTTP feature 没有实现”及 affinity 映射证明不足的问题已由当前 src/http 实现和 axvm 确定性测试解决;本次仅保留当前 head 上仍然成立的两个测试问题。
验证:确认 HEAD 为 9afc970d3aca68e0bb0f0128825da31e12596093;prepare-review、helper 自测、cargo fmt --check、git diff --check origin/dev...HEAD 均通过。组织 CI 为 completed=73、success=37、skipped=36、failure=0,相关 HTTP QEMU 检查成功;跳过项符合 host/container 或路径矩阵。依照已通过的组织 CI,未重复完整 QEMU。为验证新增测试的发现路径,本地运行 cargo xtask axvisor test qemu --arch aarch64 --test-case http-axum-readonly --list 能发现 case;同一 x86_64 命令失败,见内联意见。
新增行为需要在正确 runner 层被实际选择并让失败可观察。readonly QEMU 配置目前既无法同时断言两个 GET 状态码,也无法在 x86_64 下被发现,所以不能作为 PR 所声明双架构 API 覆盖。请修复以下两项后重新验证。
重复/重叠分析:已对比 origin/dev 的 AxVM manager/lifecycle、HTTP 相关实现及开放 PR;#1912 仅与 guest-console 有部分重叠,不替代本 PR。未发现重复实现或 [patch.crates-io]。维护者匹配为 AxVisor/axvm 的 ZR233 和 CI/test 的 ZCShou,二者已被请求,无需变更 reviewer 元数据。
审查清单已完成;除以下阻塞项外没有额外未决问题。
Powered by gpt-5.6-terra
| "(?i)\\bpanic(?:ked)?\\b", | ||
| "(?i)kernel panic", | ||
| ] | ||
| success_regex = [ |
There was a problem hiding this comment.
【阻塞|测试覆盖】这里的两个 success_regex 在 AxVisor runner 中是“任一匹配即成功”,不是两个都必须匹配:流式 matcher 命中第一个 success marker 就结束。因此 /api/vms 或 /api/vms/999 任一端点回归时,另一个日志仍会使 QEMU 用例通过,无法验证本 PR 宣称的 200/404 契约。请让 self-test 仅在两个状态码都正确时输出一个最终 PASSED 标记,并在两个架构的配置中匹配它;任一断言失败时输出 FAILED 标记并由 fail_regex 捕获。
| @@ -0,0 +1,17 @@ | |||
| # PR B: axum read-only HTTP API runtime verification (x86_64). | |||
There was a problem hiding this comment.
【阻塞|测试发现】PR 声称 readonly 用例覆盖 x86_64,但当前 runner 无法选择它:在本 head 执行 cargo xtask axvisor test qemu --arch x86_64 --test-case http-axum-readonly --list 会以 unknown Axvisor qemu test case 退出;同名 aarch64 命令能发现用例。根因是 build-x86_64-unknown-none-vmx.toml 被作为 build group 推导,和 CLI 支持的 x86_64-unknown-none target 不匹配,所以 x86 QEMU 配置及 SIMD workaround 都不会运行。请按现有 runner 的 build-group/case 布局调整(或有测试地扩展 discovery),并用上述实际执行命令验证 x86 用例可发现且可运行。
QEMU runner 的流式 matcher 遇首个 marker 即停,原两个 success_regex 是 "任一匹配即成功",任一端点回归时另一个日志仍会让用例通过,无法验证本 PR 声明的 200/404 契约。同时 x86_64 的 build/qemu 配置带 `-vmx` variant 后缀,case 名被推导成 `http-axum-readonly-vmx`,`--test-case http-axum-readonly` 在 x86_64 下无法发现该用例。 Changes: - self-test 改为两个状态码都正确才输出单一 `readonly PASSED`,否则输出 `readonly FAILED`(由 fail_regex 捕获);两个架构 QEMU 配置同步匹配哨兵 - x86_64 build/qemu 配置改为非 variant 命名,`--arch x86_64` 可直接发现并 运行 `http-axum-readonly`(保留 Intel KVM `+vmx-*` args 与 SIMD workaround) - 新增 readonly CI job(aarch64 qcs + x86_64 Intel kvm),双架构覆盖落地 CI
Merging upstream/dev a52d3a7 into feat/axvisor-pr1-axum-infra. The only conflict was in .github/workflows/ci.yml: both sides had inserted jobs at the same position in the axvisor self-hosted matrix. Kept all four jobs so no CI coverage is lost — my http readonly job plus upstream's axloader HTTP smoke and x86_64 ACPI direct/OVMF boot jobs all run, in the same matrix. Changes: - .github/workflows/ci.yml: keep both my aarch64/x86_64 http readonly jobs and upstream's axloader HTTP smoke / x86_64 ACPI direct boot (svm, vmx) jobs.
There was a problem hiding this comment.
本 PR 为 AxVisor 增加基于 axum/tokio 的 HTTP 管理控制面、VM 生命周期接口、SMP/affinity 配置、QEMU 用例和操作文档。它扩展共享且平台相关的功能,book/guideline/feature-development.md 适用;不涉及 StarryOS syscall/Linux ABI。HTTP 路由和 VM 状态转换位于 AxVisor 编排层,axvm 保留底层生命周期能力。
已核对既有意见:此前关于预留 feature、affinity 映射以及多 success marker 的问题已在当前 head 通过实现、确定性 axvm 测试和单一哨兵处理。当前仍存在下面的真实 TCP 覆盖缺口。
验证:已确认 HEAD 为 756400eb25074b740c7668ee6d68633893510bde,工作区干净;git diff --check origin/dev...HEAD、cargo fmt --check、新增 TOML 解析和 review helper 自测通过。cargo xtask axvisor test qemu --arch {aarch64,x86_64} --test-case http-axum-readonly --list 以及 aarch64 control/dynamic 的 --list 均发现对应 case。组织 CI 当前头的 AxVisor 相关任务已成功,但这些任务同样只消费 in-process self-test 哨兵,不能证明 TCP 入口;没有发现由本 PR 导致的已失败 CI。未发现 [patch.crates-io]。
测试均放在 test-suit/axvisor/normal 且被 runner 发现;不过它们没有覆盖 PR 所声称的 QEMU 网络转发和真实 HTTP 服务路径。quickstart 中的 hostfwd + curl 是手工流程,未接入 CI。已比较 origin/dev 的 AxVisor/axvm 模式及相关开放 PR;未发现重复或需要依赖的实现。
审查清单已完成。请补齐下列阻塞项后重新请求审查。
Powered by gpt-5.6-terra
| .await | ||
| .expect("failed to bind management HTTP server"); | ||
| info!("management HTTP server (axum) listening on 0.0.0.0:8080"); | ||
| axum::serve(listener, router()).await.expect("server error"); |
There was a problem hiding this comment.
【阻塞|HTTP 运行时覆盖】这里的 self_test() 在绑定 listener 之前就打印所有 QEMU 成功哨兵,并且只用 Router::oneshot 调 handler;它不经过 TcpListener::bind、axum::serve、Tokio IO reactor 或 AxVisor 网络入口。因而即使真实 TCP listener 无法绑定或无法接受请求,新增的 readonly/control/dynamic 用例仍会在这之前匹配 PASSED 而通过。请新增带 QEMU hostfwd 的 host→guest TCP 集成测试,实际请求 API 并以响应状态作为成功条件;现有 oneshot 自测可以保留作路由单测。
PR rcore-os#1909 评审阻塞:http-axum-readonly 的 oneshot 自测在 TcpListener::bind 之前 就打印所有成功哨兵,不经过 TcpListener::bind / axum::serve / Tokio IO reactor 或 AxVisor 网络入口,真实 listener 无法绑定也会提前 PASSED。本提交新增带 QEMU hostfwd 的 host→guest TCP 集成测试:宿主机侧 probe 线程通过 QEMU user-mode networking 真实请求访客内管理 API(GET /api/vms→200、GET /api/vms/999→404), 独立校验响应状态后把单一 PASSED/FAILED 裁决 POST 到测试专用 /__probe_result 端点,hypervisor 镜像到串口,复用现有哨兵→kill 机制。oneshot 自测保留作路由 单测。hostfwd 端口在测试时动态选取(bind 127.0.0.1:0)避免 CI 端口冲突。 Changes: - os/axvisor: 新增 http-tcp-test feature(http-axum,无 tower oneshot)与 POST /__probe_result 裁决中继端点 - scripts/axbuild: 新增 host_probe.rs(HostHttpProbeGuard),hostfwd 端口动态 选取,netdev/device 按独立 argv 追加;QemuCaseExtraConfig 增加 host_http_probe - test-suit: 新增 qemu-http-axum-tcp 用例(aarch64 + x86_64,[host_http_probe]) - ci: axvisor 矩阵新增 aarch64 / x86_64 (http tcp) 两个 job
There was a problem hiding this comment.
本 PR 为 AxVisor 增加基于 axum/tokio 的 HTTP 管理控制面、VM 生命周期接口、SMP=2 与 vCPU affinity 调整,以及 QEMU/host-probe 测试和 quickstart。它属于共享、架构相关的功能扩展;book/guideline/feature-development.md 适用,StarryOS syscall/Linux ABI 准则不适用。改动会影响 AxVisor 的网络暴露、QEMU 启动拓扑、vCPU 调度与测试 runner,非隔离改动。
实现方向上,HTTP 路由保留在 AxVisor 编排层,axvm 继续提供底层生命周期原语;新增的 affinity 映射单测、host-probe 单测,以及 aarch64/x86_64 readonly case 的 runner 发现均已复核。此前关于未实现 HTTP feature、affinity 映射和 readonly regex 的合理意见已在当前头以实现、确定性映射测试和最终 sentinel 处理;当前剩余的是以下两个当前 head 的阻塞问题。
验证:prepare-review 与 helper 自测通过;git diff --check origin/dev...HEAD、cargo fmt --check 通过。cargo test -p axbuild host_probe 的 6 项测试通过,但产生本次新增的 unused-import warning;cargo test -p axvm --features host-test phys_cpu_list_pins_single_vcpu_to_isolated_core 通过。按真实 feature 配置执行 cargo xtask axvisor build,web-ui 构建在未解析 web_ui 模块处失败。组织 CI 在当前 head 为 success=44、skipped=43、failure=0;相关 AxVisor HTTP/QEMU 任务成功,skipped 项符合 host/container/路径矩阵,未见由本 PR 造成的远端 CI 失败。由于 CI 已覆盖相关 QEMU 用例,未重复完整本地 QEMU 运行。
测试覆盖状态:新增 case 位于 test-suit/axvisor/normal,并可由 cargo xtask axvisor test qemu --arch {aarch64,x86_64} --test-case http-axum-readonly --list 发现;但 web-ui 公开 feature 没有对应实现或覆盖,且 axbuild 的新增测试仍不满足 warning-free 要求。
重复/重叠分析:已对比 base 的 AxVM affinity/生命周期模式,并以 AxVisor HTTP、axvm affinity、qemu-http-axum 关键词搜索开放 PR;未发现重复、替代或需先后合入的实现。未发现 [patch.crates-io]。.github/MAINTAINERS.md 的 AxVisor/axvm 和 CI/test 路径均匹配,ZR233、ZCShou 已在 requested reviewers 中,未修改审阅人。
审查清单已完成;以下两项修复后请重新运行相应构建与 clippy。
Powered by gpt-5.6-terra
|
|
||
| #[cfg(feature = "web-ui")] | ||
| { | ||
| router = router.merge(crate::http::web_ui::ui_routes()); |
There was a problem hiding this comment.
【阻塞|功能可用性】web-ui feature 在这里会合并 crate::http::web_ui::ui_routes(),但本 PR 的 http/mod.rs 只声明了 server、vm,也没有新增 web_ui 模块或实现。以 web-ui(加 ax-driver/nvme)运行 cargo xtask axvisor build 已在此处和 init() 处报 E0433。也就是说,这个公开 feature 无法构建,无法提供注释承诺的 dashboard。请补齐并声明 web_ui(包括资源初始化和路由)且加入该 feature 的编译/运行覆盖;若本 PR 尚未实现它,请移除 feature 与相关说明。
| io::{Read, Write}, | ||
| net::TcpListener, | ||
| sync::{ | ||
| atomic::{AtomicBool, Ordering}, |
There was a problem hiding this comment.
【阻塞|Clippy】这里新增的 Ordering、mpsc 没有被使用;cargo test -p axbuild host_probe 已对这两项报出 unused_imports,而 cargo clippy -p axbuild --tests -- -D warnings 也因此失败。项目要求改动后的 crate 通过 clippy 且不能靠忽略 warning,所以该新增测试目标目前不是 warning-clean。请删除未使用导入,并用针对 axbuild 测试目标的 -D warnings 检查复核。
PR1(axum 基础设施)不应包含 web-ui 仪表盘——该功能属于后续 PR6。 此前 web-ui 的 Cargo.toml feature、server.rs 引用与 CI job 被提交到本分支, 但实现(src/http/web_ui.rs、mod.rs 声明、build.rs 内嵌代码生成)未一并提交, 导致 E0433(模块 web_ui 无法解析)构建失败。按 reviewer 意见整体移除 web-ui 骨架:删除 feature、include、router merge、serve() init 调用、self-test 段落 与两个 CI job,build.rs/mod.rs 恢复与上游一致。同时清理 host_probe.rs tests 模块未使用的 Ordering/mpsc 导入,消除 clippy 阻塞项。 Changes: - os/axvisor: 移除 web-ui feature(Cargo.toml)与 server.rs 中的相关引用/自测 - scripts/axbuild: host_probe tests 模块移除未使用导入(Ordering/mpsc)
There was a problem hiding this comment.
本 PR 为 AxVisor 增加基于 axum/tokio 的 HTTP 管理控制面、VM 生命周期接口、SMP/affinity 调整,以及 QEMU/hostfwd 测试与操作文档。它是共享、平台相关的功能扩展,book/guideline/feature-development.md 适用;不涉及 StarryOS syscall/Linux ABI。HTTP 路由位于 AxVisor 编排层,axvm 保留底层生命周期原语。
已复核历史审查:此前关于预留 feature、affinity 映射、QEMU case 发现以及多 success marker 的合理意见,在当前 head 已分别由完整实现、确定性 axvm 测试、可发现的双架构 case 和单一最终哨兵处理。当前未发现 [patch.crates-io],也未发现与 base 或开放 PR 重复的实现。
验证:工作区 HEAD 已确认是 b96322eced9776dd3327230006aaf0eb22b785f9,prepare-review、git diff --check origin/dev...HEAD 通过;cargo xtask axvisor test qemu --arch aarch64 --test-case http-axum-readonly --list 发现新增 case;cargo test --manifest-path scripts/axbuild/Cargo.toml host_probe --all-features 通过。组织 CI 当前头 completed=87、success=44、skipped=43、failure=0,相关 AxVisor HTTP QEMU job 成功;跳过项属于 host/container 或平台矩阵。按要求未重复已通过的完整本地 QEMU。
但该实现将未认证的写控制面暴露到管理网络,影响现有 VM 生命周期和 hypervisor 资源安全边界,不能视为隔离的调试日志功能。请先解决下面的安全问题;除该阻塞项外,本轮没有额外未决测试缺口。
Powered by gpt-5.6-terra
| #[cfg(feature = "http-dynamic-test")] | ||
| dynamic_test::self_test_dynamic().await; | ||
|
|
||
| let listener = tokio::net::TcpListener::bind("0.0.0.0:8080") |
There was a problem hiding this comment.
【阻塞|安全】此处把无认证、无加密的 VM 生命周期控制面固定监听在 0.0.0.0:8080。/api/vms/{id}/stop、create/delete 等路由会直接改变 EL2 中的 guest 和资源状态,因此任何可达管理网络的主体都可终止或重建 VM;quickstart 也明确承认该端口对管理网络全开放。文档声明“仅用于调试”不能替代请求侧授权。请在公开这些写接口前提供认证/访问控制与受限监听配置(并补充真实 TCP 的拒绝访问回归测试),或把当前实现限制为不可对外暴露的测试接口。
There was a problem hiding this comment.
已解决(Path A:认证/访问控制 + 受限监听配置 + 真实 TCP 拒绝访问回归测试)。
认证(写路由默认拒绝)
- 新增
os/axvisor/src/http/auth.rs:ApiToken提取器匹配Authorization: Bearer <token>;token 经构建期[env] AXVM_HTTP_TOKEN注入(option_env!,与shell/command/base.rs读AX_ARCH同机制)。 create/delete/start/stop及测试专用POST /__probe_result五个写 handler 均挂载ApiToken作为第一个提取器,401 在 VM 查找之前触发。- 默认拒绝:
AXVM_HTTP_TOKEN未设置 → 写路由一律 401,无“回退为允许 + 警告”路径。
受限监听
bind_addr()默认127.0.0.1:8080(loopback,管理网络不可达);需 hostfwd/对外暴露的构建显式设置[env] AXVM_HTTP_BIND = "0.0.0.0:8080"才监听所有接口。
真实 TCP 拒绝访问回归(host_probe)
qemu-http-axum-tcp在 host 侧经 QEMU hostfwd 真实 dial guest 内管理 API,顺序断言:GET /api/vms -> 200(就绪)、无 tokenPOST /api/vms/999/start -> 401(拒绝访问回归)、带 tokenGET /api/vms/999 -> 404、带 tokenPOST /api/vms/999/start -> 404;任一失败则 verdict FAILED(经POST /__probe_result镜像进 serial,runner 以单一tcp PASSED哨兵判定)。
验证
- aarch64 + x86_64
http-axum-tcp均 PASS,日志含POST /api/vms/999/start (no token) -> 401 (expect 401)。 - aarch64 readonly/control/dynamic 回归通过(自测写请求带构建期 token 通过认证)。
cargo test -p axbuild host_probe8/8;axvisor clippy(musl+build-std)与 axbuild clippy 无新增警告;cargo fmt --check干净。
安全边界(quickstart §5 已同步):写保护 + 默认 loopback 双层防护;读路由开放但默认 loopback 下管理网络不可达;仍无 TLS(bare-metal 内 TLS 超出本期范围,文档已声明)。
安全加固(PR 阻塞项):写路由(create/delete/start/stop、__probe_result)要求
Authorization: Bearer <token>,token 经构建期 [env] AXVM_HTTP_TOKEN 注入
(option_env!);未设置时默认拒绝(一律 401)。服务器默认绑定 127.0.0.1:8080,
hostfwd 测试构建显式 opt-in [env] AXVM_HTTP_BIND="0.0.0.0:8080"。
验证:aarch64/x86_64 http-axum-tcp 均 PASS(401/200/404 断言全部命中);
aarch64 readonly/control/dynamic 回归通过;host_probe 单测 8/8;axvisor clippy
(musl+build-std)无新增警告;fmt 干净。
Changes:
- os/axvisor/src/http/auth.rs:ApiToken FromRequestParts 提取器(默认拒绝)
- http/{vm,server}.rs:五个写 handler 挂载 ApiToken;bind_addr() 可配绑定
- host_probe:request_status 支持 token;新增"无 token 写请求 -> 401"拒绝访问断言
- control/dynamic/tcp 构建 config 烘焙 token;readonly/tcp 显式绑定所有接口
- quickstart 安全边界章节改写,curl 写命令带 Bearer token
There was a problem hiding this comment.
本 PR 为 AxVisor 增加基于 axum/tokio 的 HTTP 管理控制面、受认证保护的 VM 生命周期 API、默认 SMP/CPU affinity 调整,以及 readonly/control/dynamic/真实 TCP QEMU 覆盖和操作指南。book/guideline/feature-development.md 适用:这是共享、平台相关功能;实现将 HTTP 边界保留在 AxVisor 编排层,AxVM 继续提供生命周期原语。Starry syscall/Linux ABI 指南不适用。
已复核实现逻辑与前序意见:写路由要求 Bearer token,未配置 token 时默认拒绝;监听默认 loopback,测试/显式配置才暴露至外部;TCP probe 通过 QEMU hostfwd 验证真实 listener、401 拒绝访问、200/404 及带 token 的写路由。此前关于预留 feature、affinity 证明、x86 发现、单哨兵失败传播、真实 TCP 覆盖、未实现 web-ui、clippy 和未认证外露的合理意见均已在当前头解决。当前无遗留的合理行级问题。
验证:组织当前头 CI 为 success=44、skipped=43、failure=0;相关 AxVisor HTTP readonly/control/dynamic/TCP QEMU 和 x86 self-hosted 任务成功,跳过项为 host/container 或路径矩阵项。按“已通过相关组织 CI 不重复完整运行”的约定,未重复 QEMU;本地完成 prepare-review、git diff --check origin/dev...HEAD、cargo fmt --check、cargo xtask clippy --package axbuild、cargo xtask clippy --package axvm,均通过。新增 aarch64 与 x86_64 HTTP cases 均能由 cargo xtask axvisor test qemu --arch <arch> --test-case <case> --list 发现。
测试位于 test-suit/axvisor/normal,由 AxVisor QEMU runner 和 CI 选择;HTTP handler/lifecycle 的单哨兵与 hostfwd probe 可在回归时失败。未发现 [patch.crates-io]。已比对 origin/dev 的 AxVM 生命周期/affinity 模式,并检索相关开放 PR;未发现重复、替代或需要声明依赖的实现。审查清单已完成,无未解决风险或测试缺口。维护者路由匹配 AxVisor、AxVM、CI/test(ZR233、ZCShou);本次批准后没有需新增请求的后续阻塞事项。
Powered by gpt-5.6-terra
问题
AxVisor 需要一个管理 HTTP 控制面:通过网络远程查看/启动/停止/创建/删除虚拟机。落地需要三块:ArceOS 网络栈(axum serve 监听 TCP)、双核隔离(vCPU 钉 Core 1、管理面留 Core 0)、以及一个可运行的 HTTP 管理 API(axum + serde_json,替代早期手写 pilot)。
修改
基础设施
http-axum/http-test/http-tcp-test/no-auto-start/http-dynamic-testfeature 与 axum/tokio/serde_json/tower 可选依赖;ax-std 启用netsmp = 1→smp = 2phys_cpu_ids = [1],x86phys_cpu_sets = [2])HTTP API(axum)
http-tcp-test测试专用裁决中继端点,镜像到串口)enable_io(),无需 timerfd syscall回归测试
default_vcpu_affinities+PhysCpuList确定性映射单测测试/文档/CI
GET /api/vms→200、GET /api/vms/999→404),独立校验响应状态后把 PASSED/FAILED 裁决 POST 到/__probe_result,hypervisor 镜像到串口,复用哨兵→kill 机制验证
cargo test -p axvm --features host-test:240 passed(含新增 affinity 映射单测)cargo xtask axvisor build --config qemu-http-axum-{readonly,control,dynamic,tcp}均通过cargo xtask axvisor test qemu --arch {aarch64,x86_64} --test-case http-axum-tcp:两架构通过,串口出现HTTP self-test: tcp PASSEDlist_vms返回 500,probe 收到 500≠200 后 relay FAILED,=== FAIL PATTERN MATCHED: HTTP self-test: tcp FAILED ===,用例按预期失败shell task on CPU0、HTTP 自测 200/404、control lifecycle PASSED、dynamic create/delete PASSED评审修复(本轮提交)
web-uifeature、server.rs 中 router merge / serve() init / self-test 引用,build.rs/mod.rs恢复与上游一致Ordering/mpsc导入,消除 clippy 阻塞项cargo xtask clippy --package axbuild通过;http-axum-tcp aarch64 构建通过(E0433 已消除)安全加固(评审阻塞项)
写控制面(create/delete/start/stop +
POST /__probe_result)此前无认证、固定监听0.0.0.0:8080,任何可达管理网络的实体可终止/重建 VM。本轮改为认证 + 受限监听 + 真实 TCP 拒绝访问回归:os/axvisor/src/http/auth.rs:ApiToken提取器要求Authorization: Bearer <token>;token 经构建期[env] AXVM_HTTP_TOKEN注入(option_env!,与shell/command/base.rs读AX_ARCH同机制)127.0.0.1:8080(loopback);hostfwd/对外暴露的构建显式设置[env] AXVM_HTTP_BIND = "0.0.0.0:8080"POST /api/vms/999/start (no token) -> 401);aarch64 readonly/control/dynamic 回归通过;host_probe 单测 8/8;axvisor/axbuild clippy 无新增警告;fmt 干净