Commit ff6449fe authored by Francesc Guasch's avatar Francesc Guasch
Browse files

Merge branch 'develop' into refactor/1196_ws2

parents 2a366443 6bc0a4a8
......@@ -47,6 +47,7 @@ my $LIST;
my $HIBERNATE_DOMAIN;
my $START_DOMAIN;
my $SHUTDOWN_DOMAIN;
my $REMOVE_DOMAIN;
my $REBASE;
my $RUN_REQUEST;
......@@ -80,6 +81,7 @@ my $USAGE = "$0 "
." --start\n"
." --hibernate machine\n"
." --shutdown machine\n"
." --remove machine\n"
."\n"
."Operations modifiers:\n"
." --all : execute on all virtual machines\n"
......@@ -106,6 +108,7 @@ GetOptions ( help => \$help
,'url-isos=s'=> \$URL_ISOS
,'shutdown:s'=> \$SHUTDOWN_DOMAIN
,'hibernate:s'=> \$HIBERNATE_DOMAIN
,'remove:s'=> \$REMOVE_DOMAIN
,'disconnected'=> \$DISCONNECTED
,'remove-user=s'=> \$REMOVE_USER
,'make-admin=s' => \$MAKE_ADMIN_USER
......@@ -443,6 +446,20 @@ sub hibernate {
if !$domain_name && !$found;
}
sub remove_domain {
my $domain_name = shift;
my $rvd_back = Ravada->new(%CONFIG);
my $domain = $rvd_back->search_domain($domain_name);
die "Error: domain $domain_name not found\n" if !$domain;
Ravada::Request->remove_domain(
uid => Ravada::Utils::user_daemon()->id
,name => $domain->name
);
print "Removing $domain_name\n";
}
sub start_domain {
my $domain_name = shift;
......@@ -607,6 +624,7 @@ rebase() if $REBASE;
list($ALL) if $LIST;
hibernate($HIBERNATE_DOMAIN , $ALL) if defined $HIBERNATE_DOMAIN;
remove_domain($REMOVE_DOMAIN) if defined $REMOVE_DOMAIN;
start_domain($START_DOMAIN) if $START_DOMAIN;
shutdown_domain($SHUTDOWN_DOMAIN, $ALL, $HIBERNATED)
......
......@@ -16,6 +16,9 @@ my $DIR_SRC = getcwd;
my $DIR_DST;
my $DEBIAN = "DEBIAN";
my %COPY_RELEASES = (
'ubuntu-19.04'=> ['ubuntu-18.10','ubuntu-19.10']
);
my %DIR = (
templates => '/usr/share/ravada'
,'etc/ravada.conf' => 'etc'
......@@ -324,6 +327,18 @@ sub get_fallback {
print `etc/get_fallback.pl`;
}
sub copy_identical_releases {
for my $source (sort keys %COPY_RELEASES ) {
for my $copy (@{$COPY_RELEASES{$source}}) {
my $file_source = "$DIR_SRC/../ravada_release/ravada_${VERSION}_${source}_all.deb";
die "Error: No $file_source" if !-e $file_source;
my $file_copy = "$DIR_SRC/../ravada_release/ravada_${VERSION}_${copy}_all.deb";
copy($file_source, $file_copy) or die "Error: $!\n$file_source -> $file_copy";
}
}
exit;
}
#########################################################################
get_fallback();
......@@ -367,3 +382,5 @@ tar($dist);
create_md5sums();
create_deb($dist);
}
copy_identical_releases();
......@@ -4,7 +4,7 @@ Architecture: all
Section: utils
Priority: optional
Maintainer: Francesc Guasch <frankie@telecos.upc.edu>
Depends: perl (>=5.18),libmojolicious-perl,mysql-common,libauthen-passphrase-perl, libdatetime-perl, libdbd-mysql-perl,libdbi-perl,libdbix-connector-perl,libipc-run3-perl,libio-stringy-perl,libnet-ldap-perl,libproc-pid-file-perl,libvirt-daemon-system,libsys-virt-perl,libxml-libxml-perl,libconfig-yaml-perl,libmoose-perl,libjson-xs-perl,qemu-utils,perlmagick,libmoosex-types-netaddr-ip-perl,libio-interface-perl,libiptables-chainmgr-perl,libnet-dns-perl,wget,liblocale-maketext-lexicon-perl,libmojolicious-plugin-i18n-perl,libdbd-sqlite3-perl, debconf (>= 0.2.26), adduser, libdigest-sha-perl, qemu-kvm, net-tools, libfile-rsync-perl, libnet-ssh2-perl, bridge-utils
Depends: perl (>=5.18),libmojolicious-perl,mysql-common,libauthen-passphrase-perl, libdatetime-perl, libdbd-mysql-perl,libdbi-perl,libdbix-connector-perl,libipc-run3-perl,libio-stringy-perl,libnet-ldap-perl,libproc-pid-file-perl,libvirt-daemon-system,libsys-virt-perl,libxml-libxml-perl,libconfig-yaml-perl,libmoose-perl,libjson-xs-perl,qemu-utils,perlmagick,libmoosex-types-netaddr-ip-perl,libio-interface-perl,libiptables-chainmgr-perl,libnet-dns-perl,wget,liblocale-maketext-lexicon-perl,libmojolicious-plugin-i18n-perl,libdbd-sqlite3-perl, debconf (>= 0.2.26), adduser, libdigest-sha-perl, qemu-kvm, net-tools, libfile-rsync-perl, libnet-ssh2-perl, bridge-utils, libencode-locale-perl
Description: Remote Virtual Desktops Manager
Ravada is a software that allows the user to connect to a
remote virtual desktop.
......@@ -4,7 +4,7 @@ Architecture: all
Section: utils
Priority: optional
Maintainer: Francesc Guasch <frankie@telecos.upc.edu>
Depends: perl (>=5.18),libmojolicious-perl,mysql-common,libauthen-passphrase-perl, libdatetime-perl, libdbd-mysql-perl,libdbi-perl,libdbix-connector-perl,libipc-run3-perl,libio-stringy-perl,libnet-ldap-perl,libproc-pid-file-perl,libvirt-bin,libvirt-daemon-system,libsys-virt-perl,libxml-libxml-perl,libconfig-yaml-perl,libmoose-perl,libjson-xs-perl,qemu-utils,perlmagick,libmoosex-types-netaddr-ip-perl,libio-interface-perl,libiptables-chainmgr-perl,libnet-dns-perl,wget,liblocale-maketext-lexicon-perl,libmojolicious-plugin-i18n-perl,libdbd-sqlite3-perl, debconf (>= 0.2.26), adduser, libdigest-sha-perl, qemu-kvm, net-tools, libfile-rsync-perl, libnet-ssh2-perl, bridge-utils
Depends: perl (>=5.18),libmojolicious-perl,mysql-common,libauthen-passphrase-perl, libdatetime-perl, libdbd-mysql-perl,libdbi-perl,libdbix-connector-perl,libipc-run3-perl,libio-stringy-perl,libnet-ldap-perl,libproc-pid-file-perl,libvirt-bin,libvirt-daemon-system,libsys-virt-perl,libxml-libxml-perl,libconfig-yaml-perl,libmoose-perl,libjson-xs-perl,qemu-utils,perlmagick,libmoosex-types-netaddr-ip-perl,libio-interface-perl,libiptables-chainmgr-perl,libnet-dns-perl,wget,liblocale-maketext-lexicon-perl,libmojolicious-plugin-i18n-perl,libdbd-sqlite3-perl, debconf (>= 0.2.26), adduser, libdigest-sha-perl, qemu-kvm, net-tools, libfile-rsync-perl, libnet-ssh2-perl, bridge-utils, libencode-locale-perl
Description: Remote Virtual Desktops Manager
Ravada is a software that allows the user to connect to a
remote virtual desktop.
control-ubuntu-19.04
\ No newline at end of file
......@@ -3,7 +3,7 @@ package Ravada;
use warnings;
use strict;
our $VERSION = '0.5.0-rc7';
our $VERSION = '0.5.0-rc9';
use Carp qw(carp croak);
use Data::Dumper;
......@@ -138,6 +138,7 @@ sub BUILD {
sub _install($self) {
$self->_create_tables();
$self->_upgrade_tables();
$self->_upgrade_timestamps();
$self->_update_data();
$self->_init_user_daemon();
}
......@@ -1274,6 +1275,30 @@ sub _upgrade_tables {
$self->_upgrade_table('domain_ports', 'internal_ip','char(200)');
}
sub _upgrade_timestamps($self) {
return if $CONNECTOR->dbh->{Driver}{Name} !~ /mysql/;
my $req = Ravada::Request->ping_backend();
return if $req->{date_changed};
my @commands = qw(cleanup enforce_limits list_isos list_network_interfaces
manage_pools open_exposed_ports open_iptables ping_backend
refresh_machine refresh_storage refresh_vms
screenshot);
my $sql ="DELETE FROM requests WHERE "
.join(" OR ", map { "command = '$_'" } @commands);
my $sth = $CONNECTOR->dbh->prepare($sql);
$sth->execute();
$self->_upgrade_timestamp('requests','date_changed');
}
sub _upgrade_timestamp($self, $table, $field) {
my $sth = $CONNECTOR->dbh->prepare("ALTER TABLE $table change $field "
."$field timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP");
$sth->execute();
}
sub _connect_dbh {
my $driver= ($CONFIG->{db}->{driver} or 'mysql');;
......@@ -2225,7 +2250,7 @@ sub _kill_stale_process($self) {
." AND pid IS NOT NULL "
." AND start_time IS NOT NULL "
);
$sth->execute(time - 5*scalar(@domains) + 60 );
$sth->execute(time - 5*scalar(@domains) - 60 );
while (my ($id, $pid, $command, $start_time) = $sth->fetchrow) {
if ($pid == $$ ) {
warn "HOLY COW! I should kill pid $pid stale for ".(time - $start_time)
......@@ -2315,9 +2340,9 @@ sub _execute {
}
$request->status('working','') unless $request->status() eq 'waiting';
$request->pid($$);
$request->start_time(time);
$request->error('');
$request->status('working','');
if ($dont_fork || !$CAN_FORK) {
$self->_do_execute_command($sub, $request);
return;
......@@ -2573,8 +2598,7 @@ sub _wait_pids {
for my $type ( keys %{$self->{pids}} ) {
for my $pid ( keys %{$self->{pids}->{$type}}) {
my $kid = waitpid($pid , WNOHANG);
last if $kid <= 0 ;
push @done, ($kid);
push @done, ($pid) if $kid == $pid || $kid == -1;
}
}
return if !@done;
......
......@@ -1487,6 +1487,7 @@ sub _after_remove_domain {
$self->_finish_requests_db();
$self->_remove_base_db();
$self->_remove_access_attributes_db();
$self->_remove_ports_db();
$self->_remove_volumes_db();
$self->_remove_bases_vm_db();
$self->_remove_domain_db();
......@@ -1517,6 +1518,14 @@ sub _remove_domain_cascade($self,$user, $cascade = 1) {
}
}
sub _remove_ports_db($self) {
return if !$self->{_data}->{id};
my $sth = $$CONNECTOR->dbh->prepare("DELETE FROM domain_ports"
." WHERE id_domain=?");
$sth->execute($self->id);
$sth->finish;
}
sub _remove_access_attributes_db($self) {
return if !$self->{_data}->{id};
......@@ -2290,14 +2299,21 @@ sub _add_expose($self, $internal_port, $name, $restricted) {
." VALUES (?,?,?,?,?)"
);
my $public_port = $self->_vm->_new_free_port();
$sth->execute($self->id
, $public_port, $internal_port
, ($name or undef)
, $restricted
);
$sth->finish;
my $public_port;
for (;;) {
eval {
$public_port = $self->_vm->_new_free_port();
$sth->execute($self->id
, $public_port, $internal_port
, ($name or undef)
, $restricted
);
$sth->finish;
};
last if !$@;
confess $@ if $@ && $@ !~ /Duplicate entry .*for key 'public/;
}
$self->_open_exposed_port($internal_port, $name, $restricted)
if $self->is_active && $self->ip;
......@@ -2539,7 +2555,11 @@ sub list_ports($self) {
my $base = Ravada::Front::Domain->open($self->id_base);
my @ports_base = $base->list_ports();
for my $data (@ports_base) {
push @list,($data) if !exists $clone_port{$data->{internal_port}};
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);
push @list,($data);
}
}
......
......@@ -1272,7 +1272,7 @@ sub create_iptables_chain($self, $chain, $jchain='INPUT') {
}
sub iptables($self, @args) {
my @cmd = ('/sbin/iptables');
my @cmd = ('/sbin/iptables','-w');
for ( ;; ) {
my $key = shift @args or last;
my $field = "-$key";
......
......@@ -7,7 +7,6 @@ use Encode::Locale;
use Fcntl qw(:flock O_WRONLY O_EXCL O_CREAT);
use Hash::Util qw(lock_hash);
use IPC::Run3 qw(run3);
use LWP::UserAgent;
use Moose;
use Socket qw( inet_aton inet_ntoa );
use Sys::Hostname;
......
......@@ -3,7 +3,7 @@ CREATE TABLE `requests` (
`command` char(32) DEFAULT NULL,
`args` char(255) DEFAULT NULL,
`date_req` datetime DEFAULT NULL,
`date_changed` timestamp ,
`date_changed` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ,
`status` char(64) DEFAULT NULL,
`error` text DEFAULT NULL,
`id_domain` int(11) DEFAULT NULL,
......
......@@ -251,6 +251,8 @@ sub test_user_bind {
is($mcnulty->{_auth}, 'bind');
test_uid_cn($user, $with_posix_group);
unlink $file_config_bind;
$ravada = Ravada->new(config => $file_config
......@@ -438,6 +440,58 @@ sub test_posix_group {
}
sub _replace_field($entry, $field, $with_posix_group) {
my $old_value = $entry->get_value($field);
die "Error: No $field found in LDAP entry in ".$entry->get_value('cn')
if !$old_value;
my $new_value = new_domain_name();
Ravada::Auth::LDAP::init();
my $ldap = Ravada::Auth::LDAP::_init_ldap_admin();
$entry->replace($field => $new_value);
my $mesg = $entry->update($ldap);
confess $mesg->code." ".$mesg->error if $mesg->code && $mesg->code;
_add_to_posix_group($new_value, $with_posix_group);
return ($old_value, $new_value);
}
sub test_uid_cn($user, $with_posix_group) {
Ravada::Auth::LDAP::init();
my $ldap = Ravada::Auth::LDAP::_init_ldap_admin();
my $entry = $user->{_ldap_entry};
my $field = 'uid';
my %data = (
cn => $entry->get_value('cn')
,$field => $entry->get_value($field)
);
test_login_fields(\%data);
my ($old_value, $new_value) = _replace_field($entry, $field, $with_posix_group);
$data{$field} = $new_value;
test_login_fields(\%data);
$entry->replace($field => $old_value);
$entry->update($ldap);
}
sub test_login_fields($data) {
my $password = 'jameson';
my $login_ok;
for my $field ( sort keys %$data ) {
my $value = $data->{$field};
eval { $login_ok = Ravada::Auth::login($value, $password) };
is($@,''," $field: $value");
ok($login_ok, $value);
}
}
SKIP: {
test_filter();
my $file_config = "t/etc/ravada_ldap.conf";
......@@ -478,6 +532,7 @@ SKIP: {
test_user_bind($user, $fly_config, $with_posix_group);
remove_users();
};
unlink($fly_config) if -e $fly_config;
......
......@@ -49,6 +49,9 @@ sub test_remove_domain {
my $vm_name = shift;
my $domain = test_create_domain($vm_name);
my $id_domain = $domain->id;
$domain->expose(22);
is(scalar($domain->list_ports), 1);
my @volumes = $domain->list_volumes();
$domain->remove($USER);
......@@ -63,6 +66,18 @@ sub test_remove_domain {
ok(!-e $vol,"[$vm_name] volume $vol should be removed");
}
}
test_ports_remove($id_domain);
}
sub test_ports_remove {
my $id_domain = shift;
my $sth = connector->dbh->prepare(
"SELECT count(*) FROM domain_ports "
." WHERE id_domain = ? "
);
my ($count) = $sth->fetchrow;
is($count,undef);
}
sub test_remove_domain_base {
......
......@@ -214,31 +214,6 @@ sub test_one_port($vm) {
ok($n_rule,"Expecting rule for -> $local_ip:$public_port") or exit;
#####################################################################3
#
# Check rule won't disapear refreshing
my $req1 = Ravada::Request->refresh_vms();
my $req2 = Ravada::Request->refresh_machine(id_domain => $domain->id, uid => user_admin->id);
wait_request();
is($req1->status,'done');
is($req1->error,'');
is($req2->status,'done');
is($req2->error,'');
($n_rule)
= search_iptable_remote(local_ip => "$local_ip/32"
, local_port => $public_port
, table => 'nat'
, chain => 'PREROUTING'
, node => $vm
, jump => 'DNAT'
, 'to-destination' => $domain->ip.":".$internal_port
);
ok($n_rule,"Expecting rule for -> $local_ip:$public_port") or exit;
#################################################################
#
......@@ -528,28 +503,36 @@ sub test_clone_exports_add_ports($vm) {
$base->expose(port => 22, name => "ssh");
my @base_ports0 = $base->list_ports();
$base->prepare_base(user => user_admin, with_cd => 1);
my $clone = $base->clone(name => new_domain_name, user => user_admin);
$base->expose(port => 80, name => "web");
my @base_ports = $base->list_ports();
is(scalar @base_ports, scalar @base_ports0 + 1);
my $clone_f = Ravada::Front::Domain->open($clone->id);
eval { my $info = $clone_f->info(user_admin) };
is($@,'');
$clone->start(remote_ip => '10.1.1.1', user => user_admin);
my @clone_ports = $clone->list_ports();
is(scalar @clone_ports,2 );
for my $n ( 0 .. 1 ) {
is($base_ports[$n]->{internal_port}, $clone_ports[$n]->{internal_port});
isnt($base_ports[$n]->{public_port}, $clone_ports[$n]->{public_port});
isnt($base_ports[$n]->{public_port}, $clone_ports[$n]->{public_port},"Same public port in clone and base for ".$base_ports[$n]->{internal_port});
is($base_ports[$n]->{name}, $clone_ports[$n]->{name});
}
my $out = `iptables -t nat -L PREROUTING`;
die $out;
_wait_ip($vm, $clone);
wait_request( );
my @out = split /\n/, `iptables -t nat -L PREROUTING -n`;
ok(grep /dpt:\d+.*\d+:22/, @out);
ok(grep /dpt:\d+.*\d+:80/, @out);
$clone->remove(user_admin);
$base->remove(user_admin);
}
sub _wait_ip {
my $vm_name = shift;
my $domain = shift or confess "Missing domain arg";
......@@ -951,6 +934,7 @@ for my $vm_name ( 'KVM', 'Void' ) {
next if !$vm;
diag("Testing $vm_name");
test_clone_exports_add_ports($vm);
test_no_dupe($vm);
......@@ -973,7 +957,6 @@ for my $vm_name ( 'KVM', 'Void' ) {
test_clone_exports($vm);
test_clone_exports_add_ports($vm);
}
flush_rules();
......
......@@ -96,10 +96,4 @@
</div>
% }
<div ng-show="message.length" class="alert alert-light border-primary text-primary mt-4">
<div ng-repeat="text in message">
{{text}}
</div>
</div>
</div>
Markdown is supported
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