mirror of
https://github.com/TheGrandWazoo/freenas-proxmox.git
synced 2026-10-21 11:16:10 +02:00
fix: return (size, format, used, parent) from volume_size_info in list context (#294)
PVE's content API (and the bpg/proxmox Terraform provider through it) calls volume_size_info in list context and dies "no format" when the second value is missing, so every disk on a truenas storage failed to refresh. Mirrors ZFSPoolPlugin: used comes from usedbydataset, and a missing zvol now dies instead of reporting a size of 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c45c3b0abf
commit
664dfe6a3e
@@ -985,10 +985,20 @@ sub volume_size_info {
|
||||
my ($class, $scfg, $storeid, $volname, $timeout) = @_;
|
||||
_resolve_token($storeid, $scfg);
|
||||
|
||||
my (undef, undef, undef, $parent, undef, undef, $format) = $class->parse_volname($volname);
|
||||
|
||||
my $zvol = _zvol_prefix($scfg) . "/$volname";
|
||||
my $enc = uri_escape($zvol, "^A-Za-z0-9\\-_.~");
|
||||
my $ds = _api($scfg, 'GET', "/pool/dataset/id/$enc") // {};
|
||||
return $ds->{volsize}{parsed} // 0;
|
||||
my $ds = _api($scfg, 'GET', "/pool/dataset/id/$enc");
|
||||
die "volume_size_info: zvol '$zvol' not found on $scfg->{truenas_host}\n"
|
||||
unless ref $ds eq 'HASH' && defined $ds->{volsize}{parsed};
|
||||
|
||||
my $size = int($ds->{volsize}{parsed});
|
||||
my $used = int($ds->{usedbydataset}{parsed} // $ds->{used}{parsed} // 0);
|
||||
|
||||
# List context is (size, format, used, parent), as in ZFSPoolPlugin. A bare
|
||||
# scalar here made the content API die with "no format" (#294).
|
||||
return wantarray ? ($size, $format, $used, $parent) : $size;
|
||||
}
|
||||
|
||||
sub path {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/perl
|
||||
# volume_size_info contract: scalar context → size; list context →
|
||||
# (size, format, used, parent). PVE's content API dies "no format" otherwise.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/lib", "$FindBin::Bin/../perl5";
|
||||
|
||||
use Test::More;
|
||||
|
||||
use MockTrueNAS;
|
||||
use PVE::Storage::Custom::TrueNAS;
|
||||
|
||||
my $TN = 'PVE::Storage::Custom::TrueNAS';
|
||||
|
||||
MockTrueNAS->install(datasets => {
|
||||
'tank/vm/vm-100-disk-0' => {
|
||||
volsize => { parsed => 34359738368 },
|
||||
usedbydataset => { parsed => 1073741824 },
|
||||
used => { parsed => 2147483648 },
|
||||
},
|
||||
'tank/vm/vm-100-cloudinit' => {
|
||||
volsize => { parsed => 4194304 },
|
||||
used => { parsed => 65536 },
|
||||
},
|
||||
});
|
||||
|
||||
subtest 'scalar context returns size' => sub {
|
||||
my $size = $TN->volume_size_info(MockTrueNAS::scfg(), 'store', 'vm-100-disk-0');
|
||||
is($size, 34359738368, 'size');
|
||||
};
|
||||
|
||||
subtest 'list context returns (size, format, used, parent) (#294)' => sub {
|
||||
my @r = $TN->volume_size_info(MockTrueNAS::scfg(), 'store', 'vm-100-disk-0');
|
||||
is(scalar @r, 4, 'four values');
|
||||
is($r[0], 34359738368, 'size');
|
||||
is($r[1], 'raw', 'format');
|
||||
is($r[2], 1073741824, 'used prefers usedbydataset');
|
||||
ok(!defined $r[3], 'no parent');
|
||||
};
|
||||
|
||||
subtest 'used falls back to used when usedbydataset is absent' => sub {
|
||||
my (undef, $fmt, $used) = $TN->volume_size_info(MockTrueNAS::scfg(), 'store', 'vm-100-cloudinit');
|
||||
is($fmt, 'raw', 'cloud-init drive has a format');
|
||||
is($used, 65536, 'used');
|
||||
};
|
||||
|
||||
subtest 'missing zvol dies instead of reporting size 0' => sub {
|
||||
eval { $TN->volume_size_info(MockTrueNAS::scfg(), 'store', 'vm-100-disk-9') };
|
||||
like($@, qr/not found/, 'dies');
|
||||
};
|
||||
|
||||
done_testing();
|
||||
Reference in New Issue
Block a user