package install_any;# $Id$use diagnostics;use strict;use vars qw(@ISA%EXPORT_TAGS@EXPORT_OK@needToCopy@needToCopyIfRequiresSatisfied);@ISA=qw(Exporter);%EXPORT_TAGS= (
all => [qw(getNextStep spawnShell addToBeDone)],);@EXPORT_OK=map{@$_}values%EXPORT_TAGS;#-#######################################################################################- misc imports#-######################################################################################use common qw(:common :system :functional :file);use run_program;use partition_table qw(:types);use partition_table_raw;use devices;use fsedit;use modules;use detect_devices;use lang;use any;uselog;use fs;#- package that have to be copied for proper installation (just to avoid changing cdrom)#- here XFree86 is copied entirey if not already installed, maybe better to copy only server.@needToCopy=qw(XFree86-8514 XFree86-AGX XFree86-Mach32 XFree86-Mach64 XFree86-Mach8 XFree86-MonoXFree86-P9000 XFree86-S3 XFree86-S3V XFree86-SVGA XFree86-W32 XFree86-I128XFree86-Sun XFree86-SunMono XFree86-Sun24 XFree86-3DLabs XFree86-FBDev XFree86-serverXFree86 XFree86-glide-module Device3Dfx Glide_V3-DRI Glide_V5 Mesadhcpcd pump dhcpxd dhcp-client isdn4net isdn4k-utils dev pptp-adsl-fr rp-pppoe ppp ypbindrhs-printfilters lpr cups cups-drivers samba ncpfs ghostscript-utils);#- package that have to be copied only if all their requires are satisfied.@needToCopyIfRequiresSatisfied=qw(xpp kups kisdn);#-#######################################################################################- Media change variables&functions#-######################################################################################my$postinstall_rpms='';my$current_medium=1;my$asked_medium=1;my$cdrom=undef;sub useMedium($) {#- before ejecting the first CD, there are some files to copy!#- does nothing if the function has already been called.$_[0] >1and$::o->{method}eq'cdrom'and setup_postinstall_rpms($::o->{prefix}, $::o->{packages});$asked_mediumeq$_[0]or log::l("selecting new medium '$_[0]'");$asked_medium=$_[0];}sub changeMedium($$) {my($method, $medium) =@_;log::l("change to medium$mediumfor method$method(refused by default)");0;}sub relGetFile($) {local$_=$_[0];
m|\.rpm$| ? "$::o->{packages}[2]{$asked_medium}{rpmsdir}/$_":$_;}sub askChangeMedium($$) {my($method, $medium) =@_;my$allow;do{eval{$allow= changeMedium($method, $medium) };}while($@);#- really it is not allowed to die in changeMedium!!! or install will cores with rpmlib!!!$allow;}sub errorOpeningFile($) {my($file) =@_;$fileeq'XXX'andreturn;#- special case to force closing file after rpmlib transaction.$current_mediumeq$asked_mediumand log::l("errorOpeningFile$file"),return;#- nothing to do in such case.$::o->{packages}[2]{$asked_medium}{selected}orreturn;#- not selected means no need for worying about.my$max=32;#- always refuse after $max tries.if($::o->{method}eq"cdrom") {
cat_("/proc/mounts") =~ m|(/tmp/\S+)\s+/tmp/rhimage|and$cdrom=$1;return unless$cdrom;
ejectCdrom($cdrom);while($max>0&& askChangeMedium($::o->{method},$asked_medium)) {$current_medium=$asked_medium;eval{ fs::mount($cdrom,"/tmp/rhimage","iso9660",'readonly') };my$getFile= getFile($file);$getFileandreturn$getFile;$current_medium='unknown';#- don't know what CD is inserted now.
ejectCdrom($cdrom);--$max;}}else{while($max>0&& askChangeMedium($::o->{method},$asked_medium)) {$current_medium=$asked_medium;my$getFile= getFile($file);$getFileandreturn$getFile;$current_medium='unknown';#- don't know what CD image has been copied.--$max;}}#- keep in mind the asked medium has been refused on this way.#- this means it is no more selected.$::o->{packages}[2]{$asked_medium}{selected} =undef;#- on cancel, we can expect the current medium to be undefined too,#- this enable remounting if selecting a package back.$current_medium='unknown';return;}sub getFile {my($f, $method) =@_;my$rel= relGetFile($f);log::l("getFile$f($method) relGetFile$rel");do{if($method=~/crypto/i) {require crypto;log::l("crypto::getFile$f");
crypto::getFile($f);}elsif($::o->{method}eq"ftp") {require ftp;
ftp::getFile($rel);}elsif($::o->{method}eq"http") {require http;log::l("http getFile$f");
http::getFile($rel);}else{#- try to open the file, but examine if it is present in the repository, this allow#- handling changing a media when some of the file on the first CD has been copied#- to other to avoid media change...my$f2="$postinstall_rpms/$f";$f2="/tmp/rhimage/$rel"unless$postinstall_rpms&& -e $f2;log::l("local getFile$f2");open GETFILE,$f2and*GETFILE;}} || errorOpeningFile($f);}sub getAndSaveFile {my($file, $local) =@_;log::l("getAndSaveFile$file$local");local*F;open F,">$local"orreturn;local$/= \ (16*1024);my$f=ref($file) ? $file: getFile($file)orreturn;local$_;while(<$f>) {syswrite F,$_}1;}#-#######################################################################################- Post installation RPMS from cdrom only, functions#-######################################################################################sub setup_postinstall_rpms($$) {my($prefix, $packages) =@_;$postinstall_rpmsandreturn;$postinstall_rpms="$prefix/usr/postinstall-rpm";require pkgs;require commands;log::l("postinstall rpms directory set to$postinstall_rpms");
clean_postinstall_rpms();#- make sure in case of previous upgrade problem.
commands::mkdir_('-p',$postinstall_rpms);#- compute closure of unselected package that may be copied,#- don't complain if package does not exists as it may happen#- for the various architecture taken into account (X servers).my%toCopy;foreach(@needToCopy) {my$pkg= pkgs::packageByName($packages, $_);
pkgs::selectPackage($packages, $pkg,0, \%toCopy)if$pkg;}@toCopy{@needToCopyIfRequiresSatisfied} = ();my@toCopy=map{ pkgs::packageByName($packages, $_) }keys%toCopy;#- extract headers of package, this is necessary for getting#- the complete filename of each package.#- copy the package files in the postinstall RPMS directory.#- last arg is default medium '' known as the CD#1.
pkgs::extractHeaders($prefix, \@toCopy, $packages->[2]{1});
commands::cp((map{"/tmp/rhimage/". relGetFile(pkgs::packageFile($_)) }@toCopy),$postinstall_rpms);}sub clean_postinstall_rpms() {require commands;$postinstall_rpmsand-d $postinstall_rpmsand commands::rm('-rf',$postinstall_rpms);}#-#######################################################################################- Functions#-######################################################################################sub kernelVersion {my($o) =@_;local$_=readlink("$::o->{prefix}/boot/vmlinuz")andreturn first(/vmlinuz-(.*)/);require pkgs;my$p= pkgs::packageByName($o->{packages},"kernel")or die"I couldn't find the kernel package!";
pkgs::packageVersion($p) ."-". pkgs::packageRelease($p);}sub getNextStep {my($s) = $::o->{steps}{first};$s= $::o->{steps}{$s}{next}while$::o->{steps}{$s}{done} || !$::o->{steps}{$s}{reachable};$s;}sub spawnShell {return if$::o->{localInstall} || $::testing;-x "/bin/sh"or die"cannot open shell - /usr/bin/sh doesn't exist";fork andreturn;local*F;sysopen F,"/dev/tty2",2or die"cannot open /dev/tty2 -- no shell will be provided";open STDIN,"<&F"or die'';open STDOUT,">&F"or die'';open STDERR,">&F"or die'';close F;
c::setsid();ioctl(STDIN, c::TIOCSCTTY(),0)or warn"could not set new controlling tty:$!";exec{"/bin/sh"}"-/bin/sh"or log::l("exec of /bin/sh failed:$!");}sub fsck_option {my($o) =@_;my$y=$o->{security} <3&& $::beginner ? "-y ":"";
substInFile {s/^(\s*fsckoptions="?)(-y )?/$1$y/}"$o->{prefix}/etc/rc.d/rc.sysinit";}sub getAvailableSpace {my($o) =@_;#- make sure of this place to be available for installation, this could help a lot.#- currently doing a very small install use 36Mb of postinstall-rpm, but installing#- these packages may eat up to 90Mb (of course not all the server may be installed!).#- 65mb may be a good choice to avoid almost all problem of insuficient space left...my$minAvailableSize=65* sqr(1024);my$n= !$::testing && getAvailableSpace_mounted($o->{prefix}) ||
getAvailableSpace_raw($o->{fstab}) *512/1.07;$n- max(0.1*$n, $minAvailableSize);}sub getAvailableSpace_mounted {