package Mkcd::Disc; my $VERSION = '0.0.2'; use strict; use File::Path; use Mkcd::Functions; use Mkcd::Tools qw(du); =head1 NAME Disc - mkcd disc functions =head1 SYNOPSYS require Mkcd::Disc; =head1 DESCRIPTION C include the mkcd disc handling subroutines. =head1 SEE ALSO mkcd =head1 COPYRIGHT Copyright (C) 2000,2001 MandrakeSoft This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =cut my $config; sub new { my ($class, $conf) = @_; $config = $conf; bless { config => $conf, functions => new Mkcd::Functions($config) }, $class; } # FIXME must add space for synthesis, however they are negligeable compared to hdlist. Only # a pb with very small CD. sub guessHdlistSize{ my ($class,$group,$size,$cdsize,$lists,$discsFiles) = @_; my $FACTOR = 125; my $SynFACTOR = 90; my $depsRep = "$config->{tmp}/$class->{config}{name}/$group->{depsrep}"; print {$config->{LOG}} "guessHdlistSize: depsRep $depsRep\n"; # FIXME heuristic for hdlist size on installation disc, (RPMS size / $FACTOR) per discs my $depsSize = du("$depsRep"); my $instdisc = $group->{installDisc}; my $sz; # keeping curdone outside the list loop could correct the mis value if multiple reps on one discs my %curdone; my @notdone; foreach my $list (keys %{$group->{list}}){ if ($config->{list}[$list]{auto}){ if ($config->{list}[$list]{cd}){ my $tsize = ($config->{discsize}/$FACTOR) * $config->{list}[$list]{cd}; $sz += $tsize < $depsSize ? $tsize : $depsSize; }else { $sz += $depsSize } }else { my $ok; my $listsize = $group->{listsize}{$list}{rpm}; foreach my $rd (@{$group->{list}{$list}{rpm}}){ my ($cdrep,undef,undef,$opt) = @$rd; if ($opt->{nodeps}) { $ok = 1; next } $curdone{$cdrep} and next; $curdone{$cdrep} = 1; if ($lists->{$cdrep}){ if ($listsize > $cdsize->[$cdrep]){ $sz += $cdsize->[$cdrep] / $FACTOR; $listsize -= $cdsize->[$cdrep]; }else{ $sz += $listsize / $FACTOR; last } } } $ok and push @notdone, $list } } print {$config->{LOG}} "guessHdlistSize: reserving "; if ($depsSize < $sz){ print {$config->{LOG}} "$depsSize"; $size->{disc}[$instdisc] += $depsSize; if ($config->{disc}[$instdisc]{function}{data}{installation}[1]{synthesis}) { $size->{disc}[$instdisc] += $depsSize / $SynFACTOR } } else { print {$config->{LOG}} "$sz"; $size->{disc}[$instdisc] += $sz ; if ($config->{disc}[$instdisc]{function}{data}{installation}[1]{synthesis}) { $size->{disc}[$instdisc] += $depsSize / $SynFACTOR } } print {$config->{LOG}} " (new size $size->{disc}[$instdisc]) on disc $instdisc ($depsSize/$sz) for dependencies files\n"; @notdone or return 1; my $sz; foreach my $list (@notdone){ foreach my $rd (@{$group->{list}{$list}{rpm}}){ my ($cd,$rep,$repopt,$opt) = @$rd; if ($lists->{$cd} == 1){ $sz += du("$class-{config}{topdir}/build/$class->{config}{name}/$cd/$class->{config}{disc}[$cd]{function}{data}{dir}{$rep}") }elsif ($lists->{$cd} == 2){ foreach my $rpm (keys %{$discsFiles->[$cd]{$rep}{$list}}){ $sz += du("$discsFiles->[$cd]{$rep}{$list}{$rpm}/$rpm.rpm") } } } } $sz /= $FACTOR; print {$config->{LOG}} "guessHdlistSize: reserving "; print {$config->{LOG}} "$sz"; $size->{disc}[$instdisc] += $sz; if ($config->{disc}[$instdisc]{function}{data}{installation}[1]{synthesis}) { $size->{disc}[$instdisc] += $sz / $SynFACTOR } print {$config->{LOG}} " (new size $size->{disc}[$instdisc]) on disc $instdisc ($sz) for extra dependencies files\n" } sub getBuiltDiscs{ my ($class, $lists, $group, $discsFiles) = @_; foreach my $l (keys %{$group->{list}}){ my @rpmlist; ref $group->{list}{$l}{rpm} and push @rpmlist, @{$group->{list}{$l}{rpm}}; ref $group->{list}{$l}{srpm} and push @rpmlist, @{$group->{list}{$l}{srpm}}; for (my $i; $i < @rpmlist; $i++){ my ($cd,$rep,$repopt) = @{$rpmlist[$i]}; $lists->{$cd} == 1 or next; my $dir = "$class->{config}{topdir}/build/$class->{config}{name}/$cd/$class->{config}{disc}[$cd]{function}{data}{dir}{$rep}"; # # FIXME maybe need to unshift instead of push # $repopt->{source} or push @{$class->{config}{list}[$l]{packages}}, [$dir]; $class->{config}{list}[$l]{disc}{$cd}{$rep}{done} = 1; print {$config->{LOG}} "getBuiltDiscs: get files from $dir\n"; local *A; opendir A,$dir; foreach (readdir A){ /(.*)\.rpm/ or next; # FIXME need to check if it is well placed in getList function # $group->{done}{$rpm} = $group->{orderedrep}{"$cd/$rep"}; $discsFiles->[$cd]{$rep}{$l}{$1} = $dir } } } 1 } sub makeDiscs { my ($class, $fixed, $lists, $cds, $size, $mkisos, $discsFile, $cdfile) = @_; my $dir; my $name = $class->{config}{name}; my $topdir = $class->{config}{topdir}; my $tmp = "$config->{tmp}/build/$name"; if (!$class->{config}{nolive}){ $dir = "$topdir/build/$name"; -d "$dir" or mkpath "$dir"; -d $tmp or mkpath $tmp; }else{ $dir = "$config->{tmp}/build/$name"; -d "$dir" or mkpath "$dir"; } print {$config->{LOG}} "makeDiscs: Discs @$cds TOPDIR $dir\n"; foreach my $i (@$cds){ $lists->{$i} > 1 or next; my $cd = $class->{config}{disc}[$i]; if (!$fixed){ print {$config->{LOG}} "makeDisc: Fixed part of disc $i\n"; if ($class->{config}{nolive}){ print {$config->{LOG}} "makeDisc: removing $dir/$i.list\n"; -f "$dir/$i.list" and unlink "$dir/$i.list"; print {$config->{LOG}} "makeDisc: removing $dir/$i\n"; rmtree "$dir/$i"; }else{ -d "$tmp/$i" or mkpath "$tmp/$i"; rmtree "$topdir/build/$name/$i"; rmtree "$topdir/build/$name/first/$i" } }else {print {$config->{LOG}} "Finalizing disc $i\n"} my $sz; for (my $j; $j < @{$cd->{steps}}; $j++){ my $name = $cd->{steps}[$j][0]; print {$config->{LOG}} "makeDiscs: $name ($fixed)\n"; 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,$discsFile)} else {print {$config->{LOG}} "ERROR: unrecognized function name $name\n"} print {$config->{LOG}} "SIZE ($name) $sz\n"; } if ($class->{config}{nolive}){ print {$config->{LOG}} "SIZE $size->{disc}[$i] + $sz\n"; $size->{disc}[$i] += $sz }else{ $size->{disc}[$i] = du("$dir/$i") + $sz } print {$config->{LOG}} "disc $i ($dir/$i) size: $size->{disc}[$i] ($sz)\n"; my $mkisoopt = $class->{config}{mkisoopt}; if ($fixed) { my $isodir = $class->{config}{isodir} ? $class->{config}{isodir} : "$topdir/iso/$name"; if ($class->{config}{nolive}){ $mkisos->[$i] = "mkisofs $mkisoopt -graft-points " . (-f "$dir/$i.list" ? " -path-list $dir/$i.list " : "") . " -V $cd->{serial} -o $isodir/$i-$name.iso $mkisos->[$i]" }else{ if ($mkisos->[$i]) { $mkisos->[$i] = "mkisofs $mkisoopt -V $cd->{serial} -o $isodir/$i-$name.iso $mkisos->[$i]"} else { $mkisos->[$i] = qq|mkisofs $mkisoopt -V $cd->{serial} -o "$isodir/$i-$name".iso "$dir/$i"|} } } } !$fixed and return 1; if (!$class->{config}{noiso}){ -d "$topdir/iso/$name" or mkpath "$topdir/iso/$name"; foreach my $i (@$cds){ $lists->{$i} > 1 or next; print {$config->{LOG}} "MKISOFS disc $i $mkisos->[$i]\n"; if (-x "/usr/bin/mkisofs"){ my $err = system $mkisos->[$i]; $err or print {$config->{LOG}} "ERROR: disc $i $mkisos->[$i] failed ($!)\n"; $size->{disc}[$i] = du("$topdir/iso/$name/$i-$name.iso") }else{ print {$config->{LOG}} "WARNING: mkisofs is not installed on your system, to build the ISOs, install mkisofs and type the following command: $mkisos->[$i]\n " } } } 1 } sub checkSize{ my ($class, $n,$size,$cdsize,$rejected) = @_; my $ok; for (my $i; $i < @{$size->{disc}}; $i++) { $size->{disc}[$i] or next; my $origcdsize = $class->{config}{disc}[$i]{size}; if ($size->{disc}[$i] > $origcdsize) { my $d = ($size->{disc}[$i] - $cdsize->[$i]); if ($d > 0) { $ok = 0; $cdsize->[$i] -= $d; print {$config->{LOG}} "ERROR: disc $i is too big ($size->{disc}[$i] > $origcdsize (new disc size $cdsize->[$i])\n" } }elsif ($rejected){ my $d = ($cdsize->[$i] - $size->{disc}[$i]); if ($d > $origcdsize/1000) { $ok = 0; $cdsize->[$i] += $d; print {$config->{LOG}} "ERROR: disc $i is too small ($size->{disc}[$i] < $origcdsize (new disc size $cdsize->[$i])\n" } } } return $ok } 1