From d6ee28fa1143454544f25ef0fd53792968b79024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Sat, 11 Jul 2026 19:25:19 -0300 Subject: [PATCH 1/4] feat(packaging): add xcat-release repository package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Vinícius Ferrão <2031761+viniciusferrao@users.noreply.github.com> --- buildrpms.pl | 21 ++++- .../install-guides/yum/configure_xcat.rst | 12 +-- xCAT-test/unit/xcat_release_package.t | 76 ++++++++++++++++ xcat-release/RPM-GPG-KEY-xCAT | 89 +++++++++++++++++++ xcat-release/xcat-core.repo | 6 ++ xcat-release/xcat-dep.repo | 6 ++ xcat-release/xcat-release.spec | 34 +++++++ 7 files changed, 237 insertions(+), 7 deletions(-) create mode 100644 xCAT-test/unit/xcat_release_package.t create mode 100644 xcat-release/RPM-GPG-KEY-xCAT create mode 100644 xcat-release/xcat-core.repo create mode 100644 xcat-release/xcat-dep.repo create mode 100644 xcat-release/xcat-release.spec diff --git a/buildrpms.pl b/buildrpms.pl index b4461ad4a..655a84b9a 100755 --- a/buildrpms.pl +++ b/buildrpms.pl @@ -134,6 +134,7 @@ my @PACKAGES = qw( xCAT-server xCAT-test xCAT-vlan + xcat-release ); my @TARGETS = ( @@ -628,6 +629,11 @@ sub createrepo_dir { # src.rpm enters the binary repomd, and index the SRPMS repo separately. sub index_repo { my ($repodir) = @_; + my $alias = "$repodir/xcat-release-latest.noarch.rpm"; + + # The stable bootstrap filename is a direct-download convenience, not a + # second package. Keep it out of repository metadata. + unlink $alias if -f $alias; say "Creating repository $repodir"; # Drop the top-level stray src.rpm and the mock logs (build.log/root.log/...) # that mock leaves in the resultdir, so the dir is directly deployable (upstream @@ -640,7 +646,20 @@ sub index_repo { sub update_repo { my ($target) = @_; - index_repo("dist/$target/rpms"); + my $repodir = "dist/$target/rpms"; + index_repo($repodir); + write_release_alias($repodir); +} + +sub write_release_alias { + my ($repodir) = @_; + my $alias = "$repodir/xcat-release-latest.noarch.rpm"; + + my @release_rpms = glob("$repodir/xcat-release-$VERSION-$RELEASE.noarch.rpm"); + if (@release_rpms == 1) { + cp $release_rpms[0], $alias; + chmod 0644, $alias; + } } sub sign_rpms { diff --git a/docs/source/guides/install-guides/yum/configure_xcat.rst b/docs/source/guides/install-guides/yum/configure_xcat.rst index 2f387d155..e4cee00d6 100644 --- a/docs/source/guides/install-guides/yum/configure_xcat.rst +++ b/docs/source/guides/install-guides/yum/configure_xcat.rst @@ -6,13 +6,14 @@ xCAT software and repo files can be obtained from: ``_, navigate to the correct subdirectory for the target machine and download the ``xcat-dep.repo`` file and copy it to ``/etc/yum.repos.d``. +The dependency repository is selected automatically from the operating-system +release and architecture reported by DNF. The installed repository files are +marked as configuration files, so package upgrades preserve local changes. Continue to the next section to install xCAT. @@ -28,4 +29,3 @@ Local Repository .. include:: ../common_sections.rst :start-after: BEGIN_configure_xcat_local_repo_xcat-dep_RPM :end-before: END_configure_xcat_local_repo_xcat-dep_RPM - diff --git a/xCAT-test/unit/xcat_release_package.t b/xCAT-test/unit/xcat_release_package.t new file mode 100644 index 000000000..4a818d8a5 --- /dev/null +++ b/xCAT-test/unit/xcat_release_package.t @@ -0,0 +1,76 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use Digest::SHA qw(sha256_hex); +use File::Spec; +use FindBin; +use Test::More; + +my $repo_root = File::Spec->rel2abs(File::Spec->catdir($FindBin::Bin, '..', '..')); + +my $spec = read_file('xcat-release/xcat-release.spec'); +like($spec, qr/^Name:\s+xcat-release$/m, 'package has the expected name'); +like($spec, qr/^BuildArch:\s+noarch$/m, 'package is architecture independent'); +like($spec, qr/^%config\(noreplace\) .*xcat-core\.repo$/m, 'core repo preserves local changes'); +like($spec, qr/^%config\(noreplace\) .*xcat-dep\.repo$/m, 'dependency repo preserves local changes'); +like($spec, qr{RPM-GPG-KEY-xCAT}, 'package installs the signing key'); + +my $core = read_file('xcat-release/xcat-core.repo'); +assert_repo_security($core, 'core'); +like( + $core, + qr{^baseurl=https://xcat\.org/files/xcat/repos/yum/latest/xcat-core$}m, + 'core repo uses the stable HTTPS endpoint' +); + +my $dep = read_file('xcat-release/xcat-dep.repo'); +assert_repo_security($dep, 'dependency'); +like( + $dep, + qr{^baseurl=https://xcat\.org/files/xcat/repos/yum/latest/xcat-dep/rh\$releasever/\$basearch$}m, + 'dependency repo follows the DNF release and architecture variables' +); + +my $key = read_file('xcat-release/RPM-GPG-KEY-xCAT'); +like($key, qr/^-----BEGIN PGP PUBLIC KEY BLOCK-----$/m, 'signing key is ASCII armored'); +is( + sha256_hex($key), + '72076f25ce4929d34a67e305327a37f89c964d3cbf1821e3afad4907c9d91249', + 'packaged key matches the published xCAT signing key' +); + +my $builder = read_file('buildrpms.pl'); +like($builder, qr/^\s+xcat-release\s*$/m, 'default RPM build includes xcat-release'); +like( + $builder, + qr/unlink \$alias.*?createrepo_dir\(\$repodir/s, + 'stable bootstrap alias is excluded from repository metadata' +); +like( + $builder, + qr/cp \$release_rpms\[0\], \$alias/, + 'repository export creates the stable bootstrap filename' +); + +done_testing(); + +sub assert_repo_security { + my ($content, $label) = @_; + like($content, qr/^enabled=1$/m, "$label repo is enabled"); + like($content, qr/^gpgcheck=1$/m, "$label repo verifies packages"); + like( + $content, + qr{^gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-xCAT$}m, + "$label repo uses the packaged signing key" + ); +} + +sub read_file { + my ($file) = @_; + my $path = File::Spec->catfile($repo_root, split m{/}, $file); + open(my $fh, '<', $path) or die "open $path: $!"; + my $contents = do { local $/; <$fh> }; + close($fh) or die "close $path: $!"; + return $contents; +} diff --git a/xcat-release/RPM-GPG-KEY-xCAT b/xcat-release/RPM-GPG-KEY-xCAT new file mode 100644 index 000000000..d5071b497 --- /dev/null +++ b/xcat-release/RPM-GPG-KEY-xCAT @@ -0,0 +1,89 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +G9DsOI3iK1B2pWUQZYMnWLCJfzQ= +=b6W6 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/xcat-release/xcat-core.repo b/xcat-release/xcat-core.repo new file mode 100644 index 000000000..206ea16ef --- /dev/null +++ b/xcat-release/xcat-core.repo @@ -0,0 +1,6 @@ +[xcat-core] +name=xCAT Core packages +baseurl=https://xcat.org/files/xcat/repos/yum/latest/xcat-core +enabled=1 +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-xCAT diff --git a/xcat-release/xcat-dep.repo b/xcat-release/xcat-dep.repo new file mode 100644 index 000000000..57e426e0d --- /dev/null +++ b/xcat-release/xcat-dep.repo @@ -0,0 +1,6 @@ +[xcat-dep] +name=xCAT dependencies +baseurl=https://xcat.org/files/xcat/repos/yum/latest/xcat-dep/rh$releasever/$basearch +enabled=1 +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-xCAT diff --git a/xcat-release/xcat-release.spec b/xcat-release/xcat-release.spec new file mode 100644 index 000000000..5e549b4b5 --- /dev/null +++ b/xcat-release/xcat-release.spec @@ -0,0 +1,34 @@ +Summary: xCAT repository configuration +Name: xcat-release +Version: %{?version:%{version}}%{!?version:%(cat Version)} +Release: %{?release:%{release}}%{!?release:%(cat Release)} +License: EPL +URL: https://xcat.org/ +Source0: xcat-release-%{version}.tar.gz +BuildArch: noarch + +%description +Installs the xCAT core and dependency repository definitions and the public +signing key used to verify their packages. + +%prep +%setup -q -n xcat-release + +%build + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}%{_sysconfdir}/yum.repos.d +mkdir -p %{buildroot}%{_sysconfdir}/pki/rpm-gpg +install -m 0644 xcat-core.repo %{buildroot}%{_sysconfdir}/yum.repos.d/xcat-core.repo +install -m 0644 xcat-dep.repo %{buildroot}%{_sysconfdir}/yum.repos.d/xcat-dep.repo +install -m 0644 RPM-GPG-KEY-xCAT %{buildroot}%{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-xCAT + +%files +%config(noreplace) %{_sysconfdir}/yum.repos.d/xcat-core.repo +%config(noreplace) %{_sysconfdir}/yum.repos.d/xcat-dep.repo +%{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-xCAT + +%changelog +* Sat Jul 11 2026 xCAT Project +- Add the xCAT repository bootstrap package From daddfe0fb9f630c2ddecf23d81fa58b352ac9fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Sat, 11 Jul 2026 19:38:31 -0300 Subject: [PATCH 2/4] fix(packaging): verify xCAT repository metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Vinícius Ferrão <2031761+viniciusferrao@users.noreply.github.com> --- xCAT-test/unit/xcat_release_package.t | 2 ++ xcat-release/xcat-core.repo | 1 + xcat-release/xcat-dep.repo | 1 + xcat-release/xcat-release.spec | 7 ++++--- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/xCAT-test/unit/xcat_release_package.t b/xCAT-test/unit/xcat_release_package.t index 4a818d8a5..a129c5144 100644 --- a/xCAT-test/unit/xcat_release_package.t +++ b/xCAT-test/unit/xcat_release_package.t @@ -12,6 +12,7 @@ my $repo_root = File::Spec->rel2abs(File::Spec->catdir($FindBin::Bin, '..', '..' my $spec = read_file('xcat-release/xcat-release.spec'); like($spec, qr/^Name:\s+xcat-release$/m, 'package has the expected name'); like($spec, qr/^BuildArch:\s+noarch$/m, 'package is architecture independent'); +like($spec, qr/^Requires:\s+dnf$/m, 'package is limited to DNF-based systems'); like($spec, qr/^%config\(noreplace\) .*xcat-core\.repo$/m, 'core repo preserves local changes'); like($spec, qr/^%config\(noreplace\) .*xcat-dep\.repo$/m, 'dependency repo preserves local changes'); like($spec, qr{RPM-GPG-KEY-xCAT}, 'package installs the signing key'); @@ -59,6 +60,7 @@ sub assert_repo_security { my ($content, $label) = @_; like($content, qr/^enabled=1$/m, "$label repo is enabled"); like($content, qr/^gpgcheck=1$/m, "$label repo verifies packages"); + like($content, qr/^repo_gpgcheck=1$/m, "$label repo verifies repository metadata"); like( $content, qr{^gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-xCAT$}m, diff --git a/xcat-release/xcat-core.repo b/xcat-release/xcat-core.repo index 206ea16ef..c6add8aa4 100644 --- a/xcat-release/xcat-core.repo +++ b/xcat-release/xcat-core.repo @@ -3,4 +3,5 @@ name=xCAT Core packages baseurl=https://xcat.org/files/xcat/repos/yum/latest/xcat-core enabled=1 gpgcheck=1 +repo_gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-xCAT diff --git a/xcat-release/xcat-dep.repo b/xcat-release/xcat-dep.repo index 57e426e0d..6da572b2d 100644 --- a/xcat-release/xcat-dep.repo +++ b/xcat-release/xcat-dep.repo @@ -3,4 +3,5 @@ name=xCAT dependencies baseurl=https://xcat.org/files/xcat/repos/yum/latest/xcat-dep/rh$releasever/$basearch enabled=1 gpgcheck=1 +repo_gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-xCAT diff --git a/xcat-release/xcat-release.spec b/xcat-release/xcat-release.spec index 5e549b4b5..2fa676237 100644 --- a/xcat-release/xcat-release.spec +++ b/xcat-release/xcat-release.spec @@ -1,4 +1,4 @@ -Summary: xCAT repository configuration +Summary: xCAT DNF repository configuration Name: xcat-release Version: %{?version:%{version}}%{!?version:%(cat Version)} Release: %{?release:%{release}}%{!?release:%(cat Release)} @@ -6,10 +6,11 @@ License: EPL URL: https://xcat.org/ Source0: xcat-release-%{version}.tar.gz BuildArch: noarch +Requires: dnf %description -Installs the xCAT core and dependency repository definitions and the public -signing key used to verify their packages. +Installs the xCAT core and dependency DNF repository definitions and the public +signing key used to verify their packages and repository metadata. %prep %setup -q -n xcat-release From ea490e9d486b13fee6699b51722fc049713701fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Sat, 11 Jul 2026 19:48:19 -0300 Subject: [PATCH 3/4] fix(packaging): create release alias after signing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Vinícius Ferrão <2031761+viniciusferrao@users.noreply.github.com> --- buildrpms.pl | 8 +++++++- xCAT-test/unit/xcat_release_package.t | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/buildrpms.pl b/buildrpms.pl index 655a84b9a..2d9de0859 100755 --- a/buildrpms.pl +++ b/buildrpms.pl @@ -648,7 +648,6 @@ sub update_repo { my ($target) = @_; my $repodir = "dist/$target/rpms"; index_repo($repodir); - write_release_alias($repodir); } sub write_release_alias { @@ -783,6 +782,7 @@ sub finalize_core { sign_repo_dir($dir, $opts{gpg_key_name}); } write_repo_metadata_dir($dir); + write_release_alias($dir); return 0; } @@ -835,6 +835,12 @@ sub main { write_repo_metadata($target); } + # Signing regenerates repository metadata, so create the direct-download + # alias only after the final metadata pass. + for my $target ($opts{targets}->@*) { + write_release_alias("dist/$target/rpms"); + } + exit(0); } diff --git a/xCAT-test/unit/xcat_release_package.t b/xCAT-test/unit/xcat_release_package.t index a129c5144..e5f0acbdb 100644 --- a/xCAT-test/unit/xcat_release_package.t +++ b/xCAT-test/unit/xcat_release_package.t @@ -53,6 +53,17 @@ like( qr/cp \$release_rpms\[0\], \$alias/, 'repository export creates the stable bootstrap filename' ); +my $sign_call = rindex($builder, 'sign_rpms($target)'); +my $alias_call = rindex($builder, 'write_release_alias("dist/$target/rpms")'); +ok( + $sign_call >= 0 && $alias_call > $sign_call, + 'stable bootstrap alias is created after signed metadata is finalized' +); +like( + $builder, + qr/sub finalize_core \{.*?write_repo_metadata_dir\(\$dir\);.*?write_release_alias\(\$dir\);/s, + 'assembled core repository creates the stable alias after final metadata' +); done_testing(); From 99d76dae6c915b4bb65cd980ca94d3c3dae17f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:05:08 -0300 Subject: [PATCH 4/4] fix: capitalize xCAT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Vinícius Ferrão <2031761+viniciusferrao@users.noreply.github.com> --- buildrpms.pl | 8 +++---- .../install-guides/yum/configure_xcat.rst | 4 ++-- .../RPM-GPG-KEY-xCAT | 0 .../xCAT-release.spec | 6 ++--- {xcat-release => xCAT-release}/xcat-core.repo | 0 {xcat-release => xCAT-release}/xcat-dep.repo | 0 xCAT-test/unit/xcat_release_package.t | 23 ++++++++++++++----- 7 files changed, 26 insertions(+), 15 deletions(-) rename {xcat-release => xCAT-release}/RPM-GPG-KEY-xCAT (100%) rename xcat-release/xcat-release.spec => xCAT-release/xCAT-release.spec (92%) rename {xcat-release => xCAT-release}/xcat-core.repo (100%) rename {xcat-release => xCAT-release}/xcat-dep.repo (100%) diff --git a/buildrpms.pl b/buildrpms.pl index 2d9de0859..f6d3ed4db 100755 --- a/buildrpms.pl +++ b/buildrpms.pl @@ -134,7 +134,7 @@ my @PACKAGES = qw( xCAT-server xCAT-test xCAT-vlan - xcat-release + xCAT-release ); my @TARGETS = ( @@ -629,7 +629,7 @@ sub createrepo_dir { # src.rpm enters the binary repomd, and index the SRPMS repo separately. sub index_repo { my ($repodir) = @_; - my $alias = "$repodir/xcat-release-latest.noarch.rpm"; + my $alias = "$repodir/xCAT-release-latest.noarch.rpm"; # The stable bootstrap filename is a direct-download convenience, not a # second package. Keep it out of repository metadata. @@ -652,9 +652,9 @@ sub update_repo { sub write_release_alias { my ($repodir) = @_; - my $alias = "$repodir/xcat-release-latest.noarch.rpm"; + my $alias = "$repodir/xCAT-release-latest.noarch.rpm"; - my @release_rpms = glob("$repodir/xcat-release-$VERSION-$RELEASE.noarch.rpm"); + my @release_rpms = glob("$repodir/xCAT-release-$VERSION-$RELEASE.noarch.rpm"); if (@release_rpms == 1) { cp $release_rpms[0], $alias; chmod 0644, $alias; diff --git a/docs/source/guides/install-guides/yum/configure_xcat.rst b/docs/source/guides/install-guides/yum/configure_xcat.rst index e4cee00d6..fba2ec140 100644 --- a/docs/source/guides/install-guides/yum/configure_xcat.rst +++ b/docs/source/guides/install-guides/yum/configure_xcat.rst @@ -6,10 +6,10 @@ xCAT software and repo files can be obtained from: `rel2abs(File::Spec->catdir($FindBin::Bin, '..', '..')); -my $spec = read_file('xcat-release/xcat-release.spec'); -like($spec, qr/^Name:\s+xcat-release$/m, 'package has the expected name'); +my $spec = read_file('xCAT-release/xCAT-release.spec'); +like($spec, qr/^Name:\s+xCAT-release$/m, 'package has the expected name'); +like($spec, qr/^Source0:\s+xCAT-release-%\{version\}\.tar\.gz$/m, 'source archive follows the package name'); like($spec, qr/^BuildArch:\s+noarch$/m, 'package is architecture independent'); like($spec, qr/^Requires:\s+dnf$/m, 'package is limited to DNF-based systems'); like($spec, qr/^%config\(noreplace\) .*xcat-core\.repo$/m, 'core repo preserves local changes'); like($spec, qr/^%config\(noreplace\) .*xcat-dep\.repo$/m, 'dependency repo preserves local changes'); like($spec, qr{RPM-GPG-KEY-xCAT}, 'package installs the signing key'); -my $core = read_file('xcat-release/xcat-core.repo'); +my $core = read_file('xCAT-release/xcat-core.repo'); assert_repo_security($core, 'core'); like( $core, @@ -25,7 +26,7 @@ like( 'core repo uses the stable HTTPS endpoint' ); -my $dep = read_file('xcat-release/xcat-dep.repo'); +my $dep = read_file('xCAT-release/xcat-dep.repo'); assert_repo_security($dep, 'dependency'); like( $dep, @@ -33,7 +34,7 @@ like( 'dependency repo follows the DNF release and architecture variables' ); -my $key = read_file('xcat-release/RPM-GPG-KEY-xCAT'); +my $key = read_file('xCAT-release/RPM-GPG-KEY-xCAT'); like($key, qr/^-----BEGIN PGP PUBLIC KEY BLOCK-----$/m, 'signing key is ASCII armored'); is( sha256_hex($key), @@ -42,7 +43,17 @@ is( ); my $builder = read_file('buildrpms.pl'); -like($builder, qr/^\s+xcat-release\s*$/m, 'default RPM build includes xcat-release'); +like($builder, qr/^\s+xCAT-release\s*$/m, 'default RPM build includes xCAT-release'); +like( + $builder, + qr{\$repodir/xCAT-release-latest\.noarch\.rpm}, + 'stable bootstrap alias follows the package name' +); +like( + $builder, + qr{\$repodir/xCAT-release-\$VERSION-\$RELEASE\.noarch\.rpm}, + 'stable bootstrap alias selects the xCAT-release RPM' +); like( $builder, qr/unlink \$alias.*?createrepo_dir\(\$repodir/s,