2008-11-28 16:13:06 +00:00
#! /var/run/current-system/sw/bin/perl -w
2008-11-10 13:33:12 +00:00
use strict ;
use File::Basename ;
2008-11-12 14:29:32 +00:00
use File::stat ;
2008-11-25 11:09:15 +00:00
use Hydra::Schema ;
2008-11-28 14:36:04 +00:00
use Hydra::Helper::Nix ;
2010-09-01 08:52:54 +00:00
use Hydra::Helper::AddBuilds ;
2009-07-07 16:15:38 +00:00
use Email::Sender::Simple qw( sendmail ) ;
use Email::Sender::Transport::SMTP ;
use Email::Simple ;
use Email::Simple::Creator ;
2009-07-08 15:52:55 +00:00
use Sys::Hostname::Long ;
2009-07-10 09:47:42 +00:00
use Config::General ;
2009-08-12 13:31:27 +00:00
use Text::Table ;
use POSIX qw( strftime ) ;
2009-10-15 13:23:15 +00:00
use Net::Twitter::Lite ;
2010-01-19 14:15:31 +00:00
use Data::Dump qw( dump ) ;
2010-04-26 14:36:56 +00:00
use Switch ;
2008-11-10 13:33:12 +00:00
2009-04-22 22:59:54 +00:00
STDOUT - > autoflush ( ) ;
2008-11-28 14:36:04 +00:00
my $ db = openHydraDB ;
2008-11-10 13:33:12 +00:00
2009-07-10 14:43:21 +00:00
my % config = new Config:: General ( $ ENV { "HYDRA_CONFIG" } ) - > getall ;
2009-07-10 09:47:42 +00:00
2009-10-15 13:23:15 +00:00
sub sendTwitterNotification {
my ( $ build ) = @ _ ;
return unless ( defined $ ENV { 'TWITTER_USER' } && defined $ ENV { 'TWITTER_PASS' } ) ;
my $ addURL = defined $ ENV { 'HYDRA_BUILD_BASEURL' } ;
my $ jobName = $ build - > project - > name . ":" . $ build - > jobset - > name . ":" . $ build - > job - > name ;
my $ status = $ build - > resultInfo - > buildstatus == 0 ? "SUCCEEDED" : "FAILED" ;
my $ system = $ build - > system ;
my $ duration = ( $ build - > resultInfo - > stoptime - $ build - > resultInfo - > starttime ) . " seconds" ;
my $ url = $ ENV { 'HYDRA_BUILD_BASEURL' } . "/" . $ build - > id ;
my $ nt = Net::Twitter::Lite - > new (
username = > $ ENV { 'TWITTER_USER' } ,
2009-10-15 13:35:52 +00:00
password = > $ ENV { 'TWITTER_PASS' } ,
clientname = > "Hydra Build Daemon"
2009-10-15 13:23:15 +00:00
) ;
my $ tag = $ build - > project - > name ;
my $ msg = "$jobName ($system): $status in $duration #$tag" ;
if ( length ( $ msg ) + 1 + length ( $ url ) <= 140 ) {
$ msg = "$msg $url" ;
}
eval {
my $ result = eval { $ nt - > update ( $ msg ) } ;
} ;
warn "$@\n" if $@ ;
}
2009-03-26 12:53:39 +00:00
2010-04-26 14:36:56 +00:00
sub statusDescription {
my ( $ buildstatus ) = @ _ ;
my $ status = "Unknown failure" ;
switch ( $ buildstatus ) {
case 0 { $ status = "Success" ; }
case 1 { $ status = "Failed with non-zero exit code" ; }
case 2 { $ status = "Dependency failed" ; }
case 4 { $ status = "Cancelled" ; }
}
return $ status ;
}
2009-07-07 16:15:38 +00:00
sub sendEmailNotification {
my ( $ build ) = @ _ ;
2009-07-08 15:52:55 +00:00
die unless defined $ build - > resultInfo ;
2010-09-01 10:50:57 +00:00
return if ! ( $ build - > jobset - > enableemail && ( $ build - > maintainers ne "" || $ build - > jobset - > emailoverride ne "" ) ) ;
2009-07-07 16:15:38 +00:00
2009-07-08 15:52:55 +00:00
# Do we want to send mail?
2010-01-06 13:07:59 +00:00
my $ prevBuild ;
( $ prevBuild ) = $ db - > resultset ( 'Builds' ) - > search (
{ project = > $ build - > project - > name
, jobset = > $ build - > jobset - > name
, job = > $ build - > job - > name
, system = > $ build - > system
, finished = > 1
, id = > { '!=' , $ build - > id }
} , { order_by = > [ "timestamp DESC" ] }
) ;
if ( defined $ prevBuild && ( $ build - > resultInfo - > buildstatus == $ prevBuild - > resultInfo - > buildstatus ) ) {
return ;
2009-07-08 15:52:55 +00:00
}
# Send mail.
# !!! should use the Template Toolkit here.
print STDERR "sending mail notification to " , $ build - > maintainers , "\n" ;
my $ jobName = $ build - > project - > name . ":" . $ build - > jobset - > name . ":" . $ build - > job - > name ;
2010-04-26 14:36:56 +00:00
my $ status = statusDescription ( $ build - > resultInfo - > buildstatus ) ;
2009-07-08 15:52:55 +00:00
2010-04-27 08:01:38 +00:00
my $ baseurl = hostname_long ;
2009-07-24 18:06:34 +00:00
my $ sender = $ config { 'notification_sender' } ||
2010-04-27 08:01:38 +00:00
( ( $ ENV { 'USER' } || "hydra" ) . "@" . $ baseurl ) ;
2009-07-08 15:52:55 +00:00
2009-07-10 09:47:42 +00:00
my $ selfURI = $ config { 'base_uri' } || "http://localhost:3000" ;
2009-07-08 15:52:55 +00:00
2009-08-12 13:31:27 +00:00
sub showTime { my ( $ x ) = @ _ ; return strftime ( '%Y-%m-%d %H:%M:%S' , localtime ( $ x ) ) ; }
2009-08-12 13:50:59 +00:00
my $ infoTable = Text::Table - > new ( { align = > "left" } , \ " | " , { align = > "left" } ) ;
2009-08-12 13:31:27 +00:00
my @ lines = (
[ "Build ID:" , $ build - > id ] ,
[ "Nix name:" , $ build - > nixname ] ,
[ "Short description:" , $ build - > description || '(not given)' ] ,
[ "Maintainer(s):" , $ build - > maintainers ] ,
[ "System:" , $ build - > system ] ,
[ "Derivation store path:" , $ build - > drvpath ] ,
[ "Output store path:" , $ build - > outpath ] ,
[ "Time added:" , showTime $ build - > timestamp ] ,
) ;
push @ lines , (
[ "Build started:" , showTime $ build - > resultInfo - > starttime ] ,
[ "Build finished:" , showTime $ build - > resultInfo - > stoptime ] ,
[ "Duration:" , $ build - > resultInfo - > stoptime - $ build - > resultInfo - > starttime . "s" ] ,
) if $ build - > resultInfo - > starttime ;
$ infoTable - > load ( @ lines ) ;
my $ inputsTable = Text::Table - > new (
2009-08-12 13:50:59 +00:00
{ title = > "Name" , align = > "left" } , \ " | " ,
{ title = > "Type" , align = > "left" } , \ " | " ,
2009-08-12 13:31:27 +00:00
{ title = > "Value" , align = > "left" } ) ;
@ lines = ( ) ;
foreach my $ input ( $ build - > inputs ) {
my $ type = $ input - > type ;
push @ lines ,
[ $ input - > name
, $ input - > type
2010-01-19 14:15:31 +00:00
, ( $ input - > type eq "build" || $ input - > type eq "sysbuild" )
2009-08-12 13:31:27 +00:00
? $ input - > dependency - > id
: ( $ input - > type eq "string" || $ input - > type eq "boolean" )
? $ input - > value : ( $ input - > uri . ':' . $ input - > revision )
] ;
}
$ inputsTable - > load ( @ lines ) ;
2010-01-06 13:57:41 +00:00
my $ loglines = 50 ;
my $ logfile = $ build - > resultInfo - > logfile ;
2010-04-19 10:25:17 +00:00
my $ logtext = defined $ logfile && - e $ logfile ? `tail -$loglines $logfile` : "No logfile available.\n" ;
2010-01-06 13:57:41 +00:00
2009-07-08 15:52:55 +00:00
my $ body = "Hi,\n"
. "\n"
2010-02-10 12:27:16 +00:00
. "This is to let you know that Hydra build " . $ build - > id
2010-08-09 13:08:27 +00:00
. " of job " . $ jobName . " " . ( defined $ prevBuild ? "has changed from '" . statusDescription ( $ prevBuild - > resultInfo - > buildstatus ) . "' to '$status'" : "is '$status'." ) . ".\n"
2009-07-08 15:52:55 +00:00
. "\n"
2009-08-12 13:50:59 +00:00
. "Complete build information can be found on this page: "
2009-07-08 15:52:55 +00:00
. "$selfURI/build/" . $ build - > id . "\n"
2010-01-06 13:57:41 +00:00
. ( $ build - > resultInfo - > buildstatus != 0 ? "\nThe last $loglines lines of the build log are shown at the bottom of this email.\n" : "" )
2009-07-08 15:52:55 +00:00
. "\n"
2009-08-12 13:31:27 +00:00
. "A summary of the build information follows:\n"
. "\n"
. $ infoTable - > body
. "\n"
. "The build inputs were:\n"
. "\n"
. $ inputsTable - > title
. $ inputsTable - > rule ( '-' , '+' )
. $ inputsTable - > body
. "\n"
2010-01-06 13:57:41 +00:00
. "Regards,\n\nThe Hydra build daemon.\n"
. ( $ build - > resultInfo - > buildstatus != 0 ? "\n---\n$logtext" : "" ) ;
2010-01-06 13:07:59 +00:00
# stripping trailing spaces from lines
$ body =~ s/[\ ]+$//gm ;
2009-07-08 15:52:55 +00:00
2010-01-06 13:07:59 +00:00
my $ to = ( ! $ build - > jobset - > emailoverride eq "" ) ? $ build - > jobset - > emailoverride : $ build - > maintainers ;
2009-07-07 16:15:38 +00:00
my $ email = Email::Simple - > create (
header = > [
2010-01-06 13:07:59 +00:00
To = > $ to ,
2009-07-08 15:52:55 +00:00
From = > "Hydra Build Daemon <$sender>" ,
2010-04-26 14:36:56 +00:00
Subject = > "Hydra job $jobName build " . $ build - > id . ": $status" ,
2010-04-27 08:01:38 +00:00
'X-Hydra-Instance' = > $ baseurl ,
2010-04-26 14:36:56 +00:00
'X-Hydra-Project' = > $ build - > project - > name ,
'X-Hydra-Jobset' = > $ build - > jobset - > name ,
'X-Hydra-Job' = > $ build - > job - > name
2009-07-07 16:15:38 +00:00
] ,
2010-01-07 13:53:05 +00:00
body = > "" ,
2009-07-07 16:15:38 +00:00
) ;
2010-01-07 13:53:05 +00:00
$ email - > body_set ( $ body ) ;
2009-07-07 16:15:38 +00:00
2009-07-08 15:52:55 +00:00
print $ email - > as_string if $ ENV { 'HYDRA_MAIL_TEST' } ;
2009-07-07 16:15:38 +00:00
2010-08-31 14:08:59 +00:00
sendmail ( $ email ) ;
2009-07-07 16:15:38 +00:00
}
2008-11-11 12:54:37 +00:00
sub doBuild {
my ( $ build ) = @ _ ;
2008-11-10 13:33:12 +00:00
2010-05-26 08:03:59 +00:00
my $ drvPath = $ build - > drvpath ;
my $ outPath = $ build - > outpath ;
my $ maxsilent = $ build - > maxsilent ;
my $ timeout = $ build - > timeout ;
2008-11-10 13:33:12 +00:00
my $ isCachedBuild = 1 ;
my $ outputCreated = 1 ; # i.e., the Nix build succeeded (but it could be a positive failure)
my $ startTime = 0 ;
my $ stopTime = 0 ;
2008-11-25 00:38:16 +00:00
my $ buildStatus = 0 ; # = succeeded
my $ errormsg = undef ;
2009-03-09 17:21:10 +00:00
2008-11-10 13:33:12 +00:00
if ( ! isValidPath ( $ outPath ) ) {
$ isCachedBuild = 0 ;
2009-03-09 16:22:41 +00:00
# Do the build.
2008-11-10 13:33:12 +00:00
$ startTime = time ( ) ;
2008-11-25 00:38:16 +00:00
my $ thisBuildFailed = 0 ;
my $ someBuildFailed = 0 ;
2008-11-11 17:49:50 +00:00
# Run Nix to perform the build, and monitor the stderr output
# to get notifications about specific build steps, the
# associated log files, etc.
2009-10-08 11:51:49 +00:00
my $ cmd = "nix-store --realise $drvPath " .
2010-05-26 08:03:59 +00:00
"--max-silent-time $maxsilent --keep-going --fallback " .
2009-10-08 11:51:49 +00:00
"--no-build-output --log-type flat --print-build-trace " .
2009-03-15 11:56:11 +00:00
"--add-root " . gcRootFor $ outPath . " 2>&1" ;
2010-01-06 13:57:41 +00:00
2009-10-26 13:55:54 +00:00
my $ max = $ build - > buildsteps - > find (
{ } , { select = > { max = > 'stepnr + 1' } , as = > [ 'max' ] } ) ;
my $ buildStepNr = defined $ max ? $ max - > get_column ( 'max' ) : 1 ;
2009-03-16 16:56:47 +00:00
my % buildSteps ;
2008-11-11 17:49:50 +00:00
open OUT , "$cmd |" or die ;
while ( <OUT> ) {
2008-11-25 00:38:16 +00:00
$ errormsg . = $ _ ;
2008-11-11 17:49:50 +00:00
unless ( /^@\s+/ ) {
print STDERR "$_" ;
next ;
}
if ( /^@\s+build-started\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/ ) {
2009-03-16 17:46:46 +00:00
my $ drvPathStep = $ 1 ;
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2009-03-12 14:18:30 +00:00
$ build - > buildsteps - > create (
2009-03-16 17:46:46 +00:00
{ stepnr = > ( $ buildSteps { $ drvPathStep } = $ buildStepNr + + )
2008-11-11 17:49:50 +00:00
, type = > 0 # = build
2009-03-16 17:46:46 +00:00
, drvpath = > $ drvPathStep
2008-11-11 17:49:50 +00:00
, outpath = > $ 2
2010-08-31 15:27:46 +00:00
, system = > $ 3
2008-11-11 17:49:50 +00:00
, logfile = > $ 4
, busy = > 1
2008-11-12 11:09:21 +00:00
, starttime = > time
2008-11-11 17:49:50 +00:00
} ) ;
} ) ;
}
2010-08-31 14:08:59 +00:00
elsif ( /^@\s+build-remote\s+(\S+)\s+(\S+)$/ ) {
my $ drvPathStep = $ 1 ;
my $ machine = $ 2 ;
txn_do ( $ db , sub {
my $ step = $ build - > buildsteps - > find ( { stepnr = > $ buildSteps { $ drvPathStep } } ) or die ;
$ step - > update ( { machine = > $ machine } ) ;
} ) ;
}
2008-11-12 13:00:56 +00:00
elsif ( /^@\s+build-succeeded\s+(\S+)\s+(\S+)$/ ) {
2009-03-16 17:46:46 +00:00
my $ drvPathStep = $ 1 ;
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2009-03-16 17:46:46 +00:00
my $ step = $ build - > buildsteps - > find ( { stepnr = > $ buildSteps { $ drvPathStep } } ) or die ;
2009-03-10 08:52:42 +00:00
$ step - > update ( { busy = > 0 , status = > 0 , stoptime = > time } ) ;
2008-11-11 17:49:50 +00:00
} ) ;
}
2008-11-12 13:00:56 +00:00
elsif ( /^@\s+build-failed\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/ ) {
2008-11-25 00:38:16 +00:00
my $ drvPathStep = $ 1 ;
$ someBuildFailed = 1 ;
$ thisBuildFailed = 1 if $ drvPath eq $ drvPathStep ;
2009-03-26 12:53:39 +00:00
my $ errorMsg = $ 4 ;
$ errorMsg = "build failed previously (cached)" if $ 3 eq "cached" ;
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2009-03-16 16:56:47 +00:00
if ( $ buildSteps { $ drvPathStep } ) {
my $ step = $ build - > buildsteps - > find ( { stepnr = > $ buildSteps { $ drvPathStep } } ) or die ;
2009-03-26 12:53:39 +00:00
$ step - > update ( { busy = > 0 , status = > 1 , errormsg = > $ errorMsg , stoptime = > time } ) ;
2009-04-22 14:41:12 +00:00
}
# Don't write a record if this derivation already
# failed previously. This can happen if this is a
# restarted build.
elsif ( scalar $ build - > buildsteps - > search ( { drvpath = > $ drvPathStep , type = > 0 , busy = > 0 , status = > 1 } ) == 0 ) {
2009-03-12 14:18:30 +00:00
$ build - > buildsteps - > create (
2009-03-26 12:53:39 +00:00
{ stepnr = > ( $ buildSteps { $ drvPathStep } = $ buildStepNr + + )
2008-11-12 11:09:21 +00:00
, type = > 0 # = build
2008-11-25 00:38:16 +00:00
, drvpath = > $ drvPathStep
2008-11-12 11:09:21 +00:00
, outpath = > $ 2
2009-03-26 12:53:39 +00:00
, logfile = > getBuildLog ( $ drvPathStep )
2008-11-12 11:09:21 +00:00
, busy = > 0
, status = > 1
, starttime = > time
, stoptime = > time
2009-03-26 12:53:39 +00:00
, errormsg = > $ errorMsg
2008-11-12 11:09:21 +00:00
} ) ;
}
2008-11-11 17:49:50 +00:00
} ) ;
}
2008-11-12 13:00:56 +00:00
elsif ( /^@\s+substituter-started\s+(\S+)\s+(\S+)$/ ) {
my $ outPath = $ 1 ;
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2009-03-12 14:18:30 +00:00
$ build - > buildsteps - > create (
2009-03-16 16:56:47 +00:00
{ stepnr = > ( $ buildSteps { $ outPath } = $ buildStepNr + + )
2008-11-12 13:00:56 +00:00
, type = > 1 # = substitution
, outpath = > $ 1
, busy = > 1
, starttime = > time
} ) ;
} ) ;
}
elsif ( /^@\s+substituter-succeeded\s+(\S+)$/ ) {
my $ outPath = $ 1 ;
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2009-03-16 16:56:47 +00:00
my $ step = $ build - > buildsteps - > find ( { stepnr = > $ buildSteps { $ outPath } } ) or die ;
2009-03-09 16:22:41 +00:00
$ step - > update ( { busy = > 0 , status = > 0 , stoptime = > time } ) ;
2008-11-12 13:00:56 +00:00
} ) ;
}
elsif ( /^@\s+substituter-failed\s+(\S+)\s+(\S+)\s+(\S+)$/ ) {
my $ outPath = $ 1 ;
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2009-03-16 16:56:47 +00:00
my $ step = $ build - > buildsteps - > find ( { stepnr = > $ buildSteps { $ outPath } } ) or die ;
2009-03-09 16:22:41 +00:00
$ step - > update ( { busy = > 0 , status = > 1 , errormsg = > $ 3 , stoptime = > time } ) ;
2008-11-12 13:00:56 +00:00
} ) ;
}
else {
print STDERR "unknown Nix trace message: $_" ;
}
2008-11-11 17:49:50 +00:00
}
close OUT ;
my $ res = $? ;
2008-11-10 13:33:12 +00:00
$ stopTime = time ( ) ;
2008-11-25 00:38:16 +00:00
if ( $ res != 0 ) {
if ( $ thisBuildFailed ) { $ buildStatus = 1 ; }
elsif ( $ someBuildFailed ) { $ buildStatus = 2 ; }
else { $ buildStatus = 3 ; }
}
2008-11-10 13:33:12 +00:00
2008-11-25 00:38:16 +00:00
# Only store the output of running Nix if we have a miscellaneous error.
$ errormsg = undef unless $ buildStatus == 3 ;
2008-11-10 13:33:12 +00:00
}
2009-03-09 17:21:10 +00:00
done:
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2009-03-09 17:21:10 +00:00
$ build - > update ( { finished = > 1 , timestamp = > time } ) ;
2008-11-11 12:54:37 +00:00
2010-09-01 10:50:57 +00:00
my $ releaseName = getReleaseName ( $ outPath ) ;
2008-11-25 00:38:16 +00:00
2008-12-16 16:26:33 +00:00
$ db - > resultset ( 'BuildResultInfo' ) - > create (
2008-11-11 12:54:37 +00:00
{ id = > $ build - > id
2008-11-10 13:33:12 +00:00
, iscachedbuild = > $ isCachedBuild
, buildstatus = > $ buildStatus
, starttime = > $ startTime
, stoptime = > $ stopTime
2009-03-26 15:32:19 +00:00
, logfile = > getBuildLog ( $ drvPath )
2008-11-25 00:38:16 +00:00
, errormsg = > $ errormsg
2008-11-25 16:13:22 +00:00
, releasename = > $ releaseName
2008-11-10 13:33:12 +00:00
} ) ;
2008-11-25 00:38:16 +00:00
if ( $ buildStatus == 0 ) {
2010-09-07 11:29:52 +00:00
addBuildProducts ( $ db , $ build ) ;
2008-11-10 13:33:12 +00:00
}
2008-11-11 12:54:37 +00:00
$ build - > schedulingInfo - > delete ;
2008-11-10 13:33:12 +00:00
} ) ;
2009-07-07 16:15:38 +00:00
2009-07-08 15:52:55 +00:00
sendEmailNotification $ build ;
2009-10-15 13:23:15 +00:00
sendTwitterNotification $ build ;
2008-11-10 13:33:12 +00:00
}
2008-11-11 12:54:37 +00:00
my $ buildId = $ ARGV [ 0 ] or die ;
2008-11-11 17:49:50 +00:00
print STDERR "performing build $buildId\n" ;
2008-11-10 13:33:12 +00:00
2009-07-08 15:52:55 +00:00
if ( $ ENV { 'HYDRA_MAIL_TEST' } ) {
sendEmailNotification $ db - > resultset ( 'Builds' ) - > find ( $ buildId ) ;
exit 0 ;
}
2009-10-15 13:23:15 +00:00
if ( $ ENV { 'HYDRA_TWITTER_TEST' } ) {
sendTwitterNotification $ db - > resultset ( 'Builds' ) - > find ( $ buildId ) ;
exit 0 ;
}
2009-07-07 16:15:38 +00:00
2008-11-11 12:54:37 +00:00
# Lock the build. If necessary, steal the lock from the parent
# process (runner.pl). This is so that if the runner dies, the
# children (i.e. the build.pl instances) can continue to run and won't
# have the lock taken away.
my $ build ;
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2008-11-27 15:16:06 +00:00
$ build = $ db - > resultset ( 'Builds' ) - > find ( $ buildId ) ;
2008-11-11 12:54:37 +00:00
die "build $buildId doesn't exist" unless defined $ build ;
2009-03-06 13:34:53 +00:00
die "build $buildId already done" if defined $ build - > resultInfo ;
2008-11-11 12:54:37 +00:00
if ( $ build - > schedulingInfo - > busy != 0 && $ build - > schedulingInfo - > locker != getppid ) {
die "build $buildId is already being built" ;
2008-11-10 13:33:12 +00:00
}
2009-03-09 16:22:41 +00:00
$ build - > schedulingInfo - > update ( { busy = > 1 , locker = > $$ } ) ;
2009-03-16 16:56:47 +00:00
$ build - > buildsteps - > search ( { busy = > 1 } ) - > delete_all ;
2009-03-06 13:34:53 +00:00
$ build - > buildproducts - > delete_all ;
2008-11-10 13:33:12 +00:00
} ) ;
2008-11-11 12:54:37 +00:00
die unless $ build ;
2008-11-10 13:33:12 +00:00
2008-11-11 12:54:37 +00:00
# Do the build. If it throws an error, unlock the build so that it
# can be retried.
2008-11-10 13:33:12 +00:00
eval {
2008-11-11 12:54:37 +00:00
doBuild $ build ;
2008-11-12 14:29:32 +00:00
print "done\n" ;
2008-11-10 13:33:12 +00:00
} ;
if ( $@ ) {
warn $@ ;
2009-04-22 22:43:04 +00:00
txn_do ( $ db , sub {
2009-03-09 16:22:41 +00:00
$ build - > schedulingInfo - > update ( { busy = > 0 , locker = > $$ } ) ;
2008-11-10 13:33:12 +00:00
} ) ;
}