Skip to content

Commit c2517ac

Browse files
jaycollettmvdkleijn
authored andcommitted
Fix Proxmox livestats 500 error with null handling
The livestats() method would crash with a 500 error when: - API calls returned null (connection failures, permission issues) - Node status/VM/container data was missing expected properties - Division by zero when no valid nodes were found Changes: - Add null check in apiCall() before calling getBody() - Check nodeData for null before array_map() - Add null checks for node_status, vm_stats, and container_stats - Track valid_nodes count to prevent division by zero - Use null coalescing for optional properties (cpu, memory) - Return "inactive" status gracefully instead of crashing Fixes linuxserver/Heimdall#1533
1 parent 9c739d7 commit c2517ac

1 file changed

Lines changed: 43 additions & 21 deletions

File tree

Proxmox/Proxmox.php

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,21 @@ public function test()
3939
public function livestats()
4040
{
4141
$status = "active";
42-
$attrs = $this->getRequestAttrs();
4342

4443
$nodes = explode(",", $this->getConfigValue("nodes", ""));
4544

4645
if ($nodes == [""]) {
46+
$nodeData = $this->apiCall("nodes");
47+
if ($nodeData === null) {
48+
return parent::getLiveStats("inactive", []);
49+
}
4750
$nodes = array_map(function ($v) {
4851
return $v->node;
49-
}, $this->apiCall("nodes"));
52+
}, $nodeData);
53+
}
54+
55+
if (empty($nodes)) {
56+
return parent::getLiveStats("inactive", []);
5057
}
5158

5259
$vm_running = 0;
@@ -56,39 +63,49 @@ public function livestats()
5663
$cpu_percent_sum = 0.0;
5764
$memory_total = 0.0;
5865
$memory_used = 0.0;
66+
$valid_nodes = 0;
67+
5968
foreach ($nodes as $node) {
6069
$node_status = $this->apiCall("nodes/" . $node . "/status");
61-
$cpu_percent_sum += $node_status->cpu;
62-
$memory_used += $node_status->memory->used;
63-
$memory_total += $node_status->memory->total;
70+
if ($node_status !== null) {
71+
$valid_nodes++;
72+
$cpu_percent_sum += $node_status->cpu ?? 0;
73+
$memory_used += isset($node_status->memory) ? ($node_status->memory->used ?? 0) : 0;
74+
$memory_total += isset($node_status->memory) ? ($node_status->memory->total ?? 0) : 0;
75+
}
6476

6577
$vm_stats = $this->apiCall("nodes/" . $node . "/qemu");
66-
$vm_total += count($vm_stats);
67-
$vm_running += count(
68-
array_filter($vm_stats, function ($v) {
69-
return $v->status == "running";
70-
})
71-
);
78+
if ($vm_stats !== null) {
79+
$vm_total += count($vm_stats);
80+
$vm_running += count(
81+
array_filter($vm_stats, function ($v) {
82+
return isset($v->status) && $v->status == "running";
83+
})
84+
);
85+
}
7286

7387
$container_stats = $this->apiCall("nodes/" . $node . "/lxc");
74-
$container_total += count($container_stats);
75-
$container_running += count(
76-
array_filter($container_stats, function ($v) {
77-
return $v->status == "running";
78-
})
79-
);
88+
if ($container_stats !== null) {
89+
$container_total += count($container_stats);
90+
$container_running += count(
91+
array_filter($container_stats, function ($v) {
92+
return isset($v->status) && $v->status == "running";
93+
})
94+
);
95+
}
8096
}
8197

82-
$res = parent::execute($this->url("version"), $attrs);
83-
$details = json_decode($res->getBody())->data;
98+
if ($valid_nodes === 0) {
99+
return parent::getLiveStats("inactive", []);
100+
}
84101

85102
$data = [
86103
"vm_running" => $vm_running,
87104
"vm_total" => $vm_total,
88105
"container_running" => $container_running,
89106
"container_total" => $container_total,
90-
"cpu_percent" => ($cpu_percent_sum / count($nodes)) * 100,
91-
"memory_percent" => (100 / $memory_total) * $memory_used,
107+
"cpu_percent" => ($cpu_percent_sum / $valid_nodes) * 100,
108+
"memory_percent" => $memory_total > 0 ? (100 / $memory_total) * $memory_used : 0,
92109
];
93110
return parent::getLiveStats($status, $data);
94111
}
@@ -107,6 +124,11 @@ public function url($endpoint)
107124
public function apiCall($endpoint)
108125
{
109126
$res = parent::execute($this->url($endpoint), $this->getRequestAttrs());
127+
128+
if ($res === null) {
129+
return null;
130+
}
131+
110132
$object = json_decode($res->getBody());
111133

112134
if (!$object instanceof \stdClass) {

0 commit comments

Comments
 (0)