| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- <?php
- namespace ModulesGarden\ProxmoxAddon\App\Jobs\Vps;
- use Illuminate\Database\Capsule\Manager as DB;
- use MGProvision\Proxmox\v2\Api;
- use MGProvision\Proxmox\v2\models\Kvm;
- use MGProvision\Proxmox\v2\ProxmoxApiException;
- use MGProvision\Proxmox\v2\repository\ClusterResourcesRepository;
- use ModulesGarden\ProxmoxAddon\App\Enum\Vps\CustomField;
- use ModulesGarden\ProxmoxAddon\App\Events\Vps\QemuUpdateEvent;
- use ModulesGarden\ProxmoxAddon\App\Events\Vps\VmCreatedEvent;
- use ModulesGarden\ProxmoxAddon\App\Factory\Ssh2Factory;
- use ModulesGarden\ProxmoxAddon\App\Models\CloudInitScript;
- use ModulesGarden\ProxmoxAddon\App\Models\TaskHistory;
- use ModulesGarden\ProxmoxAddon\App\Models\VmIpAddress;
- use ModulesGarden\ProxmoxAddon\App\Providers\SnippetProvider;
- use ModulesGarden\ProxmoxAddon\App\Repositories\ServerConfigurationRepository;
- use ModulesGarden\ProxmoxAddon\App\Services\CloudInitScriptConveter;
- use ModulesGarden\ProxmoxAddon\App\Services\Vps\ProductService;
- use ModulesGarden\ProxmoxAddon\App\Services\Vps\UserService;
- use ModulesGarden\ProxmoxAddon\App\Enum\Vps\ConfigurableOption;
- use function ModulesGarden\ProxmoxAddon\Core\Helper\fire;
- class CloneQemuJob extends BaseJob
- {
- use ProductService;
- use UserService;
- public function handle()
- {
- $this->initParams();
- $this->initServices();
- $this->setHostingId($this->getWhmcsParamByKey("serviceid"));
- //create task validation
- if ($this->isDone())
- {
- if(!$this->vm()->isRunning()){
- $this->deleteNetwork();
- }
- if($this->configuration()->isAdditionalDisk() && !$this->additionalDiskService->hasDisk() ){
- $this->additionalDiskService->create();
- }
- fire(new QemuUpdateEvent($this->vm()));
- try{
- if($this->agentService->isEnabled()){
- if(!$this->vm()->isRunning()){
- $this->log->info(sprintf("VM %s - Start", $this->vm()->getVmid()));
- $this->vm()->start();
- $this->sleep(5);
- return false;
- }
- $this->vm()->agent()->ping();
- $this->agentService ->getUserAndUpdate();
- $this->agentService ->passwordUpdate();
- $this->agentService ->configureNetwork();
- }
- }catch (ProxmoxApiException $ex){
- if(preg_match("/not running/", $ex->getMessage())){
- $this->log->info($ex->getMessage());
- }else{
- $this->log->error($ex->getMessage());
- }
- //sleep
- $this->sleep(5);
- return false;
- }
- fire(new VmCreatedEvent($this->vm()));
- return true;
- }
- elseif ($this->isTaskRunning())
- {
- //sleep
- $this->sleep(5);
- return false;
- }
- try
- {
- Api::beginTransaction();
- DB::beginTransaction();
- $osTemplate = $this->getWhmcsConfigOption(ConfigurableOption::OS_TEMPLATE, $this->configuration()->getOsTemplate() );
- //Support for configurable options i.e vmname|OS Name
- if (is_string($osTemplate) && !preg_match('/\//', $osTemplate))
- {
- $templateNode = $this->getNode()->getNode();
- $clusterRepository = new ClusterResourcesRepository();
- $clusterRepository->setApi($this->api());
- if(!$this->configuration()->isOsTemplatesInAllNodes()){
- $clusterRepository->findByNodes([$templateNode]);
- }
- $clusterRepository->findKvmTemplate();
- foreach ($clusterRepository->fetch() as $resurce)
- {
- if ($resurce->getName() == $osTemplate)
- {
- $templateVmid = $resurce->getVmid();
- $templateNode = $resurce->getNode();
- break;
- }
- }
- if (!$templateVmid)
- {
- throw new \Exception(sprintf("Unable to find KVM template: %s on node: %s", $osTemplate, $templateNode ));
- }
- //Support for configurable options like nodename/vmid|OS Name
- }
- else
- {
- if (preg_match('/\//', $osTemplate))
- {
- list($templateNode, $templateVmid) = explode("/", $osTemplate);
- }
- }
- //node
- $node = $this->getWhmcsCustomField(CustomField::NODE) ? $this->getWhmcsCustomField(CustomField::NODE) :$this->getNode()->getNode();
- //vmid
- $vmid = $this->nextVmid();
- $this->customFieldUpdate("vmid", $vmid);
- $this->customFieldUpdate("node", $node);
- //init container
- $container = [
- "newid" => $vmid,
- "full" => $this->configuration()->getCloneMode(),
- "target" => $node
- ];
- //description
- if ($this->configuration()->getDescription())
- {
- $container['description'] = $this->containerService->description();
- }
- //hostname
- $hostname = $this->containerService->hostname();
- if ($hostname)
- {
- $container['name'] = $hostname;
- }
- //Storage
- if (!$this->configuration()->isCloneOnTheSameStorage() && $this->configuration()->getDiskStorage() && $this->configuration()->getCloneMode() == "1")
- {
- $container['storage'] = $this->configuration()->getDiskStorage();
- }
- //pool
- if ($this->configuration()->getPool())
- {
- $container['pool'] = $this->configuration()->getPool();
- }
- //bwlimit
- if($this->configuration()->getBwLimit()){
- $container['bwlimit'] = $this->configuration()->getBwLimit();
- }
- //Create
- $template = new Kvm($templateNode, $templateVmid);
- $template->setApi($this->api());
- $taskId = $template->cloneVm($container);
- DB::commit();
- }
- catch (\Exception $ex)
- {
- DB::rollBack();
- Api::commit();
- $this->failed($ex->getMessage());
- throw $ex;
- }
- //task history
- $task = new TaskHistory();
- $task->fill([
- 'hosting_id' => $this->getWhmcsParamByKey("serviceid"),
- 'upid' => $taskId,
- 'name' => sprintf("VM %s - %s", $vmid, "Clone"),
- 'vmid' => $template->getVmid(),
- 'node' => $template->getNode(),
- 'status' => 0
- ])->save();
- //save task id
- $this->putModelDataAndSave(["taskId" => $taskId, "node" => $template->getNode(), "templateNode" => $templateNode]);
- //sleep
- $this->sleep();
- return false;
- }
- private function deleteNetwork(){
- $deleteNetwork = [];
- foreach ($this->vm()->getNetworkDevices() as $networkDevice){
- if(VmIpAddress::ofHostingId($this->getWhmcsParamByKey('serviceid'))->ofNet($networkDevice->getId())->count()){
- continue;
- }
- $deleteNetwork[]=$networkDevice->getId();
- }
- if(!empty($deleteNetwork)){
- $this->vm()->deleteConfig(implode(",",$deleteNetwork));
- }
- }
- }
|