getMessage()); } echo UI::h('div', [ 'style' => "padding:12px 0; border-bottom:1px solid #ddd" ], [ UI::hButtonPost("Check", [ 'class' => "btn btn-default", 'title' => "check if async process manager is working", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "pm2Check", ] ]), " ", UI::h('a', [ 'href' => $this->getLink('list'), 'class' => "btn btn-default", ], "Lista"), " ", UI::hButtonPost("pm2 list", [ 'class' => "btn btn-warning", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "pm2List", ] ]), " ", UI::hButtonPost("pm2 kill", [ 'class' => "btn btn-warning", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "pm2Kill", ] ]), " ", UI::hButtonPost("pm2 run1", [ 'class' => "btn btn-warning", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "mp2Start1", ] ]), " ", UI::hButtonPost("pm2 run2", [ 'class' => "btn btn-warning", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "mp2Start2", ] ]), " ", UI::hButtonPost("pm2 run3", [ 'class' => "btn btn-warning", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "mp2Start3", ] ]), " ", UI::hButtonPost("pm2 delete stopped", [ 'class' => "btn btn-warning", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "mp2DeleteStopped", ] ]), " ", UI::hButtonPost("reinstall pm2-www", [ 'class' => "btn btn-warning", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "testReinstallPm2ByWWW", ] ]), " ", UI::hButtonPost("Test", [ 'class' => "btn btn-warning", 'title' => "Test server permissions", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "makeTests", ] ]), ]); $postTask = V::get('_postTask', '', $_POST); switch ($postTask) { case "pm2Check": UI::tryCatchView([ $this, 'pm2CheckPostTask' ]); break; case "pm2List": UI::tryCatchView([ $this, 'pm2ListPostTask' ]); break; case "pm2Kill": UI::tryCatchView([ $this, 'pm2KillPostTask' ]); break; case "mp2Start1": UI::tryCatchView([ $this, 'mp2Start1PostTask' ]); break; case "mp2Start2": UI::tryCatchView([ $this, 'mp2Start2PostTask' ]); break; case "mp2Start3": UI::tryCatchView([ $this, 'mp2Start3PostTask' ]); break; case "mp2DeleteStopped": UI::tryCatchView([ $this, 'mp2DeleteStoppedPostTask' ]); break; case "testReinstallPm2ByWWW": UI::tryCatchView([ $this, 'testReinstallPm2ByWWWPostTask' ]); break; case "makeTests": UI::tryCatchView([ $this, 'makeTestsPostTask' ]); break; } } function pm2CheckPostTask() { $cmd = "pm2 ping"; V::exec($cmd, $out, $ret); echo "cmd: {$cmd}
RETURN CODE: '{$ret}'
OUTPUT:\n" . implode("\n", $out) . "
"; // expected: end($out) === "{ msg: 'pong' }" } function listAction() { UI::layout([ $this, 'listView' ]); } function listView() { echo UI::h('ol', [ 'class' => "breadcrumb", 'style' => "font-size:14px" ], [ UI::h('li', [], [ UI::h('i', [ 'class' => "glyphicon glyphicon-home" ]), " ", UI::h('a', [ 'href' => $this->getLink() ], "Async jobs"), ]), UI::h('li', [ 'class' => "active" ], [ "Lista" ]), UI::h('a', [ 'href' => $this->getLink('list'), 'class' => "pull-right btn btn-link", 'style' => "padding:0; line-height:1em", ], "odśwież"), ]); $postTask = V::get('_postTask', '', $_POST); switch ($postTask) { case "stopJob": UI::tryCatchView([ $this, 'stopJobPostTask' ]); break; case "startJob": UI::tryCatchView([ $this, 'startJobPostTask' ]); break; } echo UI::hTable([ 'rows' => array_map([ $this, 'viewTableRowAsyncJob' ], Core_AsyncJobs::getSimpleList()), ]); } function stopJobPostTask() { $idJob = V::get('idJob', 0, $_POST, 'int'); // $jobInfo['pm_id'], $name = V::get('name', '', $_POST); // $jobInfo['name'], if ($idJob < 0) throw new Exception("Wrong param idJob"); if ($idJob === 0 && $_POST['idJob'] !== '0') throw new Exception("Wrong param idJob 0"); Core_AsyncJobs::stopJob($idJob); } function startJobPostTask() { $idJob = V::get('idJob', 0, $_POST, 'int'); // $jobInfo['pm_id'], $name = V::get('name', '', $_POST); // $jobInfo['name'], if ($idJob < 0) throw new Exception("Wrong param idJob"); if ($idJob === 0 && $_POST['idJob'] !== '0') throw new Exception("Wrong param idJob 0"); Core_AsyncJobs::startJob($idJob); } function pm2ListPostTask() { $cmd = "pm2 list"; V::exec($cmd, $out, $ret); echo "cmd: {$cmd}
RETURN CODE: '{$ret}'
OUTPUT:\n" . implode("\n", $out) . "
"; $cmd = "pm2 jlist"; V::exec($cmd, $out, $ret); echo "cmd: {$cmd}
RETURN CODE: '{$ret}'
OUTPUT:\n" . implode("\n", $out) . "
"; echo '
'; $parsedJobList = Core_AsyncJobs::getFullList(); DBG::nicePrint($parsedJobList, "\$parsedJobList"); echo '
'; UI::table([ 'rows' => array_map([ $this, 'viewTableRowAsyncJob' ], Core_AsyncJobs::getSimpleList()), ]); } function viewTableRowAsyncJob($jobInfo) { return [ 'name' => $jobInfo['name'], 'pid' => $jobInfo['pid'], 'pm_id' => $jobInfo['pm_id'], 'status' => $jobInfo['pm2_env.status'], 'memory' => $jobInfo['monit.memory'], 'cpu' => $jobInfo['monit.cpu'], '#' => UI::h(null, [], [ UI::h('a', [ 'href' => $this->getLink('jobLog', [ 'idJob' => $jobInfo['pm_id'], 'name' => $jobInfo['name'], ]), 'class' => "btn btn-xs btn-warning", ], "logi"), " ", UI::hButtonPost("stop", [ 'class' => "btn btn-xs btn-default", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "stopJob", 'idJob' => $jobInfo['pm_id'], 'name' => $jobInfo['name'], ] ]), " ", UI::hButtonPost("start", [ 'class' => "btn btn-xs btn-default", 'data' => [ '_route' => 'AsyncJobs', '_postTask' => "startJob", 'idJob' => $jobInfo['pm_id'], 'name' => $jobInfo['name'], ] ]), ]), ]; } function jobLogAction() { UI::layout([ $this, 'jobLogView' ]); } function jobLogView() { $idJob = V::get('idJob', 0, $_GET, 'int'); // $jobInfo['pm_id'], $name = V::get('name', '', $_GET); // $jobInfo['name'], echo UI::h('ol', [ 'class' => "breadcrumb", 'style' => "font-size:14px" ], [ UI::h('li', [], [ UI::h('i', [ 'class' => "glyphicon glyphicon-home" ]), " ", UI::h('a', [ 'href' => $this->getLink() ], "Async jobs"), ]), UI::h('li', [], [ UI::h('a', [ 'href' => $this->getLink('list') ], "Lista"), ]), UI::h('li', [ 'class' => "active" ], [ "Log dla '{$idJob}'", ]), ]); if ($idJob < 0) throw new Exception("Wrong param idJob"); if ($idJob === 0 && $_GET['idJob'] !== '0') throw new Exception("Wrong param idJob 0"); $out = Core_AsyncJobs::getJobLogs($idJob, 10); echo UI::h('div', [ 'style' => "background-color:#ddd; padding:4px 12px" ], "Logi dla zadania '{$idJob}'"); echo UI::h('pre', [ 'style' => "border:1px solid #ddd; border-radius:0; padding:12px" ], $out); } function pm2KillPostTask() { $cmd = "pm2 kill"; V::exec($cmd, $out, $ret); echo "cmd: {$cmd}
RETURN CODE: '{$ret}'
OUTPUT:\n" . implode("\n", $out) . "
"; } function mp2Start1PostTask() { $cmd = "pm2 start " . APP_PATH_ROOT . "/../sbin/test-sleep-loop.php --name='test-job-1'"; V::exec($cmd . " 2>&1", $out, $ret); echo "cmd: {$cmd}
RETURN CODE: '{$ret}'
OUTPUT:\n" . implode("\n", $out) . "
"; } function mp2Start2PostTask() { $cmd = "pm2 start " . APP_PATH_ROOT . "/../sbin/test-sleep-loop.php --name='test-job-2'"; V::exec($cmd . " 2>&1", $out, $ret); echo "cmd: {$cmd}
RETURN CODE: '{$ret}'
OUTPUT:\n" . implode("\n", $out) . "
"; } function mp2Start3PostTask() { $jobName = implode("&", [ "ant=default_db.in7_dziennik_koresp/test-bash", "task=test-loop", "ns=default_db:IN7_DZIENNIK_KORESP", "pk=66263", ]); $jobNamespace = "p5"; $cmd = implode(" ", [ "pm2 start", APP_PATH_ROOT . "/../sbin/test-sleep-loop.php", "--name='{$jobName}'", "--namespace='{$jobNamespace}'", ]); V::exec($cmd . " 2>&1", $out, $ret); echo "cmd: {$cmd}
RETURN CODE: '{$ret}'
OUTPUT:\n" . implode("\n", $out) . "
"; } function mp2DeleteStoppedPostTask() { Core_AsyncJobs::deleteStopped(); UI::alert("DONE"); } function makeTestsPostTask() { $seBinPath = $this->getSbinPath(); $listTest = []; // [ [ ret_code, cmd ], ... ] $listTest[] = [ 0, "cd '{$seBinPath}' && bash ./se.sh test-exit-0" ]; $listTest[] = [ 1, "cd '{$seBinPath}' && bash ./se.sh test-exit-1" ]; $listTest[] = [ 1, "cd '{$seBinPath}' && bash ./se.sh test-sudo" ]; $listTest[] = [ 0, "cd '{$seBinPath}' && bash ./se.sh --sudo test-sudo" ]; // $cmd = "cd '{$seBinPath}' && bash se.sh install-pm2-www"; // DBG: require root, add prefix 'sudo--' // $cmd = "cd '{$seBinPath}' && bash ./se.sh --sudo install-pm2-www"; // $cmd = "cd '{$seBinPath}' && bash se.sh install-pm2-www"; // expected Permission denied - missing sudo // $cmd = "cd '{$seBinPath}' && bash se.sh sudo "; // expected Missing script name + usage // $cmd = "cd '{$seBinPath}' && bash se.sh non-existing-script"; // expecte Module not exists + usage // $cmd = "cd '{$seBinPath}' && bash se.sh "; // expected usage foreach ($listTest as $idx => $test) { list($expected, $cmd) = $test; $out = []; V::exec($cmd = "{$cmd} 2>&1", $out, $ret); echo UI::h('details', [], [ UI::h('summary', [], "test {$idx} " . (($expected === $ret) ? "SUCCESS" : "FAILED")), UI::h('div', [], [ UI::h('pre', [], "RET({$ret}). OUTPUT:" . "\n" . implode("\n", $out)), UI::h('div', [ 'class' => "alert alert-info" ], "test ({$ret})" . "\n
" . implode("\n
", $out) ), ($expected === $ret) ? UI::h('div', [ 'class' => 'alert alert-success' ], "OK: script return as expected!") : UI::h('div', [ 'class' => 'alert alert-danger' ], "FAIL: script return '{$ret}' but expected '{$expected}'!") , ]), ]); } } function testReinstallPm2ByWWWPostTask() { $seBinPath = $this->getSbinPath(); $out = []; $cmd = "cd '{$seBinPath}' && bash ./se.sh --sudo install-pm2-www"; V::exec($cmd = "{$cmd} 2>&1", $out, $ret); echo UI::h('pre', [], "RET({$ret}). OUTPUT:" . "\n" . implode("\n", $out)); if (0 !== $ret) throw new Exception( (empty($out)) ? "Error: install pm2-www failed! ({$ret})" : implode("\n
", $out) ); if (!file_exists('/usr/local/bin/pm2-www')) { throw new Exception("Nie udało się zainstalować pm2-www"); } else { throw new AlertSuccessException("Zainstalowano pm2-www"); } } }