Fetch VM configuration to calculate accurate total storage and update display in service view
This commit is contained in:
@@ -115,11 +115,93 @@ class Show extends Component
|
|||||||
)->json()['data'] ?? null;
|
)->json()['data'] ?? null;
|
||||||
|
|
||||||
$this->vmStatus = $data;
|
$this->vmStatus = $data;
|
||||||
|
|
||||||
|
// Also fetch VM config to calculate accurate total storage
|
||||||
|
// The status endpoint's maxdisk is often unreliable
|
||||||
|
if ($this->vmStatus) {
|
||||||
|
$config = $proxmox->request(
|
||||||
|
'/nodes/' . $this->proxmoxServer->node->name . '/qemu/' . $this->proxmoxServer->vm_id . '/config'
|
||||||
|
)->json()['data'] ?? null;
|
||||||
|
|
||||||
|
if ($config) {
|
||||||
|
$totalDiskGB = $this->calculateTotalStorage($config);
|
||||||
|
if ($totalDiskGB > 0) {
|
||||||
|
// Store as bytes for consistency with other values
|
||||||
|
$this->vmStatus['total_disk_bytes'] = $totalDiskGB * 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->vmStatus = null;
|
$this->vmStatus = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate total storage from VM config (excluding cloud-init, EFI, TPM).
|
||||||
|
* Returns size in GB.
|
||||||
|
*/
|
||||||
|
protected function calculateTotalStorage(array $config): float
|
||||||
|
{
|
||||||
|
$totalSize = 0;
|
||||||
|
|
||||||
|
foreach ($config as $key => $value) {
|
||||||
|
// Check for attached drives (ide, sata, scsi, virtio)
|
||||||
|
if (preg_match('/^(ide|sata|scsi|virtio)(\d+)$/', $key)) {
|
||||||
|
// Skip excluded disks (cloud-init, EFI, TPM)
|
||||||
|
if ($this->isExcludedDisk($value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Skip CD-ROM drives
|
||||||
|
if (str_contains($value, 'media=cdrom')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$totalSize += $this->extractDiskSize($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a disk should be excluded (cloud-init, EFI, TPM).
|
||||||
|
*/
|
||||||
|
protected function isExcludedDisk(string $value): bool
|
||||||
|
{
|
||||||
|
$excludePatterns = ['cloudinit', 'vm-\d+-cloudinit', 'efidisk', 'tpmstate'];
|
||||||
|
foreach ($excludePatterns as $pattern) {
|
||||||
|
if (preg_match('/' . $pattern . '/i', $value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract disk size in GB from a disk configuration string.
|
||||||
|
*/
|
||||||
|
protected function extractDiskSize(string $value): float
|
||||||
|
{
|
||||||
|
// Example: cephpool:vm-100-disk-0,size=32G,cache=none,ssd=1
|
||||||
|
$parts = explode(',', $value);
|
||||||
|
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
if (preg_match('/^size=(\d+)([KMGT]?)$/i', $part, $sizeMatch)) {
|
||||||
|
$size = (float) $sizeMatch[1];
|
||||||
|
$unit = strtoupper($sizeMatch[2] ?? 'G');
|
||||||
|
|
||||||
|
switch ($unit) {
|
||||||
|
case 'K': return $size / (1024 * 1024);
|
||||||
|
case 'M': return $size / 1024;
|
||||||
|
case 'G':
|
||||||
|
case '': return $size;
|
||||||
|
case 'T': return $size * 1024;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$view = null;
|
$view = null;
|
||||||
|
|||||||
@@ -151,7 +151,14 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@if(isset($vmStatus['maxdisk']))
|
@if(isset($vmStatus['total_disk_bytes']))
|
||||||
|
<div class="flex items-center justify-between py-3 px-4 bg-background/50 rounded-xl">
|
||||||
|
<span class="text-color-muted text-sm font-medium flex items-center gap-2">
|
||||||
|
<x-ri-hard-drive-2-line class="size-4" /> Storage
|
||||||
|
</span>
|
||||||
|
<span class="font-bold text-color-base">{{ Illuminate\Support\Number::fileSize(bytes: $vmStatus['total_disk_bytes']) }}</span>
|
||||||
|
</div>
|
||||||
|
@elseif(isset($vmStatus['maxdisk']))
|
||||||
<div class="flex items-center justify-between py-3 px-4 bg-background/50 rounded-xl">
|
<div class="flex items-center justify-between py-3 px-4 bg-background/50 rounded-xl">
|
||||||
<span class="text-color-muted text-sm font-medium flex items-center gap-2">
|
<span class="text-color-muted text-sm font-medium flex items-center gap-2">
|
||||||
<x-ri-hard-drive-2-line class="size-4" /> Storage
|
<x-ri-hard-drive-2-line class="size-4" /> Storage
|
||||||
|
|||||||
Reference in New Issue
Block a user