AsyncJobs.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. Lib::loadClass('Core_AsyncJobs');
  4. class Route_AsyncJobs extends RouteBase {
  5. function isInstalled() { return Core_AsyncJobs::isInstalled(); }
  6. function getSbinPath() { return realpath(APP_PATH_ROOT . "/../sbin/"); }
  7. function defaultAction() { UI::layout([ $this, 'defaultView' ]); }
  8. function defaultView() {
  9. echo UI::h('h1', [], "Async jobs (wps server)");
  10. if (!User::isAdmin()) throw new Exception("Access Denied");
  11. DBG::nicePrint(Config::getConfFile(), "Config::getConfFile()");
  12. try {
  13. Core_AsyncJobs::isInstalled();
  14. } catch (Exception $e) {
  15. UI::alert('danger', $e->getMessage());
  16. }
  17. echo UI::h('div', [ 'style' => "padding:12px 0; border-bottom:1px solid #ddd" ], [
  18. UI::hButtonPost("Check", [
  19. 'class' => "btn btn-default",
  20. 'title' => "check if async process manager is working",
  21. 'data' => [
  22. '_route' => 'AsyncJobs',
  23. '_postTask' => "pm2Check",
  24. ]
  25. ]),
  26. " ",
  27. UI::h('a', [
  28. 'href' => $this->getLink('list'),
  29. 'class' => "btn btn-default",
  30. ], "Lista"),
  31. " ",
  32. UI::hButtonPost("pm2 list", [
  33. 'class' => "btn btn-warning",
  34. 'data' => [
  35. '_route' => 'AsyncJobs',
  36. '_postTask' => "pm2List",
  37. ]
  38. ]),
  39. " ",
  40. UI::hButtonPost("pm2 kill", [
  41. 'class' => "btn btn-warning",
  42. 'data' => [
  43. '_route' => 'AsyncJobs',
  44. '_postTask' => "pm2Kill",
  45. ]
  46. ]),
  47. " ",
  48. UI::hButtonPost("pm2 run1", [
  49. 'class' => "btn btn-warning",
  50. 'data' => [
  51. '_route' => 'AsyncJobs',
  52. '_postTask' => "mp2Start1",
  53. ]
  54. ]),
  55. " ",
  56. UI::hButtonPost("pm2 run2", [
  57. 'class' => "btn btn-warning",
  58. 'data' => [
  59. '_route' => 'AsyncJobs',
  60. '_postTask' => "mp2Start2",
  61. ]
  62. ]),
  63. " ",
  64. UI::hButtonPost("pm2 run3", [
  65. 'class' => "btn btn-warning",
  66. 'data' => [
  67. '_route' => 'AsyncJobs',
  68. '_postTask' => "mp2Start3",
  69. ]
  70. ]),
  71. " ",
  72. UI::hButtonPost("pm2 delete stopped", [
  73. 'class' => "btn btn-warning",
  74. 'data' => [
  75. '_route' => 'AsyncJobs',
  76. '_postTask' => "mp2DeleteStopped",
  77. ]
  78. ]),
  79. " ",
  80. UI::hButtonPost("reinstall pm2-www", [
  81. 'class' => "btn btn-warning",
  82. 'data' => [
  83. '_route' => 'AsyncJobs',
  84. '_postTask' => "testReinstallPm2ByWWW",
  85. ]
  86. ]),
  87. ]);
  88. $postTask = V::get('_postTask', '', $_POST);
  89. switch ($postTask) {
  90. case "pm2Check": UI::tryCatchView([ $this, 'pm2CheckPostTask' ]); break;
  91. case "pm2List": UI::tryCatchView([ $this, 'pm2ListPostTask' ]); break;
  92. case "pm2Kill": UI::tryCatchView([ $this, 'pm2KillPostTask' ]); break;
  93. case "mp2Start1": UI::tryCatchView([ $this, 'mp2Start1PostTask' ]); break;
  94. case "mp2Start2": UI::tryCatchView([ $this, 'mp2Start2PostTask' ]); break;
  95. case "mp2Start3": UI::tryCatchView([ $this, 'mp2Start3PostTask' ]); break;
  96. case "mp2DeleteStopped": UI::tryCatchView([ $this, 'mp2DeleteStoppedPostTask' ]); break;
  97. case "testReinstallPm2ByWWW": UI::tryCatchView([ $this, 'testReinstallPm2ByWWWPostTask' ]); break;
  98. }
  99. }
  100. function pm2CheckPostTask() {
  101. $cmd = "pm2 ping";
  102. V::exec($cmd, $out, $ret);
  103. echo "cmd: <code>{$cmd}</code><br>RETURN CODE: '{$ret}'<br><pre>OUTPUT:\n" . implode("\n", $out) . "</pre>";
  104. // expected: end($out) === "{ msg: 'pong' }"
  105. }
  106. function listAction() { UI::layout([ $this, 'listView' ]); }
  107. function listView() {
  108. echo UI::h('ol', [ 'class' => "breadcrumb", 'style' => "font-size:14px" ], [
  109. UI::h('li', [], [
  110. UI::h('i', [ 'class' => "glyphicon glyphicon-home" ]),
  111. " ",
  112. UI::h('a', [ 'href' => $this->getLink() ], "Async jobs"),
  113. ]),
  114. UI::h('li', [ 'class' => "active" ], [
  115. "Lista"
  116. ]),
  117. UI::h('a', [
  118. 'href' => $this->getLink('list'),
  119. 'class' => "pull-right btn btn-link",
  120. 'style' => "padding:0; line-height:1em",
  121. ], "odśwież"),
  122. ]);
  123. $postTask = V::get('_postTask', '', $_POST);
  124. switch ($postTask) {
  125. case "stopJob": UI::tryCatchView([ $this, 'stopJobPostTask' ]); break;
  126. case "startJob": UI::tryCatchView([ $this, 'startJobPostTask' ]); break;
  127. }
  128. echo UI::hTable([
  129. 'rows' => array_map([ $this, 'viewTableRowAsyncJob' ], Core_AsyncJobs::getSimpleList()),
  130. ]);
  131. }
  132. function stopJobPostTask() {
  133. $idJob = V::get('idJob', 0, $_POST, 'int'); // $jobInfo['pm_id'],
  134. $name = V::get('name', '', $_POST); // $jobInfo['name'],
  135. if ($idJob < 0) throw new Exception("Wrong param idJob");
  136. if ($idJob === 0 && $_POST['idJob'] !== '0') throw new Exception("Wrong param idJob 0");
  137. Core_AsyncJobs::stopJob($idJob);
  138. }
  139. function startJobPostTask() {
  140. $idJob = V::get('idJob', 0, $_POST, 'int'); // $jobInfo['pm_id'],
  141. $name = V::get('name', '', $_POST); // $jobInfo['name'],
  142. if ($idJob < 0) throw new Exception("Wrong param idJob");
  143. if ($idJob === 0 && $_POST['idJob'] !== '0') throw new Exception("Wrong param idJob 0");
  144. Core_AsyncJobs::startJob($idJob);
  145. }
  146. function pm2ListPostTask() {
  147. $cmd = "pm2 list";
  148. V::exec($cmd, $out, $ret);
  149. echo "cmd: <code>{$cmd}</code><br>RETURN CODE: '{$ret}'<br><pre>OUTPUT:\n" . implode("\n", $out) . "</pre>";
  150. $cmd = "pm2 jlist";
  151. V::exec($cmd, $out, $ret);
  152. echo "cmd: <code>{$cmd}</code><br>RETURN CODE: '{$ret}'<br><pre>OUTPUT:\n" . implode("\n", $out) . "</pre>";
  153. echo '<hr style="margin:24px auto">';
  154. $parsedJobList = Core_AsyncJobs::getFullList();
  155. DBG::nicePrint($parsedJobList, "\$parsedJobList");
  156. echo '<hr style="margin:24px auto">';
  157. UI::table([
  158. 'rows' => array_map([ $this, 'viewTableRowAsyncJob' ], Core_AsyncJobs::getSimpleList()),
  159. ]);
  160. }
  161. function viewTableRowAsyncJob($jobInfo) {
  162. return [
  163. 'name' => $jobInfo['name'],
  164. 'pid' => $jobInfo['pid'],
  165. 'pm_id' => $jobInfo['pm_id'],
  166. 'status' => $jobInfo['pm2_env.status'],
  167. 'memory' => $jobInfo['monit.memory'],
  168. 'cpu' => $jobInfo['monit.cpu'],
  169. '#' => UI::h(null, [], [
  170. UI::h('a', [
  171. 'href' => $this->getLink('jobLog', [
  172. 'idJob' => $jobInfo['pm_id'],
  173. 'name' => $jobInfo['name'],
  174. ]),
  175. 'class' => "btn btn-xs btn-warning",
  176. ], "logi"),
  177. " ",
  178. UI::hButtonPost("stop", [
  179. 'class' => "btn btn-xs btn-default",
  180. 'data' => [
  181. '_route' => 'AsyncJobs',
  182. '_postTask' => "stopJob",
  183. 'idJob' => $jobInfo['pm_id'],
  184. 'name' => $jobInfo['name'],
  185. ]
  186. ]),
  187. " ",
  188. UI::hButtonPost("start", [
  189. 'class' => "btn btn-xs btn-default",
  190. 'data' => [
  191. '_route' => 'AsyncJobs',
  192. '_postTask' => "startJob",
  193. 'idJob' => $jobInfo['pm_id'],
  194. 'name' => $jobInfo['name'],
  195. ]
  196. ]),
  197. ]),
  198. ];
  199. }
  200. function jobLogAction() { UI::layout([ $this, 'jobLogView' ]); }
  201. function jobLogView() {
  202. $idJob = V::get('idJob', 0, $_GET, 'int'); // $jobInfo['pm_id'],
  203. $name = V::get('name', '', $_GET); // $jobInfo['name'],
  204. echo UI::h('ol', [ 'class' => "breadcrumb", 'style' => "font-size:14px" ], [
  205. UI::h('li', [], [
  206. UI::h('i', [ 'class' => "glyphicon glyphicon-home" ]),
  207. " ",
  208. UI::h('a', [ 'href' => $this->getLink() ], "Async jobs"),
  209. ]),
  210. UI::h('li', [], [
  211. UI::h('a', [ 'href' => $this->getLink('list') ], "Lista"),
  212. ]),
  213. UI::h('li', [ 'class' => "active" ], [
  214. "Log dla '{$idJob}'",
  215. ]),
  216. ]);
  217. if ($idJob < 0) throw new Exception("Wrong param idJob");
  218. if ($idJob === 0 && $_GET['idJob'] !== '0') throw new Exception("Wrong param idJob 0");
  219. $out = Core_AsyncJobs::getJobLogs($idJob, 10);
  220. echo UI::h('div', [ 'style' => "background-color:#ddd; padding:4px 12px" ], "Logi dla zadania '{$idJob}'");
  221. echo UI::h('pre', [ 'style' => "border:1px solid #ddd; border-radius:0; padding:12px" ], $out);
  222. }
  223. function pm2KillPostTask() {
  224. $cmd = "pm2 kill";
  225. V::exec($cmd, $out, $ret);
  226. echo "cmd: <code>{$cmd}</code><br>RETURN CODE: '{$ret}'<br><pre>OUTPUT:\n" . implode("\n", $out) . "</pre>";
  227. }
  228. function mp2Start1PostTask() {
  229. $cmd = "pm2 start " . APP_PATH_ROOT . "/../sbin/test-sleep-loop.php --name='test-job-1'";
  230. V::exec($cmd . " 2>&1", $out, $ret);
  231. echo "cmd: <code>{$cmd}</code><br>RETURN CODE: '{$ret}'<br><pre>OUTPUT:\n" . implode("\n", $out) . "</pre>";
  232. }
  233. function mp2Start2PostTask() {
  234. $cmd = "pm2 start " . APP_PATH_ROOT . "/../sbin/test-sleep-loop.php --name='test-job-2'";
  235. V::exec($cmd . " 2>&1", $out, $ret);
  236. echo "cmd: <code>{$cmd}</code><br>RETURN CODE: '{$ret}'<br><pre>OUTPUT:\n" . implode("\n", $out) . "</pre>";
  237. }
  238. function mp2Start3PostTask() {
  239. $jobName = implode("&", [
  240. "ant=default_db.in7_dziennik_koresp/test-bash",
  241. "task=test-loop",
  242. "ns=default_db:IN7_DZIENNIK_KORESP",
  243. "pk=66263",
  244. ]);
  245. $jobNamespace = "p5";
  246. $cmd = implode(" ", [
  247. "pm2 start",
  248. APP_PATH_ROOT . "/../sbin/test-sleep-loop.php",
  249. "--name='{$jobName}'",
  250. "--namespace='{$jobNamespace}'",
  251. ]);
  252. V::exec($cmd . " 2>&1", $out, $ret);
  253. echo "cmd: <code>{$cmd}</code><br>RETURN CODE: '{$ret}'<br><pre>OUTPUT:\n" . implode("\n", $out) . "</pre>";
  254. }
  255. function mp2DeleteStoppedPostTask() {
  256. Core_AsyncJobs::deleteStopped();
  257. UI::alert("DONE");
  258. }
  259. function testReinstallPm2ByWWWPostTask() {
  260. $seBinPath = $this->getSbinPath();
  261. $out = [];
  262. $cmd = "cd '{$seBinPath}' && bash se.sh sudo--install-pm2-www";
  263. V::exec($cmd = "{$cmd} 2>&1", $out, $ret);
  264. echo UI::h('pre', [], "RET({$ret}). OUTPUT:" . "\n" . implode("\n", $out));
  265. if (0 !== $ret) throw new Exception( (empty($out)) ? "Error: backup failed!" : implode("\n", $out) );
  266. if (!file_exists('/usr/local/bin/pm2-www')) {
  267. throw new Exception("Nie udało się zainstalować pm2-www");
  268. } else {
  269. throw new AlertSuccessException("Zainstalowano pm2-www");
  270. }
  271. }
  272. }