diff options
Diffstat (limited to 'perl-install/install/any.pm')
-rw-r--r-- | perl-install/install/any.pm | 658 |
1 files changed, 483 insertions, 175 deletions
diff --git a/perl-install/install/any.pm b/perl-install/install/any.pm index 8390aabc7..4ea2ce45d 100644 --- a/perl-install/install/any.pm +++ b/perl-install/install/any.pm @@ -1,4 +1,4 @@ -package install::any; # $Id$ +package install::any; use strict; @@ -8,6 +8,7 @@ our @EXPORT_OK = qw(addToBeDone); #-###################################################################################### #- misc imports #-###################################################################################### +use feature 'state'; use common; use run_program; use fs::type; @@ -22,8 +23,24 @@ use lang; use any; use log; +=head1 SYNOPSYS + +Misc installer specific functions + +=head1 Functions + +=over + +=cut + our @advertising_images; +=item drakx_version($o) + +Returns DrakX version as stored in C<install/stage2/VERSION> file + +=cut + sub drakx_version { my ($o) = @_; @@ -38,13 +55,25 @@ sub dont_run_directly_stage2() { readlink("/usr/bin/runinstall2") eq "runinstall2.sh"; } +=item is_network_install($o) + +Is it a network install? + +=cut + sub is_network_install { my ($o) = @_; member($o->{method}, qw(ftp http nfs)); } +=item spawnShell() + +Starts a shell on tty2 + +=cut + sub spawnShell() { - return if $::local_install || $::testing || dont_run_directly_stage2(); + return if $::local_install || $::testing; my $shellpid_file = '/var/run/drakx_shell.pid'; return if -e $shellpid_file && -d '/proc/' . chomp_(cat_($shellpid_file)); @@ -54,7 +83,8 @@ sub spawnShell() { return; } - $ENV{DISPLAY} ||= ":0"; #- why not :pp + #- why not :pp + $ENV{DISPLAY} ||= ":0" if $::o->{interactive} eq "gtk"; local *F; sysopen F, "/dev/tty2", 2 or log::l("cannot open /dev/tty2 -- no shell will be provided: $!"), goto cant_spawn; @@ -82,6 +112,12 @@ cant_spawn: c::_exit(1); } +=item getAvailableSpace($o) + +Returns available space + +=cut + sub getAvailableSpace { my ($o) = @_; fs::any::getAvailableSpace($o->{fstab}); @@ -91,7 +127,7 @@ sub preConfigureTimezone { my ($o) = @_; require timezone; - #- can not be done in install cuz' timeconfig %post creates funny things + #- cannot be done in install cuz' timeconfig %post creates funny things add2hash($o->{timezone}, timezone::read()) if $o->{isUpgrade}; $o->{timezone}{timezone} ||= timezone::bestTimezone($o->{locale}{country}); @@ -99,8 +135,29 @@ sub preConfigureTimezone { my $utc = every { !isFat_or_NTFS($_) } @{$o->{fstab}}; my $ntp = timezone::ntp_server(); add2hash_($o->{timezone}, { UTC => $utc, ntp => $ntp }); + + #- Make the timezone available to urpm::mirrors. + write_installer_timezone($o->{timezone}); +} + +=item write_installer_timezone($timezone) + +Writes a minimal version of $timezone to /etc/sysconfig/clock for use by urpm::mirrors + +=cut + +sub write_installer_timezone { + my ($timezone) = @_; + mkdir_p('/etc/sysconfig/'); + setVarsInSh('/etc/sysconfig/clock', { ZONE => $timezone->{timezone} }); } +=item ask_suppl_media_method($o) + +Enables to add supplementary media + +=cut + sub ask_suppl_media_method { my ($o) = @_; our $suppl_already_asked; @@ -113,18 +170,18 @@ sub ask_suppl_media_method { Do you have a supplementary installation medium to configure?", - join(", ", map { $_->{name} } install::media::allMediums($o->{packages})))); + "\n\n\n" . join(",\n\n", map { "- $_->{name}" . ($_->{ignore} ? " (disabled)" : '') } install::media::allMediums($o->{packages})))); my %l = my @l = ( '' => N("None"), - 'cdrom' => N("CD-ROM"), 'http' => N("Network (HTTP)"), 'ftp' => N("Network (FTP)"), 'nfs' => N("Network (NFS)"), ); - $o->ask_from( - '', $msg, + $o->ask_from_({ messages => $msg, + interactive_help_id => 'add_supplemental_media', + }, [ { val => \my $suppl, list => [ map { $_->[0] } group_by2(@l) ], @@ -137,8 +194,13 @@ Do you have a supplementary installation medium to configure?", $suppl; } -#- if the supplementary media is networked, but not the main one, network -#- support must be installed and network started. +=item prep_net_suppl_media($o) + +If the supplementary media is networked, but not the main one, network +support must be installed and network started. + +=cut + sub prep_net_suppl_media { my ($o) = @_; @@ -146,9 +208,16 @@ sub prep_net_suppl_media { return if our $net_suppl_media_configured && network::tools::has_network_connection(); $net_suppl_media_configured = 1; - #- install basesystem now - $o->do_pkgs->ensure_is_installed('basesystem', undef, 1); + # needed so that one can install basesystem-minimal before adding suppl network media: + install::media::update_media($o->{packages}); + require urpm::media; + urpm::media::configure($o->{packages}); + + #- install basesystem-minimal now + $o->do_pkgs->ensure_is_installed('basesystem-minimal', undef, 1); + # in case of no network install: + $o->{net} ||= {}; require network::netconnect; network::netconnect::real_main($o->{net}, $o, $o->{modules_conf}); require install::interactive; @@ -156,69 +225,14 @@ sub prep_net_suppl_media { sleep(3); } -sub ask_url { - my ($in, $o_url) = @_; - - my $url = $o_url; - $in->ask_from_({ messages => N("URL of the mirror?"), focus_first => 1 }, [ - { val => \$url, - validate => sub { - if ($url =~ m!^(http|ftp)://!) { - 1; - } else { - $in->ask_warn('', N("URL must start with ftp:// or http://")); - 0; - } - } } ]) && $url; -} -sub ask_mirror { - my ($o, $type, $o_url) = @_; - - require mirror; - - my $mirrors = eval { - my $_w = $o->wait_message('', N("Contacting Mandriva Linux web site to get the list of available mirrors...")); - mirror::list($o->{product_id}, $type); - }; - my $err = $@; - if (!$mirrors) { - $o->ask_warn('', N("Failed contacting Mandriva Linux web site to get the list of available mirrors") . "\n$err"); - return ask_url($o, $o_url); - } - - my $give_url = { country => '-', host => 'URL' }; - - my $mirror = $o_url ? (find { $_->{url} eq $o_url } @$mirrors) || $give_url - #- use current time zone to select best mirror - : mirror::nearest($o->{timezone}{timezone}, $mirrors); - - $o->ask_from_({ messages => N("Choose a mirror from which to get the packages"), - cancel => N("Cancel"), - }, [ { separator => '|', - format => \&mirror::mirror2text, - list => [ @$mirrors, $give_url ], - val => \$mirror, - }, - ]) or return; - - my $url; - if ($mirror eq $give_url) { - $url = ask_url($o, $o_url) or goto &ask_mirror; - } else { - $url = $mirror->{url}; - } - $url =~ s!/main/?$!!; - log::l("chosen mirror: $url"); - $url; -} - sub ask_suppl_media_url { my ($o, $method, $o_url) = @_; - if ($method eq 'ftp' || $method eq 'http') { - install::any::ask_mirror($o, 'distrib', $o_url); - } elsif ($method eq 'cdrom') { - 'cdrom://'; + if (member($method, qw(ftp http))) { + preConfigureTimezone($o); + any::ask_mirror_and_downloader($o, $o->{options}, 'downloader_only'); + $o->{packages}{options}{downloader} = $o->{options}{downloader}; + any::ask_mirror($o, 'distrib', $o_url); } elsif ($method eq 'nfs') { my ($host, $dir) = $o_url ? $o_url =~ m!nfs://(.*?)(/.*)! : (); $o->ask_from_( @@ -240,6 +254,14 @@ sub ask_suppl_media_url { "nfs://$host$dir"; } else { internal_error("bad method $method") } } + + +=item selectSupplMedia($o) + +Offers to add a supplementary media. If yes, ask which mirror to use, ... + +=cut + sub selectSupplMedia { my ($o) = @_; my $url; @@ -248,7 +270,7 @@ sub selectSupplMedia { my $method = ask_suppl_media_method($o) or return; #- configure network if needed - if (!scalar keys %{$o->{net}{ifcfg}} && $method !~ /^(?:cdrom|disk)/ && !$::local_install) { + if (!scalar keys %{$o->{net}{ifcfg}} && $method !~ /^(?:disk)/ && !$::local_install) { prep_net_suppl_media($o); } @@ -294,6 +316,15 @@ sub selectSupplMedia { goto ask_url; } +=item load_rate_files($o) + +Loads the package rates file (C<rpmsrate>) as well as the C<compssUsers.pl> +file which contains the package groups GUI. + +Both files came from the C<meta-task> package. + +=cut + sub load_rate_files { my ($o) = @_; #- must be done after getProvides @@ -306,58 +337,259 @@ sub load_rate_files { defined $o->{compssUsers} or die "Can't read compssUsers.pl file, aborting installation\n"; } +sub _core_medium() { N("Core Release") } + +sub _tainted_medium() { N("Tainted Release") } + +sub _nonfree_medium() { N("Nonfree Release") } + +# FIXME: move me in ../any.pm or in harddrake::*, might be needed by rpmdrake/harddrake: +sub is_firmware_needed_ { + my ($o) = @_; + require list_firmwares; + my @l = map { $_->{driver} } detect_devices::probeall(); + my @need = intersection(\@l, \@list_firmwares::modules_with_nonfree_firmware); + log::l("the following driver(s) need nonfree firmware(s): " . join(', ', @need)) if @need; + + require pkgs; + my @xpkgs = pkgs::detect_graphical_drivers($o->do_pkgs, undef, 'firmware-only'); + log::l("the following nonfree firmware(s) are needed for X.org: " . join(', ', @xpkgs)) if @xpkgs; + + my $need_microcode = detect_devices::hasCPUMicrocode(); + log::l("nonfree firmware is needed for the CPU (microcode)") if $need_microcode; + + if_(@need, 'kernel-firmware-nonfree'), @xpkgs, if_($need_microcode, 'microcode'); +} + +=item is_firmware_needed($o) + +Is a firmware needed by some HW? + +=cut + +sub is_firmware_needed { + my ($o) = @_; + state $res; + $res = is_firmware_needed_($o) if !defined $res; + $res; +} + +sub msg_if_firmware_needed { + my ($o) = @_; + return if !is_firmware_needed($o); + join("\n", + # FIXME: actually can be proprietary drivers (same medium eventually): + N("Some hardware on your machine needs some non free firmwares in order for the free software drivers to work."), + N("You should enable \"%s\"", _nonfree_medium()), + ); +} + +=item enable_nonfree_media($medium) + +Enable a disabled Nonfree medium. + +=cut + +sub enable_nonfree_media { + my ($medium) = @_; + return if $medium->{name} !~ /Nonfree/ || $medium->{name} =~ /32bit/ || !$medium->{ignore}; + log::l("preselecting $medium->{name}"); + $medium->{temp_enabled} = 1; +} + +=item enable_core_32bit_media($medium) + +Enable a disabled Core 32bit medium. + +=cut + +sub enable_core_32bit_media { + my ($medium) = @_; + return if $medium->{name} !~ /Core/ || $medium->{name} !~ /32bit/ || !$medium->{ignore}; + log::l("preselecting $medium->{name}"); + $medium->{temp_enabled} = 1; +} + +=item media_screen($o) + +Lists available media with their status (enabled/disabled). +Suggests to enable Nonfree media if needed. + +=cut + +sub media_screen { + my ($o) = @_; + + my $urpm = $o->{packages}; + # FIXME: + # - nice info + # - ignore already failed media (such as 32bit media on NFS) + # - detect if non-free/tainted were selected previously / are now needed + # rpm -qa |grep tainted/non-free + # - use red color in that case (gtk+ version? interactive::gtk version?) + # - present media as trees (eg 3 main branches (core/nonfree/tainted and sub medium below (release/updates/...) + # - enable to add media from the media screen + # - introduce 'mandatory' keyword for guessing media that can *not* be disabled + my %descriptions = ( + 'Core Release' => N("\"%s\" contains the various pieces of the systems and its applications", _core_medium()), + 'Nonfree Release' => N("\"%s\" contains non free software.\n", _nonfree_medium()) . " " . + N("It also contains firmwares needed for certain devices to operate (eg: some ATI/AMD graphic cards, some network cards, some RAID cards, ...)"), + 'Tainted Release' => N("\"%s\" contains software that can not be distributed in every country due to software patents.", _tainted_medium()) . " " . + N("It also contains software from \"%s\" rebuild with additional capabilities.", _core_medium()), + ); + + my $nonfree_is_needed = is_firmware_needed($o); + + $o->ask_from_({ messages => join("\n", + N("Here you can enable more media if you want."), + msg_if_firmware_needed($o) + ), + interactive_help_id => 'media_selection', + focus_first => sub { 1 } }, [ + map { + my $medium = $_; + $medium->{temp_enabled} = !$medium->{ignore}; + my $name = $medium->{name}; + my ($distribconf, $medium_path) = @{$_->{mediacfg}}; + my @media_types = split(':', $distribconf->getvalue($medium_path, 'media_type')); + my $parent = $distribconf->getvalue($distribconf->getvalue($medium_path, 'updates_for'), 'name'); + my $non_regular_medium = intersection(\@media_types, [ qw(backports debug source testing) ]); + enable_nonfree_media($medium) if $nonfree_is_needed && !$non_regular_medium; + enable_core_32bit_media($medium) if arch() eq 'x86_64' && uefi_type() eq 'ia32' && !$non_regular_medium; + $non_regular_medium ? () : + +{ + val => \$medium->{temp_enabled}, type => 'bool', text => $name, + help => $medium->{update} ? N("This medium provides package updates for medium \"%s\"", $parent) : $descriptions{$name}, + # 'Core Release' cannot be unselected: + disabled => sub { + state $parent_media = $parent && urpm::media::name2medium($urpm, $parent); + $name =~ /^(?:Core|Main) Release$/ || $parent_media ? !$parent_media->{temp_enabled} : 0; + }, + }; + } @{$urpm->{media}}, + ]); +} + +sub enable_choosen_media { + my ($o) = @_; + my $urpm = $o->{packages}; + + # is there some media to enable? + my $todo; + foreach my $medium (@{$urpm->{media}}) { + if ($medium->{temp_enabled} == $medium->{ignore}) { + $medium->{ignore} = !$medium->{temp_enabled}; + if (!$medium->{ignore}) { + delete $medium->{ignore}; + log::l("Medium '$medium->{name}' needs to be updated to be usable"); + urpm::media::select_media($urpm, $medium->{name}); + $todo = 1; + } + } + delete $medium->{temp_enabled}; + } + return if !$todo; + urpm::media::update_media($urpm, allow_failures => 1, nolock => 1, noclean => 1, + callback => \&urpm::download::sync_logger + ); +} + +=item setPackages($o) + +=over 4 + +=item * Initialize urpmi + +=item * Retrieves media.cfg + +=item * Offers to add supplementary media (according to the install method) + +=item * Offers to enable some disabled media + +=item * Ensure we have a kernel and basesystem + +=item * Flags package rates + +=item * Select default packages according to the computer + +=back + +=cut + sub setPackages { my ($o) = @_; + my $urpm; require install::pkgs; { - $o->{packages} = install::pkgs::empty_packages($o->{keep_unrequested_dependencies}); + #- clean shared regions very early + # (update_media will open rpmdb for listing existing pubkeys, + # which may fail when rpm version mistmatches between drakx & chrooted env) + install::pkgs::clean_rpmdb_shared_regions(); + $urpm = $o->{packages} = install::pkgs::empty_packages($o->{keep_unrequested_dependencies}); my $media = $o->{media} || [ { type => 'media_cfg', url => 'drakx://media' } ]; + my ($suppl_method, $copy_rpms_on_disk); - my ($suppl_method, $copy_rpms_on_disk) = install::media::get_media($o, $media, $o->{packages}); + { + install::pkgs::start_pushing_error(); + ($suppl_method, $copy_rpms_on_disk) = install::media::get_media($o, $media, $urpm); - if ($suppl_method) { - 1 while $o->selectSupplMedia; + if ($suppl_method) { + 1 while $o->selectSupplMedia; + } + install::media::update_media($urpm); + install::pkgs::popup_errors(); } + install::pkgs::start_pushing_error(); + + # in auto-install mode, we enforce selected media, else we respect media.cfg's default: + if ($::auto_install && !is_empty_array_ref($o->{enabled_media})) { + # respect enabled/disabled media selection: + foreach my $medium (@{$urpm->{media}}) { + $medium->{temp_enabled} = member($medium->{name}, @{$o->{enabled_media}}); + } + } + media_screen($o) if !$::auto_install || member('chooseMedia', @{$::o->{interactiveSteps}}); + enable_choosen_media($o); + my @choosen_media = map { $_->{name} } grep { !$_->{ignore} } @{$urpm->{media}}; + log::l("choosen media: ", join(', ', @choosen_media)); + die "no choosen media" if !@choosen_media; + + # actually read synthesis now we have all the ones we want: + require urpm::media; + urpm::media::configure($urpm); + + install::pkgs::popup_errors(); + + install::media::adjust_paths_in_urpmi_cfg($urpm); + log::l('urpmi completely set up'); + #- open rpm db according to right mode needed - $o->{packages}{rpmdb} ||= install::pkgs::rpmDbOpen('rebuild_if_needed', $o->{rpm_dbapi}); + $urpm->{rpmdb} ||= install::pkgs::rpmDbOpen('rebuild_if_needed'); { my $_wait = $o->wait_message('', N("Looking at packages already installed...")); - install::pkgs::selectPackagesAlreadyInstalled($o->{packages}); + install::pkgs::selectPackagesAlreadyInstalled($urpm); } - if (my $extension = $o->{upgrade_by_removing_pkgs_matching}) { - my $time = time(); - my ($_w, $wait_message) = $o->wait_message_with_progress_bar; - $wait_message->(N("Removing packages prior to upgrade...")); - my ($current, $total); - my $callback = sub { - my (undef, $type, $_id, $subtype, $amount) = @_; - if ($type eq 'user') { - ($current, $total) = (0, $amount); - } elsif ($type eq 'uninst' && $subtype eq 'stop') { - $wait_message->('', $current++, $total); - } - }; - push @{$o->{default_packages}}, install::pkgs::upgrade_by_removing_pkgs($o->{packages}, $callback, $extension, $o->{isUpgrade}); - log::l("Removing packages took: ", formatTimeRaw(time() - $time)); - } + remove_package_for_upgrade($o); mark_skipped_packages($o); #- always try to select basic kernel (else on upgrade, kernel will never be updated provided a kernel is already #- installed and provides what is necessary). - my $kernel_pkg = install::pkgs::bestKernelPackage($o->{packages}, $o->{match_all_hardware}); - install::pkgs::selectPackage($o->{packages}, $kernel_pkg, 1); - if ($o->{isUpgrade} && $o->{packages}{sizes}{dkms}) { - log::l("selecting kernel-desktop-devel-latest (since dkms was installed)"); - install::pkgs::select_by_package_names($o->{packages}, ['kernel-desktop-devel-latest'], 1); + my $kernel_pkg = install::pkgs::bestKernelPackage($urpm, $o->{match_all_hardware}); + install::pkgs::selectPackage($urpm, $kernel_pkg, 1); + if ($o->{isUpgrade} && $urpm->{sizes}{dkms} && $kernel_pkg =~ /(.*)-latest/) { + my $devel_kernel_pkg = "$1-devel-latest"; + log::l("selecting $devel_kernel_pkg (since dkms was installed)"); + install::pkgs::select_by_package_names($urpm, [ $devel_kernel_pkg ], 1); } - install::pkgs::select_by_package_names_or_die($o->{packages}, ['basesystem'], 1); + install::pkgs::select_by_package_names_or_die($urpm, default_bootloader(), 1) if !$o->{isUpgrade} && !$o->{match_all_hardware}; + install::pkgs::select_by_package_names_or_die($urpm, ['basesystem'], 1); my $rpmsrate_flags_was_chosen = $o->{rpmsrate_flags_chosen}; @@ -373,17 +605,45 @@ sub setPackages { } if ($o->{isUpgrade}) { - { - my $_w = $o->wait_message('', N("Finding packages to upgrade...")); - install::pkgs::selectPackagesToUpgrade($o->{packages}); - } - if ($o->{packages}{sizes}{'kdebase-progs'}) { - log::l("selecting task-kde (since kdebase-progs was installed)"); - install::pkgs::select_by_package_names($o->{packages}, ['task-kde']); - } + my $_w = $o->wait_message('', N("Finding packages to upgrade...")); + install::pkgs::selectPackagesToUpgrade($urpm); } } +=item remove_package_for_upgrade($o) + +Removes packages that must be uninstalled prior to upgrade + +=cut + +sub remove_package_for_upgrade { + my ($o) = @_; + my $extension = $o->{upgrade_by_removing_pkgs_matching}; + + return if !$extension; + + my $time = time(); + my ($_w, $wait_message) = $o->wait_message_with_progress_bar; + $wait_message->(N("Removing packages prior to upgrade...")); + my ($current, $total); + my $callback = sub { + my (undef, $type, $_id, $subtype, $amount) = @_; + if ($type eq 'user') { + ($current, $total) = (0, $amount); + } elsif ($type eq 'uninst' && $subtype eq 'stop') { + $wait_message->('', $current++, $total); + } + }; + push @{$o->{default_packages}}, install::pkgs::upgrade_by_removing_pkgs($o->{packages}, $callback, $extension, $o->{isUpgrade}); + log::l("Removing packages took: ", formatTimeRaw(time() - $time)); +} + +=item count_files($dir) + +Returns the number of files in $dir + +=cut + sub count_files { my ($dir) = @_; -d $dir or return 0; @@ -400,7 +660,7 @@ sub count_files { sub cp_with_progress { my $wait_message = shift; - my $current = shift; + my $_current = shift; my $total = shift; my $dest = pop @_; cp_with_progress_({ keep_special => 1 }, $wait_message, $total, \@_, $dest); @@ -477,10 +737,14 @@ sub rpmsrate_always_flags { $rpmsrate_flags_chosen->{DVD} = 1 if $o->{match_all_hardware} || detect_devices::dvdroms(); $rpmsrate_flags_chosen->{USB} = 1 if $o->{match_all_hardware} || $o->{modules_conf}->get_probeall("usb-interface"); $rpmsrate_flags_chosen->{PCMCIA} = 1 if $o->{match_all_hardware} || detect_devices::hasPCMCIA(); - $rpmsrate_flags_chosen->{HIGH_SECURITY} = 1 if $o->{security} > 3; + $rpmsrate_flags_chosen->{HIGH_SECURITY} = 1 if $o->{security} > 1; $rpmsrate_flags_chosen->{BIGMEM} = 1 if detect_devices::BIGMEM(); $rpmsrate_flags_chosen->{SMP} = 1 if $o->{match_all_hardware} || detect_devices::hasSMP(); - $rpmsrate_flags_chosen->{CDCOM} = 1 if any { $_->{name} =~ /commercial/i } install::media::allMediums($o->{packages}); + if (!$o->{match_all_hardware} && !defined $o->{compssListLevel} && detect_devices::need_light_desktop()) { + log::l("activation light desktop mode (for low resources systems or netbook/nettops)"); + $rpmsrate_flags_chosen->{LIGHT} = 1; + } + # FIXME: to be updated!!! $rpmsrate_flags_chosen->{'3D'} = 1 if $o->{match_all_hardware} || detect_devices::matching_desc__regexp('Matrox.* G[245][05]0') || @@ -506,18 +770,54 @@ sub rpmsrate_always_flags { $rpmsrate_flags_chosen; } +sub default_bootloader() { + require bootloader; + my (undef, $p) = bootloader::get_grub2_pkg(); + if (is_uefi()) { + log::l("defaulting to grub2-efi"); + } else { + log::l("defaulting to grub2"); + } + [ $p ]; +} + +=item default_packages($o) + +Selects default packages to install according to configuration (FS, HW, ...) + +=cut + sub default_packages { my ($o) = @_; my @l; - push @l, "brltty" if cat_("/proc/cmdline") =~ /brltty=/; - push @l, "nfs-utils-clients" if $o->{method} eq "nfs"; - push @l, "mdadm" if !is_empty_array_ref($o->{all_hds}{raids}); - push @l, "lvm2" if !is_empty_array_ref($o->{all_hds}{lvms}); - push @l, "dmraid" if any { fs::type::is_dmraid($_) } @{$o->{all_hds}{hds}}; - push @l, 'powernowd' if cat_('/proc/cpuinfo') =~ /AuthenticAMD/ && arch() =~ /x86_64/ - || cat_('/proc/cpuinfo') =~ /model name.*Intel\(R\) Core\(TM\)2 CPU/; - push @l, detect_devices::probe_name('Pkg'); + sub add_n_log { + my ($reason, @packages) = @_; + if (@packages) { + log::l("selecting " . join(',', @packages) . " because of $reason"); + push @l, @packages; + } + } + + add_n_log("/proc/cmdline=~/brltty=/", "brltty") if cat_("/proc/cmdline") =~ /brltty=/; + add_n_log("method==nfs", "nfs-utils") if $o->{method} eq "nfs"; + add_n_log("have RAID", "mdadm") if !is_empty_array_ref($o->{all_hds}{raids}); + add_n_log("have LVM", "lvm2") if !is_empty_array_ref($o->{all_hds}{lvms}); + add_n_log("have crypted DM", qw(cryptsetup dmsetup)) if !is_empty_array_ref($o->{all_hds}{dmcrypts}); + add_n_log("some disks are fake RAID", qw(mdadm dmraid)) if any { fs::type::is_dmraid($_) } @{$o->{all_hds}{hds}}; + add_n_log("CPU needs microcode", "microcode_ctl") if detect_devices::hasCPUMicrocode(); + add_n_log("either CPU or GFX needs firmware", is_firmware_needed($o)) if is_firmware_needed($o); + add_n_log("CPU needs cpupower", 'cpupower') if detect_devices::hasCPUFreq(); + add_n_log("APM support needed", 'apmd') if -e "/proc/apm"; + add_n_log("needed by hardware", detect_devices::probe_name('Pkg')); + my @ltmp = map { $_->{BOOTPROTO} eq 'dhcp' ? $_->{DHCP_CLIENT} || 'dhcp-client' : () } values %{$o->{net}{ifcfg}}; + add_n_log("needed by networking", @ltmp) if @ltmp; + # will get auto selected at summary stage for bootloader: + add_n_log("needed later at summary stage", qw(acpi acpid)); + # will get auto selected at summary stage for firewall: + add_n_log("needed for firewall/security", qw(shorewall shorewall-ipv6 mandi-ifw)); + # only needed for CDs/DVDs installations: + add_n_log("method='cdrom'", 'perl-Hal-Cdroms') if $o->{method} eq 'cdrom'; my $dmi_BIOS = detect_devices::dmidecode_category('BIOS'); my $dmi_Base_Board = detect_devices::dmidecode_category('Base Board'); @@ -527,16 +827,16 @@ sub default_packages { modules::append_to_modules_loaded_at_startup_for_all_kernels('acerhk'); } - push @l, 'quota' if any { $_->{options} =~ /usrquota|grpquota/ } @{$o->{fstab}}; - push @l, uniq(grep { $_ } map { fs::format::package_needed_for_partition_type($_) } @{$o->{fstab}}); - push @l, 'ntfs-3g' if any { $_->{fs_type} eq 'ntfs-3g' } @{$o->{fstab}}; + add_n_log("some fs is mounted with quota options", 'quota') if any { $_->{options} =~ /usrquota|grpquota/ } @{$o->{fstab}}; + @ltmp = uniq(grep { $_ } map { fs::format::package_needed_for_partition_type($_) } @{$o->{fstab}}); + add_n_log("needed by some fs", @ltmp) if @ltmp; # handle locales with specified scripting: my @languages = map { s/\@.*//; $_ } lang::langsLANGUAGE($o->{locale}{langs}); my @locale_pkgs = map { URPM::packages_providing($o->{packages}, 'locales-' . $_) } @languages; unshift @l, uniq(map { $_->name } @locale_pkgs); - @l; + uniq(@l); } sub mark_skipped_packages { @@ -555,29 +855,6 @@ sub unselectMostPackages { select_default_packages($o); } -sub warnAboutNaughtyServers { - my ($o) = @_; - my @naughtyServers = install::pkgs::naughtyServers($o->{packages}) or return 1; - my $r = $o->ask_from_list_('', -formatAlaTeX( - #-PO: keep the double empty lines between sections, this is formatted a la LaTeX - N("You have selected the following server(s): %s - - -These servers are activated by default. They do not have any known security -issues, but some new ones could be found. In that case, you must make sure -to upgrade as soon as possible. - - -Do you really want to install these servers? -", join(", ", @naughtyServers))), [ N_("Yes"), N_("No") ], 'Yes') or return; - if ($r ne 'Yes') { - log::l("unselecting naughty servers: " . join(' ', @naughtyServers)); - install::pkgs::unselectPackage($o->{packages}, install::pkgs::packageByName($o->{packages}, $_)) foreach @naughtyServers; - } - 1; -} - sub warnAboutRemovedPackages { my ($o, $packages) = @_; my @removedPackages = keys %{$packages->{state}{ask_remove} || {}} or return; @@ -632,6 +909,13 @@ sub kdemove_desktop_file { } } +sub log_system_info { + my ($o) = @_; + log::l("second stage install running (", drakx_version($o), ")"); + log::l(sprintf("Virtualization=%s", detect_devices::virt_technology() || "none")); + log::l(sprintf("Is UEFI=%s", bool2yesno(is_uefi()))); +} + #-############################################################################### #- auto_install stuff @@ -647,16 +931,16 @@ sub g_auto_install { my $o = {}; require install::pkgs; - $o->{default_packages} = install::pkgs::selected_leaves($::o->{packages}); + $o->{default_packages} = [ sort @{ install::pkgs::selected_leaves($::o->{packages}) } ]; - my @fields = qw(mntpoint fs_type size); + my @fields = qw(fs_type hd level mntpoint options parts size VG_name); $o->{partitions} = [ map { my %l; @l{@fields} = @$_{@fields}; \%l; } grep { $_->{mntpoint} && fs::format::known_type($_); } @{$::o->{fstab}} ]; - exists $::o->{$_} and $o->{$_} = $::o->{$_} foreach qw(locale authentication mouse net timezone superuser keyboard users partitioning isUpgrade manualFstab nomouseprobe crypto security security_user libsafe autoExitInstall X services postInstall postInstallNonRooted); #- TODO modules bootloader + exists $::o->{$_} and $o->{$_} = $::o->{$_} foreach qw(locale authentication mouse net timezone superuser keyboard users partitioning isUpgrade manualFstab nomouseprobe crypto security security_user autoExitInstall X services postInstall postInstallNonRooted); #- TODO modules bootloader local $o->{partitioning}{auto_allocate} = !$b_replay; $o->{autoExitInstall} = !$b_replay; @@ -665,6 +949,9 @@ sub g_auto_install { #- deep copy because we're modifying it below $o->{users} = $b_respect_privacy ? [] : [ @{$o->{users} || []} ]; + # remember selected media: + local $o->{enabled_media} = [ map { $_->{name} } grep { !$_->{ignore} } @{$::o->{packages}{media}} ]; + my @user_info_to_remove = ( if_($b_respect_privacy, qw(realname pw)), qw(oldu oldg password password2), @@ -699,9 +986,6 @@ sub getAndSaveAutoInstallFloppies { eval { modules::load('loop') }; - if (arch() =~ /ia64/) { - #- nothing yet - } else { my $mountdir = "$::prefix/root/aif-mount"; -d $mountdir or mkdir $mountdir, 0755; my $param = 'kickstart=floppy ' . generate_automatic_stage1_params($o); @@ -709,7 +993,7 @@ sub getAndSaveAutoInstallFloppies { { my $dev = devices::set_loop($img) or log::l("couldn't set loopback device"), return; - find { eval { fs::mount::mount($dev, $mountdir, $_, 0); 1 } } qw(ext2 vfat) or return; + find { eval { fs::mount::mount($dev, $mountdir, $_, 0); 1 } } qw(ext2 vfat ntfs-3g) or return; if (-e "$mountdir/menu.lst") { # hd_grub boot disk is different than others @@ -744,7 +1028,6 @@ sub getAndSaveAutoInstallFloppies { } rmdir $mountdir; $img; - } } @@ -752,14 +1035,19 @@ sub g_default_packages { my ($o) = @_; my ($_h, $file) = media_browser($o, 'save', 'package_list.pl') or return; + output($file, selected_leaves_pl($o)); +} + +sub selected_leaves_pl { + my ($o) = @_; require Data::Dumper; my $str = Data::Dumper->Dump([ { default_packages => install::pkgs::selected_leaves($o->{packages}) } ], ['$o']); $str =~ s/ {8}/\t/g; - output($file, - "# You should always check the syntax with 'perl -cw auto_inst.cfg.pl'\n" . - "# before testing. To use it, boot with ``linux defcfg=floppy''\n" . - $str); + + "# You should always check the syntax with 'perl -cw auto_inst.cfg.pl'\n" . + "# before testing. To use it, boot with ``linux defcfg=floppy''\n" . + $str; } sub loadO { @@ -769,7 +1057,7 @@ sub loadO { my $o; foreach (removable_media__early_in_install()) { my $dev = devices::make($_->{device}); - foreach my $fs (arch() =~ /sparc/ ? 'romfs' : ('ext2', 'vfat')) { + foreach my $fs (qw(ext4 vfat ntfs-3g)) { eval { fs::mount::mount($dev, '/mnt', $fs, 'readonly'); 1 } or next; if (my $abs_f = find { -e $_ } "/mnt/$f", "/mnt/$f.pl") { $o = loadO_($O, $abs_f); @@ -875,10 +1163,11 @@ sub generate_automatic_stage1_params { $method = $1; #- in stage1, FTP via HTTP proxy is available through FTP config, not HTTP @ks = (server => $2, directory => $3); } elsif ($o->{method} eq 'ftp') { + require install::ftp; my @l = install::ftp::parse_ftp_url($ENV{URLPREFIX}); @ks = (server => $l[0], directory => $l[1], user => $l[2], pass => $l[3]); } elsif ($o->{method} eq 'nfs') { - cat_("/proc/mounts") =~ m|(\S+):(\S+)\s+/tmp/media| or internal_error("can not find nfsimage"); + cat_("/proc/mounts") =~ m|(\S+):(\S+)\s+/tmp/media| or internal_error("cannot find nfsimage"); @ks = (server => $1, directory => $2); } @ks = (method => $method, @ks); @@ -911,7 +1200,7 @@ sub generate_automatic_stage1_params { sub find_root_parts { my ($fstab, $prefix) = @_; - grep { $_->{release} =~ /\b(mandrake|mandriva|conectiva)\b/i } + grep { $_->{release} =~ /\b(mandrake|mandrakelinux|mandriva|conectiva|mageia)\b/i } _find_root_parts($fstab, $prefix); } @@ -986,7 +1275,7 @@ sub migrate_device_names { goto found_one; } - #- we can not find one and only one matching hd + #- we cannot find one and only one matching hd my @from_fstab_not_handled = map { @$_ } @from_fstab_per_hds; log::l("we still do not know what to do with: " . join(' ', map { $_->{device} } @from_fstab_not_handled)); @@ -1203,9 +1492,10 @@ sub screenshot_dir__and_move() { if (-e $dir0 && ! -e '/root/non-chrooted-marker.DrakX') { ($dir0, 'nowarn'); #- it occurs during pkgs install when we are chrooted } elsif (-e $dir1) { - if (-e "$dir2/DrakX-screenshots") { - cp_af("$dir2/DrakX-screenshots", $dir1); - rm_rf("$dir2/DrakX-screenshots"); + my $path = "$dir2/DrakX-screenshots"; + if (-e $path) { + cp_af($path, $dir1); + rm_rf($path); } $dir1; } else { @@ -1219,11 +1509,14 @@ sub take_screenshot { my ($base_dir, $nowarn) = screenshot_dir__and_move(); my $dir = "$base_dir/DrakX-screenshots"; if (!-e $dir) { - mkdir $dir or $in->ask_warn('', N("Can not make screenshots before partitioning")), return; + mkdir $dir or $in->ask_warn('', N("Cannot make screenshots before partitioning")), return; } my $nb = 1; $nb++ while -e "$dir/$nb.png"; - system("fb2png /dev/fb0 $dir/$nb.png 0"); + run_program::run('scrot', "$dir/$nb.png"); + + # help doesn't remember warning has been shown (one shot processes): + $warned ||= -e "$dir/2.png"; if (!$warned && !$nowarn) { $warned = 1; @@ -1262,28 +1555,39 @@ sub remove_advertising() { } sub disable_user_view() { - substInFile { s/^UserView=.*/UserView=true/ } "$::prefix/etc/kde/kdm/kdmrc"; substInFile { s/^Browser=.*/Browser=0/ } "$::prefix/etc/X11/gdm/custom.conf"; + #TODO: Needed for sddm ? } sub set_security { my ($o) = @_; require security::various; + return if !-x "$::prefix/usr/sbin/msec"; security::level::set($o->{security}); - security::various::config_libsafe($::prefix, $o->{libsafe}); security::various::config_security_user($::prefix, $o->{security_user}); } sub write_fstab { my ($o) = @_; - fs::write_fstab($o->{all_hds}, $::prefix) - if !$o->{isUpgrade} || $o->{isUpgrade} =~ /redhat|conectiva/ || $o->{migrate_device_names}; + return if $::local_install || $o->{isUpgrade} && $o->{isUpgrade} !~ /redhat|conectiva/ && !$o->{migrate_device_names}; + fs::write_fstab($o->{all_hds}, $::prefix); } -sub adjust_files_mtime_to_timezone() { - #- to ensure linuxconf does not cry against those files being in the future - #- to ensure fc-cache works correctly on fonts installed after reboot +=item adjust_files_mtime_to_timezone() { + +Fixes mtime of a couple important files according to timezone in order to: + +=over 4 + +=item * to ensure linuxconf does not cry against those files being in the future + +=item * to ensure fc-cache works correctly on fonts installed after reboot +=back + +=cut + +sub adjust_files_mtime_to_timezone() { my $timezone_shift = run_program::rooted_get_stdout($::prefix, 'date', '+%z'); my ($h, $m) = $timezone_shift =~ /\+(..)(..)/ or return; my $now = time() - ($h * 60 + $m * 60) * 60; @@ -1379,4 +1683,8 @@ sub configure_pcmcia { run_program::run("/lib/udev/pcmcia-socket-startup"); } +=back + +=cut + 1; |