VmUpdateProvider.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <?php
  2. namespace ModulesGarden\Servers\ProxmoxCloudVps\App\UI\VmUpdate\Providers;
  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\MountPoint;
  7. use MGProvision\Proxmox\v2\models\NetworkDeviceKvm;
  8. use MGProvision\Proxmox\v2\repository\FileRepository;
  9. use MGProvision\Proxmox\v2\repository\StorageRepository;
  10. use ModulesGarden\ProxmoxAddon\App\Events\Cloud\LxcUpdateEvent;
  11. use ModulesGarden\ProxmoxAddon\App\Events\Cloud\QemuUpdateEvent;
  12. use ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\Agent\ChangePasswordJob;
  13. use ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\Agent\ConfigureNetworkJob;
  14. use ModulesGarden\ProxmoxAddon\App\Models\VirtualInterface;
  15. use ModulesGarden\ProxmoxAddon\App\Models\VmIpAddress;
  16. use ModulesGarden\ProxmoxAddon\App\Models\VmModel;
  17. use ModulesGarden\ProxmoxAddon\App\Services\ApiService;
  18. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\AdditionalDiskService;
  19. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\AdditionalMountPointService;
  20. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\AgentService;
  21. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\IpSetIpFilterService;
  22. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\NetworkService;
  23. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\ProductService;
  24. use ModulesGarden\ProxmoxAddon\App\Services\Cloud\VirtualInterfaceConverter;
  25. use ModulesGarden\Servers\ProxmoxCloudVps\App\UI\VmCreate\Providers\VmCreateProvider;
  26. use ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\ResponseTemplates\HtmlDataJsonResponse;
  27. use function ModulesGarden\ProxmoxAddon\Core\Helper\fire;
  28. use function ModulesGarden\ProxmoxAddon\Core\Helper\queue;
  29. use function ModulesGarden\Servers\ProxmoxCloudVps\Core\Helper\sl;
  30. class VmUpdateProvider extends VmCreateProvider
  31. {
  32. use ApiService;
  33. use ProductService;
  34. /**
  35. * VmUpdateProvider constructor.
  36. */
  37. public function __construct()
  38. {
  39. $this->model = VmModel::class;
  40. }
  41. public function read()
  42. {
  43. $this->vmModel = \ModulesGarden\ProxmoxAddon\Core\Helper\sl('Vm')->getVmModel();
  44. $this->data = $this->vmModel->toArray();
  45. $vm = \ModulesGarden\ProxmoxAddon\Core\Helper\sl('Vm')->getVm();
  46. $config = $vm->config();
  47. $this->data['password'] = $this->vmModel->getPassword();
  48. $this->data['description'] = html_entity_decode($config['description']);
  49. $this->data['searchdomain'] = $config['searchdomain'];
  50. $ns = explode(" ",$config['nameserver']);
  51. $this->data['nameserver[0]'] = $ns[0];
  52. $this->data['nameserver[1]'] = $ns[1];
  53. /**
  54. * @deprecated
  55. $this->data['ipv4'] = $this->vmModel->ipv4Addresses->count();
  56. $this->data['ipv6'] = $this->vmModel->ipv6Addresses->count();
  57. */
  58. //Boot order
  59. if($vm instanceof Kvm){
  60. $bootOrder = $vm->getBootOrder();
  61. logModuleCall(
  62. 'proxmoxCloud',
  63. __FUNCTION__,
  64. $bootOrder,
  65. 'Debug',
  66. $this->data['BootDevice']
  67. );
  68. $this->data['bootOrder0'] = $bootOrder[0];
  69. $this->data['bootOrder1'] = $bootOrder[1];
  70. $this->data['bootOrder2'] = $bootOrder[2];
  71. $options = [
  72. 0 => sl("lang")->tr("None"),
  73. "c" => sl("lang")->tr("Disk"),
  74. "d" => sl("lang")->tr("CD-ROM"),
  75. "n" => sl("lang")->tr("Network"),
  76. ];
  77. if(version_compare($this->api()->getVersion(), "6.3", '>=')
  78. && !in_array("c", (array) $bootOrder )){
  79. $cdrom = $vm->cdrom();
  80. $nd = $vm->getNetworkDevices();
  81. $options = [
  82. 0 => sl("lang")->tr("None"),
  83. $vm->getMasterHardDisk()->getId() => sl("lang")->tr("Disk"),
  84. ];
  85. if($cdrom['bus']){
  86. $options[$cdrom['bus']] = sl("lang")->tr("CD-ROM");
  87. }
  88. if($nd[0] instanceof NetworkDeviceKvm){
  89. $options[$nd[0]->getId()] = sl("lang")->tr("Network");
  90. }
  91. }
  92. $this->availableValues['bootOrder0'] = $options;
  93. $this->availableValues['bootOrder1'] = $options;
  94. $this->availableValues['bootOrder2'] = $options;
  95. }
  96. //sshkeys
  97. $this->data['sshkeys'] = rawurldecode($vm->config()['sshkeys']);
  98. //cpu Priority
  99. if($this->configuration()->hasCpuPriority()){
  100. for($i=1; $i<=5; $i++){
  101. $cpuunits = $this->configuration()->get('cpuunitsPriority'.$i);
  102. $cpulimit = $this->configuration()->get('cpulimitPriority'.$i);
  103. if($this->vmModel->cpulimit >= $cpulimit){
  104. $this->data['cpuPriority'] = $i;
  105. }
  106. if($this->vmModel->cpuunits >= $cpuunits){
  107. $this->data['cpuPriority'] = $i;
  108. }
  109. }
  110. }
  111. //iso
  112. if ($this->configuration()->isQemu() && $this->configuration()->isPermissionIsoImage()) {
  113. $this->availableValues['iso'] = ["none" => sl('lang')->abtr("None")];
  114. $storageRepository = new StorageRepository();
  115. $storageRepository->findByNodes([$vm->getNode()])
  116. ->findEnabed();
  117. $storages = $storageRepository->fetchAsArray();
  118. $isoRepository = new FileRepository();
  119. $isoRepository->findByNodes([$vm->getNode()])
  120. ->findByStorages($storages);
  121. $isoRepository->findIso();
  122. foreach ($isoRepository->fetch() as $entity) {
  123. if ($this->configuration()->isPermissionIsoImages() && !in_array($entity->getVolid(), $this->configuration()->getPermissionIsoImages())) {
  124. continue;
  125. }
  126. $this->availableValues['iso'][$entity->getVolid()] = $entity->getFriendlyName();
  127. }
  128. if( $vm->getCdRomRepository()->first()){
  129. $this->data['iso']= $vm->getCdRomRepository()->first()->getLocation();
  130. }
  131. }
  132. }
  133. public function update()
  134. {
  135. $this->vmModel = \ModulesGarden\ProxmoxAddon\Core\Helper\sl('Vm')->getVmModel();
  136. $vm = \ModulesGarden\ProxmoxAddon\Core\Helper\sl('Vm')->getVm();
  137. $this->networkService = new NetworkService();
  138. $networkService = new NetworkService();
  139. /**
  140. * @deprecated
  141. * $ipv4 = (int) $this->formData['ipv4'] - (int) $this->vmModel->ipv4Addresses->count();
  142. * $ipv6 = (int) $this->formData['ipv6'] - (int) $this->vmModel->ipv6Addresses->count();
  143. * $networkService->hasIp($ipv4, $ipv6, $this->vmModel->node);
  144. * $networkService->addIp($ipv4, $ipv6, $this->vmModel->node);
  145. * $networkService->unassignIpAddressesAndDeleteNetwork($ipv4, $ipv6);
  146. */
  147. //load data
  148. $this->getFormDataValues();
  149. if ($vm instanceof Kvm)
  150. {
  151. //iso
  152. if ($vm->cdrom())
  153. {
  154. $vm->updateCdrom($this->formData['iso']);
  155. }
  156. //Boot order
  157. $bootOrder = null;
  158. $order = [];
  159. for ($i = 0; $i <= 2; $i++)
  160. {
  161. if ($this->formData['bootOrder' . $i])
  162. {
  163. $bootOrder .= $this->formData['bootOrder' . $i];
  164. if(!in_array($this->formData['bootOrder' . $i],["c","d","n"])){
  165. $order[] = $this->formData['bootOrder' . $i];
  166. }
  167. }
  168. }
  169. if(version_compare($this->api()->getVersion(), "6.3", '>=') && !empty($order)){
  170. //order=scsi0;ide0;ide1;net0
  171. $vm->updateConfig(['boot' => "order=".implode(";", $order)]);
  172. }else{
  173. $vm->changeBootOrder($bootOrder);
  174. }
  175. //sshkeys
  176. if($this->configuration()->isPermissionSshkeys()){
  177. if ($this->formData['sshkeys'])
  178. {
  179. $vm->updateConfig(["sshkeys" => rawurlencode($this->formData['sshkeys'])]);
  180. } else if($vm->config()['sshkeys'])
  181. {
  182. $vm->deleteConfig('sshkeys');
  183. }
  184. }
  185. }
  186. try{
  187. Api::beginTransaction();
  188. DB::beginTransaction();
  189. $this->fillVmModel();
  190. if($this->getFormDataValues()['password']){
  191. $this->vmModel->setPassword($this->getFormDataValues()['password']);
  192. }
  193. if($this->configuration()->isCalculateSocketsAndCores()){
  194. $this->calculateSocketsAndCores();
  195. }
  196. $this->vmModel->save();
  197. if($this->configuration()->isQemu()){
  198. fire(new QemuUpdateEvent($this->vmModel, $this->formData));
  199. }
  200. if($this->configuration()->isLxc()){
  201. fire(new LxcUpdateEvent($this->vmModel, $this->formData));
  202. }
  203. $agentEnabled = (new AgentService())->isEnabled();
  204. if($agentEnabled && $this->configuration()->isAgentConfigureNetwork()){
  205. queue(ConfigureNetworkJob::class,
  206. ['hostingId' => $this->getWhmcsParamByKey('serviceid')],
  207. null,
  208. "hosting",
  209. $this->getWhmcsParamByKey("serviceid"),
  210. $this->vmModel->id
  211. );
  212. }
  213. if($agentEnabled && $this->configuration()->isAgentPassword()){
  214. queue(ChangePasswordJob::class,
  215. ['hostingId' => $this->getWhmcsParamByKey('serviceid')],
  216. null,
  217. "hosting",
  218. $this->getWhmcsParamByKey("serviceid"),
  219. $this->vmModel->id
  220. );
  221. }
  222. DB::commit();
  223. return (new HtmlDataJsonResponse())
  224. ->setMessageAndTranslate('Server has been updated')
  225. ->setCallBackFunction('pcVmUpdatedAjaxDone')
  226. ->addRefreshTargetId('serviceInformationDataTable')
  227. ->setCallBackFunction('mgLocationReload');
  228. }catch (\Exception $ex){
  229. DB::rollBack();
  230. Api::commit();
  231. return (new HtmlDataJsonResponse())
  232. ->setStatusError()
  233. ->setMessageAndTranslate($ex->getMessage());
  234. }
  235. }
  236. }