Azure Linux is a TOML-defined Linux distribution that imports RPM specs from upstream distros (primarily Fedora) and customizes them via an overlay system — no spec forking required. The azldev CLI tool drives all component and image workflows.
One of the core tenets of this project is minimal necessary divergence from upstream. Overlays should be surgical and only change what's needed to meet Azure Linux requirements. Upstream packages should be preferred over bespoke components, and local specs should be a last resort. This keeps maintenance overhead low and makes it easier to pull in new versions and security updates from upstream.
While AZL derives from Fedora, it is also an enterprise focused distro which tries to align with RHEL where it makes sense. At times this can cause conflicts in spec files that normally expect the Fedora and RHEL macros to be mutually exclusive. Use your best judgement when navigating these conflicts, but in general the guiding principle should be to minimize divergence from Fedora while still producing a stable enterprise distro suitable for use in the Azure cloud. If a spec file has complex conditional logic to handle differences between Fedora and RHEL, consult with the user to understand the rationale and determine the best path forward for AZL.
azldev.toml # Root config — includes distro/ and base/
├── base/ # The "base" project
│ ├── project.toml # Project metadata, output dirs, default distro ref
│ ├── out/ # Built RPMs/SRPMs (configured by output-dir in project.toml)
│ ├── build/ # Build artifacts (configured by log-dir, work-dir)
│ │ ├── logs/ # Build logs
│ │ └── work/<name>/ # Per-component working directories
│ └── comps/ # Component definitions
│ ├── components.toml # Main component list (includes **/*.comp.toml)
│ ├── <name>/<name>.comp.toml # Dedicated component files (when overlays/config needed)
│ └── <name>/ # May also contain local spec files and overlay sources
├── distro/ # Distro definitions (shared across projects)
│ ├── azurelinux.distro.toml # Azure Linux 4.0: default distro, mock configs, build defines
│ ├── distro.toml # Includes all *.distro.toml
│ ├── fedora.distro.toml # Fedora: dist-git URIs, lookaside, version branches
│ └── mock/ # Mock build environment configs
├── specs/ # Rendered specs (generated by `azldev comp render`)
│ └── <first-char>/<name>/ # Per-component: spec, patches, scripts (no source tarballs)
└── external/schemas/
└── azldev.schema.json # Authoritative schema for all TOML config files
The specs/ directory (as specified by rendered-specs-dir config) contains rendered spec files generated by azldev comp render. These are the final specs with all overlays applied — ready for check-in. After adding or modifying components/overlays, re-render:
azldev comp render -p <name> # Single component
azldev comp render -a # All components (slow)To inspect what a component's spec looks like after overlays, read specs/<first-char>/<name>/<name>.spec directly — no need to run prep-sources just to view the result. Use prep-sources when you need the full source tree (tarballs) or want to diff pre/post overlay output for debugging.
The locks/ directory (as specified by lock-dir config) contains per-component lock files that pin upstream commits + an input fingerprint. They are managed by azldev comp update:
azldev comp update -p <name> # Refresh a single lock
azldev comp update -a # Refresh all locksAlways re-run update before opening a PR, even after minor edits — the input fingerprint is computed from the full component config, and the Update Locks CI check runs against the committed state.
%changelog and Release: are derived from git log for the component, not the working tree. In this mono-repo, commits that change a component's tracked inputs (for example base/comps/<name>/ and/or locks/<name>.lock) drift the rendered output, so after committing you must re-render and amend (or commit the spec separately). See skill-update-component for the finalize-and-amend pattern that keeps Check Rendered Specs and Update Locks both green, including the pin-bump variant.
When making a PR, the lock and rendered specs must be updated and self-consistent.
Components = unit of packaging (→ one or more RPMs). Spec sources: upstream (default, from Fedora dist-git), local, or pinned upstream. See comp-toml.instructions.md for syntax.
Overlays modify upstream specs/sources without forking. See comp-toml.instructions.md for types, syntax, and pitfalls. Schema: azldev.schema.json.
TOML include hierarchy: azldev.toml → distro/distro.toml + base/project.toml → base/comps/components.toml → **/*.comp.toml (stitched into single namespace).
Run all commands from the repo root (where azldev.toml lives). If the terminal's cwd has drifted, use azldev -C /path/to/repo <command>. Use azldev --help and azldev <command> --help for current syntax — the tool is under active development.
Agent-friendly flags: Use -q (quiet) to reduce noise and -O json for machine-parseable output. These are global flags and work on all commands.
| Task | Command |
|---|---|
| List all components | azldev comp list -a -q -O json |
| List a specific component | azldev comp list -p <name> -q -O json |
| List with wildcard | azldev comp list -p "azurelinux*" -q -O json |
| Query a component (parsed spec, slow) | azldev comp query -p <name> -q -O json |
| Add a component | azldev comp add |
| Build a component | azldev comp build -p <name> -q |
| Build chain (auto-publish to local repo) | azldev comp build --local-repo-with-publish ./base/out -p <a> -p <b> -q |
| Render all specs for check-in | azldev comp render -a |
| Render a single component | azldev comp render -p <name> |
| Update a single lock file | azldev comp update -p <name> |
| Update all lock files | azldev comp update -a |
| Prepare sources (apply overlays) | azldev comp prep-sources -p <name> --force -o <dir> -q |
| Prepare sources (skip overlays) | azldev comp prep-sources -p <name> --skip-overlays --force -o <dir> -q |
| Build, keep env on failure | azldev comp build -p <name> --preserve-buildenv on-failure -q |
| List images | azldev image list |
| Build an image | azldev image build |
| Boot an image in QEMU | azldev image boot |
| Dump resolved config | azldev config dump -q -f json |
| Advanced commands (like mock shell) | azldev adv --help (hidden from normal help) |
- Overlay descriptions: Every overlay MUST include a
descriptionfield explaining why the change is needed. - Naming: Component names should match the upstream package name. Use
upstream-namewhen the upstream name differs (e.g.,upstream-name = "redhat-rpm-config"forazurelinux-rpm-config). - Schema validation: The authoritative schema is
external/schemas/azldev.schema.json. Do NOT add$schemakeys to TOML files —$is invalid at the start of a bare TOML key. - Don't edit generated output: Build artifacts in
base/out/andbase/build/are generated (configured byoutput-dir,log-dir,work-dirinbase/project.toml) — never edit them directly. Note:prep-sources -o <dir>writes to a user-specified directory, separate from these project output dirs. - Mandatory testing: Any change that affects a component's output (overlays, build config, spec edits, version bumps, new components) MUST be validated by building AND testing the resulting RPMs. A successful build alone is not sufficient — smoke-test in a mock chroot. Pure organizational changes (moving definitions between files, editing descriptions/comments) do not require rebuild. See
AGENTS.mdfor the full testing protocol.