Skip to content

FNOS-001 T0 收尾批次测试报告(11 个应用) ​

本报告记录 FNOS-001 1Panel 应用商店应用转换 T0 批次收尾 11 个应用的测试执行结果,并回填 2026-10-10 的真机验收证据。用例定义与编号规则见 FNOS-001 1Panel 应用转换测试用例 与测试用例规范。

第 1 轮(A 组 3 个应用)的报告见 FNOS-001 T0 试点批次第 1 轮测试报告。

本报告要纠正的问题 ​

维护者此前在需求与计划中写「14 个应用全部产出并本地验收通过」,但用例集里 11 个新应用名一个都没有出现——即「构建通过」被当成了「验收通过」。本报告补齐这 11 个应用的真实用例覆盖,并把「本地验证」与「真机验收」严格分开陈述。

本轮起,报告与用例的措辞纪律:

  • 「构建通过」只写「构建通过」,不写「验收通过」「已完成」;
  • 「本地通过」明确标注为静态/本地范围,并列出未覆盖的运行时部分;
  • 只有真机取证过的结论才写「真机通过」。

执行范围 ​

应用目录形态特征
fn-browserlessapps/fn-browserless/常规入口;上游默认端口 3000
fn-chatgpt-next-webapps/fn-chatgpt-next-web/常规入口;入口键 31 字符(最接近 32 上限)
fn-cloudflaredapps/fn-cloudflared/{} 无入口,上游无端口字段
fn-cyberchefapps/fn-cyberchef/常规入口;真机已验证(端口 8080)
fn-llama-cppapps/fn-llama-cpp/用户路径只读挂载 ${MODEL_PATH}:/models:ro
fn-lobe-chatapps/fn-lobe-chat/常规入口
fn-memcachedapps/fn-memcached/{} 无入口;端口 11211
fn-web-checkapps/fn-web-check/常规入口;真机安装失败(定性见下)
fn-wechatmarkdowneditorapps/fn-wechatmarkdowneditor/.main 入口(.Application 为 35 字符,超 32 上限)
fn-yesplaymusicapps/fn-yesplaymusic/常规入口
fn-zabbix-agentapps/fn-zabbix-agent/{} 无入口;上游用 PANEL_APP_PORT_AGENT

环境与命令 ​

项值
仓库fn-os-apps/(工作区根为 fn-os-apps/ 的上一级)
Node.jsv24.15.0
fnpack1.2.4(由 PATH 解析)
Docker Composev5.1.0(仅用于 config 解析,无 daemon)
目标 fnOS 设备${FNOS_HOST}:5666,fnOS 1.2.0800,kernel 6.18.18.c1126-trim,x86_64(真机部分)
构建目录临时目录下的源目录副本(本轮用 mktemp -d),避免把 .fpk 写入受版本控制目录

主要命令:

bash
# 0) 准备构建目录:复制到临时目录,避免污染 apps/
BUILD="$(mktemp -d)"
for a in fn-browserless fn-chatgpt-next-web fn-cloudflared fn-cyberchef fn-llama-cpp \
         fn-lobe-chat fn-memcached fn-web-check fn-wechatmarkdowneditor \
         fn-yesplaymusic fn-zabbix-agent; do
  cp -r "apps/$a" "$BUILD/"
done

# 1) 构建(逐应用,三重判定:exit 0 且 .fpk 存在 且 mtime ≥ 构建开始)
cd "$BUILD/<app>" && fnpack build

# 2) 包结构
tar tzf <app>.fpk
tar xzOf <app>.fpk app.tgz | tar tz

# 3) compose 静态解析(代入向导默认值)
docker compose -f apps/<app>/app/docker/docker-compose.yaml config

# 4) 生命周期脚本语法与末尾换行
for f in apps/<app>/cmd/*; do bash -n "$f"; done

# 5) 窗口校验
pnpm run check -- --all && pnpm run lint && git diff --check

逐条结果汇总 ​

本轮新增 4 条用例(TEST-10~13),并把 11 个应用的回填并入既有用例。

用例 ID验收条件环境状态本轮变化
FNOS-001-04-TEST-0104-AC-01本地通过回填 B 组 11 个应用的构建结果
FNOS-001-04-TEST-0204-AC-01本地通过回填 B 组 11 个应用的包结构
FNOS-001-04-TEST-0304-AC-02目标 NAS通过补充 fn-cyberchef/fn-wechatmarkdowneditor 真机证据
FNOS-001-04-TEST-0404-AC-03目标 NAS阻塞状态取值修正(原记「部分通过」,不在允许范围)
FNOS-001-04-TEST-0504-AC-04本地通过回填 11 个应用的权限静态核对
FNOS-001-04-TEST-0604-AC-06目标 NAS未执行改造为可直接执行的步骤
FNOS-001-04-TEST-0904-AC-05本地通过回填 B 组有入口应用
FNOS-001-02-TEST-0102-AC-01本地通过回填 11 个应用图标
FNOS-001-02-TEST-0202-AC-01本地通过回填;标注 3 个无入口应用为 N/A
FNOS-001-04-TEST-1004-AC-07本地通过新增:入口键长度/前缀/一致性三维硬校验 + 边界实测
FNOS-001-04-TEST-1104-AC-07本地通过新增:{} 无入口形态(3 个应用)
FNOS-001-04-TEST-1204-AC-02 + AC-05目标 NAS通过新增:改端口后入口跟随(真机已验证)
FNOS-001-04-TEST-1304-AC-01 + AC-04本地通过新增:用户路径只读挂载

用例集整体统计(28 条):通过 19 / 阻塞 7 / 未执行 2 / 失败 0。

用例结果明细 ​

FNOS-001-04-TEST-01 构建(11 个应用逐项) ​

全部满足三重判定(退出码 0 + .fpk 存在 + mtime ≥ 构建开始):

应用退出码.fpk 大小应用退出码.fpk 大小
fn-browserless027887 Bfn-memcached078708 B
fn-chatgpt-next-web094975 Bfn-web-check0150218 B
fn-cloudflared0105686 Bfn-wechatmarkdowneditor034935 B
fn-cyberchef079598 Bfn-yesplaymusic0105040 B
fn-llama-cpp017662 Bfn-zabbix-agent033467 B
fn-lobe-chat0183763 B———

FNOS-001-04-TEST-02 包结构(11 个应用逐项) ​

全部:顶层 21 个非目录条目、cmd/ 9 个脚本、wizard/ 3 个文件、app.tgz 内 ui/config 存在、.DS_Store 计数 0。

FNOS-001-04-TEST-10 入口 ID 硬校验(新增,AC-07) ​

三处硬校验实测(在临时副本中构造,未改动 apps/):

构造fnpack build 输出退出码.fpk
入口键恰好 32 字符Packing successfully.0生成 ✓
入口键恰好 33 字符Packing failed. The entry ID "fn-cyberchef.aaaaaaaaaaaaaaaaaaaa" exceeds the 32-character limit.0未生成 ✗
键不以 appname 为前缀Packing failed. The entry name "badprefix.Application" in "app/ui/config" should start with fn-cyberchef0未生成 ✗
键与 desktop_applaunchname 不一致Packing failed. The value of desktop_applaunchname in manifest does not match any entry name defined in app/ui/config0未生成 ✗

关键发现:后三种失败场景 fnpack 仍返回退出码 0,只有「.fpk 是否产出」能识别失败。这再次印证 FNOS-001-04-TEST-01 的三重判定口径是必需的(缺陷 D-01)。

14 个应用入口键全量核对(覆盖率 14/14):

形态应用入口键长度
.Applicationfn-adminerfn-adminer.Application22
.Applicationfn-it-toolsfn-it-tools.Application23
.Applicationfn-cyberchef / fn-llama-cpp / fn-lobe-chat / fn-web-checkfn-<app>.Application24
.Applicationfn-browserlessfn-browserless.Application26
.Applicationfn-yesplaymusicfn-yesplaymusic.Application27
.Applicationfn-linux-commandfn-linux-command.Application28
.mainfn-wechatmarkdowneditorfn-wechatmarkdowneditor.main28
.Applicationfn-chatgpt-next-webfn-chatgpt-next-web.Application31
{}fn-cloudflared / fn-memcached / fn-zabbix-agent—N/A

wechatmarkdowneditor 的 <app> 长度为 20 字符(appname = fn-wechatmarkdowneditor 为 23 字符),.Application 形式合计 35 字符超限,故按规约改用 .main(28 字符)。等价判据:<app> ≥ 18 字符时 .Application 必然超限。

FNOS-001-04-TEST-11 无入口形态(新增,AC-07) ​

应用app/ui/config源 manifest 的 desktop_*构建
fn-memcached{}无通过
fn-zabbix-agent{}无通过
fn-cloudflared{}无通过

fnpack 的注入行为(新观察 O-01):源 manifest 不含 desktop_* 两行时,fnpack 会在打包时向 FPK 内的 manifest 注入两行空值:

text
desktop_uidir              = 
desktop_applaunchname      =

对 fn-cloudflared 重复构建两次,FPK 内 grep -cE '^desktop_' 恒为 2(确定性行为)。对照有入口的 fn-wechatmarkdowneditor,FPK 内为真实值。

判定:AC-07 说「manifest 不含 desktop_uidir/desktop_applaunchname」,指的是仓库内受版本控制的源文件——源文件确实不含。FPK 内空值属 fnpack 的字段规范化,不构成违规。该现象登记为 U-06,已裁决闭环:判定以源 manifest 为准,空值行属 fnpack 默认行为(nil 语义),不要求构建层剔除。

FNOS-001-04-TEST-12 改端口后入口跟随(新增,真机) ​

应用端口容器监听HTTP桌面入口
fn-cyberchef8080(上游默认)✅ 0.0.0.0:8080✅ 200 / 74908 B / <title>CyberChef</title>✅ port=8080
fn-wechatmarkdowneditor8081(默认 8080 冲突)✅✅ 200 / 5771 B / <title>微信 Markdown 编辑器 | Doocs 开源社区</title>✅ fnDomain=fn-wechatmarkdowneditor-main,port=8081

两个应用上游默认端口都是 8080。安装第一个用默认值、第二个改 8081,入口端口正确跟随(8081 而非 8080)。这证明「端口冲突由用户在向导里改」的路径可用,也是 .main 形态首次在真机验证。

FNOS-001-04-TEST-13 用户路径只读挂载(新增) ​

  • compose 第 11 行:- "${MODEL_PATH}:/models:ro",带 :ro。

  • wizard/install 三个字段均 required: true:APP_PORT(8080)、MODEL_PATH(空)、START_COMMAND(-m /models/model.gguf --host 0.0.0.0 --port 8080)。

  • wizard/config 字段与 install 一致。

  • docker compose config 解析出 read_only: true:

    yaml
    volumes:
      - type: bind
        source: /vol1/models
        target: /models
        read_only: true

    上例的 /vol1/models 是执行时示例填写的目标 NAS 路径(设备端),非开发机路径。

未覆盖:目标 NAS 上填错误路径的行为未验证。U-08 已裁决闭环:fnOS 向导 rules 无路径存在性校验能力,helpText 已给指引,且失败可见(cmd/main status 返回非 0),不判缺陷、不改实现,登记为已知限制。

其他覆盖确认 ​

  • 权限(TEST-05):11 个应用全部 run-as: package、username/groupname = docker-fn-<app>、无 join-groups、无 root。
  • compose 禁止项(全 11 个):1panel-network/createdBy/${CONTAINER_NAME}/env_file/:latest/相对挂载 —— 全部零命中;container_name 全等于 fn-<app>。
  • 图标(TEST-01/02):11 个应用四产物均为正方形 PNG、尺寸正确、≤1024 KB;docs/public/icons/fn-<app>.png 全部存在。
  • 生命周期脚本:11 个应用 × 9 个脚本,bash -n 语法全部通过、全部以换行结尾。
  • 端口正则(TEST-07/08):沿用规约的单条严格正则,回归确认无偏差。

阻塞清单 ​

项状态原因 / 说明
FNOS-001-04-AC-03「保留数据后重装读回」未满足app uninstall 不提供 --custom-parameters,卸载向导含必填 wizard_data_action,必须转 App Center UI;需占用一次真机窗口
FNOS-001-04-AC-06 端口占用未执行需在设备上构造端口冲突;步骤已可执行化(TEST-06),待下次真机窗口
FNOS-001-05-AC-01 数据落盘与容器重建未执行T0 应用无状态落盘,需 T1 批次应用
FNOS-001-06-AC-01 数据库连接信息未执行依赖 T2 批次应用,尚未产出
FNOS-001-04-AC-04 运行时 uid/gid部分14 个应用的静态声明已核对;逐应用运行时复核未做(fn-it-tools 有旁证)
FNOS-001-04-AC-07 无入口形态的运行验证部分3 个无入口应用仅完成本地静态核对,未在真机确认「无入口但正常工作」
fn-web-check 真机可用性未验证见下

fn-web-check 安装失败定性(如实记录,不计为应用缺陷) ​

现象:app install-fpk 返回 timed out waiting for app-center install task;核查发现 /var/apps/fn-web-check/ 目录已完整解包(cmd/config/manifest/wizard/ICON*.PNG 齐全,target 指向 /vol4/@appcenter/fn-web-check 且内含 config/docker/ui),但应用未出现在已装列表,端口 40095 未监听。

重试:再次 install-fpk → App Center code 10500: status operation is not supported for the app in its current state。

处置尝试:app install-cancel <taskId> 返回 Canceled app-center install task fn-web-check,但残留状态未被清除,重试仍报 10500。

定性依据:同一批次、同一路径、配置与 fn-cyberchef 完全同构的 fn-wechatmarkdowneditor 安装成功。因此判定为 App Center 侧的残留安装状态,不是 FPK 或转换产物的问题。

本轮已确认的本地事实:fn-web-check 的 11 项本地检查(构建、包结构、图标、权限、compose、端口正则、入口键 24 字符合规)全部通过。

结论:fn-web-check 的真机可用性未验证,需先在 App Center UI 清理残留状态后重装。不得据此判定转换质量有问题,也不得记为应用缺陷。

缺陷清单 ​

编号严重级状态说明
D-01高已闭环(第 1 轮)fnpack build 失败仍返回退出码 0。本轮 TEST-10 又实测到 3 种同类场景,印证三重判定口径必要
D-02中已闭环(第 1 轮)清单统计偏差并导致 2 个应用错分级
D-03低已闭环(第 1 轮)fnpack 不校验图标正方形;管线已强制

本轮未发现新的转换产物缺陷。

本轮新增观察(非缺陷) ​

编号观察定性
O-01fnpack 打包时向 FPK 内 manifest 注入两行空值 desktop_*fnpack 的字段规范化行为,非违规;判定以源文件为准。U-06 已闭环,不要求构建层剔除
O-02fn-web-check 真机安装失败 code 10500,残留未清App Center 侧残留状态,非转换产物缺陷

既有应用观察(非本轮范围) ​

  • apps/fn-new-api/wizard/config 的端口校验为 ^[0-9]+$,不挡越界值,与规约「1—65535 用单条严格正则完整覆盖」不一致。该应用属「不重写已有 14 个应用」范围,若后续统一口径需单独排期。

结论与建议 ​

结论:T0 收尾 11 个应用在本地可执行范围内全部通过——构建、包结构、图标、权限静态子句、compose 规范、端口校验、入口引用、入口 ID 规则、无入口形态、只读挂载共 10 类核对均符合订正后的验收条件。真机侧新增 AC-02、AC-05 转「通过」,AC-07 的 .main 规则得到真机验证。

但 T0 批次仍不具备「已完成」条件:

  • FNOS-001-04-AC-03 未满足(「保留数据后重装读回」未执行);
  • 04-AC-06、05-AC-01、06-AC-01 未执行;
  • 因此需求与计划的 T0 批次状态不得标记为「已完成」。

建议:

  1. 下一次真机窗口的优先级:① AC-03 的保留数据重装读回;② AC-06 的端口占用(步骤已就绪);③ fn-web-check 清理残留后重装;④ 3 个无入口应用的「无入口但正常工作」确认。
  2. T1 批次(93 个应用)开工前把本轮沉淀的自检项写入批量检查:入口键 ≤32 字符(<app> ≥18 时用 .main)、无 Web UI 应用用 {} + 删 desktop_*、用户路径挂载必须带 :ro、.DS_Store 排除、端口字段用严格正则。
  3. 请维护者裁决 U-06/U-07/U-08 已全部裁决闭环(见用例集「待确认事项」):
    • U-06:判定以源 manifest 为准,FPK 内空值 desktop_* 不构成违规;
    • U-07:「无 Web UI 应用」=不通过 HTTP 提供用户界面(与有无端口无关)。T1 起统一适用,边界情形先上报裁决;
    • U-08:MODEL_PATH 无路径校验不判缺陷,登记为已知限制。

变更记录 ​

日期变更
2026-10-10建立报告:补齐 11 个 T0 收尾应用的用例覆盖(新增 4 条),回填真机 A 组三应用结果,改造 AC-06 用例为可执行步骤;修正 TEST-04 的状态取值(「部分通过」→「阻塞」);无新增转换缺陷。
2026-10-10U-06/U-07/U-08 三项裁决闭环后同步本报告:U-06 判定以源文件为准;U-07 确立「无 Web UI」判定标准(T1 起适用);U-08 登记为已知限制。

基于 VitePress 构建