Handle Repo-less RPMs
Some packages on your system may have no repository source – they were installed from a local .rpm file, their original repo was disabled, or the repo was removed after installation. inspectah detects these automatically and provides a path to include them in your migration.
How detection works
During the scan, inspectah compares each package’s install-time repository against the list of currently enabled repos (dnf repolist --enabled). A package is flagged as repo-less when:
- Its
source_repofield is empty (locally installed RPM) - Its
source_reponames a repository not in the enabled list
For each repo-less package, inspectah searches /var/cache/dnf/ for a cached .rpm file matching the package NEVRA (name-version-release.arch). Matching uses case-insensitive substring comparison to handle short name vs. full repo ID differences (e.g., AppStream vs. rhel-9-for-aarch64-appstream-rpms).
What you get
After the scan, repo-less packages fall into two categories:
| Status | Meaning | Containerfile rendering |
|---|---|---|
| Cached | .rpm found in /var/cache/dnf/ | COPY + dnf localinstall (commented-out by default) |
| Missing | No cached .rpm available | MANUAL comment with the package NEVRA |
Cached RPM example
# === Repo-less RPM packages ===
# Repo-less package: custom-tool (cached RPM, no repository provenance)
# WARNING: This package has no upstream repo and no GPG verification.
# It was found in the dnf cache but cannot be reinstalled from a repository.
# Uncomment to install from the bundled RPM.
# COPY repoless-packages/custom-tool-1.2.3-1.el9.x86_64.rpm /tmp/
# RUN dnf localinstall -y /tmp/custom-tool-1.2.3-1.el9.x86_64.rpm && rm /tmp/custom-tool-1.2.3-1.el9.x86_64.rpm
Cached RPMs are bundled in the tarball under repoless-packages/.
Missing RPM example
# Repo-less package: legacy-app (MANUAL — no cached RPM found)
# NEVRA: legacy-app-3.0-1.el9.x86_64
# ACTION REQUIRED: Obtain the RPM and upload it in the refine UI,
# or add a repository that provides this package.
Providing missing RPMs
Single upload
In the refine UI, repo-less packages with missing RPMs show an upload button. Click it to open the upload modal, then drag and drop (or browse for) the .rpm file.
The upload endpoint validates:
- File has a
.rpmextension - File matches the expected package by
name.arch(non-NEVRA filenames are accepted as long as the name and architecture match) - File size is under 500 MiB
After upload, the package status changes from MANUAL to cached, and the Containerfile preview updates to show the COPY + dnf localinstall directives.
Batch upload
When multiple repo-less packages need RPMs, use the batch upload modal. It shows a checklist of all packages needing RPMs with live match progress. Drop multiple .rpm files at once – inspectah auto-matches each file to its package by name.arch.
The batch view shows:
- Packages still needing RPMs (grey)
- Packages matched to an uploaded file (green)
- Conflicts when an uploaded file does not match any expected package
Including cached RPMs
Cached RPMs (whether from the dnf cache or uploaded) are pre-excluded by default. To include them in your Containerfile:
- Open the refine UI
- Navigate to the Packages section
- Find the repo-less package (it has a “repo-less” annotation)
- Toggle it to included
The Containerfile preview updates immediately to show active (not commented-out) COPY and dnf localinstall directives.
Alternatives to bundling RPMs
Bundling RPMs works for one-off packages, but consider these alternatives for a more maintainable image:
- Add the repository to your Containerfile and install via
dnf install. This gives you update coverage. - Rebuild the package for a supported repository if the source is available.
- Replace the package with an equivalent from an enabled repository if one exists.
The repo-less detection is a safety net – it ensures you know about every package that cannot be reinstalled from a repo, so nothing falls through the cracks during migration.