Unverified Commit 01e8d17f authored by Francesc Guasch's avatar Francesc Guasch Committed by GitHub
Browse files

Fix renamed vol (#1293)

* fix(backend): check volume name isn't already used

issue #1285
parent 9494108b
......@@ -3045,7 +3045,7 @@ sub _cmd_shutdown_clones {
if ($is_active) {
my $req = Ravada::Request->shutdown_domain(
uid => $uid
,name => $name);
,id_domain => $domain2->id);
}
}
}
......
......@@ -656,9 +656,9 @@ sub _check_volume_added($self, $file) {
return if $file =~ /\.iso$/i;
my $sth = $$CONNECTOR->dbh->prepare("SELECT id,id_domain FROM volumes "
." WHERE file=?"
." WHERE file=? or name=?"
);
$sth->execute($file);
$sth->execute($file,$file);
my ($id, $id_domain) = $sth->fetchrow();
$sth->finish;
......@@ -921,6 +921,7 @@ sub _check_tmp_volumes($self) {
for my $vol ( $self->list_volumes_info) {
next unless $vol->file && $vol->file =~ /\.(TMP|SWAP)\./;
next if $vm_local->file_exists($vol->file);
$vol->delete();
my $base = Ravada::Domain->open($self->id_base);
my @volumes = $base->list_files_base_target;
......@@ -1699,7 +1700,7 @@ sub restore($self,$user){
my $vol_base = Ravada::Volume->new(
file => $file_base
,is_base => 1
,vm => $self->_vm
,domain => $self
);
next if $vol_base->file =~ /\.DATA\.\w+$/;
my $file_clone = $file{$target} or die Dumper(\%file);
......@@ -1767,12 +1768,19 @@ sub _remove_domain_cascade($self,$user, $cascade = 1) {
my @instances = $self->list_instances();
return if !scalar(@instances);
my $sth_delete = $$CONNECTOR->dbh->prepare("DELETE FROM domain_instances "
." WHERE id=? ");
for my $instance ( @instances ) {
next if $instance->{id_vm} == $self->_vm->id;
my $vm = Ravada::VM->open($instance->{id_vm});
my $vm;
eval { $vm = Ravada::VM->open($instance->{id_vm}) };
die $@ if $@ && $@ !~ /I can't find VM/i;
my $domain;
eval { $domain = $vm->search_domain($domain_name) };
warn $@ if $@;
$domain->remove($user, $cascade) if $domain;
$sth_delete->execute($instance->{id});
}
}
......@@ -3460,6 +3468,7 @@ Check if the domain has swap volumes defined, and clean them
sub clean_swap_volumes {
my $self = shift;
for my $vol ( $self->list_volumes_info) {
confess if !$vol->domain;
if ($vol->file && $vol->file =~ /\.SWAP\.\w+$/) {
next if !$self->_vm->file_exists($vol->file);
my $backing_file;
......@@ -3476,6 +3485,8 @@ sub clean_swap_volumes {
sub _pre_rename {
my $self = shift;
confess "Error: odd number of arguments" if scalar(@_) % 2;
my %args = @_;
my $name = $args{name};
my $user = $args{user};
......
......@@ -347,7 +347,7 @@ sub list_storage_pools {
sub is_alive($self) {
return 0 if !$self->vm;
return 1;
return $self->ping(undef,0);
}
sub free_memory {
......
......@@ -175,10 +175,13 @@ sub clone_filename($self, $name = undef) {
}
sub restore ($self) {
my @domain;
@domain = ( domain => $self->domain ) if $self->domain;
my $base = Ravada::Volume->new(
vm => $self->vm
,file => $self->backing_file
,is_base => 1
,@domain
);
$base->clone(
file => $self->file
......@@ -198,6 +201,13 @@ sub set_info($self, $name, $value) {
$self->_cache_volume_info() if $self->domain();
}
sub delete($self) {
my $file = $self->file;
$self->vm->remove_file($file) if $file;
my $sth = $self->_dbh->prepare("DELETE FROM volumes WHERE file=? AND id_domain=?");
$sth->execute($file, $self->domain->id);
}
sub _dbh($self) {
return $self->domain->_dbh if $self->domain;
return $self->vm->_dbh if $self->vm;
......
......@@ -29,23 +29,56 @@ sub _around_prepare_base($orig, $self) {
$self->vm->remove_file($self->file);
my @domain = ();
@domain = ( domain => $self->domain) if $self->domain;
@domain = ( vm => $self->vm ) if !$self->domain && $self->vm;
my $base = Ravada::Volume->new(
file => $base_file
,is_base => 1
,vm => $self->vm
,@domain
);
$base->clone(file => $self->file);
return $base_file;
}
sub _domain_file($self, $file) {
my $sth = $self->_dbh->prepare("SELECT id_domain FROM volumes WHERE file=? "
." OR name=?");
$sth->execute($file,$file);
my ($id_domain) = $sth->fetchrow;
return $id_domain;
}
sub _new_clone_filename($self,$name0) {
my $extra='';
my $clone_filename = $self->clone_filename($name0);
return $clone_filename if $clone_filename =~ /\.iso$/;
for (1 .. 10) {
return $clone_filename if !$self->_domain_file($clone_filename);
$clone_filename = $self->clone_filename($name0."-"
.Ravada::Utils::random_name());
}
die "Error: I can't produce a random filename";
}
sub _around_clone($orig, $self, %args) {
my $name = delete $args{name};
my $file_clone = ( delete $args{file} or $self->clone_filename($name));
my $file_clone = ( delete $args{file} or $self->_new_clone_filename($name));
confess "Error: unkonwn args ".Dumper(\%args) if keys %args;
confess "Error: empty clone filename" if !defined $file_clone || !length($file_clone);
my $id_domain_file= $self->_domain_file($file_clone);
if ($id_domain_file && $file_clone !~ /\.iso$/) {
my $we = '';
$we = "We are domain id: ".($self->domain->id)." [ ".$self->domain->name." ]"
if $self->domain;
confess "Error: file $file_clone already exists in domain $id_domain_file.$we"
if !$self->domain || $self->domain->id != $id_domain_file;
}
return Ravada::Volume->new(
file => $orig->($self, $file_clone)
,vm => $self->vm
......
......@@ -45,12 +45,15 @@ sub test_node_down($node, $action, $action_name) {
$action->($clone);
shutdown_node($node);
$node->_clean_cache();
$clone = Ravada::Domain->open($clone->id);
eval { $clone->start(user_admin) };
is($@,'');
is(''.$@,'');
is($clone->is_active, 1, "Expecting clone ".$clone->name." active");
is($clone->is_local, 1,"Expecting clone ".$clone->name." local");
is($domain->base_in_vm($node->id),0);
is($domain->base_in_vm($node->id),1);
$node->_clean_cache();
start_node($node);
......
......@@ -833,9 +833,12 @@ sub test_base_unset($vm, $node) {
my $clone = $base->clone(name => new_domain_name, user => user_admin);
$clone->migrate($node);
$base->set_base_vm(id_vm => $node->id,value => 0, user => user_admin);
$clone->start(user_admin);
is($base->base_in_vm($node->id),0) or exit;
is(Ravada::Domain::base_in_vm($base->id,$node->id),0) or exit;
my $clone2 = Ravada::Domain->open($clone->id);
$clone2->start(user_admin);
is($clone->_vm->id, $vm->id);
is($clone2->_vm->name, $vm->name) or exit;
_remove_domain($base);
}
......
......@@ -163,6 +163,12 @@ sub test_change_hardware($vm, @nodes) {
my @volumes = $clone->list_volumes();
for my $node (@nodes) {
for ( 1 .. 10 ) {
last if $node->ping(undef,0);
diag("Waiting for ".$node->name." ping $_");
sleep 1;
}
is($node->ping(),1) or die "Error: I can't ping ".$node->ip;
$domain->set_base_vm( vm => $node, user => user_admin);
my $clone2 = $node->search_domain($clone->name);
ok(!$clone2);
......@@ -175,6 +181,12 @@ sub test_change_hardware($vm, @nodes) {
my ($hardware) = grep { !/disk|volume/ } keys %{$info->{hardware}};
$clone->remove_controller($hardware,0);
my $sth = connector->dbh->prepare("SELECT count(*) FROM domain_instances "
."WHERE id_domain = ".$clone->id );
$sth->execute();
my ($count) = $sth->fetchrow;
is($count,1,"Expecting other instances removed when hardware changed") or exit;
for my $node (@nodes) {
my $clone2 = $node->search_domain($clone->name);
ok(!$clone2,"Expecting no clone ".$clone->name." in remote node ".$node->name) or exit;
......
......@@ -119,10 +119,13 @@ sub test_shutdown_clones {
is($req->error,'');
# The first requests creates 3 more requests, process them
rvd_back->_process_all_requests_dont_fork();
is($clone1->is_active,0);
is($clone2->is_active,0);
is($clone3->is_active,0);
for my $clone ($clone1, $clone2, $clone3) {
my ($req) = grep({$_->command eq 'shutdown'} $clone->list_requests),
ok($req);
is($req->command,'shutdown') or die Dumper($clone->list_requests)
if $req;
}
$clone1->remove(user_admin);
$clone2->remove(user_admin);
......
......@@ -68,6 +68,7 @@ sub test_remove_domain {
}
test_ports_remove($id_domain);
test_instances_remove($id_domain);
}
sub test_ports_remove {
......@@ -80,6 +81,17 @@ sub test_ports_remove {
is($count,undef);
}
sub test_instances_remove {
my $id_domain = shift;
my $sth = connector->dbh->prepare(
"SELECT count(*) FROM domain_instances"
." WHERE id_domain = ? "
);
my ($count) = $sth->fetchrow;
is($count,undef);
}
sub test_remove_domain_base {
my $vm_name = shift;
......
......@@ -2,8 +2,12 @@
use strict;
use warnings;
use Data::Dumper;
use Test::More;
no warnings "experimental::signatures";
use feature qw(signatures);
use lib 't/lib';
use Test::Ravada;
......@@ -54,6 +58,50 @@ sub test_remove_domain_volumes_already_gone {
eval { $domain->remove(user_admin) };
is(''.$@,'',$vm->type);
}
sub _clone($base, $name=new_domain_name) {
return $base->clone(
name => $name
,user => user_admin
);
}
sub test_remove_rename($vm) {
my $base= create_domain($vm->type);
my $name = new_domain_name();
my $base2 = _clone($base, $name);
$base2->prepare_base(user_admin);
my @volumes_base = $base->list_files_base();
my $clone = _clone($base);
$base2->remove_base(user_admin);
$base2->rename(name => new_domain_name, user => user_admin);
my $clone2;
eval { $clone2 = _clone($base, $name); };
is($@,'') or exit;
$clone2 = rvd_back->search_domain($name);
ok($clone2);
$clone2->remove(user_admin);
for my $vol (@volumes_base, $base2->list_volumes) {
ok( -e $vol,$vol);
}
my $clone3 = _clone($base);
$clone3->start(user_admin);
_remove_domain($base, $base2);
}
sub _remove_domain(@domain) {
for my $domain (@domain) {
for my $clone_data ($domain->clones) {
my $clone = Ravada::Domain->open($clone_data->{id});
$clone->remove(user_admin);
}
$domain->remove(user_admin);
}
}
##############################################################################
......@@ -78,6 +126,7 @@ for my $vm_name ( vm_names() ) {
diag("Testing remove on $vm_name");
test_remove_rename($vm);
test_remove_domain($vm);
test_remove_domain_volumes_already_gone($vm);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment