aboutsummaryrefslogtreecommitdiffstats
path: root/iurt2
diff options
context:
space:
mode:
authorThierry Vignaud <tv@mageia.org>2012-08-27 04:25:29 +0000
committerThierry Vignaud <tv@mageia.org>2012-08-27 04:25:29 +0000
commit957142024eec83934d11b98b94035a199b57f3da (patch)
treee053bd60c3477a7840622d1f96b6270cb0d76fa5 /iurt2
parent9399b8e36848729699e1ee269c5296496aaaaa7f (diff)
downloadiurt-957142024eec83934d11b98b94035a199b57f3da.tar
iurt-957142024eec83934d11b98b94035a199b57f3da.tar.gz
iurt-957142024eec83934d11b98b94035a199b57f3da.tar.bz2
iurt-957142024eec83934d11b98b94035a199b57f3da.tar.xz
iurt-957142024eec83934d11b98b94035a199b57f3da.zip
rename iurt2 as iurt
(should have been done in commit r894 by misc on 2011-04-15, was: "remove unused files, see ml")
Diffstat (limited to 'iurt2')
-rwxr-xr-xiurt21549
1 files changed, 0 insertions, 1549 deletions
diff --git a/iurt2 b/iurt2
deleted file mode 100755
index 9b7951f..0000000
--- a/iurt2
+++ /dev/null
@@ -1,1549 +0,0 @@
-#!/usr/bin/perl
-#
-# Copyright (C) 2005 Mandrakesoft
-# Copyright (C) 2005,2006 Mandriva
-#
-# 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
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# compare and rebuild packages on different architecture
-#
-# TODO
-#
-# - use a cache (rpmctl cache for example) to find maintainer
-# - add icecream compilation support
-# - add a --group option to compile a set of packages (in progress)
-# - add a function to update a packages when it obviously need to be recompile
-# - Maybe call the function from the initial todo list (thus making the
-# argument ordering important)
-# - Change the packager tag in the chroot to have the one who submit the package
-
-use strict;
-use RPM4::Header;
-use Iurt::Config qw(config_usage get_date get_prefix config_init dump_cache_par get_maint check_arch %arch_comp get_package_prefix);
-use Data::Dumper;
-use URPM;
-use Iurt::DKMS;
-
-use Iurt::Urpmi;
-use Iurt::Chroot qw(add_local_user create_temp_chroot remove_chroot create_build_chroot clean_chroot);
-use Iurt::Process qw(perform_command kill_for_good sudo);
-use Iurt::Mail qw(sendmail);
-use Iurt::Util qw(plog_init plog);
-use File::NCopy qw(copy);
-use File::Path qw(mkpath);
-use File::Spec::Functions qw(rel2abs);
-use File::Basename qw(fileparse);
-# I did not manage to make locks work over the network
-#use File::lockf;
-use Mkcd::Commandline qw(parseCommandLine usage);
-use MDK::Common;
-use Filesys::Df qw(df);
-use POSIX;
-
-
-# copied from drakx' standalone:
-sub bug_handler {
- my ($error, $is_signal) = @_;
-
- # exceptions in eval are OK:
- return if $error && $^S && !$is_signal;
-
- # we want the full backtrace:
- $error .= "\n" if $is_signal;
- $error .= backtrace() if $error;
-
- warn "We got an uncatched exception:\n$error\n";
- #exit(1);
-}
-
-$SIG{SEGV} = sub { bug_handler(@_, 1) };
-#$SIG{__DIE__} = \&bug_handler;
-$SIG{TERM} = sub {
- warn "Got KILLED by SIGTERM at " . strftime("%c", localtime()) . " .\n";
- exit(1);
-};
-
-my $program_name = 'iurt2';
-
-# sessing parameters
-my $sudo = '/usr/bin/sudo';
-my $arg = @ARGV;
-my (@params, %run);
-$run{program_name} = $program_name;
-
-$run{todo} = [];
-@params = (
- # [ "one letter option", "long name option", "number of args (-X means ´at least X´)", "help text", "function to call", "log info"]
- #
- # no_rsync, config_help and copy_srpm kept for compatibility reasons
- #
- [ "", $program_name, 0, "[--cache] [--chrooted-urpmi <media prefix>] [--concurrent-run] [--config foo value] [--warn] [--verbose integer]
- [--copy-srpm] [--debug] [--distro] [--no-rsync] [--clean user1 user2 user3] [--clean-all] [--shell] [--stop {p|c|i|l|b|a|s}]
- [--use-system-distrib] [--dir] [--help foo?] [--log filename] [--group]
- [--upload [--markrelease] [--source]] [--dir] [--help foo?] [--log filename] [--status] [--ignore-failure]
- [--repository <distribution path>]
- [--rpmmacros <macro definition> [<macro definition>...]]
- {--config_help | --dkms {--media <media regexp>}
- --chroot --arch {i586|x86_64|ppc} --distro {cooker|2006.0|community/2006.0|...} } |
- --build-user <user> --rebuild {cooker|2006.0|community/2006.0|...} {i586|x86_64|ppc|...} {filename1.src.rpm} {filename2.src.rpm} ... {filenamen.src.rpm} }",
- "$program_name is a perl script to rebuild automatically several rpm in chroot, given a sourcerpm repository, and mail authors or rebuilder when problems occurs.
-
- e.g.: iurt --repository /dis/ -p foo\@foo.net -r cooker x86_64 /SRPMS/main/release/mkcd-4.2.5-1mdv2007.1.src.rpm",
- sub { $arg or usage($program_name, \@params) }, "" ],
- [ "", "distro", 1, "<distro>",
- "Set the distribution",
- sub { ($run{distro}) = @_; 1 }, "Setting the distribution" ],
- [ "", "dkms", [
- ["", "dkms", 0, "",
- "Set the DKMS rebuild mode",
- sub {
- my ($tmp, @arg) = @_;
- $tmp->[0] ||= {};
- push @$tmp, @arg;
- 1;
- }, "Setting auto mode arguments"],
- ["k", "kmedia", 1, "<kernel media regexp>",
- "Media Regexp to limit the kernel search to",
- sub { my ($tmp, $kmedia) = @_; $tmp->[0]{kmedia} = $kmedia; 1 }, "Limiting rebuild to the kernel in the given media regexp"],
- ["m", "media", 1, "<media regexp>",
- "Media Regexp to limit rebuild to",
- sub { my ($tmp, $media) = @_; $tmp->[0]{media} = $media; 1 }, "Limiting rebuild to the given media regexp"],
- ["u", "umedia", 1, "<upload media>",
- "Media where rebuilt DKMS packages will be uploaded",
- sub { my ($tmp, $media) = @_; $tmp->[0]{umedia} = $media; 1 }, "Uploading rebuilt DKMS packages to the given media"],
- ["v", "kversion", 1, "<kernel version>",
- "kernel for which DKMS packages should be rebuilt",
- sub { my ($tmp, $kversion) = @_; $tmp->[0]{kversion} = $kversion; 1 }, "Rebuilding only for given kernel version"],
- ["p", "package", 1, "<package>",
- "DKMS package which should be rebuilt",
- sub { my ($tmp, $package) = @_; $tmp->[0]{package} = $package; 1 }, "Rebuilding only given DKMS packages"],
-], "[options]",
- "Set the DKMS rebuild mode",
- sub { my ($opt) = @_; $run{dkms} = $opt; 1 }, "Running a DKMS rebuild run" ],
- [ "a", "arch", 1, "<architecture>",
- "Set the architecture",
- sub { ($run{my_arch}) = @_; 1 }, "Setting architecture" ],
- [ "", "cache", 0, "",
- "Use the global cache file",
- sub { $run{use_cache} = 1 }, "Activating cache use" ],
- [ "", "copy-srpm", 0, "",
- "Copy also the regenerated SRPM",
- sub { $run{copy_srpm} = 1 }, "Activating the copy_srpm mode" ],
- [ "", "copy_srpm", 0, "",
- "Copy also the regenerated SRPM",
- sub { $run{copy_srpm} = 1 }, "Activating the copy_srpm mode" ],
- [ "c", "chroot", 0, "",
- "Check chroot and update it if needed",
- sub { $run{chroot} = 1 }, "Activating chroot updating" ],
- [ "", "chrooted-urpmi", [
- [ "", "chrooted-urpmi", 1, "",
- "Create urpmi media inside the chroot instead of using --root (media prefix is like http:///server.mandriva.com/dis/)",
- sub {
- my ($tmp, @arg) = @_;
- $tmp->[0] ||= {};
- push @$tmp, @arg;
- 1;
- }, "Setting chrooted-urpmi options" ],
- ["m", "media", -1, "<media1> <media2> ... <median>",
- "Media to add instead of --distrib",
- sub { my ($tmp, @media) = @_; $tmp->[0]{media} = \@media; 1 }, "Limiting rebuild to the kernel in the given media regexp"],
- ] , "[options] <media prefix>",
- "Create urpmi media inside the chroot instead of using --root (media prefix is like http:///server.mandriva.com/dis/)",
- sub { my ($opt, $media) = @_; $opt->{rooted_media} = $media; $run{chrooted_urpmi} = $opt; 1 }, "Activating chroot media" ],
- [ "", "clean-all", 0, "",
- "Clean all remaining chroots for all the users",
- sub { $run{clean_all} = 1 }, "Activating clean chroot flag" ],
- [ "", "clean", -1, "<user 1> <user 2> ... <user n>",
- "Clean remaining chroot before runing",
- sub { $run{clean} = \@_ }, "Activating clean chroot flag" ],
- [ "", "concurrent-run", 0, "",
- "Allow several iurt to run on different machines (slower)",
- sub { $run{concurrent_run} = 1 }, "Activating concurrent run checks" ],
- [ "d", "dir", -1, "",
- "Directory where to find packages to rebuild",
- sub { $run{extra_dir} = \@_; 1 }, "Adding extra source packages directories" ],
- [ "", "config", 2, "<configuration keyword> <value>",
- "Override a configuration file variable",
- sub { my ($key, $value) = @_; $run{config}{$key} = $value }, "Overriding configuration variable" ],
- [ "", "config-help", 0, "",
- "Explain configuration files keywords",
- sub { $run{config_usage} = 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" ],
- [ "g", "group", 0, "",
- "Activate group mode, packages will be compiled as a global set, not as individual packages",
- sub { $run{group} = 1 }, "Activating the group mode" ],
- [ "", "ignore-failure", 0, "",
- "Do not take into account the failure cache, try to recompile all the packages not synchronized",
- sub { $run{ignore_failure} = 1 }, "Activating the mode ignoring previous failure" ],
- [ "l", "log", 1, "<log file>",
- "Log file.",
- sub {
- $run{log} = pop @_;
- open my $log, ">$run{log}" or die "unable to open $run{log}\n";
- $run{logfd} = $log;
- print *$log, "command line: @ARGV\n";
- 1;
- }, "Log file" ],
- [ "m", "media", -1, "<media 1> <media 2> ... <media 3>",
- "Media to rebuild",
- sub { ($run{media}) = @_; 1 }, "Adding a media to rebuild" ],
- [ "", "build-all", 0, "",
- "Build all packages of the media, even if they are up to date",
- sub { $run{build_all} = 1 }, "Setting the full build flag" ],
- [ "n", "no", 0, "",
- "Perform all the check but do not compile anything",
- sub { ($run{no_compile}) = 1 }, "Setting the no compilation flag" ],
- [ "p", "packager", 1, "<packager>",
- "Use a specific packager",
- sub { ($run{packager}) = @_ }, 'Setting packager tag' ],
- [ "", "build-user", 1, "<user>",
- "Use this username to build package",
- sub { ($run{user}) = @_ }, 'Setting build username' ],
- [ "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-12mdv2007.0.src.rpm",
- sub {
- $run{rebuild} = 1;
- $run{distro} = shift @_;
- $run{my_arch} = shift @_;
-
- foreach (@_) {
- my ($path, $srpm);
-
- unless (-f $_ && -r $_) {
- die "FATAL $program_name: $_ not a file or cannot be read\n";
- }
-
- ($srpm, $path) = fileparse(rel2abs($_));
- $srpm =~ /\.src\.rpm$/ or die "FATAL: $_ doesn't look like an SRPM";
-
- if (check_arch($_, $run{my_arch})) {
- plog('DEBUG', "force build for $2 (from $1)");
- push @{$run{todo}}, [ $path, $srpm, 1 ];
- } else {
- plog("ERROR: $_ could not be build on $run{my_arch}, ignored.");
- }
- }
- 1;
- }, "Activating rebuild mode" ],
- [ "", "rpmmacros", -1, "<macro definition 1> .. <macro definition n>",
- "Additional rpm macros to define",
- sub { $run{rpmmacros} = \@_ }, 'Setting rpm macros' ],
- [ "", "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" ],
- [ "s", "source", 0, "",
- "Upload the source package as wells",
- sub { $run{source_upload} = 1 }, "Setting source flag for upload" ],
- ], "[options]",
- "Upload the rebuild packages",
- sub { $run{upload} = 1 }, "Setting the upload flag" ],
- [ "", "use-old-chroot", 1, "<chroot path>",
- "Use the given chroot as chroot (usefull for debugging)",
- sub { ($run{use_old_chroot}) = @_ }, "Using given chroot" ],
- [ "", "no_rsync", 0, "",
- "Do not send build log to the distant rsync server",
- sub { $run{no_rsync} = 1 }, "Setting the no rsync warn flag" ],
- [ "", "delete-on-success", 0, "",
- "Don't keep generated packages and their logs",
- sub { $run{delete_on_success} = 1 }, "Setting the delete on success flag" ],
- [ "v", "verbose", 1, "<verbose level>",
- "Give more info messages about what is going on (level from 1 to 10)",
- sub { $run{verbose} = $_[0]; 1 }, "Setting verbose level" ],
- [ "w", "warn", 0, "",
- "Warn maintainer of the packages about problem in the rebuild",
- sub { $run{warn} = 1; 1 }, "Setting warn flag to warn maintainers" ],
- [ "", "shell", 0, "",
- "Dump to a shell into the newly created chroot with sudo on rpm, urpmi, urpme and urpmi.addmedia",
- sub {
- ($run{shell}) = 1;
- 1 }, "Setting option to dump to a shell" ],
- [ "", "stop", 1, "<rpm step>",
- "Perform rpmbuild -b<rpm step> (p c i l b a s) instead of rpmbuild -ba and then open a shell in the chroot",
- sub {
- ($run{stop}) = @_;
- 1;
- }, "Setting rpm build option" ],
- [ "", "repository", 1, "<distribution root path>",
- "Set a repository path if one is not created in the configuration file",
- sub {
- ($run{repository}) = @_;
- 1;
- } , "Setting the repository" ],
- [ "", "status", 1, "<mail>",
- "Send a status mail to the provided mail address",
- sub {
- ($run{status_mail}) = @_;
- 1;
- }, "Setting status mail option" ],
- [ "", "with", 1, "<flag>",
- "Use specified --with flag with rpm (can be used multiple times)",
- sub {
- $run{with_flags} .= " --with " . $_[0];
- 1;
- }, "Adding specified extra --with parameter to rpm" ],
- [ "", "without", 1, "<flag>",
- "Use specified --without flag with rpm (can be used multiple times)",
- sub {
- $run{with_flags} .= " --without " . $_[0];
- 1;
- }, "Adding specified extra --without parameter to rpm" ],
- # [ short option, long option, # of args, syntax description,
- # action description, action, execution message ]
- #############################
- [ "", "additional-media",
- [
- [ "", "additional-media", 1, "",
- "Use additional medias (media prefix is like http:///server.mandriva.com/dis/)",
- sub {
- my ($tmp, @arg) = @_;
- $tmp->[0] ||= {};
- push @$tmp, @arg;
- 1;
- }, "Setting additional medias options"
- ],
- [ "m", "media", -1, "<media1> <media2> ... <median>",
- "Media to add instead of --distrib",
- sub {
- my ($tmp, @media) = @_;
- $tmp->[0]{media} = \@media;
- 1;
- }, "Limiting rebuild to the kernel in the given media regexp"
- ],
- ],
- "[options] <media prefix>",
- "Also uses these medias (media prefix is like http:///server.mandriva.com/dis/)",
- sub {
- my ($opt, $media) = @_;
- $opt->{repository} = $media;
- $run{additional_media} = $opt;
- 1;
- }, "Activating additional medias"
- ],
- ###############################
- [ "", "icecream", 1, "<procs>",
- "Enables icecream usage by <procs> procs",
- sub {
- $run{icecream} = $_[0];
- }, "Enabling icecream usage" ],
- ###############################
- [ "", "storage", 1, "[btrfs|tar]",
- "Select how to store reference chroot",
- sub {
- $run{storage} = $_[0];
- }, "Setting storage" ],
-);
-
-open(my $LOG, ">&STDERR");
-
-plog_init($program_name, $run{logfd} || $LOG, 7, 1); # For parsing command line
-
-# Display version information
-#
-(my $iurt_rev = '$Rev$') =~ s/.*: (\d+).*/$1/;
-(my $iurt_aut = '$Author$') =~ s/.*: (..).*/$1/;
-(my $iurt_dat = '$Date$') =~ s/.*: ([\d-]* [\d:]*) .*/$1/;
-plog("MSG", "This is iurt2 revision $iurt_rev-$iurt_aut ($iurt_dat)");
-
-my $todo = parseCommandLine($program_name, \@ARGV, \@params);
-@ARGV and usage($program_name, \@params, "@ARGV, too many arguments");
-foreach my $t (@$todo) {
- plog('DEBUG', $t->[2]);
- &{$t->[0]}(@{$t->[1]}) or plog('ERROR', $t->[2]);
-}
-
-# Use the real verbose level
-plog_init($program_name, $run{logfd} || $LOG, $run{verbose}, 1);
-
-$run{distro_tag} = $run{distro};
-$run{distro_tag} =~ s,/,-,g;
-
-my $real_arch = `uname -m`;
-chomp $real_arch;
-my $HOME = $ENV{HOME};
-my $configfile = "$HOME/.iurt.$run{distro_tag}.conf";
-my $sysconfigfile = "/etc/iurt/build/$run{distro_tag}.conf";
-
-my $config = {};
-foreach my $f ($configfile, $sysconfigfile) {
- plog('DEBUG', "load config: $f");
- if (-f $f) {
- $config = eval(cat_($f))
- or die "FATAL $program_name: syntax error in $f";
- last;
- }
-}
-
-if ($run{repository}) {
- plog('DEBUG', "overriding configuration repository by the one given in the command line");
- $config->{repository} = $run{repository};
-}
-
-if (!$config->{repository}) {
- die "FATAL $program_name: no repository have been defined (use --repository to specify one on the command line";
-}
-
-my $urpmi = Iurt::Urpmi->new(run => \%run, config => $config, urpmi_options => "-v --no-verify-rpm --nolock --auto --no-suggests --ignoresize $config->{urpmi_options}");
-$run{urpmi} = $urpmi;
-
-if (!$run{chrooted_urpmi} && $run{group}) {
- die "FATAL $program_name: option --chrooted-urpmi is mandatory if --group is selected";
-}
-
-my %config_usage = (
- admin => {
- desc => 'Mail of the administrator of packages builds',
- default => ''
- },
- all_media => {
- desc => 'List of known media',
- default => {
- 'main' => [ 'release' ],
- 'contrib' => [ 'release' ]
- }
- },
- base_media => {
- desc => 'List of base media used to build chroot',
- default => [ 'core/release' ],
- },
- basesystem_packages => {
- desc => 'List of packages needed for the chroot creation',
- default => [
- 'basesystem-minimal',
- 'rpm-build',
- 'sudo',
- 'urpmi',
- 'curl',
- ]
- },
- build_timeout => {
- desc => 'Maximum build time after which the build process is terminated',
- default => {
- default => 18000,
- },
- },
- cache_home => {
- desc => 'Where to store the cache files',
- default => "$HOME/.bugs"
- },
- cache_min_size => {
- desc => 'Minimal size to consider a cache file valid',
- default => 1000000
- },
- check_binary_file => {
- desc => 'Packages rebuild should be checked, however sometime rpm is segfaulting and the test is not correct',
- default => 0
- },
- chroot_base => {
- desc => 'Where to store chroots',
- default => $HOME
- },
- iurt_root_command => {
- desc => 'Program to run sudo command',
- default => '/usr/sbin/iurt_root_command'
- },
- distribution => {
- desc => 'Name of the packages distribution',
- default => 'Mageia'
- },
- email_domain => {
- desc => 'Domain to append to usernames when sending emails',
- default => 'mageia.org'
- },
- home => {
- desc => 'Home dir',
- default => $HOME
- },
- local_home => {
- desc => 'Where to build packages',
- default => $HOME
- },
- local_upload => {
- desc => 'Where to store build packages and log',
- default => ''
- },
- local_spool => {
- desc => 'To override the directory where all the results are stored',
- default => ''
- },
- 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'
- },
- log_url => {
- desc => 'Where the log can be seen',
- default => ''
- },
- max_command_retry => {
- "Maximum number of retry Iurt will perform for a given command",
- default => 20
- },
- 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'
- },
- prompt => {
- desc => 'Default prompt in the chroot',
- default => qq(PS1='[\\[\\033[00;33m\\]iurt $run{distro}\\[\\033[00m\\]] \\[\\033[00;31m\\]\\u\\[\\033[00;32m\\]\\h\\[\\033[00m\\]\\w\$ '),
- },
- repository => {
- desc => 'Prefix of the repositories',
- default => ''
- },
- 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 => 'Mageia.Org'
- },
- additional_media => {
- desc => 'Additional medias to be used',
- default => []
- },
- icecream => {
- desc => 'Enabled icecream usage and uses N procs',
- default => 0
- },
-);
-
-# FIXME: missing parameters
-config_usage() if $run{config_usage};
-$run{my_arch} or usage($program_name, \@params, "no architecture given (media $run{media}, run{my_arch} $run{my_arch}, todo", join(', ', @{$run{todo}}));
-if (!$arch_comp{$real_arch}{$run{my_arch}}) {
- die "FATAL $program_name: could not compile $run{my_arch} binaries on a $real_arch";
-}
-config_init(\%config_usage, $config, \%run);
-
-$config->{upload} .= $run{distro};
-$config->{upload} =~ s/community//g;
-if ($run{distro} ne 'cooker') {
- if ($run{media} ne 'main') {
- $config->{upload} .= "/$run{media}";
- }
-} elsif ($run{media} eq 'contrib') {
- $config->{upload} =~ s/cooker/contrib/g;
-}
-
-my $lock = $run{media};
-if (!$lock && $run{chroot}) {
- $lock = 'chroot';
-}
-if (!$lock && $run{dkms}) {
- $lock = 'dkms';
-}
-$run{lock} = $lock;
-
-# cache file name is needed early to remove the manual lock file if the
-# lock mechanism does not work
-
-mkpath $config->{cache_home};
-my $cachefile = "$config->{cache_home}/iurt.$run{distro_tag}.$run{my_arch}.$lock.cache";
-$run{cachefile} = $cachefile;
-if (!$run{debug} && $run{media} || $run{chroot}) {
- $run{pidfile_home} = "$config->{cache_home}/";
- $run{pidfile} = "iurt.$run{distro_tag}.$run{my_arch}.$lock";
- check_pid(\%run);
-}
-
-$config->{local_upload} ||= $config->{local_home};
-my $local_spool;
-if ($config->{local_spool}) {
- $local_spool = $config->{local_spool};
-} else {
- $local_spool = "$config->{local_upload}/iurt/$run{distro_tag}/$run{my_arch}/$run{media}/";
-}
-
-# Squash double slashes
-$local_spool =~ s!/+!/!g;
-#/
-
-plog('INFO', "local spool: $local_spool");
-if (!-d "$local_spool/log") {
- plog('DEBUG', "creating local spool $local_spool");
- mkpath("$local_spool/log")
- or die "FATAL: could not create local spool dir $local_spool ($!)";
-}
-$run{local_spool} = $local_spool;
-
-my $cache;
-my $clear_cache = 1;
-if (-f $cachefile && $run{use_cache}) {
- plog('INFO', "loading cache file $cachefile");
-
- $cache = eval(cat_($cachefile))
- or plog('ERROR', "FATAL: could not load cache $cachefile ($!)");
-
- if (!$cache) {
- opendir my $cache_dir, $config->{cache_home};
- my $to_load;
-
- foreach my $file (readdir $cache_dir) {
- (my $date) = $file =~ /iurt\.$run{distro_tag}\.$run{my_arch}\.$run{media}\.cache\.tmp\.(\d{8})/ or next;
- if ($date > $to_load && -s "$config->{cache_home}/$file" > $config->{cache_min_size}) {
- $to_load = $date;
- $cachefile = "$config->{cache_home}/$file";
- }
- }
-
- plog('NOTIFY', "loading alternate cache file $cachefile");
- $cache = eval(cat_($cachefile))
- or plog('ERROR', "FATAL: could not load cache $cachefile ($!)");
- }
- $clear_cache = 0 if $cache;
-}
-
-if ($clear_cache) {
- $cache = {
- rpm_srpm => {},
- failure => {},
- queue => {},
- warning => {},
- run => 1,
- needed => {},
- };
-}
-$run{cache} = $cache;
-
-my (%srpm_version, @wrong_rpm, %provides, %pack_provide, $to_compile, %maint);
-$to_compile = @{$run{todo}};
-$to_compile += check_media(\%run, $cache, $config, \%srpm_version,
- \@wrong_rpm, \%provides, \%pack_provide, \%maint) if $run{media};
-$to_compile += search_packages(1, $cache, \%provides, \%run, \%maint,
- \%srpm_version, @{$run{extra_dir}}) if $run{extra};
-
-my $dkms;
-if ($run{dkms}) {
- $dkms = Iurt::DKMS->new(run => \%run, config => $config);
- $to_compile += $dkms->search_dkms;
-}
-$run{to_compile} = $to_compile;
-
-dump_cache_par(\%run);
-
-plog("Packages to build: $to_compile");
-
-my ($fulldate, $daydate) = get_date();
-if ($run{use_cache}) {
- $run{run} = $cache->{run};
- $run{run} ||= 1;
- $cache->{run} = $run{run} + 1;
-} else {
- $run{run} = "0.$fulldate";
-}
-$run{daydate} = $daydate;
-plog('DEBUG', "using $run{run} as chroot extension");
-$run{user} ||= $ENV{USER};
-die "Iurt should not be executed as root.\n" if $run{user} eq "root";
-$run{uid} = getpwnam $run{user};
-
-plog('DEBUG', "using local user $run{user}, id $run{uid}");
-my $luser = $run{user} || 'builder';
-
-check_sudo_access()
- or die "FATAL: you need to have sudo access on $config->{iurt_root_command} to run $program_name\n";
-
-my $debug_tag = $run{debug} && '_debug';
-$run{debug_tag} = $debug_tag;
-
-my (%done, $done);
-$run{done} = \%done;
-my $home = $config->{local_home};
-
-my $chroot_base = $config->{chroot_base};
-my ($chroot_name, $chroot_tmp, $chroot, $chroot_ref);
-$chroot_name = "chroot_$run{distro_tag}$debug_tag.$run{my_arch}";
-if (!$run{use_old_chroot}) {
- $chroot_tmp = "$chroot_base/chroot_tmp";
-
- if (!-d $chroot_tmp) {
- mkdir $chroot_tmp;
- } else {
- remove_chroot(\%run, $config, $chroot_tmp, $chroot_name);
- }
-
- mkdir_p("$chroot_tmp/$run{user}");
- $chroot_tmp = "$chroot_tmp/$run{user}/$chroot_name.$run{run}";
- $run{chroot_tmp} = $chroot_tmp;
-
- $chroot = "$config->{local_home}/$chroot_name";
-} else {
- plog(1, "using given chroot $run{use_old_chroot}");
- $chroot_tmp = $run{use_old_chroot};
- $chroot = $run{use_old_chroot};
-}
-$run{chroot_path} = $chroot;
-if ($run{storage} eq 'btrfs') {
- $chroot_ref = "$chroot_base/$chroot_name";
-} else {
- $chroot_ref = "$chroot_base/$chroot_name.tar.gz";
-}
-$run{chroot_ref} = $chroot_ref;
-# 20061222 warly
-# even in use_old_chroot mode we create the chroot if it does not exist (useful
-# if the option is used for the first time
-if ($run{chroot} || !-d "$chroot/dev") {
- create_build_chroot($chroot, $chroot_ref, \%run, $config) or die "FATAL $program_name: could not prepare initial chroot";
-}
-
-# now exit if there is nothing to do and it was just a cleaning pass
-if ($run{no_compile} || !@{$run{todo}} && !$run{debug} && !$run{shell} && !$run{rebuild}) {
- send_status_mail(\%run, $config, $cache) if $run{status_mail};
- plog("no package to compile :(");
- unlink "$run{pidfile_home}/$run{pidfile}" if $run{pidfile};
- exit();
-}
-
-plog('DEBUG', "running with pid $$");
-$run{prefix} = get_prefix($luser);
-
-my $df = df $home;
-if ($df->{per} >= 99) {
- die "FATAL: not enough space on the filesystem, only $df->{bavail} KB on $home, full at $df->{per}%";
-}
-
-if ($run{shell}) {
- if (!$run{use_old_chroot}) {
- create_temp_chroot(\%run, $config, $chroot_tmp, $chroot_ref)
- or die "FATAL $program_name: could not create temporary chroot";
- }
- add_local_user($chroot_tmp, \%run, $config, $luser, $run{uid}) or die "FATAL $program_name: could not add local user";
-
- #$urpmi->set_command($chroot_tmp);
- $urpmi->urpmi_command($chroot_tmp);
-
- $urpmi->install_packages('chroot', $chroot_tmp, $local_spool, \%pack_provide, 'configure', "[ADMIN] installation of urpmi and sudo failed in the chroot $run{my_arch}", { check => 1, maintainer => $config->{admin} }, 'urpmi', 'sudo') or die "FATAL $program_name: could not add urpmi and sudo in the chroot";
- add_sudoers($chroot_tmp, $luser);
- if ($run{shell}) {
- plog('NOTIFY', "dumping to a chrooted shell into $chroot_tmp");
- exec $sudo, $config->{iurt_root_command}, '--chroot', $chroot_tmp, '/bin/su', '-', $luser, '-c', "$config->{prompt} bash";
- die "FATAL $program_name: could not exec chroot to $chroot_tmp ($!)";
- }
-}
-
-# perform some cleaning before running to have some more space, rsync to
-# the server too in case previous iurt crashed
-
-if ($config->{rsync_to} && !$run{no_rsync}) {
- # 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 -xc arcfour', "$local_spool/log/", "$config->{rsync_to}/$run{distro_tag}/$run{my_arch}/$run{media}/log/");
-}
-
-if ($run{dkms} && $run{dkms_todo}) {
- $done += $dkms->dkms_compile($local_spool, $done);
-}
-
-# The next loop should be moved in a module someday
-
-# FIXME: (tv) kill this dead code or use it!!
-my $_s = sub {
- if ($run{main}) {
- plog("dumping cache...");
- dump_cache_par(\%run);
- $Data::Dumper::Indent = 0;
- $Data::Dumper::Terse = 1;
- plog("Running environment:\n", Data::Dumper->Dump([\%run]), "\n");
- plog("Configuration:\n", Data::Dumper->Dump([$config]), "\n");
- }
- exit();
-};
-#$SIG{TERM} = $s;
-#$SIG{INT} = $s;
-$run{main} = 1;
-
-my $rebuild;
-$run{group} = 0 if @{$run{todo}} == 1;
-if ($run{group}) {
- $rebuild = 1;
- $urpmi->set_local_media($local_spool);
- $urpmi->order_packages(\%provides, $luser)
- or die "FATAL $program_name: could not order packages";
-}
-#
-# The build loop
-#
-my $prev_done = $done;
-do {
- $rebuild = 0;
- $done = $prev_done;
- my $i;
- for ($i; $i < @{$run{todo}}; $i++) {
- my ($dir, $srpm, $status) = @{$run{todo}[$i]};
-
- # CM: Set argv[0] (in the C sense) to something we can easily spot and
- # understand in process list
- $0 = "Iurt: $run{distro_tag} $run{my_arch} $run{media} $srpm";
-
- $status or next;
- $done{$srpm} and next;
- $done{$srpm} = 1;
- check_version(\%run, $srpm, \%srpm_version) or next;
- if ($run{debug}) { $run{debug}++ == 2 and exit() }
- $done++;
- plog('NOTIFY', "Build package $srpm [$done/$to_compile]");
- # When rebuilding all the media, src.rpm can be removed from mirror before we work on them
- unless (-f "$dir/$srpm") {
- $cache->{failure}{$srpm} = 1;
- $run{status}{$srpm} = 'missing';
- dump_cache_par(\%run);
- dump_status($local_spool, \%run);
- next;
- }
- # FIXME unfortunately urpmi stalls quite often
- my $retry = 0;
-
- # current rpm is sometime segfaulting, and iurt is them blocked
- # and cannot
- #
- # $cache->{failure}{$srpm} = 1;
- # dump_cache(\%run);
-retry:
- $urpmi->clean_urpmi_process;
-
- if (!$run{use_old_chroot}) {
- $chroot_tmp = create_temp_chroot(\%run, $config,
- $chroot_tmp, $chroot_ref) or next;
- }
-
- if (!$urpmi->urpmi_command($chroot_tmp)) {
- plog('DEBUG', "Creating chroot failed.\nCommand was: $chroot_tmp");
- next;
- }
- $srpm =~ /(.*)-[^-]+-[^-]+\.src\.rpm$/ or next;
- my ($maintainer, $cc);
- if (!$run{warn}) {
- ($maintainer) = get_maint(\%run, $srpm);
- $cc = $maint{$srpm};#, maintainers\@mandriva.com";
- chomp $maintainer;
- if (!$maintainer || $maintainer eq 'NOT_FOUND') {
- $maintainer = $cc;
- #$cc = 'maintainers@mandriva.com'
- }
- }
- #($maintainer, $cc) = ($config->{admin},'');
-
- plog('DEBUG', "creating user $luser in chroot");
- add_local_user($chroot_tmp, \%run, $config, $luser, $run{uid}) or next;
-
- my $old_srpm = $srpm;
- my ($ret, $spec);
- ($ret, $srpm, $spec) = $urpmi->recreate_srpm(\%run, $config,
- $chroot_tmp, $dir, $srpm, $luser, $retry);
- if ($ret == -1) {
- if (create_build_chroot($run{chroot_path}, $run{chroot_ref}, \%run, $config)) {
- $retry = 1;
- goto retry;
- } else {
- $ret = 0;
- }
- }
- if (!$ret) {
- # CM: experimental: fail if we can't regenerate the srpm
- # This should eliminate bouncers that block the input queue
- #
- $srpm = $old_srpm;
- $cache->{failure}{$srpm} = 1;
- $run{status}{$srpm} = 'recreate_srpm_failure';
- dump_cache_par(\%run);
- dump_status($local_spool, \%run);
- next;
- }
-
- (my $log_dirname = $srpm) =~ s/.*:(.*)\.src.rpm/$1/;
- my $log_dir = "$local_spool/log/$log_dirname/";
-
- # only create the log dir for the new srpm
- mkdir $log_dir;
- -d $log_dir or die "FATAL: could not create $log_dir (check permissions and group ownerships)";
-
- plog('INFO', "Install build dependencies");
- my $path_srpm = "$chroot_tmp/home/$luser/rpm/SRPMS/";
-
- # on x86_64 the rpm database is getting corrupted and sometimes
- # rpm do not found anymore installed packages, retrying several
- # time to be sure something is really broken
-
- my $ok = $urpmi->install_packages($srpm, $chroot_tmp, $local_spool, \%pack_provide, 'install_deps', "[REBUILD] install of build dependencies of $srpm failed on $run{my_arch}", { maintainer => $maintainer }, "$path_srpm/$srpm");
- if (!$ok) {
- $run{status}{$srpm} ||= 'install_deps_failure';
- next;
- }
-
- # try to workarround the rpm -qa db4 error(2) from dbcursor->c_get:
- # No such file or directory
- # system("sudo chroot $chroot_tmp rm -rf /var/lib/rpm/__db* &> /dev/null");
- # system("$sudo chroot $chroot_tmp rpm --rebuilddb &> /dev/null");
-
- perform_command("rpm --root $chroot_tmp -qa | sort",
- \%run, $config, $cache,
- logname => "rpm_qa",
- hash => "rpm_qa_$srpm",
- timeout => 60,
- debug_mail => $run{debug},
- log => $log_dir); # or next; As this failed quite often, do not stop
- plog('NOTIFY', "Building $srpm");
- my $command = "rpmbuild --rebuild $run{with_flags} /home/$luser/rpm/SRPMS/$srpm";
- if ($run{stop}) {
- $urpmi->install_packages('chroot', $chroot_tmp, $local_spool, \%pack_provide, 'configure', "[ADMIN] installation of urpmi and sudo failed in the chroot $run{my_arch}", { check => 1, maintainer => $config->{admin} }, 'urpmi', 'sudo');
- add_sudoers($chroot_tmp, $luser);
- $command = "rpmbuild -b$run{stop} /home/$luser/rpm/SPECS/$spec";
- }
-
- my ($srpm_name) = $srpm =~ /(?:.*:)?(.*)-[^-]+-[^-]+\.src\.rpm$/;
- my $icecream;
- if ($run{icecream}) {
- $icecream = "RPM_BUILD_NCPUS=$run{icecream}";
- }
-
- if (!perform_command(qq(chroot $chroot_tmp /bin/su - $luser -c "TMP=/home/$luser/tmp/ $icecream $command"),
- \%run, $config, $cache,
- use_iurt_root_command => 1,
- mail => $maintainer,
- error => "[REBUILD] $srpm from $run{distro_tag} does not build correctly on $run{my_arch}",
- logname => "build",
- hash => "build_$srpm",
- timeout => $config->{build_timeout}{$srpm_name} || $config->{build_timeout}{default},
- srpm => $srpm,
- debug_mail => $run{debug},
- cc => $cc,
- log => $log_dir,
- error_regexp => 'rror.*ailed|Bad exit status|RPM build error',
- callback => sub {
- my ($opt, $output) = @_;
- if ($run{stop}) {
- plog("dumping to a chrooted shell into $chroot_tmp (pid $$)");
- # exec does not work because it seems stdin and out are shared between children
- system($sudo, $config->{iurt_root_command}, '--chroot', $chroot_tmp, '/bin/su', '-', $luser, '-c', "$config->{prompt} bash");
- exit();
- }
- plog('DEBUG', "calling callback for $opt->{hash}");
- if ($output =~ m!/bin/ld: cannot find -l(\S*)|configure.*error.* (?:-l(\S+)|(\S+) includes)!) {
- my $missing = $1;
- my @rpm = find_provides(\%pack_provide, $missing);
- plog(5, "likely @rpm ($missing-devel) needed to rebuilt $srpm is not in build_requires");
- if ($maintainer ne 'NOT_FOUND') {
- $opt->{mail} = $maintainer;
- #$opt->{mail} .= ", other_maint";
- }
- if (!$opt->{mail}) {
- $opt->{mail} = "Maintainer not found <$config->{admin}>";
- }
- if (@rpm > 1) {
- $opt->{error} = "[MISSING_BUILD_REQUIRES_TAG] one of @rpm ($missing-devel), needed to build $srpm, is not in buildrequires";
- } elsif (@rpm == 1) {
- $opt->{error} = "[MISSING_BUILD_REQUIRES_TAG] @rpm ($missing-devel), needed to build $srpm, is not in buildrequires";
- } else {
- $opt->{error} = "[MISSING_BUILD_REQUIRES_TAG] $missing-devel, needed to build $srpm, is not in buildrequires";
- }
- $cache->{buildrequires}{$srpm}{$missing} = \@rpm;
- return;
- }
- 1;
- },
- freq => 1)) {
-
- $cache->{failure}{$srpm} = 1;
- $run{status}{$srpm} = 'build_failure';
- # 20060615
- dump_cache_par(\%run);
- dump_status($local_spool, \%run);
- next;
- }
-
- # do some cleaning if the compilation is successful
- delete $cache->{needed}{$srpm} if defined $cache->{needed}{$srpm};
- delete $cache->{buildrequires}{$srpm} if defined $cache->{buildrequires}{$srpm};
- # FIXME It seems the glob is not correctly expanded any more, so listing the directory content to do so
- opendir my $binfh, "$chroot_tmp/home/$luser/rpm/RPMS/";
- my @packages;
- foreach my $bindir (readdir $binfh) {
- -d "$chroot_tmp/home/$luser/rpm/RPMS/$bindir" or next;
- opendir my $rpmfh, "$chroot_tmp/home/$luser/rpm/RPMS/$bindir";
- push @packages, map { "$chroot_tmp/home/$luser/rpm/RPMS/$bindir/$_" } grep { !/src\.rpm$/ && /\.rpm$/ } readdir $rpmfh;
- }
-
- # 20060810 warly We should fail here, but rpm is currently
- # segfaulting when trying to install packages
-
- if ($config->{check_binary_file}) {
- $urpmi->install_packages($srpm, $chroot_tmp, $local_spool, \%pack_provide, 'binary_test', "[REBUILD] binaries packages generated from $srpm do not install correctly", { maintainer => $maintainer } ,@packages) or next;
- } else {
- my $successfile = "$local_spool/log/$srpm/binary_test_$srpm-1.log";
- open my $f, ">$successfile";
- print $f "$srpm build ok";
- }
-
- $run{status}{$srpm} = 'ok';
- delete $cache->{failure}{$srpm} if defined $cache->{failure}{$srpm};
- if ($run{debug}) {
- plog("debug mode, skip other packages");
- exit();
- } elsif ($run{group}) {
- # we should not move the package until they are all compiled
- plog("group mode, keep packages for local media ($srpm is done $done)");
- $run{done}{$srpm} = $done;
- $urpmi->add_to_local_media($chroot_tmp, $srpm, $luser);
- } else {
- # drop packages and logs if we only want failure logs
- if ($run{delete_on_success}) {
- system("rm -rf $local_spool/log/$srpm/");
- } else {
- plog('OK', "build successful, copying packages to $local_spool.");
-
- system("cp $chroot_tmp/home/$luser/rpm/RPMS/*/*.rpm $local_spool &>/dev/null") and plog('ERROR', "ERROR: could not copy rpm files from $chroot_tmp/home/$luser/rpm/RPMS/ to $local_spool ($!)");
- }
-
- if ($run{copy_srpm}) {
- # replace the old srpm
- unlink "$local_spool/$old_srpm";
-
- system("cp $chroot_tmp/home/$luser/rpm/SRPMS/$srpm $local_spool &>/dev/null") and plog('ERROR', "ERROR: could not copy $srpm from $chroot_tmp/home/$luser/rpm/SRPMS/ to $local_spool ($!)");
- }
- process_queue($config, \%run, \@wrong_rpm, 1);
- }
- # dymp_cache each time so that concurrent process can get updated
- dump_cache_par(\%run) if $run{concurrent_run};
- }
- if ($run{group}) {
- my $i;
- for ($i; $i < @{$run{todo}}; $i++) {
- my (undef, $srpm) = @{$run{todo}[$i]};
- if (!$run{done}{$srpm}) {
- $rebuild = $urpmi->order_packages(\%provides, $luser);
- last;
- }
- }
- if ($prev_done == $done) {
- $rebuild = 0;
- if ($done == @{$run{todo}}) {
- plog('OK', "all packages succesfully compiled, copying packages to $local_spool.");
- system("cp $chroot_tmp/home/$luser/rpm/RPMS/*/*.rpm $local_spool &>/dev/null") and plog('ERROR', "ERROR: could not copy rpm files from $chroot_tmp/home/$luser/rpm/RPMS/ to $local_spool ($!)");
- if ($run{copy_srpm}) {
- system("cp $chroot_tmp/home/$luser/rpm/SRPMS/*.src.rpm $local_spool &>/dev/null") and plog('ERROR', "ERROR: could not copy SRPMS from $chroot_tmp/home/$luser/rpm/SRPMS/ to $local_spool ($!)");
- }
- } else {
- plog('FAIL', "some packages could not be compiled.");
- }
- }
- }
-} while $rebuild;
-
-if (!$run{debug} && !$run{use_old_chroot}) {
- clean_chroot($chroot_tmp, \%run, $config);
-}
-plog("reprocess generated packages queue");
-process_queue($config, \%run, \@wrong_rpm);
-
-dump_cache_par(\%run);
-
-plog('FAIL', "ERROR: RPM with a wrong SRPM name") if @wrong_rpm;
-if (@wrong_rpm && open my $file, ">$local_spool/log/wrong_srpm_names.log") {
- foreach (@wrong_rpm) {
- print $file "$_->[1] -> $_->[0] (", $cache->{rpm_srpm}{$_->[1]}, ")\n";
- }
-}
-
-dump_status($local_spool, \%run);
-
-send_status_mail(\%run, $config, $cache) if $run{status_mail};
-
-if ($config->{rsync_to} && !$run{no_rsync}) {
- # 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 -xc arcfour', "$local_spool/log/", "$config->{rsync_to}/$run{distro_tag}/$run{my_arch}/$run{media}/log/");
-}
-
-unlink "$run{pidfile_home}/$run{pidfile}" if $run{pidfile};
-
-exit();
-
-
-#
-#
-#
-
-sub check_needed {
- my ($srpm, $cache, $provides) = @_;
- if (!defined $cache->{needed}{$srpm} && !ref $cache->{needed}{$srpm}) { return 1 }
- my $ok = 1;
- # migrate old cache format
- my $ent = $cache->{needed}{$srpm};
- if (ref $ent eq 'ARRAY') {
- my $table = $ent;
- $cache->{needed}{$srpm} = {};
- foreach my $t (@$table) {
- my ($missing, $version, $maint) = @$t;
- $cache->{needed}{$srpm}{$missing} = {
- version => $version,
- maint => $maint
- };
- }
- $ent = $cache->{needed}{$srpm};
- }
- foreach my $name (keys %$ent) {
- my ($package, $version, $maint) = @{$ent->{$name}}{'package', 'version', 'maint'};
- # if packages does not exist anymore, it may have been rebuild, then try to recompute the build dependencies
- last if $package && !$provides->{$package};
- my $p_version = $provides->{$name};
- if ($p_version) {
- next if $version == $p_version;
- next if URPM::ranges_overlap($version, $p_version);
- }
- $ok = 0;
- if ($version) {
- $ent->{$name}{version} = $version;
- }
- my $v = $version;
- if ($package) {
- plog("ERROR: $srpm needs package $package which requires missing $name $v to be compiled.");
- } else {
- plog("ERROR: $srpm needs $name $v to be compiled.");
- }
- # try to recompile it once in a while
- last if $cache->{warning}{"install_deps_$srpm"}{$maint}++ % 72;
- return 1;
- }
- delete $cache->{needed}{$srpm} if $ok;
- $ok;
-}
-
-sub process_queue {
- my ($config, $run, $wrong_rpm, $o_quiet) = @_;
- return if !$run->{upload} && $o_quiet;
- my $dir = "$config->{local_upload}/iurt/$run->{distro_tag}/$run->{my_arch}/$run->{media}/";
- opendir my $rpmdir, $dir or return;
- my $urpmi = $run->{urpmi};
- foreach my $rpm (readdir $rpmdir) {
- my ($rarch, $srpm) = $urpmi->update_srpm($dir, $rpm, $wrong_rpm);
- $rarch or next;
- plog($rpm);
- next if !$run->{upload};
- # 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 $err = system('/usr/bin/scp', "$dir/$rpm", $config->{upload} . "/$config->{extra_subdir}/RPMS/");
- # try to keep the opportunity to prevent disk full
- if ($err) {
- plog("ERROR: process_queue: cannot copy $dir/$rpm to ", $config->{upload}, "/$config->{extra_subdir}/RPMS/ ($!)");
- next;
- }
- }
- if ($run->{upload_source}) {
-
- }
- unlink "$dir/$rpm";
- $cache->{queue}{$srpm} = 1;
- }
- closedir $rpmdir;
-}
-
-sub check_version {
- my ($run, $srpm, $srpm_version) = @_;
- my ($srpm_name) = $srpm =~ /(.*)-[^-]+-[^-]+\.src\.rpm/;
- $run->{build_all} and return 1;
- if (URPM::ranges_overlap("= $srpm", ">= $srpm_version->{$srpm_name}")) {
- $srpm_version->{$srpm_name} = $srpm;
- return 1;
- }
- 0;
-}
-
-sub check_pid {
- my ($run) = @_;
- my $hostname = `hostname`;
- chomp $hostname;
- my $pidfile = $run->{pidfile};
- my $lockfile = "$run->{pidfile_home}/$pidfile.$hostname.pid.lock";
- plog("trying to lock $lockfile");
- open my $lock, ">$lockfile";
- my $lock_ok;
- # lockf seems not to work, try to workarround, but this start to create lock on the lock for the lock of the file.
- my $status = 1; #File::lockf::lock($lock);
- if (!$status) {
- $lock_ok = 1;
- } else {
- plog("ERROR: could not lock pid file (status $status $!)");
- if (! -f "$lockfile.2") {
- plog("using $lockfile.2 as lock file");
- open my $lock2, ">$lockfile.2" or die "FATAL $program_name: could not open lock file $lockfile.2";
- print $lock2 $$;
- close $lock2;
- }
- }
- if (!$run->{concurrent_run}) {
- opendir my $dir, $run->{pidfile_home};
- foreach my $f (readdir $dir) {
- my ($pid_host) = $f =~ /$pidfile\.pid\.(.*)\.pid$/ or next;
- if ($pid_host ne $hostname) {
- my $pf = "$run->{pidfile_home}/$f";
- open my $test_PID, $pf;
- my $pid = <$test_PID>;
- my (@stat) = stat $pf;
- my $time = $stat[9];
- my $diff = time()-$time;
- my $msg = "$program_name: an other iurt is running for $run->{my_arch} on $pid_host, pid $pid, since $diff seconds";
- if ($diff < 36000) {
- plog("$msg\n");
- exit();
- } else {
- plog("$msg, ignoring it");
- }
- }
- }
- }
- $run->{pidfile} .= ".$hostname.pid";
- $pidfile = "$run->{pidfile_home}/$run->{pidfile}";
- if (-f $pidfile) {
- my (@stat) = stat $pidfile;
- open my $test_PID, $pidfile;
- my $pid = <$test_PID>;
- close $test_PID;
- if (!$pid) {
- plog("ERROR: invalid pidfile ($pid), should be <pid>");
- unlink $pidfile;
- }
- if ($pid && getpgrp $pid != -1) {
- my $time = $stat[9];
- my $state = `ps h -o state $pid`;
- chomp $state;
- if ($time < time()-36000 || $state eq 'Z') {
- plog("an other iurt pid $pid is running for a very long time or is zombie, killing it");
- my $i;
- while ($i < 5 && getpgrp $pid != -1) {
- kill_for_good($pid);
- $i++;
- sleep 1;
- }
- } else {
- plog("an other iurt is running for $run->{my_arch}, pid $pid, since ", time()-$time, " seconds");
- exit();
- }
- } else {
- plog("a previous iurt for $run->{my_arch} seems dead, cleaning.");
- unlink $pidfile;
- }
- }
- plog("setting $pidfile pid lock");
- open my $PID, ">$pidfile" or die "FATAL $program_name: could not open pidfile $pidfile for writing";
- print $PID $$;
- close $PID;
- if ($lock_ok) {
- File::lockf::ulock($lock);
- } else {
- unlink "$lockfile.2";
- }
- close $lock;
- unlink $lockfile;
-}
-
-sub check_media {
- my ($run, $cache, $config, $srpm_version, $wrong_rpm, $provides, $pack_provide, $maint) = @_;
-# We could rely only on parsing the synthesis, hoping that they are correct, however this scan is very fast, so...
- if (!$run->{build_all}) {
- foreach my $subdir (@{$config->{all_media}{$run->{media}}}) {
- my $rpms_dir = "$config->{repository}/$run->{distro}/$run->{my_arch}/media/$run->{media}/$subdir/";
- plog("checking current packages in $rpms_dir");
- opendir my $rpmdir, $rpms_dir or die "Could not open $rpms_dir: $!";
- my $urpmi = $run->{urpmi};
- foreach my $rpm (readdir $rpmdir) {
- my ($rarch, $srpm) = $urpmi->update_srpm($rpms_dir, $rpm, $wrong_rpm);
- $rarch or next;
- $cache->{queue}{$srpm} = 1;
- $run{status}{$srpm} = 'ok';
- check_version($run, $srpm, $srpm_version);
- }
- closedir $rpmdir;
- }
- }
-
- foreach my $m (keys %{$config->{all_media}}) {
- foreach my $subdir (@{$config->{all_media}{$m}}) {
- my $synthesis_file = "$config->{repository}/$run->{distro}/$run->{my_arch}/media/$m/$subdir/media_info/synthesis.hdlist.cz";
- if (-f $synthesis_file) {
- plog("Parsing $synthesis_file");
- # FIXME: this is reinventing the wheel and will fail if default compressor change:
- if (open my $syn, "zcat $synthesis_file |") {
- local $_;
- while (<$syn>) {
- my @prov;
- if (/^\@provides@(.*)/) {
- foreach my $p (split '@', $1) {
- if ($p =~ /([^[]+)(?:\[(.*)\])?/g) {
- push @prov, $1;
- $provides->{$1} = $2 || 1;
- }
- }
- } elsif (/\@info\@([^@]+)@/) {
- my $p = $1;
- my ($name) = $p =~ /(.*)-[^-]+-[^-]+\./;
- $provides->{$p} = 1;
- $pack_provide->{$_} = $name foreach @prov;
- }
- }
- } else {
- die "FATAL $program_name: Could not open $synthesis_file\n";
- }
- }
- }
- }
- #"
- my $nb;
- foreach my $subdir (@{$config->{all_media}{$run->{media}}}) {
- $nb += search_packages(0, $cache, $provides, $run, $maint, $srpm_version, "$config->{repository}/$run->{distro}/SRPMS/$run->{media}/$subdir/");
- }
- $nb;
-}
-
-sub search_packages {
- my ($clean, $cache, $provides, $run, $_maint, $srpm_version, @dir) = @_;
- my ($to_compile, %rep);
- plog("iurt search_package: @dir");
- foreach my $dir (@dir) {
- plog("checking SRPMS dir $dir");
- 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;
- $run->{status}{$srpm} ||= 0;
- if ($config->{unwanted_packages} && $srpm =~ /$config->{unwanted_packages}/) { next }
- my $ok = 1;
- if (check_version($run, $srpm, $srpm_version)) {
- if (!$run->{ignore_failure} && defined $cache->{failure}{$srpm}) {
- $run->{status}{$srpm} = 'build_failure';
- next;
- }
- my $check_needed = check_needed($srpm, $cache, $provides);
- $run->{status}{$srpm} = 'missing_buildrequires' if !$check_needed;
- -f "$dir/$srpm" or next;
- if (!$cache->{queue}{$srpm} && $check_needed) {
- if (!check_arch("$dir/$srpm", $run{my_arch})) {
- $run->{status}{$srpm} = 'not_on_this_arch';
- next;
- }
- my $hdr = RPM4::Header->new("$dir/$srpm");
- my $changelog = $hdr->queryformat("%{CHANGELOGNAME}");
- my ($mail) = $changelog =~ /<(.*@.*)>/;
- $maint{$srpm} = $mail;
- print "$program_name: will try to compile $srpm\n";
- $to_compile++;
- push @{$run->{todo}}, [ $dir , $srpm, 1 ];
- }
-
- $ok &&= $cache->{queue}{$srpm};
- }
- if ($clean && ($rep{$srpm} || $ok)) {
- print "$program_name: cleaning $dir/$srpm\n";
- unlink "$dir/build/$srpm";
- unlink "$dir/$srpm";
- }
- $rep{$srpm} = 1;
- }
- closedir $rpmdir;
- }
- $to_compile;
-}
-
-sub add_sudoers {
- my ($chroot, $user) = @_;
- my $tmpfile = "/tmp/sudoers";
- my $file = "$chroot/etc/sudoers";
- my $f;
- if (!open $f, ">$tmpfile") {
- plog("ERROR: could not open $file ($!)");
- return 0;
- }
- print $f qq(Cmnd_Alias RPM=/bin/rpm,/usr/sbin/urpmi,/usr/sbin/urpme,/usr/sbin/urpmi.addmedia,/usr/sbin/urpmi.update,/usr/sbin/urpmi.removemedia
-root ALL=(ALL) ALL
-$user ALL=(ALL) NOPASSWD:RPM
-);
- close $f;
- chmod 0440, $tmpfile;
-
- plog("adding sudo for /bin/rpm, /usr/sbin/urpmi and /usr/sbin/urpme");
- my $ret = sudo($config, '--cp', $tmpfile, $file);
- unlink $tmpfile;
-
- if (!$ret) {
- plog("ERROR: could not write $file ($!)");
- return 0;
- }
-
- return -f $file;
-}
-
-sub dump_status {
- my ($local_spool, $run) = @_;
- my $media = $run->{media} ? "$run->{media}." : "";
- if (open my $file, ">$local_spool/log/status.${media}log") {
- foreach my $srpm (sort keys %{$run->{status}}) {
- print $file "$srpm: ";
- if ($run{status}{$srpm}) {
- print $file $run->{status}{$srpm};
- } else {
- print $file "unknown";
- }
- print $file "\n";
- }
- }
-}
-
-#
-# CM: FIXME: should notify in case of recreate_srpm_failure
-#
-
-sub send_status_mail {
- my ($run, $config, $cache) = @_;
- my %output;
-
- print "iurt compilation status\n";
-
- foreach my $rpm (keys %{$run->{status}}) {
- next if $run->{status}{$rpm} =~ /ok|not_on_this_arch/;
-
- if ($run->{status}{$rpm} eq 'missing_buildrequires') {
- foreach my $missing (keys %{$cache->{needed}{$rpm}}) {
- my $h = $cache->{needed}{$rpm}{$missing};
- my $maint = $h->{maint} || 'Other';
- my $package = $h->{package};
- if ($package) {
- push @{$output{missing}{$maint}{$package}{$missing}{$h->{version}}}, $rpm;
- } else {
- $output{missing}{$maint}{$rpm}{$missing}{$h->{version}} = 1;
- }
- }
- } elsif ($run->{status}{$rpm} eq 'build_failure') {
- my ($maint) = get_maint($run, $rpm);
- if ($cache->{buildrequires}{$rpm}) {
- push @{$output{buildrequires}{$maint}}, $rpm;
- } else {
- push @{$output{build}{$maint}}, $rpm;
- }
- } elsif (!$run->{status}{$rpm}) {
- # need to find something more usefull to do at that point
- next;
- }
- }
-
- my $text = "*** Missing buildrequires tag in specfile ***\n";
- foreach my $maint (keys %{$output{buildrequires}}) {
- $text .= "\n$maint\n";
- foreach my $pack (keys %{$output{missing}{$maint}}) {
- foreach my $missing (keys %{$cache->{buildrequires}{$pack}}) {
- my $rpms = $cache->{buildrequires}{$pack}{$missing};
- if (@$rpms) {
- $text .= " $pack should have a buildrequires on @$rpms (for $missing-devel)\n";
- } else {
- $text .= " $pack should have a buildrequires for $missing-devel\n";
- }
- }
- }
- }
-
- $text = "*** Missing dependencies ***\n";
- foreach my $maint (keys %{$output{missing}}) {
- $text .= "\n$maint\n";
- foreach my $pack (keys %{$output{missing}{$maint}}) {
- foreach my $missing (%{$output{missing}{$maint}{$pack}}) {
- my $h = $output{missing}{$maint}{$pack}{$missing};
- foreach my $version (keys %$h) {
- if (ref $h->{$version}) {
- $text .= " $pack should be recompile because\n $missing " . ($version ? "$version " : '') . "is not provided anymore\n";
- $text .= " to compile " . join("\n ", @{$h->{$version}}) . "\n";
- } else {
- $text .= " $pack needs $missing " . ($version ? "$version " : '') . "\n";
- }
- }
- }
- }
- }
- $text .= "\n*** Build failure ***\n";
- foreach my $maint (keys %{$output{build}}) {
- $text .= "\n$maint\n";
- foreach my $rpm (@{$output{build}{$maint}}) {
- $text .= " $rpm (see $config->{log_url}/$run{distro_tag}/$run{my_arch}/$run->{media}/log/$rpm/)\n";
- }
- }
- print "$text\n";
- sendmail($run->{status_mail}, '' , "Iurt report for $run->{my_arch}/$run->{media}", $text, "Iurt the rebuild bot <$config->{admin}>", 0, $config);
-}
-
-sub find_provides {
- my ($pack_provide, $p) = @_;
- my @rpm;
- foreach my $provides (keys %{pack_provide}) {
- if ($provides =~ /$p/ && $provides =~ /devel/) {
- push @rpm, $pack_provide->{$provides};
- }
- }
- @rpm;
-}
-
-sub check_sudo_access() {
- return 0 == system("$sudo -l -n $config->{iurt_root_command} &>/dev/null </dev/null");
-}
-
-__END__
-
-Discussion
-
-20061222 Warly
- Group building
- For the group building, we need to order the source packages, the problem is that we do not
- really know what will be the provides of the resulting packages before building the.
- We could guess them by looking to older version, but that means that we need to have an access to
- the media deps files (synthesis should be enough).
- We can also perform a first pass of build to check which package build and then what are their
- provides. For the second pass, we will them be able to use the previously build packages to
- solve buildrequires.