Skip to content

decompose the release RPM into separate RPMs with a meta-rpm in the release repo #64

Open
8 of 15 issues completed

Description

@alexlovelltroy

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

  1. 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.
  2. 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.
  3. Dependency validation via the package manager. Express version ranges between services (e.g. boot-service requires smd >=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.
  4. An additional code-signing layer.
  5. 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/%files patterns, 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.yaml vs <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.

Activity

  1. moved this from Backlog to Ready in OpenCHAMI Initial Releaseon Jul 17, 2026
  2. seantronsen commented on Aug 11, 2026

    @seantronsen
    Contributor

    Discussion items pulled from: OpenCHAMI/tokensmith#47

    1. should we standardize quadlet volume names to %N.volume for simplicity?
    2. Can we move transient site-specific configurations (e.g., the custom
      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.
    3. should configuration from shared configuration files like openchami.env
      in 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:> ```
    [Container]
    ...
    EnvironmentFile=/etc/openchami/configs/<svc-name>.env
    EnvironmentFile=-/etc/openchami/configs/openchami.env
    
  3. seantronsen commented on Aug 11, 2026

    @seantronsen
    Contributor

    Discussion items pulled from: OpenCHAMI/smd#116

    1. should secrets generation for podman stay in the release repo or migrate to
      each service repo?
  4. seantronsen commented on Aug 11, 2026

    @seantronsen
    Contributor

    Multi-node deployment question:

    1. Should OpenCHAMI services have a URI endpoint which responds which the version number, thereby enabling dependent services to determine functionality/compatibility dynamically at runtime?
  5. erl-hpe commented on Aug 26, 2026

    @erl-hpe
    Contributor

    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?

  6. seantronsen commented on Aug 26, 2026

    @seantronsen
    Contributor

    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?

    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.

  7. seantrons commented on Aug 31, 2026

    @seantrons

    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?

    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.

    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).

  8. seantronsen commented on Sep 2, 2026

    @seantronsen
    Contributor

    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.volume

    Note

    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.

    • Versioning will remain templated
    • RPM Requires dependencies 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.

    • systemd files will be installed under the distro-managed path (/usr/share/containers/systemd and /usr/lib/systemd/system)
    • Fabrica service config files will live under /etc/openchami/configs/<svc-name>.yaml
    • Common configuration environment variables are moving to systemd drop in files to make better use of the systemd ecosystem.

    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-service and boot-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 systemd installations 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/system and /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.

  9. self-assigned this
    on Sep 2, 2026
  10. erl-hpe commented on Sep 2, 2026

    @erl-hpe
    Contributor

    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.

  11. seantronsen commented on Sep 14, 2026

    @seantronsen
    Contributor

    Reminder to ensure all workflows and actions from OpenCHAMI/github-actions use the most recent version.

    At the time of writing, the most recent version is v3.7 and we started this endeavor using v3.5. That being said, smd and tokensmith are now outdated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions