Files
UHD_Media_Tool/docs/runbook/storage-alist.md
T
rootandClaude Opus 5.5 adbb9b59a0 docs(storage): Alist 使用与真机验收 runbook,整理 / 文件管理 / MP 对照更新
- 新增 docs/runbook/storage-alist.md:登记、行为要点、临时 OpenList 容器真机验收步骤、排查
- organize.md 加「Alist / OpenList 存储」;moviepilot-filemanager.md 末节改为已做;
  v3 对照保留 rclone 不照抄、网盘改为 Alist 已接;file-manager-v2 存储切换与目的存储两行更新
- 设计文档补实现落点与偏离;矩阵测试补原地整理与目标已存在替换

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
2026-10-07 00:04:19 +08:00

8.4 KiB
Raw Blame History

Alist / OpenList 存储

设计与 MP 对照:docs/design/storage-alist.md。整理侧口径:docs/runbook/organize.md「Alist / OpenList 存储」。

登记

设置 → 媒体库与目录 →「存储」→ 新增:

字段 说明
地址 Alist / OpenList 的访问地址(带端口、子路径),本工具进程要能访问到;容器部署时用容器网络里的地址
根路径 本工具只用这个路径下的内容(如 /115/影视),缺省 /
认证方式 令牌(Alist 后台「设置 → 其他 → 令牌」,推荐)/用户名和密码(换临时令牌,约两天续一次,失效自动重登)/访客
路径密码 Alist「元信息」里给目录设了访问密码时填写
高级 每秒请求数(缺省 5)、并发(4)、请求超时、传输无进度超时、等待 Alist 任务上限、重试次数、上传交给 Alist 后台任务(缺省关,同 MP)、目录监控深度(5)与按目录修改时间跳过(开)

保存后点「测试连接」:显示版本、登录用户、根路径是否可访问、容量(驱动不给或令牌不是管理员时显示「未知」)。凭据加密保存在 secret 表(用途 storage_credential),接口与日志里都不出现明文;直链的 sign 参数进日志前脱敏。

之后:

  • 媒体库目录:新增时「存储」选这个 Alist,路径填 Alist 内路径(目录要先在 Alist 里建好)。Alist 上不写标记文件,目录可访问即在线。
  • 整理来源:来源目录可以选文件管理里的「Alist 存储」根下的目录,触发方式只能手动或目录快照。
  • 文件管理:左栏「Alist 存储」组,每个启用的实例一个根。浏览、新建目录、改名、删除(进 Alist 上的 .umt-trash,回收站可还原)、移动 / 复制(Alist 内走 Alist 接口,本机 ↔ Alist 上传 / 下载)、上传、下载小文件、整理、刮削。「刷新」才让 Alist 刷新目录缓存(会穿透到网盘接口)。

运行状态 →「挂载根」里列出每个存储实例的连通性;令牌失效显示「令牌失效或没有权限」。

行为要点

  • 成功判定(用户决定,同 MP):网盘方向的上传、下载、复制、移动只看接口成功 + 目标存在,不比对大小和哈希;移动在此之后删源。本地 ↔ 本地仍走现有核验。
  • 不覆盖:上传先查同名再传临时名 <名>.uhd-partial 后改名(Alist 的 put 会静默覆盖同名);复制 / 移动目标已存在报冲突;名字不同的复制 / 移动经 .umt-stage-* 暂存目录改名,失败清理。
  • 等待:Alist 的复制(v4 一律)与跨驱动移动是后台任务,按任务状态轮询到完成(失败带任务的错误信息),老版本没有任务接口时等目标出现。
  • 错误:「不存在」与连不上 / 鉴权 / 服务端错误分开;整理遇到后者按可重试 IO 退避,不当成源不存在。限流 / 风控(429、「too many」)自动退避。
  • 下载:写 <目标>.uhd-partial,中断后 Range 续传,直链签名过期自动重新获取,成功后不覆盖地改名。
  • ffprobe:远端文件不下载,对直链只读文件头;探测不到不阻塞整理。

真机验收(临时 OpenList 容器)

用户不提供真实 Alist 时,按下面起一个 OpenList(本地存储驱动)验收。容器名带 umt-alist- 前缀,用完删掉。

W=$PWD/.local/openlist   # 工作区的 .local(不进 git)
mkdir -p $W/{data,store1,store2} && chmod -R 777 $W
docker run -d --name umt-alist-it -p 127.0.0.1:55244:5244 \
  -v $W/data:/opt/openlist/data -v $W/store1:/mnt/s1 -v $W/store2:/mnt/s2 openlistteam/openlist:latest
docker exec umt-alist-it ./openlist admin set umtAdmin123        # 设管理员密码
B=http://127.0.0.1:55244
TOK=$(curl -s -X POST $B/api/auth/login -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"umtAdmin123"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["token"])')
# 两个本地存储驱动(/s1、/s2),用来测同驱动与跨驱动
for n in 1 2; do curl -s -X POST $B/api/admin/storage/create -H "Authorization: $TOK" -H 'Content-Type: application/json' \
  -d "{\"mount_path\":\"/s$n\",\"driver\":\"Local\",\"addition\":\"{\\\"root_folder_path\\\":\\\"/mnt/s$n\\\",\\\"mkdir_perm\\\":\\\"777\\\"}\"}"; done
# 永久令牌(设置里登记用)
PERM=$(curl -s "$B/api/admin/setting/get?key=token" -H "Authorization: $TOK" | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["value"])')

部署环境里本工具跑在容器中时,把 OpenList 接到同一个 docker 网络(docker network connect <app 网络> umt-alist-it),设置里的地址填 http://umt-alist-it:5244。

1. 适配器往返(脚本,可对任意地址跑)

deno run -A scripts/alist-e2e.ts --url $B --token "$PERM" --root /s1 --root2 /s2
# 或 --user admin --password umtAdmin123;退出码 0 = 全部通过

步骤:连接 → 建目录 → 上传(秒传头、临时名改名、进度)→ 同名不覆盖 → 同驱动复制并改名 → 移动 → 跨驱动复制 / 移动(任务轮询)→ 下载比对 sha256 → 不存在 ≠ 失败、容量 → 清理。

2. 自动化真机测试

export UMT_ALIST_REAL_URL=$B UMT_ALIST_REAL_TOKEN="$PERM" UMT_ALIST_REAL_ROOT=/s1 UMT_ALIST_REAL_ROOT2=/s2
(cd packages/adapters && deno run -A npm:vitest run src/alist/alist.real.test.ts)
(cd apps/server && DATABASE_URL=... deno run -A npm:vitest run test/storage/alist-organize.real.test.ts)

后者在测试库上跑整理往返:本地下载目录 → 整理(复制)到 OpenList 上的媒体库 → 文件管理「移动到」本地媒体库(下载后删远端)→ OpenList 内整理(同实例 API 移动)。

3. 界面验收(部署环境)

  1. 设置 → 媒体库与目录 → 存储:新增「OpenList」,地址、令牌 $PERM,测试连接显示版本与用户。
  2. 在 OpenList 里建好 /s1/media/movies;媒体库目录新增「OpenList 电影」,存储选 OpenList,路径 /s1/media/movies,管理方式「自动维护」。
  3. 文件管理左栏出现「Alist 存储 → OpenList」:新建目录、上传一个小文件、改名、删除后到回收站还原、移动到另一个目录、复制到本机媒体库(下载)。
  4. 整理矩阵(文件管理选文件 →「整理」,目标选对应媒体库目录,各做一次复制、一次移动):
    • 本机下载目录的视频 → OpenList 电影(上传;移动后本机源消失);
    • OpenList /s1/incoming 下的视频 → 本机媒体库(下载;移动后 OpenList 源消失);
    • OpenList /s1/incoming → OpenList 电影(Alist 内复制 / 移动)。 整理记录里每条为「成功」,目标路径显示「OpenList:/…」。
  5. 刮削写远端:OpenList 电影里已整理的作品点「刷新元数据」,OpenList 目录里出现 .nfo、poster、clearlogo.png。
  6. 目录监控:设置 → 整理来源新增,来源选「OpenList」根下的 incoming,目标 OpenList 电影,触发「目录快照」,间隔 60 秒;首扫建基线,之后往 /mnt/s1/incoming(或经 OpenList 上传)放一个新视频,两次扫描后出现整理记录。
  7. 运行状态 → 挂载根里 OpenList 在线;在 OpenList 后台重置令牌后再看,显示「令牌失效或没有权限」。

收尾

docker rm -f umt-alist-it && rm -rf .local/openlist

排查

现象 原因 / 处理
测试连接「令牌失效或无权限」 令牌被重置或用户没权限;重新复制令牌,或改用账号密码
测试连接「连不上」 地址不对、容器网络不通;在 app 容器里 curl <地址>/api/public/settings
根路径不存在 根路径要用 Alist 里的完整路径(以挂载路径开头,如 /115/影视)
整理卡在「文件操作可重试失败,等待重试」 Alist 连不上或限流;恢复后任务按退避自动重试,源文件不会被删
跨网盘复制很慢 Alist 后台任务在搬数据;在 Alist「任务」页看进度,等待上限在实例高级选项
目录监控看不到深层新文件 超过监控深度,或网盘不更新目录修改时间:调大深度或关掉「按修改时间跳过」
容量显示「未知」 驱动不给容量或令牌不是管理员(/api/admin/storage/list),不影响使用