diff options
Diffstat (limited to 'perl-install/standalone/finish-install')
-rwxr-xr-x | perl-install/standalone/finish-install | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/perl-install/standalone/finish-install b/perl-install/standalone/finish-install new file mode 100755 index 000000000..81a2f00e5 --- /dev/null +++ b/perl-install/standalone/finish-install @@ -0,0 +1,310 @@ +#!/usr/bin/perl + +use lib qw(/usr/lib/libDrakX); + +# i18n: IMPORTANT: to get correct namespace (drakx-kbd-mouse-x11 and drak3d instead of libDrakX) +BEGIN { unshift @::textdomains, 'drakx-net', 'drakx-kbd-mouse-x11', 'drak3d' } + +use standalone; +use common; +use interactive; +use any; +use authentication; +use network::network; +use security::level; +use messages; + +my $conf_file = '/etc/sysconfig/finish-install'; +my %conf = getVarsFromSh($conf_file); +my $authentication = authentication::get(); +my $security = security::level::get(); +my $net = {}; +my $locale; +my $timezone; +network::network::read_net_conf($net); + +$::isWizard = 1; +my $in = 'interactive'->vnew('su'); +$in->{untranslated_license} = messages::main_license_raw(); + +any::set_wm_hints_if_needed($in); + +sub get_conf { + my ($name) = @_; + $conf{lc($name)} || $conf{uc($name)}; +} + +sub ask_license() { + local $::isWizard = 0; + any::acceptLicense($in); +} + +sub ask_language() { + require lang; + $locale = lang::read(); + my ($lang) = cat_("/proc/cmdline") =~ /\blang=(.+?)\b/; + my $h = lang::lang_to_ourlocale($lang); + if ($lang && member($h->{lang}, lang::list_langs(exclude_non_installed => 1))) { + put_in_hash($locale, $h); + lang::set($locale); + } + any::selectLanguage_standalone($in, $locale); + lang::write_and_install($locale, $in->do_pkgs); +} + +sub ask_keyboard() { + require keyboard; + my $keyboard = $locale ? keyboard::lang2keyboard($locale->{lang}) : keyboard::read_or_default(); + + choose: + $keyboard->{KEYBOARD} = $in->ask_from_listf(N("Keyboard"), + N("Please choose your keyboard layout."), + sub { translate(keyboard::KEYBOARD2text($_[0])) }, + [ keyboard::KEYBOARDs() ], + $keyboard->{KEYBOARD}) or return; + + keyboard::group_toggle_choose($in, $keyboard) or goto choose; + + keyboard::configure_and_set_standalone($keyboard); +} + +#- TIMEZONE=simplified: do not ask timezone and make ntp settings advanced +sub ask_timezone() { + require timezone; + $timezone = timezone::read(); + $timezone->{timezone} = timezone::bestTimezone($locale->{country}) if $locale->{country}; + any::configure_timezone($in, $timezone, 'ask_gmt', lc(get_conf('TIMEZONE')) eq 'simplified'); + + $in->do_pkgs->ensure_is_installed('chrony') if $timezone->{ntp}; + timezone::write($timezone); + + #- reload sys clock from hc once we know the real timezone + timezone::reload_sys_clock($timezone); +} + +#- COUNTRY=simplified: guess the country from timezone, do not ask +sub ask_country() { + require lang; + $locale ||= lang::read(); + require Time::ZoneInfo; + my $zones = Time::ZoneInfo->new; + if ($timezone && $zones) { + #- guess only if timezone has been asked already + if (my $zone = $zones->current_zone) { + if (my $country_code = $zones->country($zone)) { + $locale->{country} = $country_code; + } + } + } + any::selectCountry($in, $locale) if lc(get_conf('COUNTRY')) ne 'simplified'; + lang::write_and_install($locale, $in->do_pkgs); +} + +sub ask_network() { + require network::tools; + require services; + return if network::tools::has_network_connection(); + + #- test again connection after waiting for network up + my $w = $in->wait_message(N("Please wait"), N("Testing your connection...")); + if (services::starts_on_boot('NetworkManager')) { + my $time = 0; + while ($time < 20 && run_program::get_stdout('systemctl show -p SubState NetworkManager-wait-online') =~ /start/) { + $time++; + sleep(1); + } + } else { + services::start('network-up'); + } + undef $w; + return if network::tools::has_network_connection(); + + require network::netconnect; + my $modules_conf = modules::any_conf->read; + network::netconnect::real_main($net, $in, $modules_conf); + $modules_conf->write; +} + +sub ask_urpmi() { + #- configure urpmi media if no online media are configured + my @media_url = map { top(split(' ', $_)) } run_program::get_stdout('urpmq', '--list-url'); + my @online_media = grep { !m,^(?:file://)?/, } @media_url; + @online_media and return; + any::urpmi_add_all_media($in); +} + +sub set_authentication { + my ($superuser) = @_; + authentication::set_root_passwd($superuser, $authentication); + my $ok = eval { + authentication::set($in, $net, $authentication) or return; + network::network::write_network_conf($net); + 1; + }; + $in->ask_warn(N("Error"), formatError($@)) if $@; + return $ok; +} + +sub ask_authentication() { + my $meta_class = { getVarsFromSh("/etc/sysconfig/system") }->{META_CLASS}; + my $superuser = {}; + authentication::ask_root_password_and_authentication($in, $net, $superuser, $authentication, $meta_class, $security); + set_authentication($superuser) or goto &ask_authentication; +} + +#- USERS=with_root: asks both root and user accounts +#- USER_RENAME_FROM=<old user>: create the new user by renaming <old user> +#- USER_AUTOLOGIN_FIRST: configure autologin for the first added user +sub ask_users() { + my $users = []; + my $superuser = to_bool(lc(get_conf('USERS')) eq 'with_root') && {}; + any::ask_user_and_root($in, $superuser, $users, $security); + my $old_user = get_conf('USER_RENAME_FROM'); + if (@$users && $old_user) { + $users->[0]{rename_from} = $old_user; + $users->[0]{home} ||= '/home/' . $users->[0]{name}; + } + my $autologin = any::get_autologin(); + my $autologin_first = ($autologin->{user} eq $old_user || lc(get_conf('USER_AUTOLOGIN_FIRST')) eq "yes") && $autologin->{desktop}; + if ($superuser) { + set_authentication($superuser) or goto &ask_users; + } + any::add_users($users, $authentication); + if ($autologin_first) { + $autologin->{user} = $users->[0]{name}; + $autologin->{desktop} = $autologin_first; + any::set_autologin($in->do_pkgs, $autologin); + } + my $finit_conf = "/etc/finit.conf"; + substInFile { + s/^user .*//; + $_ .= "user $users->[0]{name}\n" if eof; + } $finit_conf if -e $finit_conf; + if ($old_user) { + my $new_user = $users->[0]{name}; + #- replace home path in user config files + my $old_home = "/home/$old_user"; + my $new_home = "/home/$new_user"; + run_program::run(qq(grep -D skip -rl $old_home $new_home/.??* | while read f; do perl -pi -e 's,$old_home,$new_home,g' "\$f"; done)); + #- give console rights for current session + my $console_dir = "/var/run/console"; + cp_f($console_dir . "/" . $old_user, $console_dir . "/" . $new_user) if -e $console_dir . "/" . $old_user; + #- update user name in network configurations + #- for now, only support the case of a single user name + require services; + my $using_networkmanager = services::is_service_running('NetworkManager'); + foreach my $f (glob('/etc/sysconfig/network-scripts/ifcfg-*')) { + if (cat_($f) =~ /\nUSERS=$old_user\n/) { + run_program::run('perl', '-pi', '-e', "s,^USERS=$old_user,USERS=$new_user,", $f); + run_program::run('nmcli', 'con', 'load', $f) if $using_networkmanager; + } + } + } +} + +sub ask_glx() { + require Xconfig::glx; + my @installed_types = Xconfig::glx::filter_installed_types(\@Xconfig::glx::gl_compositing_types); + any { $_->{type} ne "none" } @installed_types or return; + my $glx = Xconfig::glx::detect_may_install($in->do_pkgs); + if ($glx->{supported} && Xconfig::glx::choose_interactive($in, $glx, 'installed_only')) { + Xconfig::glx::write($glx); + } +} + +sub ask_encrypt_home() { + my $user = { name => get_conf('ENCRYPT_HOME_USER'), device => get_conf('ENCRYPT_HOME_DEVICE') }; + any { !defined $_ } values %$user and return; + $in->ask_from(N("Encrypted home partition"), N("Please enter a password for the %s user", $user->{name}), + [ + { label => N("Password"), val => \$user->{password}, hidden => 1 }, + { label => N("Password (again)"), val => \$user->{password2}, hidden => 1 }, + ], + complete => sub { + authentication::check_given_password($in, $user, 6) or return 1,0; + return 0; + }); + authentication::write_passwd_user($user, $authentication); + encrypt_home($user); +} + +sub encrypt_home { + my ($user) = @_; + my $device = $user->{device}; + my $mapper = '/dev/mapper/' . $user->{name}; + my $home = '/home/' . $user->{name}; + my $wait = $in->wait_message(N("Encrypted home partition"), N("Creating encrypted home partition")); + + substInFile { + s/^volume $user->{name}.*//; + $_ .= "volume $user->{name} crypt - $device $home - - -\n" if eof; + } $::prefix . '/etc/security/pam_mount.conf'; + + authentication::set_pam_authentication('mount'); + + run_program::raw({ root => $::prefix, sensitive_arguments => 1 }, + "echo -e $user->{password} | cryptsetup luksFormat $device"); + run_program::raw({ root => $::prefix, sensitive_arguments => 1 }, + "echo -e $user->{password} | cryptsetup luksOpen $device $user->{name}"); + $wait = $in->wait_message(N("Encrypted home partition"), N("Formatting encrypted home partition")); + run_program::rooted($::prefix, 'mke2fs', '-qj', '-m', 0, '-L', 'Home', $mapper); + + my $old_home; + if (-d $::prefix . $home) { + #- if already existing, move home to a temporary folder + require File::Temp; + $old_home = File::Temp::tempdir(DIR => dirname($::prefix . $home)); + rmdir $old_home; + rename $::prefix . $home, $old_home; + } + + mkdir_p($::prefix . $home); + run_program::rooted($::prefix, 'mount', $mapper, $home); + + if ($old_home) { + #- copy previous home back + require File::Copy::Recursive; + File::Copy::Recursive::dirmove($old_home, $::prefix . $home); + } + run_program::rooted($::prefix, 'chown', '-R', join(':', ($user->{name}) x 2), $home); + rmdir $::prefix . $home . '/lost+found'; + + run_program::rooted($::prefix, 'umount', $home); + run_program::rooted($::prefix, 'cryptsetup', 'luksClose', $user->{name}); + undef $wait; +} + +sub call { + my ($step_name) = @_; + my $f_name = 'ask_' . $step_name; + if (lc(get_conf($step_name)) eq 'no') { + log::l("ignoring $f_name"); + } else { + log::l("calling $f_name"); + my $f = $::{$f_name} or internal_error "bad function $f_name"; + eval { $f->() }; + log::l("$f_name failed: $@") if $@; + } +} + +call('language'); +call('license'); +# "Previous" button isn't functiunnal and acts like "next" (#25349) +$::Wizard_no_previous = 1; +call('timezone'); +call('country'); +call('keyboard'); +call('network'); +if (defined $::WizardWindow) { + $::WizardWindow->destroy; + undef $::WizardWindow; +} +call('urpmi'); +$::Wizard_pix_up = 'redhat-config-users'; +call('authentication'); +call('users'); +call('encrypt_home'); +call('glx'); +setVarsInSh($conf_file, { FINISH_INSTALL => 'no' }); + +$in->exit(0); |