source: soft/build_system/build_system/iurt/trunk/ulri @ 1

Last change on this file since 1 was 1, checked in by fasma, 12 years ago

Initial Import from Mandriva's soft revision 224062 and package revision 45733

File size: 21.5 KB
Line 
1#!/usr/bin/perl
2#
3# Copyright (C) 2005,2006 Mandriva
4#
5# Author: Florent Villard <warly@mandriva.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2, or (at your option)
10# any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20#
21# compare and rebuild packages on different architecture
22#
23# TODO
24#
25# - create a configuration file to handle the various iurt running
26# - get the content of the rebuild dir
27# - run as many iurt as machines are available and gather results
28# - the scheduler just take the results, launch new rebuild, and quit
29# - use perl ssh and try to workarround the non working timeout when the
30#   remote machine is stalled
31# - use submitter as packager, not generic name
32#
33
34use strict;
35use MDK::Common;
36use Iurt::Config qw(config_usage get_date config_init dump_cache init_cache get_author_email check_arch check_noarch);
37use Iurt::Process qw(check_pid);
38use Iurt::File qw(check_upload_tree);
39use Iurt::Mail qw(sendmail);
40use Iurt::Util qw(plog_init plog ssh_setup ssh sout sget sput);
41use File::Copy 'move';
42use File::Path 'mkpath';
43use File::Temp 'mktemp';
44use Filesys::Df qw(df);
45use Data::Dumper;
46
47my %run;
48my $program_name = 'ulri';
49$run{program_name} = $program_name;
50
51open(my $LOG, ">&STDERR");
52$run{LOG} = sub { print $LOG @_ };
53
54plog_init($program_name, $LOG, 7, 1);
55
56my $HOME = $ENV{HOME};
57my $configfile = "$HOME/.upload.conf";
58
59my $config;
60if (-f $configfile) {
61    $config = eval(cat_($configfile)) or die "FATAL $program_name: syntax error in $configfile";
62} else {
63    $config = {};
64}
65
66my %config_usage = ( 
67    admin => {
68        desc => 'mail address of the bot administrator',
69        default => 'distrib-admin@mandrivalinux.org'
70    },
71    'arch_translation' => { 
72        desc => "Renaming of arch",
73        default => { 'sparc64' => 'sparcv9' }
74    },
75     bot => { 
76        desc => "List of bot able to compile the packages",
77        default => { 
78            i586 => { 
79                n1 => { 
80                    iurt => {
81                        user => 'mandrake' ,
82                        command => 'sudo -u mandrake -H /usr/local/bin/iurt2.sh --copy_srpm --group -v 1 --config local_spool /export/home/mandrake/iurt/__DIR__ --no_rsync --chrooted-urpmi http://kenobi/dis/ -r __TARGET__ __ARCH__',
83                        packages => '/export/home/mandrake/iurt/',
84                        log => '/export/home/mandrake/iurt/', 
85                    } ,
86                },
87            },
88        },
89    },
90    media => { 
91        desc => 'Corresponding media to add given the current media',
92        default => {
93            default => { 
94                "main/release" => [ "main/release", "main/updates" ], 
95                "main/updates" => [ "main/release", "main/updates" ],
96                "main/testing" => [ "main/release", "main/updates",
97                        "main/testing" ],
98                "main/backports" => [ "main/release", "main/updates",
99                        "main/testing", "main/backports" ],
100                "contrib/release" => [ "main/release", "main/updates",
101                        "contrib/release", "contrib/updates" ],
102                "contrib/updates" => [ "main/release", "main/updates",
103                        "contrib/release", "contrib/updates" ],
104                "contrib/testing" => [ "main/release", "main/updates",
105                        "main/testing", "contrib/release", "contrib/updates",
106                        "contrib/testing" ],
107                "contrib/backports" => [ "main/release", "main/updates",
108                        "main/testing", "main/backports", "contrib/release",
109                        "contrib/updates", "contrib/testing",
110                        "contrib/backports" ],
111                "non-free/release" => [ "main/release", "main/updates",
112                        "non-free/release", "non-free/updates" ],
113                "non-free/updates" => [ "main/release", "main/updates",
114                        "non-free/release", "non-free/updates" ],
115                "non-free/testing" => [ "main/release", "main/updates",
116                        "main/tessting", "non-free/release",
117                        "non-free/updates", "non-free/testing" ],
118                "non-free/backports" => [ "main/release", "main/updates",
119                        "main/testing", "main/backports", "non-free/release",
120                        "non-free/updates", "non-free/testing",
121                        "non-free/backports" ],
122            },
123        },
124    },
125    faildelay => {
126        desc => "Time after which the rebuild is considered as a failure",
127        default => 36000
128    },
129    http_queue => {
130        desc => 'Address where log can be consulted',
131        default => 'http://kenobi.mandriva.com/queue/'
132    },
133    queue => {
134        desc => "Root of the tree where the packages to compile are located",
135        default => "/home/mandrake/uploads/"
136    },
137    cache_home => {
138        desc => 'Where to store the cache files',
139        default => "$HOME/.bugs"
140    },
141    tmp => {
142       desc => "Temporary directory",
143       default => "$HOME/tmp/"
144    },
145    ssh_options => {
146        desc => "SSH options",
147        default => "-o ConnectTimeout=20 -o BatchMode=yes"
148    },
149    packager => {
150        desc => 'Default packager tag user by bot',
151        default => 'Mandriva Team <http://www.mandrivaexpert.com>'
152    },
153);
154config_usage(\%config_usage, $config) if $run{config_usage};
155config_init(\%config_usage, $config, \%run);
156
157my %untranslated_arch;
158foreach my $k (keys %{$config->{arch_translation}}) {
159    my $v = $config->{arch_translation}{$k};
160    push @{$untranslated_arch{$v}}, $k;
161}
162
163$run{pidfile_home} = $config->{tmp};
164$run{pidfile} = "upload";
165my $pidfile = check_pid(\%run);
166
167#my $cache = init_cache(\%run, $config, { done => {} });
168my $cache = { done => {} };
169
170my ($fulldate, $daydate) = get_date();
171$run{daydate} = $daydate;
172
173my $df = df $config->{queue};
174if ($df->{per} == 100) {
175    # FIXME should send a mail too
176    die "FATAL $program_name: not enough space on the filesystem, only $df->{bavail} KB on $config->{queue}, full at $df->{per}%";
177}
178
179($fulldate, $daydate) = get_date();
180
181my %pkg_tree;
182my $compildone = $cache->{done};
183
184my $todo = "$config->{queue}/todo/";
185my $failure = "$config->{queue}/failure/";
186my $done = "$config->{queue}/done/";
187
188# Raise this when the noarch package starts to build on any bot
189my %noarch_build;
190
191#
192# Part 0: gather data from upload tree
193#
194
195plog('MSG', "check uploads tree");
196
197# A list of what is currently building so we can report at the end
198#
199my %build_list;
200
201plog('DEBUG', "input queue is $todo");
202
203sub todo_func {
204    my ($todo, $f, $m, $s, $r) = @_;
205
206    if ($r =~ /(\d{14}\.(\w+)\.\w+\.\d+)_(.*\.src\.rpm)$/) {
207        my ($prefix, $user, $srpm) = ($1, $2, $3);
208
209        plog('DEBUG', "found srpm $srpm ($prefix)");
210        $pkg_tree{$prefix}{path} = "/$f/$m/$s";
211        $pkg_tree{$prefix}{media} = "$m/$s";
212        $pkg_tree{$prefix}{target} = $f;
213        $pkg_tree{$prefix}{user} = $user;
214        push @{$pkg_tree{$prefix}{srpms}} , $srpm;
215        my ($name) = $srpm =~ /(.*)-[^-]+-[^-]+\.src\.rpm$/;
216
217        return $pkg_tree{$prefix}{srpm_name}{$name} = $srpm;
218    }
219
220    if ($r =~ /(\d{14}\.\w+\.\w+\.\d+)_([\w-]+)\.(\w+)\.(\w+)\.(\d{14})\.(\d+)\.lock$/) {
221        my ($prefix, $arch, $bot, $host, $date, $pid) = ($1, $2, $3, $4, $5, $6);
222
223        $arch = $config->{arch_translation}{$arch} if $config->{arch_translation}{$arch};
224        plog('DEBUG', "found lock on $host/$arch for $prefix");
225
226        # Only for build status reporting
227        #
228        push @{$build_list{"$host/$arch"}}, $prefix;
229
230        if ($arch =~ /noarch/) {
231            plog('DEBUG', "... and $prefix is noarch");
232            $noarch_build{$prefix} = 1;
233            $arch =~ s/-.*//;
234        }
235
236        $run{bot}{$arch}{$host}{$bot} = $prefix;
237
238        # this should be in the cache, but waiting for a cache-clean option
239        $compildone->{$prefix}{$arch} = 1;
240
241        my $time = read_line("$todo/$f/$m/$s/$r");
242        $time = (split ' ', $time)[2];
243        push @{$pkg_tree{$prefix}{bot}}, {
244            bot => $bot,
245            host => $host,
246            date => $date,
247            pid => $pid,
248            'arch' => $arch,
249            'time' => $time
250        };
251    }
252}
253
254sub todo_post {
255    my ($todo, $f, $m, $s, $r) = @_;
256
257    if ($r =~ /([^_]*)_(.*).lock$/) {
258        if (!$pkg_tree{$1}{srpms}) {
259            plog('INFO', "cleaning orphan $r");
260            unlink "$todo/$f/$m/$s/$r";
261        }
262    }
263}
264
265sub done_func {
266    my ($_todo, $_f, $_m, $_s, $r) = @_;
267
268    if ($r =~ /(\d{14}\.\w+\.\w+\.\d+)_(.*)\.(done|fail|excluded)$/) {
269        my ($prefix, $arch) = ($1, $2);
270        $arch = $config->{arch_translation}{$arch} if $config->{arch_translation}{$arch};
271        $compildone->{$prefix}{$arch} = 1;
272    } elsif ($r =~ /(\d{14}\.\w+\.\w+\.\d+)_(.*\.([^.]+)\.rpm)$/) {
273        my ($prefix, $rpm) = ($1, $2);
274        plog('DEBUG', "found already built rpm $rpm ($prefix)");
275        push @{$pkg_tree{$prefix}{rpms}} , $rpm;
276    }
277}
278
279
280check_upload_tree(\%run, $todo, \&todo_func, \&todo_post);
281
282# getting already compiled packages
283# The cache should not be needed if the .done file are removed as the same
284# time as the src.rpm in the todo tree
285check_upload_tree(\%run, $done, \&done_func,);
286
287
288#
289# Part 1: get results from finished builds
290#
291
292plog('MSG', "check build bot results");
293
294my %later;
295foreach my $prefix (keys %pkg_tree) {
296    my $ent = $pkg_tree{$prefix};
297    my $path = $ent->{path};
298    my $user = $ent->{user};
299
300    # Local pathnames
301    my $done_dir = "$done/$path";
302    my $todo_dir = "$todo/$path";
303    my $fail_dir = "$failure/$path";
304
305    bot: foreach my $bot_list (@{$ent->{bot}}) {
306        my ($bot, $host, $date, $pid, $arch, $time) =
307                        @$bot_list{qw(bot host date pid arch time)};
308
309        my $bot_conf = $config->{bot}{$arch}{$host}{$bot};
310        my $remote = ssh_setup($config->{ssh_options},
311                                        $bot_conf->{user}, $host);
312
313        # If our build is noarch, set arch appropriately.
314        #
315        my $lock_file =
316            "$todo_dir/${prefix}_$arch-noarch.$bot.$host.$date.$pid.lock";
317
318        if (-f $lock_file) {
319            plog('DEBUG', "$prefix is noarch");
320            $arch = "noarch";
321        } else {
322            $lock_file =~ s/-noarch//;
323        }
324
325        my $prefix_dir = "$bot_conf->{packages}/$path/$prefix/";
326        my $status_file = "$prefix_dir/log/status.log";
327
328        plog('INFO', "check status: $host/$arch ($bot [$pid])");
329        my $status = sout($remote, "cat $status_file");
330        my $success;
331        my $fail;
332        my $later;
333
334        # Check if the build bot finished on the other side
335        #
336        if ($status) {
337            plog('INFO', "check result: $host/$arch ($bot [$pid])");
338            foreach my $res (split "\n", $status) {
339                my ($p, $r) = $res =~ /(.*):\s+(.*)/;
340                plog('DEBUG', $res);
341                if ($r eq 'install_deps_failure') {
342                    plog('FAIL', "install deps failure, rebuild later: $p");
343                    $later{$prefix} = 1;
344                    $later = 1;
345                }
346                if ($r ne 'ok') {
347                    plog('FAIL', "$r: $p");
348                    $fail = 1;
349                }
350            }
351
352            if (!$fail) {
353                my @list = split "\n", sout($remote, "ls $prefix_dir");
354                my $error;
355
356                my $arch_check = join '|', $arch, if_($untranslated_arch{$arch}, @{$untranslated_arch{$arch}});
357                plog('MSG', "checking for $arch_check arch");
358                foreach my $result (@list) {
359                    $result =~ /\.(src|$arch_check|noarch)\.rpm$/ or next;
360
361                    # do not copy the initial src package
362                    $result =~ /^$prefix/ and next;
363
364                    my $result_file = "$done_dir/${prefix}_$result";
365                    my $done_file = "$done_dir/${prefix}_$arch.done";
366
367                    plog('OK', "build ok: $result");
368                    $compildone->{$prefix}{$arch} = 1;
369
370                    plog('DEBUG', "copy files to done");
371                    mkpath($done_dir);
372                    if (sget($remote, "$prefix_dir/$result",
373                                 "$result_file.new")) {
374                        plog('ERR', "copying $result from $host failed ($!)");
375                        $error = 1;
376                        last;
377                    } elsif (move("$result_file.new", $result_file)) {
378                        create_file($done_file, "$bot $host");
379                        $success = 1;
380                    }
381                }
382                next if $error;
383
384                # Do nothing if the scp failed, wait for the other run
385                # (it may be a disk full problem)
386                # next if $error;
387                #if ($success) {
388                # The SRPM should be recreated thus no need to copy it
389                # foreach my $srpm (@{$ent->{srpms}}) {
390                #     plog("linking $todo_dir/${prefix}_$srpm to $done_dir/${prefix}_$srpm");
391                #     link "$todo_dir/${prefix}_$srpm", "$done_dir/${prefix}_$srpm"
392                #       }
393                # FIXME Have to remove remote remaining packages and directory
394                #}
395            }
396        } # if ($status)
397
398        #
399        # Handle build failure
400        #
401
402        my $proc_state;
403        if (!$fail) {
404            chomp($proc_state = sout($remote, "ps h -o state $pid"));
405        }
406
407        my $seconds = time()-$time;
408
409        # Reasons for failure
410        my $timeout = $seconds > $config->{faildelay};
411        my $zombie = $proc_state eq 'Z';
412        my $ended = !$proc_state;
413
414        unless ($success || $later || $fail || $timeout || $zombie || $ended) {
415            next bot;
416        }
417
418        plog('INFO', "delete lock file for $prefix");
419        unlink $lock_file;
420
421        $run{bot}{$arch}{$host}{$bot} = 0;
422
423        if ($later) {
424            next bot;
425        }
426
427        if (!$ended && !$fail) {
428            plog('FAIL', "$bot timed out on $host/$arch ($seconds sec) or " .
429                        "it's dead (status $proc_state), removing lock");
430            $compildone->{$prefix}{$arch} = 0;
431            next bot;
432        }
433
434        if ($success && !$fail) {
435            next bot;
436        }
437
438        if (!$status) {
439            plog('ERR', "build bot died on $host, reschedule compilation");
440            next bot;
441        }
442
443        plog('FAIL', "build failed");
444        create_file("$done_dir/${prefix}_$arch.fail", "$bot $host");
445        mkpath($fail_dir);
446
447        if (sget($remote, "$prefix_dir/", "$fail_dir/")) {
448            plog('ERR', "copying from $host:$prefix_dir/ " .
449                                        "to $fail_dir/ failed ($!)");
450            $compildone->{$prefix}{$arch} = 0;
451            # clean the log on the compilation machine
452            ssh($remote, "rm -rf $prefix_dir");
453            next bot;
454        }
455
456        # What to do with the previously build packages? Move them to
457        # failure, rejected ?
458        # 20061220 warly move them to failure for now
459
460        foreach my $rpm (@{$ent->{rpms}}) {
461            my $file = "$done_dir/${prefix}_$rpm";
462            plog('DEBUG', "moving built rpm $file to $fail_dir/${prefix}_$rpm");
463            link $file, "$fail_dir/${prefix}_$rpm";
464            unlink $file;
465        }
466        # Should clean the queue
467        # Must remove the SRPM and the lock
468        foreach my $srpm (@{$ent->{srpms}}) {                               
469            my $file = "$todo_dir/${prefix}_$srpm";
470            plog('DEBUG', "moving $file to $fail_dir/${prefix}_$srpm");
471            link $file, "$fail_dir/${prefix}_$srpm";
472            delete $pkg_tree{$prefix};
473            unlink $file;
474        }
475       
476        # Notify user if build failed
477        #
478        if ($user) {
479            my $text = "Build of the following packages failed:\n\n";
480            my $srpms = "";
481            foreach my $srpm (@{$ent->{srpms}}) {
482                $srpms .= "$srpm ";
483                $text .= "- $srpm\n";
484            }
485
486            my $to = get_author_email($user) || "Unknown <$config->{admin}>";
487            my $cc = undef;
488            my $fpath = "$config->{http_queue}/failure/$path/$prefix";
489            $fpath =~ tr!/!!s;  # Squash double slashes ...
490            $fpath =~ s!/!//!;  # ... except for http://
491
492            $text .= "\nFailure details available in $fpath\n";
493            sendmail($to, $cc,
494                        "Rebuild failed on $arch for $srpms", $text,
495                        "Ulri the scheduler bot <$config->{admin}>", 0);
496        }
497
498        # clean the log on the compilation machine
499        ssh($remote, "rm -rf $prefix_dir");
500
501    } # end bot
502} # end prefix
503
504
505#
506# Part 2: check queue and start new jobs if a bot is available
507#
508
509plog('MSG', "launching new compilations");
510my %to_compile;
511
512# do not sort the keys to be able to ignore packages which makes iurt
513# crash or just lock ulri somehow
514
515foreach my $prefix (sort keys %pkg_tree) {
516    next if $later{$prefix};
517    my $ent = $pkg_tree{$prefix};
518    my $path = $ent->{path};
519    my $media = $ent->{media};
520    my $target = $ent->{target};
521    my $srpms = $ent->{srpms} or next;
522    my $user = $ent->{user};
523    if ($user) {
524        $user = get_author_email($user) || $config->{packager};
525    } else {
526        $user = $config->{packager}
527    }
528    $user =~ s/([<>])/\\$1/g;
529
530    # Local pathnames
531    my $done_dir = "$done/$path";
532    my $todo_dir = "$todo/$path";
533
534    # Make sure these exist
535    mkpath($done_dir);
536    mkpath($todo_dir);
537
538    #plog('DEBUG', "searching a bot to compile @$srpms");
539
540    # count noarch todos only once even if searching multiple bots
541    my $noarch_countflag = 0;
542
543    # need to find a bot for each arch
544    foreach my $arch (keys %{$config->{bot}}) {
545        my $exclude;
546        my $noarch;
547
548        # Skip this arch if package is building as noarch
549        #
550        next if $noarch_build{$prefix};
551
552        next if $compildone->{$prefix}{noarch};
553        next if $compildone->{$prefix}{$arch};
554
555        # If all packages in a group are noarch, consider the entire group
556        # as noarch
557        #
558        $noarch = 1;
559        foreach my $srpm (@$srpms) {
560            if (!check_noarch("$todo_dir/${prefix}_$srpm")) {
561                $noarch = 0;
562                last;
563            }
564        }
565
566        #plog("@$srpms is noarch") if $noarch;
567
568        foreach my $srpm (@$srpms) {
569            if (!check_arch("$todo_dir/${prefix}_$srpm", $arch)) {
570                plog('WARN', "excluding from $arch: $srpm");
571                $exclude = 1;
572                last;
573            }
574        }
575
576        if ($exclude) {
577            create_file("$done_dir/${prefix}_$arch.excluded",
578                                        "ulri $arch excluded");
579            next;
580        }
581
582        if ($noarch) {
583            plog('DEBUG', "search any bot for @$srpms") unless $noarch_countflag;
584        } else {
585            plog('DEBUG', "search $arch bot for @$srpms");
586        }
587
588        foreach my $host (keys %{$config->{bot}{$arch}}) {
589            foreach my $bot (keys %{$config->{bot}{$arch}{$host}}) {
590                next if $run{bot}{$arch}{$host}{$bot};
591
592                # Enable noarch lock after the first bot snarfs the package
593                #
594                $noarch_build{$prefix} = 1 if $noarch;
595
596                plog('INFO', "building on $host/$arch ($bot)");
597
598                $run{bot}{$arch}{$host}{$bot} = $prefix;
599                $compildone->{$prefix}{$arch} = 1;
600
601                my $bot_conf = $config->{bot}{$arch}{$host}{$bot};
602                my $remote = ssh_setup($config->{ssh_options},
603                                        $bot_conf->{user}, $host);
604
605                my $prefix_dir = "$bot_conf->{packages}/$path/$prefix/";
606                my $status_file = "$prefix_dir/log/status.log";
607
608                # Copy packages to build node
609                #
610                next if ssh($remote, "mkdir -p $prefix_dir");
611                my $pkgs = "";
612                my $ok = 1;
613                foreach my $srpm (@$srpms) {
614                    plog('NOTIFY', "Send to $host/$arch: $srpm");
615                    $ok &&= !sput($remote, "$todo_dir/${prefix}_$srpm",
616                                        "$prefix_dir/$srpm");
617                    $pkgs .= " $prefix_dir/$srpm";
618                }
619                next unless $ok;
620
621                # spawn remote build bot and save output on local file
622                # (remove status.log before building, otherwise we can have
623                # a install_deps_failure and reschedule even if the package
624                # is currently building)
625                #
626                plog('DEBUG', "remove status file");
627                ssh($remote, "rm $status_file 2>/dev/null");
628
629                plog('INFO', "Execute build command on $host/$arch");
630
631                my $temp = mktemp("$config->{tmp}/ulri.tmp.$prefix.XXXXX");
632                my $cmd = $bot_conf->{command};
633                $cmd =~ s!__ARCH__!$arch!g;
634                $cmd =~ s!__DIR__!$path/$prefix!g;
635                $cmd =~ s!__TARGET__!$target!g;
636                $cmd =~ s!__PACKAGER__!$user!g;
637
638                my $media_to_add;
639                if (ref $config->{media}{$target}{$media}) {
640                    $media_to_add = join ' ', @{$config->{media}{$target}{$media}};
641                } elsif (ref $config->{media}{default}{$media}) { 
642                    $media_to_add = join ' ', @{$config->{media}{default}{$media}};
643                }
644                plog('DEBUG', "Will compile only with media $media_to_add");
645                $cmd =~ s!__MEDIA__!$media_to_add!g;
646
647                plog('DEBUG', "Build $pkgs");
648                ssh($remote, "$cmd $pkgs > $temp &");
649
650                # wait 10 seconds or until we have the log file
651                # plus 20 seconds if it timeouts.
652                #
653                if (check_file_timeout($temp, 10)) {
654                    plog('WARN', "Timeout waiting for building start. Waiting more 20s.");
655                    if (check_file_timeout($temp, 20)) {
656                        plog('WARN', "Timeout! Abandoning the build.");
657                        last;
658                    }
659                }
660
661                # get remote PID from log file
662                #
663                my $pid = get_pid_from_file($temp);
664                unlink $temp;
665                plog('DEBUG', "remote pid $pid");
666                if (!$pid) {
667                    plog('WARN', "pid is unknown, abandoning the build.");
668                    last;
669                }
670
671                # create lock file
672                #
673                my $lock_arch = $noarch ? "$arch-noarch" : $arch;
674                my $lock_file = "$todo_dir/${prefix}_" .
675                                "$lock_arch.$bot.$host.$fulldate.$pid.lock";
676                plog('DEBUG', "create lock $lock_file");
677                create_file($lock_file, "$program_name $$", time());
678
679                last;
680            }
681            last if $compildone->{$prefix}{$arch}; 
682            last if $compildone->{$prefix}{noarch}; 
683        }
684
685        # Count packages to compile for each architecture. Count noarch
686        # package only once.
687        #
688        $arch = 'noarch' if $noarch;
689        unless ($compildone->{$prefix}{$arch}) { 
690            $to_compile{$arch}++ if !($noarch && $noarch_countflag);
691        }
692        $noarch_countflag = 1 if $noarch;
693    }
694}
695
696plog('MSG', "Current status");
697
698if (keys %build_list) {
699    plog('INFO', "currently building:");
700    map { plog('INFO', "  $_: " . join('', @{$build_list{$_}})) } keys %build_list;
701}
702
703plog('INFO', "jobs in queue:", %to_compile ?
704    map { sprintf("%s(%d)", $_, $to_compile{$_}) } keys %to_compile : "none");
705
706
707#dump_cache(\%run);
708unlink $pidfile;
709exit();
710
711
712#
713# Subroutines
714#
715
716sub get_pid_from_file {
717    my $file = shift;
718
719    my $pid;
720    open my $FILE, $file || die "FATAL: can't open $file";
721    local $_;
722    while (<$FILE>) { ($pid) = /PID=(\d+)/ }
723
724    $pid;
725}
726
727sub create_file {
728    my $file = shift;
729    my @contents = @_;
730       
731    open my $FILE, ">$file" or die "FATAL: can't open $file for writing";
732    print $FILE "@contents";
733}
734
735sub read_line {
736    my $file = shift;
737
738    open my $FILE, "<$file" or die "FATAL: can't open $file for reading";
739    my $contents = <$FILE>;
740
741    $contents;
742}
743
744sub check_file_timeout {
745    my $file = shift;
746    my $time = shift;
747
748    my $i = 0;
749    while ($i < $time && (!-f $file || -z $file)) { sleep 1; $i++ }
750
751    $i == $time;
752}
753
754__END__
755
756# ulri ends here
757
758Discussion
759----------
760 
76120060802 (Warly)
762
763* I prefer creating a separate scheduler, so that it can eventually call
764  other bots.
765* bots should be able to take packages by themselves.
766* Iurt will perform several checks, they have to be standard and usable
767  by the maintainer, the results must be put in a visible directory or path
768* We can put packages either in a dir or to prefix all files with the date
769  and uploader. Having all files in a dir will make the listing simpler.
770  Prefixing the files could be problematic if we base the rpm name and
771  version parsing on the filename.
772* ulri knows the prefix, he could ask iurt to put the packages in a dir
773  with the same prefix.
774
77520060806 (Warly)
776
777* All the packages are put in done, then the final youri is run to put them
778  in queue/
779
78020061104 (claudio)
781
782* Instead if having configuration defaults for our environment and using
783  ulri with the defaults, it would be nicer to have minimalistic/generic
784  defaults and install a configuration file in kenobi
785* Ulri's configuration file could be renamed to .ulri.conf instead of
786  .upload.conf.   ==> ok, it's also used by emi
787
Note: See TracBrowser for help on using the repository browser.