aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorent Villard <warly@mandriva.com>2006-01-28 20:47:32 +0000
committerFlorent Villard <warly@mandriva.com>2006-01-28 20:47:32 +0000
commitcc813080359c6b96cddf4da4e98ba6a239404ba9 (patch)
tree92a77129a2758bd06ef23aeb3f35dcd2b644b166
parent599f1db48f58544a4d505020e8bd740282e6f3d2 (diff)
downloadiurt-cc813080359c6b96cddf4da4e98ba6a239404ba9.tar
iurt-cc813080359c6b96cddf4da4e98ba6a239404ba9.tar.gz
iurt-cc813080359c6b96cddf4da4e98ba6a239404ba9.tar.bz2
iurt-cc813080359c6b96cddf4da4e98ba6a239404ba9.tar.xz
iurt-cc813080359c6b96cddf4da4e98ba6a239404ba9.zip
Major revamping of the iurt code, use mkcd parsecommandline, add more function, make it more generic
-rwxr-xr-xiurt2773
1 files changed, 419 insertions, 354 deletions
diff --git a/iurt2 b/iurt2
index 3e81a1b..07530e2 100755
--- a/iurt2
+++ b/iurt2
@@ -1,9 +1,9 @@
#!/usr/bin/perl
#
# Copyright (C) 2005 Mandrakesoft
-# Copyright (C) 2005 Mandriva
+# Copyright (C) 2005,2006 Mandriva
#
-# Author: Florent Villard <warly@mandraesoft.com>
+# Author: Florent Villard <warly@mandriva.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -32,37 +32,94 @@ use URPM;
use File::NCopy qw(copy);
use MIME::Words qw(encode_mimewords);
use Fcntl ':flock';
+use Mkcd::Commandline qw(parseCommandLine usage);
+
+my $program_name = 'iurt';
+# sessing parameters
+my $arg = @ARGV;
+my (@params, %run);
+$run{todo} = [ ];
+@params = (
+ # [ "one letter option", "long name option", "number of args (-X means ´at least X´)", "help text", "function to call", "log info"]
+ [ "", "$program_name", 0, "[options]",
+ "$program_name rebuild bot",
+ sub { $arg or usage($program_name, \@params) }, "" ],
+ [ "", "cache", 0, "",
+ "Use the global cache file",
+ sub { $run{cache} = 1 }, "Activating cache use" ],
+ [ "c", "chroot", 0, "",
+ "Check chroot and update it if needed",
+ sub { $run{chroot} = 1 }, "Activating debug mode" ],
+ [ "", "config_help", 0, "",
+ "Explain configuration files keywords",
+ sub { $run{config_usage} = 1 }, "Activating debug mode" ],
+ [ "", "debug", 0, "",
+ "Activate debug mode",
+ sub { $run{debug} = 1 }, "Activating debug mode" ],
+ [ "u", "unionfs", 0, "",
+ "Activate unionfs mode",
+ sub { $run{unionfs} = 1 }, "Activating unionfs mode" ],
+ [ "l", "log", 1, "<log file>",
+ "Log file.",
+ sub {
+ $run{log} = pop @_;
+ open $run{LOG}, ">$run{log}" or die "unable to open $run{log}\n";
+ print *{$run{LOG}}, "command line: @ARGV\n"
+ }, "Log file" ],
+ [ "m", "media", -1, "",
+ "Media to rebuild",
+ sub { ($run{media}) = @_ }, "Adding a media to rebuild" ],
+ [ "r", "rebuild", -2, "<distro> <architecture> <srpm 1> <srpm 2> ... <srpm n>",
+ "Rebuild the packages, e.g. $program_name -r cooker x86_64 /home/foo/rpm/SRPMS/foo-2.3-12mdk.src.rpm",
+ sub {
+ $run{rebuild} = 1;
+ $run{distro} = shift @_;
+ $run{my_arch} = shift @_;
+ foreach (@_) {
+ if (m,(.*/)([^/]*.src.rpm)$, && -f $_) {
+ push @{$run{todo}}, [ $1, $2 ];
+ print {$run{LOG}} "iurt: force build for $2 (from $1)\n";
+ 0
+ } else {
+ die "FATAL iurt: $_ does not seems to be a SRPM\n"
+ }
+ }
+ }, "Activating rebuild mode" ],
+ [ "", "upload", [
+ ["", "upload", 0, "[options]",
+ "Upload the rebuild packages",
+ sub { my ($tmp) = @_;
+ $tmp->[0] ||= {};
+ 1
+ }, "Setting upload options"],
+ [ "m", "markrelease", 0, "",
+ "Mark SVN directory when uploading the packages",
+ sub { $run{markrelease} = 1 }, "Adding markrelease repsys option" ],
+ ], "[options]",
+ "Upload the rebuild packages",
+ sub { $run{upload} = 1 }, "Setting the upload flag" ],
+ [ "w", "warn", 0, "",
+ "Warn maintainer of the packages about problem in the rebuild",
+ sub { $run{warn} = @_ }, "Setting warn flag to warn maintainers" ],
+ [ "d", "dir", -1, "",
+ "Directory where to find packages to rebuild",
+ sub { $run{extra_dir} = @_ }, "Adding extra source packages directories" ],
+);
-# maybe time to switch to mkcd::parse_command_line
-my ($debug, $unionfs, $nocheckchroot, $force_build, @todo, $config_usage);
-my @argv = grep {
- if ($force_build && !/--/) {
- if (m,(.*/)([^/]*.src.rpm)$, && -f $_) {
- push @todo, [ $1, $2 ];
- print STDERR "iurt: force build for $2 (from $1)\n";
- 0
- } else {
- die "FATAL iurt: $_ does not seems to be a SRPM\n"
- }
- } else {
- $force_build = 0;
- if (/--debug/) { $debug = 1; 0 }
- elsif (/--unionfs/) { $unionfs = 1; 0 }
- elsif (/--nocheckchroot/) { $nocheckchroot = 1; 0 }
- elsif (/--force_build/) { $force_build = 1; 0 }
- elsif (/--help/) { usage(); 0 }
- elsif (/--config_help/) { $config_usage = 1; 0 }
- elsif (/--./) { usage("$_ is an unknown option") }
- else { 1 }
- }
-} @ARGV;
-
-my $distro_version = shift @argv;
-my $distro_tag = $distro_version;
-$distro_tag =~ s,/,-,g;
-my $my_arch = shift @argv;
-my $media = shift @argv;
-my @special_srpm_dir = @argv;
+open(my $LOG, ">&$run{LOG}");
+$run{LOG} = $LOG;
+
+my $todo = parseCommandLine("$program_name", \@ARGV, \@params);
+@ARGV and usage("$program_name", \@params, "@ARGV, too many arguments");
+foreach my $t (@$todo) {
+ print {$run{LOG}} "$program_name: $t->[2]\n";
+ &{$t->[0]}(@{$t->[1]}) or print {$run{LOG}} "ERROR: $t->[2]\n";
+}
+
+# maybe time to switch to $program_name::parse_command_line
+
+$run{distro_tag} = $run{distro};
+$run{distro_tag} =~ s,/,-,g;
my $urpmi_options = "-v --no-verify-rpm --nolock --auto";
my $real_arch = `uname -m`;
@@ -76,8 +133,8 @@ my %arch_comp = (
);
my $HOME = $ENV{HOME};
-my $configfile = "$HOME/.iurt.$distro_tag.conf";
-print STDERR "iurt: loading config file $configfile\n";
+my $configfile = "$HOME/.iurt.$run{distro_tag}.conf";
+print {$run{LOG}} "iurt: loading config file $configfile\n";
my $config;
if (-f $configfile) {
$config = do $configfile or die "FATAL iurt: syntax error in $configfile";
@@ -86,240 +143,114 @@ if (-f $configfile) {
}
my %config_usage = (
- home => { desc => 'Home dir', default => $HOME },
+ admin => { desc => 'Mail of the administrator of packages builds', default => '' },
+ all_media => { desc => 'List of known media', default => [ 'main', 'contrib' ] },
+ basesystem_media => { desc => 'Where to find basesystem packages', default => "$config->{repository}/$run{distro}/$run{my_arch}/media/main/" },
cache_home => { desc => 'Where to store the cache files', default => "$HOME/.bugs" },
- supported_arch => { desc => 'Table of supported architecture', default => ['i586', 'x86_64'] },
- upload => { desc => 'Where to copy build packages', default => "$HOME/uploads/" },
- local_home => { desc => 'Where to build packages', default => $HOME },
- repository => { desc => 'Prefix of the repositories', default => '/mnt/BIG/dis/' },
- packager => { desc => 'Name of the build bot', default => 'Iurt' },
- install_chroot_binary => { desc => 'Tool used to create initial chroot', default => 'install-chroot-tar.sh' },
distribution => { desc => 'Name of the packages distribution', default => 'Mandriva Linux' },
- vendor => { desc => 'Name of the packages vendor', default => 'Mandriva' },
- basesystem_media => { desc => 'Where to find basesystem packages', default => "$config->{repository}/$distro_version/$my_arch/media/main/" },
- all_media => { desc => 'List of known media', default => [ 'main', 'contrib' ] },
+ home => { desc => 'Home dir', default => $HOME },
+ install_chroot_binary => { desc => 'Tool used to create initial chroot', default => 'install-chroot-tar.sh' },
+ local_home => { desc => 'Where to build packages', default => $HOME },
log_size_limit => { desc => 'Maximum authorized size for a log file', default => '100M' },
log_size_date => { desc => 'Number of days log should be kept', default => '30' },
- no_mail => { desc => 'Hash table with people mail address where we should not send any mails', default => {} },
minimum_package_number => { "Minimum number of packages in a synthesis file to consider it valid", default => 1000 },
+ no_mail => { desc => 'Hash table with people mail address where we should not send any mails', default => {} },
+ packager => { desc => 'Name of the build bot', default => 'Iurt' },
+ repository => { desc => 'Prefix of the repositories', default => '/mnt/BIG/dis/' },
+ rsync_to => { desc => 'Server where the result of the builds should be rsynced (name@server:path format)', default => ''},
+ sendmail => { desc => 'If the bot will send mail reports regarding build', default => 0 },
+ supported_arch => { desc => 'Table of supported architecture', default => ['i586', 'x86_64'] },
+ upload => { desc => 'Where to copy build packages', default => "$HOME/uploads/" },
+ vendor => { desc => 'Name of the packages vendor', default => 'Mandriva' },
);
-config_usage() if $config_usage;
-$my_arch or usage("no architecture given (media $media, my_arch $my_arch, todo @todo)");
-if (!$arch_comp{$real_arch}{$my_arch}) {
- die "FATAL iurt: could not compile $my_arch binaries on a $real_arch"
+config_usage() if $run{config_usage};
+$run{my_arch} or usage("no architecture given (media $run{media}, run{my_arch} $run{my_arch}, todo @{$run{todo}})");
+if (!$arch_comp{$real_arch}{$run{my_arch}}) {
+ die "FATAL iurt: could not compile $run{my_arch} binaries on a $real_arch"
}
foreach my $k (keys %config_usage) {
$config->{$k} ||= $config_usage{$k}{default}
}
-$config->{upload} .= $distro_version;
+$config->{upload} .= $run{distro};
$config->{upload} =~ s/community//g;
-if ($distro_version ne 'cooker') {
- if ($media ne 'main') {
- $config->{upload} .= "/$media"
+if ($run{distro} ne 'cooker') {
+ if ($run{media} ne 'main') {
+ $config->{upload} .= "/$run{media}"
}
-} elsif ($media eq 'contrib') {
+} elsif ($run{media} eq 'contrib') {
$config->{upload} =~ s/cooker/contrib/g;
}
-d $config->{upload} or usage("$config->{upload} does not exist");
-my $pidfile = "$config->{cache_home}/iurt.$distro_tag.$my_arch.pid";
-if (!$debug) {
- open my $lock, "$pidfile.lock";
- flock($lock,LOCK_EX);
- if (-f $pidfile) {
- my (@stat) = stat $pidfile;
- open my $test_PID, $pidfile;
- my $pid = <$test_PID>;
- close $test_PID;
- if ($pid && getpgrp $pid != -1) {
- my $time = $stat[9];
- if ($time < time - 36000) {
- print STDERR "iurt: an other iurt pid $pid is running for a very long time, killing it\n";
- my $i;
- while ($i < 5 && getpgrp $pid != -1) {
- kill_for_good($pid);
- $i++;
- sleep 1
- }
- } else {
- print STDERR "iurt: an other iurt is running for $my_arch, pid $pid, since ",time - $time," seconds\n";
- exit
- }
- } else {
- print STDERR "iurt: a previous iurt for $my_arch seems dead, cleaning.\n";
- unlink $pidfile
- }
- }
- open my $PID, ">$pidfile" or die "FATAL iurt: could not open pidfile $pidfile for writing";
- print $PID $$;
- close $PID;
+if (!$run{debug} && $run{media} || $run{chroot}) {
+ $run{pidfile} = "$config->{cache_home}/iurt.$run{distro_tag}.$run{my_arch}.pid";
+ check_pid(\%run)
+}
- flock($lock,LOCK_UN);
- close $lock;
+
+my $debug_tag = '_debug' if $run{debug};
+my $chroot = "$config->{local_home}/chroot$debug_tag";
+my $chroot_tar = "$chroot-$run{distro_tag}.$run{my_arch}.tar.gz";
+if ($run{chroot}) {
+ check_chroot($chroot, $chroot_tar, \%run)
}
-my $cachefile = "$config->{cache_home}/iurt.$distro_tag.$my_arch.cache";
-print STDERR "iurt: loading cache file $cachefile\n";
+my $cachefile = "$config->{cache_home}/iurt.$run{distro_tag}.$run{my_arch}.cache";
my $cache;
-if (-f $cachefile) {
+if (-f $cachefile || $run{cache}) {
+ print {$run{LOG}} "iurt: loading cache file $cachefile\n";
$cache = do $cachefile
} else {
$cache = { rpm_srpm => {}, failure => {}, queue => {}, warning => {}, run => 0, needed => {}, no_unionfs => {} }
}
-my %big;
-my %srpm_version;
-my @wrong_rpm;
-# FIXME need to check if scanning all the architecture is needed (except of noarch unsynchronity this should not be mandatory)
-# in that case, @supported_arch may be removed
-#
-#foreach my $arch (@{$config->{supported_arch}}) {
-#
-# We could rely on only parsing the synthesis, hoping that they are correct, however this scan is very fast, so.
-my $rpms_dir = "$config->{repository}/$distro_version/$my_arch/media/$media/";
-print STDERR "iurt: checking current packages in $rpms_dir\n";
-opendir my $rpmdir, $rpms_dir or die "Could not open $rpms_dir: $!";
-foreach my $rpm (readdir $rpmdir) {
- my ($rarch, $srpm) = update_srpm($rpms_dir, $rpm);
- $rarch or next;
- $big{$rpm} = 1;
- $cache->{queue}{$srpm} = 1;
- check_version($srpm)
-}
-closedir $rpmdir;
-
-my %provides;
-my %pack_provide;
-foreach my $m (@{$config->{all_media}}) {
- my $synthesis_file = "$config->{repository}/$distro_version/$my_arch/media/$m/media_info/synthesis.hdlist.cz";
- if (-f $synthesis_file) {
- print STDERR "Parsing $synthesis_file\n";
- if (open my $syn, "zcat $synthesis_file |") {
- my @prov;
- my $nb;
- while (<$syn>) {
- if (/^\@provides@(.*)/) {
- foreach my $p (split '@', $1) {
- $p =~ /([^[]+)(?:\[(.*)\])?/g;
- push @prov, $1;
- $provides{$1} = $2 || 1
- }
- } elsif (/\@info\@([^@]+)@/) {
- $nb++;
- my ($name) = $1 =~ /(.*)-[^-]+-[^-]+\..*$/;
- foreach (@prov) {
- $pack_provide{$_} = $name
- }
- @prov = ()
- }
- }
- $nb < $config->{minimum_package_number} and die "FATAL iurt: synthesis files seems corrupted, only $nb packages found."
- } else {
- die "FATAL iurt: Could not open $synthesis_file\n";
- }
- }
-}
-#}
-
-my %maint;
-
--d "$config->{upload}/build/$my_arch" or mkdir "$config->{upload}/build/$my_arch";
-my $clean;
-my %rep;
-my %done_rpm;
-#
-# FIXME all the rep but the first one are cleaned
-# this may not be usefull anymore
-#
-my $to_compile;
-foreach my $dir ("$config->{repository}/$distro_version/SRPMS/$media/", @special_srpm_dir) {
- print STDERR "iurt: checking SRPMS dir $dir\n";
- opendir my $rpmdir, $dir or next;
- foreach my $srpm (readdir $rpmdir) {
- # this is for the output of the new svn system
- if ($srpm =~ /^\@\d+:(.*)/) {
- link "$dir/$srpm", "$dir/$1";
- # unlink "$dir/$srpm";
- $srpm = $1
- }
- $srpm =~ /(.*)-[^-]+-[^-]+\.src\.rpm$/ or next;
- if ($config->{unwanted_packages} && $srpm =~ /$config->{unwanted_packages}/) { next }
- my $ok = 1;
- if (check_version($srpm)) {
- defined $cache->{failure}{$srpm} and next;
- if (!$cache->{queue}{$srpm} && check_needed($srpm)) {
- my $hdr = rpm2header("$dir/$srpm");
- check_arch($hdr) and next;
- my $changelog = $hdr->queryformat("%{CHANGELOGNAME}");
- my ($mail) = $changelog =~ /<(.*@.*)>/;
- $maint{$srpm} = $mail;
- print "iurt: will try to compile $srpm\n";
- $to_compile++;
- push @todo, [ $dir , $srpm ]
- }
- foreach my $arch (@{$config->{supported_arch}}) {
- $ok &&= $cache->{queue}{$srpm}
- }
- }
- if ($clean && ($rep{$srpm} || $ok)) {
- print "iurt: cleaning $dir/$srpm\n";
- unlink "$dir/build/$srpm";
- unlink "$dir/$srpm"
- }
- $rep{$srpm} = 1
- }
- $clean = 1;
- closedir $rpmdir
-}
+my (%srpm_version, @wrong_rpm, %provides, %pack_provide, $to_compile, %maint);
+$to_compile += check_media(\%run, $cache, $config, \%srpm_version, \@wrong_rpm, \%provides, \%pack_provide, \%maint) if $run{media};
+$to_compile += search_packages(1, $cache, \%run, @{$run{extra_dir}}) if $run{extra};
dump_cache();
-if (!@todo && !$debug) {
+if (!@{$run{todo}} && !$run{debug}) {
print "iurt: nothing to do\n";
- unlink $pidfile;
+ unlink $run{pidfile} if $run{pidfile};
exit
}
print "iurt: will try to compile $to_compile packages\n";
+exit if !$run{rebuild};
+
$cache->{run} ||= 1;
-my $run = ++$cache->{run};
+$run{run} = ++$cache->{run};
-my $local_spool = "$config->{local_home}/iurt/$distro_tag/$my_arch";
-if (!-d "$config->{local_home}/iurt/$distro_tag/") {
- mkdir "$config->{local_home}/iurt/$distro_tag";
+my $local_spool = "$config->{local_home}/iurt/$run{distro_tag}/$run{my_arch}";
+if (!-d "$config->{local_home}/iurt/$run{distro_tag}/") {
+ mkdir "$config->{local_home}/iurt/$run{distro_tag}";
if (!-d $local_spool) {
mkdir $local_spool;
mkdir "$local_spool/log"
}
}
-my $debug_tag = '_debug' if $debug;
-my $chroot = "$config->{local_home}/chroot$debug_tag";
-my $chroot_tar = "$chroot-$distro_tag.$my_arch.tar.gz";
-my $unionfs_dir;
-if (!$nocheckchroot) {
- print "iurt: checking basesystem tar\n";
- system(qq{sudo pkill -9 -u root -f "urpmi $urpmi_options --root $chroot"});
- clean_chroot($chroot, 1) or die "FATAL iurt: Could no prepare initial chroot";
- perform_command("sudo $config->{install_chroot_binary} cooker $config->{basesystem_media} $chroot_tar $chroot 501 basesystem tar rpm-build",
- mail => $config->{admin},
- error => "[REBUILD] Creating the inital chroot for $distro_tag on $my_arch failed",
- hash => 'chroot_inititialization',
- timeout => 600,
- log => "$local_spool/log/",
- debug_mail => $debug,
- die => 1);
-}
dump_rpmmacros("$chroot/home/builder/.rpmmacros") or die "FATAL iurt: could not dump rpm macros";
-if ($unionfs) {
+my $unionfs_dir;
+if ($run{unionfs}) {
$unionfs_dir = "$config->{local_home}/iurt_unionfs$debug_tag";
clean_all_unionfs($unionfs_dir);
-d $unionfs_dir or mkdir $unionfs_dir
}
-my $s = sub { print "iurt: dumping cache...\n"; dump_cache(); exit };
+
+my $s = sub {
+ print "iurt: dumping cache...\n";
+ dump_cache();
+ $Data::Dumper::Indent = 0;
+ $Data::Dumper::Terse = 1;
+ print "Running environment:\n", Data::Dumper->Dump([\%run]), "\n\n";
+ print "Configuration:\n",Data::Dumper->Dump([$config]),"\n\n";
+ exit
+};
$SIG{TERM} = $s;
$SIG{INT} = $s;
@@ -328,13 +259,13 @@ my $wait_limit;
my $done;
my $home = $config->{local_home};
my $union_id = 1;
-my $unionfs_tmp = $unionfs;
-foreach (my $i ; $i < @todo; $i++) {
- my ($dir, $srpm) = @{$todo[$i]};
+my $unionfs_tmp = $run{unionfs};
+foreach (my $i ; $i < @{$run{todo}}; $i++) {
+ my ($dir, $srpm) = @{$run{todo}[$i]};
$done{$srpm} and next;
$done{$srpm} = 1;
check_version($srpm) or next;
- if ($debug) { $debug++ == 2 and exit }
+ if ($run{debug}) { $run{debug}++ == 2 and exit }
$done++;
print "iurt: packages $srpm [$done/$to_compile]\n";
# FIXME unfortunately urpmi stalls quite often
@@ -344,8 +275,8 @@ foreach (my $i ; $i < @todo; $i++) {
die "FATAL iurt: Could not have urpmi working !"
}
if ($unionfs_tmp) {
- my $mount_point = "$unionfs_dir/unionfs.$run.$union_id";
- print STDERR "Cleaning $mount_point\n";
+ my $mount_point = "$unionfs_dir/unionfs.$run{run}.$union_id";
+ print {$run{LOG}} "Cleaning $mount_point\n";
if (!clean_mnt($mount_point)) {
dump_cache();
die "FATAL iurt: could not kill remaining processes acceding $mount_point"
@@ -353,110 +284,126 @@ foreach (my $i ; $i < @todo; $i++) {
my $tmpfs;
# we cannont just rm -rf $tmpfs, this create defunct processes afterwards (and lock particularly hard the urpmi database)
- $union_id = clean_unionfs($unionfs_dir, $run, $union_id);
- $tmpfs = "$unionfs_dir/tmpfs.$run.$union_id";
- $chroot = "$unionfs_dir/unionfs.$run.$union_id";
+ $union_id = clean_unionfs($unionfs_dir, $run{run}, $union_id);
+ $tmpfs = "$unionfs_dir/tmpfs.$run{run}.$union_id";
+ $chroot = "$unionfs_dir/unionfs.$run{run}.$union_id";
mkdir $tmpfs or die "Could not create $tmpfs ($!)";
mkdir $chroot or die "Could not create $chroot ($!)";
if ($cache->{no_unionfs}{$srpm}) {
$unionfs_tmp = 0;
- clean_chroot($chroot)
+ clean_chroot($chroot, \%run)
} else {
# if the previous package has been built without unionfs, chroot need to be cleaned
- clean_chroot($chroot) if !$unionfs_tmp;
+ clean_chroot($chroot, \%run) if !$unionfs_tmp;
$unionfs_tmp = 1;
system(qq{sudo mount -t tmpfs none $tmpfs}) and die "FATAL iurt: could not mount $tmpfs ($!)";
system(qq{sudo mount -o dirs=$tmpfs=rw:$home/chroot$debug_tag=ro -t unionfs none $chroot}) and die "FATAL iurt: could not mount $tmpfs and $home/chroot with unionfs ($!)";
- system("sudo chroot $chroot mount none -t proc /proc") and die "FATAL iurt: could not mount /proc in the chroot $chroot.";
+ system("sudo mount -t proc none $chroot/proc") and die "FATAL iurt: could not mount /proc in the chroot $chroot.";
}
} else {
- print STDERR "iurt: installing a new chroot for $srpm in $chroot\n";
- clean_chroot($chroot)
+ print {$run{LOG}} "iurt: installing a new chroot for $srpm in $chroot\n";
+ clean_chroot($chroot, \%run)
}
my ($srpm_name) = $srpm =~ /(.*)-[^-]+-[^-]+\.src\.rpm$/ or next;
- my $maintainer = `rpmmon -s -p $srpm_name`;
- my $cc = "$maint{$srpm}";#, maintainers\@mandriva.com";
- chomp $maintainer;
- if (!$maintainer || $maintainer eq 'NOT_FOUND') {
+ my ($maintainer, $cc);
+ if (!$run{warn}) {
+ $maintainer = `rpmmon -s -p $srpm_name`;
+ $cc = "$maint{$srpm}";#, maintainers\@mandriva.com";
+ chomp $maintainer;
+ if (!$maintainer || $maintainer eq 'NOT_FOUND') {
$maintainer = $cc;
#$cc = 'maintainers@mandriva.com'
+ }
}
#($maintainer, $cc) = ($config->{admin},'');
# recreate a new srpm for buildarch condition in the spec file
print "Copying $srpm to $chroot\n";
perform_command("sudo cp $dir/$srpm $chroot/home/builder/rpm/SRPMS/",
+ \%run, $config,
mail => $config->{admin},
error => "[REBUILD] cannot copy $srpm to $chroot",
- debug_mail => $debug,
+ debug_mail => $run{debug},
hash => "copy_$srpm") or next;
perform_command(qq{sudo chroot $chroot su builder -c "rpm -i /home/builder/rpm/SRPMS/$srpm"},
+ \%run, $config,
mail => $config->{admin},
error => "[REBUILD] cannot install $srpm in $chroot",
- debug_mail => $debug,
+ debug_mail => $run{debug},
hash => "install_$srpm") or next;
perform_command(qq{sudo chroot $chroot su builder -c "rpm --nodeps -bs /home/builder/rpm/SPECS/*.spec"},
+ \%run, $config,
mail => $config->{admin},
error => "[REBUILD] cannot create $srpm in $chroot",
- debug_mail => $debug,
+ debug_mail => $run{debug},
hash => "create_$srpm") or next;
print "Installing build dependencies of $srpm...\n";
- #system(qq{sudo pkill -9 -u root -f "$todo[$i-1][1]"}) if $i - 1 >= 0;
- #system(qq{sudo pkill -9 -u root -f "urpmi $urpmi_options --root $chroot"});
perform_command("sudo urpmi $urpmi_options --root $chroot $chroot/home/builder/rpm/SRPMS/$srpm",
+ \%run, $config,
mail => $maintainer,
- error => "[REBUILD] install of build dependencies of $srpm failed on $my_arch",
+ error => "[REBUILD] install of build dependencies of $srpm failed on $run{my_arch}",
hash => "install_deps_$srpm",
timeout => 600,
freq => 1,
cc => $cc,
- debug_mail => $debug,
+ debug_mail => $run{debug},
error_regexp => 'cannot be installed',
wait_regexp => 'database locked',
wait_callback => sub { $wait_limit++; if ($wait_limit > 10) { $wait_limit = 0; system(qq{sudo pkill -9 urpmi}) } },
log => "$local_spool/log/",
callback => sub {
my ($opt, $output) = @_;
- print "calling callback for $opt->{hash}\n" if $debug;
- my ($missing_deps, $version) = $output =~ /\(due to unsatisfied ([^[)]*)(?:\[(.*)\])?/;
- $missing_deps or return;
- my $p = $pack_provide{$missing_deps} || $missing_deps;
- my $other_maint = `rpmmon -p $p`;
- $version ||= 0;
- chomp $other_maint;
- print "missing dep: $missing_deps ($other_maint)\n";
- if ($other_maint && $other_maint ne 'NOT_FOUND') {
- $opt->{mail} = $other_maint;
- $opt->{error} = "[missing] $missing_deps, needed to build $srpm, is not available on $my_arch";
+ print {$run{LOG}} "calling callback for $opt->{hash}\n" if $run{debug};
+ my @missing_deps = $output =~ /\(due to unsatisfied ([^[ ]*)(?: (.*)| \[(.*)\])?\)/g;
+ @missing_deps or return;
+ while (my $missing_deps = shift @missing_deps) {
+ my $version = shift @missing_deps;
+ my $version2 = shift @missing_deps;
+ $version ||= $version2 || 0;
+ my $p = $pack_provide{$missing_deps} || $missing_deps;
+ my $other_maint = `rpmmon -p $p`;
+ chomp $other_maint;
+ print {$run{LOG}} "missing dep: $missing_deps ($other_maint)\n";
+ if ($other_maint && $other_maint ne 'NOT_FOUND') {
+ $opt->{mail} = $other_maint;
+ $opt->{error} = "[missing] $missing_deps, needed to build $srpm, is not available on $run{my_arch}";
+ }
+ # remember what is needed, and do not try to recompile until it is available
+ push @{$cache->{needed}{$srpm}}, [ $missing_deps, $version, $other_maint || $maintainer ];
}
- # remember what is needed, and do not try to recompile until it is available
- push @{$cache->{needed}{$srpm}}, [ $missing_deps, $version, $other_maint || $maintainer ];
},
) or next;
+ # try to workarround the rpm -qa db4 error(2) from dbcursor->c_get: No such file or directory
+ # running rpm -qa several time seems to fix the problem
+ foreach (1 .. 3) {
+ system("sudo chroot $chroot rpm -qa")
+ }
perform_command("sudo chroot $chroot rpm -qa",
+ \%run, $config,
hash => "rpm_qa_$srpm",
timeout => 60,
- debug_mail => $debug,
- log => "$local_spool/log/") or next;
+ debug_mail => $run{debug},
+ log => "$local_spool/log/"); # or next; As this failed quite often, do not stop
print "Compiling $srpm\n";
if (!perform_command(qq{TMP=/home/builder/tmp/ sudo chroot $chroot /bin/su builder -c "rpm --rebuild /home/builder/rpm/SRPMS/$srpm"},
+ \%run, $config,
mail => $maintainer,
- error => "[REBUILD] $srpm from $distro_tag does not build correctly on $my_arch",
+ error => "[REBUILD] $srpm from $run{distro_tag} does not build correctly on $run{my_arch}",
hash => "build_$srpm",
timeout => 18000,
- debug_mail => $debug,
+ debug_mail => $run{debug},
cc => $cc,
log => "$local_spool/log/",
error_regexp => 'rror.*ailed|Bad exit status|RPM build error',
callback => sub {
my ($opt, $output) = @_;
- print STDERR "iurt: calling callback for $opt->{hash}\n" if $debug;
+ print {$run{LOG}} "iurt: calling callback for $opt->{hash}\n" if $run{debug};
if ($unionfs_tmp && $output =~ /no space left on device/i) {
- print STDERR "ERROR iurt: running out of space to compile $srpm in unionfs mode, will recompile it in normal mode\n";
+ print {$run{LOG}} "ERROR iurt: running out of space to compile $srpm in unionfs mode, will recompile it in normal mode\n";
$cache->{no_unionfs}{$srpm} = 1
} elsif ($unionfs_tmp && $output =~ m,$home,) {
- print STDERR "ERROR iurt: seems like building $srpm needs to acces /proc/self/exe, which is broken with unionfs, will recompile it in normal mode\n";
+ print {$run{LOG}} "ERROR iurt: seems like building $srpm needs to access /proc/self/exe, which is broken with unionfs, will try to recompile it in non unionfs mode\n";
$cache->{no_unionfs}{$srpm} = 1
}
},
@@ -469,9 +416,9 @@ foreach (my $i ; $i < @todo; $i++) {
# on a new machine with more ram, or if next version compiles just fine with unionfs, we will
# loose the unionfs advantage.
#
- # Maybe the right thing to do would be to first try to increate the tmpfs size (more than 50 % of the
+ # Maybe the right thing to do would be to first try to increase the tmpfs size (more than 50 % of the
# physical RAM), but this will lead to more swap usage, and slower compilation (and lost of the unionfs
- # plus). Or to keep the faulty package an unionfs exception for some time, to save some more extra builds.
+ # plus). Or to keep the faulty package a unionfs exception for some time, to save some more extra builds.
#
if (!$unionfs_tmp) {
$cache->{failure}{$srpm} = 1
@@ -483,32 +430,33 @@ foreach (my $i ; $i < @todo; $i++) {
# do some cleaning if the compilation is successful
delete $cache->{needed}{$srpm} if defined $cache->{needed}{$srpm};
if (!perform_command("sudo urpmi $urpmi_options --root $chroot $chroot/home/builder/rpm/RPMS/*/*.rpm",
+ \%run, $config,
mail => $maintainer,
error => "[REBUILD] binaries packages generated from $srpm do not install correctly",
hash => "binary_test_$srpm",
timeout => 300,
- debug_mail => $debug,
+ debug_mail => $run{debug},
freq => 1,
error_regexp => 'unable to access',
log => "$local_spool/log/")) {
$cache->{failure}{$srpm} = 1;
next
}
- if ($debug) {
+ if ($run{debug}) {
print "iurt: debug mode, skip other packages\n";
exit
} else {
system("cp $chroot/home/builder/rpm/RPMS/*/*.rpm $local_spool") and print "ERROR: could not copy rpm files from $chroot/home/builder/rpm/RPMS/ to $local_spool ($!)\n";
- process_queue()
+ process_queue($config, \%run, \@wrong_rpm)
}
}
-print STDERR "iurt: reprocess generated packages queue\n";
-process_queue();
+print {$run{LOG}} "iurt: reprocess generated packages queue\n";
+process_queue($config, \%run, \@wrong_rpm);
dump_cache();
-print STDERR "ERROR iurt: RPM with a wrong SRPM name\n" if @wrong_rpm;
+print {$run{LOG}} "ERROR iurt: RPM with a wrong SRPM name\n" if @wrong_rpm;
if (open my $file, ">$local_spool/log/wrong_srpm_names.log") {
foreach (@wrong_rpm) {
print $file "$_->[1] -> $_->[0] (", $cache->{rpm_srpm}{$_->[1]},")\n";
@@ -518,51 +466,17 @@ if (open my $file, ">$local_spool/log/wrong_srpm_names.log") {
if ($config->{rsync_to}) {
# remove some old and very big log files not to saturate the server
system(qq{find $local_spool/log/ -name "*.log" \( -size +$config->{log_size_limit} -or -mtime +$config->{log_size_date} \) -exec rm -f {} \;});
- system("rsync --delete -alHPe 'ssh -c arcfour' $local_spool/log/ $config->{rsync_to}/$distro_tag/$my_arch/log/");
+ system("rsync --delete -alHPe 'ssh -c arcfour' $local_spool/log/ $config->{rsync_to}/$run{distro_tag}/$run{my_arch}/log/");
}
# one last try to clean
-print STDERR "iurt: try to clean remaining unionfs\n";
-if ($unionfs) {
+print {$run{LOG}} "iurt: try to clean remaining unionfs\n";
+if ($run{unionfs}) {
clean_all_unionfs($unionfs_dir)
}
-
-unlink $pidfile;
-
+unlink $run{pidfile} if $run{pidfile};
exit;
-sub usage {
- my ($error) = @_;
- print "
- ERROR iurt: $error" if $error;
- print "
-
- usage:
-
- iurt [options] <distro version> <arch> <media>
- e.g. iurt community/2006.0 x86_64 main
-
- options:
- --config_help: Display configuration file help
-
- --debug: Compile one package in debug mode (do not send mail, create
- chroot_debug directory). This mode can be used on a system
- where a iurt is already running.
-
- --force_build <force_srpm_build_1> <force_srpm_build_2> ... <force_srpm_build_n>
- list of extra srpm to build
-
- --help: Display this help
-
- --nocheckchroot: start building without the inital check of the chroot.
-
- --unionfs: Use a tmpfs mounted with the chroot via unionfs as build chroot.
- This is much faster but you need some memory.
-
-";
- exit
-}
-
sub config_usage {
print "
@@ -572,7 +486,8 @@ sub config_usage {
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
foreach my $k (sort keys %config_usage) {
- print " $k: $config_usage{$k}{desc} (default: ", Data::Dumper->Dump([$config_usage{$k}{default}]), ", current: ", Data::Dumper->Dump([$config->{$k}]),")\n\n"
+ print " $k: $config_usage{$k}{desc}
+ default: ", Data::Dumper->Dump([$config_usage{$k}{default}]), ", current: ", Data::Dumper->Dump([$config->{$k}]),"\n"
}
print "\n\n";
exit
@@ -580,7 +495,7 @@ sub config_usage {
sub clean_all_unionfs {
my ($unionfs_dir) = @_;
- print STDERR "Cleaning old unionfs remaining dir in $unionfs_dir\n";
+ print {$run{LOG}} "Cleaning old unionfs remaining dir in $unionfs_dir\n";
opendir my $dir, $unionfs_dir or die "FATAL iurt: could not open $unionfs_dir ($!)";
foreach (readdir $dir) {
/unionfs\.(\d+)\.(\d+)/ or next;
@@ -590,27 +505,29 @@ sub clean_all_unionfs {
}
sub clean_chroot {
- my ($chroot, $only_clean) = @_;
+ my ($chroot, $run, $only_clean) = @_;
if (-d $chroot) {
- system("sudo chroot $chroot umount /proc");
+ system("sudo umount $chroot/proc");
perform_command("sudo rm -rf $chroot",
+ $run, $config,
mail => $config->{admin},
error => "[REBUILD] Deleting of old chroot $chroot failed",
hash => 'chroot_deletion',
- debug_mail => $debug,
+ debug_mail => $run->{debug},
die => 1);
}
return 1 if $only_clean;
mkdir $chroot;
perform_command("pushd $chroot && sudo tar xvf $chroot_tar",
+ $run, $config,
mail => $config->{admin},
error => "[REBUILD] creating the initial chroot $chroot failed",
hash => 'chroot_init',
- debug_mail => $debug,
+ debug_mail => $run->{debug},
die => 1);
dump_rpmmacros("$chroot/home/builder/.rpmmacros") or return;
- system("sudo chroot $chroot mount none -t proc /proc") and return;
+ system("sudo mount none -t proc $chroot/proc") and return;
1
}
@@ -632,7 +549,7 @@ sub clean {
system(qq{$kill_cmd "$var"});
sleep 1;
chomp $ps;
- print STDERR "Trying to removed previous blocked processes for $var ($ps)\n";
+ print {$run{LOG}} "Trying to removed previous blocked processes for $var ($ps)\n";
return 0 if $i++ > 10
}
1
@@ -640,7 +557,7 @@ sub clean {
sub clean_unionfs {
my ($unionfs_dir, $run, $union_id) = @_;
- system("sudo chroot $unionfs_dir/unionfs.$run.$union_id/ umount /proc") and print STDERR "ERROR iurt: could not umount /proc in $unionfs_dir/unionfs.$run.$union_id\n";
+ system("sudo umount $unionfs_dir/unionfs.$run.$union_id/proc") and print {$run{LOG}} "ERROR iurt: could not umount /proc in $unionfs_dir/unionfs.$run.$union_id\n";
print "Cleaning $unionfs_dir/unionfs.$run.$union_id\n";
my $nok = 1;
while ($nok) {
@@ -650,16 +567,16 @@ sub clean_unionfs {
my $last;
while (check_mounted($d, $t)) {
system("sudo fuser -k $d");
- print STDERR "iurt: umounting $d\n";
+ print {$run{LOG}} "iurt: umounting $d\n";
if (system(qq{sudo umount $d &> /dev/null})) {
- print STDERR "WARNING iurt: could not umount $d ($!)\n";
+ print {$run{LOG}} "WARNING iurt: could not umount $d ($!)\n";
$union_id++;
$last = 1;
last
}
}
$last and last;
- print STDERR "iurt: removing $d\n";
+ print {$run{LOG}} "iurt: removing $d\n";
system(qq{sudo rm -rf $d});
$nok = 0
}
@@ -667,7 +584,6 @@ sub clean_unionfs {
$union_id
}
-
sub check_mounted {
my ($mount_point, $type) = @_;
open my $mount, '/proc/mounts' or die 'FATAL iurt: could not open /proc/mounts';
@@ -693,7 +609,7 @@ sub check_needed {
$ok = 0;
push @n, [ $name, $version ];
my $v ||= $version;
- print STDERR "ERROR iurt: $srpm needs $name $v to be compiled.\n";
+ print {$run{LOG}} "ERROR iurt: $srpm needs $name $v to be compiled.\n";
# try to recompile it once in a while
return 1 if ! $cache->{warning}{"install_deps_$srpm"}{$maint}++ % 72
}
@@ -703,28 +619,31 @@ sub check_needed {
}
sub process_queue {
- my $dir = "$config->{local_home}/iurt/$distro_tag/$my_arch";
- opendir my $rpmdir, $dir or next;
- foreach my $rpm (readdir $rpmdir) {
- my ($rarch, $srpm) = update_srpm($dir, $rpm);
- $rarch or next;
- # recheck if the package has not been uploaded in the meantime
- if (! -f "$rpms_dir/$rpm") {
- my $ok = copy "$dir/$rpm", "$config->{upload}/RPMS/";
- # try to keep the opportunity to prevent disk full
- if (!$ok){
- print "ERROR process_queue: cannot copy $dir/$rpm to $config->{upload}/RPMS/ ($!)\n";
- next
- }
- }
- unlink "$dir/$rpm";
- $cache->{queue}{$srpm} = 1
+ my ($config, $run, $wrong_rpm) = @_;
+ return if !$run->{upload};
+ my $dir = "$config->{local_home}/iurt/$run->{distro_tag}/$run->{my_arch}";
+ opendir my $rpmdir, $dir or next;
+ foreach my $rpm (readdir $rpmdir) {
+ my ($rarch, $srpm) = update_srpm($dir, $rpm, $wrong_rpm);
+ $rarch or next;
+ # recheck if the package has not been uploaded in the meantime
+ my $rpms_dir = "$config->{repository}/$run->{distro}/$run->{my_arch}/media/$run->{media}/";
+ if (! -f "$rpms_dir/$rpm") {
+ my $ok = copy "$dir/$rpm", "$config->{upload}/RPMS/";
+ # try to keep the opportunity to prevent disk full
+ if (!$ok){
+ print "ERROR process_queue: cannot copy $dir/$rpm to $config->{upload}/RPMS/ ($!)\n";
+ next
+ }
}
- closedir $rpmdir;
+ unlink "$dir/$rpm";
+ $cache->{queue}{$srpm} = 1
+ }
+ closedir $rpmdir;
}
sub update_srpm {
- my ($dir, $rpm) = @_;
+ my ($dir, $rpm, $wrong_rpm) = @_;
my ($arch) = $rpm =~ /([^\.]+)\.rpm$/ or return 0;
my $srpm = $cache->{rpm_srpm}{$rpm};
if (!$srpm) {
@@ -733,13 +652,16 @@ sub update_srpm {
$srpm = $hdr->queryformat("%{SOURCERPM}");
$cache->{rpm_srpm}{$rpm} = $srpm
}
- $srpm = fix_srpm_name($srpm, $rpm);
+ $srpm = fix_srpm_name($srpm, $rpm, $wrong_rpm);
$arch, $srpm
}
sub dump_cache {
my $filename = $cachefile;
- return if $debug;
+ # Right now there are no mechanism of concurrent access/write to the cache. There is
+ # on global lock for one iurt session. A finer cache access would allow several iurt running
+ # but the idea is more to have a global parrallel build than several local ones.
+ return if $run{debug} || !$run{cache};
open my $file, ">$filename.tmp" or die "FATAL iurt dump_cache: cannot open $filename.tmp";
flock($file,LOCK_EX);
seek($file, 0, 2);
@@ -771,9 +693,9 @@ sub sendmail {
sub check_arch {
my ($hdr) = @_;
my (@exclusive_arch) = $hdr->queryformat('%{EXCLUSIVEARCH}');
- grep { $_ eq $my_arch || $_ eq '(none)' } @exclusive_arch or return 1;
+ grep { $_ eq $run{my_arch} || $_ eq '(none)' } @exclusive_arch or return 1;
my (@exclude_arch) = $hdr->queryformat('%{EXCLUDEARCH}');
- grep { $_ eq $my_arch } @exclusive_arch and return 1
+ grep { $_ eq $run{my_arch} } @exclusive_arch and return 1
}
sub check_version {
@@ -787,17 +709,17 @@ sub check_version {
}
sub fix_srpm_name {
- my ($srpm, $rpm) = @_;
+ my ($srpm, $rpm, $wrong_rpm) = @_;
my $old_srpm = $srpm;
if ($srpm =~ s/^lib64/lib/){
- push @wrong_rpm, [ $old_srpm, $rpm ];
+ push @$wrong_rpm, [ $old_srpm, $rpm ];
$cache->{rpm_srpm}{$rpm} = $srpm
}
$srpm
}
sub perform_command {
- my ($command, %opt) = @_;
+ my ($command, $run, $config, %opt) = @_;
$opt{timeout} ||= 300;
$opt{freq} ||= 24;
print "Timeout $opt{timeout}\n";
@@ -814,7 +736,7 @@ sub perform_command {
print "$command\n";
if ($opt{log}) {
#$output = `$command 2>&1 2>&1 | tee $opt{log}/$opt{hash}.$run.log`;
- system("$command &> $opt{log}/$opt{hash}.$run.log");
+ system("$command &> $opt{log}/$opt{hash}.$run->{run}.log");
} else {
$output = `$command 2>&1`;
}
@@ -826,7 +748,7 @@ sub perform_command {
return 0
} else {
# Keep the run first on the harddrive so that one can check the command status tailing it
- if ($opt{log} && open my $log, "$opt{log}/$opt{hash}.$run.log") {
+ if ($opt{log} && open my $log, "$opt{log}/$opt{hash}.$run->{run}.log") {
local $/;
$output = <$log>
}
@@ -841,8 +763,8 @@ sub perform_command {
}
if ($opt{wait_regexp} && $output =~ /$opt{wait_regexp}/) {
$opt{wait_callback}(\%opt, $output) if ref $opt{wait_callback};
- print STDERR "ERROR iurt: $opt{wait_regexp} !\n";
- sendmail($config->{admin}, '' , "$opt{hash} on $my_arch for $media: could not proceed", "$opt{wait_regexp}\n\n$output", 0, 0, $opt{debug_mail});
+ print {$run->{LOG}} "ERROR iurt: $opt{wait_regexp} !\n";
+ sendmail($config->{admin}, '' , "$opt{hash} on $run->{my_arch} for $run->{media}: could not proceed", "$opt{wait_regexp}\n\n$output", 0, 0, $opt{debug_mail});
if ($opt{die}) {
dump_cache();
die "FATAL iurt: $opt{error}."
@@ -858,7 +780,7 @@ sub perform_command {
}
}
$cache->{warning}{$opt{hash}}{$opt{mail}}++;
- print STDERR "\n$output\n";
+ print {$run->{LOG}} "\n$output\n";
if ($opt{die}) {
dump_cache();
die "FATAL iurt: $opt{error}."
@@ -882,6 +804,21 @@ sub kill_for_good {
}
}
+sub check_chroot {
+ my ($chroot, $chroot_tar, $run) = @_;
+ print "iurt: checking basesystem tar\n";
+ system(qq{sudo pkill -9 -u root -f "urpmi $urpmi_options --root $chroot"});
+ clean_chroot($chroot, $run, 1) or die "FATAL iurt: Could no prepare initial chroot";
+ perform_command("sudo $config->{install_chroot_binary} cooker $config->{basesystem_media} $chroot_tar $chroot 501 basesystem tar rpm-build",
+ $run, $config,
+ mail => $config->{admin},
+ error => "[REBUILD] Creating the inital chroot for $run->{distro_tag} on $run->{my_arch} failed",
+ hash => 'chroot_inititialization',
+ timeout => 600,
+ debug_mail => $run->{debug},
+ die => 1);
+}
+
sub dump_rpmmacros {
my ($file) = @_;
open my $f, qq{| sudo sh -c "cat > $file"} or return 0;
@@ -891,3 +828,131 @@ sub dump_rpmmacros {
\%vendor $config->{vendor}
\%packager $config->{packager}}
}
+
+sub check_pid {
+ my ($run) = @_;
+ my $pidfile = $run->{pidfile};
+ open my $lock, "$pidfile.lock";
+ flock($lock,LOCK_EX);
+ if (-f $pidfile) {
+ my (@stat) = stat $pidfile;
+ open my $test_PID, $pidfile;
+ my $pid = <$test_PID>;
+ close $test_PID;
+ if ($pid && getpgrp $pid != -1) {
+ my $time = $stat[9];
+ if ($time < time - 36000) {
+ print {$run->{LOG}} "iurt: an other iurt pid $pid is running for a very long time, killing it\n";
+ my $i;
+ while ($i < 5 && getpgrp $pid != -1) {
+ kill_for_good($pid);
+ $i++;
+ sleep 1
+ }
+ } else {
+ print {$run->{LOG}} "iurt: an other iurt is running for $run->{my_arch}, pid $pid, since ",time - $time," seconds\n";
+ exit
+ }
+ } else {
+ print {$run->{LOG}} "iurt: a previous iurt for $run->{my_arch} seems dead, cleaning.\n";
+ unlink $pidfile
+ }
+ }
+ open my $PID, ">$pidfile" or die "FATAL iurt: could not open pidfile $pidfile for writing";
+ print $PID $$;
+ close $PID;
+
+ flock($lock,LOCK_UN);
+ close $lock;
+}
+
+sub check_media {
+ my ($run, $cache, $config, $srpm_version, $wrong_rpm, $provides, $pack_provide, $maint) = @_;
+# We could rely on only parsing the synthesis, hoping that they are correct, however this scan is very fast, so...
+ my $rpms_dir = "$config->{repository}/$run->{distro}/$run->{my_arch}/media/$run->{media}/";
+ print {$run->{LOG}} "iurt: checking current packages in $rpms_dir\n";
+ opendir my $rpmdir, $rpms_dir or die "Could not open $rpms_dir: $!";
+ foreach my $rpm (readdir $rpmdir) {
+ my ($rarch, $srpm) = update_srpm($rpms_dir, $rpm, $wrong_rpm);
+ $rarch or next;
+ $cache->{queue}{$srpm} = 1;
+ check_version($srpm)
+ }
+ closedir $rpmdir;
+
+ foreach my $m (@{$config->{all_media}}) {
+ my $synthesis_file = "$config->{repository}/$run->{distro}/$run->{my_arch}/media/$m/media_info/synthesis.hdlist.cz";
+ if (-f $synthesis_file) {
+ print {$run->{LOG}} "Parsing $synthesis_file\n";
+ if (open my $syn, "zcat $synthesis_file |") {
+ my @prov;
+ my $nb;
+ while (<$syn>) {
+ if (/^\@provides@(.*)/) {
+ foreach my $p (split '@', $1) {
+ $p =~ /([^[]+)(?:\[(.*)\])?/g;
+ push @prov, $1;
+ $provides->{$1} = $2 || 1
+ }
+ } elsif (/\@info\@([^@]+)@/) {
+ $nb++;
+ my ($name) = $1 =~ /(.*)-[^-]+-[^-]+\..*$/;
+ foreach (@prov) {
+ $pack_provide->{$_} = $name
+ }
+ @prov = ()
+ }
+ }
+ $nb < $config->{minimum_package_number} and die "FATAL iurt: synthesis files seems corrupted, only $nb packages found."
+ } else {
+ die "FATAL iurt: Could not open $synthesis_file\n";
+ }
+ }
+ }
+ search_packages(0, $cache, $run, $maint, "$config->{repository}/$run->{distro}/SRPMS/$run->{media}/")
+}
+
+sub search_packages {
+ my ($clean, $cache, $run, $maint, @dir) = @_;
+ my ($to_compile, %rep, %done_rpm);
+ foreach my $dir (@dir) {
+ print {$run->{LOG}} "iurt: checking SRPMS dir $dir\n";
+ opendir my $rpmdir, $dir or next;
+ foreach my $srpm (readdir $rpmdir) {
+ # this is for the output of the new svn system
+ if ($srpm =~ /^\@\d+:(.*)/) {
+ link "$dir/$srpm", "$dir/$1";
+ # unlink "$dir/$srpm";
+ $srpm = $1
+ }
+ $srpm =~ /(.*)-[^-]+-[^-]+\.src\.rpm$/ or next;
+ if ($config->{unwanted_packages} && $srpm =~ /$config->{unwanted_packages}/) { next }
+ my $ok = 1;
+ if (check_version($srpm)) {
+ defined $cache->{failure}{$srpm} and next;
+ if (!$cache->{queue}{$srpm} && check_needed($srpm)) {
+ my $hdr = rpm2header("$dir/$srpm");
+ check_arch($hdr) and next;
+ my $changelog = $hdr->queryformat("%{CHANGELOGNAME}");
+ my ($mail) = $changelog =~ /<(.*@.*)>/;
+ $maint{$srpm} = $mail;
+ print "iurt: will try to compile $srpm\n";
+ $to_compile++;
+ push @{$run->{todo}}, [ $dir , $srpm ]
+ }
+ foreach my $arch (@{$config->{supported_arch}}) {
+ $ok &&= $cache->{queue}{$srpm}
+ }
+ }
+ if ($clean && ($rep{$srpm} || $ok)) {
+ print "iurt: cleaning $dir/$srpm\n";
+ unlink "$dir/build/$srpm";
+ unlink "$dir/$srpm"
+ }
+ $rep{$srpm} = 1
+ }
+ closedir $rpmdir
+ }
+ $to_compile
+}
+