sow dist
A Dist is a named set of packages in exactly one format (rpm or deb) inside one Repository. It is
what a client points at. A Repository can hold RPM and DEB Dists side by side; they share one pool/
but render into completely separate dists/ subtrees.
Synopsis
Naming
Dist names follow the same rule as Repository names: [a-z0-9][a-z0-9._-]*, excluding ., ..,
.sow, pool and dists.
To SOW the name is an opaque string. el9, trixie, el9-beta, customer-acme, 2026-07-31 are
all just names — beta channels, per-customer views and snapshots are naming conventions you impose,
not features SOW models.
sow dist ls
Read-only flat listing of the selected Repository’s Dists.
DESIRED and BUILT are membership counts. When they diverge, DIRTY_REASONS says why:
| Flag | Description | Default |
|---|---|---|
-C, --workdir DIR |
Workspace discovery start directory | current directory |
-r, --repo NAME |
Select a repository | selection rules |
--json |
Emit the versioned JSON envelope | false |
Architectures print as canonical families. The JSON output carries both spellings, which is how you
confirm that a DEB Dist renders binary-amd64 and binary-arm64:
sow dist new
Creates an ordinary, still-editable Dist. The only business argument is --format.
| Flag | Description | Default |
|---|---|---|
--format FORMAT |
Required; rpm or deb |
— |
-C, --workdir DIR |
Workspace discovery start directory | current directory |
-r, --repo NAME |
Select a repository | selection rules |
-T, --timeout DUR |
Maximum lock wait; 0 waits indefinitely |
0 |
-N, --no-wait |
Fail immediately when the lock is held | false |
--json |
Emit the versioned JSON envelope | false |
--format is mandatory and closed:
There is no --arch. Architectures are inherited from the Workspace permit list; an advanced user
narrows them per Dist by editing sow.yml. Policy (limit, exclude) is likewise configured in
sow.yml, never re-modelled on the command line.
Re-running dist new with the same name and the same format converges and reports the current state.
A name collision with a different format is rejected:
The three-way transaction
dist new is committed across three places at once: the sow.yml entry, the Repository database,
and the on-disk tree. It goes through the SQLite Operation Journal (the Repository database already
exists at this point, unlike repo new) and produces a new Built Generation with empty indexes.
That means a fresh Dist has a protocol-complete empty surface. An RPM Dist gets an empty
repodata/ under every architecture view; a DEB Dist gets empty Packages, Packages.gz,
the by-hash/SHA256/ entries and Release, plus InRelease/Release.gpg when signing is
configured.
sow dist show
Read-only detail for one Dist.
| Flag | Description | Default |
|---|---|---|
-C, --workdir DIR |
Workspace discovery start directory | current directory |
-r, --repo NAME |
Select a repository | selection rules |
--json |
Emit the versioned JSON envelope | false |
The JSON form additionally exposes effective_config_sha256, the digest of the resolved Dist
configuration. That digest is what makes a Dist dirty when you change limit, exclude or a signing
key — the config identity changed, so the Built Generation no longer matches Desired.
sow dist rm
Removes a Dist’s Membership and derived indexes.
| Flag | Description | Default |
|---|---|---|
-f, --force |
Remove membership and indexes but retain pool packages | false |
-C, --workdir DIR |
Workspace discovery start directory | current directory |
-r, --repo NAME |
Select a repository | selection rules |
-T, --timeout DUR |
Maximum lock wait; 0 waits indefinitely |
0 |
-N, --no-wait |
Fail immediately when the lock is held | false |
--json |
Emit the versioned JSON envelope | false |
Dist removal does not delete Pool bytes
Removing a Dist never deletes a package from pool/. The whole Dist directory is moved into the
recovery area and removed atomically; the pool is untouched:
Orphaned pool objects remain until sow gc proves they are unreachable from every safety
root: current, retained, recovery, publication, and any active maintenance operation.
A Repository’s protected: true blocks Repository deletion only; normal Dist maintenance on a
protected Repository continues to work.
Examples
Give one Repository an RPM and a DEB face:
Add a beta channel with its own retention policy — create it, then set the policy in sow.yml and
converge:
Which Dists are behind their Desired state:
Exit codes
| Code | Trigger |
|---|---|
0 |
Listed, created, shown or removed; or dist new converged an existing Dist |
1 |
Runtime I/O or renderer error creating the empty indexes |
2 |
Usage error — missing or invalid --format, Workspace not found, ambiguous Repository |
4 |
Repository lock held and --no-wait given or --timeout expired |
5 |
Integrity or recovery error in the Operation Journal |
6 |
Invalid name, unknown Dist, format conflict with an existing name, non-empty without -f |
See also
- sow repo — the layer above
- Pool & Architecture Views — how one Dist becomes several client-visible views
- Membership Policy — configuring
limitandexclude - sow build — converging after a policy edit
- Repository Layout — the RPM and DEB
dists/structures