这是本节的多页打印视图。 .
上手
SOW 为 RPM 与 DEB 软件包生成 YUM 与 APT 静态仓库。安装 SOW 后,按需要选择管理方式:
-
Plain 模式: 执行
sow create DIR为目录中的软件包生成索引,执行sow prune DIR就地清理旧版 RPM。 -
Managed 模式: 创建工作区,按 Dist 组织软件包、限制版本数、签署元数据并发布更新。
-
安装 — 安装发布归档、Linux 软件包,或从源码构建。
-
快速上手 — 创建平面仓库,并用本机客户端访问。
-
第一个工作区 — 创建 RPM 与 DEB Dist,添加软件包并检查结果。
-
核心概念 — 理解工作区、仓库、Dist 与构建快照的关系。
通过静态 HTTP 服务器或对象存储提供生成的文件。存储与签名要求见安装说明。
1 - 安装
SOW 是一个可执行文件,不依赖守护进程、数据库服务或语言运行时。发布归档支持 Linux 与 macOS 的 amd64、arm64 架构。Linux 另有 RPM 与 DEB 安装包。
下载页提供 SOW 0.7.1 软件包、归档与校验值。
将所选制品与 SHA256SUMS 下载到独立的下载目录。
安装归档
以 Linux amd64 为例,先校验归档,再解压并安装:
macOS 选择 darwin_amd64 或 darwin_arm64,替换上述归档名称,并使用 shasum -a 256 -c - 校验。
没有 root 权限时,安装到用户目录:
把 export PATH 这一行加入 shell 配置文件,让新终端也能找到 SOW。
安装 Linux 软件包
先用 SHA256SUMS 中对应的条目校验下载的软件包,再执行适合本机发行版的命令:
ARM64 主机使用以 .aarch64.rpm 或 _arm64.deb 结尾的软件包。安装后的可执行文件位于 /usr/bin/sow。
从源码构建
安装 Go 1.27.4 或更新版本,以及 Git。构建使用 CGO_ENABLED=0,不需要 C 编译器。
验证安装
version 显示产品版本、目标操作系统与架构,以及 Go 工具链版本。help 列出命令;用 sow help COMMAND 查看某条命令的参数。
升级到 0.7.1
SOW 0.7.1 保持数据库 schema v13、配置 schema sow/v3 与公开目录布局不变。
已使用 0.5.0 至 0.7.0 的工作区无需迁移数据库。
迁移后的仓库若在后续构建中被残留迁移锚点阻塞,升级到 0.7.1 即可自动恢复,无需手工修复。
SOW 0.6.1 及更早版本不支持读取包含 passfile 的 sow.yml。降级前请先移除 passfile 字段。
- 停止工作区的全部写入任务。
- 用保留硬链接的工具备份完整工作区,例如
rsync -aH或tar。 - 安装 SOW 0.7.1。
- 对
sow.yml中每个仓库执行构建与检查:
把 REPOSITORY 换成配置中的仓库名。已是最新状态的仓库会报告空操作。
没有变化的构建保留原构建快照编号与元数据时间戳。
新的构建会记录一个发布时间,并在恢复时复用。
从 0.3 或 0.4 升级
这些工作区需要在首次构建前迁移。备份工作区并安装 0.7.1 后,执行:
对每个仓库重复执行。迁移更新数据库,重建应用当前的 RPM 验签与 APT 元数据规则。
需要回退到使用旧 schema 的版本时,恢复备份。
详情见 sow repo migrate 与 0.7.1 发布说明。
升级 Plain 仓库
Plain 模式没有数据库需要迁移。更换现有 YUM 仓库的生成工具前,按迁移现有 YUM 仓库操作。--metadata-timestamp 的默认值仍为 0。根据仓库发布历史设置时间戳,才能让带缓存的 YUM 客户端接受新索引。
存储与可选工具
执行 SOW 的用户需要读取输入软件包,并能写入仓库目录。Managed 工作区应放在支持文件锁、fsync 与原子重命名的本地 POSIX 文件系统上。
软件包解析与元数据生成由 SOW 完成。可选签名功能需要以下主机工具:
| 签名方式 | 所需工具 |
|---|---|
| 使用 OpenPGP 密钥文件或密钥内容签署元数据 | 无 |
| 使用 GPG 密钥标识签署元数据 | gpg 与 gpg-agent |
| RPM 软件包签名 | rpm 及可用的 GPG 签名环境 |
2 - 快速上手
Plain 模式为一个软件包目录生成仓库,不需要工作区或配置文件。准备 SOW、用于预览的 Python 3,以及至少一个 RPM 或 DEB 文件。
准备目录
创建可写目录。将下例输入路径换成实际文件,只执行已有格式对应的复制命令:
把包放在目录顶层;sow create 不扫描子目录。
生成元数据
目录中有一个 RPM 和一个 DEB 时,输出包含:
原始软件包旁会新增索引:
- sow-quickstart/
- example.rpm
- example.deb
- repodata/RPM 索引与元数据
- PackagesDEB 平面索引
- Packages.gz
SOW 只为实际存在的格式生成索引。Plain 模式不生成 APT Release、InRelease 或 Release.gpg 文件,也不改变软件包名称与路径。
启动本地服务器
在另一个终端执行以下命令,并保持运行:
如果本机没有 APT 或 DNF 客户端,按已添加的格式检查 HTTP 入口:
此服务器只能从本机访问。要供其他客户端访问或长期运行,请按对外服务配置。
配置本机客户端
如果预览服务器运行在 Linux 上,为本机包管理器创建源配置文件。下面使用未签名元数据,并关闭客户端签名检查。需要签名元数据时,使用 Managed 工作区与签名教程。
把以下内容保存为 /etc/yum.repos.d/sow-quickstart.repo:
刷新索引并安装其中一个软件包:
把以下内容保存为 /etc/apt/sources.list.d/sow-quickstart.list:
末尾的 ./ 选择平面仓库。刷新索引并安装其中一个软件包:
把 PACKAGE_NAME 换成包内元数据中的名称,而不是文件名。macOS 用户可以完成上述 HTTP 检查;软件包安装需在兼容的 Linux 客户端上执行。
更新仓库
添加或删除软件包文件后,重新生成索引:
包文件与参数不变时,生成的元数据也不变,重复运行会报告 noop=true。
对于只包含 RPM 的平面目录,也可以运行 sow prune "$HOME/sow-quickstart" --dry-run 预览旧版 RPM,再执行 sow prune "$HOME/sow-quickstart" 删除旧版文件并刷新 repodata/。
替换其他 YUM 元数据生成工具时,按迁移现有 YUM 仓库保留客户端缓存所需的时间戳。
预览完成后,用 Ctrl+C 停止服务器,并从客户端删除本例的源配置文件。软件包目录可以保留,以后继续使用。
下一步
需要具名 Dist、架构视图、版本限制、元数据签名与发布目标时,使用 Managed 工作区。全部 Plain 参数见 sow create 与 sow prune。
3 - 第一个工作区
本例创建一个 Managed 仓库,包含两个具名软件包集合,称为 Dist:
el9 存放 RPM,bookworm 存放 DEB。使用可写的空目录 /srv/sow,或换成其他路径。
初始化工作区
init 创建:
- /srv/sow/
- sow.yml配置;schema: sow/v3
- .sow/SOW 管理的私有状态
需要调整配置时,编辑 sow.yml。私有目录 .sow/ 由 SOW 管理。
重复执行 init 不会重置已有软件包或状态。
创建仓库与两个 Dist
每个 Dist 只有一种包格式。dist new 默认创建 x86_64 与 aarch64 的空索引。
两个 Dist 共用仓库的 pool/ 目录。
此时公共布局为:
- /srv/sow/local/
- pool/
- dists/
- el9/
- x86_64/repodata/
- aarch64/repodata/
- bookworm/
- Release
- main/
- binary-amd64/Packages, Packages.gz, by-hash/
- binary-arm64/Packages, Packages.gz, by-hash/
- el9/
添加软件包
显式选择目标 Dist:
把输入路径换成实际软件包文件。SOW 读取包身份与架构,将接受的文件存入 local/pool/,更新成员并构建受影响的 Dist。后续构建使用包池,SOW 不再依赖原始输入文件。
查看与校验
ls 列出各 Dist 中的软件包。status 应显示 clean 与 ready_to_copy=true。
check 成功表示文件与记录的构建结果一致。
对外提供仓库
发布完整的 /srv/sow/local 目录,让客户端能同时访问索引与软件包。工作区配置和 .sow/ 保留在服务器根目录之外。
批量更新
以后要连续添加多批软件包时,给 add 加上 --skip,最后构建一次:
有待构建的成员变更时,sow status 显示 dirty 与 ready_to_copy=false。
选择规则
上例从当前目录找到工作区,并选择其中唯一的仓库。
在其他目录运行时,加上 -C /srv/sow;工作区内有多个仓库时,加上 -r local。
使用 -d NAME 选择 Dist,可重复指定多个。完整的发现规则与默认值见选择规则。
下一步
4 - 核心概念
选择模式
| 需求 | Plain | Managed |
|---|---|---|
| 为软件包目录生成索引 | sow create DIR |
用 sow add 导入软件包 |
| 保存配置与成员关系 | 目录内容就是状态 | sow.yml 与私有 SQLite 数据库 |
| 组织软件包 | 一个平面目录,可同时包含 RPM 与 DEB | 具名 Dist,每个 Dist 一种格式 |
| 生成架构视图 | 不支持 | 支持 |
| 过滤软件包、限制版本数 | sow prune DIR(RPM 按 NAME + ARCH 保留最新版)与 --pigsty 清理 |
每个 Dist 单独配置 |
| 签名 RPM 软件包 | 支持 | 支持 |
| 签名仓库元数据 | 在 SOW 外单独签名 | 在 sow.yml 配置密钥 |
| 记录构建快照与发布状态 | 在 SOW 外管理 | 内置 |
如果目录已包含全部待发布软件包,使用 Plain。如果需要由 SOW 持续管理成员与仓库,使用 Managed。
工作区、仓库与 Dist
- Workspace/srv/sow
- sow.yml配置
- .sow/私有状态
- Repository//srv/sow/local
- pool/软件包文件
- dists/
- Dist/具名 RPM 或 DEB 软件包集合
- views/各架构的元数据
- Dist/具名 RPM 或 DEB 软件包集合
工作区(Workspace) 保存一个或多个仓库的配置与私有状态。
仓库(Repository) 拥有自己的包池、Dist、构建历史与发布目标。对外提供完整的 pool/ 与 dists/ 目录树;把 sow.yml 和 .sow/ 留在 HTTP 文档根目录之外。
Dist 选择一种格式的软件包。例如,el9 放 RPM,bookworm 放 DEB。名称由你指定;SOW 不会检查软件包是否兼容名称所指的操作系统。
架构视图 保存某个架构的元数据。SOW 把 RPM noarch 与 DEB all 包加入每个适用的视图。
每个软件包只存一份
SOW 用完整包文件的 SHA-256 标识 包对象(Package Object),从包内元数据读取包名、版本与架构。
同一个仓库内,每个接受的软件包在 pool/ 下只有一条路径。多个 Dist 可以引用这条路径。不同仓库使用各自的包池。
RPM 元数据通过相对路径引用包池,APT Packages 使用相对于仓库根目录的路径。对外服务或复制时,保留完整仓库目录树。
部分镜像工具(包括默认 dnf reposync)拒绝 RPM 中指向父目录的路径。为这些工具使用 sow export rpm-leaf 导出独立 RPM 仓库。
期望成员与构建快照
期望成员(Desired membership) 是每个 Dist 选中的软件包集合。 Generation(构建快照) 标识一次已完成的构建及其文件清单。Built Generation 指当前已完成的构建。 包文件保存在共享包池中,每次构建无需另存一份。
add 和 rm 默认在更新成员后构建受影响的 Dist。使用 --skip 时只更新成员。完成一批跳过构建的变更后,或修改构建、签名配置后,执行 sow build。
| 命令 | 用途 |
|---|---|
sow status |
读取当前状态与 ready_to_copy 值 |
sow check |
检查软件包、索引、签名与状态记录,不修改文件 |
sow changes [BASE_GENERATION] |
列出指定快照到当前构建的文件变更 |
sow publish TARGET |
检查当前构建并发布到已配置目标 |
理解仓库状态
| 状态 | 含义 | 下一步 |
|---|---|---|
clean |
成员与配置符合已构建结果 | 可以检查或发布 |
dirty |
成员或配置变更需要构建 | 执行 build,再执行 check |
recovering |
被中断的操作需要恢复 | 按报错与恢复步骤处理 |
error |
状态记录或文件发生冲突 | 查看报错与操作日志 |
使用 sow log 查看失败或中断的操作记录。