diff options
Diffstat (limited to 'perl-install/install/install2.pm')
-rw-r--r-- | perl-install/install/install2.pm | 693 |
1 files changed, 472 insertions, 221 deletions
diff --git a/perl-install/install/install2.pm b/perl-install/install/install2.pm index 8724fda52..7f6cbd6fe 100644 --- a/perl-install/install/install2.pm +++ b/perl-install/install/install2.pm @@ -1,11 +1,18 @@ -package install::install2; # $Id$ +package install::install2; use diagnostics; use strict; use vars qw($o); +use Getopt::Long qw(GetOptionsFromArray :config no_auto_abbrev no_getopt_compat pass_through); BEGIN { $::isInstall = 1 } +=head1 SYNOPSYS + +The installer stage2 real entry point + +=cut + #-###################################################################################### #- misc imports #-###################################################################################### @@ -26,19 +33,36 @@ use any; use log; use fs; use fs::any; - +use fs::mount; +use messages; #-####################################################################################### -#-$O -#-the big struct which contain, well everything (globals + the interactive methods ...) -#-if you want to do a kickstart file, you just have to add all the required fields (see for example -#-the variable $default) +=head1 Data Structure + +=head2 $O; + +$o (or $::o in other modules) is the big struct which contain, well everything: + +=over 4 + +=item * globals + +=item * the interactive methods + +=item * ... + +=back + +if you want to do a kickstart file, you just have to add all the required fields (see for example +the variable $default) + +=cut #-####################################################################################### $o = $::o = { # bootloader => { linear => 0, message => 1, timeout => 5, restricted => 0 }, #- packages => [ qw() ], partitioning => { clearall => 0, eraseBadPartitions => 0, auto_allocate => 0 }, #-, readonly => 0 }, - authentication => { blowfish => 1, shadow => 1 }, + authentication => { sha512 => 1, shadow => 1 }, locale => { lang => 'en_US' }, #- isUpgrade => 0, toRemove => [], @@ -65,7 +89,7 @@ $o = $::o = { #- eth0 => { DEVICE => "eth0", IPADDR => '1.2.3.4', NETMASK => '255.255.255.128' } #- }, }, - + untranslated_license => messages::main_license_raw(), #-step : the current one #-prefix #-mouse @@ -76,21 +100,40 @@ $o = $::o = { }; +=head1 Steps Navigation + +=over + +=cut sub installStepsCall { my ($o, $auto, $fun, @args) = @_; $fun = "install::steps::$fun" if $auto; $o->$fun(@args); } + +=item getNextStep($o) + +Returns next step + +=cut + sub getNextStep { my ($o) = @_; find { !$o->{steps}{$_}{done} && $o->{steps}{$_}{reachable} } @{$o->{orderedSteps}}; } #-###################################################################################### -#- Steps Functions -#- each step function are called with two arguments : clicked(because if you are a -#- beginner you can force the the step) and the entered number + +=back + +=head1 Steps Functions + +Each step function are called with two arguments : clicked(because if you are a +beginner you can force the the step) and the entered number + +=cut + #-###################################################################################### #------------------------------------------------------------------------------ @@ -116,7 +159,7 @@ sub selectMouse { sub setupSCSI { my ($auto) = @_; - installStepsCall($o, $auto, 'setupSCSI'); + installStepsCall($o, $auto, 'setupSCSI') if !$::local_install; } #------------------------------------------------------------------------------ @@ -151,6 +194,15 @@ sub selectInstallClass { sub doPartitionDisks { my ($auto) = @_; $o->{steps}{formatPartitions}{done} = 0; + if ($o->{method} eq 'cdrom') { + #- Exclude the installer medium from the devices we can install onto. + #- This is needed when the installer medium is a USB Flash drive, to + #- prevent the user inadvertently overwriting the installer and to + #- prevent the installer ESP being used as the installed system ESP + # (mga#26714). + my $installer_device = $o->{stage2_phys_medium}{device}; + @{$o->{all_hds}{hds}} = grep { $_->{device} ne $installer_device } @{$o->{all_hds}{hds}}; + } installStepsCall($o, $auto, 'doPartitionDisksBefore'); installStepsCall($o, $auto, 'doPartitionDisks'); installStepsCall($o, $auto, 'doPartitionDisksAfter'); @@ -170,13 +222,20 @@ sub formatPartitions { } installStepsCall($o, $auto, 'formatMountPartitions') if !$::testing; + # Workaround for mga#22059. Because stage2 does not include the udev 60-blocks.rule, + # udev does not automatically update the soft links in /dev/disk/by-uuid after we + # write the partition table and format the partitions. We need these links to be + # updated before we create the initrd. It would be cleaner to fix this with a udev + # rule, but for now, use brute force. + run_program::run('udevadm', 'trigger', '--type=devices', '--subsystem-match=block'); + if ($want_root_formated) { #- we formatted /, ensure /var/lib/rpm is cleaned otherwise bad things can happen #- (especially when /var is *not* formatted) eval { rm_rf("$::prefix/var/lib/rpm") }; } - fs::any::prepare_minimal_root($o->{all_hds}); + fs::any::prepare_minimal_root(); install::any::screenshot_dir__and_move(); install::any::move_compressed_image_to_disk($o); @@ -199,7 +258,8 @@ sub choosePackages { log::l("rpmsrate_flags_chosen's: ", join(' ', sort @flags)); #- check pre-condition that basesystem package must be selected. - install::pkgs::packageByName($o->{packages}, 'basesystem')->flag_available or die "basesystem package not selected"; + my $base_pkg = install::pkgs::packageByName($o->{packages}, 'basesystem'); + $base_pkg->flag_available or $base_pkg->flag_installed or die "basesystem package not selected"; #- check if there are packages that need installation. $o->{steps}{installPackages}{done} = 0 if $o->{steps}{installPackages}{done} && install::pkgs::packagesToInstall($o->{packages}) > 0; @@ -287,219 +347,422 @@ sub exitInstall { installStepsCall($o, $auto, 'exitInstall', getNextStep($::o) eq 'exitInstall'); } +#-###################################################################################### + +=head1 Udev Functions + +=over + +=cut #-###################################################################################### -#- MAIN + +=item start_udev() + +=cut + +sub start_udev() { + return if fuzzy_pidofs('udevd'); + + # Start up udev: + mkdir_p("/run/udev/rules.d"); + $ENV{UDEVRULESD} = "/run/udev/rules.d"; + run_program::run("/usr/lib/systemd/systemd-udevd", "--daemon", "--resolve-names=never"); + # Coldplug all devices: + run_program::run("udevadm", "trigger", "--type=subsystems", "--action=add"); + run_program::run("udevadm", "trigger", "--type=devices", "--action=add"); +} + +=item stop_udev() + +=cut + +sub stop_udev() { + kill 15, fuzzy_pidofs('udevd'); + sleep(2); + fs::mount::umount($_) foreach '/dev/pts', '/dev/shm'; +} + #-###################################################################################### -sub main { -#- $SIG{__DIE__} = sub { warn "DIE " . backtrace() . "\n" }; - $SIG{SEGV} = sub { - my $msg = "segmentation fault: install crashed (maybe memory is missing?)"; log::l($msg); - $o->ask_warn('', $msg); - setVirtual(1); - require install::steps_auto_install; - install::steps_auto_install_non_interactive::errorInStep($o, $msg); - }; - $ENV{PERL_BADLANG} = 1; - delete $ENV{TERMINFO}; - umask 022; - $::isWizard = 1; - $::no_ugtk_init = 1; +=back - push @::textdomains, 'DrakX', 'drakx-net', 'drakx-kbd-mouse-x11'; +=head1 Other Functions + +=over + +=cut + +#-###################################################################################### +sub init_local_install { + my ($o) = @_; + push @::auto_steps, +# 'selectLanguage', 'selectKeyboard', 'miscellaneous', 'selectInstallClass', + 'doPartitionDisks', 'formatPartitions'; + eval { fs::mount::sys_kernel_debug('') }; #- do it now so that when_load doesn't do it + $o->{nomouseprobe} = 1; + $o->{mouse} = mouse::fullname2mouse('Universal|Any PS/2 & USB mice'); +} + +sub pre_init_brltty() { + if (my ($s) = cat_("/proc/cmdline") =~ /brltty=(\S*)/) { + my ($driver, $device, $table) = split(',', $s); + $table = "text.$table.tbl" if $table !~ /\.tbl$/; + log::l("brltty option $driver $device $table"); + $o->{brltty} = { driver => $driver, device => $device, table => $table }; + $o->{interactive} = 'curses'; + $o->{nomouseprobe} = 1; + } +} + +sub init_brltty() { + symlink "/tmp/stage2/$_", $_ foreach "/etc/brltty"; + devices::make($_) foreach $o->{brltty}{device}; + run_program::run("brltty"); +} + +sub init_auto_install() { + if ($::auto_install =~ /-IP(\.pl)?$/) { + my ($ip) = cat_('/tmp/stage1.log') =~ /configuring device (?!lo)\S+ ip: (\S+)/; + my $normalized_ip = join('', map { sprintf "%02X", $_ } split('\.', $ip)); + $::auto_install =~ s/-IP(\.pl)?$/-$normalized_ip$1/; + } + require install::steps_auto_install; + eval { $o = $::o = install::any::loadO($o, $::auto_install) }; + if ($@) { + if ($o->{useless_thing_accepted}) { #- Pixel's hack to be able to fail through + log::l("error using auto_install, continuing"); + undef $::auto_install; + } else { + install::steps_auto_install_non_interactive::errorInStep($o, "Error using auto_install\n" . formatError($@)); + } + } else { + log::l("auto install config file loaded successfully"); + + #- normalize for people not using our special scheme + foreach (@{$o->{manualFstab} || []}) { + $_->{device} =~ s!^/dev/!!; + } + } +} + +sub step_init { + my ($o) = @_; + my $o_; + while (1) { + $o_ = $::auto_install ? + install::steps_auto_install->new($o) : + $o->{interactive} eq "stdio" ? + install::steps_stdio->new($o) : + $o->{interactive} eq "curses" ? + install::steps_curses->new($o) : + $o->{interactive} eq "gtk" ? + install::steps_gtk->new($o) : + die "unknown install type"; + $o_ and last; + + log::l("$o->{interactive} failed, trying again with curses"); + $o->{interactive} = "curses"; + require install::steps_curses; + } + $o; +} + +sub read_product_id() { + my $product_id = cat__(install::any::getFile_($o->{stage2_phys_medium}, "product.id")); + log::l('product_id: ' . chomp_($product_id)); + $o->{product_id} = common::parse_LDAP_namespace_structure($product_id); + + $o->{meta_class} ||= { + One => 'desktop', + Free => 'download', + Powerpack => 'powerpack', + }->{$o->{product_id}{product}} || 'download'; +} + +sub sig_segv_handler() { + my $msg = "segmentation fault: install crashed (maybe memory is missing?)\n" . backtrace(); + log::l("$msg\n"); + # perl_checker: require UNIVERSAL + UNIVERSAL::can($o, 'ask_warn') and $o->ask_warn('', $msg); + setVirtual(1); + require install::steps_auto_install; + install::steps_auto_install_non_interactive::errorInStep($o, $msg); +} + +=item read_stage1_net_conf() { + +Reads back netork configuration done by stage1 (see L<stages>). + +=cut + +sub read_stage1_net_conf() { + require network::network; + #- get stage1 network configuration if any. + log::l('found /tmp/network'); + add2hash($o->{net}{network} ||= {}, network::network::read_conf('/tmp/network')); + if (my ($file) = grep { -f $_ } glob_('/tmp/ifcfg-*')) { + log::l("found network config file $file"); + my $l = network::network::read_interface_conf($file); + $o->{net}{ifcfg}{$l->{DEVICE}} ||= $l; + } + my $dsl_device = find { $_->{BOOTPROTO} eq 'adsl_pppoe' } values %{$o->{net}{ifcfg}}; + if ($dsl_device) { + $o->{net}{type} = 'adsl'; + $o->{net}{net_interface} = $dsl_device->{DEVICE}; + $o->{net}{adsl} = { + method => 'pppoe', + device => $dsl_device->{DEVICE}, + ethernet_device => $dsl_device->{DEVICE}, + login => $dsl_device->{USER}, + password => $dsl_device->{PASS}, + }; + %$dsl_device = (); + } else { + $o->{net}{type} = 'lan'; + $o->{net}{net_interface} = first(values %{$o->{net}{ifcfg}}); + } +} + +=item parse_args($cfg, $patch) + +Parse arguments (which came from either the boot loader command line or its configuration file). + +=cut + +sub parse_args { my ($cfg, $patch); - my %cmdline = map { - my ($n, $v) = split /=/; - $n => defined($v) ? $v : 1; - } split ' ', cat_("/proc/cmdline"); - - my $opt; foreach (@_) { - if (/^--?(.*)/) { - $cmdline{$opt} = 1 if $opt; - $opt = $1; - } else { - $cmdline{$opt} = $_ if $opt; - $opt = ''; - } - } $cmdline{$opt} = 1 if $opt; + my @cmdline = (@_, map { "--$_" } split ' ', cat_("/proc/cmdline")); #- from stage1 put_in_hash(\%ENV, { getVarsFromSh('/tmp/env') }); - exists $ENV{$_} and $cmdline{lc($_)} = $ENV{$_} foreach qw(METHOD PCMCIA KICKSTART); - - map_each { - my ($n, $v) = @_; - my $f = ${{ - lang => sub { $o->{lang} = $v }, - flang => sub { $o->{lang} = $v; push @::auto_steps, 'selectLanguage' }, - langs => sub { $o->{locale}{langs} = +{ map { $_ => 1 } split(':', $v) } }, - method => sub { $o->{method} = $v }, - pcmcia => sub { $o->{pcmcia} = $v }, - vga16 => sub { $o->{vga16} = $v }, - vga => sub { $o->{vga} = $v =~ /0x/ ? hex($v) : $v }, - step => sub { $o->{steps}{first} = $v }, - meta_class => sub { $o->{meta_class} = $v }, - freedriver => sub { $o->{freedriver} = $v }, - no_bad_drives => sub { $o->{partitioning}{no_bad_drives} = 1 }, - nodmraid => sub { $o->{partitioning}{nodmraid} = 1 }, - readonly => sub { $o->{partitioning}{readonly} = $v ne "0" }, - display => sub { $o->{display} = $v }, - askdisplay => sub { print "Please enter the X11 display to perform the install on ? "; $o->{display} = chomp_(scalar(<STDIN>)) }, - security => sub { $o->{security} = $v }, - noauto => sub { $::noauto = 1 }, - testing => sub { $::testing = 1 }, - patch => sub { $patch = 1 }, - defcfg => sub { $cfg = $v }, - newt => sub { $o->{interactive} = "curses" }, - text => sub { $o->{interactive} = "curses" }, - stdio => sub { $o->{interactive} = "stdio" }, - use_uuid => sub { $::no_uuid_by_default = !$v }, - kickstart => sub { $::auto_install = $v }, - local_install => sub { $::local_install = 1 }, - uml_install => sub { $::uml_install = $::local_install = 1 }, - auto_install => sub { $::auto_install = $v }, - simple_themes => sub { $o->{simple_themes} = 1 }, - theme => sub { $o->{theme} = $v }, - doc => sub { $o->{doc} = 1 }, #- will be used to know that we're running for the doc team, - #- e.g. we want screenshots with a good B&W contrast - useless_thing_accepted => sub { $o->{useless_thing_accepted} = 1 }, + exists $ENV{$_} and push @cmdline, sprintf("--%s=%s", lc($_), $ENV{$_}) foreach qw(METHOD PCMCIA KICKSTART); + + GetOptionsFromArray(\@cmdline, + $o, # must be 2nd parameter (see http://perldoc.perl.org/Getopt/Long.html#Storing-options-values-in-a-hash) + 'keyboard=s' => sub { $o->{keyboard} = $_[1]; push @::auto_steps, 'selectKeyboard' }, + 'lang=s', + 'flang=s' => sub { $o->{lang} = $_[1]; push @::auto_steps, 'selectLanguage' }, + 'langs=s' => sub { $o->{locale}{langs} = +{ map { $_ => 1 } split(':', $_[1]) } }, + 'method=s', + 'pcmcia=s', + 'step=s' => \$o->{steps}{first}, + 'meta_class=s', + 'freedriver=s', + + # fs/block options: + no_bad_drives => \$o->{partitioning}{no_bad_drives}, + nodmraid => \$o->{partitioning}{nodmraid}, + 'readonly=s' => sub { $o->{partitioning}{readonly} = $_[1] ne "0" }, + 'use_uuid=s' => sub { $::no_uuid_by_default = !$_[1] }, + + # urpmi options: + 'debug_urpmi', + 'deploops', + 'justdb', + 'tune-rpm' => sub { $o->{'tune-rpm'} = 'all' }, + 'downloader=s' => sub { $o->{options}{downloader} = $_[1] }, + + # GUI options: + 'vga16=s', + 'vga=s' => sub { $o->{vga} = $_[1] =~ /0x/ ? hex($_[1]) : $_[1] }, + 'display=s', + askdisplay => sub { print "Please enter the X11 display to perform the install on ? "; $o->{display} = chomp_(scalar(<STDIN>)) }, + 'newt|text' => sub { $o->{interactive} = "curses" }, + stdio => sub { $o->{interactive} = "stdio" }, + 'simple_themes', + 'theme=s', + 'doc', #- will be used to know that we're running for the doc team, + #- e.g. we want screenshots with a good B&W contrast + + 'security=s', + + # auto install options: + noauto => \$::noauto, + testing => \$::testing, + patch => \$patch, + 'defcfg=s' => \$cfg, + 'auto_install|kickstart=s' => \$::auto_install, + + local_install => \$::local_install, + uml_install => sub { $::uml_install = $::local_install = 1 }, + + # debugging options: + 'useless_thing_accepted', alawindows => sub { $o->{security} = 0; $o->{partitioning}{clearall} = 1; $o->{bootloader}{crushMbr} = 1 }, - fdisk => sub { $o->{partitioning}{fdisk} = 1 }, - rpm_dbapi => sub { $o->{rpm_dbapi} = $v }, - nomouseprobe => sub { $o->{nomouseprobe} = $v }, - updatemodules => sub { $o->{updatemodules} = 1 }, - suppl => sub { $o->{supplmedia} = $v }, - askmedia => sub { $o->{askmedia} = 1 }, - restore => sub { $::isRestore = 1 }, - }}{lc $n}; &$f if $f; - } %cmdline; + fdisk => \$o->{partitioning}{fdisk}, + 'nomouseprobe=s', + 'updatemodules', + 'suppl=s' => \$o->{supplmedia}, + 'askmedia', + restore => \$::isRestore, + 'compssListLevel=s' # case is important! + ); + + ($cfg, $patch); +} + +sub init_env_share() { if ($::testing) { $ENV{SHARE_PATH} ||= "/export/install/stage2/live/usr/share"; $ENV{SHARE_PATH} = "/usr/share" if !-e $ENV{SHARE_PATH}; } else { $ENV{SHARE_PATH} ||= "/usr/share"; } +} + +sub init_path() { + #- make sure we do not pick up any gunk from the outside world + my $remote_path = "$::prefix/sbin:$::prefix/bin:$::prefix/usr/sbin:$::prefix/usr/bin"; + $ENV{PATH} = "/usr/bin:/bin:/sbin:/usr/sbin:$remote_path"; +} + +sub init_mouse() { + eval { $o->{mouse} = mouse::detect($o->{modules_conf}) } if !$o->{mouse} && !$o->{nomouseprobe}; + mouse::load_modules($o->{mouse}); +} + +sub init_modules_conf() { + list_modules::load_default_moddeps(); + require modules::any_conf; + require modules::modules_conf; + # read back config from stage1: + $o->{modules_conf} = modules::modules_conf::read(modules::any_conf::vnew(), '/tmp/modules.conf'); + modules::read_already_loaded($o->{modules_conf}); +} + +sub process_auto_steps() { + foreach (@::auto_steps) { + if (my $s = $o->{steps}{/::(.*)/ ? $1 : $_}) { + $s->{auto} = $s->{hidden} = 1; + } else { + log::l("ERROR: unknown step $_ in auto_steps"); + } + } +} + +=item process_patch($cfg, $patch) + +Handle installer live patches: + +=over 4 + +=item * OEM patch (C<install/patch-oem.pl>) + +=item * defcfg (the file indicated by the defcfg option) + +=item * patch (C<patch> file) + +=back + +=cut + +sub process_patch { + my ($cfg, $patch) = @_; + #- oem patch should be read before to still allow patch or defcfg. + eval { $o = $::o = install::any::loadO($o, "install/patch-oem.pl"); log::l("successfully read oem patch") }; + #- patch should be read after defcfg in order to take precedence. + eval { $o = $::o = install::any::loadO($o, $cfg); log::l("successfully read default configuration: $cfg") } if $cfg; + eval { $o = $::o = install::any::loadO($o, "patch"); log::l("successfully read patch") } if $patch; +} + +#-###################################################################################### + +=item main() + +This is the main function, the installer entry point called by runinstall2: + +=over 4 + +=item * initialization + +=item * steps + +=back + +=cut +#-###################################################################################### +sub main { + $SIG{SEGV} = \&sig_segv_handler; + $ENV{PERL_BADLANG} = 1; + delete $ENV{TERMINFO}; + umask 022; + + $::isWizard = 1; + $::no_ugtk_init = 1; + + push @::textdomains, 'DrakX', 'drakx-net', 'drakx-kbd-mouse-x11'; + + my ($cfg, $patch) = parse_args(@_); + + init_env_share(); undef $::auto_install if $cfg; $o->{stage2_phys_medium} = install::media::stage2_phys_medium($o->{method}); - log::l("second stage install running (", install::any::drakx_version($o), ")"); + if (-e '/tmp/media/DATE.txt') { + my @mount_entry = grep { m,/tmp/media, } cat_('/proc/mounts'); + my @mount_fields = split(/ /, $mount_entry[0]); + log::l(run_program::get_stdout('blkid', '-s', 'LABEL', $mount_fields[0])); + log::l('ISO date: ' . cat_('/tmp/media/DATE.txt')); + } + + install::any::log_system_info($o); - eval { output('/proc/sys/kernel/modprobe', "\n") } if !$::local_install && !$::testing; #- disable kmod - eval { fs::mount::mount('none', '/sys', 'sysfs', 1) }; eval { touch('/root/non-chrooted-marker.DrakX') }; #- helps distinguishing /root and /mnt/root when we don't know if we are chrooted if ($::local_install) { - push @::auto_steps, -# 'selectLanguage', 'selectKeyboard', 'miscellaneous', 'selectInstallClass', - 'doPartitionDisks', 'formatPartitions'; - fs::mount::usbfs(''); #- do it now so that when_load doesn't do it - $o->{nomouseprobe} = 1; - $o->{mouse} = mouse::fullname2mouse('Universal|Any PS/2 & USB mice'); + init_local_install($o); + } else { + start_udev(); + # load some modules early but asynchronously: + run_program::raw({ detach => 1 }, 'modprobe', 'microcode'); } $o->{prefix} = $::prefix = $::testing ? "/tmp/test-perl-install" : "/mnt"; - mkdir $::prefix, 0755; + mkdir $::prefix, 0755 if ! -d $::prefix; - #- make sure we do not pick up any gunk from the outside world - my $remote_path = "$::prefix/sbin:$::prefix/bin:$::prefix/usr/sbin:$::prefix/usr/bin:$::prefix/usr/X11R6/bin"; - $ENV{PATH} = "/usr/bin:/bin:/sbin:/usr/sbin:/usr/X11R6/bin:$remote_path"; + init_path(); eval { install::any::spawnShell() }; - list_modules::load_default_moddeps(); - require modules::any_conf; - require modules::modules_conf; - $o->{modules_conf} = modules::modules_conf::read(modules::any_conf::vnew(), '/tmp/modules.conf'); - modules::read_already_loaded($o->{modules_conf}); + init_modules_conf(); #- done before auto_install is called to allow the -IP feature on auto_install file name - if (-e '/tmp/network') { - require network::network; - #- get stage1 network configuration if any. - log::l('found /tmp/network'); - add2hash($o->{net}{network} ||= {}, network::network::read_conf('/tmp/network')); - if (my ($file) = glob_('/tmp/ifcfg-*')) { - log::l("found network config file $file"); - my $l = network::network::read_interface_conf($file); - $o->{net}{ifcfg}{$l->{DEVICE}} ||= $l; - } - my $dsl_device = find { $_->{BOOTPROTO} eq 'adsl_pppoe' } values %{$o->{net}{ifcfg}}; - if ($dsl_device) { - $o->{net}{type} = 'adsl'; - $o->{net}{net_interface} = $dsl_device->{DEVICE}; - $o->{net}{adsl} = { - method => 'pppoe', - device => $dsl_device->{DEVICE}, - ethernet_device => $dsl_device->{DEVICE}, - login => $dsl_device->{USER}, - password => $dsl_device->{PASS}, - }; - %$dsl_device = (); - } else { - $o->{net}{type} = 'lan'; - $o->{net}{net_interface} = first(values %{$o->{net}{ifcfg}}); - } - } + read_stage1_net_conf() if -e '/tmp/network'; #- done after module dependencies are loaded for "vfat depends on fat" if ($::auto_install) { - if ($::auto_install =~ /-IP(\.pl)?$/) { - my ($ip) = cat_('/tmp/stage1.log') =~ /configuring device (?!lo)\S+ ip: (\S+)/; - my $normalized_ip = join('', map { sprintf "%02X", $_ } split('\.', $ip)); - $::auto_install =~ s/-IP(\.pl)?$/-$normalized_ip$1/; - } - require install::steps_auto_install; - eval { $o = $::o = install::any::loadO($o, $::auto_install) }; - if ($@) { - if ($o->{useless_thing_accepted}) { #- Pixel's hack to be able to fail through - log::l("error using auto_install, continuing"); - undef $::auto_install; - } else { - install::steps_auto_install_non_interactive::errorInStep($o, "Error using auto_install\n" . formatError($@)); - } - } else { - log::l("auto install config file loaded successfully"); - - #- normalize for people not using our special scheme - foreach (@{$o->{manualFstab} || []}) { - $_->{device} =~ s!^/dev/!!; - } - } + init_auto_install(); + } else { + $o->{interactive} ||= 'gtk'; } - $o->{interactive} ||= 'gtk' if !$::auto_install; if ($o->{interactive} eq "gtk" && availableMemory() < 22 * 1024) { log::l("switching to curses install cuz not enough memory"); $o->{interactive} = "curses"; } - if (my ($s) = cat_("/proc/cmdline") =~ /brltty=(\S*)/) { - my ($driver, $device, $table) = split(',', $s); - $table = "text.$table.tbl" if $table !~ /\.tbl$/; - log::l("brltty option $driver $device $table"); - $o->{brltty} = { driver => $driver, device => $device, table => $table }; - $o->{interactive} = 'curses'; - $o->{nomouseprobe} = 1; - } + pre_init_brltty(); # perl_checker: require install::steps_gtk # perl_checker: require install::steps_curses # perl_checker: require install::steps_stdio require "install/steps_$o->{interactive}.pm" if $o->{interactive}; + # psmouse is now modular: + eval { modules::load("psmouse") }; + + #- FIXME loading evdev should prevent crash of following line + eval { modules::load("evdev") }; + #- needed before accessing floppy (in case of usb floppy) modules::load_category($o->{modules_conf}, 'bus/usb'); - #- oem patch should be read before to still allow patch or defcfg. - eval { $o = $::o = install::any::loadO($o, "install/patch-oem.pl"); log::l("successfully read oem patch") }; - #- patch should be read after defcfg in order to take precedance. - eval { $o = $::o = install::any::loadO($o, $cfg); log::l("successfully read default configuration: $cfg") } if $cfg; - eval { $o = $::o = install::any::loadO($o, "patch"); log::l("successfully read patch") } if $patch; + process_patch($cfg, $patch); eval { modules::load("af_packet") }; @@ -507,18 +770,10 @@ sub main { harddrake::sound::configure_sound_slots($o->{modules_conf}); #- need to be after oo-izing $o - if ($o->{brltty}) { - symlink "/tmp/stage2/$_", $_ foreach "/etc/brltty"; - devices::make($_) foreach $o->{brltty}{device} ? $o->{brltty}{device} : qw(ttyS0 ttyS1); - devices::make("vcsa"); - run_program::run("brltty"); - } + init_brltty() if $o->{brltty}; #- needed very early for install::steps_gtk - if (!$::testing) { - eval { $o->{mouse} = mouse::detect($o->{modules_conf}) } if !$o->{mouse} && !$o->{nomouseprobe}; - mouse::load_modules($o->{mouse}); - } + init_mouse() if !$::testing; #- for auto_install compatibility with old $o->{lang}, #- and also for --lang and --flang @@ -532,60 +787,41 @@ sub main { $o->{allowFB} = listlength(cat_("/proc/fb")); - if (!$::testing) { - my $product_id = cat__(install::any::getFile_($o->{stage2_phys_medium}, "product.id")); - log::l('product_id: ' . chomp_($product_id)); - $o->{product_id} = common::parse_LDAP_namespace_structure($product_id); - - $o->{meta_class} ||= { - One => 'desktop', - Free => 'download', - Powerpack => 'powerpack', - }->{$o->{product_id}{product}} || 'download'; - } + read_product_id() if !$::testing; log::l("META_CLASS=$o->{meta_class}"); - $ENV{META_CLASS} = $o->{meta_class}; #- for Ia Ora - foreach (@::auto_steps) { - if (my $s = $o->{steps}{/::(.*)/ ? $1 : $_}) { - $s->{auto} = $s->{hidden} = 1; - } else { - log::l("ERROR: unknown step $_ in auto_steps"); - } - } + process_auto_steps(); - my $o_; - while (1) { - $o_ = $::auto_install ? - install::steps_auto_install->new($o) : - $o->{interactive} eq "stdio" ? - install::steps_stdio->new($o) : - $o->{interactive} eq "curses" ? - install::steps_curses->new($o) : - $o->{interactive} eq "gtk" ? - install::steps_gtk->new($o) : - die "unknown install type"; - $o_ and last; - - log::l("$o->{interactive} failed, trying again with curses"); - $o->{interactive} = "curses"; - require install::steps_curses; - } - $::o = $o = $o_; + $ENV{COLUMNS} ||= 80; + $ENV{LINES} ||= 25; + $::o = $o = step_init($o); eval { output('/proc/splash', "verbose\n") }; - #-the main cycle + real_main(); + finish_install(); +} + +=item real_main() { + +Go through the steps cycle + +=cut + +sub real_main() { MAIN: for ($o->{step} = $o->{steps}{first};; $o->{step} = getNextStep($o)) { $o->{steps}{$o->{step}}{entered}++; $o->enteringStep($o->{step}); + my $time = time(); eval { &{$install::install2::{$o->{step}}}($o->{steps}{$o->{step}}{auto}); }; my $err = $@; + log::l("step \"$o->{step}\" took: ", formatTimeRaw(time() - $time)); $o->kill_action; if ($err) { + log::l("step \"$o->{step}\" failed with error: $err"); local $_ = $err; $o->kill_action; if (!/^already displayed/) { @@ -603,6 +839,15 @@ sub main { last if $o->{step} eq 'exitInstall'; } +} + +=item finish_install() { + +Clean up the installer before the final reboot. + +=cut + +sub finish_install() { unlink $install::any::compressed_image_on_disk; install::media::clean_postinstall_rpms(); install::media::log_sizes(); @@ -616,7 +861,8 @@ sub main { #- make sure failed upgrade will not hurt too much. install::steps::cleanIfFailedUpgrade($o); - -e "$::prefix/usr/sbin/urpmi.update" or eval { rm_rf("$::prefix/var/lib/urpmi") }; + #- drop urpmi DB if urpmi is not installed: + -e "$::prefix/usr/sbin/urpmi" or eval { rm_rf("$::prefix/var/lib/urpmi") }; system("chroot", $::prefix, "bash", "-c", $o->{postInstallBeforeReboot}) if $o->{postInstallBeforeReboot}; @@ -626,9 +872,14 @@ sub main { #- ala pixel? :-) [fpons] common::sync(); common::sync(); + stop_udev() if !$::local_install; log::l("installation complete, leaving"); log::l("files still open by install2: ", readlink($_)) foreach glob_("/proc/self/fd/*"); print "\n" x 80 if !$::local_install; } +=back + +=cut + 1; |