Version Tracking and Revisions
Relevant source files
The following files were used as context for generating this wiki page:
Version tracking and revisions manage the lifecycle of software packages within the OPSI repository. The system maintains semantic ordering, prevents version downgrades, and ensures the integrity of published archives using unique package identifiers and historical checksums.
This module coordinates upstream version discovery with local packaging revisions. It ensures that every .opsi archive is uniquely identified by a combination of the product ID, a normalized version string, and an integer revision number.
Sources: README.md:129-136, builder/builder/main.py:65-72
Version Normalization and Ordering
The builder normalizes upstream version strings to ensure consistent semantic ordering. It utilizes packaging.version.Version to compare versions, ensuring that "10.0" correctly follows "9.9" regardless of the raw string format.
- Normalization Rules: The system removes leading 'v' characters and insignificant leading zeros.
- PEP 440 Compliance: Beta identifiers and pre-releases are normalized to PEP 440 notation.
- OPSI Compatibility: Local or build labels are encoded using
.local.to remain compatible with OPSI's 32-character product version limit.
Sources: README.md:129-133, builder/builder/versions.py
The diagram shows how raw upstream strings are transformed into normalized versions for comparison and packaging.
Sources: builder/builder/versions.py, builder/builder/main.py:67-75
Package Revisions
A package_revision is a separate integer incremented when deployment logic changes without an upstream software update. This allows the administrator to fix installation scripts or configuration overrides while keeping the same vendor installer.
- Identifier Format: A full package name follows the pattern
{opsi_product_id}_{version}-{package_revision}.opsi. - Manual Repackaging: Administrators can trigger a repackage of existing installers when only the OPSI logic changes, preserving original download metadata.
Sources: README.md:133-140, builder/builder/repository.py:10-14
| Field | Source | Example | Purpose |
|---|---|---|---|
opsi_product_id | Catalog | auto-firefox | Unique OPSI internal ID |
upstream_version | Vendor Feed | 121.0.1 | Exact version from source |
opsi_version | Normalized | 121.0.1 | PEP 440 compatible version |
package_revision | Catalog | 2 | Iteration of OPSI packaging logic |
Sources: README.md:133-140, catalog/packages.yaml:9-12
State Tracking and Provenance
The system tracks versions through two primary mechanisms: the central state file and individual provenance sidecars.
Persistent State
The file state/packages.json records the last successful build for every product. It stores the upstream version, OPSI version, package revision, and SHA256 checksum.
Sources: builder/builder/main.py:31-35, builder/builder/state.py
Provenance Sidecars
Every .opsi archive is accompanied by a .opsi.provenance.json file. This file contains immutable evidence of the build, including the source URL, download timestamp, and signature status. If the central state file is lost, the builder reconstructs the checksum history by scanning these sidecar files in the repository.
Sources: README.md:20-25, builder/builder/main.py:38-46
This sequence illustrates how the builder uses sidecar files to recover version history.
Sources: builder/builder/main.py:38-46
Downgrade Prevention and Retention
The builder implements safety checks to prevent stale metadata from overwriting newer repository contents.
- Downgrade Guard: The builder compares the "Desired" version (Catalog Revision + Upstream Version) against the "Existing" version in the repository. If the desired version is lower, the build is blocked.
- Retention Policy: The
KEEP_VERSIONSenvironment variable (default: 2) determines how many previous versions are retained. - Metadata Atomic Switch: Metadata is generated in a temporary workspace and atomically moved into the served repository only after successful creation, ensuring version availability during updates.
Sources: README.md:143-147, builder/builder/repository.py:27-50, builder/builder/main.py:68-75
Immutable Checksum Guard
To ensure security and version stability, the system tracks historical SHA256 checksums for every product version. If an upstream vendor replaces a file at an existing URL with a different payload, the builder detects the hash mismatch and fails the build.
- Manual Override: Bypassing this guard requires setting
ALLOW_CHANGED_CHECKSUM=truein the.envfile. - Force Rebuild: The
--forceflag allows rebuilding an archive but does not bypass the checksum integrity check for known versions.
Sources: README.md:155-167, builder/builder/main.py:77-85
Summary
Version Tracking and Revisions ensure OPSI packages remain consistent, ordered, and verifiable. By combining semantic versioning with local revisions and immutable checksum history, the system provides a reliable automated pipeline for software distribution while protecting against upstream tampering or configuration errors.