summaryrefslogtreecommitdiffstats
path: root/perl-install/install/install2.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/install/install2.pm')
-rw-r--r--perl-install/install/install2.pm885
1 files changed, 885 insertions, 0 deletions
diff --git a/perl-install/install/install2.pm b/perl-install/install/install2.pm
new file mode 100644
index 000000000..7f6cbd6fe
--- /dev/null
+++ b/perl-install/install/install2.pm
@@ -0,0 +1,885 @@
+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
+#-######################################################################################
+use install::steps_list;
+use common;
+use install::any 'addToBeDone';
+use install::steps;
+use install::any;
+use lang;
+use keyboard;
+use mouse;
+use devices;
+use partition_table;
+use modules;
+use detect_devices;
+use run_program;
+use any;
+use log;
+use fs;
+use fs::any;
+use fs::mount;
+use messages;
+
+#-#######################################################################################
+=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 => { sha512 => 1, shadow => 1 },
+ locale => { lang => 'en_US' },
+#- isUpgrade => 0,
+ toRemove => [],
+ toSave => [],
+#- simple_themes => 1,
+
+ timezone => {
+#- timezone => "Europe/Paris",
+#- UTC => 1,
+ },
+#- superuser => { password => 'a', shell => '/bin/bash', realname => 'God' },
+#- user => { name => 'foo', password => 'bar', home => '/home/foo', shell => '/bin/bash', realname => 'really, it is foo' },
+
+#- keyboard => 'de',
+#- display => "192.168.1.19:1",
+ steps => \%install::steps_list::installSteps,
+ orderedSteps => \@install::steps_list::orderedInstallSteps,
+
+ #- for the list of fields available, see network/network.pm
+ net => {
+ #- network => { HOSTNAME => 'abcd' },
+ #- resolv => { DOMAINNAME => 'foo.xyz' },
+ #- ifcfg => {
+ #- 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
+#-keyboard
+#-netc
+#-methods
+#-packages compss
+
+};
+
+=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}};
+}
+
+#-######################################################################################
+
+=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
+
+#-######################################################################################
+
+#------------------------------------------------------------------------------
+sub selectLanguage {
+ my ($auto) = @_;
+ installStepsCall($o, $auto, 'selectLanguage');
+}
+
+sub acceptLicense {
+ my ($auto) = @_;
+ installStepsCall($o, $auto, 'acceptLicense');
+}
+
+#------------------------------------------------------------------------------
+sub selectMouse {
+ my ($auto) = @_;
+ installStepsCall($o, $auto, 'selectMouse');
+
+ addToBeDone { mouse::write($o->do_pkgs, $o->{mouse}) if !$o->{isUpgrade} } 'installPackages';
+}
+
+#------------------------------------------------------------------------------
+sub setupSCSI {
+ my ($auto) = @_;
+
+ installStepsCall($o, $auto, 'setupSCSI') if !$::local_install;
+}
+
+#------------------------------------------------------------------------------
+sub selectKeyboard {
+ my ($auto) = @_;
+
+ my $force;
+ if (my $keyboard = keyboard::read()) {
+ $o->{keyboard} = $keyboard; #- for uprade
+ } elsif ($o->{isUpgrade}) {
+ #- oops, the keyboard config is wrong, forcing prompt and writing
+ $force = 1;
+ }
+
+ installStepsCall($o, $auto, 'selectKeyboard', $force);
+}
+
+#------------------------------------------------------------------------------
+sub selectInstallClass {
+ my ($auto) = @_;
+
+ installStepsCall($o, $auto, 'selectInstallClass');
+
+ if ($o->{isUpgrade}) {
+ @{$o->{orderedSteps}} = uniq(map {
+ $_ eq 'selectInstallClass' ? ($_, 'doPartitionDisks', 'formatPartitions') : $_;
+ } @{$o->{orderedSteps}});
+ }
+}
+
+#------------------------------------------------------------------------------
+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');
+}
+
+sub formatPartitions {
+ my ($auto) = @_;
+
+ $o->{steps}{choosePackages}{done} = 0;
+ installStepsCall($o, $auto, 'choosePartitionsToFormat') if !$o->{isUpgrade} && !$::local_install;
+ my $want_root_formated = fs::get::root($o->{fstab})->{toFormat};
+ if ($want_root_formated) {
+ foreach ('/usr') {
+ my $part = fs::get::mntpoint2part($_, $o->{fstab}) or next;
+ $part->{toFormat} or die N("You must also format %s", $_);
+ }
+ }
+ 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();
+
+ install::any::screenshot_dir__and_move();
+ install::any::move_compressed_image_to_disk($o);
+
+ any::rotate_logs($::prefix);
+
+ require raid;
+ raid::write_conf($o->{all_hds}{raids});
+}
+
+#------------------------------------------------------------------------------
+sub choosePackages {
+ my ($auto) = @_;
+ require install::pkgs;
+
+ #- always setPackages as it may have to copy hdlist and synthesis files.
+ installStepsCall($o, $auto, 'setPackages');
+ installStepsCall($o, $auto, 'choosePackages');
+ my @flags = map_each { if_($::b, $::a) } %{$o->{rpmsrate_flags_chosen}};
+ log::l("rpmsrate_flags_chosen's: ", join(' ', sort @flags));
+
+ #- check pre-condition that basesystem package must be 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;
+}
+
+#------------------------------------------------------------------------------
+sub installPackages {
+ my ($auto) = @_;
+
+ installStepsCall($o, $auto, 'beforeInstallPackages');
+ installStepsCall($o, $auto, 'installPackages');
+ installStepsCall($o, $auto, 'afterInstallPackages');
+}
+#------------------------------------------------------------------------------
+sub miscellaneous {
+ my ($auto) = @_;
+
+ installStepsCall($o, $auto, 'miscellaneousBefore');
+ installStepsCall($o, $auto, 'miscellaneous');
+ installStepsCall($o, $auto, 'miscellaneousAfter');
+}
+
+#------------------------------------------------------------------------------
+sub summary {
+ my ($auto) = @_;
+ installStepsCall($o, $auto, 'summaryBefore') if $o->{steps}{summary}{entered} == 1;
+ installStepsCall($o, $auto, 'summary');
+ installStepsCall($o, $auto, 'summaryAfter');
+}
+#------------------------------------------------------------------------------
+sub configureNetwork {
+ my ($auto) = @_;
+ #- get current configuration of network device.
+ require network::network;
+ eval { network::network::read_net_conf($o->{net}) };
+ modules::load_category($o->{modules_conf}, list_modules::ethernet_categories());
+ require network::connection::ethernet;
+ if (!$o->{isUpgrade}) {
+ installStepsCall($o, $auto, 'configureNetwork');
+ } else {
+ network::connection::ethernet::configure_eth_aliases($o->{modules_conf});
+ }
+}
+#------------------------------------------------------------------------------
+sub installUpdates {
+ my ($auto) = @_;
+ installStepsCall($o, $auto, 'installUpdates');
+}
+#------------------------------------------------------------------------------
+sub configureServices {
+ my ($auto) = @_;
+ installStepsCall($o, $auto, 'configureServices');
+}
+#------------------------------------------------------------------------------
+sub setRootPassword_addUser {
+ my ($auto) = @_;
+
+ installStepsCall($o, $auto, 'setRootPassword_addUser') if !$o->{isUpgrade};
+}
+
+#------------------------------------------------------------------------------
+sub setupBootloader {
+ my ($auto) = @_;
+ return if $::local_install;
+
+ $o->{modules_conf}->write;
+
+ installStepsCall($o, $auto, 'setupBootloaderBefore');
+ installStepsCall($o, $auto, 'setupBootloader');
+}
+#------------------------------------------------------------------------------
+sub configureX {
+ my ($auto) = @_;
+
+ #- done here and also at the end of install2.pm, just in case...
+ install::any::write_fstab($o);
+ $o->{modules_conf}->write;
+
+ require install::pkgs;
+ installStepsCall($o, $auto, 'configureX') if !$::testing && eval { install::pkgs::packageByName($o->{packages}, 'task-x11')->flag_installed } && !$o->{X}{disabled};
+}
+#------------------------------------------------------------------------------
+sub exitInstall {
+ my ($auto) = @_;
+ installStepsCall($o, $auto, 'exitInstall', getNextStep($::o) eq 'exitInstall');
+}
+
+#-######################################################################################
+
+=head1 Udev Functions
+
+=over
+
+=cut
+
+#-######################################################################################
+
+=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';
+}
+
+#-######################################################################################
+
+=back
+
+=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 { "--$_" } split ' ', cat_("/proc/cmdline"));
+
+ #- from stage1
+ put_in_hash(\%ENV, { getVarsFromSh('/tmp/env') });
+ 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 => \$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});
+
+ 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 { touch('/root/non-chrooted-marker.DrakX') }; #- helps distinguishing /root and /mnt/root when we don't know if we are chrooted
+
+ if ($::local_install) {
+ 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 if ! -d $::prefix;
+
+ init_path();
+
+ eval { install::any::spawnShell() };
+
+ init_modules_conf();
+
+ #- done before auto_install is called to allow the -IP feature on auto_install file name
+ read_stage1_net_conf() if -e '/tmp/network';
+
+ #- done after module dependencies are loaded for "vfat depends on fat"
+ if ($::auto_install) {
+ init_auto_install();
+ } else {
+ $o->{interactive} ||= 'gtk';
+ }
+
+ if ($o->{interactive} eq "gtk" && availableMemory() < 22 * 1024) {
+ log::l("switching to curses install cuz not enough memory");
+ $o->{interactive} = "curses";
+ }
+
+ 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');
+
+ process_patch($cfg, $patch);
+
+ eval { modules::load("af_packet") };
+
+ require harddrake::sound;
+ harddrake::sound::configure_sound_slots($o->{modules_conf});
+
+ #- need to be after oo-izing $o
+ init_brltty() if $o->{brltty};
+
+ #- needed very early for install::steps_gtk
+ init_mouse() if !$::testing;
+
+ #- for auto_install compatibility with old $o->{lang},
+ #- and also for --lang and --flang
+ if ($o->{lang}) {
+ put_in_hash($o->{locale}, lang::lang_to_ourlocale($o->{lang}));
+ }
+ lang::set($o->{locale});
+
+ # keep the result otherwise monitor-edid does not return good results afterwards
+ eval { any::monitor_full_edid() };
+
+ $o->{allowFB} = listlength(cat_("/proc/fb"));
+
+ read_product_id() if !$::testing;
+
+ log::l("META_CLASS=$o->{meta_class}");
+
+ process_auto_steps();
+
+ $ENV{COLUMNS} ||= 80;
+ $ENV{LINES} ||= 25;
+ $::o = $o = step_init($o);
+
+ eval { output('/proc/splash', "verbose\n") };
+
+ 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/) {
+ eval { $o->errorInStep($_) };
+ $o->{steps}{$o->{step}}{auto} = 0;
+ $err = $@;
+ $err and next;
+ }
+ $o->{step} = $o->{steps}{$o->{step}}{onError};
+ next MAIN unless $o->{steps}{$o->{step}}{reachable}; #- sanity check: avoid a step not reachable on error.
+ redo MAIN;
+ }
+ $o->{steps}{$o->{step}}{done} = 1;
+ $o->leavingStep($o->{step});
+
+ 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();
+ install::any::remove_advertising();
+ install::any::write_fstab($o);
+ $o->{modules_conf}->write;
+ detect_devices::install_addons($::prefix);
+
+ install::any::adjust_files_mtime_to_timezone();
+
+ #- make sure failed upgrade will not hurt too much.
+ install::steps::cleanIfFailedUpgrade($o);
+
+ #- 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};
+
+ #- copy latest log files
+ eval { cp_af("/tmp/$_", "$::prefix/root/drakx") foreach qw(ddebug.log stage1.log) };
+
+ #- 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;