update-functions.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. trait UpdateFunctions
  3. {
  4. public function testScriptFilePermissions($script, $retest = false)
  5. {
  6. if (file_exists($script)) {
  7. if (is_executable($script)) {
  8. return true;
  9. } elseif ($retest == false) {
  10. $this->setLoggerChannel('Update')->notice('Attempting to set correct permissions', ['file' => $script]);
  11. $permissions = shell_exec('chmod 677 ' . $script);
  12. $permissions = shell_exec('chmod 777 ' . $script);
  13. return $this->testScriptFilePermissions($script, true);
  14. } else {
  15. $this->setLoggerChannel('Update')->warning('Update script doesn\'t have the correct permissions', ['file' => $script]);
  16. return false;
  17. }
  18. } else {
  19. $this->setLoggerChannel('Update')->warning('Update script doesn\'t exist', ['file' => $script]);
  20. return false;
  21. }
  22. }
  23. public function updateOrganizr()
  24. {
  25. if ($this->docker) {
  26. return $this->dockerUpdate();
  27. } elseif ($this->getOS() == 'win') {
  28. return $this->windowsUpdate();
  29. } else {
  30. return $this->linuxUpdate();
  31. }
  32. }
  33. public function createUpdateStatusFile()
  34. {
  35. $file = $this->config['dbLocation'] . 'updateInProgress.txt';
  36. touch($file);
  37. return true;
  38. }
  39. public function removeUpdateStatusFile()
  40. {
  41. $file = $this->config['dbLocation'] . 'updateInProgress.txt';
  42. if (file_exists($file)) {
  43. @unlink($file);
  44. }
  45. return true;
  46. }
  47. public function hasUpdateStatusFile()
  48. {
  49. return file_exists($this->config['dbLocation'] . 'updateInProgress.txt');
  50. }
  51. public function dockerUpdate()
  52. {
  53. if (!$this->docker) {
  54. $this->setResponse(409, 'Your install type is not Docker');
  55. return false;
  56. }
  57. if ($this->hasUpdateStatusFile()) {
  58. $this->setResponse(500, 'Already Update in progress');
  59. return false;
  60. } else {
  61. $this->createUpdateStatusFile();
  62. }
  63. $dockerUpdate = null;
  64. ini_set('max_execution_time', 0);
  65. set_time_limit(0);
  66. chdir('/etc/cont-init.d/');
  67. if (file_exists('./30-install')) {
  68. $this->setAPIResponse('error', 'Update failed - OrgTools is deprecated - please use organizr/organizr', 500);
  69. return false;
  70. } elseif (file_exists('./40-install')) {
  71. $dockerUpdate = shell_exec('./40-install');
  72. }
  73. $this->removeUpdateStatusFile();
  74. if ($dockerUpdate) {
  75. $this->setAPIResponse('success', $dockerUpdate, 200);
  76. return true;
  77. } else {
  78. $this->setAPIResponse('error', 'Update failed', 500);
  79. return false;
  80. }
  81. }
  82. public function windowsUpdate()
  83. {
  84. if ($this->docker || $this->getOS() !== 'win') {
  85. $this->setResponse(409, 'Your install type is not Windows');
  86. return false;
  87. }
  88. if ($this->hasUpdateStatusFile()) {
  89. $this->setResponse(500, 'Already Update in progress');
  90. return false;
  91. } else {
  92. $this->createUpdateStatusFile();
  93. }
  94. $branch = ($this->config['branch'] == 'v2-master') ? '-m' : '-d';
  95. ini_set('max_execution_time', 0);
  96. set_time_limit(0);
  97. $logFile = $this->root . DIRECTORY_SEPARATOR . 'scripts' . DIRECTORY_SEPARATOR . 'log.txt';
  98. $windowsScript = $this->root . DIRECTORY_SEPARATOR . 'scripts' . DIRECTORY_SEPARATOR . 'windows-update.bat ' . $branch . ' > ' . $logFile . ' 2>&1';
  99. $windowsUpdate = shell_exec($windowsScript);
  100. $this->removeUpdateStatusFile();
  101. if ($windowsUpdate) {
  102. $this->setAPIResponse('success', $windowsUpdate, 200);
  103. return true;
  104. } else {
  105. $this->setAPIResponse('success', 'Update Complete - check log.txt for output', 200);
  106. return false;
  107. }
  108. }
  109. public function linuxUpdate()
  110. {
  111. if ($this->docker || $this->getOS() == 'win') {
  112. $this->setResponse(409, 'Your install type is not Linux');
  113. return false;
  114. }
  115. if ($this->hasUpdateStatusFile()) {
  116. $this->setResponse(500, 'Already Update in progress');
  117. return false;
  118. } else {
  119. $this->createUpdateStatusFile();
  120. }
  121. $branch = $this->config['branch'];
  122. ini_set('max_execution_time', 0);
  123. set_time_limit(0);
  124. $logFile = $this->root . DIRECTORY_SEPARATOR . 'scripts' . DIRECTORY_SEPARATOR . 'log.txt';
  125. $script = $this->root . DIRECTORY_SEPARATOR . 'scripts' . DIRECTORY_SEPARATOR . 'linux-update.sh ' . $branch . ' > ' . $logFile . ' 2>&1';
  126. $checkScript = $this->testScriptFilePermissions($script);
  127. if (!$checkScript) {
  128. $this->setResponse(500, 'Update script permissions error');
  129. $this->removeUpdateStatusFile();
  130. return false;
  131. }
  132. $update = shell_exec($script);
  133. $this->removeUpdateStatusFile();
  134. if ($update) {
  135. $this->setAPIResponse('success', $update, 200);
  136. return true;
  137. } else {
  138. $this->setAPIResponse('success', 'Update Complete - check log.txt for output', 200);
  139. return false;
  140. }
  141. }
  142. public function upgradeInstall($branch = 'v2-master', $stage = '1')
  143. {
  144. // may kill this function in place for php script to run elsewhere
  145. if ($this->docker) {
  146. $this->setAPIResponse('error', 'Cannot perform update action on docker install - use script', 500);
  147. return false;
  148. }
  149. if ($this->getOS() == 'win') {
  150. $this->setAPIResponse('error', 'Cannot perform update action on windows install - use script', 500);
  151. return false;
  152. }
  153. $notWritable = array_search(false, $this->pathsWritable($this->paths));
  154. if ($notWritable == false) {
  155. ini_set('max_execution_time', 0);
  156. set_time_limit(0);
  157. $url = 'https://github.com/causefx/Organizr/archive/' . $branch . '.zip';
  158. $file = "upgrade.zip";
  159. $source = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'upgrade' . DIRECTORY_SEPARATOR . 'Organizr-' . str_replace('v2', '2', $branch) . DIRECTORY_SEPARATOR;
  160. $cleanup = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . "upgrade" . DIRECTORY_SEPARATOR;
  161. $destination = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR;
  162. switch ($stage) {
  163. case '1':
  164. $this->setLoggerChannel('Update')->info('Started Upgrade Process');
  165. if ($this->downloadFile($url, $file)) {
  166. $this->setLoggerChannel('Update')->info('Downloaded Update File for Branch: ' . $branch);
  167. $this->setAPIResponse('success', 'Downloaded file successfully', 200);
  168. return true;
  169. } else {
  170. $this->setLoggerChannel('Update')->warning('Downloaded Update File Failed for Branch: ' . $branch);
  171. $this->setAPIResponse('error', 'Download failed', 500);
  172. return false;
  173. }
  174. case '2':
  175. if ($this->unzipFile($file)) {
  176. $this->setLoggerChannel('Update')->info('Unzipped Update File for Branch: ' . $branch);
  177. $this->setAPIResponse('success', 'Unzipped file successfully', 200);
  178. return true;
  179. } else {
  180. $this->setLoggerChannel('Update')->warning('Unzip Failed for Branch: ' . $branch);
  181. $this->setAPIResponse('error', 'Unzip failed', 500);
  182. return false;
  183. }
  184. case '3':
  185. if ($this->rcopy($source, $destination)) {
  186. $this->setLoggerChannel('Update')->info('Files overwritten using Updated Files from Branch: ' . $branch);
  187. $updateComplete = $this->config['dbLocation'] . 'completed.txt';
  188. if (!file_exists($updateComplete)) {
  189. touch($updateComplete);
  190. }
  191. $this->setAPIResponse('success', 'Files replaced successfully', 200);
  192. return true;
  193. } else {
  194. $this->setLoggerChannel('Update')->warning('Overwrite Failed for Branch: ' . $branch);
  195. $this->setAPIResponse('error', 'File replacement failed', 500);
  196. return false;
  197. }
  198. case '4':
  199. if ($this->rrmdir($cleanup)) {
  200. $this->setLoggerChannel('Update')->info('Deleted Update Files from Branch: ' . $branch);
  201. $this->setLoggerChannel('Update')->info('Update Completed');
  202. $this->setAPIResponse('success', 'Removed update files successfully', 200);
  203. return true;
  204. } else {
  205. $this->setLoggerChannel('Update')->warning('Removal of Update Files Failed for Branch: ' . $branch);
  206. $this->setAPIResponse('error', 'File removal failed', 500);
  207. return false;
  208. }
  209. default:
  210. $this->setAPIResponse('error', 'Action not setup', 500);
  211. return false;
  212. }
  213. } else {
  214. $this->setAPIResponse('error', 'File permissions not set correctly', 500);
  215. return false;
  216. }
  217. }
  218. }