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
243df982
Commit
243df982
authored
Jul 27, 2019
by
Francesc Guasch
Browse files
Merge branch 'master' into develop
parents
537fae11
61123c77
Changes
6
Hide whitespace changes
Inline
Side-by-side
CHANGELOG.md
View file @
243df982
...
...
@@ -3,19 +3,12 @@
**Implemented enhancements:**
-
Remote nodes support
-
Shared storage remote nodes [
\#
1014]
-
Manage Network interfaces [
\#
1011]
-
New permission to rename the machine [
\#
986]
-
Manage CDROM [
\#
973]
-
Start and Stop nodes [
\#
953]
-
Shutdown machines when disabling node enhancement [
\#
947]
-
Upgrade Bootstrap to 4.x [
\#
886]
-
Allow volatile machines in remote nodes [#865]
-
Remote machines sync back with no shared storage [
\#
583]
-
Add more storage to a VM [
\#
495]
-
Sync clock after hibernate [
\#
466]
-
Show the Internal IP [
\#
465]
-
Support TLS encryption channels in SPICE [
\#
249]
-
Allow add volumes to a virtual machine [
\#
198]
-
Check free disk space [
\#
10]
-
Add ISO for Debian Buster [
\#
1108]
-
non-predictable MAC addresses [
\#
1103]
-
first login fails after inactivity logout [
\#
1102]
**Bugfixes**
-
Specified key was too long with MariaDB 10.1 in Debian [
\#
1104]
-
Login name with spaces [
\#
1100]
-
Volatile domains get invalid SPICE IP [
\#
1099]
lib/Ravada.pm
View file @
243df982
...
...
@@ -3,7 +3,7 @@ package Ravada;
use
warnings
;
use
strict
;
our
$VERSION
=
'
0.4.
4
';
our
$VERSION
=
'
0.4.
7
';
use
Carp
qw(carp croak)
;
use
Data::
Dumper
;
...
...
@@ -2475,7 +2475,15 @@ sub _can_fork {
my
$type
=
$req
->
type
;
my
$n_pids
=
scalar
(
keys
%
{
$self
->
{
pids
}
->
{
$type
}});
return
1
if
!
$self
->
{
pids
}
->
{
$type
};
my
%reqs
=
%
{
$self
->
{
pids
}
->
{
$type
}};
for
my
$pid
(
keys
%reqs
)
{
my
$id_req
=
$reqs
{
$pid
};
my
$request
=
Ravada::
Request
->
open
(
$id_req
);
delete
$reqs
{
$pid
}
if
!
$request
||
$request
->
status
eq
'
done
';
}
my
$n_pids
=
scalar
(
keys
%reqs
);
return
1
if
$n_pids
<=
$req
->
requests_limit
();
my
$msg
=
$req
->
command
...
...
@@ -2998,9 +3006,9 @@ sub _cmd_refresh_vms($self, $request=undef) {
$self
->
_refresh_disabled_nodes
(
$request
);
$self
->
_refresh_down_nodes
(
$request
);
my
(
$active_domain
,
$active_vm
)
=
$self
->
_refresh_active_domains
(
$request
);
my
$active_vm
=
$self
->
_refresh_active_vms
();
my
$active_domain
=
$self
->
_refresh_active_domains
(
$request
);
$self
->
_refresh_down_domains
(
$active_domain
,
$active_vm
);
$self
->
_remove_unnecessary_downs
();
$self
->
_clean_requests
('
refresh_vms
',
$request
);
$self
->
_refresh_volatile_domains
();
...
...
@@ -3095,11 +3103,15 @@ sub _cmd_list_isos($self, $request){
$request
->
output
(
encode_json
(
\
@isos
));
}
sub
_clean_requests
($self, $command, $request=undef) {
sub
_clean_requests
($self, $command, $request=undef
, $status='requested'
) {
my
$query
=
"
DELETE FROM requests
"
.
"
WHERE command=?
"
.
"
AND status=
'requested'
";
.
"
AND status=
?
";
if
(
$status
eq
'
done
')
{
my
$date
=
Time::
Piece
->
localtime
(
time
-
300
);
$query
.=
"
AND date_changed <
"
.
$CONNECTOR
->
dbh
->
quote
(
$date
->
ymd
.
"
"
.
$date
->
hms
);
}
if
(
$request
)
{
confess
"
Wrong request
"
if
!
ref
(
$request
)
||
ref
(
$request
)
!~
/Request/
;
$query
.=
"
AND id <> ?
";
...
...
@@ -3107,21 +3119,16 @@ sub _clean_requests($self, $command, $request=undef) {
my
$sth
=
$CONNECTOR
->
dbh
->
prepare
(
$query
);
if
(
$request
)
{
$sth
->
execute
(
$command
,
$request
->
id
);
$sth
->
execute
(
$command
,
$status
,
$request
->
id
);
}
else
{
$sth
->
execute
(
$command
);
$sth
->
execute
(
$command
,
$status
);
}
}
sub
_refresh_active_domains
($self, $request=undef) {
my
$id_domain
;
$id_domain
=
$request
->
defined_arg
('
id_domain
')
if
$request
;
sub
_refresh_active_vms
($self) {
my
%active_domain
;
my
%active_vm
;
for
my
$vm
(
$self
->
list_vms
)
{
$request
->
status
('
working
',"
checking active domains on
"
.
$vm
->
name
)
if
$request
;
if
(
!
$vm
->
enabled
()
||
!
$vm
->
is_active
)
{
$vm
->
shutdown_domains
();
$active_vm
{
$vm
->
id
}
=
0
;
...
...
@@ -3129,21 +3136,30 @@ sub _refresh_active_domains($self, $request=undef) {
next
;
}
$active_vm
{
$vm
->
id
}
=
1
;
}
return
\
%active_vm
;
}
sub
_refresh_active_domains
($self, $request=undef) {
my
$id_domain
;
$id_domain
=
$request
->
defined_arg
('
id_domain
')
if
$request
;
my
%active_domain
;
if
(
$id_domain
)
{
my
$domain
=
$
vm
->
search_domain_by_id
(
$id_domain
);
$self
->
_refresh_active_domain
(
$vm
,
$domain
,
\
%active_domain
)
if
$domain
;
my
$domain
=
$
self
->
search_domain_by_id
(
$id_domain
);
$self
->
_refresh_active_domain
(
$domain
,
\
%active_domain
)
if
$domain
;
}
else
{
my
@domains
;
eval
{
@domains
=
$
vm
->
list_domains
};
eval
{
@domains
=
$
self
->
list_domains
};
warn
$@
if
$@
;
for
my
$domain
(
@domains
)
{
next
if
$active_domain
{
$domain
->
id
};
next
if
$domain
->
is_hibernated
;
$self
->
_refresh_active_domain
(
$vm
,
$domain
,
\
%active_domain
);
$self
->
_refresh_active_domain
(
$domain
,
\
%active_domain
);
$self
->
_remove_unnecessary_downs
(
$domain
)
if
!
$domain
->
is_active
;
}
}
}
return
\
%active_domain
,
\
%active_vm
;
return
\
%active_domain
;
}
sub
_refresh_down_nodes
($self, $request = undef ) {
...
...
@@ -3180,7 +3196,7 @@ sub _refresh_disabled_nodes($self, $request = undef ) {
$sth
->
finish
;
}
sub
_refresh_active_domain
($self,
$vm,
$domain, $active_domain) {
sub
_refresh_active_domain
($self, $domain, $active_domain) {
return
if
$domain
->
is_hibernated
();
my
$is_active
=
$domain
->
is_active
();
...
...
@@ -3188,9 +3204,6 @@ sub _refresh_active_domain($self, $vm, $domain, $active_domain) {
my
$status
=
'
shutdown
';
if
(
$is_active
)
{
$status
=
'
active
';
$domain
->
_data
(
id_vm
=>
$vm
->
id
)
if
!
defined
$domain
->
_data
('
id_vm
')
||
$domain
->
_data
('
id_vm
')
!=
$vm
->
id
;
}
$domain
->
_set_data
(
status
=>
$status
);
$domain
->
info
(
Ravada::Utils::
user_daemon
)
if
$is_active
;
...
...
@@ -3223,16 +3236,13 @@ sub _refresh_down_domains($self, $active_domain, $active_vm) {
}
}
sub
_remove_unnecessary_downs
($self, @domains) {
@domains
=
$self
->
list_domains
(
active
=>
0
)
if
!
scalar
@domains
;
sub
_remove_unnecessary_downs
($self, $domain) {
for
my
$domain
(
@domains
)
{
my
@requests
=
$domain
->
list_requests
(
1
);
for
my
$req
(
@requests
)
{
$req
->
status
('
done
')
if
$req
->
command
=~
/shutdown/
;
$req
->
_remove_messages
();
}
}
}
sub
_refresh_volatile_domains
($self) {
...
...
@@ -3294,6 +3304,9 @@ sub _cmd_set_base_vm {
sub
_cmd_cleanup
($self, $request) {
$self
->
_clean_volatile_machines
(
request
=>
$request
);
$self
->
_clean_requests
('
cleanup
',
$request
);
$self
->
_clean_requests
('
cleanup
',
$request
,'
done
');
$self
->
_clean_requests
('
enforce_limits
',
$request
,'
done
');
$self
->
_clean_requests
('
refresh_vms
',
$request
,'
done
');
$self
->
_wait_pids
();
}
...
...
@@ -3334,7 +3347,6 @@ sub _req_method {
,
rebase_volumes
=>
\
&_cmd_rebase_volumes
,
refresh_storage
=>
\
&_cmd_refresh_storage
,
refresh_machine
=>
\
&_cmd_refresh_machine
,
refresh_vms
=>
\
&_cmd_refresh_vms
,
domain_autostart
=>
\
&_cmd_domain_autostart
,
change_owner
=>
\
&_cmd_change_owner
,
add_hardware
=>
\
&_cmd_add_hardware
...
...
public/js/admin.js
View file @
243df982
...
...
@@ -99,6 +99,16 @@ ravadaApp.directive("solShowMachine", swMach)
$scope
.
seeswap
=
!
(
$scope
.
seeswap
);
};
$scope
.
get_machine_info
=
function
(
id
)
{
$http
.
get
(
'
/machine/info/
'
+
id
+
'
.json
'
)
.
then
(
function
(
response
)
{
$scope
.
machine
=
response
.
data
;
$scope
.
ramsize
=
(
$scope
.
machine
.
max_mem
/
1024
/
1024
);
if
(
$scope
.
ramsize
<
1
)
{
$scope
.
ramsize
=
1
;
}
});
};
$http
.
get
(
'
/list_machines.json
'
).
then
(
function
(
response
)
{
$scope
.
base
=
response
.
data
;
...
...
rvd_front.pl
View file @
243df982
...
...
@@ -255,6 +255,11 @@ any '/new_machine' => sub {
return
new_machine
(
$c
);
};
any
'
/copy_machine
'
=>
sub
{
my
$c
=
shift
;
return
new_machine_copy
(
$c
);
};
get
'
/domain/new.html
'
=>
sub
{
my
$c
=
shift
;
...
...
@@ -2095,6 +2100,24 @@ sub copy_machine {
return
$c
->
render
(
json
=>
{
request
=>
[
map
{
$_
->
id
}
@
reqs
]
}
);
}
sub
new_machine_copy
($c) {
my
$id_base
=
$c
->
param
('
src_machine
');
my
$copy_name
=
$c
->
param
('
copy_name
');
my
$ram
=
$c
->
param
('
copy_ram
');
$ram
=
0
if
!
$ram
||
$ram
!~
/^\d+(\.\d+)?$/
;
$ram
=
int
(
$ram
*
1024
*
1024
);
my
$req
=
Ravada::
Request
->
clone
(
uid
=>
$USER
->
id
,
id_domain
=>
$id_base
,
name
=>
$copy_name
,
memory
=>
$ram
);
return
$c
->
redirect_to
("
/admin/machines
");
}
sub
copy_machine_many
($base, $number, $create_args) {
my
$domains
=
$RAVADA
->
list_domains
;
my
%domain_exists
=
map
{
$_
->
{
name
}
=>
1
}
@$domains
;
...
...
templates/bootstrap/authors.html.ep
View file @
243df982
...
...
@@ -26,6 +26,7 @@
<li>Pascal Scholz</li>
<li>Raghav Mittal</li>
<li>Robert-André Mauchin</li>
<li>Roger Ferre</li>
<li>Sandra Marsà</li>
<li>Sanjiv Lobo</li>
<li>Shobhit Srivastava</li>
...
...
templates/ng-templates/new_machine_other.html.ep
View file @
243df982
<div class="tab-pane fade" id="frommachine" role="tabpanel">
<div class="card-body">
<form class="form" method="post" action="/machine/copy">
<form name="new_machine_other_form"
role="form" method="post" action="/copy_machine" novalidate>
<div class="form-group row">
<input class="form-control" type="hidden" name="id_base" value="{{src_machine.id}}">
<label for="src_machine" class="col-xl-3 col-form-label"><%=l 'Source Machine' %></label>
...
...
@@ -8,8 +9,9 @@
<select class="form-control"
name ="src_machine"
ng-model="src_machine"
ng-options="item.name for item in base track by item.id"
ng-options="item.name for item in base
| orderBy:'name'
track by item.id
"
required=""
ng-change="get_machine_info(src_machine.id)"
></select>
</div>
</div>
...
...
@@ -21,10 +23,13 @@
</div>
<div class="form-group row">
<div class="col-xl-2">
<label class="col-xl-12 text-muted" for="copy_name
_{{src_machine.id}}
"><%=l 'Name' %>:</label>
<label class="col-xl-12 text-muted" for="copy_name"><%=l 'Name' %>:</label>
</div>
<div class="col-xl-10">
<input class="form-control" name="copy_name_{{src_machine.id}}" type="text" size="40"
<input class="form-control" name="copy_name" type="text" size="40"
ng-model="name"
ng-pattern ="/^[a-zA-Z0-9_-]+$/"
ng-change="validate_new_name()"
value="{{src_machine.name}}-copy">
<!-- todo check unique name -->
</div>
...
...
@@ -34,8 +39,10 @@
<label class="col-xl-12 text-muted" for="copy_ram">RAM (Gb):</label>
</div>
<div class="col-xl-2">
<input class="form-control" ng-model="ramsize" type="number" name="copy_ram"
min="1" max="4" required="">
<input class="form-control" ng-model="ramsize" type="text"
ng-pattern ="/^[0-9]+\.?[0-9]*$/"
name="copy_ram"
required="">
</div>
</div>
<div class="form-group row alert alert-warning"
...
...
@@ -44,11 +51,24 @@
prepared before it can be copied. This
process may take some minutes.
</div>
<div ng-show="name_duplicated" class="form-group row alert alert-danger"
role="alert">
<strong><%=l 'Error' %> : </strong> <%=l 'A machine with that name already exists.' %>
</div>
<div ng-show="new_machine_other_form.copy_name.$error.pattern"
class="form-group row alert alert-danger" role="alert">
<strong><%=l 'Error' %> : </strong> <%=l 'The machine name must contain only alphabetic, numbers, undercores and dashes.' %>
</div>
<div class="form-group row">
<button type="reset" class="btn btn-outline-secondary mr-2" onclick = "location='/admin/machines'"><%=l 'Cancel' %></button>
<input type="submit" class="btn btn-primary" value="<%=l 'Submit' %>">
<input type="submit" class="btn btn-primary" value="<%=l 'Submit' %>"
ng-disabled="new_machine_other_form.$invalid || name_duplicated"
>
</div>
</div>
</form>
</div>
</div>
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