仓库布局
SOW 的 Managed 布局只有一种:软件包体在 pool/ 下只存一份,dists/
只保存客户端视图元数据。对外服务、复制或发布时,单位始终是完整仓库目录。
Plain 模式
sow create 在现有软件包旁写入索引,不修改无关文件:
平面 RPM 元数据引用裸文件名,平面 DEB 元数据使用 ./<filename>。构建期间
.sow-plain-stage-* 保存私有生成输出。Plain 没有持久 journal 或 recovery 状态;下次
create 会丢弃保留命名空间里的陈旧临时路径并重建。不得服务或复制这些临时路径。
Managed 工作区
去重不跨仓库边界。.sow/ 与 pending 目录权限为 0700。Pending 包体文件直接使用最终
公开权限 0644,因此提升只需修改命名空间。私有状态
可能包含尚未发布的包体、从凭据派生的状态与恢复数据。
<repo>.db 与可重建的软件包事实缓存都属于私有状态,不改变公共仓库布局或
sow/v3 配置标识。
SOW 0.4 使用内部数据库 Schema v12。Append-only Publication-target Binding Revision、Package
Facts、Signer Projection 与 Recovery Evidence 均只存在于 <repo>.db。v0.3 数据库必须先备份,
再通过 sow repo migrate 升级;绝不要手工修改 PRAGMA user_version,也不要脱离匹配的公共/私有
Repository 状态单独复制数据库。
规范包池
每个包体只有一条规范路径:
源码名取自 RPM SOURCERPM 或 DEB Source;缺失时回落到二进制包名。
前缀是首个小写字符,以 lib 开头时取前四个字符:
| Source | 示例 |
|---|---|
postgresql-18 |
pool/p/postgresql-18/libpq5_18.3-1.pgdg12+1_amd64.deb |
blackbox_exporter |
pool/b/blackbox_exporter/blackbox_exporter-0.28.0-1.x86_64.rpm |
libfoo |
pool/libf/libfoo/libfoo1_1.0-1_amd64.deb |
Pool 对象不可变。从 Dist 删除成员关系不会立即删除字节;sow gc 只有在检查当前、保留、
恢复、发布以及活动维护操作等全部安全根后,才会处理不可达包体。
RPM 纯元数据视图
这里没有 dists/<dist>/<arch>/pool/。原生包只出现在匹配架构的元数据中,noarch
出现在每个架构视图中。rpm-md 回指规范包池:
该布局要求客户端在完整 Repository Root 内正确处理 rpm-md 相对路径。默认 dnf reposync
会拒绝父级跳转 href,因为下载目标逃出
View Root。下游工具需要自包含 Leaf 时,请显式导出:
导出目录有自己的 pool/ 和改写后的 href;它是兼容性产物,不是规范 Managed 仓库。
DEB 视图
Packages 从 archive 根引用同一规范包池:
Release 使用 SHA256 清单并声明 Acquire-By-Hash: yes。校验和命名的 rpm-md 文件与
APT by-hash 条目让上一组元数据在可变指针最后替换时仍然可达。
发布目标
filesystem 与 r2 目标都会在配置前缀下得到同一棵逻辑公共树:
发布单位始终是完整仓库命名空间。不要只发布某一个 RPM 架构目录,它的 href 会有意回指 根包池。
名称与服务边界
仓库名与 Dist 名必须匹配 [a-z0-9][a-z0-9._-]*。.、..、.sow、pool、
dists、sow.yml、workspace.lock、workspace-ops 与 repo-locks 在相应位置为
保留名。SOW 会拒绝大小写不敏感的池路径冲突,使产物能在 Linux 与默认 macOS 文件系统间迁移。
Web 服务器应指向 <workspace>/<repo>/,而不是工作区根目录。公共仓库需要同时包含
pool/ 与 dists/;私有 .sow/ 必须隐藏。