Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Projets publics
Ravada-Mirror
Commits
d1b9b469
Unverified
Commit
d1b9b469
authored
Apr 08, 2020
by
Francesc Guasch
Committed by
GitHub
Apr 08, 2020
Browse files
Feature shutdown disconnected (#1291)
* feature(backend): auto shutdown disconnected issue #1280
parent
2462096c
Changes
5
Hide whitespace changes
Inline
Side-by-side
lib/Ravada.pm
View file @
d1b9b469
...
...
@@ -1169,11 +1169,31 @@ sub _upgrade_table {
return
if
$row
;
my
$sqlite_trigger
;
if
(
$dbh
->
{
Driver
}{
Name
}
=~
/sqlite/i
)
{
$definition
=~
s/DEFAULT.*ON UPDATE(.*)//i
;
$sqlite_trigger
=
$
1
;
}
warn
"
INFO: adding
$field
$definition
to
$table
\n
"
if
$
0
!~
/\.t$/
;
$dbh
->
do
("
alter table
$table
add
$field
$definition
");
$self
->
_sqlite_trigger
(
$dbh
,
$table
,
$field
,
$sqlite_trigger
)
if
$sqlite_trigger
;
return
1
;
}
sub
_sqlite_trigger
($self, $dbh, $table,$field, $trigger) {
my
$sql
=
"
CREATE TRIGGER Update
$field
AFTER UPDATE
ON
$table
FOR EACH ROW
WHEN NEW.
$field
< OLD.
$field
BEGIN
UPDATE
$table
SET
$field
=
$trigger
WHERE id=OLD.id;
END;
";
$dbh
->
do
(
$sql
);
}
sub
_remove_field
{
my
$self
=
shift
;
my
(
$table
,
$field
)
=
@_
;
...
...
@@ -1335,6 +1355,8 @@ sub _upgrade_tables {
$self
->
_upgrade_table
('
domains
','
is_pool
','
int NOT NULL default 0
');
$self
->
_upgrade_table
('
domains
','
needs_restart
','
int not null default 0
');
$self
->
_upgrade_table
('
domains
','
shutdown_disconnected
','
int not null default 0
');
$self
->
_upgrade_table
('
domains
','
date_changed
','
timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
');
if
(
$self
->
_upgrade_table
('
domains
','
screenshot
','
MEDIUMBLOB
'))
{
...
...
@@ -2858,7 +2880,7 @@ sub _cmd_clone($self, $request) {
sub
_req_clone_many
($self, $request) {
my
$args
=
$request
->
args
();
my
$id_domain
=
$args
->
{
id_domain
};
my
$base
=
Ravada::
Domain
->
open
(
$id_domain
);
my
$base
=
Ravada::
Domain
->
open
(
$id_domain
)
or
die
"
Error: Domain '
$id_domain
' not found
"
;
my
$number
=
(
delete
$args
->
{
number
}
or
1
);
my
$domains
=
$self
->
list_domains_data
();
my
%domain_exists
=
map
{
$_
->
{
name
}
=>
1
}
@$domains
;
...
...
@@ -3617,6 +3639,27 @@ sub _cmd_cleanup($self, $request) {
}
}
sub
_shutdown_disconnected
($self) {
for
my
$dom
(
$self
->
list_domains_data
(
status
=>
'
active
')
)
{
warn
$dom
->
{
name
}
.
"
"
.
$dom
->
{
shutdown_disconnected
}
.
"
"
.
$dom
->
{
client_status
};
next
if
!
$dom
->
{
shutdown_disconnected
};
my
$domain
=
Ravada::
Domain
->
open
(
$dom
->
{
id
});
my
$is_active
=
$domain
->
is_active
;
my
(
$req_shutdown
)
=
grep
{
$_
->
command
eq
'
shutdown
'
}
$domain
->
list_requests
(
1
);
if
(
$is_active
&&
$domain
->
client_status
eq
'
disconnected
')
{
next
if
$req_shutdown
;
Ravada::
Request
->
shutdown_domain
(
uid
=>
Ravada::Utils::
user_daemon
->
id
,
id_domain
=>
$domain
->
id
,
at
=>
time
+
120
);
}
else
{
$req_shutdown
->
status
('
done
','
Canceled
')
if
$req_shutdown
;
}
}
}
sub
_req_method
{
my
$self
=
shift
;
my
$cmd
=
shift
;
...
...
@@ -3805,6 +3848,7 @@ sub import_domain {
sub
_cmd_enforce_limits
($self, $request=undef) {
_enforce_limits_active
(
$self
,
$request
);
$self
->
_shutdown_disconnected
();
}
sub
_enforce_limits_active
($self, $request) {
...
...
lib/Ravada/Domain.pm
View file @
d1b9b469
...
...
@@ -33,7 +33,7 @@ our $CONNECTOR;
our
$MIN_FREE_MEMORY
=
1024
*
1024
;
our
$IPTABLES_CHAIN
=
'
RAVADA
';
our
%PROPAGATE_FIELD
=
map
{
$_
=>
1
}
qw( run_timeout )
;
our
%PROPAGATE_FIELD
=
map
{
$_
=>
1
}
qw( run_timeout
shutdown_disconnected
)
;
our
$TIME_CACHE_NETSTAT
=
60
;
# seconds to cache netstat data output
our
$RETRY_SET_TIME
=
10
;
...
...
@@ -310,10 +310,12 @@ sub _around_start($orig, $self, @arg) {
for
(;;)
{
eval
{
$self
->
_start_checks
(
@arg
)
};
if
(
$@
&&
$@
=~
/base file not found/
&&
!
$self
->
_vm
->
is_local
)
{
my
$error
=
$@
;
if
(
$error
&&
$error
=~
/base file not found/
&&
!
$self
->
_vm
->
is_local
)
{
$self
->
_request_set_base
();
next
;
}
die
$error
if
$error
;
if
(
!
defined
$listen_ip
)
{
my
$display_ip
;
if
(
$remote_ip
)
{
...
...
@@ -328,7 +330,7 @@ sub _around_start($orig, $self, @arg) {
$arg
{
listen_ip
}
=
$display_ip
;
}
eval
{
$self
->
$orig
(
%arg
)
};
my
$error
=
$@
;
$error
=
$@
;
last
if
!
$error
;
warn
"
WARNING:
$error
"
.
$self
->
_vm
->
name
.
"
"
.
$self
->
_vm
->
enabled
if
$error
;
if
(
$error
&&
$self
->
id_base
&&
!
$self
->
is_local
&&
$self
->
_vm
->
enabled
)
{
...
...
@@ -401,15 +403,15 @@ sub _start_checks($self, @args) {
if
(
$id_vm
)
{
$vm
=
Ravada::
VM
->
open
(
$id_vm
);
if
(
!
$vm
->
is_
enabled
||
!
$vm
->
ping
)
{
if
(
!
$vm
->
enabled
||
!
$vm
->
ping
)
{
$vm
=
$vm_local
;
$id_vm
=
undef
;
}
}
$self
->
_check_tmp_volumes
();
# if it is a clone ( it is not a base )
if
(
$self
->
id_base
)
{
$self
->
_check_tmp_volumes
();
# $self->_set_last_vm(1)
if
(
!
$self
->
is_local
&&
(
!
$self
->
_vm
->
enabled
||
!
base_in_vm
(
$self
->
id_base
,
$self
->
_vm
->
id
)
...
...
@@ -1516,13 +1518,13 @@ sub info($self, $user) {
,
pool_start
=>
$self
->
pool_start
,
pool_clones
=>
$self
->
pool_clones
,
is_pool
=>
$self
->
is_pool
,
comment
=>
$self
->
_data
('
comment
')
,
screenshot
=>
$self
->
_data
('
screenshot
')
,
run_timeout
=>
$self
->
run_timeout
,
autostart
=>
$self
->
autostart
,
volatile_clones
=>
$self
->
volatile_clones
,
id_owner
=>
$self
->
_data
('
id_owner
')
};
for
(
qw(comment screenshot id_owner shutdown_disconnected)
)
{
$info
->
{
$_
}
=
$self
->
_data
(
$_
);
}
if
(
$is_active
)
{
eval
{
$info
->
{
display_url
}
=
$self
->
display
(
$user
);
...
...
lib/Ravada/VM.pm
View file @
d1b9b469
...
...
@@ -431,7 +431,7 @@ sub _around_create_domain {
if
(
$id_base
)
{
$domain
->
run_timeout
(
$base
->
run_timeout
)
if
defined
$base
->
run_timeout
();
$domain
->
_data
(
shutdown_disconnected
=>
$base
->
_data
('
shutdown_disconnected
'));
for
my
$port
(
$base
->
list_ports
)
{
my
%port
=
%$port
;
delete
@port
{'
id
','
id_domain
','
public_port
'};
...
...
t/nodes/10_basic.t
View file @
d1b9b469
...
...
@@ -342,7 +342,7 @@ sub test_removed_base_file($vm, $node) {
is
(
$base
->
base_in_vm
(
$node
->
id
),
1
);
is
(
scalar
(
$base
->
list_vms
),
2
)
or
exit
;
my
$node2
=
Ravada::
VM
->
open
(
$node
->
id
);
is
(
$node2
->
is_
enabled
,
1
);
is
(
$node2
->
enabled
,
1
);
for
my
$clone_data
(
$base
->
clones
)
{
my
$clone
=
Ravada::
Domain
->
open
(
$clone_data
->
{
id
});
$clone
->
remove
(
user_admin
);
...
...
@@ -406,7 +406,7 @@ sub test_removed_base_file_and_swap_remote($vm, $node) {
wait_request
(
debug
=>
0
);
is
(
$base
->
base_in_vm
(
$node
->
id
),
1
);
my
$node2
=
Ravada::
VM
->
open
(
$node
->
id
);
is
(
$node2
->
is_
enabled
,
1
);
is
(
$node2
->
enabled
,
1
);
for
my
$clone_data
(
$base
->
clones
)
{
my
$clone
=
Ravada::
Domain
->
open
(
$clone_data
->
{
id
});
$clone
->
remove
(
user_admin
);
...
...
t/vm/10_domain.t
View file @
d1b9b469
...
...
@@ -6,6 +6,9 @@ use Hash::Util qw(lock_hash);
use
JSON::
XS
;
use
Test::
More
;
no
warnings
"
experimental::signatures
";
use
feature
qw(signatures)
;
use
lib
'
t/lib
';
use
Test::
Ravada
;
...
...
@@ -245,6 +248,45 @@ sub test_shutdown {
$domain
->
remove
(
user_admin
);
}
sub
test_auto_shutdown_disconnected
($vm) {
my
$base
=
create_domain
(
$vm
);
$base
->
_data
('
shutdown_disconnected
',
1
);
my
$domainb
=
Ravada::
Domain
->
open
(
$base
->
id
);
is
(
$domainb
->
_data
('
shutdown_disconnected
'),
1
);
my
$clone
=
$base
->
clone
(
name
=>
new_domain_name
,
user
=>
user_admin
);
is
(
$clone
->
_data
('
shutdown_disconnected
'),
1
);
$clone
->
start
(
user
=>
user_admin
,
remote_ip
=>
'
1.2.3.4
');
for
(
1
..
60
)
{
last
if
$clone
->
client_status
(
1
)
eq
'
disconnected
';
sleep
1
;
diag
("
waiting for
"
.
$clone
->
name
.
"
to disconnect
"
.
$clone
->
client_status
);
}
is
(
$clone
->
client_status
,
'
disconnected
');
my
$req
=
Ravada::
Request
->
enforce_limits
(
_force
=>
1
);
rvd_back
->
_process_requests_dont_fork
(
undef
,
1
);
is
(
$req
->
status
,'
done
');
is
(
$req
->
error
,
'');
my
(
$req_shutdown
)
=
grep
{
$_
->
command
eq
'
shutdown
'
}
$clone
->
list_requests
(
1
);
ok
(
$req_shutdown
)
or
return
;
is
(
$req_shutdown
->
status
,'
requested
');
$clone
->
start
(
user
=>
user_admin
,
remote_ip
=>
'
1.2.3.4
');
$req
=
Ravada::
Request
->
cleanup
();
rvd_back
->
_process_requests_dont_fork
(
undef
,
1
);
is
(
$req
->
status
,'
done
');
is
(
$req
->
error
,
'');
like
(
$req_shutdown
->
status
,
qr(done|requested)
);
$clone
->
remove
(
user_admin
);
$base
->
remove
(
user_admin
);
}
sub
test_shutdown_paused_domain
{
my
$vm_name
=
shift
;
my
$domain
=
shift
;
...
...
@@ -557,6 +599,7 @@ for my $vm_name ( vm_names() ) {
test_vm_in_db
(
$vm_name
,
$conf
)
if
$conf
;
test_shutdown
(
$vm
);
test_auto_shutdown_disconnected
(
$vm
);
test_vm_connect
(
$vm_name
,
$host
,
$conf
);
test_search_vm
(
$vm_name
,
$host
,
$conf
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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