[Midnightbsd-cvs] mports: magus.pl: Add logging.
ctriv at midnightbsd.org
ctriv at midnightbsd.org
Wed Oct 24 12:57:47 EDT 2007
Log Message:
-----------
Add logging. Make scp errors more verbose. Add command line flags. Fix
SIGINT bug.
Modified Files:
--------------
mports/Tools/magus/slave:
magus.pl (r1.3 -> r1.4)
-------------- next part --------------
Index: magus.pl
===================================================================
RCS file: /home/cvs/mports/Tools/magus/slave/magus.pl,v
retrieving revision 1.3
retrieving revision 1.4
diff -LTools/magus/slave/magus.pl -LTools/magus/slave/magus.pl -u -r1.3 -r1.4
--- Tools/magus/slave/magus.pl
+++ Tools/magus/slave/magus.pl
@@ -40,11 +40,15 @@
use lib qw(/usr/mports/Tools/lib);
use Magus;
+
use Sys::Syslog;
+use POSIX qw(setsid);
+use Getopt::Std qw(getopts);
+
-$SIG{INT} = sub { die "Caught SIGINT\n" };
+$SIG{INT} = sub { report('info', "$$: caught sigint"); die "Caught SIGINT $$\n" };
-main(@ARGV);
+main();
=head1 magus.pl
@@ -53,6 +57,20 @@
packages to the chroot dir, chroot's to the chroot dir, builds the port,
uploads the resulting package, and reports the results to the master database.
+=head1 OPTIONS
+
+=over 4
+
+=item -f
+
+Stay in the forground (don't daemonize).
+
+=item -v
+
+Verbose mode, print lots of status information to stdout.
+
+=back
+
=head2 main()
Top level function. Sets up logging and starts the main loop. The general
@@ -61,54 +79,34 @@
=cut
+my %opts;
+
+
sub main {
my $lock;
-
- openlog("magus", "ndelay,pid", "local0");
- syslog('info', "Starting magus on %s (%s)", $Magus::Machine->name, $Magus::Machine->arch);
+ getopts('fv', \%opts);
+
+ deamonize() unless $opts{f};
+
+ report('info', "Starting magus on %s (%s)", $Magus::Machine->name, $Magus::Machine->arch);
while (1) {
$lock = Magus::Lock->get_ready_lock();
if (!$lock) {
# there's no more ports to test, sleep for a while and check again.
- syslog('debug', "No ports to build, sleeping $Magus::Config{DoneWaitPeriod}");
+ report('debug', "No ports to build, sleeping $Magus::Config{DoneWaitPeriod} seconds.");
sleep($Magus::Config{DoneWaitPeriod});
next;
}
- syslog('info', "Starting test run for: %s", $lock->port);
+ report('info', "Starting test run for: %s", $lock->port);
- eval { run_test($lock) };
+ run_test($lock);
+
+ report('info', 'Run completed for: %s', $lock->port);
- # An exception ($@) was thrown. Note the internal error and move on.
- if ($@) {
- if ($@ =~ m/Caught SIGINT/) {
- exit 0;
- }
-
- my $error = $@;
-
- syslog('err', "Exception throw building %s: %s", $lock->port, $error);
-
- my $result = $lock->port->current_result;
-
- $result->delete if $result;
-
- $result = $lock->port->add_to_results({
- version => $lock->port->version,
- arch => $Magus::Machine->arch,
- machine => $Magus::Machine,
- summary => 'internal',
- });
-
- $result->add_to_subresults({
- type => 'internal',
- name => 'ExceptionThrown',
- msg => "Internal exception thrown: $error"
- });
- }
$lock->delete;
}
@@ -138,28 +136,49 @@
sub run_test {
my ($lock) = @_;
-
- my $port = $lock->port;
-
- my $chroot = Magus::Chroot->new(tarball => $Magus::Config{ChrootTarBall});
-
- copy_dep_pkgfiles($lock, $chroot);
+ #
+ # we have a few eval blocks here, because we want to be sure that the
+ # exception will not allow the child to go to the main program logic.
+ #
+ my ($port, $chroot);
+
+ eval {
+ $port = $lock->port;
+ $chroot = Magus::Chroot->new(tarball => $Magus::Config{ChrootTarBall});
+
+ copy_dep_pkgfiles($lock, $chroot);
+ };
+
+ if ($@) {
+ handle_exception($@, $lock);
+ return;
+ }
# we fork so just the child chroots, then we can get out of the chroot.
my $pid = fork();
if ($pid) {
# Parent, we wait for the child to finish.
+ local $SIG{INT} = sub {
+ waitpid($pid, 0);
+ handle_exception("Caught SIGINT", $lock);
+ exit(1);
+ };
+
waitpid($pid, 0);
} elsif (defined $pid) {
- # Child, chroot and go.
- $SIG{INT} = 'DEFAULT';
- $chroot->do_chroot();
- chdir($port->origin);
+ eval {
+ $chroot->do_chroot();
+ chdir($port->origin);
- my $test = Magus::PortTest->new(port => $port, chroot => $chroot);
- my $results = $test->run;
+ my $test = Magus::PortTest->new(port => $port, chroot => $chroot);
+ my $results = $test->run;
- insert_results($port, $results);
+ insert_results($port, $results);
+ };
+
+ if ($@) {
+ handle_exception($@, $lock);
+ }
exit(0);
} else {
@@ -168,15 +187,17 @@
# Back to the parent here.
if ($? == 0) {
- my $result = $port->current_result;
+ eval {
+ my $result = $port->current_result;
- if ($result->summary eq 'pass' || $result->summary eq 'warn') {
- upload_pkgfile($port, $chroot);
+ if ($result->summary eq 'pass' || $result->summary eq 'warn') {
+ upload_pkgfile($port, $chroot);
+ }
+ };
+
+ if ($@) {
+ handle_exception($@, $lock);
}
-
- syslog('info', "Test run complete for $port; summary: %s", $result->summary);
-
- return 1;
} else {
die "Child exited unexpectantly: $?\n";
}
@@ -193,9 +214,8 @@
sub copy_dep_pkgfiles {
my ($lock, $chroot) = @_;
- foreach my $depend ($lock->port->depends) {
-
- syslog('debug', "coping $depend package to chroot dir.");
+ foreach my $depend ($lock->port->all_depends) {
+ report('debug', "coping $depend package to chroot dir.");
if ($depend->current_result && ($depend->current_result->summary eq 'pass' || $depend->current_result->summary eq 'warn')) {
# There should be a package that we can use to install the port.
@@ -203,9 +223,8 @@
next;
}
-
die "Port was scheduled as ready to build, but a dependancy had not been built successfuly.\n";
- }
+ }
return 1;
}
@@ -225,8 +244,13 @@
my $dest = join('/', $chroot->root, $chroot->packages, 'All');
my $cmd = "/usr/bin/scp $Magus::Config{'PkgfilesRoot'}/$arch/$file $dest";
+ report('debug', "downloading: $cmd");
- system($cmd) == 0 || die "$cmd failed. (exit $?)\n";
+ my $out = `$cmd 2>&1`;
+
+ if ($? != 0) {
+ die "$cmd returned non-zero: $out\n";
+ }
}
@@ -244,8 +268,13 @@
my $from = join('/', $chroot->root, $chroot->packages, 'All', $file);
my $cmd = "/usr/bin/scp $from $Magus::Config{'PkgfilesRoot'}/$arch/$file";
+ report('debug', "uploading: $cmd");
- system($cmd) == 0 || die "$cmd failed (exit $?)\n";
+ my $out = `$cmd 2>&1`;
+
+ if ($? != 0) {
+ die "$cmd returned non-zero: $out\n";
+ }
}
@@ -258,6 +287,8 @@
sub insert_results {
my ($port, $results) = @_;
+
+ report('info', "Inserting results for $port; summary: $results->{summary}");
my $res = $port->add_to_results({
version => $port->version,
@@ -284,7 +315,89 @@
$res->add_to_logs($results->{log});
}
}
+
+=head2 daemonize()
+
+Disassociate with our parent process group and run as a daemon.
+
+=cut
+
+sub daemonize {
+ report('debug', 'daemonizing');
+
+ my $pid = fork;
+
+ if (!defined $pid) {
+ die "Unable to fork self: $!\n";
+ }
+
+ # if $pid is non-zero, we're the parent. Time to die.
+ exit 0 if $pid;
+
+ # create our own process group
+ setsid();
+}
+
+=head2 report($level, $format, ...)
+
+Logs the current
+
+=cut
+
+{
+ my $is_open = 0;
+
+ sub report {
+ my ($level, @msg) = @_;
+
+ openlog("magus", "ndelay,pid", "local0") unless $is_open++;
+
+ syslog($level, @msg);
+
+ if ($opts{v}) {
+ my ($format, @args) = @msg;
+ my $time = localtime;
+
+ printf "[$time] ($$): $format\n", @args;
+ }
+ }
+}
+
+
+=head2 handle_exception($error, $lock)
+
+Report an exception for the given lock.
+
+=cut
+
+sub handle_exception {
+ my ($error, $lock) = @_;
+
+ # Any result for the current port is no good.
+ my $result = $lock->port->current_result;
+ $result->delete if $result;
+
+ if ($error =~ m/SIGINT/) {
+ report('debug', 'Exiting 0 from SIGINT (prior result for %s deleted).', $lock->port);
+ exit 0;
+ }
+ report('err', "Exception throw building %s: %s", $lock->port, $error);
+
+ $result = $lock->port->add_to_results({
+ version => $lock->port->version,
+ arch => $Magus::Machine->arch,
+ machine => $Magus::Machine,
+ summary => 'internal',
+ });
+
+ $result->add_to_subresults({
+ type => 'internal',
+ name => 'ExceptionThrown',
+ msg => "Internal exception thrown: $error"
+ });
+}
+
1;
__END__
More information about the Midnightbsd-cvs
mailing list