X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=proxinstall;h=5ef12cb70799f7f5343563caf7b43ac97f4fff7e;hb=ebc4f76fa1ca0f2101f463c8df059aa396cbfb8f;hp=b19c8c97ec0d5cc15bb355137e5cbc71b4764563;hpb=dc4942618e0e5660bdf650bd2c66bcdfc2a2c5cc;p=pve-installer.git diff --git a/proxinstall b/proxinstall index b19c8c9..5ef12cb 100755 --- a/proxinstall +++ b/proxinstall @@ -190,9 +190,54 @@ my $ipv4_reverse_mask = [ '255.255.255.255', ]; +my $step_number = 0; # Init number for global function list + +my @steps = ( + { + step => 'intro', + html => 'license.htm', + next_button => 'I a_gree', + function => \&create_intro_view, + }, + { + step => 'intro', + html => 'page1.htm', + function => \&create_hdsel_view, + }, + { + step => 'country', + html => 'country.htm', + function => \&create_country_view, + }, + { + step => 'password', + html => 'passwd.htm', + function => \&create_password_view, + }, + { + step => 'ipconf', + html => 'ipconf.htm', + function => \&create_ipconf_view, + }, + { + step => 'ack', + html => 'ack.htm', + next_button => '_Install', + function => \&create_ack_view, + }, + { + step => 'extract', + next_button => '_Reboot', + function => \&create_extract_view, + }, +); + +# GUI global variables my ($window, $cmdbox, $inbox, $htmlview); +my $prev; my ($next, $next_fctn, $target_hd); my ($progress, $progress_status); + my ($ipversion, $ipaddress, $ipconf_entry_addr); my ($netmask, $ipconf_entry_mask); my ($gateway, $ipconf_entry_gw); @@ -203,11 +248,28 @@ my $cmdline = file_read_firstline("/proc/cmdline"); my $ipconf; my $country; my $timezone = 'Europe/Vienna'; -my $password; -my $mailto; my $keymap = 'en-us'; +my $password; +my $mailto = 'mail@example.invalid'; my $cmap; +my $config = { + # TODO: add all the user-provided options for previous button + country => $country, + timezone => $timezone, + keymap => $keymap, + + password => $password, + mailto => $mailto, + + mngmt_nic => undef, + hostname => $hostname, + fqdn => undef, + ipaddress => undef, + netmask => undef, + gateway => undef, +}; + # parse command line args my $config_options = {}; @@ -814,36 +876,6 @@ sub zfs_create_rpool { if defined($value) && $value != 1; } -sub zfs_create_swap { - my ($swapsize) = @_; - - my $cmd = "zfs create -V ${swapsize}K -b 4K"; - - $cmd .= " -o com.sun:auto-snapshot=false"; - - # copies for swap does not make sense - $cmd .= " -o copies=1"; - - # reduces memory pressure - $cmd .= " -o sync=always"; - - # cheapest compression to drop zero pages - $cmd .= " -o compression=zle"; - - # skip log devices - $cmd .= " -o logbias=throughput"; - # only cache metadata in RAM (caching swap content does not make sense) - $cmd .= " -o primarycache=metadata"; - # don't cache anything in L2ARC - $cmd .= " -o secondarycache=none"; - - $cmd .= " $zfspoolname/swap"; - syscmd ($cmd) == 0 || - die "unable to create zfs swap device\n"; - - return "/dev/zvol/$zfspoolname/swap"; -} - my $udevadm_trigger_block = sub { my ($nowait) = @_; @@ -867,7 +899,7 @@ my $clean_disk = sub { }; sub partition_bootable_disk { - my ($target_dev, $maxhdsize, $ptype) = @_; + my ($target_dev, $maxhdsizegb, $ptype) = @_; die "too dangerous" if $opt_testmode; @@ -878,13 +910,16 @@ sub partition_bootable_disk { my $hdsize = hd_size($target_dev); # size in KB (1024 bytes) my $restricted_hdsize_mb = 0; # 0 ==> end of partition - if ($maxhdsize && ($maxhdsize < $hdsize)) { - $hdsize = $maxhdsize; - $restricted_hdsize_mb = int($hdsize/1024) . 'M'; + if ($maxhdsizegb) { + my $maxhdsize = $maxhdsizegb * 1024 * 1024; + if ($maxhdsize < $hdsize) { + $hdsize = $maxhdsize; + $restricted_hdsize_mb = int($hdsize/1024) . 'M'; + } } my $hdgb = int($hdsize/(1024*1024)); - die "hardisk '$target_dev' too small (${hdsize}GB)\n" if $hdgb < 8; + die "hardisk '$target_dev' too small (${hdgb}GB)\n" if $hdgb < 8; # 1 - BIOS boot partition (Grub Stage2): first free 1M # 2 - EFI ESP: next free 512M @@ -1136,13 +1171,6 @@ sub extract_data { my ($devlist, $bootdevlist, $vdev) = get_zfs_raid_setup(); - my $maxhdsize; - if ($config_options->{hdsize}) { - # max hdsize passed on cmdline (GB) - $maxhdsize = $config_options->{hdsize}*1024*1024; - } - - my $disksize; foreach my $hd (@$devlist) { &$clean_disk(@$hd[1]); @@ -1151,7 +1179,7 @@ sub extract_data { my $devname = @$hd[1]; my ($size, $osdev) = - partition_bootable_disk($devname, $maxhdsize, 'BF01'); + partition_bootable_disk($devname, $config_options->{hdsize}, 'BF01'); zfs_mirror_size_check($disksize, $size) if $disksize; push @$bootdevinfo, { devname => $devname, osdev => $osdev}; $disksize = $size; @@ -1173,24 +1201,15 @@ sub extract_data { zfs_create_rpool($vdev); - my $swap_size = compute_swapsize($disksize); - $swapfile = zfs_create_swap($swap_size) if $swap_size; - } else { die "target '$target_hd' is not a valid block device\n" if ! -b $target_hd; - my $maxhdsize; - if ($config_options->{hdsize}) { - # max hdsize passed on cmdline (GB) - $maxhdsize = $config_options->{hdsize}*1024*1024; - } - &$clean_disk($target_hd); my ($os_size, $osdev, $efidev); ($os_size, $osdev, $efidev) = - partition_bootable_disk($target_hd, $maxhdsize, '8E00'); + partition_bootable_disk($target_hd, $config_options->{hdsize}, '8E00'); &$udevadm_trigger_block(); @@ -1707,6 +1726,8 @@ sub display_info { sub display_html { my ($filename) = @_; + $filename = $steps[$step_number]->{html} if !$filename; + my $path = "${proxmox_libdir}/html/$filename"; my $url = "file://$path"; @@ -1725,11 +1746,26 @@ sub display_html { $last_display_change = time(); } +sub prev_function { + + my ($text, $fctn) = @_; + + $fctn = $step_number if !$fctn; + $text = "_Previous" if !$text; + $prev->set_label ($text); + + $step_number--; + $steps[$step_number]->{function}(); + + $prev->grab_focus (); +} + sub set_next { my ($text, $fctn) = @_; $next_fctn = $fctn; - $text = "_Next" if !$text; + my $step = $steps[$step_number]; + $text //= $steps[$step_number]->{next_button} // '_Next'; $next->set_label ($text); $next->grab_focus (); @@ -1764,6 +1800,13 @@ sub create_main_window { $next = Gtk3::Button->new ('_Next'); $next->signal_connect (clicked => sub { $last_display_change = 0; &$next_fctn (); }); $cmdbox->pack_end ($next, 0, 0, 10); + + + $prev = Gtk3::Button->new ('_Previous'); + $prev->signal_connect (clicked => sub { $last_display_change = 0; &prev_function (); }); + $cmdbox->pack_end ($prev, 0, 0, 10); + + my $abort = Gtk3::Button->new ('_Abort'); $abort->set_can_focus (0); $cmdbox->pack_start ($abort, 0, 0, 10); @@ -1942,8 +1985,8 @@ my $ipconf_first_view = 1; sub create_ipconf_view { - cleanup_view (); - display_html ("ipconf.htm"); + cleanup_view(); + display_html(); my $vbox = Gtk3::VBox->new (0, 0); $inbox->pack_start ($vbox, 1, 0, 0); @@ -1952,13 +1995,15 @@ sub create_ipconf_view { my $vbox2 = Gtk3::VBox->new (0, 0); $hbox->add ($vbox2); + my $ipaddr_text = $config->{ipaddress} // "192.168.100.2"; my $ipbox; ($ipbox, $ipconf_entry_addr) = - create_text_input ("192.168.100.2", 'IP Address:'); + create_text_input ($ipaddr_text, 'IP Address:'); + my $netmask_text = $config->{netmask} // "255.255.255.0"; my $maskbox; ($maskbox, $ipconf_entry_mask) = - create_text_input ("255.255.255.0", 'Netmask:'); + create_text_input ($netmask_text, 'Netmask:'); my $device_cb = Gtk3::ComboBoxText->new(); $device_cb->set_active(0); @@ -1970,11 +2015,13 @@ sub create_ipconf_view { }; my $device_active_map = {}; + my $device_active_reverse_map = {}; my $device_change_handler = sub { my $current = shift; $ipconf->{selected} = $device_active_map->{$current->get_active()}; my $iface = $ipconf->{ifaces}->{$ipconf->{selected}}; + $config->{mngmt_nic} = $iface->{name}; $ipconf_entry_addr->set_text($iface->{inet}->{addr} || $iface->{inet6}->{addr}) if $iface->{inet}->{addr} || $iface->{inet6}->{addr}; $ipconf_entry_mask->set_text($iface->{inet}->{mask} || $iface->{inet6}->{mask}) @@ -1984,7 +2031,8 @@ sub create_ipconf_view { my $i = 0; foreach my $index (sort keys %{$ipconf->{ifaces}}) { $device_cb->append_text(&$get_device_desc($ipconf->{ifaces}->{$index})); - $device_active_map->{$i} = $index; + $device_active_map->{$i} = $index; + $device_active_reverse_map->{$ipconf->{ifaces}->{$index}->{name}} = $i; if ($ipconf_first_view && $index == $ipconf->{default}) { $device_cb->set_active($i); &$device_change_handler($device_cb); @@ -1994,8 +2042,11 @@ sub create_ipconf_view { $i++; } - $device_cb->set_active(0) - if !($ipconf->{selected}); + if (my $nic = $config->{mngmt_nic}) { + $device_cb->set_active($device_active_reverse_map->{$nic} // 0); + } else { + $device_cb->set_active(0); + } my $devicebox = Gtk3::HBox->new (0, 0); my $label = Gtk3::Label->new ("Management Interface:"); @@ -2006,8 +2057,7 @@ sub create_ipconf_view { $vbox2->pack_start ($devicebox, 0, 0, 2); - my $hn = $ipconf->{domain} ? - "$setup->{product}.$ipconf->{domain}" : "$setup->{product}.example.invalid"; + my $hn = $config->{fqdn} // "$setup->{product}." . ($ipconf->{domain} // "example.invalid"); my ($hostbox, $hostentry) = create_text_input ($hn, 'Hostname (FQDN):'); @@ -2017,7 +2067,7 @@ sub create_ipconf_view { $vbox2->pack_start ($maskbox, 0, 0, 2); - $gateway = $ipconf->{gateway} || '192.168.100.1'; + $gateway = $config->{gateway} // $ipconf->{gateway} || '192.168.100.1'; my $gwbox; ($gwbox, $ipconf_entry_gw) = @@ -2025,7 +2075,7 @@ sub create_ipconf_view { $vbox2->pack_start ($gwbox, 0, 0, 2); - $dnsserver = $ipconf->{dnsserver} || $gateway; + $dnsserver = $config->{dnsserver} // $ipconf->{dnsserver} || $gateway; my $dnsbox; ($dnsbox, $ipconf_entry_dns) = @@ -2043,6 +2093,8 @@ sub create_ipconf_view { $text =~ s/^\s+//; $text =~ s/\s+$//; + $config->{fqdn} = $text; + my $namere = "([a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?)"; # Debian does not support purely numeric hostnames @@ -2078,6 +2130,7 @@ sub create_ipconf_view { $ipconf_entry_addr->grab_focus(); return; } + $config->{ipaddress} = $ipaddress; $text = $ipconf_entry_mask->get_text(); $text =~ s/^\s+//; @@ -2091,6 +2144,7 @@ sub create_ipconf_view { $ipconf_entry_mask->grab_focus(); return; } + $config->{netmask} = $netmask; $text = $ipconf_entry_gw->get_text(); $text =~ s/^\s+//; @@ -2104,6 +2158,7 @@ sub create_ipconf_view { $ipconf_entry_gw->grab_focus(); return; } + $config->{gateway} = $gateway; $text = $ipconf_entry_dns->get_text(); $text =~ s/^\s+//; @@ -2117,15 +2172,54 @@ sub create_ipconf_view { $ipconf_entry_dns->grab_focus(); return; } + $config->{dnsserver} = $dnsserver; #print "TEST $ipaddress $netmask $gateway $dnsserver\n"; - create_extract_view (); + $step_number++; + create_ack_view(); }); $hostentry->grab_focus(); } +sub create_ack_view { + + cleanup_view(); + + my $ack_template = "${proxmox_libdir}/html/ack_template.htm"; + my $ack_html = "${proxmox_libdir}/html/$steps[$step_number]->{html}"; + my $html_data = file_get_contents($ack_template); + + my %config_values = ( + __target_hd__ => $target_hd, + __target_fs__ => $config_options->{filesys}, + __country__ => $country, + __timezone__ => $timezone, + __keymap__ => $keymap, + __mailto__ => $mailto, + __interface__ => $ipconf->{ifaces}->{$ipconf->{selected}}->{name}, + __hostname__ => $hostname, + __ip__ => $ipaddress, + __netmask__ => $netmask, + __gateway__ => $gateway, + __dnsserver__ => $dnsserver, + ); + + while ( my ($k, $v) = each %config_values) { + $html_data =~ s/$k/$v/g; + } + + write_config($html_data, $ack_html); + + display_html(); + + set_next(undef, sub { + $step_number++; + create_extract_view(); + }); +} + sub get_device_desc { my ($devname, $size, $model) = @_; @@ -2222,6 +2316,7 @@ sub create_password_view { $hbox1->pack_start ($label, 0, 0, 10); my $pwe1 = Gtk3::Entry->new (); $pwe1->set_visibility (0); + $pwe1->set_text($password) if $password; $pwe1->set_size_request (200, -1); $hbox1->pack_start ($pwe1, 0, 0, 0); @@ -2232,6 +2327,7 @@ sub create_password_view { $hbox2->pack_start ($label, 0, 0, 10); my $pwe2 = Gtk3::Entry->new (); $pwe2->set_visibility (0); + $pwe2->set_text($password) if $password; $pwe2->set_size_request (200, -1); $hbox2->pack_start ($pwe2, 0, 0, 0); @@ -2242,7 +2338,7 @@ sub create_password_view { $hbox3->pack_start ($label, 0, 0, 10); my $eme = Gtk3::Entry->new (); $eme->set_size_request (200, -1); - $eme->set_text('mail@example.invalid'); + $eme->set_text($mailto); $hbox3->pack_start ($eme, 0, 0, 0); @@ -2252,7 +2348,7 @@ sub create_password_view { $inbox->show_all; - display_html ("passwd.htm"); + display_html(); set_next (undef, sub { @@ -2288,6 +2384,7 @@ sub create_password_view { $password = $t1; $mailto = $t3; + $step_number++; create_ipconf_view(); }); @@ -2432,13 +2529,14 @@ sub create_country_view { $inbox->show_all; - display_html ("country.htm"); + display_html(); set_next (undef, sub { my $text = $w->get_text; if (my $cc = $countryhash->{lc($text)}) { $country = $cc; + $step_number++; create_password_view(); return; } else { @@ -2537,6 +2635,29 @@ my $create_raid_disk_grid = sub { # &$create_label_widget_grid($disk_labeled_widgets) }; +# shared between different ui parts (e.g., ZFS and "normal" single disk FS) +my $hdsize_size_adj; +my $hdsize_entry_buffer; + +my $get_hdsize_spinbtn = sub { + my $hdsize = shift; + + $hdsize_entry_buffer //= Gtk3::EntryBuffer->new(undef, 1); + + if (defined($hdsize)) { + $hdsize_size_adj = Gtk3::Adjustment->new($config_options->{hdsize} || $hdsize, 0, $hdsize+1, 1, 1, 1); + } else { + die "called get_hdsize_spinbtn with \$hdsize_size_adj not defined but did not pass hdsize!\n" + if !defined($hdsize_size_adj); + } + + my $spinbutton_hdsize = Gtk3::SpinButton->new($hdsize_size_adj, 1, 1); + $spinbutton_hdsize->set_buffer($hdsize_entry_buffer); + $spinbutton_hdsize->set_adjustment($hdsize_size_adj); + $spinbutton_hdsize->set_tooltip_text("only use specified size (GB) of the harddisk (rest left unpartitioned)"); + return $spinbutton_hdsize; +}; + my $create_raid_advanced_grid = sub { my $labeled_widgets = []; my $spinbutton_ashift = Gtk3::SpinButton->new_with_range(9,13,1); @@ -2591,6 +2712,7 @@ my $create_raid_advanced_grid = sub { $spinbutton_copies->set_value($config_options->{copies}); push @$labeled_widgets, "copies", $spinbutton_copies; + push @$labeled_widgets, "hdsize", $get_hdsize_spinbtn->(); return &$create_label_widget_grid($labeled_widgets);; }; @@ -2660,9 +2782,7 @@ sub create_hdoption_view { $hdsize = int((-s $target_hd) / (1024*1024*1024.0)); } - my $hdsize_size_adj = Gtk3::Adjustment->new($config_options->{hdsize} || $hdsize, 0, $hdsize+1, 1, 1, 1); - my $spinbutton_hdsize = Gtk3::SpinButton->new($hdsize_size_adj, 1, 1); - $spinbutton_hdsize->set_tooltip_text("only use specified size (GB) of the harddisk (rest left unpartitioned)"); + my $spinbutton_hdsize = $get_hdsize_spinbtn->($hdsize); push @$hdsize_labeled_widgets, "hdsize", $spinbutton_hdsize; my $entry_swapsize = Gtk3::Entry->new(); @@ -2909,6 +3029,8 @@ sub get_btrfs_raid_setup { sub create_hdsel_view { + $prev->set_sensitive(1); # enable previous button at this point + cleanup_view (); my $vbox = Gtk3::VBox->new (0, 0); @@ -2945,7 +3067,7 @@ sub create_hdsel_view { $inbox->show_all; - display_html ("page1.htm"); + display_html(); set_next (undef, sub { @@ -2955,6 +3077,7 @@ sub create_hdsel_view { display_message ("Warning: $err\n" . "Please fix ZFS setup first."); } else { + $step_number++; create_country_view(); } } elsif ($config_options->{filesys} =~ m/btrfs/) { @@ -2963,9 +3086,11 @@ sub create_hdsel_view { display_message ("Warning: $err\n" . "Please fix BTRFS setup first."); } else { + $step_number++; create_country_view(); } } else { + $step_number++; create_country_view(); } }); @@ -2977,7 +3102,7 @@ sub create_extract_view { display_info(); - $next->set_sensitive (0); + $next->set_sensitive(0); my $vbox = Gtk3::VBox->new (0, 0); $inbox->pack_start ($vbox, 1, 0, 0); @@ -2996,7 +3121,7 @@ sub create_extract_view { $vbox2->pack_start ($progress, 0, 0, 0); - $inbox->show_all; + $inbox->show_all(); my $tdir = $opt_testmode ? "target" : "/target"; mkdir $tdir; @@ -3005,22 +3130,24 @@ sub create_extract_view { eval { extract_data ($base, $tdir); }; my $err = $@; - $next->set_sensitive (1); + $next->set_sensitive(1); set_next ("_Reboot", sub { exit (0); } ); if ($err) { - display_html ("fail.htm"); - display_error ($err); + display_html("fail.htm"); + display_error($err); } else { - cleanup_view (); - display_html ("success.htm"); + cleanup_view(); + display_html("success.htm"); } } sub create_intro_view { - cleanup_view (); + $prev->set_sensitive(0); + + cleanup_view(); if ($setup->{product} eq 'pve') { eval { @@ -3032,8 +3159,9 @@ sub create_intro_view { }; } - display_html ("license.htm"); + display_html(); + $step_number++; set_next ("I a_gree", \&create_hdsel_view); } @@ -3056,7 +3184,7 @@ my $initial_error = 0; if (!defined ($hds) || (scalar (@$hds) <= 0)) { print "no hardisks found\n"; $initial_error = 1; - display_html ("nohds.htm"); + display_html("nohds.htm"); set_next ("Reboot", sub { exit (0); } ); } else { foreach my $hd (@$hds) { @@ -3069,7 +3197,7 @@ if (!defined ($hds) || (scalar (@$hds) <= 0)) { if (!$initial_error && (scalar keys %{ $ipconf->{ifaces} } == 0)) { print "no network interfaces found\n"; $initial_error = 1; - display_html ("nonics.htm"); + display_html("nonics.htm"); set_next ("Reboot", sub { exit (0); } ); }