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; | 
