]> git.proxmox.com Git - pve-installer.git/blobdiff - proxinstall
implement ipv6
[pve-installer.git] / proxinstall
index 7af40ecafb2182c6867b69de633dcac84ed4afcf..2bd9bf52726760f9ef3abe9f4e9c120e3ff5e182 100755 (executable)
@@ -52,8 +52,25 @@ my $grub_plattform = "pc"; # pc, efi-amd64 or efi-ia32
 
 $grub_plattform = "efi-amd64" if -d "/sys/firmware/efi"; 
 
-my $IPV4OCTET = "(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])";
+my $IPV4OCTET = "(?:25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])";
 my $IPV4RE = "(?:(?:$IPV4OCTET\\.){3}$IPV4OCTET)";
+my $IPV6H16 = "(?:[0-9a-fA-F]{1,4})";
+my $IPV6LS32 = "(?:(?:$IPV4RE|$IPV6H16:$IPV6H16))";
+
+my $IPV6RE = "(?:" .
+    "(?:(?:" .                             "(?:$IPV6H16:){6})$IPV6LS32)|" .
+    "(?:(?:" .                           "::(?:$IPV6H16:){5})$IPV6LS32)|" .
+    "(?:(?:(?:" .              "$IPV6H16)?::(?:$IPV6H16:){4})$IPV6LS32)|" .
+    "(?:(?:(?:(?:$IPV6H16:){0,1}$IPV6H16)?::(?:$IPV6H16:){3})$IPV6LS32)|" .
+    "(?:(?:(?:(?:$IPV6H16:){0,2}$IPV6H16)?::(?:$IPV6H16:){2})$IPV6LS32)|" .
+    "(?:(?:(?:(?:$IPV6H16:){0,3}$IPV6H16)?::(?:$IPV6H16:){1})$IPV6LS32)|" .
+    "(?:(?:(?:(?:$IPV6H16:){0,4}$IPV6H16)?::" .           ")$IPV6LS32)|" .
+    "(?:(?:(?:(?:$IPV6H16:){0,5}$IPV6H16)?::" .            ")$IPV6H16)|" .
+    "(?:(?:(?:(?:$IPV6H16:){0,6}$IPV6H16)?::" .                    ")))";
+
+my $IPRE = "(?:$IPV4RE|$IPV6RE)";
+
+
 my $ipv4_mask_hash = {
     '128.0.0.0' => 1,
     '192.0.0.0' => 2,
@@ -90,7 +107,7 @@ my $ipv4_mask_hash = {
 my ($window, $cmdbox, $inbox, $htmlview);
 my ($next, $next_fctn, $target_hd);
 my ($progress, $progress_status);
-my ($ipaddress, $ipconf_entry_addr);
+my ($ipversion, $ipaddress, $ipconf_entry_addr);
 my ($netmask, $ipconf_entry_mask);
 my ($gateway, $ipconf_entry_gw);
 my ($dnsserver, $ipconf_entry_dns);
@@ -109,10 +126,10 @@ my $cmap;
 
 my $config_options = {};
 
-if ($cmdline =~ m/\s(ext3|ext4|zfs)(\s.*)?$/) {
+if ($cmdline =~ m/\s(ext3|ext4|xfs|zfs)(\s.*)?$/) {
     $config_options->{filesys} = $1;
 } else {
-    $config_options->{filesys} = 'ext3';
+    $config_options->{filesys} = 'ext4';
 }
 
 if ($cmdline =~ m/hdsize=(\d+(\.\d+)?)[\s\n]/i) {
@@ -566,19 +583,41 @@ sub update_progress {
     Gtk3::main_iteration() while Gtk3::events_pending();
 }
 
-sub create_filesystem {
-    my ($dev, $name, $type, $start, $end, $fs, $fe, $opts) = @_;
+my $fssetup = {
+    ext3 => {
+       mkfs => 'mkfs.ext3 -F',
+       mkfs_root_opt => '',
+       mkfs_data_opt => '-m 0',
+       root_mountopt => 'errors=remount-ro',
+    },
+    ext4 => {
+       mkfs => 'mkfs.ext4 -F',
+       mkfs_root_opt => '',
+       mkfs_data_opt => '-m 0',
+       root_mountopt => 'errors=remount-ro',
+    },
+    xfs => {
+       mkfs => 'mkfs.xfs -f',
+       mkfs_root_opt => '',
+       mkfs_data_opt => '',
+       root_mountopt => '',
+    },
+};
 
-    $opts = '' if !$opts;
+sub create_filesystem {
+    my ($dev, $name, $type, $start, $end, $fs, $fe) = @_;
 
     my $range = $end - $start;
     my $rs = $start + $range*$fs;
     my $re = $start + $range*$fe;
     my $max = 0;
 
+    my $fsdata = $fssetup->{$type} || die "internal error - unknown file system '$type'";
+    my $opts = $name eq 'root' ? $fsdata->{mkfs_root_opt} : $fsdata->{mkfs_data_opt};
+    
     update_progress (0, $rs, $re, "creating $name filesystem");
 
-    run_command ("mkfs.$type $opts -F $dev", sub {
+    run_command ("$fsdata->{mkfs} $opts $dev", sub {
        my $line = shift;
 
        if ($line =~ m/Writing inode tables:\s+(\d+)\/(\d+)/) {
@@ -626,7 +665,7 @@ sub diversion_remove {
 sub zfs_create_rpool {
     my ($zfspoolname, $vdev) = @_;
 
-   syscmd ("zpool create -f -o ashift=12 $zfspoolname $vdev") == 0 ||
+   syscmd ("zpool create -f -o ashift=12 -o cachefile=none $zfspoolname $vdev") == 0 ||
        die "unable to create zfs root pool\n";
 
     syscmd ("zfs create $zfspoolname/ROOT")  == 0 ||
@@ -663,7 +702,7 @@ sub partition_bootable_disk {
 
     die "too dangerous" if $opt_testmode;
 
-    syscmd("dd if=/dev/zero of=${target_dev} bs=512 count=256");
+    syscmd("sgdisk -Z ${target_dev}");
     my $hdsize = hd_size($target_dev); # size in blocks (1024 bytes)
 
     if ($maxhdsize && ($maxhdsize < $hdsize)) {
@@ -720,7 +759,7 @@ sub partition_bootable_zfs_disk {
 
     die "too dangerous" if $opt_testmode;
 
-    syscmd("dd if=/dev/zero of=${target_dev} bs=512 count=256");
+    syscmd("sgdisk -Z ${target_dev}");
     my $hdsize = hd_size($target_dev); # size in blocks (1024 bytes)
 
     my $hdgb = int($hdsize/(1024*1024));
@@ -981,11 +1020,11 @@ sub extract_data {
            if ( -b $target_hd) {
 
                create_filesystem ($rootdev, 'root', $filesys, 0.05, $maxper, 0, 0.5);
-               create_filesystem ($datadev, 'data', $filesys, 0.05, $maxper, 0.5, 1, '-m 0');
+               create_filesystem ($datadev, 'data', $filesys, 0.05, $maxper, 0.5, 1);
 
            } else {
 
-               create_filesystem ($rootdev, 'root', $filesys, 0.05, $maxper, 0, 1, '-m 0');
+               create_filesystem ($rootdev, 'root', $filesys, 0.05, $maxper, 0, 1);
            }
        }
 
@@ -1066,15 +1105,18 @@ sub extract_data {
 
        # configure interfaces
 
-       my $ifaces =
-           "auto lo\niface lo inet loopback\n\n" .
-           "auto vmbr0\niface vmbr0 inet static\n" .
-           "\taddress $ipaddress\n" .
-           "\tnetmask $netmask\n" .
-           "\tgateway $gateway\n" .
-           "\tbridge_ports eth0\n" .
-           "\tbridge_stp off\n" .
-           "\tbridge_fd 0\n";
+       my $ifaces = "auto lo\niface lo inet loopback\n\n";
+
+       my $ntype = $ipversion == 4 ? 'inet' : 'inet6';
+
+        $ifaces .=
+            "auto vmbr0\niface vmbr0 $ntype static\n" .
+            "\taddress $ipaddress\n" .
+            "\tnetmask $netmask\n" .
+            "\tgateway $gateway\n" .
+            "\tbridge_ports eth0\n" .
+            "\tbridge_stp off\n" .
+            "\tbridge_fd 0\n";
 
        write_config ($ifaces, "$targetdir/etc/network/interfaces");
 
@@ -1088,7 +1130,8 @@ sub extract_data {
        my $fstab = "# <file system> <mount point> <type> <options> <dump> <pass>\n";
 
        if (!$use_zfs) {
-           $fstab .= "$rootdev / $filesys errors=remount-ro 0 1\n";
+           my $root_mountopt = $fssetup->{$filesys}->{root_mountopt} || 'defaults';
+           $fstab .= "$rootdev / $filesys ${root_mountopt} 0 1\n";
            $fstab .= "$datadev /var/lib/vz $filesys defaults 0 1\n" if $datadev;
        }
 
@@ -1214,6 +1257,9 @@ _EOD
        # file does not exist)
        write_config ('', "$targetdir/var/lib/apt/extended_states");
 
+       # allow ssh root login
+       syscmd ("sed -i 's/^PermitRootLogin.*/PermitRootLogin yes/' '$targetdir/etc/ssh/sshd_config'");
+       
        # save installer settings
        my $ucc = uc ($country);
        debconfig_set ($targetdir, <<_EOD);
@@ -1222,10 +1268,6 @@ _EOD
 
        update_progress (0.8, 0.95, 1, "make system bootable");
 
-       # update default grub settings
-       syscmd ("sed -i -e 's/^GRUB_DISTRIBUTOR.*/GRUB_DISTRIBUTOR=\"Proxmox Virtual Environment\"/' -e 's/#GRUB_DISABLE_RECOVERY=.*/GRUB_DISABLE_RECOVERY=\"true\"/' $targetdir/etc/default/grub") == 0 ||
-           die "unable to update /etc/default/grub\n";
-           
        if ($use_zfs) {
            syscmd ("sed -i -e 's/^GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"root=ZFS=$zfspoolname\\/ROOT\\/pve-1 boot=zfs\"/' $targetdir/etc/default/grub") == 0 ||
                die "unable to update /etc/default/grub\n";
@@ -1613,6 +1655,10 @@ sub create_ipconf_view {
        $text =~ s/\s+$//;
        if ($text =~ m!^($IPV4RE)$!) {
            $ipaddress = $text;
+           $ipversion = 4;
+       } elsif ($text =~ m!^($IPV6RE)$!) {
+           $ipaddress = $text; 
+           $ipversion = 6;
        } else {
            display_message ("IP address is not valid.");
            $ipconf_entry_addr->grab_focus();
@@ -1622,7 +1668,9 @@ sub create_ipconf_view {
        $text = $ipconf_entry_mask->get_text();
        $text =~ s/^\s+//;
        $text =~ s/\s+$//;
-       if (defined($ipv4_mask_hash->{$text})) {
+       if (($ipversion == 6) && ($text =~ m/^(\d+)$/) && ($1 >= 8) && ($1 <= 126)) {
+           $netmask = $text;
+       } elsif (($ipversion == 4) && defined($ipv4_mask_hash->{$text})) {
            $netmask = $text;
        } else {
            display_message ("Netmask is not valid.");
@@ -1633,7 +1681,9 @@ sub create_ipconf_view {
        $text = $ipconf_entry_gw->get_text();
        $text =~ s/^\s+//;
        $text =~ s/\s+$//;
-       if ($text =~ m!^($IPV4RE)$!) {
+       if (($ipversion == 4) && ($text =~ m!^($IPV4RE)$!)) {
+           $gateway = $text;
+       } elsif (($ipversion == 6) && ($text =~ m!^($IPV6RE)$!)) {
            $gateway = $text;
        } else {
            display_message ("Gateway is not valid.");
@@ -1644,7 +1694,9 @@ sub create_ipconf_view {
        $text = $ipconf_entry_dns->get_text();
        $text =~ s/^\s+//;
        $text =~ s/\s+$//;
-       if ($text =~ m!^($IPV4RE)$!) {
+       if (($ipversion == 4) && ($text =~ m!^($IPV4RE)$!)) {
+           $dnsserver = $text;
+       } elsif (($ipversion == 6) && ($text =~ m!^($IPV6RE)$!)) {
            $dnsserver = $text;
        } else {
            display_message ("DNS server is not valid.");
@@ -2012,7 +2064,7 @@ sub create_hdoption_view {
    
     my $fstypecb = Gtk3::ComboBoxText->new();
 
-    my $fstype = ['ext3', 'ext4', 'zfs (RAID0)', 'zfs (RAID1)', 
+    my $fstype = ['ext3', 'ext4', 'xfs', 'zfs (RAID0)', 'zfs (RAID1)', 
                  'zfs (RAID10)', 'zfs (RAIDZ-1)', 
                  'zfs (RAIDZ-2)', 'zfs (RAIDZ-3)'];