# wanna-build: coordination script for Debian buildds
# Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
# Copyright (C) 2005-2008 Ryan Murray <rmurray@debian.org>
+# Copyright (C) 2010 Andreas Barth <aba@not.so.argh.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
);
our $Pas = '/org/buildd.debian.org/etc/packages-arch-specific/Packages-arch-specific';
our $simulate = 0;
+our $api = 0; # allow buildds to specify an different api
# global vars
$ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin:/org/wanna-build/bin/";
my %options =
(# flags
simulate => { flag => \$simulate }, # this is not supported by all operations (yet)!
+ api => { arg => \$api, code => sub {
+ # official apis are numeric
+ die "$api isn't numeric" unless int($api) eq $api;
+ die "$api too large" unless $api <= 1;
+ } },
verbose => { short => "v", flag => \$verbose },
override => { short => "o", flag => \$opt_override },
"create-db" => { flag => \$opt_create_db },
/^merge-v3/ && do {
die "This operation is restricted to admin users\n"
if (defined @conf::admin_users and !isin( $real_user, @conf::admin_users) and !$simulate);
- # call with installed-packages+ . installed-sources+ [ . available-for-build-packages+ ]
+ # call with installed-packages+ . installed-sources+ [ . available-for-build-packages* [ . consider-as-installed-source* ] ]
# in case available-for-build-packages is not specified, installed-packages are used
lock_table() unless $simulate;
my $replacemap = { '%ARCH%' => $arch, '%SUITE%' => $distribution };
my @ipkgs = &parse_argv( \@ARGV, '.');
my @isrcs = &parse_argv( \@ARGV, '.');
my @bpkgs = &parse_argv( \@ARGV, '.');
+ my @psrcs = &parse_argv( \@ARGV, '.');
use WB::QD;
my $srcs = WB::QD::readsourcebins($arch, $Pas, \@isrcs, \@ipkgs);
- parse_all_v3($$srcs);
+ if (@psrcs) {
+ my $psrcs = WB::QD::readsourcebins($arch, $Pas, \@psrcs, []);
+ foreach my $k (keys %$$psrcs) {
+ next if $$srcs->{$k};
+ my $pkg = $$psrcs->{$k};
+ $pkg->{'status'} = 'related';
+ $$srcs->{$k} = $pkg;
+ }
+ }
+ parse_all_v3($$srcs, {'arch' => $arch, 'suite' => $distribution, 'time' => $curr_date});
@bpkgs = @ipkgs unless @bpkgs;
call_edos_depcheck( {'arch' => $arch, 'pkgs' => @bpkgs, 'srcs' => $$srcs, 'depwait' => 1 });
last SWITCH;
}
}
if ($ok) {
+ if ($api < 1) {
my $ok = 'ok';
if ($pkg->{'binary_nmu_version'}) {
print "$name: Warning: needs binary NMU $pkg->{'binary_nmu_version'}\n" .
if $pkg->{'previous_state'} =~ /^Failed/ ||
$pkg->{'state'} =~ /^Failed/;
}
+ print "$name: $ok\n" if $verbose;
+ } else {
+ print "- $name:\n";
+ print " - status: ok\n";
+ if ($pkg->{'binary_nmu_version'}) {
+ print " - binNMU:\n";
+ print " - version: $pkg->{'binary_nmu_version'}\n";
+ print " - changelog: $pkg->{'binary_nmu_changelog'}\n";
+ }
+ }
change_state( \$pkg, 'Building' );
$pkg->{'package'} = $name;
$pkg->{'version'} = $version;
$pkg->{'builder'} = $user;
log_ta( $pkg, "--take" );
update_source_info($pkg);
- print "$name: $ok\n" if $verbose;
}
else {
+ if ($api < 1) {
print "$name: NOT OK!\n $reason\n";
+ } else {
+ print "- $name:\n - status: not ok\n - reason: \"$reason\"\n";
+ }
}
}
"changed from $prevstate to $pkg->{'state'} ".
"by $real_user as $user";
+ if ($simulate) {
+ printf "update transactions: %s %s %s %s %s %s %s %s\n",
+ $pkg->{'package'}, $distribution,
+ $pkg->{'version'}, $action, $prevstate, $pkg->{'state'},
+ $real_user, $user;
+ return;
+ }
$dbh->do('INSERT INTO ' . transactions_table_name() .
' (package, distribution, version, action, ' .
' prevstate, state, real_user, set_user, time) ' .
}
if ($change) {
log_ta( $pkg, "--merge-all (edos)" ) unless $simulate;
- print "edos-builddebchange changed state of ${key}_$pkg->{'version'} to $pkg->{'state'}\n" if $verbose || $simulate;
+ print "edos-builddebchange changed state of ${key}_$pkg->{'version'} ($args->{'arch'}) to $pkg->{'state'}\n" if $verbose || $simulate;
}
if ($change || $problemchange) {
update_source_info($pkg) unless $simulate;
for my $key (keys %interesting_packages_depwait) {
if ($interesting_packages_depwait{$key}) {
- print "dependency on $key not fullfiled yet\n" if $verbose || $simulate;
+ print "dep-wait for $key ($args->{'arch'}) not fullfiled yet\n" if $verbose || $simulate;
next;
}
my $pkg = $db->{$key};
}
log_ta( $pkg, "edos_depcheck: depwait" ) unless $simulate;
update_source_info($pkg) unless $simulate;
- print "edos-builddebchange changed state of ${key}_$pkg->{'version'} to $pkg->{'state'}\n" if $verbose || $simulate;
+ print "edos-builddebchange changed state of ${key}_$pkg->{'version'} ($args->{'arch'}) from dep-wait to $pkg->{'state'}\n" if $verbose || $simulate;
}
}
sub get_source_info {
my $name = shift;
+ return get_readonly_source_info($name) if $simulate;
my $pkg = $dbh->selectrow_hashref('SELECT *, extract(days from date_trunc(\'days\', now() - state_change)) as state_days FROM ' .
table_name() . ' WHERE package = ? AND distribution = ?' .
' FOR UPDATE',
sub update_source_info {
my $pkg = shift;
+ return if $simulate;
my $pkg2 = get_source_info($pkg->{'package'});
if (! defined $pkg2)
}
sub add_source_info {
+ return if $simulate;
my $pkg = shift;
$dbh->do('INSERT INTO ' . table_name() .
' (package, distribution) values (?, ?)',
}
sub del_source_info {
+ return if $simulate;
my $name = shift;
$dbh->do('DELETE FROM ' . table_name() .
' WHERE package = ? AND distribution = ?',
}
sub update_user_info {
+ return if $simulate;
my $user = shift;
$dbh->do('UPDATE ' . user_table_name() .
' SET last_seen = now() WHERE username = ?' .
sub add_user_info {
+ return if $simulate;
my $user = shift;
$dbh->do('INSERT INTO ' . user_table_name() .
' (username, distribution, last_seen)' .
sub lock_table()
{
+ return if $simulate;
$dbh->do('LOCK TABLE ' . table_name() .
' IN EXCLUSIVE MODE', undef) or die $dbh->errstr;
}
sub parse_all_v3() {
my $srcs = shift;
+ my $vars = shift;
my $db = get_all_source_info();
my $binary = $srcs->{'_binary'};
SRCS:
foreach my $name (keys %$srcs) {
- next if $name eq '_binaries';
+ next if $name eq '_binary';
# state = installed, out-of-date, uncompiled, not-for-us
my $pkgs = $srcs->{$name};
unless ($pkg) {
next SRCS if $pkgs->{'status'} eq 'not-for-us';
+ my $logstr = "merge-v3 $vars->{'time'} ".$name."_$pkgs->{'version'} ($vars->{'arch'}, $vars->{'suite'}):";
# does at least one binary exist in the database and is more recent - if so, we're probably just outdated, ignore the source package
for my $bin (@{$pkgs->{'binary'}}) {
if ($binary->{$bin} and vercmp($pkgs->{'version'}, $binary->{$bin}) < 0) {
- print "merge-v3: skiping $name ($arch)\n" if $verbose || $simulate;
+ print "$logstr skipped because binaries (assumed to be) overwritten\n" if $verbose || $simulate;
next SRCS;
}
}
$pkg->{'package'} = $name;
}
+ my $logstr = "merge-v3 $vars->{'time'} ".$name."_$pkgs->{'version'} ($vars->{'arch'}, $vars->{'suite'}, previous: $pkg->{'version'}, $pkg->{'state'}):";
- if ($pkgs->{'status'} eq 'installed' && $pkg->{'binary_nmu_version'} && $pkgs->{'binnmu'} < $pkg->{'binary_nmu_version'}) {
+ if (isin($pkgs->{'status'}, qw (installed related)) && $pkg->{'binary_nmu_version'} && $pkgs->{'binnmu'} < $pkg->{'binary_nmu_version'}) {
$pkgs->{'status'} = 'out-of-date';
}
- if ($pkgs->{'status'} eq 'installed') {
+ if (isin($pkgs->{'status'}, qw (installed related))) {
+ my $change = 0;
if ($pkg->{'state'} ne 'Installed') {
change_state( \$pkg, 'Installed');
- $pkg->{'version'} = $pkgs->{'version'};
- $pkg->{'installed_version'} = $pkgs->{'version'};
- $pkg->{'binary_nmu_version'} = $pkgs->{'binnmu'};
- $pkg->{'section'} = $pkgs->{'section'};
- $pkg->{'priority'} = $pkgs->{'priority'};
- print "merge-v3: set $name ($arch) to installed\n" if $verbose || $simulate;
+ delete $pkg->{'depends'};
+ $change++;
+ }
+ my $attrs = { 'version' => 'version', 'installed_version' => 'version', 'binary_nmu_version' => 'binnmu', 'section' => 'section', 'priority' => 'priority' };
+ foreach my $k (keys %$attrs) {
+ if ($pkg->{$k} ne $pkgs->{$attrs->{$k}}) {
+ $pkg->{$k} = $pkgs->{$attrs->{$k}};
+ $change++;
+ }
+ }
+ if (isin($pkgs->{'status'}, qw (related))) {
+ $pkg->{'notes'} = "related";
+ $change++;
+ }
+ if ($change) {
+ print "$logstr set to installed/".$pkg->{'notes'}."\n" if $verbose || $simulate;
log_ta( $pkg, "--merge-v3: installed" ) unless $simulate;
update_source_info($pkg) unless $simulate;
}
change_state( \$pkg, "Failed-Removed" );
log_ta( $pkg, "--merge-v3: Failed-Removed" ) unless $simulate;
update_source_info($pkg) unless $simulate;
- print "$name ($pkg->{'version'}): (virtually) deleted from database\n" if $verbose || $simulate;
+ print "$logstr (virtually) deleted from database\n" if $verbose || $simulate;
next;
}
- print "should delete $name (not-for-us)\n" if $verbose || $simulate || 1; # not implemented yet on purpose
+ print "$logstr should delete (not-for-us according to P-a-s)\n" if $verbose || $simulate || 1; # not implemented yet on purpose
next;
}
# only uncompiled / out-of-date are left, so check if anything new
+ if (!(isin($pkgs->{'status'}, qw (uncompiled out-of-date)))) {
+ print "$logstr package in unknown state: $pkgs->{'status'}\n";
+ next SRCS;
+ }
next if $pkgs->{'version'} eq $pkg->{'version'};
- print "should set $name to needs-builds\n" if $simulate;
if (defined( $pkg->{'state'} ) && isin( $pkg->{'state'}, qw(Building Built Build-Attempted))) {
send_mail( $pkg->{'builder'},
"new version of $name (dist=$distribution)",
"compiling $name yet, you can stop it to save some work.\n".
"Just to inform you...\n".
"(This is an automated message)\n" ) unless $simulate;
- print "$name: new version ($pkgs->{'version'}) while building $pkg->{'version'} -- sending mail to builder ($pkg->{'builder'})\n"
+ print "$logstr new version while building $pkg->{'version'} -- sending mail to builder ($pkg->{'builder'})\n"
if $verbose || $simulate;
}
change_state( \$pkg, 'Needs-Build');
delete $pkg->{'binary_nmu_changelog'};
log_ta( $pkg, "--merge-v3: needs-build" ) unless $simulate;
update_source_info($pkg) unless $simulate;
- print "$name ($pkgs->{'version'} / $arch) needs rebuilding now.\n" if $verbose || $simulate;
+ print "$logstr set to needs-builds\n" if $simulate || $verbose;
}
foreach my $name (keys %$db) {
next if $srcs->{$name};
my $pkg = $db->{$name};
+ my $logstr = "merge-v3 $vars->{'time'} ".$name."_$pkg->{'version'} ($vars->{'arch'}, $vars->{'suite'}, previous: $pkg->{'state'}):";
# package disappeared - delete
change_state( \$pkg, 'deleted' );
log_ta( $pkg, "--merge-v3: deleted" ) unless $simulate;
- print "$name ($pkg->{'version'} / $arch) deleted from database\n" if $verbose || $simulate;
+ print "$logstr deleted from database\n" if $verbose || $simulate;
del_source_info($name) unless $simulate;
delete $db->{$name};
}