fix: SCALE 25.10 strict Pydantic rejects volsize encoded as string (#269)

SCALE 25.10 (Goldeye) enforces strict integer validation. The log call
preceding the API call stringifies $size_b (sets Perl's POK flag), causing
JSON::XS to encode it as "8589934592" (quoted) instead of 8589934592.
int() at the encode site produces a fresh IV without the POK flag.

Also adds error parser support for SCALE 25.10's field-keyed validation
error format so the full Pydantic detail surfaces in PVE task logs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Kevin Adams 2026-05-31 08:58:00 -04:00
parent 359c2af88e
commit c7ce39d8ae
1 changed files with 14 additions and 2 deletions

View File

@ -193,6 +193,15 @@ sub _api {
# SCALE 25.04+ returns Pydantic validation errors as an array
my @msgs = map { $_->{message} // $_->{msg} // '' } @$body;
$detail = " — " . join('; ', grep { length } @msgs);
} elsif (ref $body eq 'HASH') {
# SCALE 25.10+ returns field-keyed validation errors: { "field": [{message}...] }
my @msgs;
for my $field (sort keys %$body) {
my $errs = $body->{$field};
next unless ref $errs eq 'ARRAY';
push @msgs, map { "$field: " . ($_->{message} // '') } @$errs;
}
$detail = " — " . join('; ', grep { length } @msgs) if @msgs;
}
};
my $msg = "TrueNAS API $method $path: " . $res->status_line . $detail;
@ -435,15 +444,18 @@ sub alloc_image {
my $prefix = _zvol_prefix($scfg);
my $zvol = "$prefix/$name";
my $size_b = $size_kb * 1024;
my $size_b = int($size_kb) * 1024;
_log('info', "alloc_image: creating zvol $zvol ($size_b bytes) for VM $vmid");
# 1. Create the zvol
# int() here produces a fresh IV — string interpolation in the log call above
# sets Perl's POK flag on $size_b, which causes JSON::XS to encode it as a
# string. SCALE 25.10 strict Pydantic rejects string-typed integers.
_api($scfg, 'POST', '/pool/dataset', {
name => $zvol,
type => 'VOLUME',
volsize => $size_b,
volsize => int($size_b),
sparse => JSON::true,
});