2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-10-21 15:18:19 +00:00

fix(xcat-core): mock cannot read the sources staged under /root

buildrpms.pl staged each build's sources under $HOME/rpmbuild/sources.
mock now builds as the chrootuid of the target, uid 1000 for openEuler
24.03. On the Jenkins agents HOME is /root, mode 0550, so mock --sources
failed with "Permission denied" on the staging directory.

The staging directories now go under dist/sources in the checkout, next
to the mock result directories. The per-process names, the delete on
reap and the sweep of dead pids stay the same. buildrpms.pl makes the
staging tree readable by every user after it stages the sources, so the
umask of the build does not decide what mock can read.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-10-08 13:31:43 -03:00
parent e5137981ff
commit f71aabd027
2 changed files with 38 additions and 9 deletions
+36 -8
View File
@@ -14,7 +14,9 @@ package XCAT::BuildUtils;
use strict;
use warnings;
use Exporter 'import';
use Cwd ();
use File::Copy qw(copy move);
use File::Find qw(find);
use File::Basename qw(basename);
use File::Path qw(make_path remove_tree);
use File::Temp qw(tempdir tempfile);
@@ -34,7 +36,7 @@ our @EXPORT_OK = qw(
reprepro_distributions reprepro_options
lock_id_for take_build_lock
build_sources_base build_sources_dir prepare_build_sources_dir
remove_build_sources_dir sweep_build_sources_dirs
remove_build_sources_dir sweep_build_sources_dirs share_build_sources_dir
sh_quote clean_debian_residue git_revision
backup_file restore_file
sh sh_or_die usage
@@ -981,18 +983,19 @@ sub genesis_log_errors {
Descriptions: The directory that holds the per-process rpmbuild SOURCES directories.
Arguments:
$home - the home directory; defaults to $ENV{HOME}
$checkout - the source checkout; defaults to the working directory
Returns: the absolute path of the base directory.
=cut
#-------------------------------------------------------------------------------
# mock reads the sources as chrootuid, and $HOME of a root build is /root, mode 0550.
sub build_sources_base {
my ($home) = @_;
$home = $ENV{HOME} unless defined $home && length $home;
die "build_sources_base: no home directory\n" unless defined $home && length $home;
return "$home/rpmbuild/sources";
my ($checkout) = @_;
$checkout = Cwd::getcwd() unless defined $checkout && length $checkout;
die "build_sources_base: no checkout directory\n" unless defined $checkout && length $checkout;
return "$checkout/dist/sources";
}
#-------------------------------------------------------------------------------
@@ -1013,7 +1016,7 @@ Returns: the absolute path of the staging directory.
#-------------------------------------------------------------------------------
# Keyed by the process that stages. buildrpms.pl forks a child per package and target,
# and mock --sources copies the whole directory, so a shared directory lets a peer's tar
# truncate an archive mid-copy. A pid is unique only on one host, and $HOME can be on NFS.
# truncate an archive mid-copy. A pid is unique only on one host, and the checkout can be on NFS.
sub build_sources_dir {
my ($base, $pid, $host) = @_;
die "build_sources_dir: no base directory\n" unless defined $base && length $base;
@@ -1047,13 +1050,38 @@ sub prepare_build_sources_dir {
my $dir = build_sources_dir(@_);
# A directory with this name belongs to a dead process that had the same pid.
remove_tree($dir) if -e $dir;
make_path($dir);
chmod 0755, make_path($dir), $dir;
die "build_sources_dir: $dir was not created\n" unless -d $dir;
return $dir;
}
#-------------------------------------------------------------------------------
=head3 share_build_sources_dir
Descriptions: Make a staging directory and its contents readable by every user,
whatever the umask was when they were written.
Arguments:
$dir - the directory from prepare_build_sources_dir
Returns: nothing.
=cut
#-------------------------------------------------------------------------------
# mock copies --sources into the chroot as chrootuid, not as the uid that staged them.
sub share_build_sources_dir {
my ($dir) = @_;
find({ no_chdir => 1, wanted => sub {
return if -l $_;
my $mode = (lstat $_)[2] & 07777;
chmod $mode | (-d _ ? 0555 : 0444), $_;
} }, $dir);
}
#-------------------------------------------------------------------------------
=head3 remove_build_sources_dir
Descriptions: Delete the staging directory of one build process.
+2 -1
View File
@@ -55,7 +55,7 @@ use File::Temp qw(tempdir tempfile);
use FindBin qw($Bin);
use lib "$Bin/build-utils/lib";
use XCAT::BuildUtils qw(git_revision source_date_epoch sh sh_or_die usage buildinfo_text
build_sources_base prepare_build_sources_dir remove_build_sources_dir
build_sources_base prepare_build_sources_dir remove_build_sources_dir share_build_sources_dir
sweep_build_sources_dirs stage_xcat_probe_sources stage_xcatsn_templates
stage_genesis_base_sources
write_script read_line targetarch_from_target
@@ -528,6 +528,7 @@ sub buildall {
createmockconfig($pkg, $target);
prepare_mock_resultdirs($pkg, $target);
buildsources($pkg, $target);
share_build_sources_dir($SOURCES);
buildspkgs($pkg, $target);
# --source-only stops here: buildspkgs has produced the src.rpm, and the binary
# rebuild is the only thing buildpkgs does. Everything upstream of this point --