FileRepository.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. <?php
  2. /* * ********************************************************************
  3. * ProxmoxVPS product developed. (2016-10-11)
  4. * *
  5. *
  6. * CREATED BY MODULESGARDEN -> http://modulesgarden.com
  7. * CONTACT -> contact@modulesgarden.com
  8. *
  9. *
  10. * This software is furnished under a license and may be used and copied
  11. * only in accordance with the terms of such license and with the
  12. * inclusion of the above copyright notice. This software or any other
  13. * copies thereof may not be provided or otherwise made available to any
  14. * other person. No title to and ownership of the software is hereby
  15. * transferred.
  16. *
  17. *
  18. * ******************************************************************** */
  19. namespace MGProvision\Proxmox\v2\repository;
  20. use MGProvision\Proxmox\v2\interfaces\VmInterface;
  21. Use MGProvision\Proxmox\v2\models\File;
  22. use MGProvision\Proxmox\v2\models\TemplateKvm;
  23. use ModulesGarden\ProxmoxAddon\App\Models\VmModel;
  24. use ModulesGarden\ProxmoxAddon\App\Services\Utility;
  25. /**
  26. * Description of FileRepository
  27. *
  28. * @author Pawel Kopec <pawelk@modulesgarden.com>
  29. * @version 1.0.0
  30. */
  31. class FileRepository extends AbstractRepository
  32. {
  33. protected $content = null;
  34. protected $storages = array();
  35. protected $nodes = array();
  36. protected $vmid;
  37. private $templateKvm;
  38. private $vmids = array();
  39. protected $filterNotMatch = [];
  40. protected $forceFetch = true;
  41. protected $filterPattern;
  42. public function findByVmid($vmid)
  43. {
  44. $this->vmid = $vmid;
  45. return $this;
  46. }
  47. /**
  48. *
  49. * @param VmInterface $vm
  50. * @return \MGProvision\Proxmox\v2\repository\FileRepository
  51. */
  52. public function findBackup(VmInterface $vm)
  53. {
  54. $this->findByVmid($vm->getVmid())
  55. ->findByNodes(array($vm->getNode()));
  56. $this->findByContent('backup');
  57. return $this;
  58. }
  59. /**
  60. *
  61. * @param VmModel[] $vservers
  62. */
  63. public function findBackupByVmModel($vservers)
  64. {
  65. $nodes = array();
  66. foreach ($vservers as $vserver) {
  67. if (!$vserver instanceof VmModel) {
  68. throw new \MGProvision\Proxmox\v2\ProxmoxApiException("Ukown object: " . get_class($vserver));
  69. }
  70. $nodes[] = $vserver->node;
  71. $this->vmids[] = $vserver->vmid;
  72. }
  73. $this->findByNodes($nodes)
  74. ->findByContent('backup');
  75. return $this;
  76. }
  77. /**
  78. *
  79. * @return File[]|TemplateKvm[]
  80. */
  81. public function fetch()
  82. {
  83. if (!empty($this->fetch) && !$this->forceFetch) {
  84. return $this->fetch;
  85. }
  86. $request = array();
  87. if ($this->content)
  88. $request["content"] = $this->content;
  89. if ($this->vmid)
  90. $request["vmid"] = $this->vmid;
  91. $i = 0;
  92. $this->fetch = array();
  93. foreach ($this->nodes as $node) {
  94. if (isset($this->vmids[$i]) && $this->vmids[$i]) {
  95. $request["vmid"] = $this->vmids[$i];
  96. }
  97. foreach ($this->storages as $storage) {
  98. $vmid = null;
  99. if ($request["vmid"] && version_compare($this->api()->getVersion(), "5.4", '>=')) {
  100. $vmid = $request["vmid"];
  101. unset($request["vmid"]);
  102. }
  103. $path = "/nodes/{$node}/storage/{$storage}/content";
  104. logModuleCall(
  105. 'ProxmoxCloudVps',
  106. __FUNCTION__,
  107. $path,
  108. 'Debug remove Backup Cron',
  109. $request
  110. );
  111. $files = $this->api()->get($path, $request);
  112. foreach ($files as $file) {
  113. if (($vmid && $file['vmid'] && $file['vmid'] != $vmid) || ($vmid && !$file['vmid'] && !preg_match("/\-{$vmid}\-/", $file['volid']))) {
  114. continue;
  115. }
  116. if ($this->filterNotMatch && preg_match("/{$this->filterNotMatch['volid']}/", $file['volid'])) {
  117. continue;
  118. }
  119. if (!empty($this->filterPattern) && !$this->matchFilterPattern($file)) {
  120. continue;
  121. }
  122. if ($this->templateKvm) {
  123. $entityObj = $this->formatTemplateKvm($node, $file);
  124. if (!$entityObj instanceof TemplateKvm)
  125. continue;
  126. } else {
  127. $entityObj = new File();
  128. $entityObj->setAttributes($file);
  129. $entityObj->setNode($node);
  130. }
  131. $entityObj->setPath(sprintf("{$path}/%s", $file['volid']));
  132. $this->fetch[] = $entityObj;
  133. }
  134. }
  135. $i++;
  136. }
  137. $this->forceFetch = false;
  138. return $this->fetch;
  139. }
  140. public function count()
  141. {
  142. return count($this->fetch());
  143. }
  144. public function size()
  145. {
  146. $size = (float)0;
  147. foreach ($this->fetch() as $entityObj) {
  148. $size += $entityObj->getSize();
  149. }
  150. return $size;
  151. }
  152. /**
  153. * @return float
  154. * @throws \Exception
  155. */
  156. public function getSizeInGb()
  157. {
  158. $size = $this->size();
  159. Utility::unitFormat($size, "bytes", "gb");
  160. return $size;
  161. }
  162. private function formatTemplateKvm($node, array $file)
  163. {
  164. if (empty($file['vmid'])) {
  165. return;
  166. }
  167. try {
  168. $vmid = $file['vmid'];
  169. $status = $this->api()->get("/nodes/{$node}/qemu/{$vmid}/status/current", array());
  170. if ($status['template'] != '1') {
  171. return;
  172. }
  173. $config = $this->api()->get("/nodes/{$node}/qemu/{$vmid}/config", array());
  174. if (empty($config)) {
  175. return;
  176. }
  177. $attributes = array();
  178. $attributes['node'] = $node;
  179. $attributes = array_merge($attributes, $file);
  180. $attributes = array_merge($attributes, $config);
  181. $template = new TemplateKvm();
  182. $template->setAttributes($attributes);
  183. return $template;
  184. } catch (\Exception $ex) {
  185. }
  186. }
  187. public function fetchAsArray()
  188. {
  189. $data = array();
  190. foreach ($this->fetch() as $entity) {
  191. $data[$entity->getVolid()] = $entity->getFriendlyName();
  192. }
  193. return $data;
  194. }
  195. public function findByContent($content)
  196. {
  197. $this->content = $content;
  198. return $this;
  199. }
  200. public function findLxcTemplates()
  201. {
  202. $this->content = 'vztmpl';
  203. return $this;
  204. }
  205. public function findKvmTemplates()
  206. {
  207. $this->content = 'images';
  208. $this->templateKvm = true;
  209. return $this;
  210. }
  211. public function findIso()
  212. {
  213. $this->content = 'iso';
  214. return $this;
  215. }
  216. public function findByStorages($storages)
  217. {
  218. $this->storages = $storages;
  219. return $this;
  220. }
  221. public function findByNodes(array $nodes)
  222. {
  223. $this->nodes = $nodes;
  224. return $this;
  225. }
  226. public function findByNode(\MGProvision\Proxmox\v2\models\Node $node)
  227. {
  228. $this->nodes = array($node->getNode());
  229. return $this;
  230. }
  231. public function delete()
  232. {
  233. $this->reset();
  234. $backups = $this->fetch();
  235. foreach ($backups as $b) {
  236. $b->delete();
  237. }
  238. }
  239. /**
  240. *
  241. * @return File|TemplateKvm|null
  242. */
  243. public function fetchLast()
  244. {
  245. $file = null;
  246. foreach ($this->fetch() as $t) {
  247. if ($file === null) {
  248. $file = $t;
  249. continue;
  250. } else if ($t->getTimestamp() > $file->getTimestamp()) {
  251. $file = $t;
  252. }
  253. }
  254. return $file;
  255. }
  256. public function findVolidNotIn(array $volids)
  257. {
  258. $this->filterNotMatch['volid'] = $volids;
  259. return $this;
  260. }
  261. public function sortByTime()
  262. {
  263. $keys = [];
  264. $orginal = $this->fetch();
  265. foreach ($orginal as $key => $entity) {
  266. $keys[$key] = $entity->getTimestamp();
  267. }
  268. uasort($keys, function ($a, $b) {
  269. if ($a == $b) {
  270. return 0;
  271. }
  272. return ($a < $b) ? -1 : 1;
  273. });
  274. $this->fetch = [];
  275. foreach ($keys as $id => $entity) {
  276. $this->fetch[$id] = $orginal[$id];
  277. }
  278. return $this;
  279. }
  280. public function remove($id)
  281. {
  282. unset($this->fetch[$id]);
  283. return $this;
  284. }
  285. public function findSnippets()
  286. {
  287. $this->content = 'snippets';
  288. return $this;
  289. }
  290. public function findSnippetsByServiceId($serviceId)
  291. {
  292. $this->findSnippets();
  293. $this->filterPattern = [
  294. "/userconfig\-{$serviceId}\.yaml/",
  295. "/meta\-{$serviceId}\.yaml/",
  296. "/network\-{$serviceId}\.yaml/",
  297. ];
  298. return $this;
  299. }
  300. public function findSnippetsByVmModel(VmModel $vmModel)
  301. {
  302. $this->findSnippets();
  303. $this->filterPattern = [
  304. "/userconfig\-{$vmModel->hosting_id}\-{$vmModel->id}\.yaml/",
  305. "/meta\-{$vmModel->hosting_id}\-{$vmModel->id}\.yaml/",
  306. "/network\-{$vmModel->hosting_id}\-{$vmModel->id}\.yaml/",
  307. ];
  308. return $this;
  309. }
  310. public function first()
  311. {
  312. return $this->fetch()[0];
  313. }
  314. public function findBackupQemuTemplates()
  315. {
  316. $this->findByContent('backup');
  317. $this->filterPattern = "/qemu/";
  318. $this->forceFetch = true;
  319. return $this;
  320. }
  321. public function findBackupLxcTemplates()
  322. {
  323. $this->findByContent('backup');
  324. $this->filterPattern = "/lxc/";
  325. $this->forceFetch = true;
  326. return $this;
  327. }
  328. private function matchFilterPattern($file)
  329. {
  330. if (is_string($this->filterPattern)) {
  331. return preg_match($this->filterPattern, $file['volid']);
  332. }
  333. if (is_array($this->filterPattern)) {
  334. foreach ($this->filterPattern as $pattern) {
  335. if (preg_match($pattern, $file['volid'])) {
  336. return true;
  337. }
  338. }
  339. }
  340. return false;
  341. }
  342. }