Skip to content

feat(ostool-server): add network axloader control plane - #179

Merged
ZR233 merged 1 commit into
mainfrom
codex/axloader-network-control
Sep 7, 2026
Merged

feat(ostool-server): add network axloader control plane#179
ZR233 merged 1 commit into
mainfrom
codex/axloader-network-control

Conversation

@ZR233

@ZR233 ZR233 commented Sep 7, 2026

Copy link
Copy Markdown
Member

背景

现有 UEFI HTTP Boot 通过串口等待 AXLOADER READY 并发送 BOOT,控制协议与目标系统交互复用同一串口。板卡重启、串口重连和多种 UEFI 固件实现容易让控制消息与系统输出相互干扰,也无法在未配置板卡上先发现硬件再完成绑定。

本 PR 将 axloader 控制面迁移到 UDP 发现与 HTTP poll/status,板卡 TOML 以永久 MAC 作为唯一持久绑定事实;串口只保留目标系统交互。协议为不兼容的 httpboot-protocol 0.2,不保留旧 READY/BOOT 兼容路径。

主要改动

协议与板卡身份

  • httpboot-protocol 升级到 0.2,提供 no_std + alloc + serde_json 支持。
  • 增加规范化 MacAddress、硬件信息、UDP discovery、poll、启动清单和状态类型;发现报文限制为 1400 字节。
  • BoardConfig 增加 network_identity.mac_address;HTTP Boot 板卡必须配置 MAC,MAC 规范化并全局唯一。
  • board_type 仍由管理员填写,只作为 Session 资源池标签;SMBIOS 只用于辨认硬件。

Loader 与 Session 生命周期

  • UDP 固定监听 2998,签发每次固件启动独有的 registration_id
  • 增加 loader poll/status、管理端设备列表和 Session loader status API。
  • LoaderRegistry 独立管理注册挑战、在线状态、代次替换和重复 MAC 冲突;10 秒未上报为离线,记录保留 24 小时。
  • 启动清单与状态由 SessionState 原子持有,以 session_id + boot_id + registration_id 拒绝旧代次迟到状态。
  • 活动 Session 中板卡重启后,新注册代次重新取得相同 boot_id;Session 释放才删除命令和状态。
  • 板卡创建、更新、删除、Session claim 和虚拟设备删除共用清单事务门,避免 MAC/租约竞争。

ostool CLI 与 Web UI

  • HTTP Boot runner 改为上传内核后立即连接串口 WebSocket,不再等待 READY 或发送 BOOT。
  • runner 并行监听 loader 状态和原始串口;loader failed 终止运行,最终成功仍由目标系统串口条件决定。
  • Boards 页面每 5 秒刷新未绑定/已绑定 loader,显示 MAC、IP、架构、loader 版本、SMBIOS、在线和冲突状态。
  • 创建配置只预填选中设备的 MAC;板卡 ID、board_type、电源、串口和启动配置仍由用户填写。
  • MAC 支持探测下拉和手工输入,重复绑定返回稳定错误码 mac_already_bound

内建 QEMU 虚拟板

  • 增加默认关闭的 virtual_qemu 配置、QEMU 电源后端和虚拟串口 key。
  • VirtualBoardManager 管理 QEMU、OVMF VARS、TAP、QMP 和跨子进程重启保持的串口 hub;hub 保留最近 64 KiB 早期输出。
  • On/Off 幂等,关闭优先 QMP,超时后终止进程并回收资源。
  • 管理 API/UI 可以启动和清理未绑定虚拟设备;虚拟板必须经过真实 UDP/HTTP 发现,禁止注入假记录。
  • 增加幂等 virtual-lab up|status|down,管理独立 network namespace、bridge、veth、dnsmasq 和 TAP 池。

迁移与兼容性

  • 这是不兼容切换:新 server、ostool CLI 和 axloader 必须协调升级。
  • 现有 HTTP Boot 板卡配置需要先补充唯一 network_identity.mac_address
  • 合入后先发布 httpboot-protocol 0.2,再提交/合入 TGOSKits axloader 消费端,最后在维护窗口更新 server、CLI、UI 和 EFI。
  • server 重启后保留板卡配置,但本阶段不恢复重启前的活动 Session、启动命令或 WebSocket。

安全边界

当前按受信实验室网络处理。MAC 是绑定键而不是认证凭据;HTTP 和由同一控制面下发的 SHA-256 只能验证传输完整性,不能抵抗同一二层网络中的主动攻击。本 PR 不关闭 TGOSKits 的签名/HTTPS 真实性问题:rcore-os/tgoskits#1749

验证

  • cargo fmt --all -- --check
  • cargo clippy --target x86_64-unknown-linux-gnu --all-features
  • cargo build --target x86_64-unknown-linux-gnu --all-features
  • cargo test --target x86_64-unknown-linux-gnu -- --nocapture
  • cargo test -p ostool-server:119 个单元测试和 3 个 WebSocket 生命周期集成测试通过
  • cargo check -p httpboot-protocol --no-default-features --features alloc,json
  • cargo publish --workspace --dry-run --locked
  • pnpm test -- --run:27 个测试通过
  • pnpm build
  • PLAYWRIGHT_CHROMIUM_EXECUTABLE=/snap/bin/chromium pnpm test:e2e:浏览器 E2E 通过

在隔离 network namespace 中完成 x86_64 + OVMF + q35 全流程验证:真实发现未绑定 QEMU、绑定 MAC、创建 Session、上传并 handoff、保持同一 WebSocket 执行 Off -> On、新 registration_id 复用同一 boot_id、关闭 WebSocket 后释放并断电、再创建新 Session 成功运行。三次目标串口成功标志均收到。

@ZR233
ZR233 merged commit 46b6cba into main Sep 7, 2026
2 checks passed
This was referenced Sep 7, 2026

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

总结

本 PR 将 axloader 控制面从串口 READY/BOOT 迁移到 UDP 发现与 HTTP poll/status,补充板卡 MAC 绑定、虚拟 QEMU、CLI/UI 和新的 httpboot-protocol 0.2 契约;目标问题和整体改动范围与 PR 描述一致。

验证与上下文

  • 当前 head 仍为 e942197239a6aabfacefaa8ef3543c82bc96288dgit diff --check origin/main...HEAD 通过。
  • GitHub 的两个 check run 均为 completed/success;现有 workflow 主要覆盖 --all-features,因此不会覆盖下面指出的 std-only feature 组合。
  • 本地环境没有 cargo,无法执行 helper 建议的 cargo fmt --check、clippy 和测试;pnpm 也不可用,Web UI 测试未能本地执行。这些是环境限制,不是当前 CI 失败。
  • 检查了相关历史 PR 搜索结果,未发现与本次实现重叠的其他实现 PR;结果主要是本 PR #179 及其自动 release PR #180
  • 当前没有先前的 review 或 issue 评论需要处理。

未解决问题

有一条阻塞问题,已在 httpboot-protocol/src/lib.rs:287 添加行内评论:DiscoveryMessageError 只在 alloc + json 下定义,但 std::error::Error 的 impl 只检查 std。由于 std feature 并不依赖 json,合法的 --no-default-features --features std 组合会引用不存在的类型而无法编译。请对齐 cfg 条件或让 std 显式依赖 json,并补充该 feature 组合的构建覆盖。

除此之外,本轮未保留其他活动 finding;该修复前不建议合并。

Powered by gpt-5.6-luna

))
}
#[cfg(feature = "std")]
impl std::error::Error for DiscoveryMessageError {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的 cfg 与类型定义不一致:DiscoveryMessageError 及其 Display 实现都要求 alloc + json,但这个 std::error::Error impl 只检查 stdhttpboot-protocol/Cargo.tomlstd 不会启用 json,所以 cargo check -p httpboot-protocol --no-default-features --features std 会在这里引用未定义的 DiscoveryMessageError 并失败。请将条件改为 all(feature = "alloc", feature = "json", feature = "std"),或让 std 显式依赖 json,并加入该 feature 组合的构建测试。

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