mirror of
https://github.com/webmin/webmin.git
synced 2026-06-04 12:20:23 +01:00
Fix to detect NetworkManager networking on Debian
ⓘ Prefer Netplan when Debian has Netplan YAML config, otherwise select the existing NetworkManager backend for Debian systems with saved NM connection profiles, with regression tests for backend selection. https://github.com/webmin/webmin/issues/2559
This commit is contained in:
32
net/net-detect.pl
Normal file
32
net/net-detect.pl
Normal file
@@ -0,0 +1,32 @@
|
||||
# net-detect.pl
|
||||
# Helper functions for choosing the network config backend
|
||||
|
||||
sub net_has_network_manager_config
|
||||
{
|
||||
my ($dir) = @_;
|
||||
$dir ||= "/etc/NetworkManager/system-connections";
|
||||
my @files = glob("$dir/*.nmconnection");
|
||||
return -d $dir && scalar(@files);
|
||||
}
|
||||
|
||||
sub net_has_netplan_config
|
||||
{
|
||||
my ($dir) = @_;
|
||||
$dir ||= "/etc/netplan";
|
||||
return &has_command("netplan") &&
|
||||
-d $dir;
|
||||
}
|
||||
|
||||
sub net_auto_backend
|
||||
{
|
||||
my ($os_type, $netplan_dir, $nm_conn_dir) = @_;
|
||||
return "netplan"
|
||||
if ($os_type eq "debian-linux" &&
|
||||
&net_has_netplan_config($netplan_dir));
|
||||
return "nm"
|
||||
if (($os_type eq "redhat-linux" || $os_type eq "debian-linux") &&
|
||||
&net_has_network_manager_config($nm_conn_dir));
|
||||
return undef;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -6,6 +6,9 @@ use WebminCore;
|
||||
&init_config();
|
||||
%access = &get_module_acl();
|
||||
$access{'ipnodes'} = $access{'hosts'};
|
||||
do "net-detect.pl";
|
||||
|
||||
$auto_net_mode = &net_auto_backend($gconfig{'os_type'});
|
||||
|
||||
if (-r "$module_root_directory/$gconfig{'os_type'}-$gconfig{'os_version'}-lib.pl") {
|
||||
do "$gconfig{'os_type'}-$gconfig{'os_version'}-lib.pl";
|
||||
@@ -23,20 +26,16 @@ elsif ($gconfig{'os_type'} eq 'slackware-linux' &&
|
||||
do "$gconfig{'os_type'}-9.1-ALL-lib.pl";
|
||||
$net_mode = $gconfig{'os_type'}."/9.1";
|
||||
}
|
||||
elsif ($gconfig{'os_type'} eq 'redhat-linux' &&
|
||||
-d "/etc/NetworkManager/system-connections" &&
|
||||
glob("/etc/NetworkManager/system-connections/*.nmconnection")) {
|
||||
# Special case for systems with network manager
|
||||
do 'nm-lib.pl';
|
||||
$net_mode = "nm";
|
||||
}
|
||||
elsif ($gconfig{'os_type'} eq 'debian-linux' &&
|
||||
&has_command("netplan") &&
|
||||
-d "/etc/netplan") {
|
||||
elsif ($auto_net_mode eq "netplan") {
|
||||
# Special case for newer Ubuntu versions
|
||||
do "netplan-lib.pl";
|
||||
$net_mode = "netplan";
|
||||
}
|
||||
elsif ($auto_net_mode eq "nm") {
|
||||
# Special case for systems with network manager
|
||||
do 'nm-lib.pl';
|
||||
$net_mode = "nm";
|
||||
}
|
||||
else {
|
||||
do "$gconfig{'os_type'}-lib.pl";
|
||||
$net_mode = $gconfig{'os_type'};
|
||||
|
||||
@@ -4,6 +4,7 @@ use warnings;
|
||||
use Test::More;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname);
|
||||
use File::Path qw(make_path);
|
||||
use File::Temp qw(tempdir);
|
||||
|
||||
my $root = abs_path(dirname(__FILE__)."/../..") or die "rootdir: $!";
|
||||
@@ -58,6 +59,7 @@ close($fh) || die "close $file: $!";
|
||||
sub lock_file { return 1; }
|
||||
sub unlock_file { return 1; }
|
||||
sub error { die join("", @_), "\n"; }
|
||||
sub unflush_file_lines { delete($file_cache{$_[0]}); }
|
||||
sub has_command { return $_[0] eq "netplan" ? "/usr/sbin/netplan" : undef; }
|
||||
sub execute_command_logged
|
||||
{
|
||||
@@ -68,6 +70,13 @@ $$stdout = $out if (ref($stdout));
|
||||
$$stderr = $out if (ref($stderr) && $stderr ne $stdout);
|
||||
return $command_status{$cmd} || 0;
|
||||
}
|
||||
sub backquote_logged
|
||||
{
|
||||
my ($cmd) = @_;
|
||||
push(@commands, $cmd);
|
||||
$? = $command_status{$cmd} || 0;
|
||||
return $command_output{$cmd} || "";
|
||||
}
|
||||
sub check_ipaddress { return $_[0] =~ /^\d+\.\d+\.\d+\.\d+$/; }
|
||||
sub check_ip6address { return $_[0] =~ /:/; }
|
||||
sub check_ipaddress_any { return &check_ipaddress($_[0]) || &check_ip6address($_[0]); }
|
||||
@@ -83,6 +92,29 @@ return -1;
|
||||
}
|
||||
|
||||
unshift(@INC, "$root/net", $root);
|
||||
do "$root/net/net-detect.pl" || die "net-detect.pl: $@ $!";
|
||||
|
||||
my $detect_root = tempdir(CLEANUP => 1);
|
||||
my $detect_netplan = "$detect_root/netplan";
|
||||
my $detect_no_netplan = "$detect_root/no-netplan";
|
||||
my $detect_nm = "$detect_root/NetworkManager/system-connections";
|
||||
my $detect_nm_empty = "$detect_root/NetworkManager-empty/system-connections";
|
||||
make_path($detect_netplan, $detect_nm, $detect_nm_empty);
|
||||
write_text("$detect_nm/eth0.nmconnection", "");
|
||||
|
||||
is(main::net_auto_backend("debian-linux", $detect_netplan, $detect_nm_empty),
|
||||
"netplan", "Debian uses Netplan when the config directory exists");
|
||||
is(main::net_auto_backend("debian-linux", $detect_no_netplan, $detect_nm),
|
||||
"nm", "Debian uses NetworkManager when only nmconnection files exist");
|
||||
is(main::net_auto_backend("redhat-linux", $detect_no_netplan, $detect_nm),
|
||||
"nm", "Red Hat still uses NetworkManager when nmconnection files exist");
|
||||
write_text("$detect_netplan/50-cloud-init.yaml", "");
|
||||
is(main::net_auto_backend("debian-linux", $detect_netplan, $detect_nm),
|
||||
"netplan", "Debian prefers Netplan over NetworkManager when YAML exists");
|
||||
unlink("$detect_netplan/50-cloud-init.yaml");
|
||||
is(main::net_auto_backend("debian-linux", $detect_no_netplan, $detect_nm_empty),
|
||||
undef, "Debian falls back when no Netplan or NetworkManager config exists");
|
||||
|
||||
do "$root/net/netplan-lib.pl" || die "netplan-lib.pl: $@ $!";
|
||||
|
||||
{
|
||||
@@ -167,4 +199,37 @@ is_deeply(\@commands,
|
||||
"(cd / && /usr/sbin/netplan apply)" ],
|
||||
"apply_network validates before applying");
|
||||
|
||||
do "$root/net/nm-lib.pl" || die "nm-lib.pl: $@ $!";
|
||||
my $nmfile = "$tmp/eth0.nmconnection";
|
||||
write_text($nmfile, <<'NM');
|
||||
[connection]
|
||||
id=eth0
|
||||
uuid=11111111-2222-3333-4444-555555555555
|
||||
type=ethernet
|
||||
interface-name=eth0
|
||||
|
||||
[ipv4]
|
||||
method=auto
|
||||
|
||||
[ipv6]
|
||||
method=disabled
|
||||
NM
|
||||
my $nmcfg = main::read_nm_config($nmfile);
|
||||
my $nmiface = {
|
||||
'name' => 'eth0',
|
||||
'fullname' => 'eth0',
|
||||
'file' => $nmfile,
|
||||
'cfg' => $nmcfg,
|
||||
'edit' => 1,
|
||||
'up' => 1,
|
||||
'dhcp' => 1,
|
||||
'address6' => [ ],
|
||||
'netmask6' => [ ],
|
||||
'nameserver' => [ "2001:4860:4860::8888" ],
|
||||
};
|
||||
@commands = ( );
|
||||
main::save_interface($nmiface, [ $nmiface ]);
|
||||
like(join("\n", @commands), qr/ipv6\.dns/,
|
||||
"NetworkManager save_interface writes IPv6 nameservers");
|
||||
|
||||
done_testing();
|
||||
|
||||
Reference in New Issue
Block a user