[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