source: soft/build_system/build_system/mkcd/tags/v3_0_0/pm/Mkcd/Disc.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: 10.6 KB
Line 
1package Mkcd::Disc;
2
3my $VERSION = '0.0.2';
4
5use strict;
6use File::Path;
7use Mkcd::Functions;
8use Mkcd::Tools qw(du compute_md5 log_);
9
10=head1 NAME
11
12Disc - mkcd disc functions
13
14=head1 SYNOPSYS
15
16    require Mkcd::Disc;
17
18=head1 DESCRIPTION
19
20C<Mkcd::Disc> include the mkcd disc handling subroutines.
21
22=head1 SEE ALSO
23
24mkcd
25
26=head1 COPYRIGHT
27
28Copyright (C) 2000,2001 MandrakeSoft <warly@mandrakesoft.com>
29
30This program is free software; you can redistribute it and/or modify
31it under the terms of the GNU General Public License as published by
32the Free Software Foundation; either version 2, or (at your option)
33any later version.
34
35This program is distributed in the hope that it will be useful,
36but WITHOUT ANY WARRANTY; without even the implied warranty of
37MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38GNU General Public License for more details.
39
40You should have received a copy of the GNU General Public License
41along with this program; if not, write to the Free Software
42Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
43
44=cut
45
46my $config;
47
48sub new {
49    my ($class, $conf) = @_;
50    $config = $conf;
51    bless {
52           config       => $conf,
53           functions    => new Mkcd::Functions($config)
54          }, $class;
55}
56
57# FIXME must add space for synthesis, however they are negligeable compared to hdlist. Only
58# a pb with very small CD.
59
60sub guessHdlistSize{
61    my ($class,$group,$size,$cdsize,$lists,$discsFiles) = @_;
62    my $FACTOR = 150;
63    my $SynFACTOR = 90;
64    my $msg;
65    my $depsRep = "$config->{tmp}/$class->{config}{name}/$group->{depsrep}";
66    $msg = "guessHdlistSize: depsRep $depsRep\n";
67    # FIXME heuristic for hdlist size on installation disc, (RPMS size / $FACTOR) per discs
68    # need genDeps to write hdlist/synthesis, overkill
69    my $depsSize = du("$depsRep");
70    my $instdisc = $group->{installDisc};
71    my $sz;
72    my (@notdone, @rem_size);
73    push @rem_size, @$cdsize;
74    foreach my $list (keys %{$group->{list}}){
75        if ($config->{list}[$list]{auto}){
76            if ($config->{list}[$list]{cd}){
77                my $tsize = ($config->{discsize}/$FACTOR) * $config->{list}[$list]{cd}; 
78                $sz += $tsize < $depsSize ? $tsize : $depsSize;
79            }else {
80                $sz += $depsSize
81            }
82        }else {
83            my $ok;
84            my $listsize = $group->{listsize}{$list}{rpm};
85            foreach my $rd (@{$group->{list}{$list}{rpm}}){
86                my ($cdrep,undef,undef,$opt) = @$rd;
87                if ($opt->{nodeps}) { $ok = 1; next }
88                if ($lists->{$cdrep}){
89                    if ($listsize > $cdsize->[$cdrep]){
90                        $sz += $rem_size[$cdrep] / $FACTOR;
91                        $listsize -= $rem_size[$cdrep];
92                        $rem_size[$cdrep] = 0
93                    }else{
94                        $sz += $listsize / $FACTOR;
95                        $rem_size[$cdrep] -= $listsize;
96                        last
97                    }
98                }
99            }
100            $ok and push @notdone, $list       
101        }
102    }
103    $msg .= "guessHdlistSize: reserving ";
104    if ($depsSize < $sz && $depsSize > 10000){ 
105        $msg .= "$depsSize";
106        $size->{disc}[$instdisc] += int $depsSize;
107        if ($config->{disc}[$instdisc]{function}{data}{installation}[1]{synthesis}) { $size->{disc}[$instdisc] += int ($depsSize / $SynFACTOR) }
108    } elsif ($sz > 10000) { 
109        $msg .= "$sz"; 
110        $size->{disc}[$instdisc] += int $sz ;
111        if ($config->{disc}[$instdisc]{function}{data}{installation}[1]{synthesis}) { $size->{disc}[$instdisc] += int ($sz / $SynFACTOR) }
112    }else{
113        log_("ERROR guessHdlistSize: possibly wrong estimated dependencies file size\n",$config->{verbose},$config->{LOG}) 
114    }
115    $msg .= " (new size $size->{disc}[$instdisc]) on disc $instdisc ($depsSize/$sz) for dependencies files\n";
116    log_($msg,$config->{verbose},$config->{LOG});
117    @notdone or return 1;
118    my $sz;
119    foreach my $list (@notdone){
120        foreach my $rd (@{$group->{list}{$list}{rpm}}){
121            my ($cd,$rep,$repopt,$opt) = @$rd;
122            if ($lists->{$cd} == 1){
123                $sz += du("$class-{config}{topdir}/build/$class->{config}{name}/$cd/$class->{config}{disc}[$cd]{function}{data}{dir}{$rep}")
124            }elsif ($lists->{$cd} == 2){
125                foreach my $rpm (keys %{$discsFiles->[$cd]{$rep}{$list}}){
126                    $sz += du("$discsFiles->[$cd]{$rep}{$list}{$rpm}/$rpm.rpm")
127                }
128            }
129        }
130    }
131    $sz /= $FACTOR;
132    $msg = "guessHdlistSize: reserving $sz";
133    $size->{disc}[$instdisc] += $sz;
134    if ($config->{disc}[$instdisc]{function}{data}{installation}[1]{synthesis}) { $size->{disc}[$instdisc] += $sz / $SynFACTOR }
135    $msg .= " (new size $size->{disc}[$instdisc]) on disc $instdisc ($sz) for extra dependencies files\n";
136    log_($msg,$config->{verbose},$config->{LOG})
137}               
138
139sub getBuiltDiscs{
140    my ($class, $lists, $group, $discsFiles) = @_;
141    foreach my $l (keys %{$group->{list}}){
142        my @rpmlist;
143        ref $group->{list}{$l}{rpm} and push @rpmlist, @{$group->{list}{$l}{rpm}};
144        ref $group->{list}{$l}{srpm} and push @rpmlist, @{$group->{list}{$l}{srpm}};
145        for (my $i; $i < @rpmlist; $i++){
146            my ($cd,$rep,$repopt) = @{$rpmlist[$i]};
147            $lists->{$cd} == 1 or next;
148            my $dir = "$class->{config}{topdir}/build/$class->{config}{name}/$cd/$class->{config}{disc}[$cd]{function}{data}{dir}{$rep}";
149            #
150            # FIXME maybe need to unshift instead of push
151            #
152            $repopt->{source} or push @{$class->{config}{list}[$l]{packages}}, [$dir];
153            $class->{config}{list}[$l]{disc}{$cd}{$rep}{done} = 1;
154            print {$config->{LOG}} "getBuiltDiscs: get files from $dir\n";
155            local *A; opendir A,$dir;
156            foreach (readdir A){
157                /(.*)\.rpm/ or next;
158                # FIXME need to check if it is well placed in getList function
159                # $group->{done}{$rpm} = $group->{orderedrep}{"$cd/$rep"};
160                $discsFiles->[$cd]{$rep}{$l}{$1} = $dir
161            }
162        }
163    }
164    1
165}
166
167sub write_graft{
168    my ($graft, $file) = @_;
169    print {$config->{LOG}} "write_graft: $file ($graft)\n"; 
170    local *A; open A, ">$file";
171    foreach my $d (sort keys %$graft){
172        if (ref $graft->{$d}){
173            map { print A "$d=$_\n" } keys %{$graft->{$d}}
174        }
175    }
176}
177
178sub graft_to_md5{
179    my ($graft,$dir,$serial) = @_;
180    my $mdfile = ".$serial.md5";
181    print {$config->{LOG}} "graft_to_md5: $serial -> $dir/$mdfile ($graft)\n"; 
182    local *A; open A, ">$dir/$mdfile";
183    my %ignore;
184    my @to_check;
185    $graft->{$mdfile}{"$dir/$mdfile"} = 0;
186    foreach my $f (keys %$graft) { 
187        if (ref $graft->{$f}) { 
188            foreach (keys %{$graft->{$f}}){
189                my ($file) = /\/([^\/]+)$/;
190                my $dest = ($f =~ /\/$/) ? "/$f/$file" : "/$f";
191                if ($graft->{$f}{$_}) { 
192                    push @to_check, [ $dest, $_ ];
193                } else { 
194                    $ignore{$dest} = 1;
195                    print A "$f\n" 
196                }
197            }
198        } else { 
199            $ignore{$f} = 1;
200            print A "$f\n" 
201        }
202    }
203    my $digest = compute_md5(\@to_check,\%ignore);
204    print A "$digest - $serial\n"
205}   
206
207sub makeDiscs {
208    my ($class, $fixed, $lists, $cds, $size, $mkisos, $discsFile, $graft, $cdfile) = @_;
209    my $dir;
210    my $name = $class->{config}{name};
211    my $topdir = $class->{config}{topdir};
212    my $tmp = "$config->{tmp}/build/$name";
213
214    if (!$class->{config}{nolive}){
215        $dir = "$topdir/build/$name";
216        -d "$dir" or mkpath "$dir";
217        -d $tmp or mkpath $tmp;
218    }else{
219        $dir = "$config->{tmp}/build/$name";
220        -d "$dir" or mkpath "$dir";
221    }
222    print {$config->{LOG}} "makeDiscs: Discs @$cds TOPDIR $dir\n";
223    foreach my $i (@$cds){
224        $lists->{$i} > 1 or next;
225        my $cd = $class->{config}{disc}[$i];
226        $graft->{$i} ||= {};
227        if (!$fixed){
228            print {$config->{LOG}} "makeDisc: Fixed part of disc $i\n";
229            if ($class->{config}{nolive}){
230                print {$config->{LOG}} "makeDisc: removing $dir/$i.list\n";
231                -f "$dir/$i.list" and unlink "$dir/$i.list";
232                print {$config->{LOG}} "makeDisc: removing $dir/$i\n";
233                rmtree "$dir/$i";
234                mkdir "$dir/$i"
235            }else{
236                -d "$tmp/$i" or mkpath "$tmp/$i";
237                rmtree "$topdir/build/$name/$i";
238                rmtree "$topdir/build/$name/first/$i"
239            }
240        }else {print {$config->{LOG}} "Finalizing disc $i\n"}
241        my $sz;
242        for (my $j; $j < @{$cd->{steps}}; $j++){
243            my $name = $cd->{steps}[$j][0];
244            print {$config->{LOG}} "makeDiscs: $name ($fixed)\n";
245            if (defined $Mkcd::Functions::{$name}) { $sz += &{$Mkcd::Functions::{$name}}($class->{disc}->{functions},$cd->{steps}[$j],$dir,$fixed,$class->{config}{nolive},$i,$cd,$cdfile,$lists,$mkisos,$graft->{$i},$discsFile)}
246            else {print {$config->{LOG}} "ERROR: unrecognized function name $name\n"}
247            log_("SIZE ($name) $sz\n",$config->{verbose},$config->{LOG});
248        }
249        if ($class->{config}{nolive}){
250            log_("SIZE $size->{disc}[$i] + $sz\n",$config->{verbose},$config->{LOG});
251            $size->{disc}[$i] += $sz
252        }else{
253            $size->{disc}[$i] = du("$dir/$i") + $sz
254        }
255        log_("disc $i ($dir/$i) size: $size->{disc}[$i] ($sz)\n",$config->{verbose},$config->{LOG});
256        my $mkisoopt = $class->{config}{mkisoopt};
257        if ($fixed) {
258            my $isodir = $class->{config}{isodir} ? $class->{config}{isodir} : "$topdir/iso/$name";
259            $graft->{$i}{".rr_moved"} = 0;
260            if ($config->{nolive}){
261                graft_to_md5($graft->{$i},"$dir/$i",$cd->{serial});
262                write_graft($graft->{$i},"$dir/$i.list");
263                $mkisos->[$i] = "mkisofs $mkisoopt -graft-points -path-list $dir/$i.list -V $cd->{serial} -o $isodir/$i-$name.iso $mkisos->[$i]"
264            }else{
265                $graft->{$i}{"/"}{"$dir/$i/"} = 1;
266                graft_to_md5($graft->{$i},"$dir/$i",$cd->{serial});
267                if ($mkisos->[$i]) { 
268                    $mkisos->[$i] = "mkisofs $mkisoopt -V $cd->{serial} -o $isodir/$i-$name.iso $mkisos->[$i] $dir/$i"
269                } else { 
270                    $mkisos->[$i] = qq|mkisofs $mkisoopt -V $cd->{serial} -o "$isodir/$i-$name".iso "$dir/$i"|
271                }
272            }
273        }
274    }
275    !$fixed and return 1;
276    if (!$class->{config}{noiso}){
277        -d "$topdir/iso/$name" or mkpath "$topdir/iso/$name"; 
278        foreach my $i (@$cds){
279            $lists->{$i} > 1 or next;
280            log_("MKISOFS disc $i $mkisos->[$i]\n",$config->{verbose},$config->{LOG});
281            if (-x "/usr/bin/mkisofs"){
282                my $err = system $mkisos->[$i];
283                $err or print {$config->{LOG}} "ERROR: disc $i $mkisos->[$i] failed ($!)\n";
284                $size->{disc}[$i] = du("$topdir/iso/$name/$i-$name.iso")
285            }else{
286                print {$config->{LOG}} "WARNING: mkisofs is not installed on your system, to build the ISOs, install mkisofs and type the following command:
287$mkisos->[$i]\n "
288            }
289        }
290    }
291    1
292}
293
294sub checkSize{
295    my ($class, $n,$size,$cdsize,$rejected) = @_;
296    my $ok;
297    for (my $i; $i < @{$size->{disc}}; $i++) {
298        $size->{disc}[$i] or next;
299        my $origcdsize = $class->{config}{disc}[$i]{size};
300        if ($size->{disc}[$i] > $origcdsize) {
301            my $d = ($size->{disc}[$i] - $cdsize->[$i]);
302            if ($d > 0) { 
303                $ok = 0;
304                $cdsize->[$i] -= $d;
305                print {$config->{LOG}} "ERROR: disc $i is too big ($size->{disc}[$i] > $origcdsize (new disc size $cdsize->[$i])\n" }
306            }elsif ($rejected){
307                my $d = ($cdsize->[$i] - $size->{disc}[$i]);
308                if ($d > $origcdsize/300) { 
309                    $ok = 0;
310                    $cdsize->[$i] += $d;
311                    print {$config->{LOG}} "ERROR: disc $i is too small ($size->{disc}[$i] < $origcdsize (new disc size $cdsize->[$i])\n" }
312            }
313        }
314        return $ok
315}
316
3171
318
319# Changelog
320#
321# 2002 05 22
322#
323# fix a pb in graft_to_md5 that made dest incomplete when dest is a directory
Note: See TracBrowser for help on using the repository browser.