diff --git a/build-utils/lib/XCAT/BuildUtils.pm b/build-utils/lib/XCAT/BuildUtils.pm index 91e2bb792..4a16b29f2 100644 --- a/build-utils/lib/XCAT/BuildUtils.pm +++ b/build-utils/lib/XCAT/BuildUtils.pm @@ -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. diff --git a/buildrpms.pl b/buildrpms.pl index 3c623dd07..b08feee60 100755 --- a/buildrpms.pl +++ b/buildrpms.pl @@ -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 --