vmModel = VmModel::ofHostingId($this->model->rel_id)->where('id', $this->model->custom_id)->firstOrFail(); } public function initVm(){ $vm = (new VmFactory())->fromVmModel($this->getVmModel()); sl('Vm')->setVm($vm); sl('Vm')->setVmModel($this->getVmModel()); return $this; } public function initParams() { if (!$this->model->rel_id) { new \InvalidArgumentException(sprintf("Job model: #%s rel_id cannot be empty", $this->model->id)); } if (!function_exists('ModuleBuildParams')) { require_once ModuleConstants::getFullPathWhmcs('includes') . DIRECTORY_SEPARATOR . "modulefunctions.php"; } $this->params = \ModuleBuildParams($this->model->rel_id); sl("whmcsParams")->setParams($this->params); if(function_exists('\ModulesGarden\Servers\ProxmoxCloudVps\Core\Helper\sl')){ \ModulesGarden\Servers\ProxmoxCloudVps\Core\Helper\sl("whmcsParams")->setParams($this->params); } $this->setHostingId($this->params['serviceid']); return $this; } protected function sleep($seconds = 60) { $this->model->setWaiting(); $this->model->setRetryAfter(date("Y-m-d H:i:s", strtotime("+{$seconds} seconds"))); $this->model->increaseRetryCount(); } protected function vmidExistInWhmcs($vmid) { //vps $cfv = 'tblcustomfieldsvalues'; $cfn = 'tblcustomfields'; $h = 'tblhosting'; $query = DB::table($cfv) ->rightJoin($cfn, "{$cfn}.id", "=", "{$cfv}.fieldid") ->leftJoin($h, "{$h}.id", "=", "{$cfv}.relid") ->where("{$cfn}.fieldname", "like", "vmid%") ->where("{$cfv}.value", $vmid) ->whereIn("{$h}.domainstatus", ['Active', "Suspended"]); if ($query->count()) { return true; } //cloud try { $query = VmModel::where("vmid", $vmid); return $query->count() > 0; } catch (\Exception $ex) { // table does not exist } return false; } protected function findFreeVmid($vmid) { for ($i = $vmid; $i <= 1000000; $i++) { if ($this->vmidExistInWhmcs($i)) { continue; } try { $res = $this->api()->get("/cluster/nextid", ['vmid' => $i]); } catch (\Exception $ex) { continue; } if ($res == $i) { return $i; } } throw new \Exception("Unable to obtain vmid"); } protected function isVmRange() { if (RangeVm::ofServerId($this->getWhmcsParamByKey("serverid"))->count()) { return true; } return Configuration::where("setting", "proxmoxVPSMinimumVMID")->count() > 0; } protected function nextVmid() { $data = $this->api()->get("/cluster/nextid", []); $vmid = (int)$data ? (int)$data : 100; $vmid = $this->findFreeVmid($vmid); if ($this->isVmRange()) { $rageVm = new RangeVmRepository($this->getWhmcsParamByKey('serverid')); if (!$rageVm->has() && !$rageVm->getMin()) { return $vmid; } else { if (!$rageVm->getMax() && $rageVm->getMin()) { $from = (int)$rageVm->getMin(); $to = (int)$rageVm->getMin() * 100; } else { $from = (int)$rageVm->getMin(); $to = (int)$rageVm->getMax(); } } for ($i = $from; $i <= $to; $i++) { try { if ($this->vmidExistInWhmcs($i)) { continue; } $res = $this->api()->get("/cluster/nextid", ['vmid' => $i]); if ((int)$res == $i) { $vmID = $i; break; } } catch (\Exception $ex) { continue; } } if (!$vmID) { throw new \Exception("VM Ranges have been exited for this server. Please setup VM Ranges", 321); } } return $vmID ? $vmID : $vmid; } protected function createTaskHistory($taskId, $action) { $type = str_replace(["qemu", "lxc"], ["VM", "CT"], $this->getVmModel()->virtualization); $task = new TaskHistory(); $task->fill([ 'hosting_id' => $this->getWhmcsParamByKey("serviceid"), 'upid' => $taskId, 'name' => sprintf("%s %s - %s", $type, $this->getVmModel()->vmid, $action), 'vmid' => $this->getVmModel()->vmid, 'node' => $this->getVmModel()->node, 'status' => 0 ])->save(); } protected function getModelData() { return unserialize($this->model->data); } protected function putModelDataAndSave(array $newData) { $data = $this->getModelData(); $data += $newData; $this->setModelDataAndSave($data); return $this; } protected function setModelDataAndSave(array $data) { $this->model->data = serialize($data); $this->model->save(); return $this; } /** * @return \MGProvision\Proxmox\v2\models\Task * @throws \MGProvision\Proxmox\v2\ProxmoxApiException */ protected function getTask() { $taskId = $this->getModelData()['taskId']; //Init API service if($this->getModelData()['templateNode']){ $node = new Node($this->getModelData()['templateNode']); }else{ $node = new Node($this->getModelData()['node']); } $node->setApi($this->api()); return $node->task($taskId); } protected function isTask() { return !is_null($this->getModelData()['taskId']); } protected function isDone() { $taskId = $this->getModelData()['taskId']; if (!$taskId || !$this->getModelData()['node']) { return false; } $task = $this->getTask(); if ($task->getStatus() == "running") { $this->log->success(sprintf("Waiting to finish. Task Id %s Node: %s ", $task->getUpid(), $task->getNode())); return false; } //Failed if ($task->getExitstatus() && $task->getExitstatus() != "OK") { $this->log->error($task->getExitstatus()); $this->failed($task->getExitstatus()); $data = $this->getModelData(); unset($data['taskId'], $data['node']); $this->setModelDataAndSave($data); return false; } return true; } protected function isTaskRunning() { return $this->isTask() && $this->getTask()->isRunning(); } protected function isFailed() { $task = $this->getTask(); return $task->getExitstatus() && $task->getExitstatus() != "OK"; } protected function failed($error) { if ((int)$this->model->retry_count != 21) { return; } if (!preg_match("/Create/", $this->model->job) || preg_match("/Clone/", $this->model->job)) { return; } //create new entery on to do list if ($this->configuration()->isToDoList()) { $title = sprintf('Creation Failed - Service ID: %s', $this->getWhmcsParamByKey('serviceid')); if (ToDoList::ofTitle($title)->pending()->count()) { return; } $entity = new ToDoList(); $entity->fill( [ 'date' => date("Y-m-d H:i:s"), "duedate" => date("Y-m-d H:i:s"), 'title' => $title, "status" => "Pending", "description" => $error, "admin" => 0, ] ); $entity->save(); } //send admin message if ($this->configuration()->getServiceCreationFailedTemplateId()) { //init email template $this->emailService->template($this->configuration()->getServiceCreationFailedTemplateId()); //check if already send $description = printf('Email Sent to Admin (%s) - Service ID: %s', $this->emailService->getVars()['messagename'], $this->getWhmcsParamByKey('serviceid')); if (ActivityLog::ofDescription($description)->today()->count() > 0) { return; } //email vars global $customadminpath; $adminDir = $customadminpath ? $customadminpath : "admin"; $adminAreaLink = $GLOBALS['CONFIG']['SystemURL'] . "/{$adminDir}"; $hosting = $GLOBALS['CONFIG']['SystemURL'] . "/{$adminDir}/clientsservices.php?id=" . $this->getWhmcsParamByKey('serviceid'); $emailVars = [ "client_id" => $this->getWhmcsParamByKey('clientsdetails')['id'], "service_id" => $this->getWhmcsParamByKey('serviceid'), "service_product" => "{$hosting}", "service_domain" => $this->getWhmcsParamByKey('domain'), "error_msg" => $error, "whmcs_admin_link" => "{$adminAreaLink}", ]; $this->emailService->vars($emailVars)->sendToAdmin(); logActivity($description); } } /** * @return \ModulesGarden\ProxmoxAddon\App\Models\Job: */ protected function getParentModel() { if (is_null($this->model->parent_id)) { throw new \InvalidArgumentException("The Parent Id is not valid"); } if ($this->parent) { return $this->parent; } return $this->parent = \ModulesGarden\ProxmoxAddon\App\Models\Job::ofId($this->model->parent_id)->firstOrFail(); } protected function getParentModelData() { return unserialize($this->getParentModel()->data); } }