The Fedora 45 Sausage Factory
Inside the Fedora 45 Production Line
This guide provides a detailed walkthrough of the "sausage factory" that transforms raw source code and package definitions into the final artifacts users install—including ISOs, container images, cloud images, and OSTree deployments.
Note: This documentation reflects the process as of Fedora 45. Because the Fedora ecosystem is in constant flux, this is a living document. Since Fedora 45 has not yet been officially released, expect further updates.
There are currently several change proposals in development that may alter specific components, particularly the production of the boot.iso. If you spot any inaccuracies, please reach out via email at cmdr@supakeen.com.
The High-Level Workflow
The journey from a developer's keyboard to a user's machine follows this general pipeline:
1. The Starting Line: dist-git
Everything begins when a packager pushes a commit to a package repository. Fedora utilizes individual Git repositories for every package, hosted at src.fedoraproject.org.
Repository Composition
To keep Git repositories lean, large binary files are stored in a separate lookaside cache. The Git repo itself contains:
| Component | Purpose |
|---|---|
RPM spec file | The blueprint for building the package. |
Downstream patches | Fixes or modifications specific to Fedora. |
Sources file | Pointers to the upstream tarballs in the cache. |
Tooling and Infrastructure
Packagers primarily use fedpkg, a CLI tool that simplifies complex operations.
- Common
fedpkgtasks:- Cloning repositories.
- Uploading source tarballs.
- Initiating builds.
- Creating updates.
When a user executes fedpkg build, the tool generates a URL pointing to a specific Git commit and transmits it to Koji.
Branching Logic:
rawhide: The bleeding-edge development branch.f44: The specific branch for Fedora 44.
Pagure Forgejo: The hosting infrastructure is currently migrating from Pagure (src.fedoraproject.org) to Forgejo (forge.fedoraproject.org).
2. Building Packages: Koji
Koji is the heavy-lifter of the Fedora ecosystem, serving as the central build system since Fedora 7.
Architecture
Koji operates on a hub-and-spoke model:
- The Hub: A passive XML-RPC server backed by a PostgreSQL database.
- Builder Daemons: These poll the hub for pending tasks. To ensure absolute reproducibility, each build occurs within a fresh Mock chroot environment. This prevents "environmental drift" (where a build succeeds only because of a package installed on the builder previously).
Build Targets and Tags
Koji uses a system of tags to manage dependencies and destinations:
- Build Tag: Defines the buildroot (the set of packages available during the build).
- Destination Tag: Where the resulting binary is stored.
Because tags support multiple inheritance, developers can layer a specific release tag (e.g., Fedora 44) over a base tag without duplicating data.
Beyond RPMs
Koji also orchestrates the creation of larger images via specialized tasks:
kiwiBuildKiwi images.imageBuilderBuildImage Builder artifacts.runrootOSTree composes.
3. Gating Updates: Bodhi
A successful build in Koji does not immediately reach the end user. For branched releases, the package must pass through Bodhi, the update management system.
The Lifecycle of an Update
Updates move through a linear progression of states:
Pending Testing Stable
The transition to Stable is governed by "Karma" and time:
| Path Type | Karma Required | Time in Testing | Notes |
|---|---|---|---|
| Standard | +3 (Auto) / +1 (Manual) | 7 Days | General packages. |
| Critical Path | Higher Karma | 14 Days | Essential for booting/system stability. |
Integration and Automation
Bodhi doesn't just track status; it actively manages Koji tags. When an update is promoted, Bodhi moves the build from f44-updates-testing to f44-updates. It then triggers Pungi to update the actual dnf repositories.
Bodhi also integrates with:
- Greenwave (CI Testing)
- ResultsDB (Automated failure tracking)
If automated tests fail, the update is blocked from reaching the stable state.
4. Composing a Release: Pungi
While Koji builds individual RPMs, Pungi (named after the snake-charmer's instrument) coordinates the assembly of those RPMs into a cohesive product.
The Composition Process
A compose is triggered either by a cron job (for nightly Rawhide builds) or manually (for milestones). Pungi reads a configuration file, such as:
# Example reference to the config location
# Repository: pungi-fedora
# File: fedora.conf
Phase 1: Freezing the Package Set
The most critical step is the Pkgset phase. Pungi takes a snapshot of a specific Koji tag.
Crucial Detail: Once the Pkgset is frozen, any new builds submitted to Koji are ignored for that specific compose. This ensures that the resulting ISO is consistent and reproducible.
Phase 2: Distribution Logic
Once the package list is locked, Pungi determines the destination of each package using:
comps(fedora-comps): These define package groups and collections, determining which software ends up in which product variant.