2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-07-31 18:19:40 +00:00

Merge pull request #7584 from VersatusHPC/feat/xcat-release-rpm

feat: add xCAT-release package for DNF systems
This commit is contained in:
Vinícius Ferrão
2026-07-17 15:32:11 -03:00
committed by GitHub
7 changed files with 270 additions and 7 deletions
+26 -1
View File
@@ -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,19 @@ sub index_repo {
sub update_repo {
my ($target) = @_;
index_repo("dist/$target/rpms");
my $repodir = "dist/$target/rpms";
index_repo($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 {
@@ -764,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;
}
@@ -816,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);
}
@@ -6,13 +6,14 @@ xCAT software and repo files can be obtained from: `<http://xcat.org/download.ht
Internet Repository
-------------------
**[xcat-core]**
Install ``xCAT-release`` to configure both the ``xcat-core`` and ``xcat-dep``
repositories and their signing key::
For the xCAT version you want to install, download the ``xcat-core.repo`` file and copy it to ``/etc/yum.repos.d``
dnf install https://xcat.org/files/xcat/repos/yum/latest/xcat-core/xCAT-release-latest.noarch.rpm
**[xcat-dep]**
From the `xCAT-dep Online Repository <http://xcat.org/files/xcat/repos/yum/xcat-dep/>`_, 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
+89
View File
@@ -0,0 +1,89 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
G9DsOI3iK1B2pWUQZYMnWLCJfzQ=
=b6W6
-----END PGP PUBLIC KEY BLOCK-----
+35
View File
@@ -0,0 +1,35 @@
Summary: xCAT DNF 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
Requires: dnf
%description
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
%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 <xcat-user@lists.sourceforge.net>
- Add the xCAT repository bootstrap package
+7
View File
@@ -0,0 +1,7 @@
[xcat-core]
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
+7
View File
@@ -0,0 +1,7 @@
[xcat-dep]
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
+100
View File
@@ -0,0 +1,100 @@
#!/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/^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');
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{\$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,
'stable bootstrap alias is excluded from repository metadata'
);
like(
$builder,
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();
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,
"$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;
}