Files
portal-api/app/Services/VirtualMachine/Rebuild/VmRebuildAddonService.php

91 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\VirtualMachine\Rebuild;
use App\DTOs\VirtualMachine\Rebuild\RebuildContext;
use App\Http\Services\vCenter as VCenterService;
use App\Models\ModuleVmware;
use App\Models\vCenter as VCenterModel;
use Illuminate\Support\Facades\Log;
use RuntimeException;
/**
* VmRebuildAddonService
*
* Reapplies CPU / RAM / Disk addons attached to the existing service onto
* the freshly cloned VM. Uses vCenter's existing Upgrade* primitives but is
* fully independent from VmAddonResolver / CreateVirtualMachineJob.
*/
final class VmRebuildAddonService
{
public function __construct(private readonly VCenterService $vCenter)
{
}
public function reinstall(RebuildContext $ctx): void
{
if ($ctx->newVmId === null) {
throw new RuntimeException('Rebuild addons: newVmId is null');
}
$vcenter = VCenterModel::find($ctx->vcenterId);
if (!$vcenter || !$this->vCenter->loginServer($vcenter)) {
throw new RuntimeException(
"Rebuild addons: cannot login to vCenter #{$ctx->vcenterId}"
);
}
// Resolve the totals we want the rebuilt VM to end up with.
// Base spec ensures CPU/RAM/Disk parity even if there are no addons.
$targetCpu = max($ctx->baseCpu, (int) ($ctx->addonTotals['cpu'] ?? 0));
$targetRam = max($ctx->baseRam, (int) ($ctx->addonTotals['ram'] ?? 0));
$targetDisk = max($ctx->baseDisk, (int) ($ctx->addonTotals['disk'] ?? 0));
Log::info('VmRebuildAddonService: applying specs', [
'module_vmware_id' => $ctx->moduleVmwareId,
'new_vm_id' => $ctx->newVmId,
'cpu' => $targetCpu,
'ram' => $targetRam,
'disk' => $targetDisk,
]);
if ($targetCpu > $ctx->baseCpu) {
$res = $this->vCenter->UpgradeCPUVirtualMachine($ctx->newVmId, $targetCpu);
$this->ensureOk($res, 'UpgradeCPU');
}
if ($targetRam > $ctx->baseRam) {
$res = $this->vCenter->UpgradeMemoryVirtualMachine($ctx->newVmId, $targetRam);
$this->ensureOk($res, 'UpgradeMemory');
}
if ($targetDisk > $ctx->baseDisk) {
// UpgradeDiskVirtualMachine expects a "product" with vmware_id —
// build a transient ModuleVmware-like object pointing at the new VM.
$shim = new ModuleVmware();
$shim->vmware_id = $ctx->newVmId;
$res = $this->vCenter->UpgradeDiskVirtualMachine($shim, $targetDisk);
$this->ensureOk($res, 'UpgradeDisk');
}
Log::info('VmRebuildAddonService: addons reinstalled', [
'module_vmware_id' => $ctx->moduleVmwareId,
'new_vm_id' => $ctx->newVmId,
]);
}
private function ensureOk(array|string $result, string $op): void
{
if (is_string($result)) {
throw new RuntimeException("Rebuild addons: {$op} returned '{$result}'");
}
if (($result['error'] ?? false)) {
throw new RuntimeException(
"Rebuild addons: {$op} failed — " . json_encode($result),
);
}
}
}