Skip to content

Commit

Permalink
Refactor test volatiles and Host Devices (#2064)
Browse files Browse the repository at this point in the history
* refactor: fixed volatile clones and check correct network
* test: host devices
* refactor: remove volatile just gone
  • Loading branch information
frankiejol committed Jul 3, 2024
1 parent d03129b commit 38adc35
Show file tree
Hide file tree
Showing 31 changed files with 933 additions and 228 deletions.
189 changes: 133 additions & 56 deletions lib/Ravada.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2696,7 +2696,7 @@ sub _sql_insert_defaults($self){
,{
id_parent => $id_backend
,name => 'time_zone'
,value => _default_time_zone()
,value => Ravada::Utils::default_time_zone()
}
,{
id_parent => $id_backend
Expand Down Expand Up @@ -2783,26 +2783,6 @@ sub _sql_insert_defaults($self){
}
}

sub _default_time_zone() {
return $ENV{TZ} if exists $ENV{TZ};
my $timedatectl = `which timedatectl`;
chomp $timedatectl;
if (!$timedatectl) {
warn "Warning: No time zone found, checked TZ, missing timedatectl";
return 'UTC';
}
my @cmd = ( $timedatectl, '-p', 'Timezone','show');
my ($in, $out, $err);
run3(\@cmd,\$in,\$out,\$err);
my ($tz) = $out =~ /=(.*)/;
chomp $out;
if (!$tz) {
warn "Warning: No timezone found in @cmd\n$out";
return 'UTC'
}
return $tz;
}

sub _sql_insert_values($self, $table, $entry) {
my $sql = "INSERT INTO $table "
."( "
Expand Down Expand Up @@ -3548,6 +3528,8 @@ sub remove_domain {
}

my $user = Ravada::Auth::SQL->search_by_id( $arg{uid});
die "Error: user id:$arg{uid} removed\n" if !$user;

die "Error: user ".$user->name." can't remove domain $id"
if !$user->can_remove_machine($id);

Expand Down Expand Up @@ -3987,6 +3969,7 @@ sub process_requests {

for my $req (sort { $a->priority <=> $b->priority } @reqs) {
next if $req eq 'refresh_vms' && scalar@reqs > 2;
next if $req eq 'refresh_vms' && $self->_processing_start();
next if !$req->id;
next if $req->status() =~ /^(done|working)$/;

Expand Down Expand Up @@ -4021,6 +4004,17 @@ sub process_requests {
return scalar(@reqs);
}

sub _processing_start($self) {
my $sth = $CONNECTOR->dbh->prepare(
"SELECT id FROM requests WHERE "
." ( command = 'start' OR command='refresh_vms' OR command='clone')"
." AND status = 'working'"
);
$sth->execute();
my ($id) = $sth->fetchrow;
return $id;
}

sub _date_now($seconds = 0) {
my @now = localtime(time + $seconds);
$now[4]++;
Expand Down Expand Up @@ -4260,6 +4254,21 @@ sub list_vm_types {
return keys %type;
}

sub _stop_refresh($self) {
my $sth = $CONNECTOR->dbh->prepare(
"SELECT id FROM requests where status='working' "
." AND ( command like ? ) "
);
$sth->execute('refresh%');
while ( my ($id) = $sth->fetchrow ) {
eval {
my $req = Ravada::Request->open($id);
$req->stop;
};

}
}

sub _execute {
my $self = shift;
my $request = shift;
Expand All @@ -4281,6 +4290,10 @@ sub _execute {
return;
}

if ($request->command eq 'clone' || $request->command eq 'start') {
$self->_stop_refresh();
}

$self->_wait_pids();
return if !$self->_can_fork($request);

Expand Down Expand Up @@ -4566,13 +4579,29 @@ sub _cmd_create{
}

sub _cmd_list_host_devices($self, $request) {
my $id_host_device = $request->args('id_host_device');
my $id_host_device = $request->defined_arg('id_host_device');

my $hd = Ravada::HostDevice->search_by_id(
$id_host_device
);
my @id_hd;

my %list= $hd->list_devices_nodes;
if ( $id_host_device ) {
@id_hd = ($id_host_device);
} else {
my $sth = $CONNECTOR->dbh->prepare(
"SELECT id,name FROM host_devices "
." WHERE enabled=1"
);
$sth->execute;
while ( my ($id_hd, $name) = $sth->fetchrow ) {
push @id_hd , ($id_hd );
}
}

for my $id_hd (@id_hd) {
my $hd = Ravada::HostDevice->search_by_id( $id_hd);
next if !$hd;
eval { $hd->list_devices_nodes };
warn $@ if $@;
}

}

Expand Down Expand Up @@ -4820,10 +4849,26 @@ sub _cmd_clone($self, $request) {

$args->{options}->{network} = $net_bundle->{name} if $net_bundle;

my $clone = $domain->clone(
name => $name
,%$args
);
my $clone = $self->search_domain($name);
die "Error: virtual machine ".$name." already exists "
if $clone && $clone->id_owner != $user->id;

if (!$clone) {
my $volatile = $domain->volatile_clones;
if (defined $args->{volatile}) {
$volatile = $args->{volatile};
}
for my $try ( 1 .. 3 ) {
eval {
$clone = $domain->clone( name => $name ,%$args);
};
my $err = $@;
warn $err if $err;
next if $err && $err =~ /No field in .*_data/i;
die $err if $err;
last if $clone;
}
}

$request->id_domain($clone->id) if $clone;
my $req_next = $request;
Expand All @@ -4833,7 +4878,7 @@ sub _cmd_clone($self, $request) {
,id_domain => $clone->id
,remote_ip => $request->defined_arg('remote_ip')
,after_request => $req_next->id
) if $request->defined_arg('start');
) if $clone && $request->defined_arg('start');

}

Expand Down Expand Up @@ -4966,7 +5011,12 @@ sub _cmd_start {
my $domain;
$domain = $self->search_domain($name) if $name;
$domain = Ravada::Domain->open($id_domain) if $id_domain;
die "Unknown domain '".($name or $id_domain)."'" if !$domain;

if(!$domain) {
$self->_remove_inactive_gone($id_domain);
die "Unknown machine '".($name or $id_domain)."'\n";
}

$domain->status('starting');

my $uid = $request->args('uid');
Expand Down Expand Up @@ -5081,7 +5131,7 @@ sub _cmd_shutdown_clones {
my $is_active;
eval {
$domain2 = $self->search_domain_by_id($id);
$is_active = $domain2->is_active;
$is_active = $domain2->is_active if $domain2;
};
warn $@ if $@;
if ($is_active) {
Expand Down Expand Up @@ -5638,18 +5688,43 @@ sub _cmd_check_storage($self, $request) {
}
}

sub _remove_inactive_gone($self,$id_domain) {
my $sth = $CONNECTOR->dbh->prepare(
"SELECT name,is_volatile "
." FROM domains "
." WHERE id=?"
);
$sth->execute($id_domain);
my ($name,$is_volatile) = $sth->fetchrow;
if ($is_volatile) {
my $req = Ravada::Request->remove_domain(
name => $name
,uid => Ravada::Utils::user_daemon->id
);
$self->_cmd_remove($req);
}
}

sub _cmd_refresh_machine($self, $request) {

my $id_domain = $request->args('id_domain');
my $user = Ravada::Auth::SQL->search_by_id($request->args('uid'));

# it may have been removed on shutdown when volatile
my $domain = Ravada::Domain->open($id_domain) or return;
my $domain = Ravada::Domain->open($id_domain);

return $self->_remove_inactive_gone($id_domain) if !$domain;

$domain->check_status();
$domain->list_volumes_info();
my $is_active = $domain->is_active;
$self->_remove_unnecessary_downs($domain) if !$is_active;
if (!$is_active) {
$self->_remove_unnecessary_downs($domain);
if ( $domain->is_volatile && !$domain->_volatile_active ) {
$domain->remove(Ravada::Utils::user_daemon);
return;
}
}
$domain->info($user);
$domain->client_status(1) if $is_active;
$domain->_check_port_conflicts();
Expand All @@ -5658,7 +5733,7 @@ sub _cmd_refresh_machine($self, $request) {
,timeout => 60, retry => 10)
if $is_active && $domain->ip && $domain->list_ports;

$domain->_dettach_host_devices() if !$is_active;
$domain->_unlock_host_devices() if !$is_active;
}

sub _cmd_refresh_machine_ports($self, $request) {
Expand Down Expand Up @@ -5959,7 +6034,7 @@ sub _cmd_migrate($self, $request) {
if $request->defined_arg('remote_ip');

$domain->start(user => $user, @remote_ip)
if $request->defined_arg('start');
if $request->defined_arg('start') && $domain->_vm->id == $node->id;

}

Expand All @@ -5968,7 +6043,7 @@ sub _cmd_rsync_back($self, $request) {
my $id_domain = $request->args('id_domain') or die "ERROR: Missing id_domain";

my $domain = Ravada::Domain->open($id_domain);
return if $domain->is_active;
return if $domain->is_active || $domain->is_volatile;

my $user = Ravada::Auth::SQL->search_by_id($uid);
die "Error: user ".$user->name." not allowed to migrate domain ".$domain->name
Expand Down Expand Up @@ -6034,7 +6109,8 @@ sub _refresh_active_domains($self, $request=undef) {
next if $@ =~ /not found/;
warn $@;
}
$self->_refresh_active_domain($domain, \%active_domain) if $domain;
$self->_refresh_active_domain($domain, \%active_domain)
if $domain && !$domain->is_locked;
} else {
my @domains;
eval { @domains = $self->list_domains_data };
Expand All @@ -6050,7 +6126,9 @@ sub _refresh_active_domains($self, $request=undef) {
next if $@ =~ /not found/;
warn $@;
}
next if !$domain;
next if !$domain || $domain->is_locked;
next if $domain->_volatile_active();

$self->_refresh_active_domain($domain, \%active_domain);
$self->_remove_unnecessary_downs($domain) if !$domain->is_active;
last if !$CAN_FORK && time - $t0 > 10;
Expand Down Expand Up @@ -6223,7 +6301,8 @@ sub _refresh_active_domain($self, $domain, $active_domain) {
$domain->client_status(1);

$domain->_post_shutdown()
if $domain->_data('status') eq 'shutdown' && !$domain->_data('post_shutdown');
if $domain->_data('status') eq 'shutdown' && !$domain->_data('post_shutdown')
&& !$domain->_volatile_active;
}

sub _refresh_hibernated($self, $domain) {
Expand Down Expand Up @@ -6285,16 +6364,20 @@ sub _remove_unnecessary_downs($self, $domain) {

sub _refresh_volatile_domains($self) {
my $sth = $CONNECTOR->dbh->prepare(
"SELECT id, name, id_vm, id_owner, vm FROM domains WHERE is_volatile=1"
"SELECT id, name, id_vm, id_owner, vm FROM domains WHERE is_volatile=1 "
." AND date_changed < ? "
);
$sth->execute();
$sth->execute(Ravada::Utils::date_now(-120));
while ( my ($id_domain, $name, $id_vm, $id_owner, $type) = $sth->fetchrow ) {
my $domain;
eval { $domain = Ravada::Domain->open(id => $id_domain, _force => 1) } ;
next if $domain && $domain->is_locked;
if ( !$domain || $domain->status eq 'down' || !$domain->is_active) {
if ($domain) {
$domain->_post_shutdown(user => $USER_DAEMON);
$domain->remove($USER_DAEMON);
if ($domain && !$domain->is_locked ) {
Ravada::Request->shutdown_domain(
uid => $USER_DAEMON->id
,id_domain => $id_domain
);
} else {
my $user;
eval { $user = Ravada::Auth::SQL->search_by_id($id_owner) };
Expand All @@ -6304,14 +6387,6 @@ sub _refresh_volatile_domains($self) {
$user->remove();
}
}
my $sth_del = $CONNECTOR->dbh->prepare("DELETE FROM domains WHERE id=?");
$sth_del->execute($id_domain);
$sth_del->finish;

$sth_del = $CONNECTOR->dbh->prepare("DELETE FROM requests where id_domain=?");
$sth_del->execute($id_domain);
$sth_del->finish;
Ravada::Domain::_remove_domain_data_db($id_domain, $type);
}
}
}
Expand Down Expand Up @@ -6395,7 +6470,7 @@ sub _domain_just_started($self, $domain) {
my $start_time = time - 300;
$sth->execute($start_time);
while ( my ($id, $command, $args) = $sth->fetchrow ) {
next if $command !~ /create|clone|start|open/i;
next if $command !~ /create|clone|start|open|shutdown/i;
my $args_h = decode_json($args);
return 1 if exists $args_h->{id_domain} && defined $args_h->{id_domain}
&& $args_h->{id_domain} == $domain->id;
Expand Down Expand Up @@ -6782,6 +6857,8 @@ sub _clean_volatile_machines($self, %args) {
);
if ($domain_real) {
next if $domain_real->domain && $domain_real->is_active;
next if $domain_real->is_locked;
next if $domain_real->_volatile_active;
eval { $domain_real->_post_shutdown() };
warn $@ if $@;
eval { $domain_real->remove($USER_DAEMON) };
Expand All @@ -6790,7 +6867,7 @@ sub _clean_volatile_machines($self, %args) {
my $user;
eval { $user = Ravada::Auth::SQL->search_by_id($domain->{id_owner})};
warn $@ if $@;
$user->remove() if $user;
$user->remove() if $user && $user->is_temporary;
}

$sth_remove->execute($domain->{id});
Expand Down
Loading

0 comments on commit 38adc35

Please sign in to comment.