source: soft/build_system/build_system/iurt/trunk/lib/Iurt/Urpmi.pm @ 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: 25.1 KB
Line 
1package Iurt::Urpmi;
2
3use strict;
4use RPM4::Header;
5use File::Basename;
6use File::NCopy qw(copy);
7use MDV::Distribconf::Build;
8use Iurt::Chroot qw(add_local_user create_temp_chroot check_build_chroot);
9use Iurt::Process qw(perform_command clean clean_process sudo);
10use Iurt::Config qw(dump_cache_par get_maint get_package_prefix);
11use Iurt::Util qw(plog);
12
13
14sub new {
15    my ($class, %opt) = @_;
16    my $self = bless {
17        config  => $opt{config},
18        run => $opt{run},
19        urpmi_options => $opt{urpmi_options},
20    }, $class;
21    my $config = $self->{config};
22    my $run = $self->{run};
23
24    if ($run->{use_system_distrib}) {
25        $config->{basesystem_media_root} ||= $run->{use_system_distrib};
26    } elsif ($run->{chrooted_urpmi}) {
27        my ($host) = $run->{chrooted_urpmi}{rooted_media} =~ m,(?:file|http|ftp)://([^/]*),;
28        my ($_name, $_aliases, $_addrtype, $_length, @addrs) = gethostbyname($host);
29
30        my $ip = join('.', unpack('C4', $addrs[0]));
31
32        $ip =~ /\d+\.\d+\.\d+\.\d+/
33                or die "FATAL: could not resolve $host ip address";
34
35        $run->{chrooted_urpmi}{rooted_media} =~ s/$host/$ip/;
36        $run->{chrooted_media} = $run->{chrooted_urpmi}{rooted_media} .
37                        "/$run->{distro}/$run->{my_arch}";
38
39        # Now squash all slashes that don't follow colon
40        $run->{chrooted_media} =~ s|(?<!:)/+|/|g;
41
42        plog('DEBUG', "installation media: $run->{chrooted_media}");
43    }
44    $self->{urpmi_media_options} .=
45        " --use-distrib $config->{repository}/$run->{distro}/$run->{my_arch}";
46
47    $self;
48}
49
50sub set_command {
51    my ($self, $chroot_tmp) = @_;
52    $self->{urpmi_command} = "urpmi $self->{urpmi_options} $self->{urpmi_media_options} --root $chroot_tmp";
53}
54
55sub set_local_media {
56    my ($self, $local_media) = @_;
57    $self->{local_media} = $local_media;
58}
59
60sub add_to_local_media {
61    my ($self, $chroot_tmp, $srpm, $luser) = @_;
62    my $local_media = $self->{local_media};
63
64    system("cp $chroot_tmp/home/$luser/rpm/RPMS/*/*.rpm $local_media &>/dev/null") and plog("ERROR: could not copy rpm files from $chroot_tmp/home/$luser/rpm/RPMS/ to $local_media ($!)");
65    system("cp $chroot_tmp/home/$luser/rpm/SRPMS/$srpm $local_media &>/dev/null") and plog("ERROR: could not copy $srpm from $chroot_tmp/home/$luser/rpm/SRPMS/ to $local_media ($!)");
66}
67
68sub urpmi_command {
69    my ($self, $chroot_tmp, $_luser) = @_;
70    my $run = $self->{run};
71    my $local_media = $self->{local_media};
72
73    #plog(3, "urpmi_command ($chroot_tmp user $luser)");
74    if ($run->{chrooted_urpmi}) { 
75        $self->{urpmi_command} = "urpmi $self->{urpmi_options} $self->{urpmi_media_options} --root $chroot_tmp ";
76
77# CM: commented out
78#     this was causing rpm database corruption problems and the packages
79#     are already installed
80#
81#        if (!install_packages($self, 'chroot', $chroot_tmp, $local_spool, {}, 'configure', "[ADMIN] installation of urpmi and sudo failed in the chroot $run->{my_arch}", { maintainer => $config->{admin}, check => 1 }, 'urpmi', 'sudo')) {
82#           $run->{chrooted_urpmi} = 0;
83#           return
84#       }
85
86        # Here should be added only the needed media for the given package
87        #  main/release -> main/release
88        #  main/testing -> main/release main/testing
89        #  contrib/release -> contrib/release main/release
90        #  contrib/testing -> contrib/testing contrib/release main/testing main/release
91        #  non-free/release ...
92        # This is now done with an option in iurt2 --chrooted-urpmi -m media1 media2 -- media_url
93
94        if ($run->{chrooted_urpmi}{media}) {
95            foreach my $m (@{$run->{chrooted_urpmi}{media}}) {
96                my $m_name = $m;
97                $m_name =~ s,/,_,g;
98                if (!add_media($self, $chroot_tmp, $m_name,
99                        "$m_name $run->{chrooted_media}/media/$m")) {
100                    $run->{chrooted_urpmi} = 0;
101                    plog ('ERROR', "Failed to add media $m_name. Disabling chrooted_urpmi.");
102                    return;
103                }
104            }
105        } else {
106            if (!add_media($self, $chroot_tmp, 'Main', "--distrib $run->{chrooted_media}")) {
107                if (!add_media($self, $chroot_tmp, 'Main', "--wget --distrib $run->{chrooted_media}")) {
108                    $run->{chrooted_urpmi} = 0;
109                    plog ('ERROR', "Failed to add media $run->{chrooted_media}. Disabling chrooted_urpmi.");
110                    return;
111                }
112            }
113        }
114
115        foreach my $m (@{$run->{additional_media}{media}}) {
116            my $name = "$run->{additional_media}{repository}_$m";
117            $name =~ s![/:]!_!g;
118
119            my $url;
120            if (($run->{additional_media}{repository} =~ m!^(http:|ftp:)!)) {
121                $url = $run->{additional_media}{repository};
122            }
123            else {
124                $url = "/urpmi_medias/$run->{distro}/$m";
125            }
126
127            # Check if the media is not empty, as add_media will abort if it fails
128            my $DP;
129            if (!opendir ($DP, "$chroot_tmp/$url")) {
130                plog ('ERROR', "Failed to add additional media at $url: $!");
131                next;
132            }
133            my @contents = readdir $DP;
134            close ($DP);
135            if ($#contents <= 1) {
136                # Just entries: . ..
137                plog ('DEBUG', "$url has no packages, skipping it.");
138                next;
139            }
140
141            if (!add_media($self, $chroot_tmp, $name, "$name $url")) {
142                plog("ERROR: Unable to add media $m");
143            }
144        }
145
146        if (-d "$local_media") {
147            mkdir("$chroot_tmp/iurt_media/");
148            opendir my $dir, $local_media;
149            my $next;
150            foreach my $f (readdir $dir) {
151                $f =~ /(\.rpm|^hdlist.cz)$/ or next;
152                if (!link "$local_media/$f", "$chroot_tmp/iurt_media") {
153                    if (!copy "$local_media/$f", "$chroot_tmp/iurt_media") {
154                        plog('ERROR', "could not copy file $local_media/$f to $chroot_tmp/iurt_media");
155                        $next = 1;
156                        last;
157                    }
158                }
159            }
160            next if $next;
161            add_media($self, $chroot_tmp, 'iurt_group', "iurt_group file:///iurt_media") or next;
162        }
163
164        $self->{urpmi_command} = "chroot $chroot_tmp urpmi $self->{urpmi_options} ";
165        return 1;
166    } else {
167        $self->{urpmi_command} = "urpmi $self->{urpmi_options} $self->{urpmi_media_options} --root $chroot_tmp";
168    }
169}
170
171sub check_media_added {
172    my ($chroot, $media) = @_;
173    my $medias = `sudo chroot $chroot urpmq --list-media 2>&1`;
174    print "MEDIA $medias ($media)\n";
175    $medias =~ /$media/m;
176}
177
178sub add_media {
179    my ($self, $chroot, $regexp, $media) = @_;
180    my $run = $self->{run};
181    my $config = $self->{config};
182    my $cache = $run->{cache};
183
184    plog("add chroot media: $run->{chrooted_media}");
185
186    if (!perform_command("sudo chroot $chroot urpmi.addmedia --probe-hdlist $media", 
187                $run, $config, $cache, 
188                mail => $config->{admin},
189                timeout => 300, 
190                freq => 1,
191                retry => 2,
192                debug_mail => $run->{debug})) {
193        }
194    if (!check_media_added($chroot, $regexp)) { 
195        plog('ERR', "ERROR iurt could not add media into the chroot");
196        return;
197    } 
198    1;
199}
200
201sub add_packages {
202    my ($self, $chroot, $_user, @packages) = @_;
203    my $run = $self->{run};
204    my $config = $self->{config};
205    my $cache = $run->{cache};
206    if (!perform_command("sudo $self->{urpmi_command} @packages", 
207                $run, $config, $cache, 
208                timeout => 300, 
209                freq => 1,
210                retry => 2,
211                error_ok => [ 11 ],
212                debug_mail => $run->{debug},
213                error_regexp => 'cannot be installed',
214                wait_regexp => {
215                    'is needed by' => sub { 
216                        plog("WARNING: rpm database seems corrupted, retrying"); 
217                        system("sudo chroot $chroot rm -rf /var/lib/rpm/__db* &> /dev/null");
218                        1;
219                        }, 
220                    'database locked' => sub { 
221                        plog("WARNING: urpmi database locked, waiting...");
222                        sleep 30; 
223                        $self->{wait_limit}++; 
224                        if ($self->{wait_limit} > 10) { 
225                            $self->{wait_limit} = 0;
226                            system(qq(sudo pkill -9 urpmi &>/dev/null));
227                            return;
228                        } 
229                        1;
230                  } },)) {
231        plog("ERROR: could not install @packages inside $chroot");
232        return 0;
233    }
234    1;
235}
236
237sub get_local_provides {
238    my ($self) = @_;
239    my $run = $self->{run};
240    my $program_name = $run->{program_name};
241    my $local_media = $self->{local_media};
242
243    opendir my $dir, $local_media;
244    plog(1, "get local provides ($local_media)");
245    require URPM;
246    my $urpm = new URPM;
247    foreach my $d (readdir $dir) {
248        $d =~ /\.src\.rpm$/ and next;
249        $d =~ /\.rpm$/ or next;
250        my $id = $urpm->parse_rpm("$local_media/$d");
251        my $pkg = $urpm->{depslist}[$id];
252        plog(3, "$program_name: checking $d provides");
253        foreach ($pkg->provides, $pkg->files) {
254            plog(3, "$program_name: adding $_ as provides of $d");
255            $run->{local_provides}{$_} = $d;
256        }
257    }
258    1;
259}
260
261sub get_build_requires {
262    my ($self, $union_id, $luser) = @_;
263    my $run = $self->{run};
264    my $config = $self->{config};
265    my $cache = $run->{cache};
266
267    $run->{todo_requires} = {};
268    plog("get_build_requires");
269
270    my ($u_id, $chroot_tmp) = create_temp_chroot($run, $config, $cache, $union_id, $run->{chroot_tmp}, $run->{chroot_tar}) or return;
271    add_local_user($chroot_tmp, $run, $config, $luser, $run->{uid}) or return;
272    $union_id = $u_id;
273   
274    my $urpm = new URPM;
275    foreach my $p (@{$run->{todo}}) {
276        my ($dir, $srpm, $s) = @$p;
277        recreate_srpm($self, $run, $config, $chroot_tmp, $dir, $srpm, $run->{user}) or return;
278        $s or next;
279        my $id = $urpm->parse_rpm("$dir/$srpm");
280        my $pkg = $urpm->{depslist}[$id];
281        foreach ($pkg->requires) {
282            plog(3, "adding $_ as requires of $srpm");
283            $run->{todo_requires}{$_} = $srpm;
284        }
285    }
286    1;
287}
288
289sub order_packages {
290    my ($self, $union_id, $provides, $luser) = @_;
291    my $run = $self->{run};
292    my @packages = @{$run->{todo}};
293    my $move;
294
295    plog(1, "order_packages");
296    get_local_provides($self) or return;
297    if (!$run->{todo_requires}) {
298        get_build_requires($self, $union_id, $luser) or return;
299    }
300    my %visit;
301    my %status;
302    do { 
303        $move = 0;
304        foreach my $p (@packages) {
305            my ($_dir, $rpm, $status) = @$p;
306            defined $status{$rpm} && $status{$rpm} == 0 and next;
307            plog("checking packages $rpm");
308            foreach my $r (@{$run->{todo_requires}{$rpm}}) {
309                plog("checking requires $r");
310                if (!$run->{local_provides}{$r}) { 
311                    if ($provides->{$r}) {
312                        $status = 1;
313                    } else {
314                        $status = 0;
315                    }
316                } elsif ($visit{$rpm}{$r}) {
317                    # to evit loops
318                    $status = 0;
319                } elsif ($run->{done}{$rpm} && $run->{done}{$provides->{$r}}) {
320                    if ($run->{done}{$rpm} < $run->{done}{$provides->{$r}}) {
321                        $move = 1;
322                        $status = $status{$provides->{$r}} + 1;
323                    } else {
324                        $status = 0;
325                    }
326                } elsif ($status < $status{$provides->{$r}}) {
327                    $move = 1;
328                    $status = $status{$provides->{$r}} + 1;
329                }
330                $visit{$rpm}{$r} = 1;
331            }
332            $status{$rpm} = $status;
333            $p->[2] = $status;
334        }
335    } while $move;   
336    $run->{todo} = [ sort { $a->[2] <=> $b->[2] } @packages ];
337    if ($run->{verbose}) {
338        foreach (@packages) {
339            plog("order_packages $_->[1]");
340        }
341    }
342    @packages;
343}
344       
345sub wait_urpmi { 
346    my ($self) = @_;
347    my $run = $self->{run};
348
349    plog("WARNING: urpmi database locked, waiting...") if $run->{debug};
350    sleep 30; 
351    $self->{wait_limit}++; 
352    if ($self->{wait_limit} > 8) { 
353        $self->{wait_limit} = 0; system(qq(sudo pkill -9 urpmi &>/dev/null));
354    } 
355}
356
357sub install_packages_old {
358    my ($self, $local_spool, $srpm, $log, $error, @packages) = @_;
359    my $run = $self->{run};
360    my $config = $self->{config};
361    my $cache = $run->{cache};
362    my $log_spool = "$local_spool/log/$srpm/";
363    -d $log_spool or mkdir $log_spool;
364    if (!perform_command("sudo $self->{urpmi_command} @packages", 
365                $run, $config, $cache, 
366                #       mail => $maintainer,
367                error => $error, 
368                hash => "${log}_$srpm", 
369                srpm => $srpm,
370                timeout => 600, 
371                retry => 2,
372                debug_mail => $run->{debug},
373                freq => 1, 
374                wait_regexp => { 'database locked' => \&wait_urpmi },
375                error_regexp => 'unable to access',
376                log => $log_spool)) {
377            $cache->{failure}{$srpm} = 1;
378            $run->{status}{$srpm} = 'binary_test_failure';
379            return 0;
380        }
381        1;
382}
383
384sub install_packages {
385    my ($self, $title, $chroot_tmp, $local_spool, $pack_provide, $log, $error, $opt, @packages) = @_;
386
387    my $maintainer = $opt->{maintainer};
388    my $run = $self->{run};
389    my $config = $self->{config};
390    my $cache = $run->{cache};
391    my $program_name = $run->{program_name};
392    my $ok;
393    my @to_install;
394
395    plog('DEBUG', "installing @packages");
396
397    if ($run->{chrooted_urpmi}) {
398        @to_install = map { s/$chroot_tmp//; $_ } @packages;
399    } else {
400        push @to_install, @packages;
401    }
402
403    @to_install or return 1;
404
405    (my $log_dirname = $title) =~ s/.*:(.*)\.src.rpm/$1/;
406
407    my $log_spool = "$local_spool/log/$log_dirname/";
408
409    mkdir $log_spool;
410
411    my $try_urpmi = 1;
412    my @rpm = grep { !/\.src\.rpm$/ } @to_install;
413
414    return 1 if ($opt->{check} && -f "$chroot_tmp/bin/rpm" && @rpm && !system("sudo chroot $chroot_tmp rpm -q @to_install"));
415
416    if ($try_urpmi) {
417        foreach my $try (
418                [ '', 'using urpmi' ],
419                [ '', 'rebuild rpm base and retry', '_retry' ],
420                [ ' --allow-nodeps', 'retrying with nodeps' , '_nodeps' ],
421                [ ' --no-install', 'using rpm directly', '_rpm' ]
422        ) {
423            my ($opt, $msg, $suf) = @$try;
424
425            plog('INFO', "install dependencies: $msg");
426            my $unsatisfied;
427
428            if (!perform_command(
429                    "sudo $self->{urpmi_command} $opt @to_install", 
430                    $run, $config, $cache,
431                    error => $error,
432                    logname => "${log}$suf", 
433                    hash => "${log}_$title$suf", 
434                    timeout => 600, 
435                    srpm => $title,
436                    freq => 1,
437                    #cc => $cc,
438                    retry => 3,
439                    debug_mail => $run->{debug},
440                    error_regexp => 'cannot be installed',
441                    wait_regexp => { 
442                        'database locked' => \&wait_urpmi, 
443                        'is needed by' => sub { 
444                            plog('WARN', "WARNING: rpm database seems corrupted, retrying"); 
445                            system("sudo chroot $chroot_tmp rm -rf /var/lib/rpm/__db* &> /dev/null");
446                            1;
447                        }, 
448                    }, 
449                    log => $log_spool,
450                    callback => sub { 
451                        my ($opt, $output) = @_;
452                        plog('DEBUG', "calling callback for $opt->{hash}");
453
454# 20060614
455# it seems the is needed urpmi error is due to something else (likely a
456# database corruption error).       
457# my @missing_deps = $output =~ /(?:(\S+) is needed by )|(?:\(due to unsatisfied ([^[ ]*)(?: (.*)|\[(.*)\])?\))/g;
458#
459
460                        my @missing_deps = $output =~ /([^ \n]+) \(due to unsatisfied ([^[ \n]*)(?: ([^\n]*)|\[([^\n]*)\])?\)/g;
461
462                        # as it seems that rpm db corruption is making urpmi
463                        # returning false problem on deps installation, try
464                        # to compile anyway
465
466                        @missing_deps or return 1;
467                        $unsatisfied = 1;
468
469                        while (my $missing_package = shift @missing_deps) {
470                            my $missing_deps = shift @missing_deps;
471                            my $version = shift @missing_deps;
472                            my $version2 = shift @missing_deps;
473                            $version ||= $version2 || 0;
474                            my $p = $pack_provide->{$missing_deps} || $missing_deps;
475                            my ($missing_package_name, $first_maint);
476                            if ($missing_package !~ /\.src$/) {
477                                ($first_maint, $missing_package_name) = get_maint($run, $missing_package);
478                                plog(5, "likely $missing_package_name need to be rebuilt ($first_maint)");
479                            } else {
480                                $missing_package = '';
481                            }
482
483                            my ($other_maint) = get_maint($run, $p);
484                            plog('FAIL', "missing dep: $missing_deps ($other_maint) missing_package $missing_package ($first_maint)");
485                            $run->{status}{$title} = 'missing_dep';
486                            foreach my $m ($first_maint, $other_maint) { # FIXME: (tv) this loop is useless !!!
487                                if ($other_maint && $other_maint ne 'NOT_FOUND') {
488                                    $opt->{mail} = $config->{admin};
489                                    #$opt->{mail} .= ", $other_maint";
490                                }
491                            }
492
493                            if (!$opt->{mail}) { 
494                                $opt->{mail} = $config->{admin};
495                            }
496
497                            # remember what is needed, and do not try to
498                            # recompile until it is available
499
500                            if ($missing_package) {
501                                $opt->{error} = "[MISSING] $missing_deps, needed by $missing_package to build $title, is not available on $run->{my_arch} (rebuild $missing_package?)";
502                                $cache->{needed}{$title}{$missing_deps} = { package => $missing_package , version => $version, maint => $first_maint || $other_maint || $maintainer };
503                            } else {
504                                $opt->{error} = "[MISSING] $missing_deps, needed to build $title, is not available on $run->{my_arch}";
505                                $cache->{needed}{$title}{$missing_deps} = { package => $missing_package , version => $version, maint => $maintainer || $other_maint };
506                            }
507                        } 
508                        0;
509                    },
510                )) {
511                if (!clean_process($run, "$self->{urpmi_command} $opt @to_install", $run->{verbose})) {
512                    dump_cache_par($run);
513                    die "FATAL $program_name: Could not have urpmi working !";
514                }
515                $unsatisfied and last;
516            } else { 
517                if (!@rpm || !system("sudo chroot $chroot_tmp rpm -q @rpm")) {
518                    plog("installation successful");
519                    $ok = 1;
520                }
521            }
522
523            if (-f "$chroot_tmp/bin/rpm") {
524                if (!$ok && system("sudo chroot $chroot_tmp rm -rf /var/lib/rpm/__db*; sudo chroot $chroot_tmp rpm --rebuilddb")) {
525                    plog("ERROR: rebuilding rpm db failed, aborting ($!)");
526                    last;
527                }
528                if ($suf eq '_rpm') {
529                    plog(1, "trying to install all the rpms in $chroot_tmp/var/cache/urpmi/rpms/ manually");
530                    if (!system("sudo chroot $chroot_tmp rpm -Uvh --force --nodeps /var/cache/urpmi/rpms/*.rpm")) {
531                        $ok = 1;
532                        last;
533                    } else {
534                        $ok = 0;
535                    }
536                }
537            }
538            last if $ok == 1;
539        }
540    }
541    if (!-f "$chroot_tmp/bin/rpm" || @rpm && system("sudo chroot $chroot_tmp rpm -q @to_install")) {
542        plog(1, "ERROR: urpmi is not working, doing it manually");
543        my $root = "$config->{repository}/$run->{distro}/$run->{my_arch}";
544        my $depslist = "$root/media/media_info/depslist.ordered";
545        if (-f $depslist) {
546            my $distrib = $self->{distrib};
547            if (!$distrib) { 
548                $distrib = MDV::Distribconf::Build->new($root);
549                plog(3, "getting media config from $root");
550                if (!$distrib->loadtree) {
551                    plog(1, "ERROR: $root does not seem to be a distribution tree\n");
552                    return;
553                }
554                $distrib->parse_mediacfg;
555                foreach my $media ($distrib->listmedia) {
556                    $media =~ /(SRPMS|debug_)/ and next;
557                    my $path = $distrib->getfullpath($media, 'path');
558                    opendir my $rpmdh, $path;
559                    foreach my $rpm (readdir $rpmdh) {
560                        if ($rpm =~ /^(.*)-([^-]+)-([^-]+)\.([^.]+)\.rpm/) {
561                            $distrib->{file}{"$1-$2-$3.$4"} = "$path/$rpm";
562                        }
563                    }
564                }
565            }
566            $self->{distrib} = $distrib;
567            plog(3, "using $depslist to resolve dependencies");
568            open my $depsfh, $depslist;
569            my %packages;
570            my @deps;
571            my $i;
572            my @install;
573            my @pack;
574            while (<$depsfh>) {
575                my ($pack, $_size, @d) = split ' ';
576                $pack =~ s/:\d+$//;
577                push @deps, \@d;
578                my ($name, $version, $release, $arch) = $pack =~ /(.*)-([^-]+)-([^-]+)\.([^.]+)$/;
579                $pack[$i] = $pack;
580                $packages{$pack} ||= $i;
581                if ($arch ne 'src' && !$packages{$name}) {
582                    $packages{$name} = $i;
583                    $packages{"$name-$version"} = $i;
584                    $packages{"$name-$version-$release"} = $i;
585                }
586                $i++;
587            }
588            plog(4, "$i packages found");
589            my %done;
590            # rpm -root $chroot -qa does not work
591            if (-f "$chroot_tmp/bin/rpm") {
592                my $qa = `sudo chroot $chroot_tmp rpm -qa --qf "\%{name}-\%{version}-\%{release}.\%{arch}\n"`;
593                foreach my $rpm (split "\n", $qa) {
594                    plog(6, "$rpm already installed");
595                    $done{$rpm} = 1;
596                }
597            }
598            foreach my $p (@to_install) {
599                my $pa = $pack[$packages{$p}];
600                $done{$pa} and next;
601                my $f = $distrib->{file}{$pa};
602                if ($f) {
603                    push @install, $pa;
604                } else {
605                    plog(1, "ERROR: main package $p is not present in the repository");
606                    return 0;
607                }
608            }
609            my $dok;
610            while (!$dok) {
611                $dok = 1;
612                foreach my $p (@install) {
613                    $done{$p} and next;
614                    $done{$p} = 1;
615                    plog(5, "adding deps for $p (", join(', ', @{$deps[$packages{$p}]}, ")"));
616                    foreach my $d (@{$deps[$packages{$p}]}) {
617                        plog("$d (pack $pack[$d]) done $done{$d} done pack $done{$pack[$d]}");
618                        $done{$d} and next;
619                        $done{$pack[$d]} and next;
620                        $done{$d} = 1;
621                        if ($d =~ /\d+/) {
622                            my $f = $distrib->{file}{$pack[$d]};
623                            if ($f) {
624                                $dok = 1;
625                                plog(5, "adding $pack[$d]");
626                                push @install, $pack[$d];
627                            } else {
628                                plog(2, "ERROR: deps for $p, $pack[$d] ($d) is not present in the repository");
629                            }
630                        } elsif ($d =~ /\|/) {
631                            my $done;
632                            foreach my $a (split '\|', $d) {
633                                my $f = $distrib->{file}{$pack[$a]};
634                                if ($f) {
635                                    $done = 1;
636                                    if (!$done{$pack[$a]}) {
637                                        $dok = 1;
638                                        plog(5, "adding $pack[$a]");
639                                        push @install, $pack[$a];
640                                        $done{$pack[$a]} = 1;
641                                    }
642                                    last;
643                                } else {
644                                    plog(2, "ERROR: alternate deps, $pack[$a] ($d) is not present in the repository, using alternative");
645                                }
646                            }
647                            if (!$done) {
648                                plog(2, "ERROR: no alternatives present in the repository");
649                            }
650                        }
651                    }
652                }
653            }
654            my $rpms;
655            my %install_done;
656         # FIXME: (tv) this loop could be simplified with uniq() from MDK::Common:
657         # eg: $rpms = join(map { "$distrib->{file}{$_}" } uniq(@install))
658            foreach my $rpm (@install) {
659                $install_done{$rpm} and next;
660                print "$program_name: will install $rpm ($distrib->{file}{$rpm})\n" if $run->{verbose} > 3;
661                $install_done{$rpm} = 1;
662                $rpms .= "$distrib->{file}{$rpm} ";
663            }
664            if ($rpms) {
665                return !system("sudo rpm --ignoresize --nosignature --root $chroot_tmp -Uvh $rpms");
666            }
667            $ok = 1;
668        }
669    }
670    $ok;
671}
672
673sub clean_urpmi_process {
674    my ($self) = @_;
675    my $run = $self->{run};
676    my $program_name = $run->{program_name};
677    if (!$run->{chrooted_urpmi}) {
678        my $match = $self->{urpmi_command} or return;
679        if (!clean_process($run, $match, $run->{verbose})) {
680            dump_cache_par($run);
681            die "FATAL $program_name: Could not have urpmi working !";
682        }
683    }
684}
685
686sub update_srpm {
687        my ($self, $dir, $rpm, $wrong_rpm) = @_;
688        my $run = $self->{run};
689        my $cache = $run->{cache};
690        my ($arch) = $rpm =~ /([^\.]+)\.rpm$/ or return 0;
691        my $srpm = $cache->{rpm_srpm}{$rpm};
692        if (!$srpm) {
693                my $hdr = RPM4::Header->new("$dir/$rpm");
694                $hdr or return 0;
695                $srpm = $hdr->queryformat('%{SOURCERPM}');
696                $cache->{rpm_srpm}{$rpm} = $srpm;
697        }
698        $srpm = fix_srpm_name($cache, $srpm, $rpm, $wrong_rpm);
699        $arch, $srpm;
700}
701
702sub fix_srpm_name {
703        my ($cache, $srpm, $rpm, $wrong_rpm) = @_;
704        my $old_srpm = $srpm;
705        if ($srpm =~ s/^lib64/lib/) {
706                push @$wrong_rpm, [ $old_srpm, $rpm ] if ref $wrong_rpm;
707                $cache->{rpm_srpm}{$rpm} = $srpm;
708        }
709        $srpm;
710}
711
712sub recreate_srpm {
713    my ($_self, $run, $config, $chroot_tmp, $dir, $srpm, $luser, $b_retry) = @_;
714# recreate a new srpm for buildarch condition in the spec file
715    my $program_name = $run->{program_name};
716    my $cache = $run->{cache};
717    my $with_flags = $run->{with_flags};
718
719    plog('NOTIFY', "recreate srpm: $srpm");
720
721    perform_command([ 
722        sub { 
723            my ($s, $d) = @_; 
724            sudo($run, $config, '--cp', $s, $d) } , [ "$dir/$srpm", "$chroot_tmp/home/$luser/rpm/SRPMS/" ] ], 
725        $run, $config, $cache, 
726        type => 'perl',
727        mail => $config->{admin}, 
728        error => "[REBUILD] cannot copy $srpm to $chroot_tmp", 
729        debug_mail => $run->{debug},
730        hash => "copy_$srpm") or return;
731
732    my %opt = (mail => $config->{admin}, 
733        error => "[REBUILD] cannot install $srpm in $chroot_tmp", 
734        debug_mail => $run->{debug},
735        hash => "install_$srpm",
736        retry => $b_retry,
737        callback => sub { 
738            my ($opt, $output) = @_;
739            plog('DEBUG', "calling callback for $opt->{hash}");
740            if ($output =~ /warning: (group|user) .* does not exist - using root|Header V3 DSA signature/i) {
741                return 1;
742            } elsif ($output =~ /user $luser does not exist|cannot write to \%sourcedir/) {
743                plog('WARN', "WARNING: chroot seems corrupted!");
744                $opt->{error} = "[CHROOT] chroot is corrupted";
745                $opt->{retry} ||= 1;
746                return;
747            }
748            1;
749        });
750    plog('DEBUG', "recreating src.rpm...");
751    if (!perform_command(qq(sudo chroot $chroot_tmp su $luser -c "rpm -i /home/$luser/rpm/SRPMS/$srpm"), 
752            $run, $config, $cache, %opt)) {
753        plog("ERROR: chrooting failed (retry $opt{retry}") if $run->{debug};
754        if ($opt{retry}) {
755            check_build_chroot($run->{chroot_path}, $run->{chroot_tar}, $run,  $config) or return;
756            return -1;
757        }
758        return;
759    }
760   
761    my $spec;
762    my $oldsrpm = "$chroot_tmp/home/$luser/rpm/SRPMS/$srpm";
763    my $filelist = `rpm -qlp $oldsrpm`;
764    my ($name) = $srpm =~ /(?:.*:)?(.*)-[^-]+-[^-]+\.src\.rpm$/;
765    foreach my $file (split "\n", $filelist) {
766        if ($file =~ /(.*)\.spec/) {
767            if (!$spec) {
768                $spec = $file;
769            } elsif ($1 eq $name) {
770                $spec = $file;
771            }
772        }
773    } 
774    # 20060515 This should not be necessairy any more if urpmi *.spec works, but it doesn't
775    #
776    my $ret = perform_command(qq(sudo chroot $chroot_tmp su $luser -c "rpm --nodeps -bs $with_flags /home/$luser/rpm/SPECS/$spec"), 
777        $run, $config, $cache, 
778        mail => $config->{admin}, 
779        error => "[REBUILD] cannot create $srpm in $chroot_tmp", 
780        debug_mail => $run->{debug},
781        hash => "create_$srpm"
782    );
783
784    # Return if we can't regenerate srpm
785    #
786    return (0, ,) unless $ret;
787
788    # CM: was: foreach my $file (readdir $dir)
789    #     The above line returned entries in a strange order in my test
790    #     system, such as
791    #      ..
792    #      cowsay-3.03-11mdv2007.1.src.rpm
793    #      cowsay-3.03-11mdv2007.0.src.rpm
794    #      .
795    #     assigning '.' to $new_rpm. Now sorting the output.
796
797    # we should better perform a rpm -qp -qf "%{name}-%{version}-%{release}.src.rpm" $spec
798    my $file;
799    my $stat;
800    foreach my $f (glob "$chroot_tmp/home/$luser/rpm/SRPMS/$name-*.src.rpm") {
801        my (@s) = stat $f;
802        if ($s[9] > $stat) {
803            $file = $f;
804            $stat = $s[9];
805        }
806    }     
807    my ($new_srpm) = basename($file);
808    my $prefix = get_package_prefix($srpm);
809    my $newfile = "$chroot_tmp/home/$luser/rpm/SRPMS/$prefix$new_srpm";
810    if (-f $file && $newfile ne $file) {
811        if (-f $newfile) {
812            sudo($run, $config, '--rm', $newfile) or die "$program_name: could not delete $newfile ($!)";
813        }
814        sudo($run, $config, '--ln', $file, $newfile) or die "$program_name: linking $file to $newfile failed ($!)";
815        unlink $file;
816        unlink $oldsrpm if $oldsrpm ne $newfile;
817    }
818    plog('NOTIFY', "new srpm: $prefix$new_srpm");
819    ($ret, "$prefix$new_srpm", $spec);
820}
821
8221;
Note: See TracBrowser for help on using the repository browser.