diff --git a/lib/Ravada.pm b/lib/Ravada.pm index 3a3fd505e..897f6c9c6 100644 --- a/lib/Ravada.pm +++ b/lib/Ravada.pm @@ -2711,7 +2711,7 @@ sub _sql_insert_defaults($self){ ,{ id_parent => $id_backend ,name => 'delay_migrate_back' - ,value => 600 + ,value => 60 * 60 * 24 } ,{ id_parent => $id_backend @@ -2978,6 +2978,7 @@ sub _upgrade_tables { $self->_upgrade_table('bases_vm','id_vm','int not null references `vms` (`id`) ON DELETE CASCADE'); $self->_upgrade_table('bases_vm','id_domain','int not null references `domains` (`id`) ON DELETE CASCADE'); + $self->_upgrade_table('bases_vm','id_request','integer'); $self->_upgrade_table('domain_instances','id_vm','int not null references `vms` (`id`) ON DELETE CASCADE'); @@ -5752,8 +5753,8 @@ sub _cmd_connect_node($self, $request) { my $node; if ($id_node) { - $node = Ravada::VM->open($id_node); - $hostname = $node->host; + $node = Ravada::VM->open(id => $id_node, force => 1); + $hostname = $node->host if $node; } else { $node = Ravada::VM->open( type => $backend , host => $hostname @@ -5762,7 +5763,7 @@ sub _cmd_connect_node($self, $request) { } die "I can't ping $hostname\n" - if ! $node->ping(); + if !$node || ! $node->ping(); $request->error("Ping ok. Trying to connect to $hostname"); my ($out, $err); @@ -5778,7 +5779,10 @@ sub _cmd_connect_node($self, $request) { $err .= "\n"; die $err if $err; } - $node->connect() && $request->error("Connection OK"); + $node->connect() && do { + $request->error("Connection OK"); + $node->_data('cached_down' => 0); + }; } sub _cmd_list_network_interfaces($self, $request) { @@ -6003,7 +6007,7 @@ sub _refresh_active_vms ($self) { my %active_vm; for my $vm ($self->list_vms) { next if !$vm; - if ( !$vm->enabled() || !$vm->is_active ) { + if ( !$vm->vm || !$vm->enabled() || !$vm->is_active ) { $vm->shutdown_domains(); $active_vm{$vm->id} = 0; $vm->disconnect(); @@ -6038,7 +6042,7 @@ sub _refresh_active_domains($self, $request=undef) { my $t0 = time; for my $domain_data (sort { $b->{date_changed} cmp $a->{date_changed} } @domains) { - $request->error("checking $domain_data->{name}") if $request; + $request->output("checking $domain_data->{name}") if $request; next if $active_domain{$domain_data->{id}}; my $domain; eval { $domain = Ravada::Domain->open($domain_data->{id}) }; @@ -6202,6 +6206,7 @@ sub _refresh_disabled_nodes($self, $request = undef ) { } sub _refresh_active_domain($self, $domain, $active_domain) { + return if $domain->is_locked(); $domain->check_status(); return $self->_refresh_hibernated($domain) if $domain->is_hibernated(); @@ -6326,6 +6331,18 @@ sub _cmd_set_base_vm { my $id_vm = $request->args('id_vm') or die "ERROR: Missing id_vm"; my $id_domain = $request->args('id_domain') or die "ERROR: Missing id_domain"; + eval { + $self->_do_cmd_set_base_vm($uid, $id_vm, $id_domain, $value, $request); + }; + my $err = $@; + if ($err) { + my $domain = Ravada::Front::Domain->open($id_domain); + $domain->_set_base_vm_db($id_vm, (!$value or 0), 0); + die $err; + } +} + +sub _do_cmd_set_base_vm($self, $uid, $id_vm, $id_domain, $value, $request) { my $user = Ravada::Auth::SQL->search_by_id($uid); my $domain = Ravada::Domain->open($id_domain) or confess "Error: Unknown domain id $id_domain"; diff --git a/lib/Ravada/Domain.pm b/lib/Ravada/Domain.pm index 47a5fd9ce..01d63bedb 100644 --- a/lib/Ravada/Domain.pm +++ b/lib/Ravada/Domain.pm @@ -367,12 +367,14 @@ sub _around_start($orig, $self, @arg) { $error = $@; last if !$error; - die "Error: starting ".$self->name." on ".$self->_vm->name." $error" + my $vm_name = Ravada::VM::_get_name_by_id($self->_data('id_vm')); + + die "Error: starting ".$self->name." on ".$vm_name." $error" if $error =~ /there is no device|Did not find .*device/; die $error if $error =~ /No DRM render nodes/; - warn "WARNING: $error ".$self->_vm->name." ".$self->_vm->enabled if $error; + warn "WARNING: $error ".$vm_name if $error; ;# pool has asynchronous jobs running. next if $error && ref($error) && $error->code == 1 @@ -479,6 +481,8 @@ sub _start_checks($self, @args) { $request = delete $args{request} if exists $args{request}; $enable_host_devices = delete $args{enable_host_devices}; } + my $id_prev = $self->_data('id_vm'); + # If not specific id_manager we go to the last id_vmanager unless it was localhost # If the last VManager was localhost it will try to balance here. $id_vm = $self->_data('id_vm') @@ -531,7 +535,8 @@ sub _start_checks($self, @args) { ,'set_base_vm', encode_json($args)); } - $self->rsync(request => $request); + $self->rsync(request => $request) + unless defined $id_prev && $self->_vm->id == $id_prev; } } $self->_check_free_vm_memory(); @@ -5210,27 +5215,26 @@ sub _id_base_in_vm($self, $id_vm) { return $sth->fetchrow; } -sub _set_base_vm_db($self, $id_vm, $value) { +sub _set_base_vm_db($self, $id_vm, $value, $id_request=undef) { my $is_base; $is_base = $self->base_in_vm($id_vm) if $self->is_base; - return if defined $is_base && $value == $is_base; - my $id_is_base = $self->_id_base_in_vm($id_vm); if (!defined $id_is_base) { return if !$value && !$self->is_known; my $sth = $$CONNECTOR->dbh->prepare( - "INSERT INTO bases_vm (id_domain, id_vm, enabled) " - ." VALUES(?, ?, ?)" + "INSERT INTO bases_vm (id_domain, id_vm, enabled, id_request) " + ." VALUES(?, ?, ?, ?)" ); - $sth->execute($self->id, $id_vm, $value); + $sth->execute($self->id, $id_vm, $value, $id_request); $sth->finish; } else { my $sth = $$CONNECTOR->dbh->prepare( - "UPDATE bases_vm SET enabled=?" + "UPDATE bases_vm SET enabled=?, id_request=?" ." WHERE id_domain=? AND id_vm=?" ); - $sth->execute($value, $self->id, $id_vm); + $value = 0 if !defined $value; + $sth->execute($value, $id_request, $self->id, $id_vm); $sth->finish; } } @@ -5271,13 +5275,23 @@ sub set_base_vm($self, %args) { $vm = $node if $node; $vm = Ravada::VM->open($id_vm) if !$vm; + if ( !$vm || !$vm->is_active || !$vm->vm) { + die "Error: VM ".Ravada::VM::_search_name($id_vm)." not available\n" + } + $value = 1 if !defined $value; + my $id_request; + if ($request) { + $request->status("working"); + $id_request = $request->id; + } + $self->_set_base_vm_db($vm->id, $value, $id_request); + if ($vm->is_local) { $self->_set_vm($vm,1); # force set vm on domain if (!$value) { $request->status("working","Removing base") if $request; - $self->_set_base_vm_db($vm->id, $value); $self->remove_base($user); } else { $self->prepare_base($user) if !$self->is_base(); @@ -5406,17 +5420,27 @@ Returns a list for virtual machine managers where this domain is base =cut -sub list_vms($self, $check_host_devices=0) { +sub list_vms($self, $check_host_devices=0, $only_available=0) { confess "Domain is not base" if !$self->is_base; - my $sth = $$CONNECTOR->dbh->prepare("SELECT id_vm FROM bases_vm WHERE id_domain=? AND enabled = 1"); + my $sth = $$CONNECTOR->dbh->prepare("SELECT id_vm, id_request " + ." FROM bases_vm WHERE id_domain=? AND enabled = 1"); $sth->execute($self->id); + my $sth_req = $$CONNECTOR->dbh->prepare( + "SELECT status FROM requests " + ." WHERE id=? " + ); my @vms; - while (my $id_vm = $sth->fetchrow) { + while (my ($id_vm, $id_request) = $sth->fetchrow) { + if ($id_request && $only_available) { + $sth_req->execute($id_request); + my ($status) =$sth_req->fetchrow; + next if $status && $status ne 'done'; + } my $vm; eval { $vm = Ravada::VM->open($id_vm) }; warn "id_domain: ".$self->id."\n".$@ if $@; - push @vms,($vm) if $vm && !$vm->is_locked(); + push @vms,($vm) if $vm; } my $vm_local = $self->_vm->new( host => 'localhost' ); if ( !grep { $_->name eq $vm_local->name } @vms) { diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index 30002b6ef..212217a47 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1101,6 +1101,7 @@ sub list_requests($self, $id_domain_req=undef, $seconds=60) { "SELECT requests.id, command, args, requests.date_changed, requests.status" ." ,requests.error, id_domain ,domains.name as domain" ." ,domains.alias as domain_alias" + ." ,requests.output " ." FROM requests left join domains " ." ON requests.id_domain = domains.id" ." WHERE " @@ -1111,9 +1112,9 @@ sub list_requests($self, $id_domain_req=undef, $seconds=60) { $sth->execute($time_recent); my @reqs; my ($id_request, $command, $j_args, $date_changed, $status - , $error, $id_domain, $domain, $alias); + , $error, $id_domain, $domain, $alias, $output); $sth->bind_columns(\($id_request, $command, $j_args, $date_changed, $status - , $error, $id_domain, $domain, $alias)); + , $error, $id_domain, $domain, $alias, $output)); while ( $sth->fetch) { my $epoch_date_changed = time; @@ -1137,6 +1138,8 @@ sub list_requests($self, $id_domain_req=undef, $seconds=60) { || $command eq 'list_network_interfaces' || $command eq 'list_isos' || $command eq 'manage_pools' + || $command eq 'list_storage_pools' + || $command eq 'list_cpu_models' ; next if ( $command eq 'force_shutdown' || $command eq 'force_reboot' @@ -1166,6 +1169,7 @@ sub list_requests($self, $id_domain_req=undef, $seconds=60) { ,date => $date_changed ,message => Encode::decode_utf8($message) ,error => Encode::decode_utf8($error) + ,output => Encode::decode_utf8($output) }; } $sth->finish; diff --git a/lib/Ravada/HostDevice.pm b/lib/Ravada/HostDevice.pm index 45803ef2d..f32262652 100644 --- a/lib/Ravada/HostDevice.pm +++ b/lib/Ravada/HostDevice.pm @@ -147,13 +147,27 @@ sub is_device($self, $device, $id_vm) { } sub _device_locked($self, $name, $id_vm=$self->id_vm) { - my $sth = $$CONNECTOR->dbh->prepare("SELECT id FROM host_devices_domain_locked " + my $sth = $$CONNECTOR->dbh->prepare( + "SELECT id,id_domain " + ." FROM host_devices_domain_locked " ." WHERE id_vm=? AND name=? " ); $sth->execute($id_vm, $name); - my ($is_locked) = $sth->fetchrow; - $is_locked = 0 if !defined $is_locked; - return $is_locked; + my $sth_status = $$CONNECTOR->dbh->prepare( + "SELECT status FROM domains WHERE id=?" + ); + + my $sth_unlock = $$CONNECTOR->dbh->prepare( + "DELETE FROM host_devices_domain_locked " + ." WHERE id=?" + ); + while ( my ($id_lock, $id_domain)= $sth->fetchrow ) { + $sth_status->execute($id_domain); + my ($status) = $sth_status->fetchrow; + return $id_domain if $status && $status ne 'down'; + $sth_unlock->execute($id_lock); + } + return 0; } sub list_available_devices($self, $id_vm=$self->id_vm) { diff --git a/lib/Ravada/Request.pm b/lib/Ravada/Request.pm index 8da82430f..dcb6e5765 100644 --- a/lib/Ravada/Request.pm +++ b/lib/Ravada/Request.pm @@ -1428,11 +1428,19 @@ sub set_base_vm { my $self = {}; bless ($self, $class); - return $self->_new_request( + my $req = $self->_new_request( command => 'set_base_vm' , args => $args ); + my $id_domain = $args->{id_domain}; + my $domain = Ravada::Front::Domain->open($id_domain); + my $id_vm = $args->{id_vm}; + $id_vm = $args->{id_node} if exists $args->{id_node} && $args->{id_node}; + + $domain->_set_base_vm_db($id_vm, $args->{value}, $req->id); + + return $req; } =head2 remove_base_vm diff --git a/lib/Ravada/VM.pm b/lib/Ravada/VM.pm index c057ede04..776e9f37f 100644 --- a/lib/Ravada/VM.pm +++ b/lib/Ravada/VM.pm @@ -46,7 +46,7 @@ our $MIN_DISK_MB = 1024 * 1024; our $CACHE_TIMEOUT = 60; our $FIELD_TIMEOUT = '_data_timeout'; -our $TIMEOUT_DOWN_CACHE = 120; +our $TIMEOUT_DOWN_CACHE = 300; our %VM; # cache Virtual Manager Connection our %SSH; @@ -207,12 +207,19 @@ sub open { } else { $args{id} = shift; } + my $force = delete $args{force}; + confess "Error: undefind id in ".Dumper(\%args) if !$args{id}; my $class=ref($proto) || $proto; my $self = {}; bless($self, $class); + + if ($force) { + _set_by_id($args{id}, 'cached_down' => 0 ); + } + my $row = $self->_do_select_vm_db( id => $args{id}); lock_hash(%$row); confess "ERROR: I can't find VM id=$args{id}" if !$row || !keys %$row; @@ -242,7 +249,7 @@ sub open { $internal_vm = $vm->vm; }; $VM{$args{id}} = $vm unless $args{readonly} || !$internal_vm; - return if $self->is_local && !$internal_vm; + return if $vm->is_local && !$internal_vm; return $vm; } @@ -256,6 +263,14 @@ sub _search_id($name) { return $id; } +sub _search_name($id) { + my $sth = $$CONNECTOR->dbh->prepare( + "SELECT name FROM vms WHERE id=?" + ); + $sth->execute($id); + my ($name) = $sth->fetchrow; + return $name; +} sub _refresh_version($self) { my $version = $self->get_library_version(); return if defined $self->_data('version') @@ -389,12 +404,12 @@ sub _pre_create_domain { sub _pre_search_domain($self,@) { $self->_connect(); - die "ERROR: VM ".$self->name." unavailable" if !$self->ping(); + die "ERROR: VM ".$self->name." unavailable\n" if !$self->ping(); } sub _pre_list_domains($self,@) { $self->_connect(); - die "ERROR: VM ".$self->name." unavailable" if !$self->ping(); + die "ERROR: VM ".$self->name." unavailable\n" if !$self->ping(); } sub _connect_ssh($self) { @@ -411,6 +426,11 @@ sub _connect_ssh($self) { if (!$ssh || !$ssh->check_master) { delete $SSH{$self->host}; + if ($self->_data('cached_down') + && time-$self->_data('cached_down')< $self->timeout_down_cache()) { + return; + } + for ( 1 .. 3 ) { $ssh = Net::OpenSSH->new($self->host ,timeout => 2 @@ -425,6 +445,7 @@ sub _connect_ssh($self) { } if ( $ssh->error ) { $self->_cached_active(0); + $self->_data('cached_down' => time); warn "Error connecting to ".$self->host." : ".$ssh->error(); return; } @@ -565,7 +586,7 @@ sub _around_create_domain { $domain->_chroot_filesystems(); } my $user = Ravada::Auth::SQL->search_by_id($id_owner); - $domain->is_volatile(1) if $user->is_temporary() || $volatile; + $domain->is_volatile(1) if $user->is_temporary() || $volatile || $args_create{volatile}; my @start_args = ( user => $owner ); push @start_args, (remote_ip => $remote_ip) if $remote_ip; @@ -1065,11 +1086,29 @@ sub _data($self, $field, $value=undef) { return $self->{_data}->{$field}; } +sub _set_by_id($id, $field, $value) { + my $sth = $$CONNECTOR->dbh->prepare( + "UPDATE vms set $field=?" + ." WHERE id=?" + ); + $sth->execute($value, $id); + $sth->finish; + + return $value; +} + sub _timed_data_cache($self) { return if !$self->{$FIELD_TIMEOUT} || time - $self->{$FIELD_TIMEOUT} < $CACHE_TIMEOUT; return _clean($self); } +sub _get_name_by_id($id) { + my $sth = $$CONNECTOR->dbh->prepare("SELECT name FROM vms WHERE id=?"); + $sth->execute($id); + my ($name) = $sth->fetchrow; + return $name; +} + sub _clean($self) { my $name = $self->{_data}->{name}; my $id = $self->{_data}->{id}; @@ -1680,6 +1719,7 @@ sub is_active($self, $force=0) { sub _do_is_active($self, $force=undef) { my $ret = 0; + $self->_data('cached_down' => 0); if ( $self->is_local ) { eval { $ret = 1 if $self->vm; @@ -2063,7 +2103,7 @@ sub balance_vm($self, $uid, $base=undef, $id_domain=undef, $host_devices=undef) confess "Error: base is not an object ".Dumper($base) if !ref($base); - @vms = $base->list_vms($host_devices); + @vms = $base->list_vms($host_devices,1); } else { @vms = $self->list_nodes(); } diff --git a/lib/Ravada/VM/KVM.pm b/lib/Ravada/VM/KVM.pm index 2c773cc75..a1f5dc66a 100644 --- a/lib/Ravada/VM/KVM.pm +++ b/lib/Ravada/VM/KVM.pm @@ -616,6 +616,7 @@ sub file_exists($self, $file) { sub _file_exists_remote($self, $file) { $file = $self->_follow_link($file) unless $file =~ /which$/; + return if !$self->vm; for my $pool ($self->vm->list_all_storage_pools ) { next if !$pool->is_active; $self->_wait_storage( sub { $pool->refresh() } ); @@ -809,6 +810,7 @@ sub search_domain($self, $name, $force=undef) { } my $dom; + return if !$self->vm; eval { $dom = $self->vm->get_domain_by_name($name); }; my $error = $@; return if $error =~ /error code: 42,/ && !$force; diff --git a/lib/Ravada/VM/Void.pm b/lib/Ravada/VM/Void.pm index 83f4d8d84..85b2e7386 100644 --- a/lib/Ravada/VM/Void.pm +++ b/lib/Ravada/VM/Void.pm @@ -107,25 +107,25 @@ sub create_domain { , _vm => $self ,storage => $storage ); - my ($out, $err) = $self->run_command("/usr/bin/test", - "-e ".$domain->_config_file." && echo 1" ); - chomp $out; - return $domain if $out && exists $args{config}; - - die "Error: Domain $args{name} already exists " if $out; - - $domain->_set_default_info($listen_ip, $network); - $domain->_store( autostart => 0 ); - $domain->_store( is_active => $active ); - $domain->set_memory($args{memory}) if $args{memory}; + my $file_exists = $self->file_exists($domain->_config_file); $domain->_insert_db(name => $args{name} , id_owner => $user->id , id => $id , id_vm => $self->id , id_base => $args{id_base} , description => $description - ); + ) unless $domain->is_known(); + + return $domain if $file_exists && exists $args{config}; + + die "Error: Domain $args{name} already exists in ".$self->name + ." ".$domain->_config_file if $file_exists; + + $domain->_set_default_info($listen_ip, $network); + $domain->_store( autostart => 0 ); + $domain->_store( is_active => $active ); + $domain->set_memory($args{memory}) if $args{memory}; if ($args{id_base}) { my $owner = $user; diff --git a/public/css/sb-admin.css b/public/css/sb-admin.css index 6d5a0f660..cac87a712 100644 --- a/public/css/sb-admin.css +++ b/public/css/sb-admin.css @@ -454,6 +454,10 @@ span.info { font-style: italic; } +span.output { + color: lightgray; +} + .title { padding-top: 4px; padding-bottom: 0px; diff --git a/public/js/ravada.js b/public/js/ravada.js index a7c1f497e..147aa448b 100644 --- a/public/js/ravada.js +++ b/public/js/ravada.js @@ -788,6 +788,7 @@ $http.get("/machine/public/"+machineId+"/"+value); }; $scope.set_base= function(vmId,machineId, value) { + $scope.showmachine.bases[vmId]=value; var url = 'set_base_vm'; if (value == 0 || !value) { url = 'remove_base_vm'; diff --git a/t/device/40_mediated_device.t b/t/device/40_mediated_device.t index 54cf46274..181177738 100644 --- a/t/device/40_mediated_device.t +++ b/t/device/40_mediated_device.t @@ -73,6 +73,8 @@ sub _check_used_mdev($vm, $hd) { $dom_imported = $vm->import_domain($dom->get_name,user_admin) unless $dom_imported; + $dom_imported->_data('status' => 'active'); + $dom_imported->add_host_device($hd->id); my ($dev) = grep /^$uuid/, $hd->list_devices; if (!$dev) { @@ -134,7 +136,7 @@ sub test_mdev($vm) { is($hd->list_available_devices(), $n_devices-1); test_config($domain); - sleep 1; + sleep 3; _req_shutdown($domain); for ( 1 .. 3 ) { last if $hd->list_available_devices() <= $n_devices; @@ -548,10 +550,24 @@ sub test_volatile_clones($vm, $domain, $host_device) { is($clone->is_active,1) unless $MOCK_MDEV; is($clone->is_volatile,1); test_config($clone); + sleep 3; $clone->shutdown_now(user_admin); + $exp_avail++; + + for (1 .. 3 ) { + $n_device = $host_device->list_available_devices(); + last if $n_device == $exp_avail; + Ravada::Request->force_shutdown( + uid => user_admin->id + ,id_domain => $clone->id + ); + wait_request; + } + is($n_device,$exp_avail) or exit; + $n_device = $host_device->list_available_devices(); - is($n_device,++$exp_avail) or exit; + is($n_device,$exp_avail) or exit; my $clone_gone = rvd_back->search_domain($clone_data->{name}); ok(!$clone_gone,"Expecting $clone_data->{name} removed on shutdown"); diff --git a/t/lib/Test/Ravada.pm b/t/lib/Test/Ravada.pm index 8c94b27d1..4b2753f73 100644 --- a/t/lib/Test/Ravada.pm +++ b/t/lib/Test/Ravada.pm @@ -2227,6 +2227,10 @@ sub start_node($node) { for my $try ( 1 .. 3) { my $is_active; for ( 1 .. 90 ) { + Ravada::Request->connect_node(uid => user_admin->id + ,id_node => $node->id + ); + wait_request(); eval { $node->disconnect; $node->clear_netssh(); @@ -2236,7 +2240,7 @@ sub start_node($node) { warn $@ if $@; last if $is_active; sleep 1; - diag("Waiting for active node ".$node->name." $_") if !($_ % 10); + diag("Waiting for active node ".$node->name." $try - $_") if !($_ % 10); } last if $is_active; if ($try == 1 ) { diff --git a/t/nodes/10_basic.t b/t/nodes/10_basic.t index 0e5cfdeb6..80b8976f0 100644 --- a/t/nodes/10_basic.t +++ b/t/nodes/10_basic.t @@ -455,6 +455,30 @@ sub test_removed_base_file_and_swap_remote($vm, $node) { $base->remove(user_admin); } +sub _check_base_in_vm_db($base, $id_node, $id_req, $value) { + my $sth = connector->dbh->prepare( + "SELECT * FROM bases_vm " + ." WHERE id_domain=? AND id_vm=?" + ); + $sth->execute($base->id, $id_node); + my $found = $sth->fetchrow_hashref; + ok($found) or exit; + is($found->{enabled}, $value); + is($found->{id_request}, $id_req) or confess; + + my @vms = $base->list_vms(); + my @vms_avail = $base->list_vms(undef, 1); + + if ($id_req && $value) { + my ($found_vms) = grep { $_->id == $id_node } @vms; + my ($found_vms_avail) = grep { $_->id == $id_node } @vms_avail; + ok($found_vms,"Expecting ".$base->id." in $id_node ") + or die Dumper([[map {$_->id } @vms ],[map {$_->id } @vms_avail]]); + ok(!$found_vms_avail); + } + +} + sub test_set_vm_fail($vm, $node) { return if $vm->type ne 'KVM'; diag("Test set vm fail"); @@ -677,9 +701,18 @@ sub test_volatile_req_clone($vm, $node, $machine='pc-i440fx') { my $base = create_domain_v2(vm => $vm, options => { machine => $machine }); $base->prepare_base(user_admin); - $base->set_base_vm(user => user_admin, node => $node); + my $req = Ravada::Request->set_base_vm( + uid => user_admin->id + ,id_domain => $base->id + ,id_vm => $node->id + ,value => 1 + ); + _check_base_in_vm_db($base, $node->id,$req->id, 1); $base->volatile_clones(1); ok($base->base_in_vm($node->id)); + _check_base_in_vm_db($base, $node->id,$req->id, 1); + wait_request(debug => 1); + _check_base_in_vm_db($base, $node->id,undef, 1); my $clone; for ( 1 .. 20 ) { diff --git a/templates/bootstrap/requests.html.ep b/templates/bootstrap/requests.html.ep index 36101f74a..1ca83662b 100644 --- a/templates/bootstrap/requests.html.ep +++ b/templates/bootstrap/requests.html.ep @@ -70,6 +70,7 @@ {{request.status}} {{request.error}} + {{request.output}}