diff options
Diffstat (limited to 'perl-install/install_any.pm')
-rw-r--r-- | perl-install/install_any.pm | 236 |
1 files changed, 177 insertions, 59 deletions
diff --git a/perl-install/install_any.pm b/perl-install/install_any.pm index 9fb467cfa..3e88c58ed 100644 --- a/perl-install/install_any.pm +++ b/perl-install/install_any.pm @@ -1,6 +1,5 @@ package install_any; # $Id$ -use diagnostics; use strict; use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK $boot_medium $current_medium $asked_medium @advertising_images); @@ -38,6 +37,13 @@ $asked_medium = $boot_medium; #-###################################################################################### my $postinstall_rpms = ''; my $cdrom; + +sub mountCdrom($;$) { + my ($mountpoint, $cdrom_) = @_; + $cdrom_ = $cdrom if !defined $cdrom_; + eval { fs::mount($cdrom_, $mountpoint, "iso9660", 'readonly') }; +} + sub useMedium($) { #- before ejecting the first CD, there are some files to copy! #- does nothing if the function has already been called. @@ -60,37 +66,43 @@ sub relGetFile($) { $_; } sub askChangeMedium($$) { - my ($method, $medium) = @_; + my ($method, $medium_name) = @_; my $allow; do { - eval { $allow = changeMedium($method, $medium) }; + local $::o->{method} = $method = 'cdrom' if $medium_name =~ /^\d+s$/; #- Suppl CD + eval { $allow = changeMedium($method, $medium_name) }; } while $@; #- really it is not allowed to die in changeMedium!!! or install will cores with rpmlib!!! - log::l($allow ? "accepting medium $medium" : "refusing medium $medium"); + log::l($allow ? "accepting medium $medium_name" : "refusing medium $medium_name"); $allow; } + +sub method_allows_medium_change($) { $_[0] eq "cdrom" } + sub errorOpeningFile($) { my ($file) = @_; $file eq 'XXX' and return; #- special case to force closing file after rpmlib transaction. $current_medium eq $asked_medium and log::l("errorOpeningFile $file"), return; #- nothing to do in such case. - $::o->{packages}{mediums}{$asked_medium}{selected} or return; #- not selected means no need for worying about. + $::o->{packages}{mediums}{$asked_medium}{selected} or return; #- not selected means no need to worry about. + my $current_method = $::o->{packages}{mediums}{$asked_medium}{method} || $::o->{method}; my $max = 32; #- always refuse after $max tries. - if ($::o->{method} eq "cdrom") { - cat_("/proc/mounts") =~ m,(/(?:dev|tmp)/\S+)\s+(?:/mnt/cdrom|/tmp/image), and $cdrom = $1; + if ($current_method eq "cdrom") { + cat_("/proc/mounts") =~ m,(/(?:dev|tmp)/\S+)\s+(/mnt/cdrom|/tmp/image), + and ($cdrom, my $mountpoint) = ($1, $2); return unless $cdrom; - ejectCdrom($cdrom); - while ($max > 0 && askChangeMedium($::o->{method}, $asked_medium)) { + ejectCdrom($cdrom, $mountpoint); + while ($max > 0 && askChangeMedium($current_method, $asked_medium)) { $current_medium = $asked_medium; - eval { fs::mount($cdrom, "/tmp/image", "iso9660", 'readonly') }; + mountCdrom("/tmp/image"); my $getFile = getFile($file); $getFile && @advertising_images and copy_advertising($::o); $getFile and return $getFile; $current_medium = 'unknown'; #- don't know what CD is inserted now. - ejectCdrom($cdrom); + ejectCdrom($cdrom, $mountpoint); --$max; } } else { - while ($max > 0 && askChangeMedium($::o->{method}, $asked_medium)) { + while ($max > 0 && askChangeMedium($current_method, $asked_medium)) { $current_medium = $asked_medium; my $getFile = getFile($file); $getFile and return $getFile; $current_medium = 'unknown'; #- don't know what CD image has been copied. @@ -98,19 +110,24 @@ sub errorOpeningFile($) { } } + #- Don't unselect supplementary CDs. + return if $asked_medium =~ /^\d+s$/; + #- keep in mind the asked medium has been refused on this way. #- this means it is no more selected. $::o->{packages}{mediums}{$asked_medium}{selected} = undef; #- on cancel, we can expect the current medium to be undefined too, - #- this enable remounting if selecting a package back. + #- this enables remounting if selecting a package back. $current_medium = 'unknown'; return; } + sub getFile { - my ($f, $o_method) = @_; - log::l("getFile $f:$o_method"); + my ($f, $o_method, $o_altroot) = @_; + my $current_method = ($asked_medium ? $::o->{packages}{mediums}{$asked_medium}{method} : '') || $::o->{method}; + log::l("getFile $f:$o_method ($asked_medium:$current_method)"); my $rel = relGetFile($f); do { if ($f =~ m|^http://|) { @@ -119,22 +136,25 @@ sub getFile { } elsif ($o_method =~ /crypto|update/i) { require crypto; crypto::getFile($f); - } elsif ($::o->{method} eq "ftp") { + } elsif ($current_method eq "ftp") { require ftp; ftp::getFile($rel); - } elsif ($::o->{method} eq "http") { + } elsif ($current_method eq "http") { require http; - http::getFile("$ENV{URLPREFIX}/$rel"); + http::getFile(($ENV{URLPREFIX} || $o_altroot) . "/$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... + #- try to open the file, but examine if it is present in the repository, + #- this allows handling changing a media when some of the files on the + #- first CD have been copied to other to avoid media change... my $f2 = "$postinstall_rpms/$f"; - $f2 = "/tmp/image/$rel" if !$postinstall_rpms || !-e $f2; - my $F; open($F, $f2) && $F; + $o_altroot ||= '/tmp/image'; + $f2 = "$o_altroot/$rel" if $rel !~ m,^/, && (!$postinstall_rpms || !-e $f2); + $f2 = "/$rel" if !$::o->{packages}{mediums}{$asked_medium}{rpmsdir} && !-e $f2; + my $F; open($F, $f2) ? $F : do { $f2 !~ /XXX/ and log::l("Can't open $f2: $!"); undef } } } || errorOpeningFile($f); } + sub getAndSaveFile { my ($file, $local) = @_ == 1 ? ("Mandrake/mdkinst$_[0]", $_[0]) : @_; local $/ = \ (16 * 1024); @@ -282,12 +302,89 @@ sub preConfigureTimezone { add2hash_($o->{timezone}, { UTC => $utc, ntp => $ntp }); } +sub ask_if_suppl_media { + my ($o) = @_; + return $o->ask_yesorno('', N("Do you have a supplementary CD to install?"), 0) ? "CD-ROM" : "None"; +} + +sub selectSupplMedia { + my ($o, $suppl_method) = @_; + #- ask whether there are supplementary media + my $prev_asked_medium = $asked_medium; + if ($suppl_method && (my $suppl = ask_if_suppl_media($o)) ne 'None') { + #- translate to method name + $suppl_method = 'cdrom'; + #- by convention, the media names for suppl. CDs match /^\d+s$/ + my $medium_name = (max(map { $_->{medium} =~ /^(\d+)s$/ ? $1 : 0 } values %{$o->{packages}{mediums}}) + 1) . "s"; + local $::isWizard = 0; + my $main_method = $o->{method}; + local $o->{method} = $suppl_method; + (my $cdromdev) = detect_devices::cdroms(); + $o->ask_warn('', N("No device found")), return 'error' if !$cdromdev; + $cdrom = $cdromdev->{device}; + devices::make($cdrom); + ejectCdrom($cdrom); + if ($o->ask_okcancel('', N("Insert the CD"), 1)) { + #- mount suppl CD in /mnt/cdrom to avoid umounting /tmp/image + mountCdrom("/mnt/cdrom", $cdrom); + log::l($@) if $@; + useMedium($medium_name); + + #- probe for an hdlists file and then look for all hdlists listed herein + eval { pkgs::psUsingHdlists($o, $suppl_method, "/mnt/cdrom", $o->{packages}, $medium_name) }; + log::l("psUsingHdlists failed: $@") if $@; + + #- copy latest compssUsers and rpmsrate somewhere locally + getAndSaveFile("/mnt/cdrom/Mandrake/base/compssUsers", "/tmp/compssUsers"); + getAndSaveFile("/mnt/cdrom/Mandrake/base/compssUsers.$o->{meta_class}", "/tmp/compssUsers.$o->{meta_class}"); + getAndSaveFile("/mnt/cdrom/Mandrake/base/rpmsrate", "/tmp/rpmsrate"); + + #- umount supplementary CD. Will re-ask for it later + getFile("XXX"); #- close still opened filehandles + log::l("Umounting suppl. CD, back to medium 1"); + eval { fs::umount("/mnt/cdrom") }; + #- re-mount CD 1 if this was a cdrom install + if ($main_method eq 'cdrom') { + eval { + my $dev = detect_devices::tryOpen($cdrom); + ioctl($dev, c::CDROMEJECT(), 1); + }; + $o->ask_warn('', N("Insert the CD 1 again")); + mountCdrom("/tmp/image", $cdrom); + log::l($@) if $@; + $asked_medium = 1; + } + } + } else { + $suppl_method = ''; + } + useMedium($prev_asked_medium); #- back to main medium + return $suppl_method; +} + +sub load_rate_files { + my ($o) = @_; + #- must be done after getProvides + #- if there is a supplementary media, the rpmsrate/compssUsers are overridable + pkgs::read_rpmsrate( + $o->{packages}, + getFile(-e "/tmp/rpmsrate" ? "/tmp/rpmsrate" : "Mandrake/base/rpmsrate") + ); + ($o->{compssUsers}, $o->{compssUsersSorted}) = pkgs::readCompssUsers( + $o->{meta_class}, + -e '/tmp/compssUsers' || -e "/tmp/compssUsers.$o->{meta_class}" ? '/tmp/compssUsers' : 'Mandrake/base/compssUsers' + ); +} + sub setPackages { my ($o, $rebuild_needed) = @_; require pkgs; if (!$o->{packages} || is_empty_array_ref($o->{packages}{depslist})) { - $o->{packages} = pkgs::psUsingHdlists($o->{prefix}, $o->{method}); + my $cdrom; + ($o->{packages}, my $suppl_method) = pkgs::psUsingHdlists($o, $o->{method}); + + $suppl_method = $o->selectSupplMedia($suppl_method); #- open rpm db according to right mode needed. $o->{packages}{rpmdb} ||= pkgs::rpmDbOpen($o->{prefix}, $rebuild_needed); @@ -300,13 +397,12 @@ sub setPackages { pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, 'basesystem') || die("missing basesystem package"), 1); - #- must be done after getProvides - pkgs::read_rpmsrate($o->{packages}, getFile("Mandrake/base/rpmsrate")); - ($o->{compssUsers}, $o->{compssUsersSorted}) = pkgs::readCompssUsers($o->{meta_class}); + load_rate_files($o); #- preselect default_packages and compssUsersChoices. setDefaultPackages($o); pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, $_) || next) foreach @{$o->{default_packages}}; + } else { #- this has to be done to make sure necessary files for urpmi are #- present. @@ -380,11 +476,10 @@ sub setDefaultPackages { detect_devices::matching_desc('[nN][vV]idia.*Quadro'); - foreach (lang::langs($o->{locale}{langs}), substr(lang::c2locale($o->{locale}{country}), 0, 2)) { - unshift @{$o->{default_packages}}, map { $_->name } pkgs::packagesProviding($o->{packages}, "locales-$_"); - } - foreach (lang::langs($o->{locale}{langs}), #- mainly for zh in case of zh_TW.Big5 - lang::langsLANGUAGE($o->{locale}{langs})) { + my @locale_pkgs = map { pkgs::packagesProviding($o->{packages}, 'locales-' . $_) } lang::langsLANGUAGE($o->{locale}{langs}); + unshift @{$o->{default_packages}}, uniq(map { $_->name } @locale_pkgs); + + foreach (lang::langsLANGUAGE($o->{locale}{langs})) { $o->{compssUsersChoice}{qq(LOCALES"$_")} = 1; } $o->{compssUsersChoice}{'CHARSET"' . lang::l2charset($o->{locale}{lang}) . '"'} = 1; @@ -464,20 +559,20 @@ sub unlockCdrom(;$) { $cdrom or cat_("/proc/mounts") =~ m,(/(?:dev|tmp)/\S+)\s+(?:/mnt/cdrom|/tmp/image), and $cdrom = $1; eval { $cdrom and ioctl detect_devices::tryOpen($1), c::CDROM_LOCKDOOR(), 0 }; } -sub ejectCdrom(;$) { - my ($cdrom) = @_; +sub ejectCdrom { + my ($o_cdrom, $o_mountpoint) = @_; getFile("XXX"); #- close still opened filehandle - $cdrom ||= $1 if cat_("/proc/mounts") =~ m,(/(?:dev|tmp)/\S+)\s+(?:/mnt/cdrom|/tmp/image),; - if ($cdrom) { - #- umount BEFORE opening the cdrom device otherwise the umount will - #- D state if the cdrom is already removed - eval { fs::umount("/tmp/image") }; - if ($@) { log::l("files still open: ", readlink($_)) foreach map { glob_("$_/fd/*") } glob_("/proc/*") } - eval { - my $dev = detect_devices::tryOpen($cdrom); - ioctl($dev, c::CDROMEJECT(), 1) if ioctl($dev, c::CDROM_DRIVE_STATUS(), 0) == c::CDS_DISC_OK(); - }; - } + my $cdrom = $o_cdrom || cat_("/proc/mounts") =~ m!(/(?:dev|tmp)/\S+)\s+(/mnt/cdrom|/tmp/image)! && $1 or return; + $o_mountpoint ||= $2 || '/tmp/image'; + + #- umount BEFORE opening the cdrom device otherwise the umount will + #- D state if the cdrom is already removed + eval { fs::umount($o_mountpoint) }; + if ($@) { log::l("files still open: ", readlink($_)) foreach map { glob_("$_/fd/*") } glob_("/proc/*") } + eval { + my $dev = detect_devices::tryOpen($cdrom); + ioctl($dev, c::CDROMEJECT(), 1) if ioctl($dev, c::CDROM_DRIVE_STATUS(), 0) == c::CDS_DISC_OK(); + }; } sub setupFB { @@ -502,6 +597,7 @@ sub install_urpmi { #- rare case where urpmi cannot be installed (no hd install path). $method eq 'disk' && !any::hdInstallPath() and return; + log::l("install_urpmi $method"); #- clean to avoid opening twice the rpm db. delete $packages->{rpmdb}; @@ -529,7 +625,8 @@ sub install_urpmi { cdrom => "removable://mnt/cdrom" }}{$method} || #- for live_update or live_install script. readlink("/tmp/image/Mandrake") =~ m,^(/.*)/Mandrake/*$, && "removable:/$1") . "/$_->{rpmsdir}"; - my $need_list = $dir =~ m,^(?:[^:]*://[^/:\@]*:[^/:\@]+\@|.*%{),; #- use list file only if visible password or macro. + #- use list file only if visible password or macro. + my $need_list = $dir =~ m,^(?:[^:]*://[^/:\@]*:[^/:\@]+\@|.*%{),; #- } #- build a list file if needed. if ($need_list) { @@ -537,7 +634,7 @@ sub install_urpmi { open(my $LIST, ">$prefix/var/lib/urpmi/list.$name") or log::l("failed to write list.$name"); umask $mask; - #- build list file using internal data, synthesis file should exists. + #- build list file using internal data, synthesis file should exist. if ($_->{end} > $_->{start}) { #- WARNING this method of build only works because synthesis (or hdlist) #- has been read. @@ -581,7 +678,7 @@ sub install_urpmi { } else { $with = $_->{rpmsdir}; $with =~ s|/[^/]*%{ARCH}.*||; - $with =~ s|/+|/|g; $with =~ s|/$||; $with =~ s|[^/]||g; $with =~ s|/|../|g; + $with =~ s|/+|/|g; $with =~ s|/$||; $with =~ s|[^/]||g; $with =~ s!/!../!g; $with .= "../Mandrake/base/$_->{hdlist}"; } @@ -598,6 +695,7 @@ sub install_urpmi { "; } else { #- remove not selected media by removing hdlist and synthesis files copied. + log::l("removing media $name"); unlink "$prefix/var/lib/urpmi/hdlist.$name.cz"; unlink "$prefix/var/lib/urpmi/synthesis.hdlist.$name.cz"; } @@ -775,12 +873,6 @@ sub getAndSaveAutoInstallFloppies { my $dev = devices::set_loop($img) or log::l("couldn't set loopback device"), return; find { eval { fs::mount($dev, $mountdir, $_, 0); 1 } } qw(ext2 vfat) or return; - if (@imgs == 1 || $img =~ /drivers/) { - local $o->{partitioning}{clearall} = !$replay; - eval { output("$mountdir/auto_inst.cfg", g_auto_install($replay)) }; - $@ and log::l("Warning: <", formatError($@), ">"); - } - if (-e "$mountdir/menu.lst") { # hd_grub boot disk is different than others substInFile { @@ -788,17 +880,25 @@ sub getAndSaveAutoInstallFloppies { s/\bautomatic=method:disk/$param/; } "$mountdir/menu.lst"; } elsif (-e "$mountdir/syslinux.cfg") { + #- make room first + unlink "$mountdir/help.msg", "$mountdir/boot.msg"; + substInFile { s/timeout.*/$replay ? 'timeout 1' : ''/e; s/^(\s*append)/$1 $param/ } "$mountdir/syslinux.cfg"; - unlink "$mountdir/help.msg"; - output "$mountdir/boot.msg", "\n0c", + output "$mountdir/boot.msg", $replay ? '' : "\n0c" . "!! If you press enter, an auto-install is going to start. All data on this computer is going to be lost, including any Windows partitions !! -", "07\n" if !$replay; +" . "07\n"; + } + + if (@imgs == 1 || $img =~ /drivers/) { + local $o->{partitioning}{clearall} = !$replay; + eval { output("$mountdir/auto_inst.cfg", g_auto_install($replay)) }; + $@ and log::l("Warning: <", formatError($@), ">"); } fs::umount($mountdir); @@ -962,8 +1062,18 @@ sub find_root_parts { if ($s) { chomp($s); $s =~ s/\s+for\s+\S+//; - log::l("find_root_parts found $_->{device}: $s"); - { release => $s, part => $_ }; + my $oem_file = "$handle->{dir}/etc/sysconfig/oem"; + my $t; + if (-f $oem_file) { + my $oem = cat_($oem_file); + my ($company) = $oem =~ /company=(.*)/i; + my ($system) = $oem =~ /system=(.*)/i; + my ($product) = $oem =~ /product=(.*)/i; + $t = "$company $system $product" + } + $t ||= $s; + log::l("find_root_parts found $_->{device}: $s ($t) file $oem_file"); + { release => $t, real_release => $s, part => $_ }; } else { () } } @$fstab; } @@ -1027,6 +1137,14 @@ sub log_sizes { formatXiB(sum(run_program::rooted_get_stdout($o->{prefix}, 'rpm', '-qa', '--queryformat', '%{size}\n')))) if -x "$o->{prefix}/bin/rpm"; } +sub X_options_from_o { + my ($o) = @_; + { + freedriver => $o->{freedriver}, + allowFB => $o->{allowFB}, + }; +} + sub copy_advertising { my ($o) = @_; |