Skip to content

feat(packaging): add amdrocm-repo package for ROCm repository setup - #7269

Open
lsudarsh-amd wants to merge 8 commits into
mainfrom
shared/amdrocm-repo-package
Open

lsudarsh-amd wants to merge 8 commits into
mainfrom
shared/amdrocm-repo-package

Conversation

@lsudarsh-amd

@lsudarsh-amd lsudarsh-amd commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Installing ROCm today needs a manual repository setup. The user has to fetch and dearmor the AMD signing key, write a sources or repo file by hand, and look up the correct URL for their distribution and release line.

This change adds amdrocm-repo, a repo configuration package that replaces that multi-step manual setup. Once it is installed, ROCm can be installed and updated with the native package manager.

This is the first of four pull requests:

Contributes to #6986.

Technical Details

build_repo_package.py renders the package from the Jinja templates under template/repo/. It builds one package per OS profile (ubuntu2404, rhel8, rhel10, sles16) and release line (prerelease, release, nightly).

Repository URLs are derived per release line. The lines do not share a layout. Prerelease and release publish one repository per distribution. Nightly publishes one per package type, under a dated sub-folder. repo_baseurl() selects the correct form. It branches on the release line rather than on whether the line is signed, because those two properties are independent even though they correlate today.

The package version carries the release line. Two lines can therefore never produce an identically named package. Without this, installing the release package over the prerelease one at the same ROCm version reports success and silently leaves the old repository configured.

The signing key is fetched at build time. For signed lines it is retrieved over https, size-bounded, checked against a pinned fingerprint, and embedded in the package. It is never stored in the source tree. The nightly repository is unsigned upstream, so nightly packages ship no key and disable signature checking.

The package conflicts with amdgpu-install, which configures a different ROCm repository and raises it above the default priority. Its repository files use different names from ours, so nothing else stops both being installed, and its repository then wins resolution silently. On apt the conflict is settled by removing amdgpu-install, which leaves its configuration files behind. The deb postinst detects that state and tells the user to run apt purge. dnf and zypper refuse the pair outright and remove their %config files on erase, so no equivalent is needed there.

Nothing builds the repo packages yet. The script writes finished packages to --dest-dir and is run once per profile and release line. The workflow that calls it is in the third pull request; until then it is invoked by hand, as the documentation describes. Each format needs its own tooling, dpkg-buildpackage for deb and rpmbuild for rpm, so the CI job added later builds each profile in a container that has it.

build_tools/.gitignore is deleted. Its only entry was an unanchored repo pattern, which would hide the entire new template/repo/ directory from git. The tool it guarded was removed in #128.

Notes for reviewers

  • repo_baseurl() derives the same URLs as get_repo_url_multi_arch() in get_url_repo_params.py, from the same five inputs. Where the two differ it is only a trailing slash, which this one adds on the deb URLs and on nightly rpm. They are not merged here because their base-URL contracts differ: that function takes a scheme and host and appends the layout segments itself, while this one requires them already present. That file is also on the next pull request's path, which is where the two are reconciled.
  • list-profiles has no caller until the CI pull request. Unit tests cover it in the meantime.
  • The test file sits in build_tools/tests/ rather than packaging/linux/tests/, where the other tests for that module's directory live. build_tools/tests/ is already in testpaths, so these tests run in CI from the first push, including on the Windows leg. No module name collides on the path the file inserts.
  • The root-ownership directives in rules.j2 and the spec are convention alignment, not bug fixes. Building as a non-root user already produces root:root. They are stated so that behaviour cannot change silently, and to match the other ROCm packages.
  • No apt pin or priority= is shipped; the package sits at each manager's default. amdgpu-install pins its own repository above the default, so an equivalent here would mean bidding above another AMD package rather than resolving anything. Its pin also covers every package from that origin, so matching it would elevate this whole CDN over the distribution's own repositories. The conflict declaration, and the purge the postinst points at, address the overlap directly instead. Happy to add a pin if you would prefer one.
  • RELEASE_TYPES covers three of the five canonical release types. ci has no published repository to point at, and dev is deferred until there is a reason to ship one.

Test Plan

All testing ran in containers.

  • Built the package for all four OS profiles, signed and unsigned, and inspected each payload with dpkg-deb -c or rpm -qp.
  • Installed the package on ubuntu2404, rhel8, rhel10 and sles16, refreshed metadata against the live prerelease repository, and resolved the amdrocm package.
  • Tested the amdgpu-install conflict in both directions on both formats, using the real amdgpu-install 31.40 packages, then repeated it on each format with the declaration removed as a control.
  • Installed the deb against all four amdgpu-install states: not installed, installed, removed but not purged, and purged.
  • Ran the documented install, verification and build commands.
  • Ran the unit tests with networking disabled, and again with the module's path handling bound to the Windows flavour.
  • Ran pre-commit, shellcheck, and the full unit test suite.

Test Result

Check Result
New unit tests 106 pass, 1 skip. The skip needs a locale no standard image provides.
Full suite 1747 passing before, 1853 after. The delta is exactly the new test file.
Package payload Correct on all four profiles. Every file lands at its documented path, owned by root:root.
Signing key The pinned fingerprint matched on every build that fetches the key.
Live repository Metadata refreshes on all four profiles and amdrocm resolves. apt-get update verifies the repository signature, and rpm --checksig reports digests signatures OK.
Documented commands All ran as written. zypper needs --allow-unsigned-rpm for a locally built file, which the documentation states.
Conflict enforcement Refused in both directions on both formats.
Conflict controls With the declaration removed, both packages install together and two then own competing repository files.
postinst Warns only in the removed-but-not-purged state, and never fails an install. With amdgpu-install present the conflict refuses the install before the scriptlet runs.
Networking disabled 106 pass, so no unit test reaches the network.
Windows path handling Binding the Windows flavour makes the keyring test fail, so a regression there would be caught.
pre-commit, shellcheck Clean.

Three tests fail on this branch. They also fail on main without this change, all three are in build_tools/github_actions/, which this pull request does not touch, and the failure set is identical either way.

Submission Checklist

@therock-pr-bot

therock-pr-bot Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass —
🔎 pre-commit ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —
🤖 therock-pr-bot ✅ Pass —

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

Adds a configuration package pointing apt, dnf, or zypper at a public
ROCm repository, so ROCm installs and updates through the native package
manager instead of a manual multi-step setup.

One package is generated per OS profile and release line. The version
carries the line, so packages from different lines are never confusable,
and URL derivation is isolated in one function because the published
layout is expected to change. For signed lines the signing key is
fetched and fingerprint-checked at build time; it is never stored in the
source tree.

It conflicts with amdgpu-install, whose competing ROCm repository uses
different filenames and sits above the default priority, so nothing
else would stop it silently winning. On apt that conflict is settled by
removal, which leaves the configuration behind — hence the deb postinst
pointing at "apt purge".

build_tools/.gitignore is removed: its unanchored "repo" pattern would
hide the new template/repo/ tree from git, and the tool it guarded is
long gone.
ROCm 10 ships from <stream>.repo.amd.com. The legacy packages-multi-arch
release line is frozen at ROCm 7.14, so a package built against it
points users three releases back.

Streams are modelled by layout shape, not name: flat (stable) serves one
repository per distro, per-build (nightly) adds a YYYYMMDD-runid
segment. Signing follows from the shape rather than a parallel list, so
the two cannot drift apart.

  --release-type prerelease  ->  --stream stable
  amdrocm.sources            ->  amdrocm-<stream>.sources

The stream in the filename stops one stream's package silently replacing
another's config. The key is passed whole via --gpg-key-url; it sits
outside the packages base and cannot be derived from it. The deb822 file
gains X-Repo-Id and Enabled, matching the published install
instructions.

rc is absent: it resolves but serves no content, so a package pointing
there would install and then find nothing.

Verified in containers across ubuntu2404/rhel8/rhel10/sles16 on both
streams: build, install, clean refresh, signature check, amdrocm
10.0.0-4.
@lsudarsh-amd
lsudarsh-amd force-pushed the shared/amdrocm-repo-package branch from 71cbd7b to de7e7b4 Compare August 28, 2026 16:23
@therock-pr-bot

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

Comment thread build_tools/packaging/linux/build_repo_package.py Fixed
@dbieleck

Copy link
Copy Markdown

Folks, let's move this along this week. Thanks.

Ubuntu:

```bash
sudo apt install ./repo-package-out/amdrocm-repo_*_all.deb

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the repo packages are merged might have to update these steps in the RELEASES.md file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree. amdrocm-repo has no public download URL yet, so those steps would not be actionable until the publish side lands. I have left RELEASES.md alone here and will update it as a follow up once the package is reachable.

Comment thread build_tools/.gitignore
@@ -1 +0,0 @@
repo

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a oversight change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is deliberate. Scott asked for the file to be removed rather than edited in #6901, since the repo tool it guarded has been unused since #128. Its bare repo pattern would also have matched the new template/repo/ directory and hidden those files.

embedded in the package; it is never stored in the source tree.

```
python build_repo_package.py \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With these parameters, looks like the package created will be amdrocm-repo_10.0.0_all.deb Which is not as per the packaging name standard.
amdrocm-_-<build_no>_amd64.deb

Also the package name will be same for ubuntu2404, ubuntu2604, debian10 or any other debian os flavors.

One possibility is to name the packages something like this.

10.0.0-1~noble1      # Ubuntu 24.04 (Noble)
10.0.0-1~jammy1       # Ubuntu 22.04 (Jammy)
10.0.0-1~bookworm1    # Debian 12

Another option would be to have one deb package which has all the config for all deb flavors and install only the correct one checking the OS version

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this. Deb now builds as:

amdrocm-repo_10.0.0-1~ubuntu2404_all.deb
amdrocm-repo_20260716.12345-1~ubuntu2404_all.deb    (nightly)

For the distro token I used the OS-profile name rather than a codename, to keep things consistent with the directory names and to avoid maintaining a codename mapping.

I applied the same fix to rpm, where %{?dist} is empty on SUSE, so sles15 and sles16 would have collided once a second SUSE profile was added. RHEL package names are unchanged.

I avoided taking the second approach you suggested regarding a single deb choosing config at install time, since it needs OS detection in a maintainer script and the repository URL is already per distro.

--stream stable \
--repo-base-url https://stable.repo.amd.com/rocm/core/packages \
--rocm-version 10.0.0 \
--dest-dir ./output

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the parameter handling is bit complicated. Can you give more samples and the expected output(package name and version) for better review?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module docstring and docs/packaging/rocm_repo_setup.md have been updated to both carry the naming rule and a worked examples table. All rows use --rocm-version 10.0.0 and the default --version-suffix. The nightly rows add --repo-sub-folder 20260716-12345.

--os-profile --stream Resulting file
ubuntu2404 stable amdrocm-repo_10.0.0-1~ubuntu2404_all.deb
ubuntu2404 rc amdrocm-repo_10.0.0~pre-1~ubuntu2404_all.deb
ubuntu2404 nightly amdrocm-repo_20260716.12345-1~ubuntu2404_all.deb
rhel8 stable amdrocm-repo-10.0.0-1.stable.el8.noarch.rpm
rhel8 rc amdrocm-repo-10.0.0-1.rc.el8.noarch.rpm
rhel8 nightly amdrocm-repo-20260716-12345.1.nightly.el8.noarch.rpm
rhel10 stable amdrocm-repo-10.0.0-1.stable.el10.noarch.rpm
sles16 stable amdrocm-repo-10.0.0-1.stable.sles16.noarch.rpm


%changelog
* {{ changelog_date }} {{ maintainer }} - {{ version }}-{{ release }}
- ROCm {{ rocm_version }} repository configuration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rpm is not having a post install script like debian. Which is a difference in package behavior

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rpm now has a post install script. It prints the same message the deb postinst does, with the refresh command for each family: sudo dnf makecache or sudo zypper refresh. I confirmed the message reaches the user on both dnf install and zypper install.

amdrocm-repo produced one filename for every debian-family profile and
carried no build number:

  amdrocm-repo_10.0.0_all.deb -> amdrocm-repo_10.0.0-1~ubuntu2404_all.deb

The token is the os-profile name, not a Debian codename, which would not
sort: bullseye ranks above bookworm. rpm takes it from an explicit
dist_tag rather than %{?dist}, which reads the build host and is empty on
SUSE; RHEL names are unchanged.

rc is now built, reversing an earlier commit that skipped it for serving
no content: RFC0012 requires stable and rc at v1. Also adds a
message-only %post mirroring the deb postinst.
The key check only looked at the first key in the downloaded file, so a
file with an extra key appended still passed and both keys ended up
trusted. Now the file must contain just the pinned key, and only that
key is embedded. The tests use real gpg instead of mocks.

The docs said installing another stream's deb over the current one
switches repos. It doesn't: the old .sources stays behind. They now say
to purge first on Ubuntu, and to use --oldpackage on SLES.

Also swaps a link to an internal repo for the public install docs,
fixes the --repo-base-url help, and corrects a few wrong comments.
@lsudarsh-amd

Copy link
Copy Markdown
Contributor Author

@nunnikri Thanks for the initial review. I've made some changes since then:

  • Package names include the distro and a build number (--version-suffix, default 1): amdrocm-repo_10.0.0-1~ubuntu2404_all.deb, amdrocm-repo-10.0.0-1.stable.el8.noarch.rpm. Examples are in the docs.
  • rpm %post now prints a refresh message, like the deb postinst.
  • Signing key: the check only looked at the first key in the file. Now the file must contain only the pinned key, and only that key is embedded.
  • Docs: purge before switching streams on Ubuntu, use --oldpackage on SLES, and use apt purge to remove. Plus a few text fixes.
  • rc stream: can now be built.

@lsudarsh-amd
lsudarsh-amd added this pull request to stack #8646 September 30, 2026 19:12

@arvindcheru arvindcheru left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Thank you.

  • Verified the install Test FULL (ub24/rhel/sles), uninstall, no-gpg install_test on shared/amdrocm-repo-ci @ a0bfec8
  • Uninstall: Must exclude/handle amdrocm-repo before CI enablement.
  • (non-blocking): refresh PR body to streams stable/rc/nightly (instead of prerelease/release);

Please hold merge until existing/pending review threads are re-acked.

This branch has not been deployed

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

Labels

None yet

Projects

Status: TODO

Development

Successfully merging this pull request may close these issues.

5 participants