source: soft/build_system/build_system/mkcd/tags/V3_0_4_1mdk/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.8 KB
Line 
1package Mkcd::Disc;
2
3my $VERSION = '0.1.1';
4
5use strict;
6use File::Path;
7use Mkcd::Functions;
8use Mkcd::Tools qw(du compute_md5 log_ include_md5);
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    $sz = 0;
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            log_("getBuiltDiscs: get files from $dir\n",1,$config->{LOG});
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    log_("write_graft: $file ($graft)\n",1,$config->{LOG}); 
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    log_("graft_to_md5: $serial -> $dir/$mdfile ($graft)\n",1,$config->{LOG}); 
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    log_("makeDiscs: Discs @$cds TOPDIR $dir\n",1,$config->{LOG});
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            log_("makeDisc: Fixed part of disc $i\n",1,$config->{LOG});
229            if ($class->{config}{nolive}){
230                log_("makeDisc: removing $dir/$i.list\n",1,$config->{LOG});
231                -f "$dir/$i.list" and unlink "$dir/$i.list";
232                log_("makeDisc: removing $dir/$i\n",1,$config->{LOG});
233                rmtree "$dir/$i";
234                mkdir "$dir/$i"
235            }else{
236                -d "$tmp/$i" or mkpath "$tmp/$i";
237                for ("$topdir/build/$name/$i","$topdir/build/$name/first/$i") { rmtree $_; mkdir $_ } 
238            }
239        } else { log_("Finalizing disc $i\n",1,$config->{LOG}) }
240        my $sz;
241        for (my $j; $j < @{$cd->{steps}}; $j++){
242            my $name = $cd->{steps}[$j][0];
243            log_("makeDiscs: $name ($fixed)\n",1,$config->{LOG});
244            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)}
245            else {log_("ERROR: unrecognized function name $name\n",1,$config->{LOG})}
246            log_("SIZE ($name) $sz\n",$config->{verbose},$config->{LOG});
247        }
248        if ($class->{config}{nolive}){
249            log_("SIZE $size->{disc}[$i] + $sz\n",$config->{verbose},$config->{LOG});
250            $size->{disc}[$i] += $sz
251        }else{
252            $size->{disc}[$i] = du("$dir/$i") + $sz
253        }
254        log_("disc $i ($dir/$i) size: $size->{disc}[$i] ($sz)\n",$config->{verbose},$config->{LOG});
255        my $mkisoopt = $class->{config}{mkisoopt};
256        if ($fixed) {
257            my $isodir = $class->{config}{isodir} ? $class->{config}{isodir} : "$topdir/iso/$name";
258            $graft->{$i}{".rr_moved"} = 0;
259            if ($config->{nolive}){
260                # include_md5 replaces md5 per files
261                #graft_to_md5($graft->{$i},"$dir/$i",$cd->{serial});
262                write_graft($graft->{$i},"$dir/$i.list");
263                $mkisos->[$i] = "mkisofs $mkisoopt -A \"$cd->{appname}\" -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                # include_md5 replaces md5 per files
267                #graft_to_md5($graft->{$i},"$dir/$i",$cd->{serial});
268                if ($mkisos->[$i]) { 
269                    $mkisos->[$i] = "mkisofs $mkisoopt -A \"$cd->{appname}\" -V \"$cd->{serial}\" -o $isodir/$i-$name.iso $mkisos->[$i] $dir/$i"
270                } else { 
271                    $mkisos->[$i] = qq|mkisofs $mkisoopt -A \"$cd->{appname}\" -V \"$cd->{serial}\" -o "$isodir/$i-$name".iso "$dir/$i"|
272                }
273            }
274        }
275    }
276    !$fixed and return 1;
277    if (!$class->{config}{noiso}){
278        -d "$topdir/iso/$name" or mkpath "$topdir/iso/$name"; 
279        foreach my $i (@$cds){
280            $lists->{$i} > 1 or next;
281            log_("MKISOFS disc $i $mkisos->[$i]\n",$config->{verbose},$config->{LOG});
282            my $err = system $mkisos->[$i];
283            if (!$err){ 
284                log_("ERROR: disc $i $mkisos->[$i] failed ($!)\n",1,$config->{LOG});
285                print { $config->{LOG} } "WARNING: a problem may have appear, if ISOs files are not OK and you want to retry to build the ISOs, type the following command:
286                $mkisos->[$i]\n "
287            }
288            include_md5("$topdir/iso/$name/$i-$name.iso",1);
289            $size->{disc}[$i] = du("$topdir/iso/$name/$i-$name.iso")
290        }
291    }
292    1
293}
294
295sub checkSize{
296    my ($class, $n,$size,$cdsize,$rejected) = @_;
297    my $ok;
298    for (my $i; $i < @{$size->{disc}}; $i++) {
299        $size->{disc}[$i] or next;
300        my $origcdsize = $class->{config}{disc}[$i]{size};
301        if ($size->{disc}[$i] > $origcdsize) {
302            my $d = ($size->{disc}[$i] - $cdsize->[$i]);
303            if ($d > 0) { 
304                $ok = 0;
305                $cdsize->[$i] -= $d;
306                log_("ERROR: disc $i is too big ($size->{disc}[$i] > $origcdsize (new disc size $cdsize->[$i])\n",1,$config->{LOG}) }
307            }elsif ($rejected){
308                my $d = ($cdsize->[$i] - $size->{disc}[$i]);
309                if ($d > $origcdsize/300) { 
310                    $ok = 0;
311                    $cdsize->[$i] += $d;
312                    log_("ERROR: disc $i is too small ($size->{disc}[$i] < $origcdsize (new disc size $cdsize->[$i])\n",1,$config->{LOG}) }
313            }
314        }
315        return $ok
316}
317
3181
319
320# Changelog
321#
322# 2002 05 22
323#
324# 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.