2
0
mirror of https://github.com/xcat2/xcat-dep.git synced 2026-09-12 12:36:23 +00:00

Merge pull request #66 from VersatusHPC/feature/riscv64

feat(xcat-dep): build the EL10 riscv64 dependency repository
This commit is contained in:
Daniel Hilst
2026-09-02 09:15:57 -03:00
committed by GitHub
24 changed files with 988 additions and 237 deletions
+132
View File
@@ -293,6 +293,138 @@ Because of this, to build `ppc64le` artifacts you must run `mockbuild-all.pl` on
In short: build `ppc64le` packages on a Power machine.
# riscv64 (EL10): cross-building on an x86_64 host
There is no riscv64 build host in the xCAT build farm and no EPEL for riscv64, so the
EL10 riscv64 dependency repository (`rh10/riscv64`) is cross-built on an x86_64 host:
mock runs a Rocky Linux 10 riscv64 chroot through user-mode QEMU (`forcearch`), so the
packages are compiled by the riscv64 toolchain of the chroot itself. The mock
configuration for that chroot is shipped in this repository:
- `mock-configs/rocky-10-riscv64-xcat.cfg`
It includes the stock `templates/rocky-10.tpl` from mock-core-configs (Rocky 10 BaseOS,
AppStream, CRB and extras for `$basearch` = riscv64) and sets
`root = 'rocky-10-riscv64-xcat'`, `target_arch = 'riscv64'`,
`legal_host_arches = ('x86_64', 'riscv64')` and `forcearch = 'riscv64'`. The stock
`rocky-10-riscv64.cfg` cannot be used from an x86_64 host (it only admits a riscv64 host
and names its chroot `rocky-10-x86_64`).
## Host prerequisites
On an x86_64 EL10 host with the baseline tooling from "Prerequisites":
- `mock` (>= 5) and `mock-core-configs` providing `templates/rocky-10.tpl` and
`rocky-10-x86_64.cfg` (the native, EPEL-free Rocky 10 chroot used for the noarch
packages of the riscv64 build), `podman` (mock pulls the Rocky 10 bootstrap image),
`golang` (goconserver is cross-compiled on the host with `GOARCH=riscv64`).
- A static user-mode QEMU for riscv64 registered in `binfmt_misc` with the `F` (fix
binary) flag. On Fedora this is the `qemu-user-static-riscv` package. EL10 has no such
package: copy `/usr/bin/qemu-riscv64-static` out of a Fedora container (for example
`registry.fedoraproject.org/fedora:44` with `dnf install qemu-user-static-riscv`) to
`/usr/local/bin/qemu-riscv64-static` on the host, then register it:
```text
# /etc/binfmt.d/qemu-riscv64-static.conf
:qemu-riscv64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-riscv64-static:FP
```
```bash
systemctl restart systemd-binfmt
cat /proc/sys/fs/binfmt_misc/qemu-riscv64 # enabled, flags: PF
```
- mock refuses `forcearch` unless `/usr/bin/qemu-riscv64-static` exists (it only checks
for the file; the kernel runs the interpreter registered above). When the binary lives
in `/usr/local/bin`, a symlink is enough:
```bash
ln -s /usr/local/bin/qemu-riscv64-static /usr/bin/qemu-riscv64-static
```
Validate the host before building (all as root; mock also accepts members of the `mock`
group):
```bash
podman run --rm --arch riscv64 quay.io/rockylinux/rockylinux:10 uname -m # riscv64
install -m 644 mock-configs/rocky-10-riscv64-xcat.cfg /etc/mock/
mock -r rocky-10-riscv64-xcat --init # ~3-4 min
mock -r rocky-10-riscv64-xcat --chroot -- uname -m # riscv64
```
The per-package `mockbuild.pl` scripts reference the target by name only
(`include('/etc/mock/<target>.cfg')` in their deterministic overlay), so the config must
live in `/etc/mock/` for a build.
Emulated builds are slow: a chroot init takes 3-4 minutes and a C or XS build 5-30
minutes instead of seconds, so the riscv64 build of the dependency set takes on the order
of an hour on a large host. Chroots and caches live under `/var/lib/mock` and
`/var/cache/mock` as for any other mock target (about 1 GB per per-package chroot).
## Building and deploying `rh10/riscv64`
`mockbuild-all.pl` knows `rocky-10-riscv64-xcat` as a *forcearch target* (see
`%forcearch_targets` in the script): it is selected with `--target` only (the default
rh8/rh9/rh10 run stays the host arch), installs the shipped config into `/etc/mock/` if
missing, and then builds:
| what | how |
|---|---|
| ipmitool-xcat, conserver-xcat | `mock --rebuild` in the riscv64 chroot (emulated), `--target-arch riscv64` |
| goconserver | cross-compiled on the host (`GOARCH=riscv64`), packaged with `rpmbuild --target riscv64` |
| grub2-xcat (noarch) | built in the native, EPEL-free `rocky-10-x86_64` chroot |
| perl list6 + EPEL gap (`--epel-gap`) | `mockbuild-perl-packages.pl --target-arch riscv64 --noarch-mock-cfg rocky-10-x86_64 --epel-gap`: XS modules in the riscv64 chroot, noarch modules in the native chroot |
| elilo-xcat, syslinux-xcat, xnba-undi | not built (x86 bootloaders) |
There is no EPEL for riscv64, so the perl deps of xCAT that EL10 otherwise takes from EPEL
are built here as well (`--epel-gap` in `mockbuild-perl-packages.pl`: perl-Crypt-Blowfish,
perl-Crypt-CBC, perl-Crypt-Rijndael, perl-Digest-SHA1, perl-Expect, perl-Mail-Sender,
perl-Net-DNS, perl-Net-IP and the build-only perl-Path-Class), and the noarch deps are
built once, natively, rather than imported from another repo. The required set asserted
after the build is ipmitool-xcat, grub2-xcat, perl-IO-Stty, perl-HTTP-Async and
perl-Net-HTTPS-NB (plus xCAT-genesis-base unless `--skip-genesis`).
Deliberately not built for riscv64:
- perl-DB_File: needs libdb, which EL10 dropped (EPEL 10 re-adds it for its own
architectures only, and Rocky Linux 10 riscv64 has no libdb at all). Only the Confluent
client of xCAT-server uses DB_File and xCAT-server only recommends perl-DB_File, so a
riscv64 management node installs without it.
- perl-SOAP-Lite: its Fedora BuildRequires (IO::SessionData, MIME::Lite, XML::Parser::Lite,
Test::XML) are EPEL-only as well, so it can neither be built nor installed without EPEL;
xCAT uses it for HP blade and VirtualBox support only.
Known differences from the EPEL-fed x86_64 repo: perl-Net-DNS is the 0.80 release of
`perl-Net-DNS/Net-DNS.spec`, built pure-perl (`--noxs`) as noarch, where EPEL 10 ships
1.47 -- its spec BuildRequires perl(Net::LibIDN2), which is EPEL-only too. A newer,
XS-free perl-Net-DNS without that BuildRequires is a follow-up. The riscv64 goconserver
binaries are stripped by the Go linker (`-ldflags "-s -w"`, cross build only) because the
host's brp-strip cannot strip a riscv64 ELF.
On a host where `/` is small, note that every per-package mock chroot (riscv64 and the
native noarch one) and its bootstrap chroot live under `/var/lib/mock` while it builds
(about 0.5-1 GB each; the bootstrap dirs stay behind after a successful build until
scrubbed), so `--max-parallel` bounds the peak disk usage as well as the CPU load.
```bash
cd <REPO_ROOT>
perl ./mockbuild-all.pl \
--target rocky-10-riscv64-xcat \
--output <OUTPUT> \
--skip-xcat --skip-genesis --skip-install \
--max-parallel 8
```
Outputs (as for every target): the build tree under `<OUTPUT>/mockbuild-all/` and the
deployable repo `<OUTPUT>/xcat-dep/rh10/riscv64/` (rpms, `repodata/`, `xcat-dep.repo` with
`baseurl=https://xcat.org/files/xcat/repos/yum/devel/xcat-dep/rh10/riscv64`,
`mklocalrepo.sh`, `buildinfo.txt`). Builder failures are tolerated and listed at the end.
The cross-built rpms are smoke-tested without installing them on the host: ipmitool-xcat,
conserver-xcat and the XS perl modules inside the emulated chroot, goconserver by running
its binaries through the binfmt handler. `--skip-install` only skips those checks and the
host installation of the noarch perl rpms (built in the native chroot); pass it when the
build host must stay untouched.
# Validation Commands
```bash
+21 -3
View File
@@ -25,6 +25,7 @@ my $version = '8.2.1';
my $work_dir = '/tmp/conserver-mockbuild';
my $mock_cfg = '';
my $target_arch = '';
my $mock_uniqueext = '';
my $result_dir = "$script_dir/../build-output/list-conserver/conserver";
my $log_dir = "$script_dir/../build-logs/list-conserver/conserver";
@@ -34,6 +35,7 @@ my $build_timestamp;
GetOptions(
'work-dir=s' => \$work_dir,
'mock-cfg=s' => \$mock_cfg,
'target-arch=s' => \$target_arch,
'mock-uniqueext=s' => \$mock_uniqueext,
'result-dir=s' => \$result_dir,
'log-dir=s' => \$log_dir,
@@ -63,12 +65,16 @@ if (!$mock_cfg) {
my ($rel) = capture('rpm -E %rhel');
$mock_cfg = "${os_id}+epel-${rel}-${arch}";
}
# Arch of the rpms --mock-cfg produces: the host arch unless the config is a forcearch (cross)
# one, e.g. rocky-10-riscv64-xcat built on x86_64 (see BUILD.md "riscv64").
$target_arch = $arch if $target_arch eq '';
my $uniq = $mock_uniqueext ne '' ? ' --uniqueext ' . sh_quote($mock_uniqueext) : '';
make_path($result_dir, $log_dir);
print "package: conserver-xcat\n";
print "version: $version\n";
print "arch: $arch\n";
print "target-arch:$target_arch\n";
print "mock-cfg: $mock_cfg\n";
print "result-dir: $result_dir\n";
@@ -96,7 +102,7 @@ print "SRPM: $srpm\n";
print "== mock --rebuild ($mock_cfg) ==\n";
my $mock_result = "$work_dir/mock-result";
make_path($mock_result);
run("mock -r " . sh_quote($mock_cfg) . $uniq
run_mock("mock -r " . sh_quote($mock_cfg) . $uniq
. " --rebuild " . sh_quote($srpm)
. " --resultdir " . sh_quote($mock_result)
. " > " . sh_quote("$log_dir/mock-rebuild.log") . " 2>&1");
@@ -104,7 +110,7 @@ run("mock -r " . sh_quote($mock_cfg) . $uniq
my @rpms = grep { $_ !~ /\.src\.rpm$/ && $_ !~ /-debug(info|source)-/ }
glob("$mock_result/*.rpm");
die "FATAL: no binary RPM produced (see $log_dir/mock-rebuild.log)\n" unless @rpms;
my ($main) = grep { basename($_) =~ /^conserver-xcat-\Q$version\E-.*\.(?:$arch|noarch)\.rpm$/ } @rpms;
my ($main) = grep { basename($_) =~ /^conserver-xcat-\Q$version\E-.*\.(?:$target_arch|noarch)\.rpm$/ } @rpms;
die "FATAL: main conserver-xcat RPM not found among: @rpms\n" unless $main;
for my $r (@rpms) {
@@ -140,8 +146,20 @@ sub capture {
chomp $out if defined $out;
return $out // '';
}
# mock exits 30 when its package manager failed (chroot init, build deps), which against public
# mirrors is most often a transient download error (stale mirror metadata): retry such a run once.
sub run_mock {
my ($cmd) = @_;
my $rc = system('bash', '-c', $cmd);
if ($rc != -1 && ($rc >> 8) == 30) {
print "mock failed with rc=30 (package manager); retrying once\n";
$rc = system('bash', '-c', $cmd);
}
die "FATAL: command failed (rc=" . ($rc >> 8) . "): $cmd\n" if $rc != 0;
return 1;
}
sub sh_quote { my ($s) = @_; $s =~ s/'/'\\''/g; return "'$s'"; }
sub usage {
return "usage: mockbuild.pl --mock-cfg <cfg> [--result-dir DIR] [--work-dir DIR]\n"
return "usage: mockbuild.pl --mock-cfg <cfg> [--target-arch ARCH] [--result-dir DIR] [--work-dir DIR]\n"
. " [--log-dir DIR] [--mock-uniqueext EXT] [--skip-install]\n";
}
Executable → Regular
+42 -2
View File
@@ -14,6 +14,7 @@ my $pkg_dir = "$repo_root/goconserver";
my $work_dir = '/tmp/goconserver-mockbuild';
my $mock_cfg = '';
my $target_arch = '';
my $mock_uniqueext = '';
my $result_dir = "$repo_root/build-output/list5/goconserver";
my $log_dir = "$repo_root/build-logs/list5/goconserver";
@@ -26,6 +27,7 @@ my $build_timestamp;
GetOptions(
'work-dir=s' => \$work_dir,
'mock-cfg=s' => \$mock_cfg,
'target-arch=s' => \$target_arch,
'mock-uniqueext=s' => \$mock_uniqueext,
'result-dir=s' => \$result_dir,
'log-dir=s' => \$log_dir,
@@ -50,6 +52,13 @@ if (!$mock_cfg) {
my ($rel) = $mock_cfg =~ /-(\d+)-/;
$rel //= '10';
# Arch of the rpm to produce: the host arch unless --mock-cfg is a forcearch (cross) config,
# e.g. rocky-10-riscv64-xcat built on x86_64 (see BUILD.md "riscv64"). goconserver is not built
# in the chroot: go cross-compiles on the host and rpmbuild --target packages the result.
$target_arch = $arch if $target_arch eq '';
my %goarch = (x86_64 => 'amd64', aarch64 => 'arm64', ppc64le => 'ppc64le', s390x => 's390x', riscv64 => 'riscv64');
my $cross = $target_arch ne $arch;
die "No GOARCH known for target arch $target_arch\n" if $cross && !exists $goarch{$target_arch};
my $SOURCE_DATE_EPOCH;
$SOURCE_DATE_EPOCH = $build_timestamp if defined $build_timestamp;
@@ -77,6 +86,7 @@ print "result_dir: $result_dir\n";
print "log_dir: $log_dir\n";
print "mock_cfg: $mock_cfg\n";
print "arch: $arch\n";
print "target_arch:$target_arch" . ($cross ? " (GOARCH=$goarch{$target_arch}, rpmbuild --target)" : '') . "\n";
print "version: $version\n";
print "go_repo: $go_repo\n";
print "go_ref: $go_ref\n";
@@ -114,6 +124,7 @@ $ENV{GOPATH} = "$work_dir/gopath";
$ENV{GOCACHE} = "$work_dir/gocache";
$ENV{GOMODCACHE} = "$work_dir/gomodcache";
$ENV{CGO_ENABLED} = '0';
$ENV{GOARCH} = $goarch{$target_arch} if $cross;
# The archived github.com/kr/pty sets SysProcAttr.Ctty to the parent-side fd,
# which modern Go's os/exec rejects with "Setctty set but Ctty not valid in
@@ -129,6 +140,8 @@ my $go_build_dir = "$work_dir/bin";
make_path($go_build_dir);
my $ldflags = "-X main.Version=$version";
# rpm's brp-strip on the host cannot strip a foreign-arch ELF, so let the Go linker do it.
$ldflags .= ' -s -w' if $cross;
run("cd " . sh_quote($src_dir) . " && " .
"go build -trimpath -buildvcs=false -ldflags " . sh_quote($ldflags) .
@@ -187,6 +200,9 @@ run("tar --sort=name --owner=0 --group=0 --mtime=\@$SOURCE_DATE_EPOCH" .
" goconserver-$version");
print_step("Create spec and build RPM");
# rpm refuses 'BuildArch: <foreign arch>' on this host, so a cross build gets its arch from
# rpmbuild --target instead.
my $buildarch_line = $cross ? '' : "BuildArch: $arch";
my $spec_content = <<"SPEC";
Name: goconserver
Version: $version
@@ -194,7 +210,7 @@ Release: 3.el$rel
Summary: Console server written in Go for xCAT
License: EPL-1.0
URL: https://github.com/xcat2/goconserver
BuildArch: $arch
$buildarch_line
Source0: goconserver-%{version}.tar.gz
@@ -239,6 +255,7 @@ run(
" --define " . sh_quote("use_source_date_epoch_as_buildtime 1") .
" --define " . sh_quote("clamp_mtime_to_source_date_epoch 1") .
" --define " . sh_quote("_buildhost xcat-build") .
($cross ? " --target " . sh_quote($target_arch) : '') .
" -ba " . sh_quote($spec_file) .
" >" . sh_quote("$log_dir/rpmbuild.log") . " 2>&1"
);
@@ -250,7 +267,28 @@ for my $rpm (glob("$rpmbuild_top/RPMS/*/*.rpm"), glob("$rpmbuild_top/SRPMS/*.rpm
print "Copied: $dest\n";
}
if (!$skip_install) {
if (!$skip_install && $cross) {
# A cross-built rpm cannot be installed on this host. Unpack it and run the static Go
# binaries through the binfmt_misc handler (qemu-user-static) that the forcearch mock
# builds of the other deps need anyway.
print_step("Smoke test the $target_arch binaries (binfmt)");
my @built = glob("$rpmbuild_top/RPMS/$target_arch/goconserver-*.rpm");
die "No $target_arch RPM found\n" if !@built;
my $smoke_root = "$work_dir/smoke-root";
remove_tree($smoke_root) if -d $smoke_root;
make_path($smoke_root);
run("cd " . sh_quote($smoke_root) . " && rpm2cpio " . sh_quote($built[0]) . " | cpio -idm --quiet" .
" >" . sh_quote("$log_dir/smoke-unpack.log") . " 2>&1");
for my $bin (qw(goconserver congo)) {
my $path = "$smoke_root/usr/bin/$bin";
die "Missing $path in the $target_arch rpm\n" if !-x $path;
my $rc = run_rc(sh_quote($path) . " -h >" . sh_quote("$log_dir/smoke-$bin.log") . " 2>&1");
die "$bin -h failed (rc=$rc): running a $target_arch binary on this $arch host needs the"
. " qemu-user-static binfmt handler (or pass --skip-install)\n" if $rc > 1;
}
print "Smoke tests passed ($target_arch binaries ran through binfmt).\n";
}
elsif (!$skip_install) {
print_step("Install and smoke test");
my @built = glob("$rpmbuild_top/RPMS/$arch/goconserver-*.rpm");
die "No arch RPM found\n" if !@built;
@@ -284,6 +322,8 @@ Build goconserver RPM from source.
Options:
--work-dir PATH Working directory (default: /tmp/goconserver-mockbuild)
--mock-cfg NAME Mock config name (auto-detected if omitted)
--target-arch ARCH Arch of the rpm to build (default: uname -m); another arch is
cross-compiled (GOARCH) and packaged with rpmbuild --target
--mock-uniqueext STR Mock uniqueext value (for compatibility with mockbuild-all.pl)
--result-dir PATH Output directory for RPMs
--log-dir PATH Output directory for logs
+7
View File
@@ -1,3 +1,10 @@
grub2-xcat (2.12-2) unstable; urgency=low
* Ship the EL10 riscv64 grub2 UEFI image as riscv64-efi/grubriscv64.efi and
install it as /tftpboot/boot/grub2/grub2.riscv64 for riscv64 nodes
-- XCAT <xcat-user@lists.sourceforge.net> Thu, 20 Aug 2026 12:00:00 +0000
grub2-xcat (2.12-1) unstable; urgency=low
* Bump version to satisfy xcat-server dependency (>= 2.02)
+1
View File
@@ -1 +1,2 @@
powerpc-ieee1275/* tftpboot/boot/grub2/powerpc-ieee1275/
grubriscv64.efi tftpboot/boot/grub2/riscv64-efi/
+2
View File
@@ -22,6 +22,8 @@ case "$1" in
configure)
rm -f /tftpboot/boot/grub2/grub2.ppc
cp /tftpboot/boot/grub2/powerpc-ieee1275/core.elf /tftpboot/boot/grub2/grub2.ppc
rm -f /tftpboot/boot/grub2/grub2.riscv64
cp /tftpboot/boot/grub2/riscv64-efi/grubriscv64.efi /tftpboot/boot/grub2/grub2.riscv64
;;
abort-upgrade|abort-remove|abort-deconfigure)
+1
View File
@@ -22,6 +22,7 @@ set -e
case "$1" in
purge|remove)
rm /tftpboot/boot/grub2/grub2.ppc
rm -f /tftpboot/boot/grub2/grub2.riscv64
;;
upgrade)
;;
+14 -2
View File
@@ -6,7 +6,7 @@ Name: grub2-xcat
Epoch: 1
Version: 1.0
#Release: snap%(date +"%Y%m%d%H%M")
Release: 2
Release: 3
License: GPLv3+
Group: Applications/System
Vendor: IBM Corp.
@@ -16,13 +16,18 @@ Prefix: /tftpboot/boot/grub2
BuildRoot: /var/tmp/%{name}-root
BuildArch: noarch
Source1: grub2-res.tar.gz
# EL10 riscv64 grub2 UEFI image, taken unmodified from the Rocky Linux 10
# BaseOS riscv64 tree (EFI/BOOT/grubriscv64.efi, built from
# grub2-2.12-46.el10_2.rocky.0.1.src.rpm, GPL-3.0-or-later); see readme.
Source2: grubriscv64.efi
Provides: grub2-xcat
Requires:/bin/sh
%description
grub2-xcat provides some grub2 resources generated by grub2-mknetdir,including grub2 modules and grub2 image.
grub2-xcat provides some grub2 resources generated by grub2-mknetdir,including grub2 modules and grub2 image,
and the EL grub2 UEFI image for riscv64 nodes, which boot through UEFI and grub2 only.
%define _binaries_in_noarch_packages_terminate_build 0
@@ -53,12 +58,17 @@ cp %{SOURCE1} $RPM_BUILD_ROOT/%{prefix}/
gunzip -f grub2-res.tar.gz
tar -xf grub2-res.tar
%endif
mkdir -p $RPM_BUILD_ROOT/%{prefix}/riscv64-efi
install -m 0644 %{SOURCE2} $RPM_BUILD_ROOT/%{prefix}/riscv64-efi/grubriscv64.efi
%post
rm -f %{prefix}/grub2.ppc
cp %{prefix}/powerpc-ieee1275/core.elf %{prefix}/grub2.ppc
# riscv64 firmware loads boot/grub2/grub2.riscv64 (DHCP client architecture 27)
rm -f %{prefix}/grub2.riscv64
cp %{prefix}/riscv64-efi/grubriscv64.efi %{prefix}/grub2.riscv64
exit 0
%clean
@@ -68,11 +78,13 @@ exit 0
#%{prefix}
# one for sles, one for rhel. yes, it's ugly...
%{prefix}/powerpc-ieee1275/
%{prefix}/riscv64-efi/
%defattr(-,root,root)
%postun
if [ "$1" = "0" ]; then
rm %{prefix}/grub2.ppc
rm -f %{prefix}/grub2.riscv64
fi
true
Binary file not shown.
Executable → Regular
+71 -2
View File
@@ -108,6 +108,15 @@ run(
" | grep -F 'powerpc-ieee1275/core.elf' >/dev/null"
);
print_step("Verify riscv64 grub2 UEFI image");
my $riscv_efi = "$pkg_dir/grubriscv64.efi";
die "Missing required riscv64 grub2 image: $riscv_efi\n" if !-f $riscv_efi;
# Read the PE header ourselves: file(1) only learned the RISC-V PE machine types in 5.38,
# so an older build host (EL8 ships 5.33) would reject a perfectly good image.
my $riscv_efi_type = pe_image_type($riscv_efi);
die "Unexpected riscv64 grub2 image type: $riscv_efi is $riscv_efi_type, expected PE32+ RISC-V 64-bit\n"
if $riscv_efi_type ne 'PE32+ RISC-V 64-bit';
print_step("Verify spec assets");
for my $asset (@spec_assets) {
my $path = "$pkg_dir/$asset";
@@ -143,7 +152,7 @@ print "Prep dry run passed. Applied patches: $patch_count\n";
print_step("Build SRPM with mock");
my $srpm_out = "$work_dir/srpm";
make_path($srpm_out);
run(
run_mock(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt .
" --buildsrpm --spec " . sh_quote($spec_file) .
" --sources " . sh_quote($pkg_dir) .
@@ -161,7 +170,7 @@ print "SRPM: $srpm\n";
print_step("Rebuild RPM with mock");
my $rpm_out = "$work_dir/rpm";
make_path($rpm_out);
run(
run_mock(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt .
" --rebuild " . sh_quote($srpm) .
" --resultdir " . sh_quote($rpm_out) .
@@ -198,6 +207,10 @@ run(
"rpm -qpl " . sh_quote($main_rpm) .
" | grep -Fx /tftpboot/boot/grub2/powerpc-ieee1275/core.elf >/dev/null"
);
run(
"rpm -qpl " . sh_quote($main_rpm) .
" | grep -Fx /tftpboot/boot/grub2/riscv64-efi/grubriscv64.efi >/dev/null"
);
print "Verified RPM name/arch/payload: $main_rpm\n";
print_step("Copy artifacts and logs");
@@ -241,6 +254,22 @@ if (!$skip_install) {
die "Smoke check failed: rpm -qf returned $rc_qf\n" if $rc_qf != 0;
die "Smoke check failed: core.elf and grub2.ppc differ (cmp rc=$rc_cmp)\n" if $rc_cmp != 0;
my $riscv_image = '/tftpboot/boot/grub2/riscv64-efi/grubriscv64.efi';
my $grub2riscv = '/tftpboot/boot/grub2/grub2.riscv64';
die "Missing installed riscv64 grub2 image: $riscv_image\n" if !-f $riscv_image;
die "Missing installed post script output: $grub2riscv\n" if !-f $grub2riscv;
# The installed image must be the verified source image byte for byte, and %post must have
# copied it to grub2.riscv64.
my $rc_cmp_riscv_src = run_capture_rc("cmp -s " . sh_quote($riscv_efi) . " $riscv_image",
"$log_dir/smoke-cmp-riscv64-source.log");
my $rc_cmp_riscv = run_capture_rc("cmp -s $riscv_image $grub2riscv", "$log_dir/smoke-cmp-riscv64.log");
die "Smoke check failed: installed grubriscv64.efi differs from the source image (cmp rc=$rc_cmp_riscv_src)\n"
if $rc_cmp_riscv_src != 0;
die "Smoke check failed: grubriscv64.efi and grub2.riscv64 differ (cmp rc=$rc_cmp_riscv)\n" if $rc_cmp_riscv != 0;
my $riscv_type = pe_image_type($grub2riscv);
die "riscv64 grub2 image type check failed: $grub2riscv is $riscv_type\n"
if $riscv_type ne 'PE32+ RISC-V 64-bit';
my $core_out = slurp($file_core_log);
my $qf_out = slurp($qf_log);
@@ -257,6 +286,10 @@ if (!$skip_install) {
print {$sfh} "rc_file_ppc=$rc_file_ppc\n";
print {$sfh} "rc_qf=$rc_qf\n";
print {$sfh} "rc_cmp=$rc_cmp\n";
print {$sfh} "grub2riscv64=$grub2riscv\n";
print {$sfh} "rc_cmp_riscv64_source=$rc_cmp_riscv_src\n";
print {$sfh} "type_riscv64=$riscv_type\n";
print {$sfh} "rc_cmp_riscv64=$rc_cmp_riscv\n";
close $sfh;
}
@@ -351,6 +384,22 @@ sub capture {
return $out;
}
# mock exits 30 when its package manager failed (chroot init, build deps), which against public
# mirrors is most often a transient download error (stale mirror metadata): retry such a run once.
sub run_mock {
my ($cmd) = @_;
print "+ $cmd\n";
my $rc = system($cmd);
if ($rc != -1 && ($rc >> 8) == 30) {
print "mock failed with rc=30 (package manager); retrying once\n";
$rc = system($cmd);
}
if ($rc != 0) {
my $exit = $rc == -1 ? 255 : ($rc >> 8);
die "Command failed (rc=$exit): $cmd\n";
}
}
sub run_capture_rc {
my ($cmd, $log_file) = @_;
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
@@ -359,6 +408,26 @@ sub run_capture_rc {
return $rc == -1 ? 255 : ($rc >> 8);
}
# Image type of a PE file read from its headers, "PE32+ RISC-V 64-bit" for the grub2 UEFI
# image riscv64 firmware loads (COFF machine 0x5064, optional header magic 0x20b); anything
# else comes back as a short description for the error message.
sub pe_image_type {
my ($path) = @_;
open my $fh, '<:raw', $path or die "Cannot read $path: $!\n";
my $buf = '';
return 'not an MZ/PE file' if read($fh, $buf, 2) != 2 || $buf ne 'MZ';
return 'truncated PE file' if !seek($fh, 0x3c, 0) || read($fh, $buf, 4) != 4;
my $pe_off = unpack('V', $buf);
return 'truncated PE file' if !seek($fh, $pe_off, 0) || read($fh, $buf, 26) != 26;
close $fh;
my ($sig, $machine, $magic) = unpack('a4 v x18 v', $buf);
return 'not a PE file' if $sig ne "PE\0\0";
my %machine_name = (0x5064 => 'RISC-V 64-bit', 0x5032 => 'RISC-V 32-bit',
0x8664 => 'x86-64', 0xaa64 => 'Aarch64', 0x014c => 'Intel 80386');
my $format = $magic == 0x20b ? 'PE32+' : $magic == 0x10b ? 'PE32' : sprintf('PE (magic 0x%x)', $magic);
return "$format " . ($machine_name{$machine} // sprintf('machine 0x%04x', $machine));
}
sub slurp {
my ($path) = @_;
open my $fh, '<', $path or die "Cannot read $path: $!\n";
+18
View File
@@ -16,3 +16,21 @@ run the following cmd on a RHEL7-PPC64 node:
2.Please update the %version or %release when any modification is made for the files
#riscv64:
riscv64 nodes boot through UEFI firmware and grub2 only. The file
grubriscv64.efi (Source2) is the unmodified grub2 UEFI image from the
Rocky Linux 10 riscv64 BaseOS tree (the copy used for installation media
and network boot, embedded prefix /EFI/BOOT):
path: BaseOS/riscv64/os/EFI/BOOT/grubriscv64.efi (Rocky Linux 10.2)
built from: grub2-2.12-46.el10_2.rocky.0.1.src.rpm (GPL-3.0-or-later),
the same build as grub2-efi-riscv64-2.12-46.el10_2.rocky.0.1
sha256: 40baf4e65d20f73e6a5ec4f882d8a50450eaaf8b6688acf871824824ef0bad54
It is installed as /tftpboot/boot/grub2/riscv64-efi/grubriscv64.efi and
copied to /tftpboot/boot/grub2/grub2.riscv64 by the package scripts, which
is the boot file xCAT hands to DHCP client architecture 27 (0x001b). To
refresh it, take EFI/BOOT/grubriscv64.efi from the BaseOS tree of the EL10
release you target and record the release, source rpm and sha256 here.
Executable → Regular
+50 -5
View File
@@ -17,6 +17,7 @@ my $source_url = 'https://github.com/ipmitool/ipmitool/archive/refs/tags/IPMITOO
my $source_file = '';
my $work_dir = '/tmp/ipmitool-xcat-mockbuild';
my $mock_cfg = '';
my $target_arch = '';
my $mock_uniqueext = '';
my $result_dir = "$repo_root/build-output/list3/ipmitool-xcat";
my $log_dir = "$repo_root/build-logs/list3/ipmitool-xcat";
@@ -28,6 +29,7 @@ GetOptions(
'source-file=s' => \$source_file,
'work-dir=s' => \$work_dir,
'mock-cfg=s' => \$mock_cfg,
'target-arch=s' => \$target_arch,
'mock-uniqueext=s' => \$mock_uniqueext,
'result-dir=s' => \$result_dir,
'log-dir=s' => \$log_dir,
@@ -55,6 +57,9 @@ if (!$mock_cfg) {
my $os_id = capture(q{bash -lc 'source /etc/os-release; echo $ID'});
$mock_cfg = resolve_mock_cfg($os_id, '10', $arch);
}
# Arch of the rpms --mock-cfg produces: the host arch unless the config is a forcearch (cross)
# one, e.g. rocky-10-riscv64-xcat built on x86_64 (see BUILD.md "riscv64").
$target_arch = $arch if $target_arch eq '';
my $mock_uniqueext_opt = $mock_uniqueext ne ''
? ' --uniqueext ' . sh_quote($mock_uniqueext)
: '';
@@ -79,6 +84,7 @@ print "work_dir: $work_dir\n";
print "result_dir: $result_dir\n";
print "log_dir: $log_dir\n";
print "mock_cfg: $mock_cfg\n";
print "target_arch:$target_arch\n";
print "mock_uniqueext: " . ($mock_uniqueext ne '' ? $mock_uniqueext : '(none)') . "\n";
print "source_url: $source_url\n";
print "source_file:$source_file\n";
@@ -132,7 +138,7 @@ print "Patch application check passed. Applied patches: $patch_count\n";
print_step("Build SRPM with mock");
my $srpm_out = "$work_dir/srpm";
make_path($srpm_out);
run(
run_mock(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt .
" --buildsrpm --spec " . sh_quote($spec_file) .
" --sources " . sh_quote($pkg_dir) .
@@ -150,7 +156,7 @@ print "SRPM: $srpm\n";
print_step("Rebuild RPM with mock");
my $rpm_out = "$work_dir/rpm";
make_path($rpm_out);
run(
run_mock(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt .
" --rebuild " . sh_quote($srpm) .
" --define " . sh_quote("use_source_date_epoch_as_buildtime 1") .
@@ -159,7 +165,7 @@ run(
" --resultdir " . sh_quote($rpm_out)
);
my @arch_rpms = sort glob("$rpm_out/*.${arch}.rpm");
my @arch_rpms = sort glob("$rpm_out/*.${target_arch}.rpm");
die "No architecture RPMs generated in $rpm_out\n" if !@arch_rpms;
my $main_rpm = '';
@@ -176,7 +182,7 @@ print_step("Verify generated RPM");
my $rpm_name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($main_rpm));
my $rpm_arch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($main_rpm));
die "Unexpected RPM name: $rpm_name\n" if $rpm_name ne 'ipmitool-xcat';
die "Unexpected RPM arch: $rpm_arch (expected $arch)\n" if $rpm_arch ne $arch;
die "Unexpected RPM arch: $rpm_arch (expected $target_arch)\n" if $rpm_arch ne $target_arch;
run(
"rpm -qpl " . sh_quote($main_rpm) .
" | grep -Fx /opt/xcat/bin/ipmitool-xcat >/dev/null"
@@ -195,7 +201,28 @@ for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
or die "Failed to copy $src to $log_dir: $!\n";
}
if (!$skip_install) {
if (!$skip_install && $target_arch ne $arch) {
# A cross-built rpm cannot be installed on this host: install it into the (emulated) build
# chroot instead and run the binary there.
print_step("Install RPM into the chroot and run smoke tests");
run_mock("mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt . " --install " . sh_quote($main_rpm)
. " > " . sh_quote("$log_dir/smoke-chroot-install.log") . " 2>&1");
my $bin = '/opt/xcat/bin/ipmitool-xcat';
my $version_log = "$log_dir/smoke-version.log";
my $rc_version = run_capture_rc(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt . " -q --chroot -- " . sh_quote("$bin -V"),
$version_log);
die "Smoke check failed: -V in the chroot returned $rc_version\n" if $rc_version != 0;
my $version_out = slurp($version_log);
die "Version output missing expected version string\n"
if $version_out !~ /ipmitool-xcat version \Q$version\E/i;
my $summary = "$log_dir/smoke-summary.txt";
open my $sfh, '>', $summary or die "Cannot write $summary: $!\n";
print {$sfh} "binary=$bin (in chroot $mock_cfg)\n";
print {$sfh} "rc_version=$rc_version\n";
close $sfh;
}
elsif (!$skip_install) {
print_step("Install RPM and run smoke tests");
run("dnf -y install " . sh_quote($main_rpm));
@@ -262,6 +289,8 @@ Usage: $0 [options]
--source-file FILE Source filename stored in ipmitool/ (default: inferred from spec version)
--work-dir PATH Temporary work dir (default: $work_dir)
--mock-cfg NAME Mock config (default: <ID>+epel-10-<ARCH>)
--target-arch ARCH Arch of the rpms --mock-cfg produces (default: uname -m); a forcearch
config such as rocky-10-riscv64-xcat needs it
--mock-uniqueext TXT Optional mock --uniqueext suffix to isolate concurrent builds
--result-dir PATH Output RPM/SRPM directory (default: $result_dir)
--log-dir PATH Log directory (default: $log_dir)
@@ -374,6 +403,22 @@ sub capture {
return $out;
}
# mock exits 30 when its package manager failed (chroot init, build deps), which against public
# mirrors is most often a transient download error (stale mirror metadata): retry such a run once.
sub run_mock {
my ($cmd) = @_;
print "+ $cmd\n";
my $rc = system($cmd);
if ($rc != -1 && ($rc >> 8) == 30) {
print "mock failed with rc=30 (package manager); retrying once\n";
$rc = system($cmd);
}
if ($rc != 0) {
my $exit = $rc == -1 ? 255 : ($rc >> 8);
die "Command failed (rc=$exit): $cmd\n";
}
}
sub run_capture_rc {
my ($cmd, $log_file) = @_;
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
+14
View File
@@ -0,0 +1,14 @@
# Rocky Linux 10 riscv64 chroot for the xCAT dependency build, cross-built on an x86_64 host
# through qemu-user-static (binfmt_misc). mock-core-configs ships rocky-10-riscv64.cfg, but it
# only admits a riscv64 build host and names its chroot after the x86_64 one, so it cannot be
# used from the x86_64 hosts that produce the xcat-dep repos; this config includes the same
# template and adds forcearch. There is no EPEL for riscv64, so nothing EPEL-only is reachable
# from this chroot: mockbuild-all.pl builds the EPEL-only perl deps of xCAT for this target.
# See BUILD.md ("riscv64") for the host prerequisites and how mockbuild-all.pl uses it.
include('templates/rocky-10.tpl')
config_opts['root'] = 'rocky-10-riscv64-xcat'
config_opts['description'] = 'Rocky Linux 10 riscv64 (xCAT dependency build, forcearch)'
config_opts['target_arch'] = 'riscv64'
config_opts['legal_host_arches'] = ('x86_64', 'riscv64')
config_opts['forcearch'] = 'riscv64'
Executable → Regular
+123 -34
View File
@@ -150,7 +150,11 @@ acquire_repository_lock($repo_dep, $force_unlock)
$xcat_src = resolve_xcat_source($xcat_src, $repo_root);
my $arch = capture_command('uname', '-m');
my $host_arch = capture_command('uname', '-m');
# Arch of the target being built: the host arch, except for the forcearch targets below, which
# cross-build another arch on this host. Set per target in build_one_target; the deploy and
# the repo metadata take the arch from the target profile instead of this variable.
my $arch = $host_arch;
my %os = read_os_release('/etc/os-release');
my $os_id = $os{ID} // '';
my $version_id = $os{VERSION_ID} // '';
@@ -188,10 +192,28 @@ if ($genesis_release ne '') {
# An explicit --target builds just that target; otherwise build the current host
# arch across rh8/rh9/rh10 into a deployable per-EL xcat-dep repo. This script builds
# ONLY the host arch (uname -m) -- the other arch is produced on its own build host.
# ONLY the host arch (uname -m) -- the other arch is produced on its own build host --
# except for the forcearch targets (%forcearch_targets, --target only), which are
# cross-built here through qemu-user-static.
my @build_targets = $target
? ($target)
: map { resolve_mock_cfg($os_id, $_, $arch) } (8, 9, 10);
: map { resolve_mock_cfg($os_id, $_, $host_arch) } (8, 9, 10);
# What a target builds. The mock-core-configs targets (<os>+epel-<rel>-<arch>) build every
# dep natively on the host arch. The forcearch targets shipped in mock-configs/ cross-build
# another arch that has no EPEL: the x86-only bootloaders are not built for it, the EPEL-only
# perl deps of xCAT are (mockbuild-perl-packages.pl --epel-gap), and the noarch deps are built
# in the native, EPEL-free chroot of the same release (the rpms are identical for every arch
# and an emulated build is an order of magnitude slower). See BUILD.md ("riscv64").
my %forcearch_targets = (
'rocky-10-riscv64-xcat' => {
rel => 10,
arch => 'riscv64',
noarch_cfg => "rocky-10-$host_arch",
dep_builders => [qw(grub2-xcat ipmitool-xcat goconserver conserver-xcat)],
required => [qw(ipmitool-xcat grub2-xcat perl-IO-Stty perl-HTTP-Async perl-Net-HTTPS-NB)],
},
);
# NOTE: no dhcp- packages are built here. DHCP backend selection is an install-time
# rich dep in xCAT.spec (kea if system-release>=10 else /usr/sbin/dhcpd), so there is
@@ -255,8 +277,9 @@ sub build_one_target {
# different targets (e.g. alma+epel-8 vs -9) share build-output/<run_id> and
# cross-contaminate. Fold the target into run_id so each target gets its own tree.
$run_id = "$target-$run_id" unless index($run_id, $target) >= 0;
my ($rel) = $target =~ /epel-(\d+)-/;
die "Could not parse EL release from target '$target'\n" unless defined $rel;
my $profile = target_profile($target);
my $rel = $profile->{rel};
$arch = $profile->{arch};
my $run_root = "$output_root/$run_id";
my $build_root = "$run_root/build-results";
@@ -269,16 +292,18 @@ my $srpm_tarball = "$output_root/mockbuild-all-$target-$run_id-srpm.tar.gz";
# All dep builders run natively on every arch. xnba-undi and grub2-xcat are noarch packagings of
# committed artifacts (an x86 UNDI ROM / the grub2 resource tarball) with no arch-specific build
# step, so ppc builds them the same as x86 -- no cross-arch import.
# step, so ppc builds them the same as x86 -- no cross-arch import. A forcearch target builds
# only the builders its profile lists; the noarch ones run in the profile's native chroot.
my @dep_builders = (
{ name => 'elilo-xcat', script => "$repo_root/elilo/mockbuild.pl" },
{ name => 'grub2-xcat', script => "$repo_root/grub2-xcat/mockbuild.pl" },
{ name => 'elilo-xcat', script => "$repo_root/elilo/mockbuild.pl", noarch => 1 },
{ name => 'grub2-xcat', script => "$repo_root/grub2-xcat/mockbuild.pl", noarch => 1 },
{ name => 'ipmitool-xcat', script => "$repo_root/ipmitool/mockbuild.pl" },
{ name => 'syslinux-xcat', script => "$repo_root/syslinux/mockbuild.pl" },
{ name => 'goconserver', script => "$repo_root/goconserver/mockbuild.pl" },
{ name => 'conserver-xcat', script => "$repo_root/conserver/mockbuild.pl" },
{ name => 'xnba-undi', script => "$repo_root/xnba/mockbuild.pl" },
{ name => 'xnba-undi', script => "$repo_root/xnba/mockbuild.pl", noarch => 1 },
);
my %profile_builds = map { $_ => 1 } @{ $profile->{dep_builders} };
my $perl_builder = "$repo_root/mockbuild-perl-packages.pl";
@@ -287,6 +312,7 @@ die "Missing xCAT build script: $xcat_src/buildrpms.pl\n"
my @active_dep_builders;
for my $b (@dep_builders) {
next if !$profile_builds{$b->{name}};
if (-f $b->{script}) {
push @active_dep_builders, $b;
next;
@@ -320,6 +346,10 @@ print "xcat_source: $xcat_src\n";
print "output_root: $output_root\n";
print "run_root: $run_root\n";
print "arch: $arch\n";
print "host_arch: $host_arch\n";
print "forcearch: $profile->{forcearch}\n";
print "noarch_cfg: $profile->{noarch_cfg}\n";
print "epel: $profile->{epel}\n";
print "os_id: $os_id\n";
print "version_id: $version_id\n";
print "rel: $rel\n";
@@ -343,12 +373,19 @@ print "srpm_tarball: $srpm_tarball\n";
my @collect_roots;
install_mock_cfg($target);
if ($scrub_all_chroots) {
run_step(
step => "Scrub all chroots for target $target",
cmd => "mock -r " . shell_quote($target) . " --scrub=all",
log => "$log_root/scrub-all-chroots.log",
);
run_step(
step => "Scrub all chroots for noarch config $profile->{noarch_cfg}",
cmd => "mock -r " . shell_quote($profile->{noarch_cfg}) . " --scrub=all",
log => "$log_root/scrub-all-chroots-noarch.log",
) if $profile->{noarch_cfg} ne $target;
}
if (!$skip_build) {
@@ -364,7 +401,8 @@ if (!$skip_build) {
my $step_uniqueext = build_mock_uniqueext($run_id, ++$build_step_seq, $name);
my $cmd = join(' ',
'perl', shell_quote($script),
'--mock-cfg', shell_quote($target),
'--mock-cfg', shell_quote($builder->{noarch} ? $profile->{noarch_cfg} : $target),
($profile->{forcearch} && !$builder->{noarch} ? ('--target-arch', shell_quote($arch)) : ()),
'--mock-uniqueext', shell_quote($step_uniqueext),
'--result-dir', shell_quote($step_result),
'--log-dir', shell_quote($step_log),
@@ -393,6 +431,10 @@ if (!$skip_build) {
my $cmd = join(' ',
'perl', shell_quote($perl_builder),
'--mock-cfg', shell_quote($target),
($profile->{forcearch}
? ('--target-arch', shell_quote($arch), '--noarch-mock-cfg', shell_quote($profile->{noarch_cfg}))
: ()),
($profile->{epel} ? () : ('--epel-gap')),
'--mock-uniqueext', shell_quote($perl_uniqueext),
'--result-dir', shell_quote($perl_result),
'--log-dir', shell_quote($perl_log),
@@ -602,7 +644,7 @@ if (!$dry_run) {
print {$sfh} "run_root=$run_root\n";
print {$sfh} "repo_dir=$repo_dir\n";
print {$sfh} "target=$target\n";
print {$sfh} "arch=$arch\n";
print {$sfh} "arch=$profile->{arch}\n";
print {$sfh} "os_id=$os_id\n";
print {$sfh} "version_id=$version_id\n";
print {$sfh} "rel=$rel\n";
@@ -631,7 +673,55 @@ print "Summary: $summary_file\n" if !$dry_run;
print "Tarball: $tarball\n" if !$skip_tarball;
print "SRPM Tarball: $srpm_tarball\n" if !$skip_tarball;
return { repo_dir => $repo_dir, rel => $rel };
return { repo_dir => $repo_dir, rel => $rel, profile => $profile };
}
# The build profile of a target: EL release, arch of the rpms, where its noarch deps are built,
# which dep builders run and which rpms the deployed repo must contain.
sub target_profile {
my ($target) = @_;
if (my $fa = $forcearch_targets{$target}) {
return {
%{$fa},
forcearch => 1,
epel => 0,
};
}
my ($rel) = $target =~ /epel-(\d+)-/;
die "Could not parse EL release from target '$target'\n" unless defined $rel;
return {
rel => $rel,
arch => $host_arch,
noarch_cfg => $target,
forcearch => 0,
epel => 1,
dep_builders => [qw(elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat goconserver conserver-xcat xnba-undi)],
# xCAT Requires all of these on every arch, and every one of them builds natively on
# every arch (the noarch deps -- grub2-xcat, xnba-undi -- just repackage committed
# artifacts), so a self-sufficient per-arch build produces the whole set.
required => [qw(ipmitool-xcat syslinux-xcat grub2-xcat xnba-undi
perl-IO-Stty perl-HTTP-Async perl-Net-HTTPS-NB)],
};
}
# The forcearch targets are shipped in mock-configs/; mock, and the include('/etc/mock/<cfg>.cfg')
# overlays of the per-package builders, need them in /etc/mock. Install a missing one; never
# overwrite one the host already has.
sub install_mock_cfg {
my ($cfg) = @_;
my $src = "$repo_root/mock-configs/$cfg.cfg";
return if !-f $src;
my $dst = "/etc/mock/$cfg.cfg";
if (-f $dst) {
die "$dst differs from $src: the build would not use the configuration shipped in this"
. " tree. Remove or update the host copy (it is never overwritten here) and rerun.\n"
if system("cmp -s " . shell_quote($src) . ' ' . shell_quote($dst)) != 0;
return;
}
print "Installing mock config $src -> $dst\n";
return if $dry_run;
copy($src, $dst) or die "Failed to install $src -> $dst: $!\n";
chmod 0644, $dst;
}
# Assemble the built per-target repo into the deployable, signed per-EL layout
@@ -639,9 +729,10 @@ print "SRPM Tarball: $srpm_tarball\n" if !$skip_tarball;
# xcat-dep.repo / mklocalrepo.sh / buildinfo.txt (ready to push to xcat.org).
sub deploy_target {
my ($tgt, $info) = @_;
my $rel = $info->{rel};
my $src = $info->{repo_dir};
my $dest = "$repo_dep/rh$rel/$arch";
my $rel = $info->{rel};
my $src = $info->{repo_dir};
my $tarch = $info->{profile}{arch};
my $dest = "$repo_dep/rh$rel/$tarch";
print_step("Deploy $tgt -> $dest");
return if $dry_run;
make_path($dest);
@@ -651,11 +742,11 @@ sub deploy_target {
publish_file($rpm, $destination);
}
remove_genesis_packages($dest, 0) if $genesis_release;
assert_required_deps($dest);
assert_required_deps($dest, $info->{profile}{required});
sign_and_index_repo($dest);
write_dep_repo_metadata($dest, $rel);
write_dep_repo_metadata($dest, $rel, $tarch);
my $n = scalar(grep { !/\.src\.rpm$/ } bsd_glob("$dest/*.rpm"));
print "Deployed rh$rel/$arch: $n rpms\n";
print "Deployed rh$rel/$tarch: $n rpms\n";
}
sub publish_genesis_common_repo {
@@ -757,14 +848,14 @@ sub sign_and_index_repo {
}
sub write_dep_repo_metadata {
my ($dir, $rel) = @_;
my $baseurl = "https://xcat.org/files/xcat/repos/yum/devel/xcat-dep/rh$rel/$arch";
my ($dir, $rel, $tarch) = @_;
my $baseurl = "https://xcat.org/files/xcat/repos/yum/devel/xcat-dep/rh$rel/$tarch";
my $gpgcheck = $gpg_sign ? 1 : 0;
my $gpgkey_line = $gpg_sign ? "gpgkey=$baseurl/repodata/repomd.xml.key" : "# gpgkey=";
open my $r, '>', "$dir/xcat-dep.repo" or die "Cannot write $dir/xcat-dep.repo: $!\n";
print {$r} <<"EOF";
[xcat-dep]
name=xCAT 2 dependencies (rh$rel $arch)
name=xCAT 2 dependencies (rh$rel $tarch)
baseurl=$baseurl
enabled=1
gpgcheck=$gpgcheck
@@ -773,7 +864,7 @@ EOF
close $r;
write_local_repo_helper($dir);
write_buildinfo($dir, "rh$rel/$arch");
write_buildinfo($dir, "rh$rel/$tarch");
}
sub write_common_repo_metadata {
@@ -866,8 +957,10 @@ Options:
--gpg-sign Sign RPMs and repomd.xml in every published repository
--gpg-key-name NAME GPG key name (default: "xCAT Signing Key")
--gpg-home PATH GNUPGHOME for signing (default: system keyring)
--target NAME Build only this target (<ID>+epel-<REL>-<ARCH>); default is
the host arch across rh8, rh9 and rh10
--target NAME Build only this target (<ID>+epel-<REL>-<ARCH>, or a forcearch
config from mock-configs/ such as rocky-10-riscv64-xcat, which
cross-builds that arch on this host); default is the host arch
across rh8, rh9 and rh10
--nproc N Parallel jobs for buildrpms.pl (default: 1)
--parallel-builds N Max concurrent top-level build steps within one EL target (default: auto)
--parallel-targets N Concurrent EL targets (rh8/rh9/rh10). 0/auto = all at once, 1 = serial,
@@ -892,7 +985,7 @@ Options:
Notes:
- Run this script as root on the build host.
- ARCH is derived from: uname -m
- ARCH is derived from: uname -m (or from the forcearch target)
- Top-level parallel queue includes xcat-dep mockbuild.pl steps, perl builder,
and ../xcat-core/buildrpms.pl.
- Child mockbuild scripts are invoked with per-step mock --uniqueext values
@@ -1045,16 +1138,12 @@ sub have_rpm {
return scalar(@m) > 0;
}
# assert_required_deps: the per-EL dep repo is unusable without these, so a MISSING one is
# fatal even though individual builder failures are tolerated above. genesis-base is required
# unless --skip-genesis.
# assert_required_deps: the per-EL dep repo is unusable without these (the target profile's
# required set), so a MISSING one is fatal even though individual builder failures are
# tolerated above. genesis-base is required unless --skip-genesis.
sub assert_required_deps {
my ($dir) = @_;
# xCAT Requires all of these on every arch, and every one of them builds natively on every
# arch (the noarch deps -- grub2-xcat, xnba-undi -- just repackage committed artifacts), so
# a self-sufficient per-arch build produces the whole set with no cross-arch import.
my @req = qw(ipmitool-xcat syslinux-xcat grub2-xcat xnba-undi
perl-IO-Stty perl-HTTP-Async perl-Net-HTTPS-NB);
my ($dir, $required) = @_;
my @req = @{$required};
push @req, 'xCAT-genesis-base' unless $skip_genesis;
my @missing = grep { !have_rpm($dir, $_) } @req;
die "FATAL: required deps missing from $dir: @missing\n" if @missing;
Executable → Regular
+253 -27
View File
@@ -12,10 +12,13 @@ use Parallel::ForkManager;
my $repo_root = abs_path(dirname(__FILE__));
my $work_dir = '/tmp/perl-list6-mockbuild';
my $mock_cfg = '';
my $noarch_mock_cfg = '';
my $target_arch = '';
my $mock_uniqueext = '';
my $result_dir = '';
my $log_dir = '';
my $packages_csv = '';
my $epel_gap = 0;
my $jobs = 0;
my $skip_install = 0;
my $allow_erasing = 0;
@@ -24,10 +27,13 @@ my $build_timestamp;
GetOptions(
'work-dir=s' => \$work_dir,
'mock-cfg=s' => \$mock_cfg,
'noarch-mock-cfg=s' => \$noarch_mock_cfg,
'target-arch=s' => \$target_arch,
'mock-uniqueext=s' => \$mock_uniqueext,
'result-dir=s' => \$result_dir,
'log-dir=s' => \$log_dir,
'packages=s' => \$packages_csv,
'epel-gap!' => \$epel_gap,
'jobs=i' => \$jobs,
'skip-install!' => \$skip_install,
'allow-erasing!' => \$allow_erasing,
@@ -45,6 +51,12 @@ if (!$mock_cfg) {
my $os_id = capture(q{bash -lc 'source /etc/os-release; echo $ID'});
$mock_cfg = resolve_mock_cfg($os_id, $arch);
}
# Arch of the rpms --mock-cfg produces: the host arch unless the config is a forcearch (cross)
# one, e.g. rocky-10-riscv64-xcat built on x86_64 (see BUILD.md "riscv64"). The noarch packages
# may be built in a native chroot of the same release instead of the emulated one (their rpms
# are identical for every arch and emulated builds are slow).
$target_arch = $arch if $target_arch eq '';
$noarch_mock_cfg = $mock_cfg if $noarch_mock_cfg eq '';
my $mock_uniqueext_opt = $mock_uniqueext ne ''
? ' --uniqueext ' . sh_quote($mock_uniqueext)
: '';
@@ -63,13 +75,44 @@ $SOURCE_DATE_EPOCH = time() unless $SOURCE_DATE_EPOCH =~ /^\d+$/;
$ENV{SOURCE_DATE_EPOCH} = $SOURCE_DATE_EPOCH;
if (!$result_dir) {
$result_dir = "$repo_root/build-output/list6/perl/$arch";
$result_dir = "$repo_root/build-output/list6/perl/$target_arch";
}
if (!$log_dir) {
$log_dir = "$repo_root/build-logs/list6/perl/$arch";
$log_dir = "$repo_root/build-logs/list6/perl/$target_arch";
}
my %meta = (
'perl-Crypt-Blowfish' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-Crypt-Blowfish",
srpm_globs => [
"$repo_root/perl-Crypt-Blowfish/perl-Crypt-Blowfish-2.14-25.el10_0.src.rpm",
"$repo_root/perl-Crypt-Blowfish/perl-Crypt-Blowfish-*.src.rpm",
],
rpm_name => 'perl-Crypt-Blowfish',
rpm_arch => 'native',
module => 'Crypt::Blowfish',
needs => ['perl-Crypt-CBC'], # optional tests (BuildRequires)
},
'perl-Crypt-CBC' => {
mode => 'spec',
pkg_dir => "$repo_root/perl-Crypt-CBC",
spec => "$repo_root/perl-Crypt-CBC/perl-Crypt-CBC.spec",
rpm_name => 'perl-Crypt-CBC',
rpm_arch => 'noarch',
module => 'Crypt::CBC',
},
'perl-Crypt-Rijndael' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-Crypt-Rijndael",
srpm_globs => [
"$repo_root/perl-Crypt-Rijndael/perl-Crypt-Rijndael-1.13-10.fc29.src.rpm",
"$repo_root/perl-Crypt-Rijndael/perl-Crypt-Rijndael-*.src.rpm",
],
rpm_name => 'perl-Crypt-Rijndael',
rpm_arch => 'native',
module => 'Crypt::Rijndael',
},
'perl-Crypt-SSLeay' => {
mode => 'spec',
pkg_dir => "$repo_root/perl-Crypt-SSLeay",
@@ -77,6 +120,29 @@ my %meta = (
rpm_name => 'perl-Crypt-SSLeay',
rpm_arch => 'native',
module => 'Crypt::SSLeay',
needs => ['perl-Path-Class'], # Makefile.PL (configure_requires), EPEL-only on EL
},
'perl-Digest-SHA1' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-Digest-SHA1",
srpm_globs => [
"$repo_root/perl-Digest-SHA1/perl-Digest-SHA1-2.13-23.fc28.src.rpm",
"$repo_root/perl-Digest-SHA1/perl-Digest-SHA1-*.src.rpm",
],
rpm_name => 'perl-Digest-SHA1',
rpm_arch => 'native',
module => 'Digest::SHA1',
},
'perl-Expect' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-Expect",
srpm_globs => [
"$repo_root/perl-Expect/perl-Expect-1.35-6.fc29.src.rpm",
"$repo_root/perl-Expect/perl-Expect-*.src.rpm",
],
rpm_name => 'perl-Expect',
rpm_arch => 'noarch',
module => 'Expect',
},
'perl-HTML-Form' => {
mode => 'srpm',
@@ -108,6 +174,25 @@ my %meta = (
rpm_arch => 'noarch',
module => 'IO::Stty',
},
'perl-Mail-Sender' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-Mail-Sender",
srpm_globs => [
"$repo_root/perl-Mail-Sender/perl-Mail-Sender-0.903-7.fc29.src.rpm",
"$repo_root/perl-Mail-Sender/perl-Mail-Sender-*.src.rpm",
],
rpm_name => 'perl-Mail-Sender',
rpm_arch => 'noarch',
module => 'Mail::Sender',
},
'perl-Net-DNS' => {
mode => 'spec',
pkg_dir => "$repo_root/perl-Net-DNS",
spec => "$repo_root/perl-Net-DNS/Net-DNS.spec",
rpm_name => 'perl-Net-DNS',
rpm_arch => 'noarch',
module => 'Net::DNS',
},
'perl-Net-HTTPS-NB' => {
mode => 'spec',
pkg_dir => "$repo_root/perl-Net-HTTPS-NB",
@@ -116,6 +201,17 @@ my %meta = (
rpm_arch => 'noarch',
module => 'Net::HTTPS::NB',
},
'perl-Net-IP' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-Net-IP",
srpm_globs => [
"$repo_root/perl-Net-IP/perl-Net-IP-1.26-30.el10_0.src.rpm",
"$repo_root/perl-Net-IP/perl-Net-IP-*.src.rpm",
],
rpm_name => 'perl-Net-IP',
rpm_arch => 'noarch',
module => 'Net::IP',
},
'perl-Net-Telnet' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-Net-Telnet",
@@ -127,6 +223,28 @@ my %meta = (
rpm_arch => 'noarch',
module => 'Net::Telnet',
},
'perl-Path-Class' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-Path-Class",
srpm_globs => [
"$repo_root/perl-Path-Class/perl-Path-Class-0.37-24.el10_0.src.rpm",
"$repo_root/perl-Path-Class/perl-Path-Class-*.src.rpm",
],
rpm_name => 'perl-Path-Class',
rpm_arch => 'noarch',
module => 'Path::Class',
},
'perl-SOAP-Lite' => {
mode => 'srpm',
pkg_dir => "$repo_root/perl-SOAP-Lite",
srpm_globs => [
"$repo_root/perl-SOAP-Lite/perl-SOAP-Lite-1.27-3.fc29.src.rpm",
"$repo_root/perl-SOAP-Lite/perl-SOAP-Lite-*.src.rpm",
],
rpm_name => 'perl-SOAP-Lite',
rpm_arch => 'noarch',
module => 'SOAP::Lite',
},
'perl-Sys-Virt' => {
mode => 'spec',
pkg_dir => "$repo_root/perl-Sys-Virt",
@@ -137,6 +255,7 @@ my %meta = (
},
);
# xcat-dep's own perl deps of xCAT, built for every EL and arch ("list6").
my @default_order = qw(
perl-Crypt-SSLeay
perl-HTML-Form
@@ -147,7 +266,25 @@ my @default_order = qw(
perl-Sys-Virt
);
# The perl deps of xCAT that EL takes from EPEL. Built only where there is no EPEL (riscv64,
# --epel-gap); the x86_64/ppc64le repos keep getting them from EPEL. perl-Path-Class is a
# build dep of perl-Crypt-SSLeay only. Not here although in the table: perl-SOAP-Lite (its
# fc29 BuildRequires IO::SessionData, MIME::Lite, XML::Parser::Lite, Test::XML are EPEL-only
# too, so it cannot be built or installed without EPEL; xCAT uses it for HP blades only).
my @epel_gap_order = qw(
perl-Crypt-Blowfish
perl-Crypt-CBC
perl-Crypt-Rijndael
perl-Digest-SHA1
perl-Expect
perl-Mail-Sender
perl-Net-DNS
perl-Net-IP
perl-Path-Class
);
my @packages = @default_order;
push @packages, @epel_gap_order if $epel_gap;
if ($packages_csv ne '') {
@packages = grep { $_ ne '' } map { s/^\s+|\s+$//gr } split /,/, $packages_csv;
}
@@ -178,8 +315,11 @@ print "work_dir: $work_dir\n";
print "result_dir: $result_dir\n";
print "log_dir: $log_dir\n";
print "arch: $arch\n";
print "target_arch: $target_arch\n";
print "mock_cfg: $mock_cfg\n";
print "noarch_mock_cfg: $noarch_mock_cfg\n";
print "mock_uniqueext: " . ($mock_uniqueext ne '' ? $mock_uniqueext : '(none)') . "\n";
print "epel_gap: $epel_gap\n";
print "packages: " . join(', ', @packages) . "\n";
print "jobs: $jobs\n";
print "skip_install:$skip_install\n";
@@ -187,6 +327,8 @@ print "allow_erasing:$allow_erasing\n";
print_step("Mock config check");
run("mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt . " --print-root-path >/dev/null");
run("mock -r " . sh_quote($noarch_mock_cfg) . $mock_uniqueext_opt . " --print-root-path >/dev/null")
if $noarch_mock_cfg ne $mock_cfg;
my @failed;
my @passed;
@@ -204,28 +346,36 @@ $pm->run_on_finish(
}
);
for my $idx (0 .. $#packages) {
my $pkg = $packages[$idx];
my $cfg = $meta{$pkg};
my $pkg_uniqueext = package_uniqueext($mock_uniqueext, $idx + 1, $pkg);
# A package that 'needs' others (see %meta) is built after them, with their rpms installed into
# its chroot, so the waves run one after the other; the packages of a wave build in parallel.
my %selected = map { $_ => 1 } @packages;
my $idx = 0;
for my $wave (build_waves(\@packages)) {
for my $pkg (@{$wave}) {
my $cfg = $meta{$pkg};
my $pkg_uniqueext = package_uniqueext($mock_uniqueext, ++$idx, $pkg);
my @needs = grep { $selected{$_} } @{ $cfg->{needs} // [] };
my $pid = $pm->start($pkg);
next if $pid;
my $ok = build_package(
pkg => $pkg,
cfg => $cfg,
work_dir => $work_dir,
result_dir => $result_dir,
log_dir => $log_dir,
mock_cfg => $mock_cfg,
mock_uniqueext => $pkg_uniqueext,
arch => $arch,
skip_install => $skip_install,
allow_erasing => $allow_erasing,
);
$pm->finish($ok ? 0 : 1);
my $pid = $pm->start($pkg);
next if $pid;
my $ok = build_package(
pkg => $pkg,
cfg => $cfg,
work_dir => $work_dir,
result_dir => $result_dir,
log_dir => $log_dir,
mock_cfg => ($cfg->{rpm_arch} eq 'noarch' ? $noarch_mock_cfg : $mock_cfg),
mock_uniqueext => $pkg_uniqueext,
arch => $target_arch,
host_arch => $arch,
needs => \@needs,
skip_install => $skip_install,
allow_erasing => $allow_erasing,
);
$pm->finish($ok ? 0 : 1);
}
$pm->wait_all_children;
}
$pm->wait_all_children;
for my $pkg (@packages) {
my $status_file = "$log_dir/$pkg/status.txt";
@@ -252,10 +402,12 @@ for my $pkg (@packages) {
open my $sfh, '>', "$log_dir/build-summary.txt"
or die "Cannot write $log_dir/build-summary.txt: $!\n";
print {$sfh} "mock_cfg=$mock_cfg\n";
print {$sfh} "noarch_mock_cfg=$noarch_mock_cfg\n" if $noarch_mock_cfg ne $mock_cfg;
print {$sfh} "mock_uniqueext=$mock_uniqueext\n" if $mock_uniqueext ne '';
print {$sfh} "arch=$arch\n";
print {$sfh} "arch=$target_arch\n";
print {$sfh} "result_dir=$result_dir\n";
print {$sfh} "log_dir=$log_dir\n";
print {$sfh} "epel_gap=$epel_gap\n";
print {$sfh} "packages=" . join(',', @packages) . "\n";
print {$sfh} "passed=" . join(',', @passed) . "\n";
print {$sfh} "failed=" . join(',', @failed) . "\n";
@@ -280,6 +432,8 @@ sub build_package {
my $mock_cfg = $args{mock_cfg};
my $mock_uniqueext = $args{mock_uniqueext};
my $arch = $args{arch};
my $host_arch = $args{host_arch} // $arch;
my $needs = $args{needs} // [];
my $skip_install = $args{skip_install};
my $allow_erasing = $args{allow_erasing};
@@ -304,7 +458,9 @@ sub build_package {
my $mock_uniqueext_opt = ' --uniqueext ' . sh_quote($mock_uniqueext);
print_step("Build $pkg");
print "mock_cfg: $mock_cfg\n";
print "mock_uniqueext: $mock_uniqueext\n";
print "needs: " . (@{$needs} ? join(', ', @{$needs}) : '(none)') . "\n";
my $summary = '';
my $ok = 0;
@@ -358,7 +514,7 @@ sub build_package {
my $srpm_result = "$pkg_run_dir/srpm";
make_path($srpm_result);
run(
run_mock(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt .
" --buildsrpm --spec " . sh_quote($spec) .
" --sources " . sh_quote($source_dir) .
@@ -373,9 +529,19 @@ sub build_package {
$srpm_path = $srpms[-1];
}
run(
# The rpms of the packages this one needs (built in an earlier wave) go into the chroot
# on top of the build requirements the chroot resolves itself.
my $additional_opt = '';
for my $need (@{$needs}) {
my @need_rpms = grep { !/\.src\.rpm$/ && !/-debug(?:info|source)-/ }
sort glob("$result_dir/$need/*.rpm");
die "Needed package $need left no rpms in $result_dir/$need (build failed?)\n" if !@need_rpms;
$additional_opt .= " --additional-package " . sh_quote($_) for @need_rpms;
}
run_mock(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt .
" --rebuild " . sh_quote($srpm_path) .
" --rebuild " . sh_quote($srpm_path) . $additional_opt .
" --define " . sh_quote("use_source_date_epoch_as_buildtime 1") .
" --define " . sh_quote("clamp_mtime_to_source_date_epoch 1") .
" --define " . sh_quote("_buildhost xcat-build") .
@@ -425,7 +591,22 @@ sub build_package {
}
}
if (!$skip_install) {
if (!$skip_install && $cfg->{rpm_arch} eq 'native' && $arch ne $host_arch) {
# A cross-built XS module cannot be loaded on this host: install the rpm into the
# (emulated) build chroot and import the module there.
my $module = $cfg->{module};
run_mock(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt .
" --install " . sh_quote($main_rpm) .
" > " . sh_quote("$pkg_log/smoke-chroot-install.log") . " 2>&1"
);
my $rc_mod = run_capture_rc(
"mock -r " . sh_quote($det_mock_cfg) . $mock_uniqueext_opt .
" -q --chroot -- perl -M$module -e 1",
"$pkg_log/smoke-perl-module.log");
die "Perl module import failed for $pkg ($module) in the $arch chroot, rc=$rc_mod\n" if $rc_mod != 0;
}
elsif (!$skip_install) {
my $install_cmd = "dnf -y install ";
$install_cmd .= "--allowerasing " if $allow_erasing;
run($install_cmd . sh_quote($main_rpm));
@@ -455,6 +636,28 @@ sub build_package {
return $ok;
}
# Order the selected packages in waves: a package comes after the selected packages it 'needs'
# (installed into its chroot, see %meta). Needs outside the selection are ignored: the chroot
# then has to provide the module itself (e.g. from EPEL).
sub build_waves {
my ($pkgs) = @_;
my %selected = map { $_ => 1 } @{$pkgs};
my %done;
my @waves;
my @left = @{$pkgs};
while (@left) {
my @ready = grep {
my $p = $_;
!grep { $selected{$_} && !$done{$_} } @{ $meta{$p}{needs} // [] };
} @left;
die "Circular 'needs' among packages: @left\n" if !@ready;
push @waves, \@ready;
$done{$_} = 1 for @ready;
@left = grep { !$done{$_} } @left;
}
return @waves;
}
sub package_uniqueext {
my ($base, $index, $pkg) = @_;
my $tag = lc $pkg;
@@ -472,11 +675,18 @@ sub usage {
Usage: $0 [options]
--work-dir PATH Temporary work dir (default: $work_dir)
--mock-cfg NAME Mock config (default: <ID>+epel-10-<ARCH>)
--noarch-mock-cfg NAME Mock config for the noarch packages (default: --mock-cfg); with a
forcearch --mock-cfg, a native config of the same release builds them
without emulation
--target-arch ARCH Arch of the rpms --mock-cfg produces (default: uname -m); a forcearch
config such as rocky-10-riscv64-xcat needs it
--mock-uniqueext TXT Optional mock --uniqueext suffix to isolate concurrent builds
--jobs N Number of parallel package workers (default: selected package count)
--result-dir PATH Output directory (default: build-output/list6/perl/<ARCH>)
--log-dir PATH Log directory (default: build-logs/list6/perl/<ARCH>)
--packages LIST Comma-separated subset of packages to build
--epel-gap Also build the perl deps of xCAT that EL takes from EPEL (for an arch
without EPEL, e.g. riscv64)
--build-timestamp EPOCH Unix epoch for SOURCE_DATE_EPOCH (deterministic builds)
--skip-install Skip dnf install + perl module import checks
--allow-erasing Allow dnf to erase conflicting packages during install smoke tests
@@ -574,6 +784,22 @@ sub capture {
return $out;
}
# mock exits 30 when its package manager failed (chroot init, build deps), which against public
# mirrors is most often a transient download error (stale mirror metadata): retry such a run once.
sub run_mock {
my ($cmd) = @_;
print "+ $cmd\n";
my $rc = system($cmd);
if ($rc != -1 && ($rc >> 8) == 30) {
print "mock failed with rc=30 (package manager); retrying once\n";
$rc = system($cmd);
}
if ($rc != 0) {
my $exit = $rc == -1 ? 255 : ($rc >> 8);
die "Command failed (rc=$exit): $cmd\n";
}
}
sub run_capture_rc {
my ($cmd, $log_file) = @_;
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
+4
View File
@@ -2,3 +2,7 @@
1. Copy Crypt-Blowfish-2.14.tar.gz to /usr/src/packages/SOURCES/.
2. Copy perl-Crypt-Blowfish.spec to /usr/src/packages/SPECS/
3. Run "rpmbuild -ba /usr/src/packages/SPECS/perl-Crypt-Blowfish.spec" which creates /usr/src/packages/RPMS/x86_64/perl-Crypt-Blowfish-2.14-5.1.x86_64.rpm
perl-Crypt-Blowfish.spec above is a SUSE spec (perl-macros). For RHEL 10 (EPEL-only there), run
"rpmbuild --rebuild perl-Crypt-Blowfish-2.14-25.el10_0.src.rpm" (the EPEL 10 source rpm); its
optional tests need perl(Crypt::CBC) at build time.
+5
View File
@@ -5,3 +5,8 @@
3. Run "rpmbuild -ba /usr/src/packages/SPECS/perl-Crypt-CBC.spec" which creates /usr/src/packages/RPMS/noarch/perl-Crypt-CBC-2.33-3.7.noarch.rpm
For RHEL 8, run "rpmbuild --rebuild perl-Crypt-CBC-2.33-20.fc29.src.rpm".
perl-Crypt-CBC.spec is now the Fedora spec of perl-Crypt-CBC-2.33-20.fc29.src.rpm with the
BuildRequires an EL10 buildroot needs (make, perl-interpreter); the SUSE spec it replaces is in
the git history. For RHEL 10 (EPEL-only there), run "rpmbuild -ba perl-Crypt-CBC.spec" with
Crypt-CBC-2.33.tar.gz in SOURCES.
+199 -159
View File
@@ -1,172 +1,212 @@
#
# spec file for package perl-Crypt-CBC
#
# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
Name: perl-Crypt-CBC
Version: 2.33
Release: 5.26
%define cpan_name Crypt-CBC
Summary: Encrypt Data with Cipher Block Chaining Mode
License: GPL-1.0+ or Artistic-1.0
Group: Development/Libraries/Perl
Url: http://search.cpan.org/dist/Crypt-CBC/
Source: http://www.cpan.org/authors/id/L/LD/LDS/%{cpan_name}-%{version}.tar.gz
BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: perl
BuildRequires: perl-macros
#BuildRequires: perl(Crypt::CBC)
#BuildRequires: perl(Crypt::IDEA)
%{perl_requires}
Summary: Encrypt Data with Cipher Block Chaining Mode
Name: perl-Crypt-CBC
Version: 2.33
Release: 21%{?dist}
# Upstream confirms that they're under the same license as perl.
# Wording in CBC.pm is less than clear, but still.
License: GPL+ or Artistic
Group: Development/Libraries
URL: https://metacpan.org/release/Crypt-CBC
Source0: https://cpan.metacpan.org/authors/id/L/LD/LDS/Crypt-CBC-%{version}.tar.gz
BuildArch: noarch
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
# EL >= 8 buildroots have neither perl nor make by default
BuildRequires: make
BuildRequires: perl-interpreter
BuildRequires: perl-generators
BuildRequires: perl(bytes)
BuildRequires: perl(constant)
BuildRequires: perl(Digest::MD5) >= 2.00
BuildRequires: perl(ExtUtils::MakeMaker)
# Modules used for test suite, skipped when bootstrapping as
# some of these modules use Crypt::CBC themselves
# Crypt::CAST5 not yet packaged in Fedora
# Crypt::IDEA is unavailable due to patents
%if 0%{!?perl_bootstrap:1}
BuildRequires: perl(Crypt::DES)
%if ! (0%{?rhel} >= 7)
BuildRequires: perl(Crypt::Blowfish)
BuildRequires: perl(Crypt::Blowfish_PP)
BuildRequires: perl(Crypt::Rijndael)
%endif
%endif
%description
This module is a Perl-only implementation of the cryptographic cipher block
chaining mode (CBC). In combination with a block cipher such as DES or
IDEA, you can encrypt and decrypt messages of arbitrarily long length. The
encrypted messages are compatible with the encryption format used by the
*OpenSSL* package.
To use this module, you will first create a Crypt::CBC cipher object with
new(). At the time of cipher creation, you specify an encryption key to use
and, optionally, a block encryption algorithm. You will then call the
start() method to initialize the encryption or decryption process, crypt()
to encrypt or decrypt one or more blocks of data, and lastly finish(), to
pad and encrypt the final block. For your convenience, you can call the
encrypt() and decrypt() methods to operate on a whole data value at once.
This is Crypt::CBC, a Perl-only implementation of the cryptographic
cipher block chaining mode (CBC). In combination with a block cipher
such as Crypt::DES or Crypt::IDEA, you can encrypt and decrypt
messages of arbitrarily long length. The encrypted messages are
compatible with the encryption format used by SSLeay.
%prep
%setup -q -n %{cpan_name}-%{version}
%setup -q -n Crypt-CBC-%{version}
chmod 644 eg/*.pl
%build
%{__perl} Makefile.PL INSTALLDIRS=vendor
%{__make} %{?_smp_mflags}
%check
%{__make} test
make
%install
%perl_make_install
%perl_process_packlist
%perl_gen_filelist
rm -rf $RPM_BUILD_ROOT
make pure_install DESTDIR=$RPM_BUILD_ROOT
find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';'
%{_fixperms} $RPM_BUILD_ROOT
%files -f %{name}.files
%defattr(-,root,root,755)
%doc Changes Crypt-CBC-2.16-vulnerability.txt README
%check
make test
%files
%doc Changes README eg/
%{perl_vendorlib}/Crypt/
%{_mandir}/man3/*.3*
%changelog
* Tue Aug 6 2013 coolo@suse.com
- updated to 2.33
- Fix minor RT bugs 83175 and 86455.
* Mon Jun 3 2013 coolo@suse.com
- updated to 2.32
- Fixes "Taint checks are turned on and your key is tainted" error when autogenerating salt and IV.
- Fixes to regular expressions to avoid rare failures to
correctly strip padding in decoded messages.
- Add padding type = "none".
- Both fixes contributed by Bas van Sisseren.
* Fri Nov 18 2011 coolo@suse.com
- use original .tar.gz
* Fri Aug 26 2011 chris@computersalat.de
- remove Author from desc
- added bcond_with opt
o test optional pkgs via local build (osc build --with opt)
- fix deps for CentOS
- some spec cleanup
* Wed Dec 8 2010 coolo@novell.com
- avoid even more requires to avoid even more cycles
* Tue Nov 30 2010 coolo@novell.com
- remove extra requires to avoid cycle
* Wed Nov 24 2010 chris@computersalat.de
- recreated by cpanspec 1.78
o fix deps
- noarch pkg
* Sun Jan 10 2010 jengelh@medozas.de
- enable parallel build
* Fri Feb 27 2009 anicka@suse.cz
- update to 2.30
* setting $cipher correctly
* Thu Jun 19 2008 anicka@suse.cz
* Thu Aug 20 2026 xCAT build - 2.33-21
- Fedora spec from perl-Crypt-CBC-2.33-20.fc29.src.rpm, with BuildRequires make
and perl-interpreter so it builds in an EL10 buildroot
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.33-20
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Sat Jun 30 2018 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-19
- Perl 5.28 re-rebuild of bootstrapped packages
* Wed Jun 27 2018 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-18
- Perl 5.28 rebuild
* Thu Feb 08 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.33-17
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Thu Jul 27 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.33-16
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Wed Jun 07 2017 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-15
- Perl 5.26 re-rebuild of bootstrapped packages
* Sun Jun 04 2017 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-14
- Perl 5.26 rebuild
* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.33-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Wed May 18 2016 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-12
- Perl 5.24 re-rebuild of bootstrapped packages
* Sun May 15 2016 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-11
- Perl 5.24 rebuild
* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 2.33-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Thu Jun 18 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.33-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Wed Jun 10 2015 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-8
- Perl 5.22 re-rebuild of bootstrapped packages
* Wed Jun 03 2015 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-7
- Perl 5.22 rebuild
* Sun Sep 07 2014 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-6
- Perl 5.20 re-rebuild of bootstrapped packages
* Wed Aug 27 2014 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-5
- Perl 5.20 rebuild
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.33-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Wed Aug 14 2013 Jitka Plesnikova <jplesnik@redhat.com> - 2.33-3
- Perl 5.18 re-rebuild of bootstrapped packages
* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.33-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
* Tue Jul 30 2013 Paul Howarth <paul@city-fan.org> - 2.33-1
- Update to 2.33
- Fixes to regular expressions to avoid rare failures to correctly strip
padding in decoded messages
- Add padding type = "none"
- Fix "Taint checks are turned on and your key is tainted" error when
autogenerating salt and IV
- Fix minor bugs CPAN RT#83175 and CPAN RT#86455
- Don't need to remove empty directories from the buildroot
- Drop %%defattr, redundant since rpm 4.4
- Use %%{_fixperms} macro rather than our own chmod incantation
- Use DESTDIR rather than PERL_INSTALL_ROOT
* Thu Jul 18 2013 Petr Pisar <ppisar@redhat.com> - 2.29-16
- Perl 5.18 rebuild
* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.29-15
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
* Fri Jul 20 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.29-14
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
* Tue Jul 10 2012 Petr Pisar <ppisar@redhat.com> - 2.29-13
- Perl 5.16 re-rebuild of bootstrapped packages
* Mon Jun 11 2012 Petr Pisar <ppisar@redhat.com> - 2.29-12
- Perl 5.16 rebuild
* Mon Jun 11 2012 Marcela Mašláňová <mmaslano@redhat.com> - 2.29-11
- Do not build-require Crypt::Blowfish, Crypt::Blowfish_PP, and Crypt::Rijndael
on RHEL >= 7
- Resolves: rhbz#822812
* Sat Apr 21 2012 Paul Howarth <paul@city-fan.org> - 2.29-10
- BR: perl(bytes), perl(constant), perl(Digest::MD5) - required by module
- BR: perl(Crypt::Blowfish), perl(Crypt::Blowfish_PP), perl(Crypt::DES),
perl(Crypt::Rijndael) for improved test coverage, except when bootstrapping
* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.29-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
* Fri Jun 17 2011 Marcela Mašláňová <mmaslano@redhat.com> - 2.29-8
- Perl mass rebuild
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.29-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
* Wed Dec 15 2010 Marcela Maslanova <mmaslano@redhat.com> - 2.29-6
- Rebuild to fix problems with vendorarch/lib (#661697)
* Fri Apr 30 2010 Marcela Maslanova <mmaslano@redhat.com> - 2.29-5
- Mass rebuild with perl-5.12.0
* Fri Dec 4 2009 Stepan Kasal <skasal@redhat.com> - 2.29-4
- rebuild against perl 5.10.1
* Sat Jul 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.29-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
* Thu Feb 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.29-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
* Fri Jul 11 2008 Tom "spot" Callawau <tcallawa@redhat.com> - 2.29-1
- update to 2.29
* Fixed errors that occurred when encrypting/decrypting utf8
strings in Perl's more recent than 5.8.8.
* Wed Apr 2 2008 anicka@suse.cz
- update to 2.28
- Fixed bug in onesandzeroes test that causes it to fail
with Rijndael module is not installed.
- When taint mode is turned on and user is using a tainted key,
explicitly check tainting of key in order to avoid "cryptic"
failure messages from some crypt modules.
- Fixed onezeropadding test, which was not reporting
its test count properly.
- Fixed failure of oneandzeroes padding when plaintext size is
an even multiple of blocksize.
- Added new "rijndael_compat" padding method, which is compatible
with the oneandzeroes padding method used by Crypt::Rijndael in
CBC mode.
* Mon Oct 8 2007 anicka@suse.cz
- update to 2.24
* Fixed failure to run under taint checks with Crypt::Rijndael
or Crypt::OpenSSL::AES (and maybe other Crypt modules).
* Added checks for other implementations of CBC which add no
standard padding at all when cipher text is an even multiple
of the block size.
* Tue Dec 12 2006 anicka@suse.cz
- update to 2.22
* Fixed bug in which plaintext encrypted with the
- literal_key option could not be decrypted using a new
object created with the same -literal_key.
* Added documentation confirming that -literal_key must be
accompanied by a -header of 'none' and a manually specificied IV.
* Thu Oct 19 2006 anicka@suse.cz
- update to 2.21
* Fixed bug in which new() failed to work when first option is
- literal_key.
* Added ability to pass a preinitialized Crypt::* block cipher
object instead of the class name.
* Thu Sep 14 2006 anicka@suse.cz
- update to 2.19
* Renamed Crypt::CBC-2.16-vulnerability.txt so that
package installs correctly under Cygwin
* Fri Jul 14 2006 anicka@suse.cz
- update to 2.18
* added lots of documentation
* fixed using 8 byte IVs when generating the old-style RandomIV
style header for the Rijndael algorithm.
* versions 2.17 and higher will not decrypt messages
encrypted with versions 2.16 and lower unless you pass
an optional value 'randomiv' to the new() call
* Wed Apr 5 2006 schubi@suse.de
- Bug 153627 - VUL-0: perl-Crypt-CBC: ciphertext weakness when using certain block algorithms
* Wed Jan 25 2006 mls@suse.de
- converted neededforbuild to BuildRequires
* Mon Jul 11 2005 schubi@suse.de
- update to 2.14
* Fri Apr 15 2005 schubi@suse.de
- update to 2.12
* Sun Jan 11 2004 adrian@suse.de
- build as user
* Fri Aug 22 2003 mjancar@suse.cz
- require the perl version we build with
* Fri Jul 18 2003 choeger@suse.de
- use install_vendor and new %%perl_process_packlist macro
* Tue Jun 17 2003 choeger@suse.de
- updated filelist
- update to version 2.08
* Mon May 19 2003 choeger#@suse.de
- remove installed (but unpackaged) file perllocal.pod
* Wed Aug 14 2002 choeger@suse.de
- new package, version 2.07
* Mon Mar 3 2008 Tom "spot" Callaway <tcallawa@redhat.com> - 2.22-3
- work around buildsystem burp
* Fri Feb 8 2008 Tom "spot" Callaway <tcallawa@redhat.com> - 2.22-2
- rebuild for new perl
* Mon Oct 15 2007 Tom "spot" Callaway <tcallawa@redhat.com> - 2.22-1.1
- add BR: perl(ExtUtils::MakeMaker)
* Wed Feb 07 2007 Andreas Thienemann <andreas@bawue.net> - 2.22-1
- Upgrade to 2.22
* Fri Sep 08 2006 Andreas Thienemann <andreas@bawue.net> - 2.19-1
- Upgrade to 2.19
* Fri Feb 24 2006 Andreas Thienemann <andreas@bawue.net> - 2.17-1
- Upgrade to 2.17
* Thu Jul 14 2005 Andreas Thienemann <andreas@bawue.net> - 2.14-2
- Remove execute permissions from example files
* Thu Jul 14 2005 Andreas Thienemann <andreas@bawue.net> - 2.14-1
- Initial package
+21 -3
View File
@@ -14,17 +14,29 @@
name: perl-Net-DNS
summary: Net-DNS - Perl DNS resolver module
version: 0.80
release: 1
release: 2
vendor: Olaf Kolkman <olaf@net-dns.org>
packager: Arix International <cpan2rpm@arix.com>
license: Artistic
group: Applications/CPAN
url: http://www.cpan.org
buildroot: %{_tmppath}/%{name}-%{version}-%(id -u -n)
buildarch: x86_64
buildarch: noarch
prefix: %(echo %{_prefix})
source: Net-DNS-0.80.tar.gz
# cpan2rpm specs carry no BuildRequires; an EL10 buildroot has neither perl nor make, and
# perl-generators is what makes rpm compute the perl(...) Requires.
BuildRequires: make
BuildRequires: perl-interpreter
BuildRequires: perl-generators
BuildRequires: perl(ExtUtils::MakeMaker)
BuildRequires: perl(Digest::HMAC)
BuildRequires: perl(Digest::MD5)
BuildRequires: perl(Digest::SHA)
BuildRequires: perl(MIME::Base64)
BuildRequires: perl(Test::More)
%description
Net::DNS is a collection of Perl modules that act as a Domain Name System
(DNS) resolver. It allows the programmer to perform DNS queries that are
@@ -49,7 +61,8 @@ grep -rsl '^#!.*perl' . |
grep -v '.bak$' |xargs --no-run-if-empty \
%__perl -MExtUtils::MakeMaker -e 'MY->fixin(@ARGV)'
CFLAGS="$RPM_OPT_FLAGS"
%{__perl} Makefile.PL `%{__perl} -MExtUtils::MakeMaker -e ' print qq|PREFIX=%{buildroot}%{_prefix}| if \$ExtUtils::MakeMaker::VERSION =~ /5\.9[1-6]|6\.0[0-5]/ '`
# --noxs: pure-perl Net::DNS (no compiled dn_expand), so one noarch rpm serves every arch
%{__perl} Makefile.PL --noxs `%{__perl} -MExtUtils::MakeMaker -e ' print qq|PREFIX=%{buildroot}%{_prefix}| if \$ExtUtils::MakeMaker::VERSION =~ /5\.9[1-6]|6\.0[0-5]/ '`
%{__make}
%if %maketest
%{__make} test
@@ -126,5 +139,10 @@ find %{buildroot}%{_prefix} \
%defattr(-,root,root)
%changelog
* Thu Aug 20 2026 xCAT build - 0.80-2
- Build the pure-perl module (--noxs) as noarch instead of an XS x86_64 rpm.
- BuildRequires for an EL10 buildroot (make, perl-interpreter, perl-generators,
MakeMaker, Digest::HMAC/MD5/SHA, MIME::Base64, Test::More).
* Tue Oct 28 2014 root@slesmn
- Initial build.
+4
View File
@@ -0,0 +1,4 @@
perl-Net-IP (Net::IP, used by xCAT::NetworkUtils) is EPEL-only on EL10. The source rpm is
the EPEL 10 one (Fedora spec, Net-IP 1.26, noarch).
For RHEL 10, run "rpmbuild --rebuild perl-Net-IP-1.26-30.el10_0.src.rpm".
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
perl-Path-Class (Path::Class) is only a build dependency: Crypt-SSLeay's Makefile.PL uses it
(configure_requires), and EL10 has it in EPEL only. The source rpm is the EPEL 10 one (Fedora
spec, Path-Class 0.37, noarch). mockbuild-perl-packages.pl builds it where there is no EPEL
(--epel-gap) and installs it into the perl-Crypt-SSLeay build chroot.
For RHEL 10, run "rpmbuild --rebuild perl-Path-Class-0.37-24.el10_0.src.rpm".