Add VM rebuild pipeline with isolated job chain and admin log API
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
<?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),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user