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);
}
}