Open Source Governance¶
This document describes how quadletman aligns with the upstream Podman project and how it tracks, models, and implements support for new Podman features.
Upstream alignment¶
quadletman aims to follow the Podman project as closely as possible, supporting new features as they are released. This is achieved through three mechanisms:
- Automated release monitoring via GitHub workflows
- Internal data modelling of Podman version support via the VersionSpan system
- Conditional code branches that adapt behaviour to the detected Podman version
Monitoring Podman releases¶
A GitHub Actions workflow (.github/workflows/podman-watch.yml) runs weekly and checks
the latest Podman releases. For each new release it runs
scripts/podman_feature_check.py, which:
- Diffs the Quadlet man page between the new and previous releases to detect added or removed unit-file keys.
- Scans the release notes for Quadlet-relevant entries using keyword matching.
- Cross-references the findings against the current
PodmanFeaturesflags in the codebase to highlight coverage gaps.
The script opens a GitHub issue labelled podman-release with the full report.
Developers then triage the issue and implement support for the new features. See
Upstream Monitoring for the detailed workflow.
Modelling version support (VersionSpan)¶
Every Podman-version-sensitive property in the data model carries a VersionSpan
annotation that records when it was introduced, deprecated, and removed:
from typing import Annotated
from quadletman.models.version_span import VersionSpan
apparmor_profile: Annotated[SafeStr, VersionSpan(
introduced=(5, 8, 0),
quadlet_key="AppArmor",
)] = SafeStr.trusted("", "default")
VersionSpan metadata drives three layers of version awareness automatically:
| Layer | Mechanism | Effect |
|---|---|---|
| Route validation | validate_version_spans() in HTTP handlers |
Rejects requests that set unsupported fields (HTTP 400) |
| Quadlet file generation | field_availability() dicts passed to Jinja2 templates |
Omits unsupported keys from generated unit files |
| UI form gating | Pre-computed availability globals in templates | Disables form inputs for features unavailable on the host |
For features that are not tied to a single model field (e.g. entire unit-file types like
.pod or .build), feature-level VersionSpan constants serve the same purpose:
POD_UNITS = VersionSpan(introduced=(5, 0, 0))
BUILD_UNITS = VersionSpan(introduced=(5, 2, 0))
QUADLET_CLI = VersionSpan(introduced=(5, 6, 0))
These constants are pre-evaluated into boolean flags on the PodmanFeatures dataclass
at startup and used in route guards and conditional code paths.
Conditional code branches¶
Where the same operation can be performed differently depending on Podman version, quadletman uses version-gated branching rather than requiring a single minimum version. For example, the Quadlet unit-file writer supports two backends:
- Podman < 5.6.0 — direct file I/O (
host.write_text()+systemctl daemon-reload) - Podman >= 5.6.0 —
podman quadlet installCLI (official API)
The version gate is transparent to callers:
def _persist_unit(service_id, filename, content):
if get_features().quadlet_cli:
_install_via_cli(service_id, filename, content)
else:
_write_to_disk(service_id, filename, content)
This pattern ensures quadletman works on the widest range of Podman versions while automatically using the best available mechanism.
Feature lifecycle¶
When a new Podman release is detected by the monitoring workflow, the typical response follows this sequence:
- Triage — review the
podman-releaseissue; identify new Quadlet keys, new unit types, new CLI commands, and deprecations. - Model — add
VersionSpanannotations to new or existing model fields; add feature-level constants for new unit types or CLI capabilities. - Schema — add DB columns (Alembic migration) and ORM definitions for new fields.
- Templates — update Quadlet Jinja2 templates to render new keys with version gates.
- Routes — add route-level validation (
validate_version_spans()) and feature guards. - Tests — add version boundary tests and extraction count tests.
- Documentation — update CLAUDE.md, Key Files table, and feature docs.
Supported Podman versions¶
quadletman supports Podman from version 4.1.0 (pasta network driver) onward. Core Quadlet functionality requires 4.4.0. The following table shows when major capabilities became available:
| Version | Capability |
|---|---|
| 4.1.0 | Pasta network driver |
| 4.4.0 | Quadlet (.container, .volume, .network, .kube) |
| 4.8.0 | .image unit files |
| 5.0.0 | .pod unit files |
| 5.2.0 | .build unit files |
| 5.6.0 | podman quadlet CLI (install, list, rm, print) |
| 5.7.0 | .artifact unit files |
| 5.8.0 | .quadlets bundle format |
The full per-field version mapping is maintained in models/version_span.py and
models/api/__init__.py via VersionSpan annotations.