X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=proxinstall;h=b256c6e020b902bd7c5a09b1aaf835fda2b2ca3b;hb=a346a962dbb3095009222d212c3f80f5580aa36f;hp=2c44567f4dc9d6eee437d5e8223fc36733ab4031;hpb=8d7ddbde84b3ebde29108b2080977b03853b2b69;p=pve-installer.git diff --git a/proxinstall b/proxinstall index 2c44567..b256c6e 100755 --- a/proxinstall +++ b/proxinstall @@ -18,6 +18,7 @@ use Encode; use String::ShellQuote; use Data::Dumper; use File::Basename; +use File::Path; use Time::HiRes; use ProxmoxInstallerSetup; @@ -39,6 +40,11 @@ my $zfstestpool = "test_rpool"; my $zfspoolname = $opt_testmode ? $zfstestpool : 'rpool'; my $zfsrootvolname = "$setup->{product}-1"; +my $product_fullname = { + pve => 'Proxmox VE', + pmg => 'Proxmox MailGateway', +}; + my $storage_cfg_zfs = <<__EOD__; dir: local path /var/lib/vz @@ -96,9 +102,7 @@ my $proxmox_libdir = $opt_testmode ? my $proxmox_cddir = $opt_testmode ? "../pve-cd-builder/tmp/data-gz/" : "/cdrom"; my $proxmox_pkgdir = "${proxmox_cddir}/proxmox/packages/"; -my $grub_plattform = "pc"; # pc, efi-amd64 or efi-ia32 - -$grub_plattform = "efi-amd64" if -d "/sys/firmware/efi"; +my $boot_type = -d '/sys/firmware/efi' ? 'efi' : 'bios'; my $IPV4OCTET = "(?:25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])"; my $IPV4RE = "(?:(?:$IPV4OCTET\\.){3}$IPV4OCTET)"; @@ -588,6 +592,7 @@ sub hd_list { next if $info !~ m/^E: DEVTYPE=disk$/m; next if $info =~ m/^E: ID_CDROM/m; + next if $info =~ m/^E: ID_FS_TYPE=iso9660/m; my ($name) = $info =~ m/^N: (\S+)$/m; @@ -901,6 +906,7 @@ my $clean_disk = sub { next if $part eq $disk; next if $part !~ /^\Q$disk\E/; eval { syscmd("pvremove -ff -y $part"); }; + eval { syscmd("zpool labelclear -f $part"); }; eval { syscmd("dd if=/dev/zero of=$part bs=1M count=16"); }; } }; @@ -1078,6 +1084,51 @@ sub compute_swapsize { return $swapsize; } +sub prepare_systemd_boot_esp { + my ($espdev, $targetdir) = @_; + + my $espuuid = find_dev_by_uuid($espdev); + my $espmp = "var/tmp/$espuuid"; + mkdir "$targetdir/$espmp"; + + syscmd("mount -n $espdev -t vfat $targetdir/$espmp") == 0 || + die "unable to mount ESP $espdev\n"; + + File::Path::make_path("$targetdir/$espmp/EFI/proxmox") || + die "unable to create directory $targetdir/$espmp/EFI/proxmox\n"; + + syscmd("chroot $targetdir bootctl --path /$espmp install") == 0 || + die "unable to install systemd-boot loader\n"; + write_config("timeout 3\ndefault proxmox-*\n", + "$targetdir/$espmp/loader/loader.conf"); + + syscmd("umount $targetdir/$espmp") == 0 || + die "unable to umount ESP $targetdir/$espmp\n"; + +} + +sub prepare_grub_efi_boot_esp { + my ($dev, $espdev, $targetdir) = @_; + + syscmd("mount -n $espdev -t vfat $targetdir/boot/efi") == 0 || + die "unable to mount $espdev\n"; + + my $rc = syscmd("chroot $targetdir /usr/sbin/grub-install --target x86_64-efi --no-floppy --bootloader-id='proxmox' $dev"); + if ($rc != 0) { + if ($boot_type eq 'efi') { + die "unable to install the EFI boot loader on '$dev'\n"; + } else { + warn "unable to install the EFI boot loader on '$dev', ignoring (not booted using UEFI)\n"; + } + } + # also install fallback boot file (OVMF does not boot without) + mkdir("$targetdir/boot/efi/EFI/BOOT"); + syscmd("cp $targetdir/boot/efi/EFI/proxmox/grubx64.efi $targetdir/boot/efi/EFI/BOOT/BOOTx64.EFI") == 0 || + die "unable to copy efi boot loader\n"; + + syscmd("umount $targetdir/boot/efi") == 0 || + die "unable to umount $targetdir/boot/efi\n"; +} sub extract_data { my ($basefile, $targetdir) = @_; @@ -1178,17 +1229,24 @@ sub extract_data { my ($devlist, $bootdevlist, $vdev) = get_zfs_raid_setup(); - my $disksize; foreach my $hd (@$devlist) { &$clean_disk(@$hd[1]); } + + my $disksize; foreach my $hd (@$bootdevlist) { my $devname = @$hd[1]; - my ($size, $osdev) = + my ($size, $osdev, $efidev) = partition_bootable_disk($devname, $config_options->{hdsize}, 'BF01'); + zfs_mirror_size_check($disksize, $size) if $disksize; - push @$bootdevinfo, { devname => $devname, osdev => $osdev}; + + push @$bootdevinfo, { + esp => $efidev, + devname => $devname, + osdev => $osdev + }; $disksize = $size; } @@ -1198,11 +1256,8 @@ sub extract_data { my $devname = $di->{devname}; $di->{by_id} = find_stable_path ("/dev/disk/by-id", $devname); - # Note: using /dev/disk/by-id/ does not work for unknown reason, we get - # cannot create 'rpool': no such pool or dataset - #my $osdev = find_stable_path ("/dev/disk/by-id", $di->{osdev}) || $di->{osdev}; + my $osdev = find_stable_path ("/dev/disk/by-id", $di->{osdev}) || $di->{osdev}; - my $osdev = $di->{osdev}; $vdev =~ s/ $devname/ $osdev/; } @@ -1323,6 +1378,10 @@ sub extract_data { die "unable to mount proc on $targetdir/proc\n"; syscmd("mount -n -t sysfs sysfs $targetdir/sys") == 0 || die "unable to mount sysfs on $targetdir/sys\n"; + if ($boot_type eq 'efi') { + syscmd("mount -n -t efivarfs efivarfs $targetdir/sys/firmware/efi/efivars") == 0 || + die "unable to mount efivarfs on $targetdir/sys/firmware/efi/efivars: $!\n"; + } syscmd("chroot $targetdir mount --bind /mnt/hostrun /run") == 0 || die "unable to re-bindmount hostrun on /run in chroot\n"; @@ -1417,9 +1476,10 @@ sub extract_data { # Note: this is required by current grub, but really dangerous, because # vfat does not have journaling, so it triggers manual fsck after each crash # so we only mount /boot/efi if really required (efi systems). - if ($grub_plattform =~ m/^efi-/) { + if ($boot_type eq 'efi' && !$use_zfs) { if (scalar(@$bootdevinfo)) { my $di = @$bootdevinfo[0]; # simply use first disk + if ($di->{esp}) { my $efi_boot_uuid = $di->{esp}; if (my $uuid = find_dev_by_uuid ($di->{esp})) { @@ -1450,6 +1510,13 @@ sub extract_data { diversion_add($targetdir, "/usr/sbin/update-grub", "/bin/true"); diversion_add($targetdir, "/usr/sbin/update-initramfs", "/bin/true"); + my $machine_id = run_command("systemd-id128 new"); + die "unable to create a new machine-id\n" if ! $machine_id; + write_config($machine_id, "$targetdir/etc/machine-id"); + + syscmd("cp /etc/hostid $targetdir/etc/") == 0 || + die "unable to copy hostid\n"; + syscmd("touch $targetdir/proxmox_install_mode"); my $grub_install_devices_txt = ''; @@ -1483,10 +1550,6 @@ _EOD chomp; my $path = $_; my ($deb) = $path =~ m/${proxmox_pkgdir}\/(.*\.deb)/; -# if ($deb =~ m/^grub-efi-/ && $deb !~ m/^grub-${grub_plattform}/) { -# $count++; -# next; -# } update_progress($count/$pkg_count, 0.5, 0.75, "extracting $deb"); print "extracting: $deb\n"; syscmd("cp $path $targetdir/tmp/$deb") == 0 || @@ -1564,6 +1627,10 @@ _EOD syscmd("sed -i -e 's/^GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"root=ZFS=$zfspoolname\\/ROOT\\/$zfsrootvolname boot=zfs\"/' $targetdir/etc/default/grub") == 0 || die "unable to update /etc/default/grub\n"; + if ($boot_type eq 'efi') { + write_config("root=ZFS=$zfspoolname/ROOT/$zfsrootvolname boot=zfs", "$targetdir/etc/kernel/cmdline"); + } + } diversion_remove($targetdir, "/usr/sbin/update-grub"); @@ -1592,30 +1659,23 @@ _EOD syscmd("chroot $targetdir /usr/sbin/grub-install --target i386-pc --no-floppy --bootloader-id='proxmox' $dev") == 0 || die "unable to install the i386-pc boot loader on '$dev'\n"; - if ($di->{esp}) { - syscmd("mount -n $di->{esp} -t vfat $targetdir/boot/efi") == 0 || - die "unable to mount $di->{esp}\n"; - my $rc = syscmd("chroot $targetdir /usr/sbin/grub-install --target x86_64-efi --no-floppy --bootloader-id='proxmox' $dev"); - if ($rc != 0) { - if (-d '/sys/firmware/efi') { - die "unable to install the EFI boot loader on '$dev'\n"; - } else { - warn "unable to install the EFI boot loader on '$dev', ignoring (not booted using UEFI)\n"; - } + if (my $esp = $di->{esp}) { + if ($use_zfs) { + prepare_systemd_boot_esp($esp, $targetdir); + } else { + prepare_grub_efi_boot_esp($dev, $esp, $targetdir); } - # also install fallback boot file (OVMF does not boot without) - mkdir("$targetdir/boot/efi/EFI/BOOT"); - syscmd("cp $targetdir/boot/efi/EFI/proxmox/grubx64.efi $targetdir/boot/efi/EFI/BOOT/BOOTx64.EFI") == 0 || - die "unable to copy efi boot loader\n"; - - syscmd("umount $targetdir/boot/efi") == 0 || - die "unable to umount $targetdir/boot/efi\n"; } } syscmd("chroot $targetdir /usr/sbin/update-grub") == 0 || die "unable to update boot loader config\n"; + if ($use_zfs && $boot_type eq 'efi') { + syscmd("chroot $targetdir /etc/kernel/postinst.d/zz-pve-efiboot") == 0 || + die "unable to generate systemd-boot config\n"; + } + syscmd("umount $targetdir/dev"); } @@ -1686,6 +1746,7 @@ _EOD syscmd("umount $targetdir/mnt/hostrun"); syscmd("umount $targetdir/tmp"); syscmd("umount $targetdir/proc"); + syscmd("umount $targetdir/sys/firmware/efi/efivars"); syscmd("umount $targetdir/sys"); if ($use_zfs) { @@ -2038,7 +2099,7 @@ sub create_ipconf_view { my $current = shift; my $new = $device_active_map->{$current->get_active()}; - return if $new eq $ipconf->{selected}; + return if defined($ipconf->{selected}) && $new eq $ipconf->{selected}; $ipconf->{selected} = $new; my $iface = $ipconf->{ifaces}->{$ipconf->{selected}}; @@ -2793,6 +2854,12 @@ sub create_hdoption_view { $grid->attach($sep, 0, $row, 2, 1); $row++; + my $hw_raid_note = Gtk3::Label->new("Note: ZFS is not compatible with disks backed by a hardware RAID controller. For details see the reference documentation."); + $hw_raid_note->set_line_wrap(1); + $hw_raid_note->set_max_width_chars(30); + $hw_raid_note->set_visible(0); + $grid->attach($hw_raid_note, 0, $row++, 2, 1); + my $hdsize_labeled_widgets = []; # size compute @@ -2860,6 +2927,7 @@ sub create_hdoption_view { $target_hd_combo->set_visible(!$raid); $options_stack->get_child_by_name("hdsize")->set_visible(!$raid); $options_stack->get_child_by_name("raiddisk")->set_visible($raid); + $hw_raid_note->set_visible($raid); $options_stack_switcher->set_visible($enable_zfs_opts); $options_stack->get_child_by_name("raidzfsadvanced")->set_visible($enable_zfs_opts); if ($raid) { @@ -2881,6 +2949,10 @@ sub create_hdoption_view { &$switch_view(); }); + my $sep2 = Gtk3::HSeparator->new(); + $sep2->set_visible(1); + $contarea->pack_end($sep2, 1, 1, 10); + $dialog->show(); $dialog->run(); @@ -3178,11 +3250,18 @@ sub create_intro_view { cleanup_view(); + if (int($total_memory) < 1024) { + my $fullname = $product_fullname->{$setup->{product}}; + + display_error("Less than 1 GiB of usable memory detected, installation will probably fail.\n\n". + "See 'System Requirements' in the $fullname documentation."); + } + if ($setup->{product} eq 'pve') { eval { my $cpuinfo = file_get_contents('/proc/cpuinfo'); if ($cpuinfo && !($cpuinfo =~ /^flags\s*:.*(vmx|svm)/m)) { - display_error("No support for KVM virtualisation detected.\n\n" . + display_error("No support for KVM virtualization detected.\n\n" . "Check BIOS settings for Intel VT / AMD-V / SVM.") } };