diff --git a/MockBuildUtils.pm b/MockBuildUtils.pm index aa9065b..a03c2f7 100644 --- a/MockBuildUtils.pm +++ b/MockBuildUtils.pm @@ -20,7 +20,7 @@ our @EXPORT_OK = qw( parse_evr evr_cmp evr_constraint_ok parse_pin rpmkeys_checksig_problem rpm_version rpm_release rpm_sigmd5 rpm_is_signed restamp_release_line cross_copy_genesis finalize_xcat_dep bump_dep_release_suffix - build_mock_uniqueext + build_mock_uniqueext rpm_arch rpm_in_cell ); # install_deps_packages($os_id): the host packages mockbuild-all.pl needs to run at all, for the @@ -568,6 +568,32 @@ sub bump_dep_release_suffix { # their roots apart, so three concurrent el8/el9/el10 ppc64le goconserver builds race in one root. # When the id is too long, keep a readable leading token AND append a short digest of the FULL id, so # distinct ids always yield distinct uniqueext regardless of where in the string they differ. +# rpm_arch($rpm): the architecture of an rpm. The header decides when the file can be read, so a +# renamed file does not pass for another architecture; a bare file name falls back to its suffix. +sub rpm_arch { + my ($rpm) = @_; + return unless defined $rpm; + if (-f $rpm) { + my $arch = `rpm -qp --qf '%{ARCH}' ${\ sh_quote($rpm)} 2>/dev/null`; + chomp $arch; + return $arch if $arch ne ''; + } + my ($arch) = $rpm =~ /\.([A-Za-z0-9_]+)\.rpm$/; + return $arch; +} + +# rpm_in_cell($rpm, $target_arch): whether an rpm belongs in the repository cell of $target_arch. +# A noarch builder run in another architecture's chroot (the x86 boot loaders for riscv64) can +# emit that chroot's native rpms beside the noarch one; only noarch and the cell's own +# architecture are kept. +sub rpm_in_cell { + my ($rpm, $target_arch) = @_; + my $arch = rpm_arch($rpm); + return 0 unless defined $arch && defined $target_arch; + return 1 if $arch eq 'noarch'; + return $arch eq $target_arch ? 1 : 0; +} + sub build_mock_uniqueext { my ($run, $seq, $label) = @_; diff --git a/mockbuild-all.pl b/mockbuild-all.pl index cfd532c..6f97fd0 100755 --- a/mockbuild-all.pl +++ b/mockbuild-all.pl @@ -15,7 +15,7 @@ use Parallel::ForkManager; use POSIX qw(strftime); use FindBin qw($RealBin); use lib $RealBin, "$RealBin/lib"; -use MockBuildUtils qw(sh_quote print_step version_matches required_pkgs +use MockBuildUtils qw(sh_quote print_step version_matches required_pkgs rpm_in_cell install_deps_packages install_deps_command missing_perl_modules read_manifest verify_repo_packages verify_repo_signature verify_rpm_signatures rpm_version rpm_release rpm_sigmd5 restamp_release_line @@ -848,11 +848,13 @@ print_step('Collect RPM artifacts'); print "collection roots:\n"; print " $_\n" for @collect_roots; -my ($copied, $skipped_src, $missing_roots) = collect_rpms( +my ($copied, $skipped_src, $missing_roots, $skipped_foreign) = collect_rpms( roots => \@collect_roots, dest_dir => $repo_dir, + arch => $arch, dry_run => $dry_run, ); +print "skipped $skipped_foreign rpm(s) of another architecture\n" if $skipped_foreign; # Assert on what this run BUILT, before the Genesis release is added: the release is # installed from a verified directory rather than built here, so counting it first would @@ -1970,11 +1972,13 @@ sub collect_rpms { my (%args) = @_; my $roots = $args{roots} // []; my $dest = $args{dest_dir} // die "collect_rpms missing dest_dir\n"; + my $cell_arch = $args{arch} // die "collect_rpms missing arch\n"; my $is_dry = $args{dry_run} ? 1 : 0; my %seen; my $copied = 0; my $skipped_src = 0; + my $skipped_foreign = 0; my $missing_roots = 0; for my $root (@{$roots}) { @@ -2002,6 +2006,10 @@ sub collect_rpms { my $base = basename($rpm); next if $genesis_release && $base =~ /^xCAT-genesis-openembedded-/; + if (!rpm_in_cell($rpm, $cell_arch)) { + $skipped_foreign++; + next; + } next if $seen{$base}++; if ($is_dry) { print "DRY-RUN copy: $rpm -> $dest/$base\n"; @@ -2014,7 +2022,7 @@ sub collect_rpms { } } - return ($copied, $skipped_src, $missing_roots); + return ($copied, $skipped_src, $missing_roots, $skipped_foreign); } sub collect_srpms {