Commit 6400eea1 authored by Francesc Guasch's avatar Francesc Guasch
Browse files

Merge branch 'robertperez-upc-feat/cool_new_branch'

parents 41dd8fc0 ed00d463
......@@ -2332,9 +2332,10 @@ sub clone {
my $request = delete $args{request};
my $memory = delete $args{memory};
my $start = delete $args{start};
my $is_pool = delete $args{is_pool};
my $no_pool = delete $args{no_pool};
my $with_cd = delete $args{with_cd};
my $volatile = delete $args{volatile};
my $id_owner = delete $args{id_owner};
confess "ERROR: Unknown args ".join(",",sort keys %args)
if keys %args;
......@@ -2353,7 +2354,7 @@ sub clone {
delete $args2{from_pool};
return $self->_copy_clone(%args2) if !$self->is_base && $self->id_base();
my $uid = $user->id;
my $uid = $id_owner || $user->id;
if ( !$self->is_base() ) {
$request->status("working","Preparing base") if $request;
......@@ -2367,6 +2368,7 @@ sub clone {
push @args_copy, ( remote_ip => $remote_ip) if $remote_ip;
push @args_copy, ( from_pool => $from_pool) if defined $from_pool;
push @args_copy, ( add_to_pool => $add_to_pool) if defined $add_to_pool;
push @args_copy, ( volatile => $volatile ) if defined $volatile;
my $vm = $self->_vm;
if ($self->volatile_clones ) {
......@@ -2408,6 +2410,9 @@ sub _copy_clone($self, %args) {
my $memory = delete $args{memory};
my $request = delete $args{request};
my $add_to_pool = delete $args{add_to_pool};
my $volatile = delete $args{volatile};
my $id_owner = delete $args{id_owner};
$id_owner = $user->id if (! $id_owner);
confess "ERROR: Unknown arguments ".join(",",sort keys %args)
if keys %args;
......@@ -2416,6 +2421,7 @@ sub _copy_clone($self, %args) {
my @copy_arg;
push @copy_arg, ( memory => $memory ) if $memory;
push @copy_arg, ( volatile => $volatile ) if $volatile;
$request->status("working","Copying domain ".$self->name
." to $name") if $request;
......@@ -2423,7 +2429,7 @@ sub _copy_clone($self, %args) {
my $copy = $self->_vm->create_domain(
name => $name
,id_base => $base->id
,id_owner => $user->id
,id_owner => $id_owner
,from_pool => 0
,@copy_arg
);
......@@ -2455,7 +2461,7 @@ sub _copy_ports($base, $copy) {
for my $port ( $base->list_ports ) {
my %port = %$port;
next if $port_already{$port->{internal_port}};
delete @port{'id','id_domain','public_port'};
delete @port{'id','id_domain','public_port','is_active'};
$copy->expose(%port);
}
......@@ -4379,7 +4385,7 @@ sub _pre_clone($self,%args) {
confess "ERROR: Missing user owner of new domain" if !$user;
for (qw(is_pool start add_to_pool from_pool with_cd)) {
for (qw(is_pool start add_to_pool from_pool with_cd volatile id_owner)) {
delete $args{$_};
}
confess "ERROR: Unknown arguments ".join(",",sort keys %args) if keys %args;
......
......@@ -129,26 +129,24 @@ Returns: listref of machines
=cut
sub list_machines_user($self, $user, $access_data={}) {
my $sth = $CONNECTOR->dbh->prepare(
"SELECT id,name,is_public, description, screenshot"
"SELECT id,name,is_public, description, screenshot, id_owner"
." FROM domains "
." WHERE is_base=1"
." ORDER BY name "
);
my ($id, $name, $is_public, $description, $screenshot);
my ($id, $name, $is_public, $description, $screenshot, $id_owner);
$sth->execute;
$sth->bind_columns(\($id, $name, $is_public, $description, $screenshot));
$sth->bind_columns(\($id, $name, $is_public, $description, $screenshot, $id_owner));
my @list;
while ( $sth->fetch ) {
next if !$is_public && !$user->is_admin;
next if !$user->allowed_access($id);
my $is_active = 0;
my $clone = $self->search_clone(
id_owner =>$user->id
,id_base => $id
);
next unless $clone || $user->is_admin || ($is_public && $user->allowed_access($id));
my %base = ( id => $id, name => $name
, is_public => ($is_public or 0)
, screenshot => ($screenshot or '')
......
......@@ -81,7 +81,7 @@ our %VALID_ARG = (
,check_storage => { uid => 1 }
,set_base_vm=> {uid => 1, id_vm=> 1, id_domain => 1, value => 2 }
,cleanup => { }
,clone => { uid => 1, id_domain => 1, name => 2, memory => 2, number => 2
,clone => { uid => 1, id_domain => 1, name => 2, memory => 2, number => 2, volatile => 2, id_owner => 2
# If base has pools, from_pool = 1 if undefined
# when from_pool is true the clone is picked from the pool
# when from_pool is false the clone is created
......
......@@ -414,8 +414,9 @@ sub _around_create_domain {
|| $owner->can_create_machine()
|| ($base && $owner->can_clone);
confess "ERROR: Base ".$base->name." is private"
if !$owner->is_admin && $base && !$base->is_public();
# Do not check if base is public to allow not public machines to be copied
# confess "ERROR: Base ".$base->name." is private"
# if !$owner->is_admin && $base && !$base->is_public();
if ($add_to_pool) {
confess "Error: This machine can only be added to a pool if it is a clone"
......@@ -455,7 +456,7 @@ sub _around_create_domain {
}
}
my $user = Ravada::Auth::SQL->search_by_id($id_owner);
$domain->is_volatile(1) if $user->is_temporary() ||($base && $base->volatile_clones());
$domain->is_volatile(1) if $user->is_temporary() ||($base && $base->volatile_clones()) || $volatile;
my @start_args = ( user => $owner );
push @start_args, (remote_ip => $remote_ip) if $remote_ip;
......@@ -801,7 +802,7 @@ sub _check_require_base {
delete $args{start};
delete $args{remote_ip};
delete @args{'_vm','name','vm', 'memory','description','id_iso','listen_ip','spice_password','from_pool'};
delete @args{'_vm','name','vm', 'memory','description','id_iso','listen_ip','spice_password','from_pool', 'volatile'};
confess "ERROR: Unknown arguments ".join(",",keys %args)
if keys %args;
......@@ -824,10 +825,12 @@ sub _check_require_base {
die "ERROR: Domain ".$self->name." is not base"
if !$base->is_base();
my $user = Ravada::Auth::SQL->search_by_id($id_owner);
# Do not check if base is public to allow not public machines to be copied
# my $user = Ravada::Auth::SQL->search_by_id($id_owner);
die "ERROR: Base ".$base->name." is not public\n"
unless $user->is_admin || $base->is_public;
# die "ERROR: Base ".$base->name." is not public\n"
# unless $user->is_admin || $base->is_public;
}
=head2 id
......
......@@ -25,18 +25,19 @@ has ravada => (
);
my %SUB = (
list_alerts => \&_list_alerts
,list_bases => \&_list_bases
,list_isos => \&_list_isos
,list_nodes => \&_list_nodes
,list_machines => \&_list_machines
,list_machines_tree => \&_list_machines_tree
,list_machines_user => \&_list_machines_user
,list_bases_anonymous => \&_list_bases_anonymous
,list_requests => \&_list_requests
,machine_info => \&_get_machine_info
,ping_backend => \&_ping_backend
,request => \&_request
list_alerts => \&_list_alerts
,list_bases => \&_list_bases
,list_isos => \&_list_isos
,list_nodes => \&_list_nodes
,list_machines => \&_list_machines
,list_machines_tree => \&_list_machines_tree
,list_machines_user => \&_list_machines_user
,list_machines_user_including_privates => \&_list_machines_user_including_privates
,list_bases_anonymous => \&_list_bases_anonymous
,list_requests => \&_list_requests
,machine_info => \&_get_machine_info
,ping_backend => \&_ping_backend
,request => \&_request
);
our %TABLE_CHANNEL = (
......@@ -171,6 +172,17 @@ sub _list_machines_user($rvd, $args) {
return $ret;
}
sub _list_machines_user_including_privates($rvd, $args) {
my $login = $args->{login} or die "Error: no login arg ".Dumper($args);
my $user = Ravada::Auth::SQL->new(name => $login)
or die "Error: uknown user $login";
my $client = $args->{client};
my $ret = $rvd->list_machines_user($user, {client => $client});
return $ret;
}
sub _list_bases_anonymous($rvd, $args) {
my $remote_ip = $args->{remote_ip} or die "Error: no remote_ip arg ".Dumper($args);
return $rvd->list_bases_anonymous($remote_ip);
......
......@@ -121,7 +121,7 @@
$scope.subscribe_list_machines_user = function(url) {
$scope.machines = [];
var channel = 'list_machines_user';
var channel = 'list_machines_user_including_privates';
if ($scope.anonymous) {
channel = 'list_bases_anonymous';
}
......@@ -212,6 +212,7 @@
var data = JSON.parse(event.data);
$scope.$apply(function () {
$scope.showmachine = data;
$scope.copy_is_volatile = $scope.showmachine.is_volatile;
if (!subscribed_extra) {
subscribed_extra = true;
subscribe_nodes(url,data.type);
......@@ -506,6 +507,9 @@
,'copy_number': $scope.copy_number
,'copy_ram': $scope.copy_ram
,'new_name': $scope.new_name
,'new_owner': $scope.copy_owner
,'copy_is_volatile': $scope.copy_is_volatile
,'copy_is_pool': $scope.copy_is_pool
})
).then(function(response) {
// if there are many , we pick the last one
......@@ -736,6 +740,7 @@
$scope.list_users=response.data;
for (var i = 0; i < response.data.length; i++) {
if (response.data[i].id == $scope.showmachine.id_owner) {
$scope.copy_owner = response.data[i].id;
$scope.new_owner = response.data[i];
}
}
......
......@@ -2442,9 +2442,18 @@ sub copy_machine {
my $base = $RAVADA->search_domain_by_id($id_base) or confess "I can't find domain $id_base";
my $name = ( $arg->{new_name} or $base->name."-".$USER->name );
$USER = _logged_in($c);
my $owner = $arg->{new_owner};
$owner = undef if (! $USER) || (! $USER->is_admin);
confess "owner do not exists" if ($owner) && (! Ravada::Auth::SQL->new(name => $owner));
my @create_args = ( from_pool => 0 );
push @create_args,( memory => $ram ) if $ram;
push @create_args, ( name => $name ) if $number == 1;
push @create_args, ( id_owner => $owner ) if ($owner);
push @create_args, ( volatile => $arg->{copy_is_volatile} ? 1 : 0 );
push @create_args, ( add_to_pool => $arg->{copy_is_pool} && $base->is_pool() ? 1 : 0 );
my $req2 = Ravada::Request->clone(
uid => $USER->id
, id_domain => $base->id
......
use warnings;
use strict;
use Carp qw(confess);
use Data::Dumper;
use Hash::Util qw(lock_hash);
use Test::More;
......@@ -103,7 +104,7 @@ sub test_access_by_attribute_deny($vm, $do_clones=0) {
is($data->{teacher}->{user}->allowed_access( $base->id ), 1);
is($data->{other}->{user}->allowed_access( $base->id ), 1);
_do_clones($data, $base, $do_clones);
my ($clone_student, $clone_teacher) = _do_clones($data, $base, $do_clones);
$base->deny_ldap_access( givenName => $data->{student}->{user}->{name});
_refresh_users($data);
......@@ -111,6 +112,7 @@ sub test_access_by_attribute_deny($vm, $do_clones=0) {
is($data->{teacher}->{user}->allowed_access( $base->id ), 1);
is($data->{other}->{user}->allowed_access( $base->id ), 1);
$clone_student->remove(user_admin) if $clone_student;
my $list_bases = rvd_front->list_machines_user($data->{student}->{user});
is(scalar (@$list_bases), 0);
......@@ -310,7 +312,7 @@ sub test_access_by_attribute($vm, $do_clones=0) {
$base->prepare_base(user_admin);
$base->is_public(1);
_do_clones($data, $base, $do_clones);
my ($clone_student, $clone_teacher) = _do_clones($data, $base, $do_clones);
my $list_bases = rvd_front->list_machines_user($data->{student}->{user});
is(scalar (@$list_bases), 1);
......@@ -338,8 +340,10 @@ sub test_access_by_attribute($vm, $do_clones=0) {
$list_bases = rvd_front->list_machines_user($data->{student}->{user});
is(scalar (@$list_bases), 1);
$clone_teacher->remove(user_admin) if $clone_teacher;
$list_bases = rvd_front->list_machines_user($data->{teacher}->{user});
is(scalar (@$list_bases), 0);
is(scalar (@$list_bases), 0) or confess Dumper($list_bases,$base->id);
# other has no external_auth, access denied
$list_bases = rvd_front->list_machines_user($data->{other}->{user});
......@@ -409,7 +413,7 @@ sub test_access_by_attribute_2bases($vm, $do_clones=0) {
my @bases = _create_bases($vm,2);
_do_clones($data, $bases[0], $do_clones);
my($clone_student, $clone_teacher) = _do_clones($data, $bases[0], $do_clones);
_do_clones($data, $bases[1], $do_clones);
my $list_bases = rvd_front->list_machines_user($data->{student}->{user});
......@@ -444,8 +448,14 @@ sub test_access_by_attribute_2bases($vm, $do_clones=0) {
$list_bases = rvd_front->list_machines_user($data->{student}->{user});
is(scalar (@$list_bases), 2);
if ($do_clones) {
$list_bases = rvd_front->list_machines_user($data->{teacher}->{user});
is(scalar (@$list_bases), 2) or die Dumper($do_clones,$list_bases);
$clone_teacher->remove(user_admin) if $clone_teacher;
}
$list_bases = rvd_front->list_machines_user($data->{teacher}->{user});
is(scalar (@$list_bases), 1);
is(scalar (@$list_bases), 1) or die Dumper($list_bases, $bases[0]->id);
$list_bases = rvd_front->list_machines_user($data->{other}->{user});
is(scalar (@$list_bases), 1);
......
......@@ -24,7 +24,7 @@ for my $vm_name ( 'KVM' ) {
next if $vm_name eq 'KVM' && $>;
_set_no_password();
my $domain = import_domain($vm_name);
my $domain = import_domain($vm_name, $base);
is($domain->is_base,1);
my $clone = $domain->clone(
user => user_admin
......
......@@ -581,18 +581,11 @@ sub test_private_base {
my $clone_name = new_domain_name();
my $clone;
eval { $clone = $domain->clone(user => $USER, name => $clone_name); };
like($@,qr(private)) or exit;
my $clone2 = $vm->search_domain($clone_name);
ok(!$clone2,"Expecting no clone");
$clone2->remove(user_admin) if $clone2;
# admin can clone
eval { $clone = $domain->clone(user => user_admin, name => $clone_name); };
is($@,'');
$clone2 = $vm->search_domain($clone_name);
my $clone2 = $vm->search_domain($clone_name);
ok($clone2,"Expecting a clone");
$clone->remove(user_admin) if $clone;
......@@ -605,13 +598,6 @@ sub test_private_base {
ok($clone2,"Expecting a clone");
$clone->remove(user_admin) if $clone;
# hide it again
$domain->is_public(0);
eval { $clone = $domain->clone(user => $USER, name => $clone_name); };
like($@,qr(.));
$clone2 = $vm->search_domain($clone_name);
ok(!$clone2,"Expecting no clone");
}
sub test_domain_limit_admin {
my $vm_name = shift;
......
......@@ -14,7 +14,7 @@
<div class="card-body">
<div ng-repeat="machine in machines | orderBy: 'id_clone'"
class="col-sm-4 d-inline-block mb-2"
ng-show="machine.is_public || (!machine.is_public && !only_public)">
ng-show="machine.is_public || (!only_public)">
<div class="card card-success">
<div class="card-header" id="step1" >
<h3 class="card-title">
......
......@@ -33,6 +33,30 @@
<input class="form-control" ng-model="copy_ram" type="text" size="3">
</div>
</div>
<div class="row">
<div class="col-md-12 mt-12">
<input type="checkbox" name="copy_is_volatile" ng-model="copy_is_volatile">
<label class="control-label" for="copy_is_volatile"><%=l 'Volatile' %></label>
</div>
</div>
<div class="row" ng-show="showmachine.is_pool">
<div class="col-md-12 mt-12">
<input type="checkbox" name="copy_is_pool" ng-model="copy_is_pool">
<label class="control-label" for="copy_is_pool"><%=l 'Pool' %></label>
</div>
</div>
% if ($USER->is_admin){
<div class="form-group row">
<div class="col-md-2 mt-2">
<label class="control-label" for="copy_owner"><%=l 'Owner' %></label>
</div>
<div class="col-md-4">
<select class="form-control" ng-model="copy_owner" name="copy_owner">
<option ng-repeat="user in list_users" ng-value="user.id" ng-selected="user.id == copy_owner">{{user.name}}</option>
</select>
</div>
</div>
% }
<div ng-show="copy_request" class="alert alert-warning">
Copy {{showmachine.name}} {{copy_request.status}}.
<br/>
......
......@@ -185,7 +185,7 @@
<label class="control-label" for="new_owner"><%=l 'Owner' %></label>
</div>
<div class="col-lg-4">
<select ng-model="new_owner" name="id_owner"
<select class="form-control" ng-model="new_owner" name="id_owner"
ng-options="user.name for user in list_users track by user.id"
ng-change="set_value('id_owner',new_owner.id)"
>
......
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