云电脑模式持久化目录挂载 bug 定位

Blade OS & Blade Agent · 跨服务目录共享问题

症状

用户在云电脑模式(blade-agent 持久会话)下,于 /workspace/.home 创建的文件夹或文件,无法从 Blade OS 文件管理器中看到,导致用户数据无法跨服务持久化与共享。

根因(三层叠加)

① 部署层 — box-deploy 漏挂 /opt/box/files

宿主机 /opt/box/files/ 不存在;blade-os 容器 compose 未声明该路径的 bind mount。文档 / 模板里写了,box-deploy 实际渲染时丢了这行。

/opt/box-deploy/agent/blade-os/docker-compose.yaml(对比 blade-os/dist/docker-compose.yaml:73

② 业务层 — blade-os 不会主动为新用户创建目录

FileService.ensure_user_home(user_id) 是纯懒加载方法,只在目录不存在时建;调用方 全部 位于文件管理器 API 路由内。新用户跳过文件管理器、直接进云电脑模式 → 目录永远没人触发创建。

backend/app/services/file_service.py:45-53 · 调用方 backend/app/api/v1/files.py

③ fail-soft 层 — blade-agent 目录不存在时静默降级

_resolve_user_home_host_path 检测到目录不存在直接 return None,sandbox fallback 到一个独立 named volume blade-home-{user} 挂到 /root,与 /opt/box/files/users/{id} 彻底脱钩。

host/src/blade_agent/host/_engine_runtime.py:33-58 · 分支 host/src/blade_agent/host/sandbox/docker.py:657-668

触发链

  1. 宿主机 /opt/box/files 不存在(①)
  2. 新用户跳过文件管理器,blade-os 不会创建 /opt/box/files/users/{id}(②)
  3. 用户首次进入 blade-agent 持久会话
  4. blade-agent 调用 _resolve_user_home_host_path,目录不存在 → return None(③)
  5. sandbox 挂独立 named volume blade-home-{user} 到容器内 /root
  6. 用户文件落在 named volume 里,blade-os 文件管理器只看 /opt/box/files/users/{id} → 完全看不到

现场证据(gpu22)

# 宿主机目录不存在
$ ls /opt/box/files/
ls: cannot access '/opt/box/files/': No such file or directory
# blade-os 容器挂载里没有 /opt/box/files
$ docker inspect blade-os | grep -A1 "Mounts"
/opt/box-deploy/agent/blade-os/workspace → /workspace
blade-os_blade-data → /data
...
# 持久 sandbox 走的是 named volume 兜底分支
$ docker inspect blade-user-local-dev-default | grep "Source\|Destination"
/opt/box-deploy/agent/blade/workspace/persistent-local-dev/workspace → /workspace
blade-home-local-dev (named volume) → /root

修复方案

三层缺一不可。建议按职责划分:

必修

F1 · box-deploy 补挂 /opt/box/files

/opt/box-deploy/agent/blade-os/docker-compose.yaml.j2 渲染出 - /opt/box/files:/opt/box/files;首次部署 mkdir -p /opt/box/files

必修

F2 · blade-os 在用户首次登录/创建会话时预创建目录

oauth_service.pycreate_new_user() 末尾(或 auth_setup.py_resolve_username 后)调一次 file_service.ensure_user_home(new_user.id),保证所有用户都有目录,不依赖用户打开文件管理器。

强烈建议

F3 · blade-agent 不要静默降级,失败时显式报错

_resolve_user_home_host_path 在目录不存在时改成:若 BLADE_OS_BASE_URL 已配置(说明期望共享)但目录不存在 → 报错而非 fallback 到 named volume,避免与 blade-os 脱钩。fallback 行为只在 BLADE_OS_BASE_URL 未配置时保留(即 blade-os 不可达时也能跑)。

注意:仅修任一层都不能彻底解决问题 —— F1 修部署但 F2 漏修则新用户仍无目录;F2 修业务但 F1 漏修则目录落在 blade-os 容器层(ephemeral);F3 修 fail-soft 但 F1+F2 漏修则一直报错。

关键代码位置

文件 说明
blade-os services/file_service.py 45-53 ensure_user_home(懒加载)
blade-os api/v1/files.py 多处 唯一调用方(全在文件管理器 API)
blade-os core/config.py 159 FILES_ROOT 默认 /opt/box/files/users
blade-agent host/_engine_runtime.py 30-58 目录解析 + 静默 return None(根因③)
blade-agent sandbox/docker.py 657-668 if/elif 双分支(共享 vs fallback)
box-deploy .../blade-os/docker-compose.yaml volumes 漏挂 /opt/box/files(gpu22 实测)