CloneQemuJob.php 7.0 KB

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