diff options
Diffstat (limited to 'perl-install/any.pm')
-rw-r--r-- | perl-install/any.pm | 736 |
1 files changed, 587 insertions, 149 deletions
diff --git a/perl-install/any.pm b/perl-install/any.pm index e68158c51..ab93036dc 100644 --- a/perl-install/any.pm +++ b/perl-install/any.pm @@ -9,6 +9,7 @@ use strict; use common; use detect_devices; use partition_table; +use fs::proc_partitions; use fs::type; use lang; use run_program; @@ -81,6 +82,7 @@ sub create_user { ? ('-l', $u->{name}, $u->{rename_from}) : $u->{name})); symlink($u->{home}, $symlink_home_from) if $symlink_home_from; + eval { run_program::rooted($::prefix, 'systemctl', 'try-restart', 'accounts-daemon.service') }; } my (undef, undef, $uid, $gid, undef, undef, undef, $home) = getpwnam($u->{name}); @@ -116,10 +118,10 @@ sub install_acpi_pkgs { my $acpi = bootloader::get_append_with_key($b, 'acpi'); my $use_acpi = !member($acpi, 'off', 'ht'); if ($use_acpi) { - $do_pkgs->ensure_files_are_installed([ [ 'acpi', '/usr/bin/acpi' ], [ 'acpid', '/usr/sbin/acpid' ] ], $::isInstall); + $do_pkgs->ensure_files_are_installed([ [ qw(acpi acpi) ], [ qw(acpid acpid) ] ], $::isInstall); } require services; - services::set_status($_, $use_acpi, $::isInstall) foreach qw(acpi acpid); + services::set_status($_, $use_acpi, $::isInstall) foreach qw(acpid); } sub setupBootloaderBeforeStandalone { @@ -135,7 +137,7 @@ sub setupBootloaderBeforeStandalone { } sub setupBootloaderBefore { - my ($_do_pkgs, $bootloader, $all_hds, $fstab, $keyboard, $allow_fb, $vga_fb, $splash, $quiet) = @_; + my ($do_pkgs, $bootloader, $all_hds, $fstab, $keyboard, $allow_fb, $vga_fb, $splash, $quiet) = @_; require bootloader; #- auto_install backward compatibility @@ -172,7 +174,7 @@ sub setupBootloaderBefore { my $biggest_swap_dev = fs::wild_device::from_part('', $biggest_swap); bootloader::set_append_with_key($bootloader, resume => $biggest_swap_dev); mkdir_p("$::prefix/etc/dracut.conf.d"); - output("$::prefix/etc/dracut.conf.d/51-mageia-resume.conf", qq(add_device+="$biggest_swap_dev"\n)); + output("$::prefix/etc/dracut.conf.d/51-mageia-resume.conf", qq(add_device+=" $biggest_swap_dev "\n)); } } @@ -207,6 +209,17 @@ sub setupBootloaderBefore { splash => $splash, quiet => $quiet); + if (is_uefi()) { + if (my @esp = grep { $_->{mntpoint} eq '/boot/EFI' } @$fstab) { + $bootloader->{removable} = $esp[0]{is_removable}; + } + } else { + if (my $root_part = fs::get::root($fstab)) { + $bootloader->{removable} = $root_part->{is_removable}; + } + } + $bootloader->{default_to_no_probe} = 1 if $bootloader->{removable}; + $bootloader->{keytable} ||= keyboard::keyboard2kmap($keyboard); log::l("setupBootloaderBefore end"); } @@ -223,7 +236,11 @@ sub setupBootloader { setupBootloader__boot_bios_drive($in, $b, $all_hds->{hds}) or goto general; { local $::Wizard_finished = 1 if $::isStandalone; - setupBootloader__entries($in, $b, $all_hds, $fstab) or goto general; + if (bootloader::main_method($b->{method}) eq 'grub2') { + setupBootloader__grub2($in, $b, $all_hds, $fstab) or goto general; + } else { + setupBootloader__entries($in, $b, $all_hds, $fstab) or goto general; + } } 1; } @@ -234,7 +251,9 @@ sub setupBootloaderUntilInstalled { my $before = fs::fstab_to_string($all_hds); setupBootloader($in, $b, $all_hds, $fstab, $security) or $in->exit; if ($before ne fs::fstab_to_string($all_hds)) { - #- for /tmp using tmpfs when "clean /tmp" is chosen + #- ovitters: This fstab comparison was needed for optionally + #- setting up /tmp using tmpfs. That code was removed. Not removing + #- this code as I'm not sure if something still relies on this fs::write_fstab($all_hds); } } while !installBootloader($in, $b, $all_hds); @@ -244,12 +263,10 @@ sub installBootloader { my ($in, $b, $all_hds) = @_; return if detect_devices::is_xbox(); - return 1 if arch() =~ /mips|arm/; + return 1 if arch() =~ /arm/; install_bootloader_pkgs($in->do_pkgs, $b); - eval { run_program::rooted($::prefix, 'echo | lilo -u') } if $::isInstall && !$::o->{isUpgrade} && -e "$::prefix/etc/lilo.conf" && glob("$::prefix/boot/boot.*"); - retry: eval { my $_w = $in->wait_message(N("Please wait"), N("Bootloader installation in progress")); @@ -277,11 +294,6 @@ Assign a new Volume ID?", $dev)))) { $in->ask_warn('', [ N("Installation of bootloader failed. The following error occurred:"), $err ]); return; } - } elsif (arch() =~ /ppc/) { - if (detect_devices::get_mac_model() !~ /IBM/) { - my $of_boot = bootloader::dev2yaboot($b->{boot}); - $in->ask_warn('', N("You may need to change your Open Firmware boot-device to\n enable the bootloader. If you do not see the bootloader prompt at\n reboot, hold down Command-Option-O-F at reboot and enter:\n setenv boot-device %s,\\\\:tbxi\n Then type: shut-down\nAt your next boot you should see the bootloader prompt.", $of_boot)); - } } 1; } @@ -293,7 +305,7 @@ sub setupBootloader_simple { require bootloader; bootloader::ensafe_first_bios_drive($hds) - || $b->{bootUnsafe} || arch() =~ /ppc/ or return 1; #- default is good enough + || $b->{bootUnsafe} or return 1; #- default is good enough if (arch() !~ /ia64/) { setupBootloader__mbr_or_not($in, $b, $hds, $fstab) or return 0; @@ -309,8 +321,7 @@ sub setupBootloader_simple { sub setupBootloader__boot_bios_drive { my ($in, $b, $hds) = @_; - if (arch() =~ /ppc/ || - !is_empty_hash_ref($b->{bios})) { + if (!is_empty_hash_ref($b->{bios})) { #- some bios mapping already there return 1; } elsif (bootloader::mixed_kind_of_disks($hds) && $b->{boot} =~ /\d$/) { #- on a partition @@ -347,14 +358,6 @@ sub setupBootloader__mbr_or_not { log::l("setupBootloader__mbr_or_not"); - if (arch() =~ /ppc/) { - if (defined $partition_table::mac::bootstrap_part) { - $b->{boot} = $partition_table::mac::bootstrap_part; - log::l("set bootstrap to $b->{boot}"); - } else { - die "no bootstrap partition - yaboot.conf creation failed"; - } - } else { my $floppy = detect_devices::floppy(); my @l = ( @@ -379,15 +382,9 @@ sub setupBootloader__mbr_or_not { #- remove bios mapping if the user changed the boot device delete $b->{bios} if $new_boot && $new_boot ne $b->{boot}; $b->{boot} = $new_boot or return; - } 1; } -sub get_apple_boot_parts { - my ($fstab) = @_; - map { "/dev/$_" } (map { $_->{device} } (grep { isAppleBootstrap($_) } @$fstab)); -} - sub setupBootloader__general { my ($in, $b, $all_hds, $fstab, $_security) = @_; @@ -397,14 +394,16 @@ sub setupBootloader__general { my $prev_enable_apic = my $enable_apic = !bootloader::get_append_simple($b, 'noapic'); my $prev_enable_lapic = my $enable_lapic = !bootloader::get_append_simple($b, 'nolapic'); my $prev_enable_smp = my $enable_smp = !bootloader::get_append_simple($b, 'nosmp'); - my $prev_clean_tmp = my $clean_tmp = any { $_->{mntpoint} eq '/tmp' } @{$all_hds->{special} ||= []}; my $prev_boot = $b->{boot}; my $prev_method = $b->{method}; $b->{password2} ||= $b->{password} ||= ''; $::Wizard_title = N("Boot Style Configuration"); - if (arch() !~ /ppc/) { - my (@boot_devices, %boot_devices); + my (@boot_devices, %boot_devices); + if (is_uefi()) { + @boot_devices = 'ESP'; + %boot_devices = (ESP => N("EFI System Partition")); + } else { foreach (bootloader::allowed_boot_parts($b, $all_hds)) { my $dev = "/dev/$_->{device}"; push @boot_devices, $dev; @@ -415,19 +414,18 @@ sub setupBootloader__general { } $boot_devices{$dev} = $name ? "$dev ($name)" : $dev; } + } - $in->ask_from_({ #messages => N("Bootloader main options"), - title => N("Bootloader main options"), - interactive_help_id => 'setupBootloader', - }, [ + $in->ask_from_({ #messages => N("Bootloader main options"), + title => N("Bootloader main options"), + interactive_help_id => 'setupBootloader', + }, [ #title => N("Bootloader main options"), { label => N("Bootloader"), title => 1 }, { label => N("Bootloader to use"), val => \$b->{method}, list => \@method_choices, format => \&bootloader::method2text }, - if_(arch() !~ /ia64/, - { label => N("Boot device"), val => \$b->{boot}, list => \@boot_devices, + { label => N("Boot device"), val => \$b->{boot}, list => \@boot_devices, allow_empty_list => 1, format => sub { $boot_devices{$_[0]} } }, - ), { label => N("Main options"), title => 1 }, { label => N("Delay before booting default image"), val => \$b->{timeout} }, { text => N("Enable ACPI"), val => \$force_acpi, type => 'bool', advanced => 1 }, @@ -446,25 +444,7 @@ sub setupBootloader__general { $ok && $ok2; } }, { label => N("Password (again)"), val => \$b->{password2}, hidden => 1 }, - { text => N("Clean /tmp at each boot"), val => \$clean_tmp, type => 'bool', advanced => 1 }, ]) or return 0; - } else { - $b->{boot} = $partition_table::mac::bootstrap_part; - $in->ask_from_({ messages => N("Bootloader main options"), - title => N("Bootloader main options"), - interactive_help_id => 'setupYabootGeneral', - }, [ - { label => N("Bootloader to use"), val => \$b->{method}, - list => \@method_choices, format => \&bootloader::method2text }, - { label => N("Init Message"), val => \$b->{'init-message'} }, - { label => N("Boot device"), val => \$b->{boot}, list => [ get_apple_boot_parts($fstab) ] }, - { label => N("Open Firmware Delay"), val => \$b->{delay} }, - { label => N("Kernel Boot Timeout"), val => \$b->{timeout} }, - { label => N("Enable CD Boot?"), val => \$b->{enablecdboot}, type => "bool" }, - { label => N("Enable OF Boot?"), val => \$b->{enableofboot}, type => "bool" }, - { label => N("Default OS?"), val => \$b->{defaultos}, list => [ 'linux', 'macos', 'macosx', 'darwin' ] }, - ]) or return 0; - } #- remove bios mapping if the user changed the boot device delete $b->{bios} if $b->{boot} ne $prev_boot; @@ -496,19 +476,110 @@ sub setupBootloader__general { ($enable_lapic ? \&bootloader::set_append_simple : \&bootloader::remove_append_simple)->($b, 'lapic'); } - if ($prev_clean_tmp != $clean_tmp) { - if ($clean_tmp && !fs::get::has_mntpoint('/tmp', $all_hds)) { - push @{$all_hds->{special}}, { device => 'none', mntpoint => '/tmp', fs_type => 'tmpfs' }; - } else { - @{$all_hds->{special}} = grep { $_->{mntpoint} ne '/tmp' } @{$all_hds->{special}}; - } - } - if (bootloader::main_method($prev_method) eq 'lilo' && bootloader::main_method($b->{method}) eq 'grub') { log::l("switching for lilo to grub, ensure we don't read lilo.conf anymore"); renamef("$::prefix/etc/lilo.conf", "$::prefix/etc/lilo.conf.unused"); } + if ($prev_method eq 'refind' && $b->{method} ne 'refind') { + log::l("switching from rEFInd, ensure we don't detect refind as the active boot method"); + renamef("$::prefix/boot/refind_linux.conf", "$::prefix/boot/refind_linux.conf.unused"); + } + if ($b->{method} eq 'refind') { + if (bootloader::main_method($prev_method) eq 'grub2') { + #- grub2 doesn't provide any entries we can use, so revert to the defaults + %$b = (); + setupBootloaderBeforeStandalone($in->do_pkgs, $b, $all_hds, $fstab); + $b->{method} = 'refind'; + $b->{boot} = 'ESP'; + undef $b->{default}; + } + setupBootloader__refind($in, $b, $fstab); + } else { + 1; + } +} + +sub setupBootloader__refind { + my ($in, $b, $fstab) = @_; + + my $already_in_refind = -e "$::prefix/boot/EFI/EFI/refind/refind.conf"; + my $already_in_default = -e "$::prefix/boot/EFI/EFI/BOOT/refind.conf"; + my $already_installed = $already_in_refind || $already_in_default; + + my $update_esp = !$already_installed; + my $as_default = $already_in_default || $b->{removable}; + + if (!defined $b->{banner_path}) { + #- We haven't yet read any existing configuration, either because we are doing a clean + #- install or because we are switching from a different bootloader. Try to read it now. + #- Even if we are doing a clean install, rEFInd may already be installed in the ESP. + bootloader::read_refind_config($b); + } + + my $use_nvram = $b->{use_nvram}; + my $banner_path = $b->{banner_path}; + my $banner_scale = $b->{banner_scale}; + my $banner_type = $banner_path eq 'refind_banner.png' ? 'banner' + : $banner_path eq 'mageia_theme.png' ? 'theme' + : 'custom'; + $in->ask_from_( + { + title => N("Bootloader Configuration"), + interactive_help_id => 'setupBootloader', + }, + [ + { label => N("Install Options"), title => 1, }, + { text => N("Install or update rEFInd in the EFI system partition"), + val => \$update_esp, type => 'bool', disabled => sub { !$already_installed } }, + { text => N("Install in /EFI/BOOT (removable device or workaround for some BIOSs)"), + val => \$as_default, type => 'bool', disabled => sub { !$update_esp } }, + { text => N("Configure rEFInd to store its variables in the EFI NVRAM"), + val => \$use_nvram, type => 'bool' }, + { label => N("Background"), title => 1, }, + { val => \$banner_type, type => 'combo', list => [ 'banner', 'theme', 'custom' ], + format => sub { + my ($choice) = @_; + +{ + 'banner' => N("rEFInd banner"), + 'theme' => N("Mageia theme"), + 'custom' => N("Custom"), + }->{$choice}; + }, + changed => sub { + if ($banner_type eq 'banner') { + $banner_path = 'refind_banner.png'; + $banner_scale = 'noscale'; + } elsif ($banner_type eq 'theme') { + $banner_path = 'mageia_theme.png'; + $banner_scale = 'fillscreen'; + } + } + }, + { val => \$banner_path, type => 'entry', disabled => sub { $banner_type ne 'custom' } }, + { val => \$banner_scale, type => 'combo', list => [ 'noscale', 'fillscreen' ], + format => sub { + my ($choice) = @_; + +{ + 'noscale' => N("No scaling"), + 'fillscreen' => N("Scale to fit"), + }->{$choice}; + } + }, + ] + ) or return 0; + + if ($update_esp) { + $b->{install_mode} = $as_default ? 'as_default' : 'as_refind'; + } else { + $b->{install_mode} = $as_default ? 'no_install' : 'nvram_only'; + } + $b->{use_nvram} = $use_nvram; + $b->{banner_path} = $banner_path; + $b->{banner_scale} = $banner_scale; + if (my @esp = grep { $_->{mntpoint} eq '/boot/EFI' } @$fstab) { + $b->{esp_device} = $esp[0]{real_device} || fs::wild_device::from_part('', $esp[0]); + } 1; } @@ -534,18 +605,23 @@ sub setupBootloader__entries { } @$fstab; my @l; - if ($e->{type} eq "image") { + if ($b->{method} eq 'refind') { + @l = ( + { label => N("Label"), val => \$e->{label} }, + { label => N("Append"), val => \$append }, + { label => N("Video mode"), val => \$vga, list => [ '', Xconfig::resolution_and_depth::bios_vga_modes() ], + format => \&Xconfig::resolution_and_depth::to_string, advanced => 1 }, + ); + } elsif ($e->{type} eq "image") { @l = ( { label => N("Image"), val => \$e->{kernel_or_dev}, list => [ map { "/boot/$_" } bootloader::installed_vmlinuz() ], not_edit => 0 }, -{ label => N("Root"), val => \$e->{root}, list => [ map { fs::wild_device::from_part('', $_) } @$fstab ], format => sub { $root_descr{$_[0]} } }, +{ label => N("Root"), val => \$e->{root}, list => [ map { fs::wild_device::from_part('', $_) } grep { !isSwap($_) } @$fstab ], format => sub { $root_descr{$_[0]} } }, { label => N("Append"), val => \$append }, if_($e->{xen}, { label => N("Xen append"), val => \$e->{xen_append} } ), if_($b->{password}, { label => N("Requires password to boot"), val => \$e->{lock}, type => "bool" }), - if_(arch() !~ /ppc|ia64/, { label => N("Video mode"), val => \$vga, list => [ '', Xconfig::resolution_and_depth::bios_vga_modes() ], format => \&Xconfig::resolution_and_depth::to_string, advanced => 1 }, -), { label => N("Initrd"), val => \$e->{initrd}, list => [ map { if_(/^initrd/, "/boot/$_") } all("$::prefix/boot") ], not_edit => 0, advanced => 1 }, { label => N("Network profile"), val => \$netprofile, list => [ sort(uniq('', $netprofile, network::network::netprofile_list())) ], advanced => 1 }, ); @@ -554,26 +630,16 @@ sub setupBootloader__entries { { label => N("Root"), val => \$e->{kernel_or_dev}, list => [ map { "/dev/$_->{device}" } @$fstab, detect_devices::floppies() ] }, ); } - if (arch() !~ /ppc/) { + if ($b->{method} ne 'refind') { @l = ( { label => N("Label"), val => \$e->{label} }, @l, { text => N("Default"), val => \$default, type => 'bool' }, ); - } else { - unshift @l, { label => N("Label"), val => \$e->{label}, list => ['macos', 'macosx', 'darwin'] }; - if ($e->{type} eq "image") { - @l = ({ label => N("Label"), val => \$e->{label} }, - (@l[1..2], { label => N("Append"), val => \$append }), - { label => N("NoVideo"), val => \$e->{novideo}, type => 'bool' }, - { text => N("Default"), val => \$default, type => 'bool' } - ); - } } - $in->ask_from_( { - interactive_help_id => arch() =~ /ppc/ ? 'setupYabootAddEntry' : 'setupBootloaderAddEntry', + interactive_help_id => 'setupBootloaderAddEntry', callbacks => { complete => sub { $e->{label} or $in->ask_warn('', N("Empty label not allowed")), return 1; @@ -596,17 +662,22 @@ sub setupBootloader__entries { my $Add = sub { my @labels = map { $_->{label} } @{$b->{entries}}; my ($e, $prefix); - if ($in->ask_from_list_('', N("Which type of entry do you want to add?"), - [ N_("Linux"), arch() =~ /sparc/ ? N_("Other OS (SunOS...)") : arch() =~ /ppc/ ? - N_("Other OS (MacOS...)") : N_("Other OS (Windows...)") ] - ) eq "Linux") { + if ($b->{method} eq 'refind') { + $e = { type => 'image', + kernel_or_dev => '/boot/vmlinuz', + root => '/dev/' . fs::get::root($fstab)->{device}, #- assume a good default. + }; + $prefix = "linux"; + } elsif ($in->ask_from_list_('', N("Which type of entry do you want to add?"), + [ N_("Linux"), N_("Other OS (Windows...)") ] + ) eq "Linux") { $e = { type => 'image', root => '/dev/' . fs::get::root($fstab)->{device}, #- assume a good default. }; $prefix = "linux"; } else { $e = { type => 'other' }; - $prefix = arch() =~ /sparc/ ? "sunos" : arch() =~ /ppc/ ? "macos" : "windows"; + $prefix = "windows"; } $e->{label} = $prefix; for (my $nb = 0; member($e->{label}, @labels); $nb++) { @@ -645,6 +716,18 @@ sub setupBootloader__entries { }; my @prev_entries = @{$b->{entries}}; + + #- the rEFInd configuration file just provides alternative kernel command lines + #- so we only want to display entries that relate to the default kernel. + if ($b->{method} eq 'refind') { + @{$b->{entries}} = + grep { + my $pb = $_->{type} ne 'image' || $_->{kernel_or_dev} ne '/boot/vmlinuz'; + log::l("dropping bootloader entry $_->{label} because it is not needed by rEFInd") if $pb; + !$pb; + } @{$b->{entries}}; + } + if ($in->ask_from__add_modify_remove(N("Bootloader Configuration"), N("Here are the entries on your boot menu so far. You can create additional entries or change the existing ones."), [ { @@ -662,35 +745,136 @@ You can create additional entries or change the existing ones."), [ { } } +sub setupBootloader__grub2 { + my ($in, $b, $_all_hds, $_fstab) = @_; + + # update entries (so that we can display their list below): + my $error; + # grub2-update can take many minutes on some systems (mga#18538) + # FIXME: change the message to be more informative + my $_w = $in->wait_message(N("Please wait"), N("Please wait")); + run_program::rooted($::prefix, 'update-grub2', '2>', \$error) or die "update-grub2 failed: $error"; + undef $_w; + + # read grub2 auto-generated entries (instead of keeping eg: grub/lilo ones): + my $b2 = bootloader::read_grub2(); + + # get default parameters: + my $append = $b->{perImageAppend} || bootloader::get_grub2_append($b2); + my $default = $b2->{default}; + + require Xconfig::resolution_and_depth; + + require network::network; #- to list network profiles + my $vga = Xconfig::resolution_and_depth::from_bios($b->{default_vga}); + my $os_prober = $in->do_pkgs->is_installed('os-prober', '/usr/bin/os-prober') && !$b->{default_to_no_probe}; + + my $res = $in->ask_from_( + { + title => N("Bootloader Configuration"), + interactive_help_id => 'setupBootloaderAddEntry', + }, + [ + { label => N("Default"), val => \$default, + list => [ map { $_->{label} } @{$b2->{entries}} ] }, + { label => N("Append"), val => \$append }, + { label => N("Video mode"), val => \$vga, list => [ '', Xconfig::resolution_and_depth::bios_vga_modes() ], + format => \&Xconfig::resolution_and_depth::to_string, advanced => 1 }, + { text => N("Do not touch ESP or MBR"), val => \$b->{no_esp_or_mbr}, type => 'bool', advanced => 1, + validate => sub { + $b->{no_esp_or_mbr} and $in->ask_warn(N("Warning"), + N("Not installing on ESP or MBR means that the installation is not bootable unless chain loaded from another OS!")); + 1; + }, + }, + { text => N("Probe Foreign OS"), val => \$os_prober, type => 'bool', + help => N("Unselect this option to stop grub2 scanning for other operating systems, which will prevent them from being included in the grub2 boot menu. The option may also be unselected after installation, removing the other operating systems from the grub2 boot menu, but reducing the time needed for installing kernel updates"), + }, + if_(is_uefi(), + { text => N("Install in /EFI/BOOT (removable device or workaround for some BIOSs)"), + val => \$b->{removable}, type => 'bool' }, + ), + ]); + if ($res) { + $b->{entries} = $b2->{entries}; + $b->{default} = $default; + $b->{default_vga} = ref($vga) ? $vga->{bios} : $vga; + $b->{perImageAppend} = $append; + if ($os_prober) { + $in->do_pkgs->ensure_is_installed('os-prober', '/usr/bin/os-prober'); + } else { + $in->do_pkgs->remove('os-prober'); + } + 1; + } else { + ''; + } +} + +sub get_session_file { + my ($desktop) = @_; + my @dir_wm = qw(xsessions wayland-sessions); + my $xsession_file; + foreach my $dwm (@dir_wm) { + my $xs_file = find { + my %xsession = read_gnomekderc($_, 'Desktop Entry'); + $xsession{Name} =~ s/\s+//g; + $xsession{Name} eq ${desktop}; + } glob("$::prefix/usr/share/$dwm/*.desktop"); + $xsession_file = $xs_file unless $xsession_file; + } + $xsession_file =~ s!\.[^.]+$!!; + $xsession_file =~ s!.*/!!; + $xsession_file ||= $desktop; + return $xsession_file; +} + +sub get_session_file_with_extension { + return get_session_file(@_) . '.desktop'; +} + +sub available_dms() { + my @l; + foreach (glob("$::prefix/usr/share/X11/dm.d/*.conf")) { + my %dm = getVarsFromSh($_); + push @l, $dm{EXEC} if $dm{EXEC} && -x "$::prefix/$dm{EXEC}"; + } + @l; +} + sub get_autologin() { my %desktop = getVarsFromSh("$::prefix/etc/sysconfig/desktop"); my $gdm_file = "$::prefix/etc/X11/gdm/custom.conf"; - my $kdm_file = common::read_alternative('kdm4-config'); + my $sddm_file = "$::prefix/etc/sddm.conf"; + my $lightdm_conffile = "$::prefix/etc/lightdm/lightdm.conf.d/50-mageia-autologin.conf"; + my $lxdm_conffile = "$::prefix/etc/lxdm/lxdm.conf"; my $autologin_file = "$::prefix/etc/sysconfig/autologin"; my $desktop = $desktop{DESKTOP} || first(sessions()); my %desktop_to_dm = ( GNOME => 'gdm', - KDE4 => 'kdm', - xfce4 => 'gdm', + Plasma => 'sddm', + Xfce => 'lightdm', LXDE => 'lxdm', ); - my %dm_canonical = ( - gnome => 'gdm', - kde => 'kdm', - ); my $dm = - lc($desktop{DISPLAYMANAGER}) || + basename(readlink("$::prefix/etc/systemd/system/display-manager.service")) =~ s/(.*)\.service/$1/r || $desktop_to_dm{$desktop} || - basename(chomp_(run_program::rooted_get_stdout($::prefix, "/etc/X11/lookupdm"))); - $dm = $dm_canonical{$dm} if exists $dm_canonical{$dm}; + basename(first(available_dms())); my $autologin_user; if ($dm eq "gdm") { my %conf = read_gnomekderc($gdm_file, 'daemon'); $autologin_user = text2bool($conf{AutomaticLoginEnable}) && $conf{AutomaticLogin}; - } elsif ($dm eq "kdm") { - my %conf = read_gnomekderc($kdm_file, 'X-:0-Core'); - $autologin_user = text2bool($conf{AutoLoginEnable}) && $conf{AutoLoginUser}; + } elsif ($dm eq "sddm") { + my %conf = read_gnomekderc($sddm_file, 'Autologin'); + $autologin_user = $conf{User}; + } elsif ($dm eq "lightdm") { + my %conf = read_gnomekderc($lightdm_conffile, 'Seat:*'); + $autologin_user = text2bool($conf{'#dummy-autologin'}) && $conf{"autologin-user"}; + } elsif ($dm eq "lxdm") { + my %conf = read_gnomekderc($lxdm_conffile, 'base'); + $autologin_user = $conf{autologin}; + $autologin_user =~ s/^.//; } else { my %conf = getVarsFromSh($autologin_file); $autologin_user = text2bool($conf{AUTOLOGIN}) && $conf{USER}; @@ -701,28 +885,28 @@ sub get_autologin() { sub is_standalone_autologin_needed { my ($dm) = @_; - return member($dm, qw(lxdm slim xdm)); + return member($dm, qw(slim xdm)); } sub set_autologin { - my ($do_pkgs, $autologin) = @_; + my ($do_pkgs, $autologin, $o_auto) = @_; log::l("set_autologin $autologin->{user} $autologin->{desktop}"); my $do_autologin = bool2text($autologin->{user}); $autologin->{dm} ||= 'xdm'; - $do_pkgs->ensure_is_installed($autologin->{dm}) + $do_pkgs->ensure_is_installed($autologin->{dm}, undef, $o_auto) or return; if ($autologin->{user} && is_standalone_autologin_needed($autologin->{dm})) { - $do_pkgs->ensure_is_installed('autologin', '/usr/bin/startx.autologin') + $do_pkgs->ensure_is_installed('autologin', '/usr/bin/startx.autologin', $o_auto) or return; } - #- Configure KDM / MDKKDM - my $kdm_conffile = common::read_alternative('kdm4-config'); - eval { common::update_gnomekderc_no_create($kdm_conffile, 'X-:0-Core' => ( - AutoLoginEnable => $do_autologin, - AutoLoginUser => $autologin->{user}, - )) } if -e $kdm_conffile; + #- Configure SDDM + my $sddm_conffile = "$::prefix/etc/sddm.conf"; + eval { common::update_gnomekderc_no_create($sddm_conffile, 'Autologin' => ( + Session => get_session_file_with_extension($autologin->{desktop}), + User => $autologin->{user}, + )) } if -e $sddm_conffile; #- Configure GDM my $gdm_conffile = "$::prefix/etc/X11/gdm/custom.conf"; @@ -731,8 +915,27 @@ sub set_autologin { AutomaticLogin => $autologin->{user}, )) } if -e $gdm_conffile; + #- Configure LIGHTDM + my $lightdm_conffile = "$::prefix/etc/lightdm/lightdm.conf.d/50-mageia-autologin.conf"; + eval { update_gnomekderc($lightdm_conffile, 'Seat:*' => ( + '#dummy-autologin' => $do_autologin, + 'autologin-user' => $autologin->{user}, + 'autologin-session' => get_session_file($autologin->{desktop}), + )) } if -e $lightdm_conffile; + + #- Configure LXDM + my $lxdm_conffile = "$::prefix/etc/lxdm/lxdm.conf"; + eval { update_gnomekderc($lxdm_conffile, 'base' => ( + 'autologin' => $autologin->{user} ? '@' . $autologin->{user} : '' + )); + if ($autologin->{user} && $autologin->{desktop} && !member($autologin->{desktop}, qw(default failsafe))) { + update_gnomekderc($lxdm_conffile, $autologin->{user} => ( + 'user' => $autologin->{user}, + 'session' => get_session_file($autologin->{desktop}), + )) } } if -e $lxdm_conffile; + + #- Configure XDM my $xdm_autologin_cfg = "$::prefix/etc/sysconfig/autologin"; - # TODO: configure lxdm in /etx/lxdm/lxdm.conf if (is_standalone_autologin_needed($autologin->{dm})) { setVarsInShMode($xdm_autologin_cfg, 0644, { USER => $autologin->{user}, AUTOLOGIN => bool2yesno($autologin->{user}), EXEC => '/usr/bin/startx.autologin' }); @@ -745,6 +948,7 @@ sub set_autologin { $desktop{DESKTOP} = $autologin->{desktop}; $desktop{DISPLAYMANAGER} = $autologin->{dm}; setVarsInSh($sys_conffile, \%desktop); + symlinkf("/usr/lib/systemd/system/$autologin->{dm}.service", "$::prefix/etc/systemd/system/display-manager.service"); if ($autologin->{user}) { my $home = (getpwnam($autologin->{user}))[7]; @@ -885,7 +1089,7 @@ sub ask_user_and_root { my $id = $u->{$field} or return 'ok'; my $name = $field eq 'uid' ? N("User ID") : N("Group ID"); $id =~ /^\d+$/ or $in->ask_warn('', N("%s must be a number", $name)), return; - $id >= 500 or $in->ask_yesorno('', N("%s should be above 500. Accept anyway?", $name)) or return; + $id >= 1000 or $in->ask_yesorno('', N("%s should be above 1000. Accept anyway?", $name)) or return; 'ok'; }; my $ret = $in->ask_from_( @@ -894,7 +1098,9 @@ sub ask_user_and_root { if_($::isInstall && $superuser, cancel => ''), }, [ $superuser ? ( + if_(0, { text => N("Enable guest account"), val => \$xguest, type => 'bool', advanced => 1 }, + ), { label => N("Set administrator (root) password"), title => 1 }, { label => N("Password"), val => \$superuser->{password}, hidden => 1, alignment => 'right', weakness_check => 1, focus => sub { 1 }, @@ -921,9 +1127,10 @@ sub ask_user_and_root { { label => N("Shell"), val => \$u->{shell}, list => [ shells() ], advanced => 1 }, { label => N("User ID"), val => \$u->{uid}, advanced => 1, validate => sub { $validate_uid_gid->('uid') } }, { label => N("Group ID"), val => \$u->{gid}, advanced => 1, validate => sub { $validate_uid_gid->('gid') } }, - if_($security > 3, + if_($security >= 1, + { label => N("Extra Groups:"), advanced => 1, title => 1 }, map { - { label => $_, val => \$groups{$_}, text => $high_security_groups{$_}, type => 'bool' }; + { label => $_, val => \$groups{$_}, text => $high_security_groups{$_}, type => 'bool', advanced => 1 }; } keys %high_security_groups, ), ], @@ -943,7 +1150,12 @@ sub ask_user_and_root { } sub sessions() { - split(' ', run_program::rooted_get_stdout($::prefix, '/usr/sbin/chksession', '-l')); + my @l; + my @dir_wm = qw(xsessions wayland-sessions); + foreach my $dwm (@dir_wm) { + push @l, map { s/.desktop$//; basename($_) } glob("$::prefix/usr/share/$dwm/*.desktop"); + } + @l; } sub sessions_with_order() { my %h = map { /(.*)=(.*)/ } split(' ', run_program::rooted_get_stdout($::prefix, '/usr/sbin/chksession', '-L')); @@ -951,20 +1163,32 @@ sub sessions_with_order() { } sub urpmi_add_all_media { - my ($in, $o_previous_release) = @_; + my ($in, $o_previous_release, $o_mirror_url) = @_; - my $binary = find { whereis_binary($_, $::prefix) } if_(check_for_xserver(), 'gurpmi.addmedia'), 'urpmi.addmedia' or return; + $o_mirror_url = undef if $o_mirror_url eq '$MIRRORLIST'; + + my $binary = find { whereis_binary($_, $::prefix) } if_(check_for_xserver(), 'gurpmi.addmedia'), 'urpmi.addmedia'; + if (!$binary) { + log::l("urpmi.addmedia not found!"); + return; + } #- configure urpmi media if network is up require network::tools; - return if !network::tools::has_network_connection(); + if (!network::tools::has_network_connection()) { + log::l("no network connexion!"); + return; + } + # First remove all media: + run_program::rooted($::prefix, 'urpmi.removemedia', '-a'); + # Then add online media: my $wait; - my @options = ('--distrib', '--mirrorlist', '$MIRRORLIST'); + my @options = $o_mirror_url ? ( '--distrib', $o_mirror_url) : ('--distrib', '--mirrorlist', '$MIRRORLIST'); if ($binary eq 'urpmi.addmedia') { $wait = $in->wait_message(N("Please wait"), N("Please wait, adding media...")); } elsif ($in->isa('interactive::gtk')) { push @options, '--silent-success'; - mygtk2::flush(); + mygtk3::flush(); } my $reason = join(',', $o_previous_release ? @@ -975,10 +1199,46 @@ sub urpmi_add_all_media { my $log_file = '/root/drakx/updates.log'; my $val = run_program::rooted($::prefix, $binary, '>>', $log_file, '2>>', $log_file, @options); + undef $wait; $val; } +sub urpmi_set_downloader { + my ($in, $urpm, $downloader) = @_; + + if ($urpm->{global_config}{downloader} ne $downloader) { + my $binary = $downloader eq 'aria2' ? 'aria2c' : $downloader; + if ($in->do_pkgs->ensure_binary_is_installed($downloader, $binary, 1)) { + log::l("Setting urpmi downloader to '$downloader'"); + $urpm->{global_config}{downloader} = $downloader; + urpm::media::write_config($urpm); + } else { + return; + } + } + 1; +} + +sub format_wm { + my ($wm) = @_; + return { + cinnamon => 'Cinnamon', + enlightenment => 'Enlightenment', + 'gnome-classic' => 'GNOME Classic', + gnome => 'GNOME', + i3 => 'I3', + 'i3-with-shmlog' => 'I3 with shmlog', + lxqt => 'LxQt', + mate => 'Mate', + openbox => 'OpenBox', + 'plasma-mediacenter' => 'Plasma Mediacenter', + '01plasma' => 'Plasma', + sugar => 'Sugar', + xfce => 'Xfce', + }->{$wm}; +} + sub autologin { my ($o, $in) = @_; @@ -997,7 +1257,7 @@ sub autologin { messages => N("I can set up your computer to automatically log on one user.") }, [ { text => N("Use this feature"), val => \$use_autologin, type => 'bool' }, { label => N("Choose the default user:"), val => \$o->{autologin}, list => \@users, disabled => sub { !$use_autologin } }, - { label => N("Choose the window manager to run:"), val => \$o->{desktop}, list => \@wm, disabled => sub { !$use_autologin } } ] + { label => N("Choose the window manager to run:"), val => \$o->{desktop}, list => \@wm, disabled => sub { !$use_autologin }, format => \&format_wm } ] ); delete $o->{autologin} if !$use_autologin; } else { @@ -1014,27 +1274,28 @@ sub display_release_notes { return; } - require Gtk2::WebKit; - require ugtk2; - ugtk2->import(':all'); - require mygtk2; - mygtk2->import('gtknew'); - my $view = gtknew('WebKit_View', no_popup_menu => 1); - $view->load_html_string($release_notes, '/'); + require Gtk3::WebKit2; + Gtk3::WebKit2->import; + require ugtk3; + ugtk3->import(':all'); + require mygtk3; + mygtk3->import('gtknew'); + my $view = gtknew('WebKit2_WebView', no_popup_menu => 1); + $view->load_html($release_notes, '/'); - my $w = ugtk2->new(N("Release Notes"), transient => $::main_window, modal => 1, pop_it => 1); + my $w = ugtk3->new(N("Release Notes"), transient => $::main_window, modal => 1, pop_it => 1); gtkadd($w->{rwindow}, - gtkpack_(Gtk2::VBox->new, - 1, create_scrolled_window(ugtk2::gtkset_border_width($view, 5), + gtkpack_(Gtk3::VBox->new, + 1, create_scrolled_window(ugtk3::gtkset_border_width($view, 5), [ 'never', 'automatic' ], ), 0, gtkpack(create_hbox('end'), gtknew('Button', text => N("Close"), - clicked => sub { Gtk2->main_quit }) + clicked => sub { Gtk3->main_quit }) ), ), ); - mygtk2::set_main_window_size($w->{rwindow}); + mygtk3::set_main_window_size($w->{rwindow}); $w->{real_window}->grab_focus; $w->{real_window}->show_all; $w->main; @@ -1055,7 +1316,7 @@ sub get_release_notes { my $d = find { -e "$_/$file" } glob_("/usr/share/doc/*-release-*"); $d && cat_("$d/$file"); } - } "release-notes$ext", 'release-notes.' . arch() . $ext); + } "release-notes$ext", 'release-notes.' . $ext); # we do not handle links: $release_notes =~ s!<a href=".*?">(.*?)</a>!$1!g; @@ -1065,7 +1326,8 @@ sub get_release_notes { sub run_display_release_notes { my ($release_notes) = @_; output('/tmp/release_notes.html', $release_notes); - system('/usr/bin/display_release_notes.pl'); + local $ENV{LC_ALL} = $::o->{locale}{lang} || 'C'; + run_program::raw({ detach => 1 }, '/usr/bin/display_release_notes.pl'); } sub acceptLicense { @@ -1188,7 +1450,7 @@ sub selectLanguage_standalone { ]); $locale->{utf8} = !$non_utf8; lang::set($locale); - Gtk2->set_locale if $in->isa('interactive::gtk'); + c::init_setlocale() if $in->isa('interactive::gtk'); lang::lang_changed($locale) if $old_lang ne $locale->{lang}; } @@ -1258,20 +1520,29 @@ sub set_login_serial_console { substInFile { s/^s$port:.*//; $_ = $line if eof } "$::prefix/etc/inittab"; } -sub report_bug { - my (@other) = @_; - - sub header { " +sub header { " ******************************************************************************** * $_[0] ********************************************************************************"; - } +} + +sub fdisk() { + my @devs = grep { !m!^/dev/(loop|ram)\d+! && !/\d$/ } map { "/dev/$_->{dev}" } fs::proc_partitions::read_raw(); + `fdisk -l @devs`; + +} + +sub report_bug { + my (@other) = @_; join '', map { chomp; "$_\n" } header("lspci"), detect_devices::stringlist(), + header("hid_devices"), (map { sprintf("%-16s: %s", $_->{driver} || "unknown", $_->{description}) } c::hid_probe()), + header("input devices"), cat_("/proc/bus/input/devices"), + header("libinput devices"), `libinput list-devices`, header("pci_devices"), cat_("/proc/bus/pci/devices"), header("dmidecode"), arch() =~ /86/ ? `dmidecode` : (), - header("fdisk"), arch() =~ /ppc/ ? `pdisk -l` : `fdisk -l`, + header("fdisk"), fdisk(), header("scsi"), cat_("/proc/scsi/scsi"), header("/sys/bus/scsi/devices"), -d '/sys/bus/scsi/devices' ? `ls -l /sys/bus/scsi/devices` : (), header("lsmod"), cat_("/proc/modules"), @@ -1279,23 +1550,34 @@ sub report_bug { header("pcmcia: stab"), cat_("$::prefix/var/lib/pcmcia/stab") || cat_("$::prefix/var/run/stab"), header("usb"), cat_("/sys/kernel/debug/usb/devices"), header("partitions"), cat_("/proc/partitions"), + header("PVs"), `pvs`, + header("VGs"), `vgs`, + header("LVs"), `lvs`, + header("dmsetup info"), `dmsetup info`, + header("dmsetup table"), `dmsetup table`, + header("dmsetup ls"), `dmsetup ls`, header("cpuinfo"), cat_("/proc/cpuinfo"), - header("syslog"), cat_("/tmp/syslog") || cat_("$::prefix/var/log/syslog"), + header("syslog"), cat_("/tmp/syslog") || cat_("$::prefix/var/log/syslog") || `journalctl -q -D $::prefix/var/log/journal -b`, header("Xorg.log"), cat_("/var/log/Xorg.0.log"), header("monitor_full_edid"), monitor_full_edid(), header("stage1.log"), cat_("/tmp/stage1.log") || cat_("$::prefix/root/drakx/stage1.log"), header("ddebug.log"), cat_("/tmp/ddebug.log") || cat_("$::prefix/root/drakx/ddebug.log"), header("install.log"), cat_("$::prefix/root/drakx/install.log"), + header("draklive-install.log"), cat_("/tmp/draklive-install.log") || cat_("$::prefix/root/drakx/draklive-install.log"), header("fstab"), cat_("$::prefix/etc/fstab"), header("modprobe.conf"), cat_("$::prefix/etc/modprobe.conf"), header("lilo.conf"), cat_("$::prefix/etc/lilo.conf"), header("grub: menu.lst"), join('', map { s/^(\s*password)\s+(.*)/$1 xxx/; $_ } cat_("$::prefix/boot/grub/menu.lst")), header("grub: install.sh"), cat_("$::prefix/boot/grub/install.sh"), header("grub: device.map"), cat_("$::prefix/boot/grub/device.map"), + header("grub2: grub"), cat_("$::prefix/etc/default/grub"), + header("grub2: grub.cfg"), join('', map { s/^(\s*password_pbkdf2)\s+grub.pbkdf2.*/$1 xxx/; $_ } cat_("$::prefix/boot/grub2/grub.cfg")), + header("grub2: install.sh"), cat_("$::prefix/boot/grub2/install.sh"), header("xorg.conf"), cat_("$::prefix/etc/X11/xorg.conf"), header("urpmi.cfg"), cat_("$::prefix/etc/urpmi/urpmi.cfg"), header("modprobe.preload"), cat_("$::prefix/etc/modprobe.preload"), header("sysconfig/i18n"), cat_("$::prefix/etc/sysconfig/i18n"), + header("locale.conf"), cat_("$::prefix/etc/locale.conf"), header("/proc/iomem"), cat_("/proc/iomem"), header("/proc/ioport"), cat_("/proc/ioports"), map_index { even($::i) ? header($_) : $_ } @other; @@ -1342,7 +1624,7 @@ Allowing this will permit users to simply click on \"Share\" in konqueror and na nfs => [ 'nfs-utils', 'nfs-server', N("NFS: the traditional Unix file sharing system, with less support on Mac and Windows.") ], - smb => [ 'samba-server', 'smb', + smb => [ 'samba', 'smb', N("SMB: a file sharing system used by Windows, Mac OS X and many modern Linux systems.") ], ); @@ -1358,7 +1640,7 @@ Allowing this will permit users to simply click on \"Share\" in konqueror and na } foreach (keys %types) { my ($pkg, $service, $_descr) = @{$types{$_}}; - my $file = "/etc/init.d/$service"; + my $file = "/usr/lib/systemd/system/${service}.service"; if ($l{$_}) { $in->do_pkgs->ensure_is_installed($pkg, $file) or return; services::start($service); @@ -1390,15 +1672,17 @@ You can use userdrake to add a user to this group.") } sub monitor_full_edid() { - return if $::noauto; + return if $::noauto || $::local_install; my ($vbe, $edid); { # prevent warnings in install's logs: local $ENV{LC_ALL} = 'C'; + # don't use --try-in-console as it can cause a GNOME session to die (mga#28124) + # with most DMs the DE is running in vt1, so it does nothing anyway run_program::raw({ timeout => 20 }, 'monitor-edid', '>', \$edid, '2>', \$vbe, - '-v', '--perl', if_($::isStandalone, '--try-in-console')); + '-v', '--perl'); } if ($::isInstall) { foreach (['edid', \$edid], ['vbe', \$vbe]) { @@ -1420,7 +1704,7 @@ sub monitor_full_edid() { # FIXME: is buggy regarding multiple sessions sub running_window_manager() { - my @window_managers = qw(drakx-matchbox-window-manager ksmserver kwin gnome-session icewm wmaker afterstep fvwm fvwm2 fvwm95 mwm twm enlightenment xfce4-session blackbox sawfish olvwm fluxbox compiz lxsession); + my @window_managers = qw(drakx-matchbox-window-manager ksmserver kwin kwin_x11 kwin_wayland gnome-session icewm wmaker afterstep fvwm fvwm2 fvwm95 mwm twm enlightenment xfce4-session blackbox sawfish olvwm fluxbox compiz lxsession); foreach (@window_managers) { my @pids = fuzzy_pidofs(qr/\b$_\b/) or next; @@ -1584,4 +1868,158 @@ sub enable_x_screensaver() { run_program::run("xset", "s", "reset"); } +=item ask_url($in, $o_url) + +Asks URL of the mirror + +=cut + +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!^(https?|ftp)://!) { + 1; + } else { + $in->ask_warn('', N("URL must start with ftp:// or http:// or https://")); + 0; + } + } } ]) && $url; +} + +=item ask_mirror($in, $type, $o_url) + +Retrieves list of mirrors and offers to pick one + +=cut + +sub ask_mirror { + my ($in, $type, $o_url) = @_; + + require mirror; + + my $mirrors = eval { + my $_w = $in->wait_message('', N("Contacting %s web site to get the list of available mirrors...", N("Mageia"))); + mirror::list($in->{product_id}, $type); + }; + my $err = $@; + if (!$mirrors) { + $in->ask_warn('', N("Failed contacting %s web site to get the list of available mirrors", N("Mageia")) . "\n$err"); + return ask_url($in, $o_url); + } + + my $give_url = { country => '-', host => 'URL' }; + + my $mirror; + if ($o_url) { + $mirror = (find { $_->{url} eq $o_url } @$mirrors) || $give_url; + } else { + #- use current time zone to select best mirror + require urpm::mirrors; + my $urpm = $in->{packages} || { log => \&log::l }; + urpm::mirrors::add_proximity_and_sort($urpm, $mirrors); + $mirror = @$mirrors[0] || $give_url; + } + $in->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($in, $o_url) or goto &ask_mirror; + } else { + $url = $mirror->{url}; + } + $url =~ s!/main/?$!!; + log::l("chosen mirror: $url"); + $url; +} + +=item ask_mirror_and_downloader($in, $options, $o_downloader_only) + +Asks whether to automatically select the mirror (using $MIRRORLIST) or use +one specified by the user. Also asks whether to use the default downloader +or to use one specified by the user. + +Default values are supplied and user-entered values are returned in $options +which should be a reference to a hash containing the following fields: + +=over 4 + +=item * B<mirror_url>: the currently selected mirror URL ('$MIRRORLIST' for automatic selection) + +=item * B<downloader>: the currently selected downloader (undefined when using the default downloader) + +=back + +If $o_downloader_only is true, the mirror selection choice is not displayed. + +=cut + +sub ask_mirror_and_downloader { + my ($in, $options, $o_downloader_only) = @_; + + my $mirror_url = $options->{mirror_url} || ''; + my $downloader = $options->{downloader} || 'default'; + + my $mirror_choice = $mirror_url eq '$MIRRORLIST' ? 'automatic' : 'specific'; + + my $enable_aria2 = $::isInstall || $in->do_pkgs->is_installed('aria2', '/usr/bin/aria2c'); + my $enable_curl = $::isInstall || $in->do_pkgs->is_installed('curl', '/usr/bin/curl'); + my $enable_wget = $::isInstall || $in->do_pkgs->is_installed('wget', '/usr/bin/wget'); + + $in->ask_from_( + { + }, + [ + if_(!$o_downloader_only, + { label => N("Mirror choice"), val => \$mirror_choice, + type => 'combo', list => [ 'automatic', 'specific' ], + format => sub { + my ($choice) = @_; + +{ + 'automatic' => N("Automatic"), + 'specific' => N("Specific"), + }->{$choice}; + }, + }, + ), + { label => N("Downloader"), val => \$downloader, + type => 'combo', list => [ 'default', 'aria2', 'curl', 'wget' ], + format => sub { + my ($choice) = @_; + +{ + 'default' => N("Default"), + if_($enable_aria2, 'aria2' => 'aria2'), + if_($enable_curl, 'curl' => 'curl'), + if_($enable_wget, 'wget' => 'wget'), + }->{$choice}; + }, + }, + ] + ) or return; + + if ($mirror_choice eq 'automatic') { + $mirror_url = '$MIRRORLIST'; + } elsif ($mirror_url eq '$MIRRORLIST') { + $mirror_url = undef; + } + if ($downloader eq 'default') { + $downloader = undef; + } + + $options->{mirror_url} = $mirror_url; + $options->{downloader} = $downloader; + + 1; +} + 1; |