21
22
#######################################################################
24
($main::HOME = $ENV{'HOME'})
25
or die "HOME not defined in environment!\n";
27
use Buildd qw(open_log close_log lock_file unlock_file);
41
$Buildd::Conf::dupload_to ||= "anonymous-ftp-master";
42
$Buildd::Conf::dupload_to_security ||= "security";
46
END { unlock_file( "$main::HOME/daemon.log" ) if $log_locked;
47
unlock_file( "$main::HOME/buildd-uploader" ) if $locked; }
49
lock_file( "$main::HOME/daemon.log" );
54
if (lock_file( "$main::HOME/buildd-uploader", 1 ) == 0) {
55
logger( "exiting; another buildd-uploader is still running" );
62
upload( "upload-security", $Buildd::Conf::dupload_to_security );
63
upload( "upload", $Buildd::Conf::dupload_to );
65
foreach my $dist (keys %uploaded_pkgs) {
66
logger( "Set to Uploaded($dist):$uploaded_pkgs{$dist}" );
73
my @propagated_pkgs = ();
74
foreach my $dist (@_) {
76
if (open( PIPE, "$Buildd::Conf::sshcmd wanna-build --uploaded --user=$Buildd::Conf::wanna_build_user ".
77
($Buildd::Conf::wanna_build_dbbase?"--database=$Buildd::Conf::wanna_build_dbbase ":"").
78
"--no-down-propagation --dist=$dist ".
81
if (/^(\S+): Propagating new state /) {
82
push( @propagated_pkgs, $1 );
84
elsif (/^(\S+): already uploaded/ &&
85
Buildd::isin( $1, @propagated_pkgs )) {
94
lock_file( "$main::HOME/daemon.log" );
96
logger( $msgs ) if $msgs;
97
logger( "uploaded-build failed with status ", exitstatus($?), "\n" )
99
unlock_file( "$main::HOME/daemon.log" );
102
$uploaded_pkgs{$dist} .= " $pkg";
106
lock_file( "$main::HOME/daemon.log" );
108
logger( "Cannot spawn uploaded-build: $!\n" );
109
unlock_file( "$main::HOME/daemon.log" );
117
my $upload_to = shift;
119
chdir( "$main::HOME/$udir" ) || return;
120
lock_file( "$main::HOME/$udir" );
122
my( $f, $g, @before, @after );
123
foreach $f (<*.changes>) {
124
($g = $f) =~ s/\.changes$/\.upload/;
125
push( @before, $f ) if ! -f $g;
128
unlock_file( "$main::HOME/$udir" );
131
logger( "Nothing to do for $udir\n" );
135
logger( scalar(@before), " jobs to upload in $udir: @before\n" );
136
unlock_file( "$main::HOME/daemon.log" );
139
foreach $f (@before) {
140
($g = $f) =~ s/\.changes$/\.upload/;
141
my $logref = do_dupload( $upload_to, $f );
143
if (defined $logref and scalar(@$logref) > 0) {
146
lock_file( "$main::HOME/daemon.log" );
149
foreach $line (@$logref) {
152
unlock_file( "$main::HOME/daemon.log" );
157
if (!open( F, "<$f" )) {
158
logger( "Cannot open $f: $!\n" );
162
{ local($/); undef $/; $text = <F>; }
164
if ($text !~ /^Distribution:\s*(.*)\s*$/m) {
165
lock_file( "$main::HOME/daemon.log" );
167
logger( "$f doesn't have a Distribution: field\n" );
168
unlock_file( "$main::HOME/daemon.log" );
172
my @dists = split( /\s+/, $1 );
173
my ($version,$source,$pkg);
174
if ($text =~ /^Version:\s*(\S+)\s*$/m) {
177
if ($text =~ /^Source:\s*(\S+)(?:\s+\(\S+\))?\s*$/m) {
180
if (defined($version) and defined($source)) {
181
$pkg = "${source}_$version";
183
($pkg = $f) =~ s/_\S+\.changes$//;
185
uploaded($pkg,@dists);
191
lock_file( "$main::HOME/daemon.log" );
194
logger( "The following jobs were not processed (successfully):\n".
198
logger( "dupload successful.\n" );
200
write_stats( "uploads", scalar(@before) - scalar(@after) );
203
sub do_dupload ($@) {
204
my $upload_to = shift;
208
my( $current_job, $current_file, @failed, $errs );
210
if (!open( PIPE, "dupload -k --to $upload_to @jobs </dev/null 2>&1 |" )) {
211
return "Cannot spawn dupload: $!";
218
if (/^\[ job \S+ from (\S+\.changes)$/) {
221
elsif (/^warning: MD5sum mismatch for (\S+), skipping/i) {
223
push( @log, "dupload error: md5sum mismatch for $f\n" );
224
$errs .= "md5sum mismatch on file $f ($current_job)\n";
225
push( @failed, $current_job );
227
elsif (/^\[ Uploading job (\S+)$/) {
228
$current_job = "$1.changes";
230
elsif (/dupload fatal error: Can't upload (\S+)/i ||
231
/^\s(\S+).*scp: (.*)$/) {
232
my($f, $e) = ($1, $2);
233
push( @log, "dupload error: upload error for $f\n" );
234
push( @log, "($e)\n" ) if $e;
235
$errs .= "upload error on file $f ($current_job)\n";
236
push( @failed, $current_job );
238
elsif (/Timeout at [\S]+ line [\d]+$/) {
239
$errs .= "upload timeout on file $current_job\n";
240
push( @failed, $current_job );
242
elsif (/^\s(\S+)\s+[\d.]+ kB /) {
248
if (($? >> 8) == 141) {
249
push( @log, "dupload error: SIGPIPE (broken connection)\n" );
250
$errs .= "upload error (broken connection) during ".
251
"file $current_file ($current_job)\n";
252
push( @failed, $current_job );
255
push( @log, "dupload exit status ". exitstatus($?) );
256
$errs .= "dupload exit status ".exitstatus($?)."\n";
257
push( @failed, $current_job );
263
($u = $_) =~ s/\.changes$/\.upload/;
265
push( @log, "Removed $u due to upload errors.\n" );
266
$errs .= "Removed $u to reupload later.\n";
270
$errs .= "\nComplete output from dupload:\n\n$dup_log";
271
send_mail( $Buildd::Conf::admin_mail, "dupload errors", $errs );
30
use Sbuild::OptionsBase;
32
my $conf = Buildd::Conf->new();
33
exit 1 if !defined($conf);
34
my $options = Sbuild::OptionsBase->new($conf, "buildd-uploader", "1");
35
exit 1 if !defined($options);
36
my $uploader = Buildd::Uploader->new($conf);
37
exit 1 if !defined($uploader);
39
my $log = open_log($uploader->get('Config'));
40
$uploader->set('Log Stream', $log);
42
my $status = $uploader->run();
49
unlock_file($conf->get('HOME') . "/buildd-uploader")
52
defined($uploader->get('Uploader Lock')));