From 5d871e8b2176c977f30318e270c28cb7319f6532 Mon Sep 17 00:00:00 2001 From: mofeng-git Date: Sun, 19 Jul 2026 20:08:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20MSD=20=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E6=97=B6=20Ventoy=20=E8=B5=84=E6=BA=90=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E9=97=AE=E9=A2=98=20#275?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 Ventoy 资源初始化纳入 MSD 控制器启用流程 - 支持运行时启用 MSD,无需重启服务 - 调整验收测试并移除启用后的重启逻辑 --- src/main.rs | 18 +----------------- src/msd/controller.rs | 16 ++++++++++++++-- src/web/handlers/config/apply.rs | 3 ++- test/okvm-test/okvm_report.py | 8 ++------ test/okvm-test/okvm_testctl.py | 27 +++++---------------------- 5 files changed, 24 insertions(+), 48 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0a3752f5..aae6d39f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -335,24 +335,8 @@ async fn main() -> anyhow::Result<()> { #[cfg(unix)] let msd = if config.msd.enabled { let ventoy_resource_dir = data_dir.join("ventoy"); - if ventoy_resource_dir.exists() { - if let Err(e) = ventoy_img::init_resources(&ventoy_resource_dir) { - tracing::warn!("Failed to initialize Ventoy resources: {}", e); - } else { - tracing::info!( - "Ventoy resources initialized from {}", - ventoy_resource_dir.display() - ); - } - } else { - tracing::warn!( - "Ventoy resource directory not found: {}", - ventoy_resource_dir.display() - ); - } - let controller = MsdController::new(otg_service.clone(), config.msd.msd_dir_path()); - if let Err(e) = controller.init().await { + if let Err(e) = controller.init(&ventoy_resource_dir).await { tracing::warn!("Failed to initialize MSD controller: {}", e); None } else { diff --git a/src/msd/controller.rs b/src/msd/controller.rs index b742aefd..bfbfcf58 100644 --- a/src/msd/controller.rs +++ b/src/msd/controller.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::Arc; use tokio::sync::RwLock; use tokio_util::sync::CancellationToken; @@ -47,9 +47,21 @@ impl MsdController { } } - pub async fn init(&self) -> Result<()> { + pub async fn init(&self, ventoy_resource_dir: &Path) -> Result<()> { info!("Initializing MSD controller"); + match ventoy_img::init_resources(ventoy_resource_dir) { + Ok(()) => info!( + "Ventoy resources ready from {}", + ventoy_resource_dir.display() + ), + Err(e) => warn!( + "Failed to initialize Ventoy resources from {}: {}. Ventoy drive creation will be unavailable, but regular ISO/IMG MSD remains available", + ventoy_resource_dir.display(), + e + ), + } + if let Err(e) = std::fs::create_dir_all(&self.images_path) { warn!("Failed to create images directory: {}", e); } diff --git a/src/web/handlers/config/apply.rs b/src/web/handlers/config/apply.rs index 0ea6e4fa..741331a9 100644 --- a/src/web/handlers/config/apply.rs +++ b/src/web/handlers/config/apply.rs @@ -317,7 +317,8 @@ pub async fn apply_msd_config( let msd = crate::msd::MsdController::new(state.otg_service.clone(), new_config.msd_dir_path()); - msd.init() + let ventoy_resource_dir = state.data_dir().join("ventoy"); + msd.init(&ventoy_resource_dir) .await .map_err(|e| AppError::Config(format!("MSD initialization failed: {}", e)))?; diff --git a/test/okvm-test/okvm_report.py b/test/okvm-test/okvm_report.py index f2c0b98c..cb9e50f7 100644 --- a/test/okvm-test/okvm_report.py +++ b/test/okvm-test/okvm_report.py @@ -61,7 +61,7 @@ REPORT_HIDDEN_RESULTS = { } CATEGORY_RULES = ( - ("初始化与环境", ("target_", "setup_", "login", "network_", "target_inventory", "stream_codecs", "windows_agent", "ventoy_resources", "msd_restart")), + ("初始化与环境", ("target_", "setup_", "login", "network_", "target_inventory", "stream_codecs", "windows_agent", "ventoy_resources")), ("视频性能", ("video_", "config_video_")), ("HDMI 画面与颜色", ("hdmi_", "config_video_hdmi_probe")), ("HID / MSD / ATX", ("hid_", "msd", "atx_")), @@ -71,12 +71,10 @@ DISPLAY_NAMES = { "target_reset": "目标机重置", "setup_init": "初始化账号", "login": "登录", - "login_after_restart": "重启后登录", "network_latency": "网络延迟", "target_inventory": "目标机设备清单", "hid_msd_config": "HID/MSD 配置", "ventoy_resources": "Ventoy 资源", - "msd_restart": "MSD 启用后重启", "video_input_select": "视频输入选择", "windows_agent": "Windows 配套程序连接", "config_video_hdmi_probe": "HDMI 采集配置", @@ -564,14 +562,12 @@ def summarize_result(result: CheckResult, metrics: list[Metric]) -> str: return "数据库已备份,服务已重启" if name == "setup_init": return "初始化检查完成" - if name in {"login", "login_after_restart"}: + if name == "login": return "认证成功" if name == "hid_msd_config": return "已按设备能力配置 HID/MSD" if name == "ventoy_resources": return "Ventoy 资源检查完成" - if name == "msd_restart": - return "服务重启完成" if name == "video_input_select": cases = data.get("cases") or [] return ",".join(f"{c.get('fmt')} {c.get('width')}x{c.get('height')}@{c.get('fps')}" for c in cases if isinstance(c, dict)) diff --git a/test/okvm-test/okvm_testctl.py b/test/okvm-test/okvm_testctl.py index b51d9739..440e0d64 100755 --- a/test/okvm-test/okvm_testctl.py +++ b/test/okvm-test/okvm_testctl.py @@ -507,6 +507,11 @@ echo "$BACKUP" }, ) self.selected_hid_backend = "otg" + if not self.args.no_ventoy_sync: + try: + self.sync_ventoy_resources() + except Exception as exc: + self.reporter.add("ventoy_resources", "WARN", f"failed to sync Ventoy resources: {exc}") try: self.api.patch("/config/msd", {"enabled": True}) except Exception as exc: @@ -514,16 +519,6 @@ echo "$BACKUP" self.reporter.add("hid_msd_config", "WARN", f"configured OTG HID but failed to enable MSD: {exc}", udc=udc_name) return self.reporter.add("hid_msd_config", "PASS", "configured OTG HID and enabled MSD", udc=udc_name) - if not self.args.no_ventoy_sync: - try: - self.sync_ventoy_resources() - except Exception as exc: - self.reporter.add("ventoy_resources", "WARN", f"failed to sync Ventoy resources: {exc}") - if not self.args.no_msd_restart_after_enable: - try: - self.restart_target_service("msd_restart", "restarted One-KVM after enabling MSD") - except Exception as exc: - self.reporter.add("msd_restart", "WARN", f"failed to restart after enabling MSD: {exc}") return if serial: port = serial[0]["path"] @@ -556,17 +551,6 @@ echo "$BACKUP" ) ) - def restart_target_service(self, check_name: str, detail: str) -> None: - if not self.ssh_password and self.args.ssh_password_prompt: - self.ssh_password = getpass.getpass(f"SSH password for {self.args.ssh_user}@{self.args.target}: ") - ssh = SSHRunner(self.args.target, self.args.ssh_user, self.ssh_password, self.args.ssh_port) - code, out, err = ssh.run("systemctl restart one-kvm || service one-kvm restart", timeout=90) - if code != 0: - raise RuntimeError(err or out or "service restart command failed") - self.api.wait_health(timeout=self.args.health_timeout) - self.authenticate("login_after_restart", "authenticated after One-KVM restart") - self.reporter.add(check_name, "PASS", detail) - def sync_ventoy_resources(self) -> None: source_dir = Path(self.args.ventoy_resources_dir) if self.args.ventoy_resources_dir else default_ventoy_resources_dir() if not source_dir.exists(): @@ -2277,7 +2261,6 @@ def build_parser() -> argparse.ArgumentParser: run.add_argument("--msd-probe-bytes", type=int, default=1024 * 1024) run.add_argument("--ventoy-resources-dir", default=None, help="local Ventoy resource directory; defaults to repo libs/ventoy-img-rs/resources") run.add_argument("--no-ventoy-sync", action="store_true", help="do not copy Ventoy resources to the target before MSD testing") - run.add_argument("--no-msd-restart-after-enable", action="store_true", help="do not restart One-KVM after enabling MSD") run.add_argument("--strict-performance", action="store_true", help="fail video results below the expected FPS threshold; default only requires fps > 0") run.add_argument("--no-color", action="store_true", help="disable colored terminal output") run.add_argument("--no-screenshots", action="store_true", help="skip Playwright webpage screenshots")