Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix display ip #1949

Merged
merged 10 commits into from
May 29, 2023
2 changes: 1 addition & 1 deletion lib/Ravada.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package Ravada;
use warnings;
use strict;

our $VERSION = '2.0.0';
our $VERSION = '2.1.0';

use utf8;

Expand Down
64 changes: 55 additions & 9 deletions lib/Ravada/VM.pm
Original file line number Diff line number Diff line change
Expand Up @@ -810,9 +810,19 @@ sub _list_ip_address($self) {
return %address;
}

sub _ip_a($self, $dev) {
my ($out, $err) = $self->run_command_cache("/sbin/ip","-o","a");
die $err if $err;
for my $line ( split /\n/,$out) {
my ($ip) = $line =~ m{^\d+:\s+$dev.*inet (.*?)/};
return $ip if $ip;
}
warn "Warning $dev not found in active interfaces";
}

sub _interface_ip($self, $remote_ip=undef) {
return '127.0.0.1' if $remote_ip && $remote_ip =~ /^127\./;
my ($out, $err) = $self->run_command("/sbin/ip","route");
my ($out, $err) = $self->run_command_cache("/sbin/ip","route");
my %route;
my ($default_gw , $default_ip);

Expand All @@ -823,18 +833,36 @@ sub _interface_ip($self, $remote_ip=undef) {
if ( $line =~ m{^default via ([\d\.]+)} ) {
$default_gw = NetAddr::IP->new($1);
}
if ($line =~ m{^default via.*dev (.*?)(\s|$)}) {
my $dev = $1;
$default_ip = $self->_ip_a($dev) if !$default_ip;
}
if ( $line =~ m{^([\d\.\/]+).*src ([\d\.\/]+)} ) {
my ($network, $ip) = ($1, $2);
$route{$network} = $ip;
if ($ip) {
$route{$network} = $ip;

return $ip if $remote_ip && $remote_ip eq $ip;
return $ip if $remote_ip && $remote_ip eq $ip;

my $netaddr = NetAddr::IP->new($network)
or confess "I can't find netaddr for $network";
return $ip if $remote_ip_addr->within($netaddr);
my $netaddr = NetAddr::IP->new($network)
or confess "I can't find netaddr for $network";
return $ip if $remote_ip_addr->within($netaddr);

$default_ip = $ip if !defined $default_ip && $ip !~ /^127\./;
$default_ip = $ip if defined $default_gw && $default_gw->within($netaddr);
$default_ip = $ip if defined $default_gw && $default_gw->within($netaddr);
}
}
if ( $line =~ m{^([\d\.\/]+).*dev (.+?) } ) {
my ($network, $dev) = ($1, $2);
my $ip = $self->_ip_a($dev);
if ($ip) {
$route{$network} = $ip;

return $ip if $remote_ip && $remote_ip eq $ip;

my $netaddr = NetAddr::IP->new($network)
or confess "I can't find netaddr for $network";
return $ip if $remote_ip_addr->within($netaddr);
}
}
}
return $default_ip;
Expand Down Expand Up @@ -1451,7 +1479,7 @@ sub remove($self) {

Run a command on the node

my @ls = $self->run_command("ls");
my ($out,$err) = $self->run_command_cache("ls");

=cut

Expand Down Expand Up @@ -1482,6 +1510,24 @@ sub run_command($self, @command) {
return ($out, $err);
}

=head2 run_command_cache

Run a command on the node

my ($out,$err) = $self->run_command_cache("ls");

=cut


sub run_command_cache($self, @command) {
my $key = join(" ",@command);
return @{$self->{_run}->{$key}} if exists $self->{_run}->{$key};

my ($out, $err) = $self->run_command(@command);
$self->{_run}->{$key}=[$out,$err];
return ($out, $err);
}

=head2 run_command_nowait

Run a command on the node
Expand Down
95 changes: 95 additions & 0 deletions t/vm/82_route.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use warnings;
use strict;

use Data::Dumper;
use Test::More;
use XML::LibXML;

use lib 't/lib';
use Test::Ravada;

no warnings "experimental::signatures";
use feature qw(signatures);

use_ok('Ravada');
###############################################################################
sub test_default_ip($vm) {
my $ip = $vm->_interface_ip('1.1.36.99');
unlike($ip, qr/^192.168.12/);

my $ip2 = $vm->listen_ip('1.1.36.99');
unlike($ip2, qr/^192.168.12/);


}

sub test_slim_route($vm) {
my $route = "default via 10.2.2.1 dev eth0
10.2.2.1 dev eth0 scope link

192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
192.18.1.0/24 dev foo1 proto kernel scope link src 192.18.1.3
192.18.2.0/24 dev foo2 scope link"
;
$vm->{_run}->{"/sbin/ip route"}=[$route,''];

my $devs = "1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
1: lo inet6 ::1/128 scope host \ valid_lft forever preferred_lft forever
3: wlp4s0 inet 192.168.1.62/24 brd 192.168.1.255 scope global noprefixroute wlp4s0\ valid_lft forever preferred_lft forever
5: eth0 inet 10.2.2.3/24 brd 10.2.2.255 scope global noprefixroute eth0\ valid_lft forever preferred_lft forever
6: foo1 inet 192.18.1.3/24 brd 192.168.1.255 scope global noprefixroute foo1\ valid_lft forever preferred_lft forever
7: foo2 inet 192.18.2.3/24 brd 192.168.2.255 scope global noprefixroute foo2\ valid_lft forever preferred_lft forever
8: virbr0 inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0\ valid_lft forever preferred_lft forever
";
$vm->{_run}->{"/sbin/ip -o a"}=[$devs,''];

my $domain = create_domain($vm);

for my $remote_ip ( qw ( 1.1.36.99 10.2.2.33 192.18.1.9 192.18.2.9)) {
my $expected_ip = '10.2.2.3';
if ($remote_ip =~ /192.18/) {
$expected_ip = $remote_ip;
$expected_ip =~ s/\.\d+$/\.3/;
}

my $ip = $vm->_interface_ip($remote_ip);
unlike($ip, qr/^192.168.12/);
is($ip, $expected_ip,"remote ip $remote_ip") or exit;
my $ip2 = $vm->listen_ip($remote_ip);
unlike($ip2, qr/^192.168.12/);
is($ip2,$expected_ip);

eval {
$domain->start(user => user_admin, remote_ip => $remote_ip);
};
like($@, qr/binding socket to/) if$vm->type ne 'Void';
my $display = $domain->info(user_admin)->{hardware}->{display};
for my $dp (@$display) {
unlike($dp->{listen_ip}, qr/^192.168.12/);
is($dp->{listen_ip}, $expected_ip) or exit;
}
$domain->shutdown_now(user_admin);

}
delete $vm->{_run};
}

###############################################################################
clean();

for my $vm_name (vm_names()) {
diag($vm_name);
my $vm;
eval { $vm = rvd_back->search_vm($vm_name); };
SKIP: {
if (!$vm) {
skip("No $vm_name virtual manager found",3);
}
test_slim_route($vm);
test_default_ip($vm);
}
}

end();
done_testing();

Loading