CloneQemuJob.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. namespace ModulesGarden\ProxmoxAddon\App\Jobs\Cloud;
  3. use Illuminate\Database\Capsule\Manager as DB;
  4. use MGProvision\Proxmox\v2\Api;
  5. use MGProvision\Proxmox\v2\models\Kvm;
  6. use MGProvision\Proxmox\v2\models\Lxc;
  7. use MGProvision\Proxmox\v2\ProxmoxApiException;
  8. use ModulesGarden\ProxmoxAddon\App\Events\Cloud\QemuUpdateEvent;
  9. use ModulesGarden\ProxmoxAddon\App\Events\Cloud\VmCreatedEvent;
  10. use ModulesGarden\ProxmoxAddon\App\Jobs\BaseJob;
  11. use ModulesGarden\ProxmoxAddon\App\Models\TaskHistory;
  12. use ModulesGarden\ProxmoxAddon\App\Models\VmIpAddress;
  13. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\AdditionalDiskService;
  14. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\AgentService;
  15. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\ContainerService;
  16. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\ProductService;
  17. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\UserService;
  18. use ModulesGarden\ProxmoxAddon\App\Services\EmailService;
  19. use function ModulesGarden\ProxmoxAddon\Core\Helper\fire;
  20. use function ModulesGarden\ProxmoxAddon\Core\Helper\sl;
  21. class CloneQemuJob extends BaseJob
  22. {
  23. use ProductService;
  24. use UserService;
  25. /**
  26. * @var \ModulesGarden\ProxmoxAddon\App\Services\Cloud\ContainerService
  27. */
  28. protected $containerService;
  29. /**
  30. * @var Kvm|Lxc
  31. */
  32. protected $vm;
  33. /**
  34. * @var AdditionalDiskService
  35. */
  36. protected $additionalDiskService;
  37. protected function initServices()
  38. {
  39. $this->emailService = new EmailService();
  40. $this->containerService = new ContainerService();
  41. $this->agentService = new AgentService();
  42. $this->additionalDiskService = new AdditionalDiskService();
  43. }
  44. public function handle()
  45. {
  46. $this->initParams();
  47. $this->initServices();
  48. //create task validation
  49. if ($this->isDone())
  50. {
  51. $this->initVm();
  52. if(!sl('Vm')->getVm()->isRunning()){
  53. $this->deleteNetwork();
  54. }
  55. if($this->getModelData()['additionalDiskSize1'] && !$this->additionalDiskService->hasDisk()){
  56. $this->additionalDiskService->create($this->getModelData());
  57. }
  58. logModuleCall(
  59. 'proxmoxCloud',
  60. __FUNCTION__,
  61. $this->getModelData(),
  62. 'Debug',
  63. $this->getVmModel()
  64. );
  65. fire(new QemuUpdateEvent($this->getVmModel(), $this->getModelData()));
  66. try{
  67. if($this->agentService->isEnabled()){
  68. if(!sl('Vm')->getVm()->isRunning()){
  69. $this->log->info(sprintf("VM %s - Start", sl('Vm')->getVm()->getVmid()));
  70. sl('Vm')->getVm()->start();
  71. $this->sleep(5);
  72. return false;
  73. }
  74. sl('Vm')->getVm()->agent()->ping();
  75. $this->agentService ->passwordUpdate();
  76. $this->agentService ->configureNetwork();
  77. }
  78. }catch (ProxmoxApiException $ex){
  79. if(preg_match("/not running/", $ex->getMessage())){
  80. $this->log->info($ex->getMessage());
  81. }else{
  82. $this->log->error($ex->getMessage());
  83. }
  84. //sleep
  85. $this->sleep(5);
  86. return false;
  87. }
  88. fire(new VmCreatedEvent($this->getVmModel()));
  89. return true;
  90. }
  91. elseif ($this->isTaskRunning())
  92. {
  93. //sleep
  94. $this->sleep(5);
  95. return false;
  96. }
  97. try
  98. {
  99. Api::beginTransaction();
  100. DB::beginTransaction();
  101. $osTemplate = $this->getModelData()['osTemplate'];
  102. //Support for configurable options i.e vmname|OS Name
  103. if (preg_match('/\//', $osTemplate))
  104. {
  105. list($templateNode, $templateVmid) = explode("/", $osTemplate);
  106. }
  107. //vmid
  108. $vmid = $this->nextVmid();
  109. $this->getVmModel();
  110. $this->vmModel->vmid = $vmid;
  111. $this->vmModel->save();
  112. //init container
  113. $container = [
  114. "newid" => $vmid,
  115. "full" => $this->configuration()->getCloneMode(),
  116. "target" => $this->vmModel->node
  117. ];
  118. //description
  119. $container['description'] = $this->getModelData()['description'];
  120. //hostname
  121. $container['name'] = $this->getModelData()['name'];
  122. //Storage
  123. if (!$this->configuration()->isCloneOnTheSameStorage() && $this->configuration()->getDiskStorage() && $this->configuration()->getCloneMode() == "1")
  124. {
  125. $container['storage'] = $this->configuration()->getDiskStorage();
  126. }
  127. //pool
  128. if ($this->configuration()->getPool())
  129. {
  130. $container['pool'] = $this->configuration()->getPool();
  131. }
  132. //bwlimit
  133. if($this->configuration()->getBwLimit()){
  134. $container['bwlimit'] = $this->configuration()->getBwLimit();
  135. }
  136. //no start
  137. $container['start'] = 0;
  138. //Create
  139. $template = new Kvm($templateNode, $templateVmid);
  140. $template->setApi($this->api());
  141. $taskId = $template->cloneVm($container);
  142. DB::commit();
  143. }
  144. catch (\Exception $ex)
  145. {
  146. DB::rollBack();
  147. Api::commit();
  148. $this->failed($ex->getMessage());
  149. throw $ex;
  150. }
  151. //task history
  152. $task = new TaskHistory();
  153. $task->fill([
  154. 'hosting_id' => $this->getWhmcsParamByKey("serviceid"),
  155. 'upid' => $taskId,
  156. 'name' => sprintf("VM %s - %s", $vmid, "Clone"),
  157. 'vmid' => $template->getVmid(),
  158. 'node' => $template->getNode(),
  159. 'status' => 0
  160. ])->save();
  161. //save task id
  162. $this->putModelDataAndSave(["taskId" => $taskId, "node" => $template->getNode(), "templateNode" => $templateNode]);
  163. //sleep
  164. $this->sleep();
  165. return false;
  166. }
  167. private function deleteNetwork(){
  168. $deleteNetwork = [];
  169. foreach (sl('Vm')->getVm()->getNetworkDevices() as $networkDevice){
  170. if(VmIpAddress::ofHostingId($this->getWhmcsParamByKey('serviceid'))
  171. ->ofNet($networkDevice->getId())
  172. ->ofVmId(sl('Vm')->getVmModel()->id)
  173. ->count()){
  174. continue;
  175. }
  176. $deleteNetwork[]=$networkDevice->getId();
  177. }
  178. if(!empty($deleteNetwork)){
  179. sl('Vm')->getVm()->deleteConfig(implode(",",$deleteNetwork));
  180. }
  181. }
  182. }