[pve-devel] [PATCH container 1/1] cloud-init: add support for multiple IP addresses
Julian Pawlowski
julian at pawlowski.me
Wed Oct 24 08:57:34 CEST 2018
Signed-off-by: Julian Pawlowski <julian at pawlowski.me>
---
PVE/QemuServer.pm | 50 ++++-----
PVE/QemuServer/Cloudinit.pm | 202 +++++++++++++++++++++---------------
2 files changed, 145 insertions(+), 107 deletions(-)
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 933f54f..9bd8c18 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -773,36 +773,38 @@ PVE::JSONSchema::register_standard_option("pve-qm-net", $netdesc);
my $ipconfig_fmt = {
ip => {
- type => 'string',
- format => 'pve-ipv4-config',
- format_description => 'IPv4Format/CIDR',
- description => 'IPv4 address in CIDR format.',
- optional => 1,
- default => 'dhcp',
+ type => 'string',
+ format => 'pve-ipv4-config',
+ format_description => 'IPv4Format/CIDR',
+ description => 'IPv4 address in CIDR format.',
+ optional => 1,
+ multiple => 1,
+ default => 'dhcp',
},
gw => {
- type => 'string',
- format => 'ipv4',
- format_description => 'GatewayIPv4',
- description => 'Default gateway for IPv4 traffic.',
- optional => 1,
- requires => 'ip',
+ type => 'string',
+ format => 'ipv4',
+ format_description => 'GatewayIPv4',
+ description => 'Default gateway for IPv4 traffic.',
+ optional => 1,
+ requires => 'ip',
},
ip6 => {
- type => 'string',
- format => 'pve-ipv6-config',
- format_description => 'IPv6Format/CIDR',
- description => 'IPv6 address in CIDR format.',
- optional => 1,
- default => 'dhcp',
+ type => 'string',
+ format => 'pve-ipv6-config',
+ format_description => 'IPv6Format/CIDR',
+ description => 'IPv6 address in CIDR format.',
+ optional => 1,
+ multiple => 1,
+ default => 'dhcp',
},
gw6 => {
- type => 'string',
- format => 'ipv6',
- format_description => 'GatewayIPv6',
- description => 'Default gateway for IPv6 traffic.',
- optional => 1,
- requires => 'ip6',
+ type => 'string',
+ format => 'ipv6',
+ format_description => 'GatewayIPv6',
+ description => 'Default gateway for IPv6 traffic.',
+ optional => 1,
+ requires => 'ip6',
},
};
PVE::JSONSchema::register_format('pve-qm-ipconfig', $ipconfig_fmt);
diff --git a/PVE/QemuServer/Cloudinit.pm b/PVE/QemuServer/Cloudinit.pm
index 53f1de9..a0ddd37 100644
--- a/PVE/QemuServer/Cloudinit.pm
+++ b/PVE/QemuServer/Cloudinit.pm
@@ -162,34 +162,48 @@ sub configdrive2_network {
my @ifaces = grep(/^net(\d+)$/, keys %$conf);
foreach my $iface (@ifaces) {
- (my $id = $iface) =~ s/^net//;
- next if !$conf->{"ipconfig$id"};
- my $net = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"});
- $id = "eth$id";
-
- $content .="auto $id\n";
- if ($net->{ip}) {
- if ($net->{ip} eq 'dhcp') {
- $content .= "iface $id inet dhcp\n";
- } else {
- my ($addr, $mask) = split_ip4($net->{ip});
- $content .= "iface $id inet static\n";
- $content .= " address $addr\n";
- $content .= " netmask $mask\n";
- $content .= " gateway $net->{gw}\n" if $net->{gw};
- }
- }
- if ($net->{ip6}) {
- if ($net->{ip6} =~ /^(auto|dhcp)$/) {
- $content .= "iface $id inet6 $1\n";
- } else {
- my ($addr, $mask) = split('/', $net->{ip6});
- $content .= "iface $id inet6 static\n";
- $content .= " address $addr\n";
- $content .= " netmask $mask\n";
- $content .= " gateway $net->{gw6}\n" if $net->{gw6};
- }
- }
+ ( my $id = $iface ) =~ s/^net//;
+ next if !$conf->{"ipconfig$id"};
+ my $net = PVE::QemuServer::parse_ipconfig( $conf->{"ipconfig$id"} );
+ $id = "eth$id";
+
+ $content .= "auto $id\n";
+ if ( $net->{ip} ) {
+ my $loop = 0;
+ foreach my $ip ( @{ $net->{ip} } ) {
+ if ( $ip eq 'dhcp' ) {
+ $content .= "iface $id inet dhcp\n";
+ last;
+ }
+ else {
+ my ( $addr, $mask ) = split_ip4($ip);
+ $content .= "iface $id inet static\n";
+ $content .= " address $addr\n";
+ $content .= " netmask $mask\n";
+ $content .= " gateway $net->{gw}\n"
+ if ( $net->{gw} && !$loop );
+ }
+ $loop++;
+ }
+ }
+ if ( $net->{ip6} ) {
+ my $loop = 0;
+ foreach my $ip ( @{ $net->{ip6} } ) {
+ if ( $net->{ip6} =~ /^(auto|dhcp)$/ ) {
+ $content .= "iface $id inet6 $1\n";
+ last;
+ }
+ else {
+ my ( $addr, $mask ) = split( '/', $net->{ip6} );
+ $content .= "iface $id inet6 static\n";
+ $content .= " address $addr\n";
+ $content .= " netmask $mask\n";
+ $content .= " gateway $net->{gw6}\n"
+ if ( $net->{gw6} && !$loop );
+ }
+ $loop++;
+ }
+ }
}
return $content;
@@ -254,20 +268,28 @@ sub nocloud_network_v2 {
. "${i} macaddress: \"$mac\"\n"
. "${i}set-name: eth$id\n";
my @addresses;
- if (defined(my $ip = $ipconfig->{ip})) {
- if ($ip eq 'dhcp') {
- $content .= "${i}dhcp4: true\n";
- } else {
- push @addresses, $ip;
- }
- }
- if (defined(my $ip = $ipconfig->{ip6})) {
- if ($ip eq 'dhcp') {
- $content .= "${i}dhcp6: true\n";
- } else {
- push @addresses, $ip;
- }
- }
+ if ( $ipconfig->{ip} ) {
+ foreach my $ip ( @{ $ipconfig->{ip} } ) {
+ if ( $ip eq 'dhcp' ) {
+ $content .= "${i}dhcp4: true\n";
+ last;
+ }
+ else {
+ push @addresses, $ip;
+ }
+ }
+ }
+ if ( $ipconfig->{ip6} ) {
+ foreach my $ip ( @{ $ipconfig->{ip6} } ) {
+ if ( $ip eq 'dhcp' ) {
+ $content .= "${i}dhcp6: true\n";
+ last;
+ }
+ else {
+ push @addresses, $ip;
+ }
+ }
+ }
if (@addresses) {
$content .= "${i}addresses:\n";
$content .= "${i}- $_\n" foreach @addresses;
@@ -307,47 +329,61 @@ sub nocloud_network {
my @ifaces = grep(/^net(\d+)$/, keys %$conf);
foreach my $iface (@ifaces) {
- (my $id = $iface) =~ s/^net//;
- next if !$conf->{"ipconfig$id"};
-
- # indentation - network interfaces are inside an 'ethernets' hash
- my $i = ' ';
-
- my $net = PVE::QemuServer::parse_net($conf->{$iface});
- my $ipconfig = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"});
-
- my $mac = lc($net->{macaddr})
- or die "network interface '$iface' has no mac address\n";
-
- $content .= "${i}- type: physical\n"
- . "${i} name: eth$id\n"
- . "${i} mac_address: $mac\n"
- . "${i} subnets:\n";
- $i .= ' ';
- if (defined(my $ip = $ipconfig->{ip})) {
- if ($ip eq 'dhcp') {
- $content .= "${i}- type: dhcp4\n";
- } else {
- my ($addr, $mask) = split_ip4($ip);
- $content .= "${i}- type: static\n"
- . "${i} address: $addr\n"
- . "${i} netmask: $mask\n";
- if (defined(my $gw = $ipconfig->{gw})) {
- $content .= "${i} gateway: $gw\n";
- }
- }
- }
- if (defined(my $ip = $ipconfig->{ip6})) {
- if ($ip eq 'dhcp') {
- $content .= "${i}- type: dhcp6\n";
- } else {
- $content .= "${i}- type: static\n"
- . "${i} address: $ip\n";
- if (defined(my $gw = $ipconfig->{gw6})) {
- $content .= "${i} gateway: $gw\n";
- }
- }
- }
+ ( my $id = $iface ) =~ s/^net//;
+ next if !$conf->{"ipconfig$id"};
+
+ # indentation - network interfaces are inside an 'ethernets' hash
+ my $i = ' ';
+
+ my $net = PVE::QemuServer::parse_net( $conf->{$iface} );
+ my $ipconfig =
+ PVE::QemuServer::parse_ipconfig( $conf->{"ipconfig$id"} );
+
+ my $mac = lc( $net->{macaddr} )
+ or die "network interface '$iface' has no mac address\n";
+
+ $content .=
+ "${i}- type: physical\n"
+ . "${i} name: eth$id\n"
+ . "${i} mac_address: $mac\n"
+ . "${i} subnets:\n";
+ $i .= ' ';
+ if ( $ipconfig->{ip} ) {
+ my $loop = 0;
+ foreach my $ip ( @{ $ipconfig->{ip} } ) {
+ if ( $ip eq 'dhcp' ) {
+ $content .= "${i}- type: dhcp4\n";
+ last;
+ }
+ else {
+ my ( $addr, $mask ) = split_ip4($ip);
+ $content .=
+ "${i}- type: static\n"
+ . "${i} address: $addr\n"
+ . "${i} netmask: $mask\n";
+ if ( !$loop && defined( my $gw = $ipconfig->{gw} ) ) {
+ $content .= "${i} gateway: $gw\n";
+ }
+ }
+ $loop++;
+ }
+ }
+ if ( $ipconfig->{ip6} ) {
+ my $loop = 0;
+ foreach my $ip ( @{ $ipconfig->{ip6} } ) {
+ if ( $ip eq 'dhcp' ) {
+ $content .= "${i}- type: dhcp6\n";
+ last;
+ }
+ else {
+ $content .= "${i}- type: static\n" . "${i} address: $ip\n";
+ if ( !$loop && defined( my $gw = $ipconfig->{gw6} ) ) {
+ $content .= "${i} gateway: $gw\n";
+ }
+ }
+ $loop++;
+ }
+ }
}
my $i = ' ';
--
2.19.1
More information about the pve-devel
mailing list