FileRepository.php 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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. $files = $this->api()->get($path, $request);
  105. foreach ($files as $file) {
  106. if (($vmid && $file['vmid'] && $file['vmid'] != $vmid) || ($vmid && !$file['vmid'] && !preg_match("/\-{$vmid}\-/", $file['volid']))) {
  107. continue;
  108. }
  109. if ($this->filterNotMatch && preg_match("/{$this->filterNotMatch['volid']}/", $file['volid'])) {
  110. continue;
  111. }
  112. if (!empty($this->filterPattern) && !$this->matchFilterPattern($file)) {
  113. continue;
  114. }
  115. if ($this->templateKvm) {
  116. $entityObj = $this->formatTemplateKvm($node, $file);
  117. if (!$entityObj instanceof TemplateKvm)
  118. continue;
  119. } else {
  120. $entityObj = new File();
  121. $entityObj->setAttributes($file);
  122. $entityObj->setNode($node);
  123. }
  124. $entityObj->setPath(sprintf("{$path}/%s", $file['volid']));
  125. $this->fetch[] = $entityObj;
  126. }
  127. }
  128. $i++;
  129. }
  130. $this->forceFetch = false;
  131. return $this->fetch;
  132. }
  133. public function count()
  134. {
  135. return count($this->fetch());
  136. }
  137. public function size()
  138. {
  139. $size = (float)0;
  140. foreach ($this->fetch() as $entityObj) {
  141. $size += $entityObj->getSize();
  142. }
  143. return $size;
  144. }
  145. /**
  146. * @return float
  147. * @throws \Exception
  148. */
  149. public function getSizeInGb()
  150. {
  151. $size = $this->size();
  152. Utility::unitFormat($size, "bytes", "gb");
  153. return $size;
  154. }
  155. private function formatTemplateKvm($node, array $file)
  156. {
  157. if (empty($file['vmid'])) {
  158. return;
  159. }
  160. try {
  161. $vmid = $file['vmid'];
  162. $status = $this->api()->get("/nodes/{$node}/qemu/{$vmid}/status/current", array());
  163. if ($status['template'] != '1') {
  164. return;
  165. }
  166. $config = $this->api()->get("/nodes/{$node}/qemu/{$vmid}/config", array());
  167. if (empty($config)) {
  168. return;
  169. }
  170. $attributes = array();
  171. $attributes['node'] = $node;
  172. $attributes = array_merge($attributes, $file);
  173. $attributes = array_merge($attributes, $config);
  174. $template = new TemplateKvm();
  175. $template->setAttributes($attributes);
  176. return $template;
  177. } catch (\Exception $ex) {
  178. }
  179. }
  180. public function fetchAsArray()
  181. {
  182. $data = array();
  183. foreach ($this->fetch() as $entity) {
  184. $data[$entity->getVolid()] = $entity->getFriendlyName();
  185. }
  186. return $data;
  187. }
  188. public function findByContent($content)
  189. {
  190. $this->content = $content;
  191. return $this;
  192. }
  193. public function findLxcTemplates()
  194. {
  195. $this->content = 'vztmpl';
  196. return $this;
  197. }
  198. public function findKvmTemplates()
  199. {
  200. $this->content = 'images';
  201. $this->templateKvm = true;
  202. return $this;
  203. }
  204. public function findIso()
  205. {
  206. $this->content = 'iso';
  207. return $this;
  208. }
  209. public function findByStorages($storages)
  210. {
  211. $this->storages = $storages;
  212. return $this;
  213. }
  214. public function findByNodes(array $nodes)
  215. {
  216. $this->nodes = $nodes;
  217. return $this;
  218. }
  219. public function findByNode(\MGProvision\Proxmox\v2\models\Node $node)
  220. {
  221. $this->nodes = array($node->getNode());
  222. return $this;
  223. }
  224. public function delete()
  225. {
  226. $this->reset();
  227. $backups = $this->fetch();
  228. foreach ($backups as $b) {
  229. $b->delete();
  230. }
  231. }
  232. /**
  233. *
  234. * @return File|TemplateKvm|null
  235. */
  236. public function fetchLast()
  237. {
  238. $file = null;
  239. foreach ($this->fetch() as $t) {
  240. if ($file === null) {
  241. $file = $t;
  242. continue;
  243. } else if ($t->getTimestamp() > $file->getTimestamp()) {
  244. $file = $t;
  245. }
  246. }
  247. return $file;
  248. }
  249. public function findVolidNotIn(array $volids)
  250. {
  251. $this->filterNotMatch['volid'] = $volids;
  252. return $this;
  253. }
  254. public function sortByTime()
  255. {
  256. $keys = [];
  257. $orginal = $this->fetch();
  258. foreach ($orginal as $key => $entity) {
  259. $keys[$key] = $entity->getTimestamp();
  260. }
  261. uasort($keys, function ($a, $b) {
  262. if ($a == $b) {
  263. return 0;
  264. }
  265. return ($a < $b) ? -1 : 1;
  266. });
  267. $this->fetch = [];
  268. foreach ($keys as $id => $entity) {
  269. $this->fetch[$id] = $orginal[$id];
  270. }
  271. return $this;
  272. }
  273. public function remove($id)
  274. {
  275. unset($this->fetch[$id]);
  276. return $this;
  277. }
  278. public function findSnippets()
  279. {
  280. $this->content = 'snippets';
  281. return $this;
  282. }
  283. public function findSnippetsByServiceId($serviceId)
  284. {
  285. $this->findSnippets();
  286. $this->filterPattern = [
  287. "/userconfig\-{$serviceId}\.yaml/",
  288. "/meta\-{$serviceId}\.yaml/",
  289. "/network\-{$serviceId}\.yaml/",
  290. ];
  291. return $this;
  292. }
  293. public function findSnippetsByVmModel(VmModel $vmModel)
  294. {
  295. $this->findSnippets();
  296. $this->filterPattern = [
  297. "/userconfig\-{$vmModel->hosting_id}\-{$vmModel->id}\.yaml/",
  298. "/meta\-{$vmModel->hosting_id}\-{$vmModel->id}\.yaml/",
  299. "/network\-{$vmModel->hosting_id}\-{$vmModel->id}\.yaml/",
  300. ];
  301. return $this;
  302. }
  303. public function first()
  304. {
  305. return $this->fetch()[0];
  306. }
  307. public function findBackupQemuTemplates()
  308. {
  309. $this->findByContent('backup');
  310. $this->filterPattern = "/qemu/";
  311. $this->forceFetch = true;
  312. return $this;
  313. }
  314. public function findBackupLxcTemplates()
  315. {
  316. $this->findByContent('backup');
  317. $this->filterPattern = "/lxc/";
  318. $this->forceFetch = true;
  319. return $this;
  320. }
  321. private function matchFilterPattern($file)
  322. {
  323. if (is_string($this->filterPattern)) {
  324. return preg_match($this->filterPattern, $file['volid']);
  325. }
  326. if (is_array($this->filterPattern)) {
  327. foreach ($this->filterPattern as $pattern) {
  328. if (preg_match($pattern, $file['volid'])) {
  329. return true;
  330. }
  331. }
  332. }
  333. return false;
  334. }
  335. }