Unverified Commit aac6eabf authored by Francesc Guasch's avatar Francesc Guasch Committed by GitHub
Browse files

Feat: config minimum port expose (#1550)

feat(ports): set minimum port to expose

also do not assign public port for bases

issue #1531
parent 908c4b72
......@@ -1472,6 +1472,11 @@ sub _sql_insert_defaults($self){
,name => "debug_ports"
,value => 0
}
,{
id_parent => $id_backend
,name => 'expose_port_min'
,value => '60000'
}
]
);
my %field = ( settings => 'name' );
......
......@@ -25,6 +25,7 @@ no warnings "experimental::signatures";
use feature qw(signatures);
use Ravada::Domain::Driver;
use Ravada::Auth::SQL;
use Ravada::Utils;
our $TIMEOUT_SHUTDOWN = 20;
......@@ -2798,7 +2799,10 @@ sub _add_expose($self, $internal_port, $name, $restricted) {
my $public_port;
for (;;) {
eval {
$public_port = $self->_vm->_new_free_port();
$public_port = $self->_vm->_new_free_port() if !$self->is_base;
};
die $@ if $@ && $@ !~ /no free ports/i;
eval {
$sth->execute($self->id
, $public_port, $internal_port
, ($name or undef)
......@@ -2816,7 +2820,12 @@ sub _add_expose($self, $internal_port, $name, $restricted) {
}
sub _set_public_port($self, $id_port, $internal_port, $name, $restricted) {
my $public_port = $self->_vm->_new_free_port();
my $public_port;
eval {
$public_port = undef;
$public_port = $self->_vm->_new_free_port();
};
my $error = $@;
for (;;) {
if ($id_port) {
my $sth = $$CONNECTOR->dbh->prepare("UPDATE domain_ports set public_port=?"
......@@ -2844,6 +2853,12 @@ sub _set_public_port($self, $id_port, $internal_port, $name, $restricted) {
}
$public_port += int(rand(10))+1;
}
if ($error) {
my $user = Ravada::Auth::SQL->search_by_id($self->_data('id_owner'));
$user->send_message($error);
warn $error;
die $error;
}
}
sub _used_ports_iptables($self, $port, $skip_port) {
......@@ -2880,7 +2895,7 @@ sub _open_exposed_port($self, $internal_port, $name, $restricted) {
);
$sth->execute($internal_ip, $self->id, $internal_port);
if ( !$> ) {
if ( !$> && $public_port ) {
my ($out, $err) = $self->_vm->run_command("iptables-save","-t","nat");
my @open1 = (grep /--dport $public_port/, split/\n/,$out );
my @open2 = (grep /--to-destination $internal_ip:$internal_port/, split/\n/,$out );
......@@ -3112,9 +3127,19 @@ sub list_ports($self) {
my @ports_base = $base->list_ports();
for my $data (@ports_base) {
next if exists $clone_port{$data->{internal_port}};
unlock_hash(%$data);
$data->{public_port} = $self->_vm->_new_free_port() if $self->_vm;
lock_hash(%$data);
if ($self->_vm) {
unlock_hash(%$data);
eval {
$data->{public_port} = '';
$data->{public_port} = $self->_vm->_new_free_port();
};
my $error = $@;
if ($error) {
my $user = Ravada::Auth::SQL->search_by_id($self->_data('id_owner'));
$user->send_message(substr($error,0,80));
}
lock_hash(%$data);
}
push @list,($data);
}
}
......
......@@ -1925,10 +1925,13 @@ sub _new_free_port($self) {
$self->_list_used_ports_ss($used_port);
$self->_list_used_ports_iptables($used_port);
my $free_port = 5950;
my $min_free_port = Ravada::setting(undef,'/backend/expose_port_min');
my $free_port = $min_free_port;
for (;;) {
last if !$used_port->{$free_port};
$free_port++ ;
die "Error: no free ports available from $min_free_port.\n"
if $free_port > 65535;
}
return $free_port;
}
......
......@@ -140,6 +140,18 @@
</div>
</div>
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-2">
<label for="debug">Port expose</label>
</div>
<div class="col-md-8">
<input name="debug" ng-model="settings.backend.expose_port_min.value"
type="number" min="1" max="65530">
<%= l 'Minimum port number to expose virtual machine services.' %>
<a href="https://ravada.readthedocs.io/en/latest/docs/expose_ports.html"><i class="fa fa-info"></i></a>
</div>
</div>
<hr>
......
......@@ -65,9 +65,12 @@
<ul ng-show="domain.ports.length">
<li ng-repeat="port in domain.ports">
<b>{{port.name}}</b>
<span ng-show="port.public_port">
{{domain.display.ip}}:{{port.public_port}}
<i class="fa fa-arrow-right"></i>
{{port.internal_port}}
</span>
<span ng-hide="port.public_port">Error: no free ports to expose</span>
</li>
</ul>
</div>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment