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