fix: implement multiqueue support for network interfaces and update UI documentation
This commit is contained in:
@@ -528,6 +528,9 @@ class Network extends Component
|
|||||||
$this->interfaceSelections = collect($this->interfaces)
|
$this->interfaceSelections = collect($this->interfaces)
|
||||||
->map(fn ($meta) => $meta['model'] ?? 'virtio')
|
->map(fn ($meta) => $meta['model'] ?? 'virtio')
|
||||||
->toArray();
|
->toArray();
|
||||||
|
$this->interfaceMultiqueues = collect($this->interfaces)
|
||||||
|
->map(fn ($meta) => $meta['queues'] ?? 1)
|
||||||
|
->toArray();
|
||||||
$this->selectedInterface = array_key_first($this->interfaces) ?? 'net0';
|
$this->selectedInterface = array_key_first($this->interfaces) ?? 'net0';
|
||||||
$this->interfaceType = $this->interfaceSelections[$this->selectedInterface] ?? 'virtio';
|
$this->interfaceType = $this->interfaceSelections[$this->selectedInterface] ?? 'virtio';
|
||||||
$this->canRemoveInterfaces = count($this->interfaces) > 1;
|
$this->canRemoveInterfaces = count($this->interfaces) > 1;
|
||||||
@@ -547,6 +550,69 @@ class Network extends Component
|
|||||||
$this->interfaceType = $this->interfaceSelections[$name];
|
$this->interfaceType = $this->interfaceSelections[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateMultiqueue(string $name, int $queues): void
|
||||||
|
{
|
||||||
|
if (!isset($this->interfaces[$name])) {
|
||||||
|
$this->notify('Network device not found.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cpuCores = $this->getCpuCores();
|
||||||
|
$queues = max(1, min($queues, $cpuCores));
|
||||||
|
|
||||||
|
$this->interfaceMultiqueues[$name] = $queues;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$proxmox = new Proxmox;
|
||||||
|
$currentConfig = $proxmox->request('/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/config')->json()['data'] ?? [];
|
||||||
|
$currentValue = (string) ($currentConfig[$name] ?? '');
|
||||||
|
|
||||||
|
if (empty($currentValue)) {
|
||||||
|
$this->notify('Network device configuration not found.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$segments = array_filter(array_map('trim', explode(',', $currentValue)));
|
||||||
|
$newSegments = [];
|
||||||
|
$queuesFound = false;
|
||||||
|
|
||||||
|
foreach ($segments as $segment) {
|
||||||
|
if (!str_contains($segment, '=')) {
|
||||||
|
$newSegments[] = $segment;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
[$key, $value] = array_map('trim', explode('=', $segment, 2));
|
||||||
|
$lowerKey = strtolower($key);
|
||||||
|
|
||||||
|
if ($lowerKey === 'queues') {
|
||||||
|
$queuesFound = true;
|
||||||
|
$newSegments[] = 'queues=' . $queues;
|
||||||
|
} else {
|
||||||
|
$newSegments[] = $key . '=' . $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If queues parameter wasn't found, add it
|
||||||
|
if (!$queuesFound) {
|
||||||
|
$newSegments[] = 'queues=' . $queues;
|
||||||
|
}
|
||||||
|
|
||||||
|
$newValue = implode(',', $newSegments);
|
||||||
|
|
||||||
|
$proxmox->request(
|
||||||
|
'/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/config',
|
||||||
|
'put',
|
||||||
|
[$name => $newValue]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->interfaces[$name]['queues'] = $queues;
|
||||||
|
$this->notify('Multiqueue updated for ' . strtoupper($name) . ' to ' . $queues . ' queues.', 'success');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->notify('Failed to update multiqueue: ' . $e->getMessage(), 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getCanAddInterfaceProperty(): bool
|
public function getCanAddInterfaceProperty(): bool
|
||||||
{
|
{
|
||||||
return count($this->interfaces) < 5;
|
return count($this->interfaces) < 5;
|
||||||
|
|||||||
@@ -226,6 +226,9 @@
|
|||||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||||
<span class="font-semibold text-base/90">Remove Device:</span> Removes a network interface from the VM configuration. Changes take effect after the VM is restarted.
|
<span class="font-semibold text-base/90">Remove Device:</span> Removes a network interface from the VM configuration. Changes take effect after the VM is restarted.
|
||||||
</p>
|
</p>
|
||||||
|
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||||
|
<span class="font-semibold text-base/90">Multiqueue:</span> Enables the network adapter to distribute packet processing across multiple CPU cores. Set this value equal to your vCPU count for optimal performance in multi-core VMs. This improves network throughput significantly.
|
||||||
|
</p>
|
||||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||||
The "Synced" indicator shows when your local changes match the server configuration; "Unsynced" indicates modifications that need to be saved.
|
The "Synced" indicator shows when your local changes match the server configuration; "Unsynced" indicates modifications that need to be saved.
|
||||||
</p>
|
</p>
|
||||||
@@ -249,6 +252,7 @@
|
|||||||
<th class="px-4 py-3">Adapter</th>
|
<th class="px-4 py-3">Adapter</th>
|
||||||
<th class="px-4 py-3">MAC Address</th>
|
<th class="px-4 py-3">MAC Address</th>
|
||||||
<th class="px-4 py-3 text-center">MTU</th>
|
<th class="px-4 py-3 text-center">MTU</th>
|
||||||
|
<th class="px-4 py-3 text-center">Multiqueue</th>
|
||||||
<th class="px-4 py-3 text-center">Actions</th>
|
<th class="px-4 py-3 text-center">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -267,6 +271,25 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3 font-mono text-xs text-base/70">{{ strtoupper($interfaces[$name]['mac'] ?? 'N/A') }}</td>
|
<td class="px-4 py-3 font-mono text-xs text-base/70">{{ strtoupper($interfaces[$name]['mac'] ?? 'N/A') }}</td>
|
||||||
<td class="px-4 py-3 text-center text-sm text-base/70">{{ $interfaces[$name]['mtu'] ?? 'Default' }}</td>
|
<td class="px-4 py-3 text-center text-sm text-base/70">{{ $interfaces[$name]['mtu'] ?? 'Default' }}</td>
|
||||||
|
<td class="px-4 py-3 text-center">
|
||||||
|
<div x-data="{
|
||||||
|
queues: {{ $interfaces[$name]['queues'] ?? 1 }},
|
||||||
|
maxQueues: {{ $this->getCpuCores() }},
|
||||||
|
updateQueues() {
|
||||||
|
this.queues = Math.max(1, Math.min(this.queues, this.maxQueues));
|
||||||
|
$wire.updateMultiqueue('{{ $name }}', this.queues);
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
<input type="number"
|
||||||
|
x-model.number="queues"
|
||||||
|
@blur="updateQueues()"
|
||||||
|
@keydown.enter="updateQueues()"
|
||||||
|
min="1"
|
||||||
|
:max="maxQueues"
|
||||||
|
class="bg-background border border-neutral rounded-md px-3 py-2 text-sm text-center focus:outline-none focus:ring-2 focus:ring-secondary w-20"
|
||||||
|
:title="'Number of queues (1-' + maxQueues + ')'">
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td class="px-4 py-3 text-center">
|
<td class="px-4 py-3 text-center">
|
||||||
<div class="flex items-center justify-center gap-2">
|
<div class="flex items-center justify-center gap-2">
|
||||||
<button wire:click="toggleInterfaceLink('{{ $name }}')"
|
<button wire:click="toggleInterfaceLink('{{ $name }}')"
|
||||||
@@ -319,6 +342,9 @@
|
|||||||
</x-button.primary>
|
</x-button.primary>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-base/50 mt-2">VirtIO provides the best performance; legacy adapters (E1000, Realtek, PCnet, VMware) improve compatibility.</p>
|
<p class="text-xs text-base/50 mt-2">VirtIO provides the best performance; legacy adapters (E1000, Realtek, PCnet, VMware) improve compatibility.</p>
|
||||||
|
<p class="text-xs text-base/50 mt-1">
|
||||||
|
<strong>Multiqueue:</strong> Allows the network adapter to use multiple CPU cores for packet processing. Set to the number of vCPU cores (max {{ $this->getCpuCores() }}) for best performance. Higher values improve throughput for multi-core VMs.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@foreach($server->ipAddresses as $network)
|
@foreach($server->ipAddresses as $network)
|
||||||
|
|||||||
Reference in New Issue
Block a user