Vmango RPM and systemd
Run this example on a disposable AlmaLinux 10 x86_64 machine with root,
DNF 4, systemd as PID 1, network access to distribution repositories, EPEL and COPR,
and a built Linux Richt binary at bin/richt. Run all commands from the
repository root. The example owns /etc/yum.repos.d/richt-vmango.repo,
/etc/vmango.conf, the vmango package and vmango.service; start without an
existing Vmango installation or either managed configuration file.
It uses published, signed Vmango COPR RPMs
.
No package build, fixture repository, rpm-build, createrepo_c, or COPR CLI
plugin is needed. The config-only repository service runs before the package
service. The rhel-10 target is deliberate: EPEL 10 builds target CentOS Stream
and can require newer libvirt than AlmaLinux/RHEL provides. Runtime dependencies
are resolved by DNF during apply; no hypervisor or VM image is required.
The minimal application configuration binds only 127.0.0.1:18080, has no
clouds/hosts or login users, and stores generated state below /var/lib/vmango.
It demonstrates installation and process lifecycle, not VM provisioning or a
usable authenticated deployment. The package supplies the service unit; its
configuration changes use restart because no reload interface is assumed.
Root ownership and mode 0644 let the package-created vmango user read the
config without requiring that account to exist during first preparation.
Enable the standard AlmaLinux CRB and EPEL repositories before applying. The
published package requires genisoimage, which was available through EPEL in
the recorded AlmaLinux 10.2 run:
dnf config-manager --set-enabled crb
dnf install -y epel-release
These prepare dependency sources; Richt still installs Vmango and its runtime dependencies through the reviewed plan. Keep package signature checking enabled.
Inspect, install, and inspect again
Inventory validation opens no templates, contacts no hosts and fetches no packages. The remaining commands observe or modify this disposable local host:
bin/richt inventory validate -i examples/vmango/inventory.yaml
bin/richt inventory show -i examples/vmango/inventory.yaml
bin/richt diff -i examples/vmango/inventory.yaml -o /root/vmango-install.json
bin/richt apply -y /root/vmango-install.json
rpm -q vmango
systemctl is-active vmango.service
systemctl is-enabled vmango.service
curl --fail --silent --output /dev/null http://127.0.0.1:18080/
bin/richt diff -i examples/vmango/inventory.yaml
The second diff should have no changes. Richt verifies systemd’s running state;
the separate HTTP request checks that an HTTP response is served, without
claiming application or hypervisor readiness. For startup diagnostics use
journalctl -u vmango.service --no-pager -n 50.
Exact upgrade, downgrade, and config reaction
The pinned initial version is 0:0.16.0-1.el10.x86_64. Repository primary
metadata read on 2026-11-01 also contained 0:0.12.3-1.el10.x86_64,
0:0.15.0-1.el10.x86_64, and 0:0.17.0-1.el10.x86_64.
Repository metadata
is mutable; if a version is no longer available, inspect available published
versions before selecting another compatible pair. Never replace this step
with a locally built fixture RPM.
Edit examples/vmango/services/vmango.yaml: change the exact version from
0:0.16.0-1.el10.x86_64 to 0:0.17.0-1.el10.x86_64, then:
bin/richt diff -i examples/vmango/inventory.yaml -o /root/vmango-upgrade.json
bin/richt apply -y /root/vmango-upgrade.json
rpm -q vmango
systemctl is-active vmango.service
Change it back to 0:0.16.0-1.el10.x86_64 and repeat with a new plan path
/root/vmango-downgrade.json. DNF’s exact installation request permits a
downgrade as well as an upgrade. Omitting version instead keeps any installed
version; it does not request the latest available package.
For a config-only change, record the service’s InvocationID, change
log_level: info to log_level: debug in examples/vmango/inventory.yaml,
prepare and apply a new plan, then compare:
systemctl show vmango.service -p InvocationID
bin/richt diff -i examples/vmango/inventory.yaml -o /root/vmango-config.json
bin/richt apply -y /root/vmango-config.json
systemctl show vmango.service -p InvocationID
bin/richt diff -i examples/vmango/inventory.yaml
The diff displays the config change and restart branch. The invocation changes when the running process is restarted. A stopped process receives start only; there is no extra restart after that start. For failure/continuation without packages, use the separate config-only example .
Explicit removal
Set state: absent on both assignments under tags.example.services in
examples/vmango/inventory.yaml, keeping service definition orders 10 and 20. Then:
bin/richt diff -i examples/vmango/inventory.yaml -o /root/vmango-remove.json
bin/richt apply -y /root/vmango-remove.json
rpm -q vmango
systemctl is-active vmango.service
bin/richt diff -i examples/vmango/inventory.yaml
The RPM query and active check are expected to return nonzero after removal.
Richt removes the declared repository file, stops/disables the process,
removes its config, then removes its package. Package removal uses the
installed RPM database and does not require the removed repository file.
A missing assignment alone never removes resources. Application state,
package-manager dependencies, possible .rpmsave files, generated keys, imported
RPM signing keys, and saved plans are not purged by Richt. Restore the example
files’ original version, log level, and present assignments before another run.
Validation status: the published-package lifecycle passed on 2026-11-01 on AlmaLinux 10.2 x86_64 with DNF 4.20.0, systemd 257 and SELinux Enforcing. Install, no-op, unversioned preservation, exact upgrade/downgrade, config restart, independent stopped/enablement states and explicit removal were exercised. See the acceptance report for dependency prerequisites, evidence, cleanup and limits.