1 #!/usr/bin/perl -- -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
3 # /home/src/perl/repoperls/installed-perls/perl/p5B38YI/perl-5.10.0@35088/bin/perl /home/k/sources/CPAN/ghub/cpanpm/bin/loop-over-recent.pl
11 loop-over-recent.pl [OPTIONS]
20 my $optpod = <<'=back';
24 Defaults to C<install>. Other supported values are
31 Takes one argument of the form C<v5.15.7-109-g035b682,v5.15.5>.
32 Incompatible with C<--perlglob>.
34 NOT IMPLEMENTED. Needs more work to find out whether a child had
35 success with its task.
37 =item B<--config_test_report=s>
39 Defaults to C<1>. By setting it to anything, we set
40 $CPAN::Config->{test_report} to that value. Note that this string will
41 be passed to a subprocess, so will be subject to an evaluation there.
49 Completely different beast than the original program design: instead
50 of looping over recent we only run these CPAN shell object identifiers
51 against all perls in this config and stop after that.
53 Bonus feature: when the string contains dash(es) and no slash, then
54 dashes are turned into double colons, turning eg. C<Text-PO-Parser>
55 into C<Text::PO::Parser>.
57 Another bonus feature: string is split on comma and whitespace and
58 then converted to multiple --distro arguments.
60 Third bonus feature: if an argument looks like an http URL, it is
61 shortened to a distro argument.
63 =item B<--dotcpanhome=s>
65 defaults to C< $ENV{HOME}/.cpan >. The place passed to every
66 smoker-perl where it should pick the MyConfig from.
72 =item B<--historical-excursions-arraysize=i>
74 TEMPORARILY DISABLED. Needs the equivalent of https://github.com/eserte/srezic-misc/blob/master/scripts/cpan_recent_uploads2#L225
77 my $do = eval { CPAN::Shell->expand('Distribution', $path) };
78 debug('not indexed'), next if !$do;
81 Defaults to 0, so no historical excursions are being done. If set,
82 whenever all work is done, we pick some random distro from the N most
83 recent distros to keep the CPU busy.
87 when determining the config file, use this hostname.
91 Boolean. Build new perls on demand. When we encounter a perl path that
92 does not exist, we try to get a hold of that corresponding directory
93 with a lock for competing processes and then call this program with
94 the usual parameters. When that other program finishes and we have no
95 perl, we log this in the corresponding directory and give up. The
96 logfile will then prevent further attempts.
98 If this option is used together with the --perlglob option, the result
99 depends on the results of the glob which may in turn depend on perls
100 already present, so may become confusing to debug. But it's OK to use
101 when the glob returns one or more not-existing perls, so we usually
102 bootstrap with one perl we want to have for all the following
107 Perform not more loops than this many.
109 =item B<--monitoring=s>
111 Defaults to the string C<default>, which means the parent process
112 printd a line like this every second:
114 ==========monitoring proc 28683 perl /home/src/perl/repoperls/installed-perls/perl/v5.16.3/a2da secs 6.0000=======
116 Other possible values:
118 silent parent prints nothing
120 =item B<--mydistrobundles!>
122 Shortcut for several frequently used --distro=... options. Hardcoded
123 in the program. RTFS.
125 =item B<--parallel=i>
127 Defaults to 1 which means we never have more than one job running.
128 Specifies how many children we spawn when there is enough work to do.
130 =item B<--perlglob=s@>
132 Instead of using the perls from the configuration, use those specified
133 in the glob expression. Repeatable. Incompatible with C<--bisect>.
135 =item B<--randomskip=f>
137 Value between 0 and 1. Defaults to 0 which means no test will be
138 skipped. A value of 0.25 will skip on average every fourth activity, a
139 value of 1 would skip all activities.
141 =item B<--skip_sanity_check!>
143 Normally we allocate big files every now and then to verify we have
144 disk space available.
148 Sleep that many seconds after every build.
152 do not install, only test. Equivalent to
158 Defaults to 45 minutes. Time allowed for one whole process of
159 installing/testing/running one job with one perl. When timeout
160 is reached the child process is killed and reaped.
164 In the two places where we use a temporary file or directory, use
165 this directory as base.
167 =item B<--transient_build_dir!>
169 If true, a new build_dir is provided for every cpan run. Intended to
170 make concurrent invocations easy. Note: the most annoying interaction
171 with other users of the same homedirectory ist the lock around the
172 FTPstats.yml file. TODO: there needs to be a way to disallow download
179 Picks the 512 most recent uploads, filters out outdated stuff, and
180 installs the not outdated parts into a (sample of) perl(s). The order
181 goes from oldest to newest distro. After every upload it writes a
182 status kind of timestamp into something like
183 ~/.cpan/loop-over-recent.state file (grep for $statefile). The status
184 item is the epoch according to the RECENT files. This ensures that a
185 new run of this program will not retry more than one distro from the
196 our $HAVE_SHUFFLE = eval { require Algorithm
::Numerical
::Shuffle
};
198 use CPAN
::DistnameInfo
;
200 use Fcntl
qw( :flock :seek O_RDONLY O_RDWR O_CREAT );
201 use File
::Basename
qw(fileparse dirname);
202 use File
::Path
qw(rmtree);
206 Getopt
::Long
::Configure
("no_auto_abbrev");
207 use Pod
::Usage
qw(pod2usage);
208 use List
::MoreUtils
qw(uniq);
209 use POSIX
":sys_wait_h";
210 use Sys
::Hostname
qw(hostname);
211 use Time
::HiRes
qw(sleep);
213 our $HAVE_DD = eval { require Data
::Dump
};
215 # indirect dependencies:
219 if (-e
"/home/k/sources/rersyncrecent/lib/") {
221 lib
->import("/home/k/sources/rersyncrecent/lib/");
224 our $HAVE_RRR = eval { require File
::Rsync
::Mirror
::Recent
};
227 my @opt = $optpod =~ /B<--(\S+)>/g;
235 pod2usage
(0) if $Opt{help
};
236 pod2usage
(1) if @ARGV;
238 $Opt{"historical-excursions-arraysize"} = 0;
239 if ($Opt{"historical-excursions-arraysize"} && !$HAVE_SHUFFLE) {
240 warn "WARNING: will fail soonish because Shuffle missing, better install Algorithm::Numerical::Shuffle now";
243 $Opt{tmpdir
} ||= "/tmp";
244 $Opt{timeout
} ||= 45*60; # PDL
245 $Opt{dotcpanhome
} ||= "$ENV{HOME}/.cpan";
246 $Opt{parallel
} ||= 1;
247 $Opt{action
} ||= "install";
248 $Opt{monitoring
} ||= "default";
249 $Opt{config_test_report
} //= "1";
250 if (defined $Opt{randomskip
} && ($Opt{randomskip
} < 0 || $Opt{randomskip
} > 1)) {
251 die "option --randomskip must be between 0 and 1 (inclusive); is $Opt{randomskip}\n";
253 if (my $d = $Opt{distro
}) {
257 push @d2, split /[,\s]+/, $d0;
259 $d = $Opt{distro
} = \
@d2;
261 if (/-/ and not m
|/|) {
264 s
|^https?
://.+?
/authors/id/[A-Z]/[A
-Z
]{2}/||;
267 } elsif (! $HAVE_RRR) {
268 die "this perl ($^X) has no File::Rsync::Mirror::Recent available, so we must have a --distro option specified";
270 if ($Opt{perlglob
} && $Opt{bisect
}) {
271 die "The options perlglob and bisect cannot be used together";
273 if ($Opt{mydistrobundles
}) {
275 my $date = "2011_10_21";
276 my @snaps = glob "$Opt{dotcpanhome}/Bundle/Snapshot_${date}_*.pm";
278 my($n) = $s =~ /Snapshot_${date}_(\d+)/;
279 push @
{$Opt{distro
}}, "Bundle::Snapshot_${date}_$n";
288 sub determine_perls
{
289 my($perls_config_file) = @_;
291 return unless $perls_config_file;
292 return unless -e
$perls_config_file;
293 my $hostname = $Opt{hostname
} || hostname
();
294 my $path_slice_for_perl = $hostname eq "k83" ?
"perl" : "host/$hostname";
295 if (open my $fh2, $perls_config_file) {
298 s/#.*//; # remove comments
299 next if /^\s*$/; # remove empty/white lines
301 s
|^|/home/sand
/src/perl
/repoperls/installed
-perls
/$path_slice_for_perl/|;
304 next if ! -x
$_ && ! $Opt{makeperl
};
314 sub single_child_parental_control
{
315 my($pid,$system,$perlnick,$perl,$upload) = @_;
316 my $start = my $sleep_to = Time
::HiRes
::time;
317 SUPERVISE
: while (waitpid($pid, WNOHANG
) <= 0) {
319 my $this_sleep = $sleep_to - Time
::HiRes
::time;
320 $this_sleep = 0.1 if $this_sleep < 0.1; # maybe to enable ^C at all (?)
324 for my $c (qw(k i l l e d)) {
332 sleep 0.5; # give them a chance to ^C immediately again
333 my $ret = waitpid($pid, WNOHANG
);
335 warn "Warning: process $ret returned \$\?=$?.
337 Command was '@$system'
343 my $have_waited = $sleep_to-$start;
344 if ($Opt{monitoring
} eq "default") {
345 warn sprintf "==========monitoring proc %d perl %s secs %.4f=======\n", $pid, $perlnick, $have_waited;
346 } elsif ($Opt{monitoring
} eq "silent") {
349 if ($have_waited >= $Opt{timeout
}) {
352 warn "ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN\n";
353 warn " Something went wrong during\n";
355 warn " $upload->{path}\n";
356 warn " have_waited='$have_waited' Opt{timeout}=$Opt{timeout}'\n";
357 warn " (sleeping $sleep)\n";
358 warn "ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN-ATTN\n";
363 warn "Sleeping $Opt{sleep} seconds now\n";
369 my($chldr,$action,$distro,$perlnick,$perl,$upload,$combo,$cmbsn) = @_;
372 if (! defined $pid) { # contention
373 warn "Contention '$!', sleeping 2";
376 } elsif ($pid) { # parent
378 while (@
$chldr >= $Opt{parallel
}){
379 for (my $i = $#$chldr; $i>=0; $i--){
380 if (waitpid($chldr->[$i], WNOHANG
) > 0){
381 openlog
"smoke", "pid", "local0";
382 syslog
"info", "reaped proc|->$chldr->[$i]";
384 splice @
$chldr, $i, 1;
387 sleep 0.01; # wait until some job finishes, we are at maximum
390 one_fork
($action,$distro,$perlnick,$perl,$upload,$combo);
397 $cmbsn->{$perl,$upload->{path
}} = $upload->{epoch
};
401 my($action,$distro,$perlnick,$perl,$upload,$combo) = @_;
405 "-I$Opt{dotcpanhome}",
411 my $bdir; # build directory
414 my @actions = split " ", $action;
415 push @actions, $distro;
416 my $f = shift @actions;
417 $func = sprintf "%s(%s)", $f, join(",",map {"q{$_}"} @actions);
419 my $commonshellcmd = qq{
420 \
$SIG{XCPU
} = sub { warn sprintf "%s: Caught inner SIGXCPU after %d seconds running\n", scalar localtime, time-\
$^T
};
421 \
$CPAN::Config
->{test_report
}=$Opt{config_test_report
}; \
$CPAN::Suppress_readline
=1; $func};
422 if ($Opt{transient_build_dir
}) {
423 $bdir = File
::Temp
::tempdir
(
424 "loop_over_bdir-$$-XXXXXX",
426 CLEANUP
=> 0, # we clean up ourselves
428 # *this* program exit
430 warn "DEBUG: bdir[$bdir] \$\$[$$]\n";
431 push @system, "\$CPAN::Config->{build_dir}=q{$bdir}; $commonshellcmd",
433 push @system, "\$CPAN::Config->{build_dir_reuse}=0; $commonshellcmd",
435 # 0==system @system or die;
438 if (! defined $pid) { # contention
439 warn "Contention '$!', sleeping 2";
441 } elsif ($pid) { # parent
442 single_child_parental_control
($pid,\
@system,$perlnick,$perl,$upload);
444 warn sprintf "%s: About to rmtree '%s'", scalar localtime, $bdir;
452 openlog
"smoke", "pid", "local0";
453 syslog
"info", "$combo\nproc|->$$";
456 my ($soft, $hard) = BSD
::Resource
::getrlimit
(+BSD
::Resource
::RLIMIT_CPU
);
458 BSD
::Resource
::setrlimit
(+BSD
::Resource
::RLIMIT_CPU
, 0.9*3600, 1*3600);
460 exec @system or sleep 1; # give them a chance to ^C immediately again
467 # '-Dprefix=/home/src/perl/repoperls/installed-perls/perl/v5.19.1/165a -Dmyhostname=k83 -Dinstallusrbinperl=n -Uversiononly -Dusedevel -des -Ui_db -DDEBUGGING=-g';
468 # (have removed:) -Uuseithreads -Uuselongdouble
469 # perl ~/src/andk/andk-cpan-tools/bin/makeperl.pl -j=4 --ud=UD --report --module=Moose
470 my($perlroot) = $mperl =~ m
|(.+)/bin/perl
$|;
471 unless (-d
$perlroot) {
472 File
::Path
::make_path
($perlroot, { verbose
=> 1, mode
=> 0755 });
474 my($lockfile) = File
::Spec
->catfile($perlroot,"LOGCK");
476 unless (open $lfh, "+<", $lockfile) {
477 unless ( open $lfh, ">>", $lockfile ) {
478 die "ALERT: Could not open >> '$lockfile': $!"; # XXX should not die
480 unless ( open $lfh, "+<", $lockfile ) {
481 die "ALERT: Could not open +< '$lockfile': $!"; # XXX should not die
484 if (flock $lfh, LOCK_EX
|LOCK_NB
) {
485 warn "Info[$$]: Got the lock, continuing";
487 warn "FATAL[$$]: lockfile '$lockfile' locked by a different process; skipping this perl";
492 "127e" => ["--ud=UD"],
493 "165a" => ["--ud=UU"],
494 "a2da" => ["--ud=DD"],
495 "9980" => ["--ud=DU"],
496 "8378" => ["--ud=UD", "--nodebugging"],
497 "9ab7" => ["--ud=UU", "--nodebugging"],
498 "7e7a" => ["--ud=DD", "--nodebugging"],
499 "8005" => ["--ud=DU", "--nodebugging"],
500 # with 2016 libswanted:
501 "8942" => ["--ud=UD"],
502 "79cc" => ["--ud=UU"],
503 "109d" => ["--ud=DD"],
504 "f7bf" => ["--ud=DU"],
505 "8d81" => ["--ud=UD", "--nodebugging"],
506 "f991" => ["--ud=UU", "--nodebugging"],
507 "de40" => ["--ud=DD", "--nodebugging"],
508 "13e0" => ["--ud=DU", "--nodebugging"],
510 "f11c" => ["--ud=DU"],
511 "89ad" => ["--ud=UU"],
512 "5ea4" => ["--ud=DD"],
513 "2d7c" => ["--ud=UD"],
514 "d2d1" => ["--ud=UU", "--debuggingoption=DEBUGGING=both"],
515 "a1a1" => ["--ud=DD", "--debuggingoption=DEBUGGING=both"],
516 "276a" => ["--ud=DU", "--debuggingoption=DEBUGGING=both"],
517 "0a29" => ["--ud=UD", "--debuggingoption=DEBUGGING=both"],
518 # note 2015-03-08: Today I succeeded for 5.8.9 with just the current hints/linux.sh
519 # and that's why we now have a perl-5.8.9/165a
520 # 2015-03-08 07:12 git checkout perl-5.8.9
521 # 2015-03-08 07:31 git fetch
522 # 2015-03-08 07:32 git show FETCH_HEAD:hints/linux.sh >| hints/linux.sh
523 # 2015-03-08 07:32 perl /home/sand/src/andk/andk-cpan-tools/bin/makeperl.pl --j=6 --ud=rand --report --module=PAUSE::Packages
524 "5da8" => ["--ud=UU",
527 "--addopts=Ddlsrc=dl_dlopen.xs",
528 "--addopts=Dlibs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lc",
529 "--addopts=Dlibpth=/usr/lib/x86_64-linux-gnu /usr/local/lib /lib /usr/lib",
532 my($hash,$pdir) = fileparse
($perlroot); # ("127e","/home/sand/src/....")
534 my($tag) = fileparse
($pdir);
535 my $opts = $map{$hash};
537 print $lfh "Could not determine arguments for hash[$hash] mperl[$mperl]\n";
540 my $bindir = dirname
(__FILE__
);
544 "$bindir/makeperl.pl",
548 "--notest", # TODO: FIXME: should only turn off testing when necessary
550 warn "prepare a clone to run system[@system2]";
551 my $clonedir = File
::Temp
::tempdir
553 "loop_over_clonedir-$$-XXXXXX",
555 CLEANUP
=> 1, # we clean up
556 # ourselves much earlier than *this* program exit
559 print $lfh "Could not create a clonedir: $!\n";
562 # cd /tmp && git clone /home/sand/src/perl/repoperls/perl5.git.perl.org/perl --no-single-branch perl-clone-$$ && cd perl-clone-$$/
563 my $cwd = Cwd
::cwd
();
564 chdir $clonedir or die "Could not chdir to $clonedir: $!"; # XXX should not die
565 warn "Info: now in $clonedir";
566 0==system("git", "clone", "/home/sand/src/perl/repoperls/perl5.git.perl.org/perl", "--no-single-branch", ".") # XXX hardcoded sand
567 or die "problem building a clone"; # XXX should not die
568 warn "Info: now have checked out perl";
569 0==system("git", "checkout", $tag) or die "problem checking out tag '$tag'";
570 warn "Info: checked out $tag";
574 "Alert: %s: problem building perl %s/%s with '%s'",
580 chdir $cwd or die "could not chdir back to '$cwd': $!"; # XXX should not die
581 File
::Path
::remove_tree
($clonedir);
584 sub read_recent_events
{
585 my($rf,$rx,$max) = @_;
587 my $recent_events = $rf->news(max
=> $max);
588 $recent_events = [ grep { $_->{path
} =~ $rx and $_->{type
} eq "new" } @
$recent_events ];
591 $recent_events = [ grep {
592 my $path = $_->{path
};
593 my $d = CPAN
::DistnameInfo
->new($path);
595 # warn "no dist for path[$path]" unless $dist;
596 $dist ?
!$seen{$dist}++ : "";
602 my $recentfile = "/home/ftp/pub/PAUSE/authors/RECENT.recent";
604 # local is for reading the recentfiles, localroot is for reading the
605 # files. one should go away.
607 $rf = File
::Rsync
::Mirror
::Recent
->new
609 localroot
=> "/home/ftp/pub/PAUSE/authors/",
610 local => $recentfile,
612 my $hostname = $Opt{hostname
} || hostname
();
613 if ($hostname =~ s/\..*//) {
614 warn "Warning: hostname contained a dot, shortening to '$hostname'";
616 my $perls_config_file;
617 if ($hostname eq "k75") {
618 $perls_config_file = "$0.otherperls";
619 } elsif ($Opt{perlglob
} || $Opt{bisect
}) {
622 $perls_config_file = "$0.otherperls.$hostname";
623 if (-f
$perls_config_file) {
624 warn "Using perls config '$perls_config_file'";
626 die "Could not find '$perls_config_file'";
629 my $bbname = fileparse
($0,qr{\.pl});
630 my $statefile = "$ENV{HOME}/.cpan/$bbname.state";
631 my $rx = qr!\.(tar.gz|tar.bz2|zip|tgz|tbz)$!;
632 my $max_epoch_worked_on = 0;
635 my $state = do { open my $fh, $statefile or die "Couldn't open '$statefile': $!";
641 $max_epoch_worked_on = $state if $state;
643 warn "max_epoch_worked_on[$max_epoch_worked_on] statefile[$statefile]";
644 BSD
::Resource
::setrlimit
(BSD
::Resource
::RLIMIT_CORE
(), 40*1024*1024, 45*1024*1024);
646 # whenever we do not run in an endless loop, we want to limit globally
647 BSD
::Resource
::setrlimit
(+BSD
::Resource
::RLIMIT_CPU
, 2.5*3600, 3*3600);
648 $SIG{XCPU
} = sub { warn sprintf "%s: Caught SIGXCPU after %d seconds running\n", scalar localtime, time-$^T
};
650 # 2012-07-12: we had several oom-killer experiences that locked the
651 # klatt machine up. oom killed the wrong processes first. The right
652 # one would have been a perl with 3387649 kB:
653 BSD
::Resource
::setrlimit
(BSD
::Resource
::RLIMIT_RSS
(), 3_000_000_000
, 4_000_000_000
);
654 # 2012-07-29: the above limit to RSS did not prevent the OOM but the
656 BSD
::Resource
::setrlimit
(BSD
::Resource
::RLIMIT_AS
(), 3_000_000_000
, 4_000_000_000
);
658 # BSD::Resource::setrlimit(BSD::Resource::RLIMIT_FSIZE(), 4_000_000_000, 4_000_000_000);
659 my $cmbsn = {}; # was: %comboseen
660 my $count_uploaditem = 0;
661 my $chldr = []; # was: @children
662 ITERATION
: while () {
664 my $optdstrs = $Opt{distro
}||[]; # was: @distro
665 my $iteration_start = time;
667 my $historical_excursion = 0;
669 $recent_events = [map {+{path
=> $_}} @
$optdstrs];
671 $recent_events = read_recent_events
($rf,$rx);
673 if ($Opt{"historical-excursions-arraysize"}) {
674 if ($max_epoch_worked_on >= $recent_events->[0]{epoch
}) {
675 $historical_excursion = 1;
676 $recent_events = read_recent_events
($rf,$rx,$Opt{"historical-excursions-arraysize"});
677 while (! $HAVE_SHUFFLE){
678 $HAVE_SHUFFLE = eval { require Algorithm
::Numerical
::Shuffle
};
679 warn "Note: this perl ($^X) has no Algorithm::Numerical::Shuffle";
682 Algorithm
::Numerical
::Shuffle
::shuffle
($recent_events);
684 warn sprintf "DEBUG: \$max_epoch_worked_on '%s' >= \$recent_events->[0] '%s'\n", $max_epoch_worked_on, $HAVE_DD ? Data
::Dump
::pp
($recent_events->[0]) : $recent_events->[0];
685 @
$recent_events = reverse @
$recent_events;
688 @
$recent_events = reverse @
$recent_events;
693 if ($Opt{perlglob
}) {
694 my @globs = @
{$Opt{perlglob
}};
696 for my $glob (@globs) {
697 my @perls = glob $glob;
698 push @allperls, @perls;
702 UPLOADITEM
: for my $upload (@
$recent_events) {
704 unless (@
$optdstrs) {
705 next UPLOADITEM
unless $upload->{path
} =~ $rx;
706 next UPLOADITEM
unless $upload->{type
} eq "new";
707 next UPLOADITEM
if $upload->{path
} =~ m
|/perl
-5\
.[12]\d
|;
708 next UPLOADITEM
if $upload->{path
} =~ m
|A
/AN/ANDK
/.*CPAN
-Test
-Dummy
-Perl5
-|;
709 if ($historical_excursion) {
710 if ($cmbsn->{"ALL",$upload->{path
}}) {
711 if ($upload->{epoch
} > $max_epoch_worked_on) {
712 # we never know wheather what we was the mtime of the
713 # latest is still the same one, we know, that pause may
714 # touch a file (for unknown reasons)
715 $max_epoch_worked_on = $upload->{epoch
};
719 } elsif ($upload->{epoch
} < $max_epoch_worked_on) {
720 warn sprintf "Already done: %s %.1f\n", substr($upload->{path
},8), $upload->{epoch
} unless keys %$cmbsn;
723 } elsif ($upload->{epoch
} == $max_epoch_worked_on) {
724 if ($cmbsn->{"ALL",$upload->{path
}}) {
727 warn "Maybe already worked on, we'll retry them: $upload->{path}";
729 if ($historical_excursion) {
730 for (qw(h i s t o r i c a l)) {
737 open my $fh, ">", $statefile or die "Could not open >$statefile\: $!";
738 print $fh $upload->{epoch
}, "\n";
739 close $fh or die "Could not write: $!\nTry\n echo '$upload->{epoch}' > '$statefile'\n ";
741 $max_epoch_worked_on = $upload->{epoch
};
744 last ITERATION
if $Opt{max
} && ++$count_uploaditem > $Opt{max
};
746 my $action = $Opt{action
};
747 if ($upload->{path
} =~ m
{^D
/DA/DAGOLDEN
/CPAN
-Reporter
-\d
+\
.\d
+_
748 /CPAN
-Distribution
-\d
751 } elsif ($Opt{test
}) {
755 # XXX: we should compute exceptions for every distro that has a
756 # higher numbered developer release. Say Foo-1.4801 is released
757 # but we have already 1.48_51 installed. We do not want this
758 # stable stuff. Test yes, so we should 'make test' instead of
759 # 'make install'. The problem with this is that we do not know
760 # what exactly is in the distro. So we must go through
761 # CPAN::DistnameInfo somehow. It gets even more complicated when
762 # the item here gets passed to a queuerunner because then the
763 # decision if test or install shall be called cannot be made now,
764 # it must be made when the job is actually started.
767 # https://github.com/eserte/srezic-misc/blob/master/scripts/cpan_recent_uploads2#L225
768 # how slaven decides to limit operations on indexed distros (we
769 # talked about the gotcha with downgrading XML::LibXML::Common)
771 my($upload_epoch,$epoch_as_localtime);
772 if ($upload->{epoch
}){
773 $upload_epoch = $upload->{epoch
};
774 $epoch_as_localtime = scalar localtime $upload->{epoch
};
776 $epoch_as_localtime = $upload_epoch = "N/A";
778 $perls ||= determine_perls
($perls_config_file) || [];
779 my @perlset = @
$perls;
780 PERL
: while (@perlset) {
781 my $perl = shift @perlset;
782 last PERL
if $Signal;
784 # cautious code location. Once we have this robust, we would
785 # prefer to move it into the forked process; but the
786 # downside is that we do not know whether this process will
788 if ($Opt{"makeperl"}) {
792 next PERL
unless -e
$perl;
793 my $perlnick = $perl;
794 $perlnick =~ s
|^/home/sand
/src/perl
/repoperls/installed
-perls
/perl/||;
795 $perlnick =~ s
|/bin/perl
||;
797 do { open my $fh, "$perl -e \"print \$]\" |" or die "Couldn't open $perl: $!";
800 unless ($perl_version) {
801 warn "Alert: could not determine perl version of '$perl', skipping";
805 if ($Opt{randomskip
} && rand() <= $Opt{randomskip
}) {
806 require Term
::ANSIColor
;
807 warn Term
::ANSIColor
::colored
(["green on_magenta"], "skipping due to randomskip = $Opt{randomskip}\n");
811 my $testtime = localtime;
812 my $combo = "perl|-> $perl (=$perl_version)\npath|-> $upload->{path}\n".
813 "recv|-> $epoch_as_localtime (=$upload_epoch)\ntime|-> $testtime";
815 } elsif ($cmbsn->{$perl,$upload->{path
}}){
816 warn "dead horses combo $combo";
820 warn "\n\n$combo\n\n\n";
822 # need no sanity check on path or anything
824 my $abs = File
::Spec
->catfile($rf->localroot, $upload->{path
});
833 warn "Giving up waiting for '$abs', maybe already deleted?";
839 $ENV{PERL_MM_USE_DEFAULT
} = 1;
840 $ENV{AUTOMATED_TESTING
} = 1 unless defined $ENV{AUTOMATED_TESTING
} && length $ENV{AUTOMATED_TESTING
};
841 $ENV{PERL_CANARY_STABILITY_NOPROMPT
}=1;
842 # How do I make sure this DISPLAY is running?
843 # while true; do date ; if ! ps auxww | grep -v grep | grep -q Xvfb ; then Xvfb :121 & fi; echo -n 'sleeping 60 '; sleep 60; done
844 # alternatives: vncserver, Xnest, etc.
845 $ENV{DISPLAY
} = ":121";
846 my $distro = $upload->{path
};
848 if ($Opt{parallel
} <= 1) {
849 one_fork
($action,$distro,$perlnick,$perl,$upload,$combo);
851 some_forks
($chldr,$action,$distro,$perlnick,$perl,$upload,$combo,$cmbsn);
858 $cmbsn->{"ALL",$upload->{path
}} = $upload->{epoch
};
860 next UPLOADITEM
; # nothing can change that would influence us
861 } elsif ($historical_excursion) {
865 next ITERATION
; # see what is new before simply going through the ordered list
869 last ITERATION
; # nothing left to do
871 my $minimum_time_per_loop = 15;
872 while (time - $iteration_start < $minimum_time_per_loop) {
873 my @stat = stat($recentfile);
874 last if $stat[9] > $iteration_start;
878 for my $k (keys %$cmbsn) {
879 delete $cmbsn->{$k} if $cmbsn->{$k} < time - 60*60*24*2;
881 { local $| = 1; print "."; } # painting dots
885 for (my $i = $#$chldr; $i; $i--){
886 if (waitpid($chldr->[$i], WNOHANG
) > 0){
887 openlog
"smoke", "pid", "local0";
888 syslog
"info", "reaped proc|->$chldr->[$i]";
890 splice @
$chldr, $i, 1;
894 warn "giving up on signal";
897 warn "will have to wait for children[@$chldr]";
898 while (my $c = pop @
$chldr){
899 if (waitpid($c, 0) > 0){
900 warn "Finished child: $c";
901 openlog
"smoke", "pid", "local0";
902 syslog
"info", "reaped proc|->$c";
907 print "all children reaped\n";
912 # cleanup => 1 only active at program exit, not at scope exit!
913 return if $Opt{skip_sanity_check
};
915 my $cannotcontinuenow = 0;
916 for my $dir ($Opt{tmpdir
},
918 "/var/tmp", # these bloody testers write everywhere,
919 # sometimes in /var/lib/ for databases,
920 # this is a proxy for this case
922 my $tmpdir = eval { File
::Temp
::tempdir
(
923 "loop-over-recent-XXXXXX",
925 ) } or die "Could not create tempdir in '$dir': $!";
926 my $ttt = "$tmpdir/testfreespace";
927 open my $fh, ">", $ttt or die "Could not open > '$ttt': $!";
929 # 32 bytes times 2**15 equals 1 MB
930 print $fh "f r e e e e s p a c e <%-1/8-\> " x
2**15;
934 $success = close $fh;
937 warn "Couldn't close '$ttt': $!";
938 $cannotcontinuenow = 1;
941 if ($cannotcontinuenow) {
942 warn "$$: n o f r e e s p a c e\n" for 1..8;
943 sleep(30 + rand(180));
948 open my $fh, "-|", "ipcs -m" or die "Could not fork ipcs -m: $!";
949 my $shared_mem_segments = 0;
952 $shared_mem_segments++;
954 if ($shared_mem_segments > 4000) {
955 die sprintf "Too many shared memory segments (%d) for further testing, try something like\n %s\n", $shared_mem_segments, q{ipcs -m|grep sand|head -1004|awk '{print $2}'|xargs -n 1 ipcrm -m};
956 } elsif ($shared_mem_segments > 1000) {
957 warn sprintf "Info: (%s) allocated shared mem segments now: %d\n", $0, $shared_mem_segments;
965 # cperl-indent-level: 2