Files
server-deploy/docs/implementation-status.md

211 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 新架构实施状态
更新:2026-09-25。这是工程状态,不是生产部署验收报告。
跨设备接续从 [HANDOFF.md](../HANDOFF.md) 开始;工具链准备及可复现命令见[开发指南](development.md)。
本文件各工作包的测试结论属于相应阶段的历史证据,新设备仍需复跑。
## 已固定的选择
Traefik、本地 React/Node 管理面板、Go deployctl。当前目录开发,分支为
`codex/new-deployment-architecture`,不自动提交或推送。
## 第一工作包:只读执行器基础
已实现:
- 独立 Go module,标准库实现,无第三方 Go 依赖。
- `version`、`plan`、`verify-plan` CLI;JSON stdin/stdout 协议。
- 严格输入校验:字段大小写、未知/重复/缺失字段、null、类型、体积限制。
- 实例标识、DNS 名称和 SHA-256 摘要校验。
- 实例项目名/数据路径推导、15 分钟有效期、内容绑定和状态漂移拒绝。
- 所有输出标记为不可执行的离线预览;未提供任何部署写命令。
- Go 单元测试以及真实二进制 Node 冒烟测试。
此阶段输入中的主机身份和状态摘要由调用方提供,不代表远程探测。
单镜像摘要只是预览基础字段,正式应用包必须完整绑定所有组件镜像。
摘要不是签名;只读校验通过不是写操作授权;路径拼接不是安全文件系统访问实现。
## 验证记录
- 在 Windows 使用临时 Go 1.27.1 官方工具链(下载 SHA-256 校验通过)。
- `go test ./... -count=1` 通过。
- `go vet ./...` 通过。
- Windows amd64 二进制构建、运行预览、校验、拒绝 apply 通过。
- `node --test tests/cli-smoke.test.mjs` 通过;确认测试工作目录无新增文件。
- 独立审查未发现 Critical/Important 问题;发现时间格式接受范围过宽,已通过先失败后通过的回归测试收紧为 UTC 秒级格式。
- Linux amd64 / CGO_ENABLED=0 交叉编译通过;未在 Linux 执行。
- 构建产物位于忽略目录 dist,不纳入源码发布。
## 第二工作包:任务状态与互斥基础
已实现 internal/state 内部模块,尚未接入 CLI 写操作:
- Linux flock / Windows LockFileEx 主机目录互斥,支持真实进程终止后释放锁。
- 操作 ID 与计划摘要绑定;重复请求返回原记录,不能改绑计划。
- 修订号比较确保只有一个调用方能领取任务;未决任务阻止其他写任务。
- 状态机区分成功、失败已恢复、需处理、未知及取消;终态不可重跑。
- 有界、带完整性摘要的快照;私有临时文件、同步、替换及 Linux 目录同步。
- 写入失败后冻结会话,必须重新打开并核对现场;不伪装保存成功。
- 初始化标记避免已有快照丢失后静默重置;新任务入库预留后续状态空间。
- 不自动清理幂等历史,不自动重跑中断任务;尚无事件审计日志和任务监督器。
验证使用临时目录,不涉及应用数据。Windows 测试通过;两项符号链接用例在
Windows 因创建链接权限不足跳过,在 Ubuntu WSL 中实际通过。Linux 全套测试、
状态模块竞态检测、go vet 和真实 CLI 运行已完成。进程终止测试不等于断电测试。
独立审查指出接近容量上限时缺少终态空间,已用 113,357 条历史记录复现并修复。
## 第三工作包:应用包校验与本机只读检查
已实现:
- 共享严格 JSON 解码,递归校验组件/文件数组,拒绝未知字段、null 和非法 UTF-8。
- 应用包清单绑定所有组件镜像摘要、平台、入口和文件内容摘要。
- 校验调用方提供的清单摘要,精确检查文件清单;拒绝缺失、多余、越界路径、符号链接和特殊文件。
- 清单、单文件、总内容和文件数量均设上限;返回已验证字节,供后续适配器使用。
- `verify-package` 仅输出清单和结果,不输出文件正文,不授予执行权限。
- `inspect` 只读取本机平台和 systemd/Docker 客户端文件状态,不启动进程或连接 Docker。
- 未检查的条件明确列出,`deploymentReady` 始终为 false。
调用方必须通过可信渠道获取期望摘要,并保证暂存目录及其父目录可信、校验期间不被修改。
内容摘要匹配不是发布者身份认证;本批不解析 Compose 语义,也不证明镜像能运行。
本机文件存在不等于服务健康,尚未检测 Docker daemon、Compose 版本、网络或磁盘容量。
本批验证:Windows 全套测试、go vet、构建及两项真实 CLI 冒烟测试通过;Ubuntu WSL
全套测试、go vet、全模块竞态检测、构建和真实 plan/inspect 运行通过。
Linux 实际执行了符号链接和 FIFO 拒绝测试。第一次 Linux 竞态构建曾报标准库 fmt
导入异常;待并行开发结束后以全新工具链目录和缓存重跑通过,异常未再复现,根因未确认。
独立审查发现默认 Docker 路径无效或不可读时漏查备用路径,已先复现三个失败用例再修复;
复审无遗留发现,修复后 Windows/Linux 全套检查再次通过。
## 第四工作包:受限 Compose 策略基础
- 新增 `check-package`:先校验完整应用包,再检查内存中的入口字节,不重新打开文件。
- `isolated-compose-v1` 仅接受严格 JSON;字段白名单拒绝未覆盖功能。
- 服务与清单组件/镜像精确匹配;要求显式非 root UID:GID、只读根文件系统、
丢弃全部 capabilities 和 no-new-privileges。
- 首版仅允许 backend 内部网络及普通项目命名卷;拒绝宿主挂载、外部资源、
跨服务共享卷、重叠挂载、系统目录挂载、Docker socket、主机网络、额外服务和构建/钩子。
- 扩展共享 JSON 解码器,递归检查动态服务字典的未知字段、缺失字段和 null。
- 包摘要与策略名在结果中明确返回,`executable` 和发布者认证始终为 false。
这是策略基础,不是完整 Compose 适配器。环境/秘密注入、Traefik 路由、健康规则、
应用权限例外、卷初始化权限和资源上限尚未实现;当前策略无法直接覆盖 Gitea 等完整应用。
它不验证镜像内部路径/默认行为,不证明 Docker 资源归属,也不替代实际部署/恢复测试。
精确契约见 [策略说明](../internal/composepolicy/README.md)。本批未连接或修改云服务器。
验证:先观察策略缺失、字典递归校验缺失和 CLI 命令缺失导致测试失败,再实现通过。
Windows 全套 Go 测试、go vet、构建和 3 项真实 CLI 冒烟测试通过;Ubuntu WSL
全套测试、go vet、全模块竞态检测、构建及现有只读 CLI 检查通过。
独立审查未发现本批范围内的问题,并独立重跑 composepolicy/wire/cli 测试通过。
尚未用真实 Docker/Compose 加载或运行策略示例,不能视为容器运行验收。
## 第五工作包:本机预检与环境安装提案
- 新增只读 `preflight`,输出实际观察、阻塞项、候选步骤和影响;不是可执行安装计划。
- 在 Linux 读取有限大小的 os-release、有效 UID 和 /var/lib 所在文件系统可用空间。
- 对常见运行时/数据/安装源路径作保守存在性检查,链接或不可读路径不视作干净环境。
- 仅在支持的 Ubuntu 版本/代号组合、root、systemd、磁盘初筛及资源检查通过时显示候选步骤。
- 明确指出软件包安装可能启动 Docker 并影响主机网络规则;不生成或执行 Shell 命令。
- 版本锁、软件包清单、源信任、主机身份和网络检查未完成,任何提案始终不可执行。
目前只是现场观察和安装提案基础,尚未实现完整运行前检查、APT 事务计划或环境安装。
5 GiB 是安装初筛阈值,不是应用/备份容量保证。没有扫描所有安装源或非标准数据路径。
本批未上传或在云服务器执行新二进制;CLI 只报告它实际运行的本机环境。
详细边界见 [预检说明](../internal/preflight/README.md)。
验证:Windows 全套测试、go vet、构建和 4 项真实 CLI 冒烟测试通过;Ubuntu WSL
全套测试、go vet、竞态检测、构建和实际 preflight 输出通过。Linux 用临时目录验证了
真实 statfs 查询和悬空符号链接拒绝作为“空环境”的行为,未涉及应用数据。
独立静态审查未发现本批范围内的问题;未完成真实软件包安装验收。
## 第六工作包:dpkg 清单、版本锁与安装事务草案
- 只读检查 dpkg 状态及更新日志目录,报告 Docker/容器运行时相关包和状态文件摘要。
- 相关包无论已安装、残留配置或部分安装均阻止全新安装候选;读取失败不视为未安装。
- 新增 `plan-environment`,输入明确的 Docker 五包版本锁,现场信息由本机收集。
- 限制官方源地址、发行版、架构、文件路径、版本、大小和 SHA-256;Engine/CLI 版本须一致。
- 草案绑定锁文件与现场观察摘要,列明请求包、影响和阻塞项;不执行下载、apt 或配置写入。
本批实现的是源地址约束和调用方版本锁校验,不是仓库签名认证。仍未验证签名 Release、
Packages 到 deb 的摘要链、元数据时效、实际文件或完整依赖事务;始终返回不可执行且源未认证。
未从在线仓库选择真实安装版本;没有对云服务器执行安装、升级或数据改动。
验证:Windows 全套 Go 测试、go vet、构建和 5 项真实 CLI 冒烟测试通过;Ubuntu WSL
全套测试、go vet、竞态检测、构建及真实 dpkg 清单读取通过。独立审查指出两项测试
被提前校验掩盖,已修正输入并通过临时停用对应校验的反向测试证明能捕获错误;
恢复生产校验后全套复验通过,复审无遗留发现。未执行真实 APT 安装事务或仓库签名验收。
## 第七工作包:官方仓库签名与元数据摘要链
- 新增 `verify-repository`:在 Linux 验证暂存的 Docker 公钥、Release 签名和 Packages 摘要。
- 公钥字节摘要及主指纹固定在代码中;使用隔离临时目录调用系统 GnuPG,不修改 APT 或个人密钥环。
- 校验发行版、架构、stable 组件、元数据日期与有效期,再按五个明确版本生成绑定 Release 的版本锁。
- 文件大小、类型、重复字段/记录、无效路径及未知签名状态均受限制;错误不回显原始输入。
- 认证输出不是执行授权;实际 deb 文件尚未下载验证,`packageBytesVerified`、`executable` 仍为 false。
真实 Docker resolute/amd64 元数据在本地 WSL 验证通过,篡改 Release 和 Packages 的端到端
CLI 测试均被拒绝。验证所选版本仅作测试样本,不代表最终安装版本。没有访问或修改云服务器,
没有安装软件、变更防火墙或接触应用数据。GnuPG 只写入本次创建的临时目录。
该校验依赖可信系统时钟、GnuPG 和无并发写入的可信暂存目录;30 天时效窗口不是持久防回退账本。
详细契约见 [仓库验证说明](../internal/aptrepo/README.md)。
验证:Windows 全套 Go 测试、go vet、构建及 6 项真实 CLI 冒烟测试通过;Linux 全套测试、
go vet、竞态检测、构建与官方在线元数据验证通过。独立审查发现并修复了输出缓冲的
io.Copy 大小限制绕过,失败回归用例已转绿;篡改测试改为合法语法,并增加交叉验证以防
其他解析错误掩盖签名/摘要检查。测试用 Python 已隔离环境,实测 PYTHONOPTIMIZE=1
不能禁用断言。没有完成实际 deb 文件验证或依赖事务预演。
## 第八工作包:实际 deb 文件完整性验证
- 新增 `verify-artifacts`:每次重新认证仓库元数据,再验证对应五个真实 deb 文件。
- 暂存目录必须精确包含这五个文件;拒绝缺失、多余、符号链接、特殊文件及大小/摘要不符。
- 流式计算 SHA-256,不将大型 deb 整体载入内存,不解包、不执行包内安装脚本。
- 任一文件失败时整个请求失败;只有全部通过才返回 `packageBytesVerified: true`。
- `executable` 保持 false;验证结果是当次观察,不是以后可复用的安装授权。
本地 Ubuntu WSL 下载并验证了五个官方 resolute/amd64 deb 测试样本(约 90 MB);
同长度单字节篡改测试被拒绝。没有安装任何下载包,没有调用 APT,没有连接或修改云服务器。
测试样本暂存于本地临时目录,其中一个被测试故意修改,不可拿去安装。
验证:Windows 全套测试、go vet、构建与 7 项 CLI 冒烟通过;Linux 全套测试、go vet、
竞态检测、构建及真实 deb 下载/签名/摘要/篡改测试通过。独立审查指出的临时辅助文件权限
边界和协议测试被其他错误掩盖的问题已修复,复审无遗留发现。协议测试通过临时换用宽松
解码器确认能够失败,恢复严格解码后复验通过。以上是本批范围内的验证,不是安装验收。
本批完成的是 Docker 五包的字节校验,不是完整安装事务预演。Ubuntu 依赖源的认证、
全部依赖的版本/摘要锁定,以及隔离 APT 配置/包状态的预演仍未交付。
APT 会读取多层配置,后续适配器须隔离配置与状态,不直接复用宿主默认配置;
参考 [APT 配置加载顺序](https://manpages.debian.org/trixie/apt/apt.conf.5.en.html)。
## 跨设备开发交接(2026-09-25)
用户要求补充记录并实现其他设备拉取接续。本次将此前八个工作包的源码、测试、协议及文档
纳入 `codex/new-deployment-architecture` 分支交付,不合并到 master;交接入口为根目录 HANDOFF.md。
开发指南记录工具链基线、Windows/Linux 命令、可选在线测试和凭据边界;补充了本地服务+浏览器
的便携交付目标,并明确 APT 隔离细化方案仍待确认。原有旧 `.env` 本地删除不纳入本次提交。
对 Git 暂存快照导出的新架构干净源码副本复验:Windows 全量 Go 测试、vet、构建、7 项 CLI
冒烟及示例运行通过;Linux 全量测试、vet、race、构建及 CLI 只读检查通过。Windows 最初在
创建构建目录时遇到本地沙箱权限拒绝,授权重跑同一副本后通过,未修改代码或放宽目录权限。
这是同一设备上的隔离源码副本/双环境验证,不是另一台物理设备或 macOS 的验收。
文档相对链接已检查。本轮未重复在线下载;其通过证据保留在第七、八工作包,新设备可按指南重跑。
## 尚未交付
1. 远程现场 inspect、持久化状态与执行器集成、systemd 任务监督及重启现场核对。
2. 应用包可信分发、发布者认证、完整 Compose 安全策略和运行适配器,以及应用包与计划的完整绑定。
3. Traefik 环境安装、受限 Docker API 代理、网络与 ACME 实测。
4. Gitea/Joplin 和其余工具的部署、升级、备份与隔离恢复。
5. 本地面板、SSH、SQLite 与 Apple 风格交互界面。
6. Windows/macOS 便携产品、Linux 故障注入与生产发布验收。
前三个工作包未连接服务器。用户随后指定新服务器 `121.199.168.54` 并确认主机指纹,
现已完成 SSH 只读初检,详见 [现场记录](2026-09-25-target-server-preflight.md)。
未安装环境、迁移或清除任何应用数据,未操作旧服务器,未删除旧部署实现。
旧脚本暂留作开发对照,不作为新执行器后端;新架构完成验收后按总方案移除。
下一工作包是 Ubuntu 依赖源认证与隔离的完整依赖事务预演,之后才接入安装执行,
再逐步接入受控配置/秘密、入口路由和任务执行器。
完整产品尚未完成,不可将当前 CLI 用作部署工具。