Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Projets publics
Ravada-Mirror
Commits
6400eea1
Commit
6400eea1
authored
Jun 15, 2021
by
Francesc Guasch
Browse files
Merge branch 'robertperez-upc-feat/cool_new_branch'
parents
41dd8fc0
ed00d463
Changes
13
Hide whitespace changes
Inline
Side-by-side
lib/Ravada/Domain.pm
View file @
6400eea1
...
...
@@ -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
;
...
...
lib/Ravada/Front.pm
View file @
6400eea1
...
...
@@ -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
'')
...
...
lib/Ravada/Request.pm
View file @
6400eea1
...
...
@@ -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
...
...
lib/Ravada/VM.pm
View file @
6400eea1
...
...
@@ -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
...
...
lib/Ravada/WebSocket.pm
View file @
6400eea1
...
...
@@ -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
);
...
...
public/js/ravada.js
View file @
6400eea1
...
...
@@ -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
];
}
}
...
...
script/rvd_front
View file @
6400eea1
...
...
@@ -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
...
...
t/front/70_ldap_access.t
View file @
6400eea1
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
);
...
...
t/vm/02_import_base.t
View file @
6400eea1
...
...
@@ -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
...
...
t/vm/20_base.t
View file @
6400eea1
...
...
@@ -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
;
...
...
templates/main/list_bases_ng.html.ep
View file @
6400eea1
...
...
@@ -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"
>
...
...
templates/main/vm_copy.html.ep
View file @
6400eea1
...
...
@@ -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/>
...
...
templates/main/vm_options.html.ep
View file @
6400eea1
...
...
@@ -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)"
>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment