fix: repair freenas_api_connect autovivification and ping URL passthrough (#238)

Two bugs caused clone/migrate to fail with 'setHost on undefined value'
followed by 'Loop recursion prevention':

1. freenas_api_check reads $freenas_server_list->{$apihost}{client} to
   check if initialized. Perl autovivifies {$apihost} as an empty {} on
   that read. freenas_api_connect then saw a defined (but empty) hash and
   skipped initialization, leaving client undef → setHost crash.
   Fix: guard also checks !defined ...{client}.

2. $ping was a local variable reset to v1.0 on each recursive call.
   TrueNAS 25.04+ removed the v1.0 endpoint (returns 404), so the
   v1.0→v2.0 upgrade branch looped until the runaway counter tripped.
   Fix: accept $ping as optional second parameter (defaults to v1.0)
   and pass it through on both recursive call sites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Kevin Adams
2026-05-19 23:34:58 -04:00
co-authored by Claude Sonnet 4.6
parent 3b3cc8d135
commit 168cf0adf7
+5 -5
View File
@@ -334,15 +334,15 @@ sub run_delete_lu {
sub freenas_api_connect {
my ($scfg) = @_;
my ($scfg, $ping) = @_;
$ping //= '/api/v1.0/system/version/';
syslog("info", (caller(0))[3] . " : called");
my $scheme = $scfg->{freenas_use_ssl} ? "https" : "http";
my $apihost = defined($scfg->{freenas_apiv4_host}) ? $scfg->{freenas_apiv4_host} : $scfg->{portal};
my $ping = '/api/v1.0/system/version/';
if (!defined $freenas_server_list->{$apihost}) {
if (!defined $freenas_server_list->{$apihost} || !defined $freenas_server_list->{$apihost}{client}) {
$freenas_server_list->{$apihost} = {
client => REST::Client->new(),
product_name => undef,
@@ -390,13 +390,13 @@ sub freenas_api_connect {
syslog("info", (caller(0))[3] . " : v1.0 API unavailable (HTTP $code) — upgrading to v2.0");
$host->{runaway_count}++;
$ping =~ s/v1\.0/v2\.0/;
freenas_api_connect($scfg);
freenas_api_connect($scfg, $ping);
# A 307 from FreeNAS means redirect http to https.
} elsif ($code == 307) {
syslog("info", (caller(0))[3] . " : Redirecting to HTTPS protocol");
$host->{runaway_count}++;
$scfg->{freenas_use_ssl} = 1;
freenas_api_connect($scfg);
freenas_api_connect($scfg, $ping);
# For now, any other code we fail.
} else {
freenas_api_log_error($host->{client});