跳转到主要内容

仓库布局

SOW 的公共与私有路径,包括唯一规范包池与纯元数据视图。

SOW 的 Managed 布局只有一种:软件包体在 pool/ 下只存一份,dists/ 只保存客户端视图元数据。对外服务、复制或发布时,单位始终是完整仓库目录。

Plain 模式

sow create 在现有软件包旁写入索引,不修改无关文件:

/srv/offline/
├── blackbox_exporter-0.28.0-1.x86_64.rpm
├── libpq5_18.3-1.pgdg12+1_amd64.deb
├── repodata/
│   ├── <sha256>-primary.xml.gz
│   ├── <sha256>-filelists.xml.gz
│   ├── <sha256>-other.xml.gz
│   └── repomd.xml
├── Packages
├── Packages.gz
└── repo_complete                         # 仅 --pigsty 生成

平面 RPM 元数据引用裸文件名,平面 DEB 元数据使用 ./<filename>。构建期间 .sow-plain-stage-* 保存私有生成输出。Plain 没有持久 journal 或 recovery 状态;下次 create 会丢弃保留命名空间里的陈旧临时路径并重建。不得服务或复制这些临时路径。

Managed 工作区

<workspace>/
├── sow.yml                               # 配置,保持私有
├── .sow/                                 # 数据库、锁、stage/recovery,保持私有
│   ├── workspace.lock
│   ├── workspace-ops/
│   ├── repo-locks/<repo>.lock
│   ├── <repo>.db
│   └── <repo>/
│       ├── stage/
│       ├── recovery/
│       └── pending/
└── <repo>/                               # 发布这个完整目录
    ├── pool/
    └── dists/

去重不跨仓库边界。.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 状态单独复制数据库。

规范包池

每个包体只有一条规范路径:

pool/<prefix>/<source>/<filename>

源码名取自 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 纯元数据视图

<repo>/
├── pool/
│   ├── b/blackbox_exporter/blackbox_exporter-0.28.0-1.x86_64.rpm
│   └── p/pev2/pev2-1.23.0-1.noarch.rpm
└── dists/el9/
    ├── x86_64/repodata/
    │   ├── <sha256>-primary.xml.gz
    │   └── repomd.xml
    └── aarch64/repodata/
        ├── <sha256>-primary.xml.gz
        └── repomd.xml

这里没有 dists/<dist>/<arch>/pool/。原生包只出现在匹配架构的元数据中,noarch 出现在每个架构视图中。rpm-md 回指规范包池:

<location href="../../../pool/b/blackbox_exporter/blackbox_exporter-0.28.0-1.x86_64.rpm"/>

该布局要求客户端在完整 Repository Root 内正确处理 rpm-md 相对路径。默认 dnf reposync 会拒绝父级跳转 href,因为下载目标逃出 View Root。下游工具需要自包含 Leaf 时,请显式导出:

sow export rpm-leaf el9 x86_64 /srv/export/el9-x86_64

导出目录有自己的 pool/ 和改写后的 href;它是兼容性产物,不是规范 Managed 仓库。

DEB 视图

dists/trixie/
├── Release
├── InRelease                         # 配置元数据签名时生成
├── Release.gpg                       # 配置元数据签名时生成
└── main/
    ├── binary-amd64/
    │   ├── Packages
    │   ├── Packages.gz
    │   └── by-hash/SHA256/<digest>
    └── binary-arm64/
        └── ...

Packages 从 archive 根引用同一规范包池:

Filename: pool/p/postgresql-18/libpq5_18.3-1.pgdg12+1_amd64.deb

Release 使用 SHA256 清单并声明 Acquire-By-Hash: yes。校验和命名的 rpm-md 文件与 APT by-hash 条目让上一组元数据在可变指针最后替换时仍然可达。

发布目标

filesystemr2 目标都会在配置前缀下得到同一棵逻辑公共树:

<prefix>/
├── pool/
└── dists/

发布单位始终是完整仓库命名空间。不要只发布某一个 RPM 架构目录,它的 href 会有意回指 根包池。

名称与服务边界

仓库名与 Dist 名必须匹配 [a-z0-9][a-z0-9._-]*....sowpooldistssow.ymlworkspace.lockworkspace-opsrepo-locks 在相应位置为 保留名。SOW 会拒绝大小写不敏感的池路径冲突,使产物能在 Linux 与默认 macOS 文件系统间迁移。

绝不要暴露 .sow

Web 服务器应指向 <workspace>/<repo>/,而不是工作区根目录。公共仓库需要同时包含 pool/dists/;私有 .sow/ 必须隐藏。

延伸阅读