summaryrefslogtreecommitdiffstats
path: root/perl-install/install_any.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/install_any.pm')
-rw-r--r--perl-install/install_any.pm236
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) = @_;