Unverified Commit 7ce7653e authored by Francesc Guasch's avatar Francesc Guasch Committed by GitHub
Browse files

Refactor #10 disk (#1040)

feature(backend): check for free disk space

* test(volumes): check error when disk full
* test(backend): check disk space before prepare base
* fix(backend): error when no space available


issue #10
parent b091e104
......@@ -501,6 +501,14 @@ sub _around_add_volume {
$args{allocation} = Ravada::Utils::size_to_number($args{allocation})
if exists $args{allocation} && defined $args{allocation};
my $free = $self->_vm->free_disk();
my $free_out = int($free / 1024 / 1024 / 1024 ) * 1024 *1024 *1024;
die "Error creating volume, out of space $size . Disk free: "
.Ravada::Utils::number_to_size($free_out)
."\n"
if exists $args{size} && $args{size} >= $free;
my $ok = $self->$orig(%args);
confess "Error adding ".Dumper(\%args) if !$ok;
$path = $ok if ! $path;
......@@ -597,6 +605,18 @@ sub _pre_prepare_base($self, $user, $request = undef ) {
my $vm_local = Ravada::VM->open( type => $self->vm );
$self->migrate($vm_local);
}
$self->_check_free_space_prepare_base();
}
sub _check_free_space_prepare_base($self) {
my $pool_base = $self->_vm->default_storage_pool_name;
$pool_base = $self->_vm->base_storage_pool() if $self->_vm->base_storage_pool();
for my $volume ($self->list_volumes_info(device => 'disk')) {;
next if $volume->{device} ne 'disk';
$self->_vm->_check_free_disk($volume->{capacity} * 2, $pool_base);
}
};
sub _post_prepare_base {
......
......@@ -423,6 +423,9 @@ sub _create_qcow_base {
my $pool_base = $self->_vm->default_storage_pool_name;
$pool_base = $self->_vm->base_storage_pool() if $self->_vm->base_storage_pool();
$pool_base = $self->_vm->storage_pool() if !$pool_base;
$self->_vm->_check_free_disk($vol_data->{capacity} * 2);
my $dir_base = $self->_vm->_storage_path($pool_base);
......
......@@ -63,6 +63,7 @@ requires 'import_domain';
requires 'is_alive';
requires 'free_memory';
requires 'free_disk';
requires '_fetch_dir_cert';
......@@ -1384,6 +1385,21 @@ sub shutdown($self) {
$self->run_command_nowait('/sbin/poweroff');
}
sub _check_free_disk($self, $size, $storage_pool=undef) {
my $size_out = int($size / 1024 / 1024 / 1024 ) * 1024 *1024 *1024;
my $free = $self->free_disk($storage_pool);
my $free_out = int($free / 1024 / 1024 / 1024 ) * 1024 *1024 *1024;
die "Error creating volume, out of space."
." Requested: ".Ravada::Utils::number_to_size($size_out)
." , Disk free: ".Ravada::Utils::number_to_size($free_out)
."\n"
if $size > $free;
}
1;
......@@ -176,7 +176,7 @@ sub _load_storage_pool {
my $vm_pool;
my $available;
if (defined $self->default_storage_pool_name) {
if ($self->default_storage_pool_name) {
return( $self->vm->get_storage_pool_by_name($self->default_storage_pool_name)
or confess "ERROR: Unknown storage pool: ".$self->default_storage_pool_name);
}
......@@ -2247,4 +2247,14 @@ sub _fetch_dir_cert($self) {
close $in;
}
sub free_disk($self, $pool_name = undef ) {
my $pool;
if ($pool_name) {
$pool = $self->vm->get_storage_pool_by_name($pool_name);
} else {
$pool = $self->storage_pool();
}
my $info = $pool->get_info();
return $info->{available};
}
1;
......@@ -323,6 +323,15 @@ sub free_memory {
sub _fetch_dir_cert {
confess "TODO";
}
sub free_disk($self, $storage_pool = undef) {
my $df = `df`;
for my $line (split /\n/, $df) {
my @info = split /\s+/,$line;
return $info[3] * 1024 if $info[5] eq '/';
}
die "Not found";
}
#########################################################################3
1;
......@@ -154,6 +154,7 @@ sub test_volumes_in_two_pools {
my $domain;
eval { $domain = $vm->create_domain(name => $name
, id_owner => $USER->id
, disk => 1024 * 1024
, arg_create_dom($vm_name))
};
......
......@@ -386,6 +386,37 @@ sub test_domain_swap {
}
sub test_too_big($vm) {
my $domain = create_domain($vm);
my $free_disk = $vm->free_disk();
my $file;
eval { $file = $domain->add_volume(size => int($free_disk * 1.1)) };
like($@, qr(out of space),$vm->type) or exit;
ok(!$file);
my $free_disk2 = $vm->free_disk();
is($free_disk2, $free_disk);
$domain->remove(user_admin);
}
sub test_too_big_prepare($vm) {
my $domain = create_domain($vm);
my $free_disk = $vm->free_disk();
my $file;
eval { $file = $domain->add_volume(size => int($free_disk * 0.9)) };
is($@,'');
ok($file);
is($domain->is_base, 0) or exit;
eval { $domain->prepare_base(user_admin); };
like($@, qr(out of space),$vm->type." prepare base") or exit;
is(scalar($domain->list_files_base),0,"[".$vm->type."] ".Dumper([$domain->list_files_base]));
is($domain->is_base, 0) or exit;
$domain->remove(user_admin);
}
sub test_search($vm_name) {
my $vm = rvd_back->search_vm($vm_name);
$vm->set_default_storage_pool_name('default') if $vm eq 'KVM';
......@@ -440,6 +471,17 @@ for my $vm_name (reverse sort @VMS) {
use_ok("Ravada::VM::$vm_name");
test_too_big_prepare($vm);
my $old_pool = $vm->default_storage_pool_name();
if ($old_pool) {
$vm->default_storage_pool_name('');
test_too_big_prepare($vm);
$vm->default_storage_pool_name($old_pool);
}
test_too_big($vm);
test_domain_swap($vm_name);
test_domain_create_with_swap($vm_name);
test_domain_1_volume($vm_name);
......
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