#!/usr/local/bin/perl # # Copyright (c) 2002-2004 Eric Wallengren # This file is part of the Continuous Automated Build and Integration # Environment (CABIE) # # CABIE is distributed under the terms of the GNU General Public # License version 2 or any later version. See the file COPYING for copying # permission or http://www.gnu.org. # # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED OR # IMPLIED, without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. ANY USE IS AT YOUR OWN RISK. # # Permission to modify the code and to distribute modified code is granted, # provided the above notices are retained, and a notice that the code was # modified is included with the above copyright notice. # # # Rewrite of mailer to be more modular supporting remote # perforce servers # my $POSIX = 1; my $ospackage; # # See if this is a windoz system... # if ($^O =~ /MSWin32/) { $POSIX = 0; $ospackage = "winsys"; } else { $ospackage = "unixsys"; } BEGIN { push @INC, "lib"; push @INC, "../lib"; push @INC, "../../lib"; } # # Standard Perl packages # use strict; no strict "refs"; use Getopt::Std; use Cwd; use Sys::Hostname; use Mail::Sendmail; # # Get hostname # my $hostname = hostname(); $hostname =~ s/\.[a-zA-Z0-9\n]+//g; # # Buildserver specific packages # use Bldsvr; require "$hostname.pm"; # # Use winsys for M$ # require "$ospackage.pm"; my $dir = cwd(); unshift (@INC, "$dir/lib"); # # Call CM broker # use cmbroker; my $cmbroker = new cmbroker; # # Use winsys for M$ # my $os = new $ospackage; my $config = new $hostname; my %mail; # # Grab configuration information from server # $mail{From} = $config->NOTIFYFROM; $mail{Smtp} = $config->SMTP; # # get current dir # my $dir = cwd(); my %Options; # # Use lib from buildserver # unshift (@INC, "$dir/lib"); # Prepend a directory name open (MAILDBG, ">$dir/proc/maildbg.log"); getopt('n:t:j:s:', \%Options); # # We got past that, get job properties # my $buildname = $Options{n}; my $buildtype = $Options{t}; my $buildnum = $Options{j}; my $buildstat = $Options{s}; if (!defined($buildname) || !defined($buildtype) || !defined($buildnum) || !defined($buildstat)) { usage(); } _logger("$buildname $buildtype $buildnum $buildstat"); # # declare build vars # my $port; my $client; my $top; my $type; my $sccs; my $browserlink; # # Declare hash variables # my %emailhash; my %emailbchash; my %emptyhash; # # Declare mail variables # my $subject; my @message; my @tousers; my @bctousers; my $heading; my $key; my $address; my $line; # # Get configuraton information # my $TmpDir = $config->BTMP; my $WriteDir = $config->JOBDIR; my $Company = $config->COMPANY; my $Webserver = $config->WEBSERVER; my $Notifyall = $config->NOTIFYALL; my $Globmail = $config->GLOBMAIL; my $Admin = $config->ADMIN; my $Delim = $config->SMTPDELIM; my $failall = $config->FAILALL; my $serverroot = $config->BSR; # # Set default boolean values # my $Globfail = 0; my $Spamon = 0; my $bSendMail = 1; # # Set tempdir (for all platfoms) # $ENV{"TMPDIR"}="$TmpDir"; $ENV{"TEMP"} ="$TmpDir"; $ENV{"TMP"} ="$TmpDir"; # # Globally read job roperties... # if (!_getjobproperties($buildname)) { print STDERR "no job $buildname!\n"; exit 1; } # # Log messages # _logger("got job properties"); # # Set default messages # if ($buildstat =~ "failed") { $Globfail = 1; $mail{Subject} = "*BUILDBREAKER* $buildname $buildnum $buildtype ". "build failed"; $heading = "$buildname $buildnum build failed!"; } else { $mail{Subject} = "$buildname $buildnum build completed"; $heading = "$buildname $buildnum is available from ". "$Webserver/$buildname/$buildnum/"; } push (@message, "$heading\n\n"); _logger("heading will be $heading"); my $logs = "Logfiles are available from ". "$Webserver/$buildname/$buildnum/"; _logger("going to add subscribers"); # # Generate list of subscribers # _addsubscribers($buildname); my $sccscommand = $sccs."_client"; my $realclient = $cmbroker->$sccscommand($client); push @message, "Files checked out from $port using $realclient:\n\n"; # # Call function to populate mailer hashes for this particular job # my @changes = genchanges($buildname, $port, $realclient, $top, $sccs, $browserlink); # # Create an html representation of changes made to the tree # since the '.log' extension doesn't open an editor by default # open(HTM, ">$WriteDir/$buildname/$buildnum/$buildname.update.html"); print HTM "Changes for $buildname $buildnum". "

Changes for $buildname $buildnum


";


foreach my $line (@changes) {
    print HTM $line;
    push (@message, "$line");
}

#
# Write each entry to the html file
#
push (@message, "\n");

print HTM "
"; # # Close the html file # close(HTM); foreach $address (keys %emailhash) { push (@tousers, $address); } foreach $address (keys %emailbchash) { push (@bctousers, $address); } _logger( "$subject" ); push (@message, "\n$logs\n"); if (-f "$dir/config/$hostname.disclaimer") { my @Disclaimer = `cat $dir/config/$hostname.disclaimer`; foreach $line (@Disclaimer) { push (@message, $line); } } open (F, ">$TmpDir/$buildname.mail"); foreach $line (@message) { print F $line; } close (F); open (MSG, "<$TmpDir/$buildname.mail"); foreach $line () { $mail{Message} .= $line; } close (MSG); foreach $line (@tousers) { $mail{To} .= "$line$Delim"; } foreach $line (@bctousers) { $mail{Bcc} .= "$line$Delim"; } # # If the build failed sequentially - from .bad file # see if the server is set to send multiple spams... # if ($Globfail && -f "$serverroot/proc/$buildname.bad" ) { # # if global failure spam is set to 0 # if (! $failall) { $bSendMail = 0; } } if ($bSendMail) { sendmail %mail; if ($Mail::Sendmail::error) { $mail{To} = "$Admin"; $mail{Message} = "content of ". "\$Mail::Sendmail::error:\n$Mail::Sendmail::error\n"; $mail{Subject} = "*Failed to deliver email* $buildname $buildnum ". "$buildtype "; sendmail %mail; } } close(MAILDBG); # # Add the list of subscribers to the emailhash # sub _addsubscribers() { my $name = shift; my @subscribers; my $entry; # # SQL Stuff... # my $sqlquery; my @sqlarray; my @spamarray; _logger("_addsubscribers using SQL"); # # Always notify build admin # _addemailhash($Admin, 1); # # If all users need to be notified of a build failure # if ($Notifyall && $Globfail) { _logger("_addsubscribers notifyall and globfail"); # # Get general spam setting # $sqlquery = "select spam from configuration where ". "server=\"$hostname\" and title=\"$name\""; _logger("_addsubscribers $sqlquery"); @spamarray = $os->run_sql_query("$sqlquery", ";", 0); # # If spam is on for the build add global email address # to the mail hash # if ($spamarray[0]) { $Spamon = 1; _logger("_addsubscribers adding $Globmail 0"); _addemailhash($Globmail, 0); } else { # # Spam is not set for this build, get subscribers # $sqlquery = "select address from subscription ". "where server=\"$hostname\" and title=\"$name\" ". "order by address"; _logger("_addsubscribers $sqlquery if not spamarray"); @sqlarray = $os->run_sql_query("$sqlquery", ";", 0); # # Add any subscribers found # foreach $entry (@sqlarray) { chomp $entry; _logger("_addsubscribers adding $entry 1"); _addemailhash($entry, 1); } } } else { # # This is a good build, just add subscribers initially # _logger("_addsubscribers !notifyall or !globfail"); $sqlquery = "select address from subscription ". "where server=\"$hostname\" and title=\"$name\" ". "order by address"; @sqlarray = $os->run_sql_query("$sqlquery", ";", 0); foreach $entry (@sqlarray) { chomp $entry; _addemailhash($entry, 1); } } } # # Parse sync log, generate changelist, user, and email info # sub genchanges() { my $name = shift; my $port = shift; my $client = shift; my $root = shift; my $sccs = shift; my $formatted = shift; my $sccscommand; my @synclist; my $href = \%emailhash; _logger( "genchanges changing dir to $root" ); $sccscommand = $sccs."_lastcheckout"; @synclist = $cmbroker->$sccscommand($port, $client, $root, $name, $buildnum, $formatted, $href); return @synclist; } sub usage { print "usage: \n\n"; print "\t-n jobname\n"; print "\t-j jobnumber\n"; print "\t-t type [debug|retail]\n"; print "\t-s status [passed|failed]\n\n"; exit 1; } # # Add email addresses to hash in order to help aviod duplicate addresses # sub _addemailhash() { my $emailaddress = shift; my $type = shift; _logger("addemailhash $emailaddress $type"); # # If this is a bcc address # if ($type) { $emailbchash{"$emailaddress"} = ""; } else { $emailhash{"$emailaddress"} = ""; } } # # Get job properties for this build # sub _getjobproperties() { my $job = shift; my $Found; my @JobDesc; # # SQL Stuff... # my $sqlquery; my @sqlarray; my $ret; $sqlquery = "select port, client, top, type, sccs, browserlink ". "from configuration where server=\"$hostname\" ". "and title=\"$job\""; @sqlarray = $os->run_sql_query("$sqlquery", ";", 0); $ret = @sqlarray; ($port, $client, $top, $type, $sccs, $browserlink) = split(/;/, @sqlarray[0]); return $ret; } sub _logger { my $string = shift; my $reqtime = scalar localtime; print MAILDBG "[$reqtime]: $string\n"; }