mirror of
https://github.com/TheGrandWazoo/freenas-proxmox.git
synced 2026-09-30 03:51:27 +02:00
fix: correct iscsi.extent/target/targetextent.delete param shapes (WS transport)
Live-tested the write path against .92 for the first time (alloc_image
-> path -> volume_size_info -> free_image full cycle) and found two
real bugs in the inferred delete mappings:
- iscsi.target.delete and iscsi.targetextent.delete were passing a raw
regex-captured id as a Perl string; Pydantic rejects "Input should
be a valid integer" without int().
- iscsi.extent.delete(id, remove=False, force=False) is positional --
REST's DELETE body {force=>true} was being passed as a single hash
in position 2, which the API validates as a boolean field named
"remove", not force. Fixed to unpack positionally: id, remove
(always false -- REST never asked for this), force (from the REST
body's force field).
Confirmed clean after the fix: a full alloc_image/free_image cycle
against .92 leaves zero orphaned targets, extents, targetextents, or
datasets. This is the first write-path confirmation for the WebSocket
transport -- narrows ADR-012's "not yet live-tested" warning to the
remaining untested calls (targetextent.create/query filters beyond
what alloc_image exercises, pool.dataset.delete's options shape,
zfs.snapshot.* entirely).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b2187654dc
commit
c05de59396
@@ -398,13 +398,13 @@ sub _api_ws {
|
||||
}
|
||||
|
||||
} elsif ($base =~ m{^/iscsi/target/id/(.+)$}) {
|
||||
my $id = $1;
|
||||
my $id = int($1);
|
||||
if ($method eq 'DELETE') {
|
||||
$rpc_method = 'iscsi.target.delete';
|
||||
$params = [$id];
|
||||
} else {
|
||||
$rpc_method = 'iscsi.target.query';
|
||||
$params = [[[ 'id', '=', int($id) ]], {}];
|
||||
$params = [[[ 'id', '=', $id ]], {}];
|
||||
$single = 1;
|
||||
}
|
||||
|
||||
@@ -422,7 +422,11 @@ sub _api_ws {
|
||||
|
||||
} elsif ($base =~ m{^/iscsi/targetextent/id/(.+)$}) {
|
||||
$rpc_method = 'iscsi.targetextent.delete';
|
||||
$params = [$1, $data // JSON::false];
|
||||
# REST call sites pass either a bare boolean or {force=>...} as $data;
|
||||
# iscsi.targetextent.delete(id, force=False) is positional (id, bool).
|
||||
my $force = (ref($data) eq 'HASH') ? ($data->{force} ? JSON::true : JSON::false)
|
||||
: ($data ? JSON::true : JSON::false);
|
||||
$params = [int($1), $force];
|
||||
|
||||
} elsif ($base eq '/iscsi/extent') {
|
||||
if ($method eq 'POST') {
|
||||
@@ -435,7 +439,15 @@ sub _api_ws {
|
||||
|
||||
} elsif ($base =~ m{^/iscsi/extent/id/(.+)$}) {
|
||||
$rpc_method = 'iscsi.extent.delete';
|
||||
$params = [$1, $data // {}];
|
||||
# CONFIRMED live 2026-08-31: iscsi.extent.delete(id, remove=False,
|
||||
# force=False) is positional, NOT (id, {force=>bool}) — a {force=>...}
|
||||
# hash in position 2 fails Pydantic validation on the "remove" field.
|
||||
# REST's "force" concept maps to WS's 3rd positional "force"; "remove"
|
||||
# (whether to also delete the underlying zvol/file, which the REST
|
||||
# path never asked for since free_image deletes the dataset itself
|
||||
# afterward) stays false.
|
||||
my $force = (ref($data) eq 'HASH' && $data->{force}) ? JSON::true : JSON::false;
|
||||
$params = [int($1), JSON::false, $force];
|
||||
|
||||
} elsif ($base eq '/service/reload') {
|
||||
$rpc_method = 'service.reload';
|
||||
|
||||
Reference in New Issue
Block a user