[pve-devel] [RFC installer 5/7] use iproute2, support interface selection
Fabian Grünbichler
f.gruenbichler at proxmox.com
Tue Mar 7 16:03:02 CET 2017
Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
proxinstall | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 144 insertions(+), 18 deletions(-)
diff --git a/proxinstall b/proxinstall
index 8d8d263..47676a4 100755
--- a/proxinstall
+++ b/proxinstall
@@ -144,6 +144,42 @@ my $ipv4_mask_hash = {
'255.255.255.252' => 30
};
+my $ipv4_reverse_mask = [
+ '0.0.0.0',
+ '128.0.0.0',
+ '192.0.0.0',
+ '224.0.0.0',
+ '240.0.0.0',
+ '248.0.0.0',
+ '252.0.0.0',
+ '254.0.0.0',
+ '255.0.0.0',
+ '255.128.0.0',
+ '255.192.0.0',
+ '255.224.0.0',
+ '255.240.0.0',
+ '255.248.0.0',
+ '255.252.0.0',
+ '255.254.0.0',
+ '255.255.0.0',
+ '255.255.128.0',
+ '255.255.192.0',
+ '255.255.224.0',
+ '255.255.240.0',
+ '255.255.248.0',
+ '255.255.252.0',
+ '255.255.254.0',
+ '255.255.255.0',
+ '255.255.255.128',
+ '255.255.255.192',
+ '255.255.255.224',
+ '255.255.255.240',
+ '255.255.255.248',
+ '255.255.255.252',
+ '255.255.255.254',
+ '255.255.255.255',
+];
+
my ($window, $cmdbox, $inbox, $htmlview);
my ($next, $next_fctn, $target_hd);
my ($progress, $progress_status);
@@ -1234,15 +1270,26 @@ sub extract_data {
my $ntype = $ipversion == 4 ? 'inet' : 'inet6';
+ my $bridge_port = $ipconf->{ifaces}->{$ipconf->{selected}}->{name};
+
+ $ifaces .= "iface $bridge_port $ntype manual\n";
+
$ifaces .=
- "auto vmbr0\niface vmbr0 $ntype static\n" .
+ "\nauto vmbr0\niface vmbr0 $ntype static\n" .
"\taddress $ipaddress\n" .
"\tnetmask $netmask\n" .
"\tgateway $gateway\n" .
- "\tbridge_ports eth0\n" .
+ "\tbridge_ports $bridge_port\n" .
"\tbridge_stp off\n" .
"\tbridge_fd 0\n";
+ foreach my $iface (sort keys %{$ipconf->{ifaces}}) {
+ my $name = $ipconf->{ifaces}->{$iface}->{name};
+ next if $name eq $bridge_port;
+
+ $ifaces .= "\niface $name $ntype manual\n";
+ }
+
write_config ($ifaces, "$targetdir/etc/network/interfaces");
# configure dns
@@ -1722,21 +1769,60 @@ sub create_text_input {
sub get_ip_config {
- my $ifconfig = `ifconfig eth0`;
+ my $ifaces = {};
+ my $default;
- my ($addr) = $ifconfig =~ m/inet addr:(\S*)/m;
- my ($mask) = $ifconfig =~ m/Mask:(\S*)/m;
+ my $links = `ip -o l`;
+ foreach my $l (split /\n/,$links) {
+ my ($index, $name, $flags, $state, $mac) = $l =~ m/^(\d+):\s+(\S+):\s+<(\S+)>.*\s+state\s+(\S+)\s+.*\s+link\/ether\s+(\S+)\s+/;
+ next if !$name || $name eq 'lo';
- my $route = `route -n`;
- my ($gateway) = $route =~ m/^0\.0\.0\.0\s+(\d+\.\d+\.\d+\.\d+)\s+/m;
+ my $driver = readlink "/sys/class/net/$name/device/driver" || 'unknown';
+ $driver =~ s!^.*/!!;
+
+ $ifaces->{"$index"} = {
+ name => $name,
+ driver => $driver,
+ flags => $flags,
+ state => $state,
+ mac => $mac,
+ };
+
+ my $addresses = `ip -o a s $name`;
+ foreach my $a (split /\n/,$addresses) {
+ my ($family, $ip, $prefix) = $a =~ m/^\Q$index\E:\s+\Q$name\E\s+(inet|inet6)\s+($IPRE)\/(\d+)\s+/;
+ next if !$ip;
+
+ my $mask = $prefix;
+
+ if ($family eq 'inet') {
+ next if !$ip =~ /$IPV4RE/;
+ next if $prefix < 8 || $prefix > 32;
+ $mask = @$ipv4_reverse_mask[$prefix];
+ } else {
+ next if !$ip =~ /$IPV6RE/;
+ }
+
+ $default = $index if !$default;
+
+ $ifaces->{"$index"}->{"$family"} = {
+ mask => $mask,
+ addr => $ip,
+ };
+ }
+ }
+
+
+ my $route = `ip route`;
+ my ($gateway) = $route =~ m/^default\s+via\s+(\S+)\s+/m;
my $resolvconf = `cat /etc/resolv.conf`;
my ($dnsserver) = $resolvconf =~ m/^nameserver\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/m;
my ($domain) = $resolvconf =~ m/^domain\s+(\S+)$/m;
return {
- addr => $addr,
- mask => $mask,
+ default => $default,
+ ifaces => $ifaces,
gateway => $gateway,
dnsserver => $dnsserver,
domain => $domain,
@@ -1761,6 +1847,8 @@ sub display_error {
$dialog->destroy();
}
+my $ipconf_first_view = 1;
+
sub create_ipconf_view {
cleanup_view ();
@@ -1773,8 +1861,52 @@ sub create_ipconf_view {
my $vbox2 = Gtk3::VBox->new (0, 0);
$hbox->add ($vbox2);
- my $addr = $ipconf->{addr} || '192.168.100.2';
- my $mask = $ipconf->{mask} || '255.255.255.0';
+ my $ipbox;
+ ($ipbox, $ipconf_entry_addr) =
+ create_text_input ("192.168.100.2", 'IP Address:');
+
+ my $maskbox;
+ ($maskbox, $ipconf_entry_mask) =
+ create_text_input ("255.255.255.0", 'Netmask:');
+
+ my $device_cb = Gtk3::ComboBoxText->new();
+ $device_cb->set_active(0);
+ $device_cb->set_visible(1);
+
+ my $get_device_desc = sub {
+ my $iface = shift;
+ return "$iface->{name} - $iface->{mac} ($iface->{driver})";
+ };
+
+ my $device_active_map = {};
+ 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;
+ if ($ipconf_first_view && $index == $ipconf->{default}) {
+ $device_cb->set_active($i);
+ $ipconf_first_view = 0;
+ }
+ $device_cb->signal_connect ('changed' => sub {
+ my $current = shift;
+ $ipconf->{selected} = $device_active_map->{$current->get_active};
+ my $iface = $ipconf->{ifaces}->{$ipconf->{selected}};
+ $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})
+ if $iface->{inet}->{mask} || $iface->{inet6}->{mask};
+ });
+ $i++;
+ }
+
+ my $devicebox = Gtk3::HBox->new (0, 0);
+ my $label = Gtk3::Label->new ("Management Interface:");
+ $label->set_size_request (150, -1);
+ $label->set_alignment (1, 0.5);
+ $devicebox->pack_start ($label, 0, 0, 10);
+ $devicebox->pack_start ($device_cb, 0, 0, 0);
+
+ $vbox2->pack_start ($devicebox, 0, 0, 2);
my $hn = $ipconf->{domain} ? "pve.$ipconf->{domain}" : 'pve.example.invalid';
@@ -1782,14 +1914,8 @@ sub create_ipconf_view {
create_text_input ($hn, 'Hostname (FQDN):');
$vbox2->pack_start ($hostbox, 0, 0, 2);
- my $ipbox;
- ($ipbox, $ipconf_entry_addr) =
- create_text_input ($addr, 'IP Address:');
$vbox2->pack_start ($ipbox, 0, 0, 2);
- my $maskbox;
- ($maskbox, $ipconf_entry_mask) =
- create_text_input ($mask, 'Netmask:');
$vbox2->pack_start ($maskbox, 0, 0, 2);
$gateway = $ipconf->{gateway} || '192.168.100.1';
@@ -2796,7 +2922,7 @@ sub create_intro_view {
$ipconf = get_ip_config ();
-$country = detect_country() if $ipconf->{addr} || $opt_testmode;;
+$country = detect_country() if $ipconf->{default} || $opt_testmode;;
# read country, kmap and timezone infos
$cmap = read_cmap ();
--
2.1.4
More information about the pve-devel
mailing list