Repository navigation
decompose the release RPM into separate RPMs with a meta-rpm in the release repo #64
Description
Summary
Move service-specific configuration and packaging out of the release repo and into each service's own repository, publishing per-service RPMs. The release repo then becomes a composite package: a curated, known-working set that declares versioned dependencies on the individual service packages and layers a single-node opinion on top of them.
Problem
The release repo is both a key installation target and the reference installation path in the OpenCHAMI walkthrough. Today it's a collection of quadlets and configs maintained entirely separately from the upstream service repos.
That separation is a maintenance hazard, particularly for configuration. Nothing ties a default config to the service version it was written against, so as features land and refactors happen, the two drift. The failure mode is a user keeping the release-repo default config, upgrading a service RPM, and discovering the config is stale at runtime.
It's also all-or-nothing. Downstream sites take the whole bundle whether or not they want every piece.
Goals
- Eliminate config drift. Default configs live with their service and are maintained alongside it. Installing a service RPM should yield a working default config out of the box.
- Mix and match. Core services are required, but the supplementary services and third-party components that tie things together (HAProxy, etc.) are not. Per-service packages let downstream sites install and configure what they need and skip the rest, instead of inheriting our full bundle.
- Dependency validation via the package manager. Express version ranges between services (e.g.
boot-servicerequiressmd >=3,<4) and pull in system dependencies (systemd, podman, etc.) automatically, rather than documenting them as manual install steps. We target RPM today; every package manager we care about supports this. - An additional code-signing layer.
- Compile-time compatibility checking across services. As a composite package, the release repo surfaces incompatibilities at build time instead of shipping a pile of quadlets and hoping for the best.
Layering model
The split between service packages and the composite package is deliberate, and the boundary is opinionatedness:
Service-level packages are generic. Each service repo builds a quadlet-based package (and likely a baremetal-based package later) whose configuration takes no position on deployment topology — it should be equally valid as the starting point for a single-node install or a multi-node/federated one. No assumptions about co-location, no hardcoded local endpoints.
The composite release package is opinionated, for the single-node case only. It depends on the service packages and then overrides their generic configuration into a coherent all-on-one-box deployment, using a mix of systemd drop-ins and config override files rather than replacing the shipped defaults. This keeps the release repo as our worked example of a good installation while leaving the upstream defaults intact and upgradable.
Multi-node and federated deployments are explicitly not served by the composite package; they consume the generic service packages directly and supply their own overrides.
Standardization
Decomposition only removes drift if the resulting per-repo packaging is uniform. Without an agreed layout, we trade one drift problem for N of them. We need to settle on and document a template covering at minimum:
- Directory layout — where packaging lives in each repo (e.g.
packaging/rpm/,packaging/deb/), and where source configs, quadlets, and unit files live relative to it. - Spec file conventions — naming,
Source/%filespatterns, macro usage, changelog handling, and what gets templated vs. hand-written. - Package naming and versioning — package name derivation from repo/service name, subpackage split (
-config,-quadlet, future-baremetal), and how upstream version maps to RPM version/release. - Installed file paths — config under
/etc/openchami/<service>/, quadlets under a single agreed location, data/state dirs, ownership and permissions. - Config file naming — one convention across all services (
config.yamlvs<service>.yaml), plus how we handle%config(noreplace)on upgrade. - Override contract — the drop-in and config-fragment paths each service guarantees, so the composite package (and downstream sites) can override predictably without editing shipped files.
- Dependency declaration — how inter-service version ranges are expressed and where the authoritative range lives (service spec, composite spec, or both).
- Build inputs/outputs contract — the Make targets and artifact paths every repo must expose so shared CI can drive them identically.
- Metadata — license, vendor, URL, summary/description conventions.
Enforcement mechanism is also open: cookiecutter-style template repo, a shared packaging repo vendored in, or lint checks in CI.
Scope
In scope: decomposing per-service packaging and config into the service repos; converting the release repo into a single-node composite package; defining the standardization template above.
Out of scope (this phase):
- How CI-built RPMs reach the distribution server. @alexlovelltroy is standing up distribution on AWS in the near future.
- How signing works end to end — open questions include whether we need a validation script embedded in the composite RPM, or a separate keys RPM.
- Baremetal (non-container) service packages.
- A composite package for multi-node/federated topologies.
Notes
- We currently target RHEL only, since that's what we run on site. SLES, Debian, and others will follow. The layout template should anticipate this rather than bake in RPM-only assumptions.
- The repos undergoing decomposition share substantial packaging logic. Abstract GitHub Actions, reusable workflows, and build recipes (Makefiles) into shared components wherever possible rather than duplicating per repo.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsReady
Activity
openchami-commonRPM release containing files not specific to any one service #69seantronsen commentedon Aug 11, 2026
Discussion items pulled from: OpenCHAMI/tokensmith#47
%N.volumefor simplicity?hostname config for the
tokensmith.container) to systemd drop in files?This would make it easier for us to provide update scripts to users AND to
provide sane defaults.
openchami.envin the release repo be migrated to each service repo? We could use a sane
override pattern as shown below, albeit at the cost of noise:> ```
seantronsen commentedon Aug 11, 2026
Discussion items pulled from: OpenCHAMI/smd#116
each service repo?
seantronsen commentedon Aug 11, 2026
Multi-node deployment question:
erl-hpe commentedon Aug 26, 2026
What is the plan for service-non-specific resources like virtual networks and so forth, that multiple services may share as a dependency? Would there be a separate OpenCHAMI-Infrastructure package or something like that? Would that be baked into OpenCHAMI/Release?
seantronsen commentedon Aug 26, 2026
Yes that's correct. I don't think we've decided on a name if you want to toss a hat in the ring, but in current discussions it is being referred to as "openchami-common".
Essentially, it will be an RPM containing all configs+resources for items that aren't specific to a single service.
All service RPMs which depend on a common config will then depend on this RPM, so the package manager will rope it in automatically as needed.
From there, the plan is to include all of these RPMs in the release via a composite package.
seantrons commentedon Aug 31, 2026
The approach here pends some further discussion. A possible alternative is configuring each service with sane defaults to avoid the additional required dependency (thus making the common RPM recommended, but optional).
seantronsen commentedon Sep 2, 2026
Per a a meeting the other day:
Directory layout — where packaging lives in each repo (e.g. packaging/rpm/, packaging/deb/), and where source configs, quadlets, and unit files live relative to it.
packaging/ ├── common │ ├── configs │ │ └── boot-service.yaml │ └── systemd │ ├── boot-service.container │ └── boot-service-data.volume ├── rpm-baremetal │ ├── boot-service.spec │ └── configs │ └── boot-service.yaml │ └── rpm-quadlet ├── boot-service.spec ├── configs │ └── boot-service.yaml └── systemd ├── boot-service.container └── boot-service-data.volumeNote
Symlinks are used to mitigate duplication when possible.
Spec file conventions — naming, Source/%files patterns, macro usage, changelog handling, and what gets templated vs. hand-written.
Requiresdependencies specifications will only be used to enforce minimum versions, not maximal versions (backwards compatibility goal).Package naming and versioning — package name derivation from repo/service name, subpackage split (-config, -quadlet, future -baremetal), and how upstream version maps to RPM version/release.
See the names used under directory layout. RPM filenames will be derived from the VCS repo name and suffxed with the deployment type (e.g., quadlet).
Installed file paths — config under /etc/openchami//, quadlets under a single agreed location, data/state dirs, ownership and permissions.
systemdfiles will be installed under the distro-managed path (/usr/share/containers/systemdand/usr/lib/systemd/system)/etc/openchami/configs/<svc-name>.yamlsystemddrop in files to make better use of thesystemdecosystem.Config file naming — one convention across all services (config.yaml vs .yaml), plus how we handle %config(noreplace) on upgrade.
TBD based on the standardization issues+prs in progress for
metadata-serviceandboot-service.Override contract — the drop-in and config-fragment paths each service guarantees, so the composite package (and downstream sites) can override predictably without editing shipped files.
OpenCHAMI intends to first support
systemdinstallations with newer versions shipping files under the distro-managed path (see previous discussion). Given that, users can easily override environment specifications using additional drop in files under the administrator paths (/etc/systemd/systemand/etc/containers/systemd).Dependency declaration — how inter-service version ranges are expressed and where the authoritative range lives (service spec, composite spec, or both).
The existing dependency hierarchy set forth by the current release repository will be maintained, but with the dependency checks moving into packages for each service specific repo.
Recall from a previous response that only minimal software dependency version numbers will be enforced. Maximums are not currently planned since our goal is to provided backward compatibility in future releases.
Build inputs/outputs contract — the Make targets and artifact paths every repo must expose so shared CI can drive them identically.
Renovate bot will be configured to ensure the necessary interface contract is met by each repositories
Makefile.Metadata — license, vendor, URL, summary/description conventions.
Existing licensing strategies will be mirrored in the release packages with documentation pointing to VCS repository or the OpenCHAMI homepage where appropriate.
openchami-acme-quadletrepository #72openchami-postgres-quadletrepository #73openchami-haproxy-quadletrepository #74openchami.envto systemd drop-in files #75erl-hpe commentedon Sep 2, 2026
Thanks! Alex has asked me to start helping out with this effort, which will be my priority once I resolve an issue I have been seeing with the deployment tool (shouldn't be much longer). I will drop you a note when I am ready to start and we can coordinate a bit.
Makefile's #76seantronsen commentedon Sep 14, 2026
Reminder to ensure all workflows and actions from
OpenCHAMI/github-actionsuse the most recent version.At the time of writing, the most recent version is
v3.7and we started this endeavor usingv3.5. That being said,smdandtokensmithare now outdated.