oldVmId === '') { Log::info('RebuildDeleteOldVmJob: nothing to delete (oldVmId empty)'); return; } $vm = ModuleVmware::find($this->moduleVmwareId); if (!$vm) { Log::warning('RebuildDeleteOldVmJob: ModuleVmware vanished, skipping', [ 'module_vmware_id' => $this->moduleVmwareId, ]); return; } if ((string) $vm->vmware_id === $this->oldVmId) { // DB swap never happened — refuse to delete the live VM. Log::error('RebuildDeleteOldVmJob: ABORT — module_vmware still references oldVmId', [ 'module_vmware_id' => $this->moduleVmwareId, 'old_vm_id' => $this->oldVmId, ]); return; } $vcenter = VCenterModel::find($vm->vcenter_id); if (!$vcenter || !$vCenter->loginServer($vcenter)) { Log::error('RebuildDeleteOldVmJob: cannot login to vCenter', [ 'old_vm_id' => $this->oldVmId, ]); return; } try { $vCenter->PowerOffVirtualMachine($this->oldVmId); $res = $vCenter->DeleteVirtualMachine($this->oldVmId); Log::info('RebuildDeleteOldVmJob: old VM deleted', [ 'old_vm_id' => $this->oldVmId, 'result' => $res, ]); (new Telegram)->SendRebuildStepNotification($vm->name ?? '', $vm->ip ?? '', 'Xoá VM cũ', true); } catch (Throwable $e) { Log::error('RebuildDeleteOldVmJob: delete failed', [ 'old_vm_id' => $this->oldVmId, 'error' => $e->getMessage(), ]); // Re-throw so Laravel retries. throw $e; } } public function failed(Throwable $e): void { Log::error('RebuildDeleteOldVmJob: retries exhausted — manual cleanup required', [ 'module_vmware_id' => $this->moduleVmwareId, 'old_vm_id' => $this->oldVmId, 'error' => $e->getMessage(), ]); $vm = ModuleVmware::find($this->moduleVmwareId); (new Telegram)->SendRebuildStepNotification( $vm->name ?? "VM #{$this->moduleVmwareId}", $vm->ip ?? '', 'Xoá VM cũ', false, "Old VM {$this->oldVmId} cần xoá thủ công: " . $e->getMessage(), ); } }