91 lines
3.2 KiB
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),
|
|
);
|
|
}
|
|
}
|
|
}
|