[pve-devel] [PATCH v2 pve-manager] API2 : Network : add network config reload

Alexandre Derumier aderumier at odiso.com
Wed Jun 27 04:53:57 CEST 2018


changelog:

- remove restart option
- check if vm|ct are running on a bridge delete
- run the networking service reload in a task


This add a new api to online reload networking configuration
with ifupdown2.

This work with native ifupdown2 modules, as ifupdown2 have
interface dependency relationships.

---
 PVE/API2/Network.pm | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/PVE/API2/Network.pm b/PVE/API2/Network.pm
index c0ae1df3..9475396f 100644
--- a/PVE/API2/Network.pm
+++ b/PVE/API2/Network.pm
@@ -4,7 +4,7 @@ use strict;
 use warnings;
 
 use Net::IP qw(:PROC);
-use PVE::Tools qw(extract_param);
+use PVE::Tools qw(extract_param dir_glob_regex);
 use PVE::SafeSyslog;
 use PVE::INotify;
 use PVE::Exception qw(raise_param_exc);
@@ -477,6 +477,73 @@ __PACKAGE__->register_method({
    }});
 
 __PACKAGE__->register_method({
+    name => 'reload_network_config', 
+    path => '', 
+    method => 'PUT',
+    permissions => {
+	check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
+    },
+    description => "Reload network configuration",
+    protected => 1,
+    proxyto => 'node',
+    parameters => {
+    	additionalProperties => 0,
+	properties => {
+	    node => get_standard_option('pve-node'),
+	},
+    },
+    returns => { type => 'string' },
+    code => sub {
+
+	my ($param) = @_;
+
+        my $rpcenv = PVE::RPCEnvironment::get();
+
+        my $authuser = $rpcenv->get_user();
+
+	my $current_config_file = "/etc/network/interfaces";
+	my $new_config_file = "/etc/network/interfaces.new";
+
+	raise_param_exc({ config => "you need ifupdown2 to reload networking" }) if !-e '/usr/share/ifupdown2';
+	raise_param_exc({ config => "no new network config to apply" }) if !-e $new_config_file;
+
+	my $tmp = PVE::INotify::read_file('interfaces', 1);
+	my $config = $tmp->{data};
+	my $changes = $tmp->{changes};
+
+	raise_param_exc({ config => "no changes detected" }) if !$changes;
+
+	my $ovs_changes = undef;
+	my $bridges_delete = {};
+	my @lines = split(/\n/, $changes);
+	foreach my $line (@lines) {
+	   if($line =~ m/^\-iface\s(vmbr(\S+))/) {
+		$bridges_delete->{$1} = 1;
+	   } elsif ($line =~ m/ovs_type/) {
+		$ovs_changes = 1;
+	   } 
+	}
+
+	raise_param_exc({ config => "reloading config with ovs changes is not possible currently\n" }) 
+	    if $ovs_changes && !$param->{restart};
+
+	foreach my $bridge (keys %$bridges_delete) {
+
+	    my (undef, $interface) = dir_glob_regex("/sys/class/net/$bridge/brif", '(tap|veth|fwpr).*');
+	    raise_param_exc({ config => "bridge deletion is not possible currently if vm or ct are running on this bridge\n" }) 
+		if defined($interface);
+	}
+
+	PVE::Tools::file_copy($new_config_file, $current_config_file);
+	unlink $new_config_file;
+
+	my $worker = sub {
+	    PVE::Tools::run_command(['systemctl', 'reload', 'networking']);
+	};
+	return $rpcenv->fork_worker('srvreload', 'networking', $authuser, $worker);
+   }});
+
+__PACKAGE__->register_method({
     name => 'delete_network', 
     path => '{iface}', 
     method => 'DELETE',
-- 
2.11.0



More information about the pve-devel mailing list