Install.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. Lib::loadClass('UI');
  4. //TODO install nie kopiuje aktualnej /config/.config_base_structure.php @2017-09-24 bindera - sprawdzone na medicalu
  5. class Route_Install extends RouteBase {
  6. public function handleAuth() {
  7. if (!User::logged()) {
  8. throw new HttpException('Unauthorized', 401);
  9. }
  10. if (!User::isAdmin()) {
  11. throw new HttpException('Unauthorized - only for administrators', 401);
  12. }
  13. }
  14. public function defaultAction() {
  15. UI::gora();
  16. UI::menu();
  17. $this->menu();
  18. UI::dol();
  19. }
  20. public function menu() {
  21. $serversList = $this->fetchActiveLicences();
  22. ?>
  23. <div class="jumbotron">
  24. <div class="container">
  25. <form class="form-inline" method="GET">
  26. <input type="hidden" name="_route" value="Install" />
  27. <input type="hidden" name="_task" value="createApp" />
  28. <label>Przygotuj kod źródłowy do aktualizacji na serwerze klienta:</label>
  29. <select id="servers_list" class="form-control" name="licence_id">
  30. <?php foreach ($serversList as $srv) : ?>
  31. <option value="<?php echo $srv->ID; ?>">[<?php echo $srv->ID; ?>] <?php echo $srv->domain; ?></option>
  32. <?php endforeach; ?>
  33. </select>
  34. <button type="submit" id="fldSbmtBtn" class="btn btn-primary" autocomplete="off">
  35. Generuj
  36. </button>
  37. <div id="servers_list_react"></div>
  38. </form>
  39. </div>
  40. </div>
  41. <script type="text/javascript">
  42. jQuery(document).ready(function () {
  43. jQuery('#fldSbmtBtn').on('click', function () {
  44. jQuery(this).text(jQuery(this).text() + '...').attr('disabled', 'disabled');
  45. jQuery(this).parent().submit();
  46. })
  47. });
  48. </script>
  49. <?php
  50. echo UI::h('script', ['src'=>"static/vendor.js", 'type'=>"text/javascript"]);
  51. // echo UI::h('script', ['src'=>"https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js", 'type'=>"text/javascript"]);
  52. // echo UI::h('script', ['src'=>"https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js", 'type'=>"text/javascript"]);
  53. // echo UI::h('script', ['src'=>"https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap-typeahead/0.10.4/react-bootstrap-typeahead.js", 'type'=>"text/javascript"]);
  54. $jsonServersList = array_values(array_map(
  55. function ($srv) {
  56. return [
  57. 'id' => $srv->ID,
  58. 'label' => "{$srv->domain} [{$srv->ID}]"
  59. ];
  60. },
  61. $serversList
  62. ));
  63. echo UI::h('script', ['type'=>"text/javascript"], "
  64. (function(global){
  65. if (!global.p5VendorJs) { console.warn('Brak p5VendorJs'); return; }
  66. if (!global.p5VendorJs.React) { console.warn('Brak p5VendorJs.React'); return; }
  67. if (!global.p5VendorJs.ReactDOM) { console.warn('Brak p5VendorJs.ReactDOM'); return; }
  68. if (!global.p5VendorJs.Typeahead) { console.warn('Brak p5VendorJs.Typeahead'); return; }
  69. const React = global.p5VendorJs.React;
  70. const ReactDOM = global.p5VendorJs.ReactDOM;
  71. const Typeahead = global.p5VendorJs.Typeahead;
  72. var options = ".json_encode($jsonServersList).";
  73. var selected = [];
  74. var onInputChange = function (query) {
  75. // console.log('onInputChange:: query', query);
  76. }
  77. var onChange = function (value) {
  78. // console.log('onChange:: value', value);
  79. if (value.length > 0) {
  80. var id = value[0]['id'];
  81. if (id > 0) {
  82. document.getElementById('servers_list').value = id;
  83. }
  84. }
  85. }
  86. ReactDOM.render(
  87. React.createElement(Typeahead, {
  88. options: options,
  89. emptyLabel: 'Brak danych',
  90. placeholder: 'Wybierz serwer',
  91. selected: selected,
  92. // onInputChange: onInputChange,
  93. onChange: onChange,
  94. }, null),
  95. document.getElementById('servers_list_react')
  96. );
  97. })(window);
  98. ");
  99. }
  100. public function createAppAction() {
  101. session_write_close();
  102. $args = array();
  103. $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int');
  104. UI::gora();
  105. UI::menu();
  106. //$this->menu($args['licence_id']);// TODO: GO BACK BTN
  107. try {
  108. $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']);
  109. } catch (Exception $e) {
  110. $this->_endWithException($e);
  111. }
  112. //$this->generateApp($args['licence_id']);
  113. //DBG::_(true, true, "appLicenceInfo", $appLicenceInfo, __CLASS__, __FUNCTION__, __LINE__);
  114. ?>
  115. <div class="jumbotron">
  116. <div class="container">
  117. <h3>Generowanie aplikacji dla licencji <?php echo $appLicenceInfo->ID; ?></h3>
  118. <p>Licencja dla domen: <?php echo implode(', ', $appLicenceInfo->domains); ?></p>
  119. <p>Katalog z zakodowanymi plikami: <?php echo $appLicenceInfo->installFolderName; ?></p>
  120. <form class="form-inline" method="POST">
  121. <input type="hidden" name="_task" value="createApp" />
  122. <input type="hidden" name="licence_id" value="<?php echo $appLicenceInfo->ID; ?>" />
  123. <input type="hidden" name="_generateEncryptedSource" value="1" />
  124. <button type="submit" id="fldSbmtBtn" class="btn btn-primary" autocomplete="off">
  125. Generuj
  126. </button>
  127. </form>
  128. <?php if ($appLicenceInfo->installFolderGitExists) : ?>
  129. <br>
  130. <div class="alert alert-info">
  131. Katalog istnieje i zawiera już repozytorium git:
  132. <br> - <a href="index.php?_route=Install&_task=gitResetHard&licence_id=<?php echo $appLicenceInfo->ID; ?>"
  133. target="_blank"
  134. class="btn btn-xs btn-default">aktualizuj werjsę</a> (git reset --hard, git pull, set SE/VERSION - tak samo co 'rm -rf; git clone', ale szybciej)
  135. <br> - <a href="index.php?_route=Install&_task=encodeSource&licence_id=<?php echo $appLicenceInfo->ID; ?>"
  136. target="_blank"
  137. class="btn btn-xs btn-default">encode files</a>
  138. <br> - <a href="index.php?_route=Install&_task=sendToRemoteTestDir&licence_id=<?php echo $appLicenceInfo->ID; ?>"
  139. target="_blank"
  140. class="btn btn-xs btn-default">send encoded files to remote server test folder (generates ssh key if not set)</a>
  141. <p style="margin-top:30px">
  142. Test online: <a target="_blank" href="https://<?php echo $appLicenceInfo->mainServer; ?>/se.encrypted.upgrade/">https://<?php echo $appLicenceInfo->mainServer; ?>/se.encrypted.upgrade/</a>
  143. </p>
  144. <br> - <a href="index.php?_route=Install&_task=upgradeRemoteFromTestDir&licence_id=<?php echo $appLicenceInfo->ID; ?>"
  145. onclick="return confirm('Uruchomić aktualizację SE na https://<?php echo $appLicenceInfo->mainServer; ?>/SE/?')"
  146. target="_blank"
  147. class="btn btn-xs btn-warning">UPGRADE Production folder from uploaded dir: ~/se.encrypted.upgrade/</a>
  148. </div>
  149. <?php endif; ?>
  150. </div>
  151. </div>
  152. <script type="text/javascript">
  153. jQuery(document).ready(function () {
  154. jQuery('#fldSbmtBtn').on('click', function () {
  155. jQuery(this).text(jQuery(this).text() + '...').attr('disabled', 'disabled');
  156. jQuery(this).parent().submit();
  157. })
  158. });
  159. </script>
  160. <?php
  161. $generateEncryptedSource = (1 == V::get('_generateEncryptedSource', 0, $_REQUEST, 'int'));
  162. if ($generateEncryptedSource) {
  163. echo '<div class="container">';
  164. echo '<h4>' . "Generowanie..." . '</h4>';
  165. echo '<div style="border:1px solid silver; max-height:400px; overflow-y:scroll">';
  166. try {
  167. $this->generateApp($appLicenceInfo);
  168. } catch (Exception $e) {
  169. echo '</div></div>';// .container/ scroll
  170. $this->_endWithException($e);
  171. }
  172. echo '</div>';// .container
  173. UI::alert('success', "<strong>Gotowe</strong> Aplikacja znajduje się w katalogu {$appLicenceInfo->installFolderName}");
  174. }
  175. UI::dol();
  176. }
  177. public function gitResetHardAction() {
  178. session_write_close();
  179. $args = array();
  180. $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int');
  181. UI::gora();
  182. UI::menu();
  183. //$this->menu($args['licence_id']);// TODO: GO BACK BTN
  184. try {
  185. $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']);
  186. if (empty($appLicenceInfo->ID)) throw new Exception("Nie wybrano serwera/licencji.");
  187. if (empty($appLicenceInfo->domains)) throw new Exception("Domains not found");
  188. if (empty($appLicenceInfo->installPath)) throw new Exception("Install path not found");
  189. UI::startContainer();
  190. $this->gitResetHard($appLicenceInfo->installPath);
  191. UI::endContainer();
  192. } catch (Exception $e) {
  193. $this->_endWithException($e);
  194. }
  195. UI::dol();
  196. }
  197. public function gitResetHard($installPath) {
  198. if (empty($installPath)) throw new Exception("Install path not found");
  199. $cmds = array();
  200. $cmds[] = "git reset --hard";
  201. $cmds[] = "git pull";
  202. $cmds[] = "echo `git show-ref --head|head -1|head -c 8` > SE/VERSION ";
  203. $hasError = false;
  204. foreach ($cmds as $cmd) {
  205. $out = ''; $ret = '';
  206. exec("cd {$installPath} && {$cmd}", $out, $ret);
  207. if (0 !== $ret) $hasError = true;
  208. DBG::nicePrint($out, "cmd: `{$cmd}` (return:{$ret})");
  209. }
  210. if (!$hasError) {
  211. UI::alert('success', "OK");
  212. } else {
  213. UI::alert('danger', "errors");
  214. }
  215. }
  216. public function encodeSourceAction() {
  217. session_write_close();
  218. $args = array();
  219. $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int');
  220. UI::gora();
  221. UI::menu();
  222. //$this->menu($args['licence_id']);// TODO: GO BACK BTN
  223. try {
  224. $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']);
  225. $this->_encodeSource($appLicenceInfo);
  226. } catch (Exception $e) {
  227. $this->_endWithException($e);
  228. }
  229. UI::dol();
  230. }
  231. public function _encodeSource($appLicenceInfo) {
  232. if (empty($appLicenceInfo->ID)) throw new Exception("Nie wybrano serwera/licencji.");
  233. if (empty($appLicenceInfo->domains)) throw new Exception("Domains not found");
  234. if (empty($appLicenceInfo->installPath)) throw new Exception("Install path not found");
  235. UI::startContainer();
  236. $this->encodeSourceFiles($appLicenceInfo->installPath, $appLicenceInfo->domains, $dbg = true);
  237. // try {
  238. // $this->encodeSourceFiles($appLicenceInfo->installPath, $appLicenceInfo->domains, $dbg = false);
  239. // UI::alert('success', "OK");
  240. // } catch (Exception $e) {
  241. // UI::alert('danger', $e->getMessage());
  242. // }
  243. UI::endContainer();
  244. }
  245. // @usage: Router::getRoute('Install')->encodeSourceFiles($installPath = '/path_to_git_repo', $domains = [ 'domain.com', 'localhost' ], $dbg = false);
  246. public function encodeSourceFiles($installPath, $domains, $dbg = false) {
  247. if (empty($installPath)) throw new Exception("Install path not found");
  248. if (empty($domains)) throw new Exception("Domains not found");
  249. $phpVersionsForSgencoder = '--phpversion 5.5 --phpversion 5.6';// encode for PHP 5.x (currently supported PHP 5.0-5.6)
  250. if ('1' == V::get('DBG_ENCODER_HELP', '', $_REQUEST)) {// encoder help
  251. $cmd = "cd {$installPath}/SE && /Applications/SourceGuardian.app/Contents/MacOS/sgencoder --help ";
  252. $out = ''; $ret = '';
  253. exec($cmd, $out, $ret);
  254. DBG::nicePrint($out, "cmd: `{$cmd}` (return:{$ret})");
  255. exit;
  256. }
  257. $domainEncodePhpFiles = [
  258. 'ant.php',
  259. 'api.php',
  260. 'budynki.php',
  261. 'index-ajax.php',
  262. 'index.php',
  263. 'procesy5.php',
  264. 'session-expire.php',
  265. 'test-sync.php',
  266. 'wfs-data.php',
  267. 'wfs-qgis.php',
  268. 'wfs.php',
  269. ];
  270. $cmd = "find . -name '*.php' ";
  271. $out = ''; $ret = '';
  272. exec("cd {$installPath}/SE && {$cmd}", $out, $ret);
  273. if ($dbg) DBG::nicePrint($out, "cmd: `{$cmd}` (return:{$ret})");
  274. else DBG::log($out, 'array', "cmd: `{$cmd}` (return:{$ret})");
  275. if (0 !== $ret) throw new Exception("Error at find php files");
  276. if (empty($out)) throw new Exception("No php files found");
  277. $allPhpFiles = array_map(function ($phpFilePath) {
  278. return ('./' == substr($phpFilePath, 0, 2))? substr($phpFilePath, 2) : $phpFilePath;
  279. }, $out);
  280. $freeEncodePhpFiles = array_filter($allPhpFiles, function ($phpFilePath) use ($domainEncodePhpFiles) {
  281. if ('se-lib/Vendor/' === substr($phpFilePath, 0, strlen('se-lib/Vendor/'))) return false; // SKIP se-lib/Vendor/*
  282. if ('.ini.php' === substr($phpFilePath, -1 * strlen('.ini.php'))) return false; // SKIP *.ini.php
  283. return (!in_array($phpFilePath, $domainEncodePhpFiles));
  284. });
  285. DBG::log($freeEncodePhpFiles, 'array', "\$freeEncodePhpFiles");
  286. if (empty($freeEncodePhpFiles)) throw new Exception("No php files to encode");
  287. $cmdTempl = "cd {$installPath}/SE && /Applications/SourceGuardian.app/Contents/MacOS/sgencoder {$phpVersionsForSgencoder} -b- ";
  288. $cmdDomainEncodeDomainsTempl = " --domain " . implode(" --domain ", array_merge($domains, ['localhost']));
  289. $cmdDomainEncodeFilesTempl = " " . implode(" ", $domainEncodePhpFiles);
  290. $cmdFreeEncodeFilesTempl = " " . implode(" ", $freeEncodePhpFiles);
  291. $cmds = [
  292. $cmdTempl . $cmdDomainEncodeDomainsTempl . $cmdDomainEncodeFilesTempl,
  293. $cmdTempl . $cmdFreeEncodeFilesTempl,
  294. ];
  295. $returnValues = [];
  296. foreach ($cmds as $cmd) {
  297. $out = ''; $ret = '';
  298. exec($cmd, $out, $ret);
  299. $encoderSummaryLine = end($out);
  300. $returnValues[] = $encoderSummaryLine;
  301. if ($dbg) {
  302. DBG::nicePrint([$cmd], "cmd");
  303. DBG::nicePrint($out, "return: '{$ret}'");
  304. // DBG::nicePrint([$encoderSummaryLine], "cmd last line");
  305. }
  306. else DBG::log([$cmd, $out], 'array', "cmd return:'{$ret}'");
  307. // if (0 !== $ret) throw new Exception("Error at encode files");
  308. if (empty($out)) throw new Exception("No output for encode files command");
  309. }
  310. $statusInfo = array_reduce($returnValues, function ($ret, $encoderSummaryLine) {
  311. DBG::log([$ret, $encoderSummaryLine], 'array', "DBG reduce [\$ret, \$encoderSummaryLine]");
  312. $matches = [];
  313. preg_match_all('/(\d+) files, (\d+) processed, (\d+) errors/', $encoderSummaryLine, $matches, PREG_SET_ORDER, 0);
  314. return [
  315. 'files' => $ret['files'] + (int)$matches[0][1],
  316. 'processed' => $ret['processed'] + (int)$matches[0][2],
  317. 'errors' => $ret['errors'] + (int)$matches[0][3],
  318. ];
  319. }, [
  320. 'files' => 0,
  321. 'processed' => 0,
  322. 'errors' => 0,
  323. ]);
  324. if ($statusInfo['errors'] === 0 && $statusInfo['files'] > 0) {
  325. if ($dbg) UI::alert('success', "{$statusInfo['files']} files, {$statusInfo['processed']} processed, {$statusInfo['errors']} errors");
  326. } else {
  327. if ($dbg) UI::alert('danger', "{$statusInfo['files']} files, {$statusInfo['processed']} processed, {$statusInfo['errors']} errors");
  328. else throw new Exception("{$statusInfo['files']} files, {$statusInfo['processed']} processed, {$statusInfo['errors']} errors");
  329. }
  330. }
  331. public function getAppLicenceInfo($idLicence) {
  332. $idLicence = intval($idLicence);
  333. if (empty($idLicence)) throw new Exception("Nie wybrano serwera/licencji.");
  334. //DBG::_(true, true, 'idLicence', $idLicence, __CLASS__, __FUNCTION__, __LINE__);
  335. $appLicenceInfo = (object)$this->fetchAppLicenceInfo($idLicence);
  336. $appLicenceInfo->domains = $this->fetchDomainsByLicenceId($idLicence);
  337. $installRootPath = '/Library/Server/Web/Data/Sites/Default/PLIKI/SES_PROCESY5_A';
  338. $appLicenceInfo->installFolderName = "{$idLicence}_upgrade_SE_source_encrypted";
  339. $appLicenceInfo->installPath = "{$installRootPath}/{$appLicenceInfo->installFolderName}";
  340. //DBG::_(true, true, 'appLicenceInfo', $appLicenceInfo, __CLASS__, __FUNCTION__, __LINE__);
  341. if (empty($appLicenceInfo->domains)) throw new Exception("Domains not found.");
  342. $appLicenceInfo->installFolderExists = file_exists("{$appLicenceInfo->installPath}/SE");
  343. $appLicenceInfo->installFolderGitExists = file_exists("{$appLicenceInfo->installPath}/.git");
  344. return $appLicenceInfo;
  345. }
  346. public function generateApp($appLicenceInfo) {
  347. if (empty($appLicenceInfo->ID)) throw new Exception("Nie wybrano serwera/licencji.");
  348. if (empty($appLicenceInfo->domains)) throw new Exception("Domains not found");
  349. $installPath = $appLicenceInfo->installPath;
  350. if (empty($installPath)) throw new Exception("Install path not found");
  351. $cmds = array();
  352. $cmds[] = "if [ -d {$installPath} ] ; then rm -rf '{$installPath}'; fi";
  353. $cmds[] = "mkdir {$installPath}";
  354. $cmds[] = "cd {$installPath} && git clone ssh://git@biuro.biall-net.pl:2222/plabudda/se.git .";
  355. $cmds[] = "cd {$installPath} && echo `git show-ref --head|head -1|head -c 8` > SE/VERSION ";
  356. //echo'<pre>cmds: ';print_r($cmds);echo'</pre>';
  357. foreach ($cmds as $cmd) {
  358. $out = ''; $ret = '';
  359. exec($cmd, $out, $ret);
  360. echo'<pre>cmd: '. $cmd . ': (return:'.$ret.')'."\n";print_r($out);echo'</pre>';
  361. }
  362. $this->_encodeSource($appLicenceInfo);
  363. // 1763: $exec='cd '.$installer_dir.' && /Applications/SourceGuardian.app/Contents/MacOS/sgencoder -b-
  364. // '.INSTALL_SES_PROCESY_A::get_same_domains_for_install($h->SERVER_ADDRESS_SHORT).'
  365. // -r *.php
  366. // -x superedit-DB_PROCEDURES_CREATE.php
  367. // -x INI.php
  368. // -x .config_base_structure.php
  369. // ';
  370. //
  371. // INSTALL_SES_PROCESY_A::get_same_domains_for_install($h->SERVER_ADDRESS_SHORT):
  372. // $res2=DB::query("select SERVER_ADDRESS_SHORT from SES_PROCESY5_A where SERVER_ADDRESS_IP='".$h->SERVER_ADDRESS_IP."'");
  373. // while($h2=DB::fetch($res2)) {
  374. // $domain[]=' --domain '.$h2->SERVER_ADDRESS_SHORT;
  375. // ssh server@biuro.galeriaprzymorze.eu: PHP 5.5.20
  376. // ssh server@biuro.biall-net.pl
  377. // cd /Users/plabudda/procesy5-install-galeriaprzymorze.eu/
  378. // sudo chown -R server:admin SE/
  379. // /Applications/SourceGuardian.app/Contents/MacOS/sgencoder --phpversion 5.5 -b- --domain galeriaprzymorze.eu -r SE/*.php SE/se-lib/*.php SE/se-lib/*/*.php SE/se-lib/*/*/*.php SE/procesy/*.php SE/odt2xhtml/*.php -x superedit-DB_PROCEDURES_CREATE.php -x INI.php -x .config_base_structure.php
  380. }
  381. public function fetchActiveLicences() {
  382. $activeLic = array();
  383. $sql = "
  384. select l.`ID`
  385. , l.`SERVER_ADDRESS`
  386. , l.`SERVER_ADDRESS_SHORT` as domain -- domain for sgencoder
  387. , l.`SERVER_ADDRESS_IP`
  388. from `SES_PROCESY5_A` l
  389. where 1=1
  390. -- TODO: and l.`A_STATUS` in('NORMAL','WAITING')
  391. order by l.`ID` DESC
  392. ";
  393. $rows = DB::getPDO()->fetchAll($sql);
  394. foreach ($rows as $row) {
  395. $r = (object)$row;
  396. $activeLic[$r->ID] = $r;
  397. }
  398. return $activeLic;
  399. }
  400. public function fetchDomainsByLicenceId($licenceId) {
  401. $domains = array();
  402. $sql = "
  403. select g.`SERVER_ADDRESS_SHORT`, g.`SERVER_ADDRESS`
  404. from `SES_PROCESY5_A` g
  405. where g.`SERVER_ADDRESS_IP`=(select l.`SERVER_ADDRESS_IP`
  406. from `SES_PROCESY5_A` l
  407. where l.`ID`='{$licenceId}'
  408. -- TODO: and l.`A_STATUS` in('NORMAL','WAITING')
  409. )
  410. -- TODO: and g.`A_STATUS` in('NORMAL','WAITING')
  411. ";
  412. $rows = DB::getPDO()->fetchAll($sql);
  413. foreach ($rows as $row) {
  414. $r = (object)$row;
  415. $domains[] = $r->SERVER_ADDRESS_SHORT;
  416. if ($r->SERVER_ADDRESS != $r->SERVER_ADDRESS_SHORT) {
  417. $domains[] = $r->SERVER_ADDRESS;
  418. }
  419. }
  420. return $domains;
  421. }
  422. public function fetchMainServerByLicenceId($licenceId) {
  423. return DB::getPDO()->fetchValue("
  424. select g.`SERVER_ADDRESS`
  425. from `SES_PROCESY5_A` g
  426. where g.`ID`='{$licenceId}'
  427. -- TODO: and g.`A_STATUS` in('NORMAL','WAITING')
  428. ");
  429. }
  430. public function fetchAppLicenceInfo($licenceId) {
  431. $licenceInfo = null;
  432. $sql = "
  433. select g.ID
  434. , g.SERVER_ADDRESS as mainServer
  435. , g.ADMIN_USERNAME as rootLogin
  436. , g.ADMIN_USERNAME_PASSWD as rootPassword
  437. , g.SSH_PORT as sshPort
  438. from SES_PROCESY5_A g
  439. where g.`ID`=:id_licence
  440. -- TODO: and g.A_STATUS in('NORMAL','WAITING')
  441. ";
  442. $all = DB::getPDO()->fetchAll($sql, [ ':id_licence' => $licenceId ]);
  443. if (empty($all)) throw new Exception("Brak licencji o nr '{$licenceId}'");
  444. $licenceInfo = reset($all);
  445. if (!$licenceInfo['sshPort']) $licenceInfo['sshPort'] = 22;
  446. return $licenceInfo;
  447. }
  448. public function _endWithException($e) {
  449. echo UI::h('div', ['class'=>"container"], [
  450. UI::h('div', ['class' => "alert alert-danger"], "#" . $e->getLine() . ": " . $e->getMessage()),
  451. UI::h('p', [], [
  452. "Wróć do ",
  453. UI::h('a', ['href'=>"index.php?_route=Install"], "menu")
  454. ])
  455. ]);
  456. UI::dol();
  457. exit;
  458. }
  459. public function sendToRemoteTestDirAction() {
  460. session_write_close();
  461. $args = array();
  462. $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int');
  463. UI::gora();
  464. //UI::menu();
  465. //$this->menu($args['licence_id']);// TODO: GO BACK BTN
  466. try {
  467. $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']);
  468. // TODO: if (59 ) => baratosz.sledz - na lokalnym kompie
  469. // bn:~/$ scp -r SE server@192.168.61.153:~/se.encrypted.upgrade
  470. // remote SE.git = '/Users/bartoszsledz/Desktop/production-se'
  471. // remote:~/$ mv SE ~/SE.bup.2017-07-03
  472. // remote:~/$ mv ~/se.encrypted.upgrade/SE SE
  473. // remote:~/$ cp -r ~/SE.bup.2017-07-03/config SE/
  474. // remote:~/$ sudo chown -R bartoszsledz:staff SE/
  475. $this->_sendToRemoteTestDir($appLicenceInfo);
  476. echo "Test online: ";
  477. echo UI::h('a', ['target'=>"_blank", 'href'=>"https://{$appLicenceInfo->mainServer}/se.encrypted.upgrade/"], "https://{$appLicenceInfo->mainServer}/se.encrypted.upgrade/");
  478. } catch (Exception $e) {
  479. $this->_endWithException($e);
  480. }
  481. UI::dol();
  482. }
  483. public function _fetchRemoteHomeDir($appLicenceInfo) {
  484. $this->_assertRsaKeyExists($appLicenceInfo);
  485. $sshHostUsr = "{$appLicenceInfo->rootLogin}@{$appLicenceInfo->mainServer}";
  486. $sshArgs = (22 != $appLicenceInfo->sshPort)? "-p {$appLicenceInfo->sshPort}" : '';
  487. $rsyncSshPort = (22 != $appLicenceInfo->sshPort)? "-e 'ssh -p {$appLicenceInfo->sshPort}'" : '';
  488. if (V::get('DBG_REMOTE', '', $_GET)) {// DBG
  489. $cmd = "echo ~";
  490. V::exec("ssh {$sshArgs} {$sshHostUsr} '{$cmd}'", $out, $ret);
  491. DBG::_(true, true, "exec(ssh ... 'cmd'): {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  492. V::execRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort);
  493. DBG::_(true, true, "execRemote(cmd): {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  494. V::execRootRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort);
  495. DBG::_(true, true, "execRootRemote(cmd): {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  496. }
  497. $cmd = "echo ~";
  498. V::exec("ssh {$sshArgs} {$sshHostUsr} '{$cmd}'", $out, $ret);
  499. DBG::_(true, true, "exec(ssh ... '{$cmd}') (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  500. if (empty($out) || empty($out[0])) throw new Exception("Cannot fetch remote home dir");
  501. return $out[0];
  502. }
  503. public function _sendToRemoteTestDir($appLicenceInfo) {
  504. $cmd = ''; $out = ''; $ret = '';
  505. $this->_assertRsaKeyExists($appLicenceInfo);
  506. $sshHostUsr = "{$appLicenceInfo->rootLogin}@{$appLicenceInfo->mainServer}";
  507. $sshArgs = (22 != $appLicenceInfo->sshPort)? "-p {$appLicenceInfo->sshPort}" : '';
  508. $rsyncSshPort = (22 != $appLicenceInfo->sshPort)? "-e 'ssh -p {$appLicenceInfo->sshPort}'" : '';
  509. // $appLicenceInfo->sshPort
  510. /* rsync options:
  511. -a, --archive archive mode; same as -rlptgoD (no -H)
  512. -u, --update skip files that are newer on the receiver
  513. -t, --times preserve times
  514. --delete delete extraneous files from dest dirs
  515. */
  516. DBG::_(true, true, "remote home dir:", $this->_fetchRemoteHomeDir($appLicenceInfo), __CLASS__, __FUNCTION__, __LINE__);
  517. $cmd = "
  518. ssh {$sshArgs} {$sshHostUsr} '[ ! -d ~/se.encrypted.upgrade ] && mkdir ~/se.encrypted.upgrade || echo 1';
  519. ssh {$sshArgs} {$sshHostUsr} 'rm -rf ~/se.encrypted.upgrade/SE';
  520. ssh {$sshArgs} {$sshHostUsr} 'cp -r /Library/Server/Web/Data/Sites/Default/SE ~/se.encrypted.upgrade/SE';
  521. ssh {$sshArgs} {$sshHostUsr} 'rm -rf ~/se.encrypted.upgrade/SE/config';
  522. rsync --archive --times --delete --compress --one-file-system --omit-dir-times --no-g --no-perms \
  523. --verbose {$rsyncSshPort} \
  524. --exclude='stuff/qgis__kyngchaos.com' \
  525. --exclude='stuff/qgis__kyngchaos.com/QGIS-2.14.3-1.dmg' \
  526. --exclude='stuff/postgis' \
  527. --exclude='stuff/postgis2' \
  528. --exclude='stuff/KindleGen_Mac_i386_v2_9' \
  529. --exclude='stuff/jdk-8u121-macosx-x64.dmg' \
  530. --exclude='stuff/jre-8u112-macosx-x64.tar.gz' \
  531. --exclude='stuff/jre-8u121-macosx-x64.dmg' \
  532. --exclude='schema/default_db.instance.xml' \
  533. --exclude='schema/default_db_xml_cache.public' \
  534. --exclude='schema/default_db.instance.xml/**' \
  535. --exclude='schema/default_db_xml_cache.public/**' \
  536. '{$appLicenceInfo->installPath}/SE/' {$sshHostUsr}:~/se.encrypted.upgrade/SE/;
  537. ssh {$sshArgs} {$sshHostUsr} 'cp -r /Library/Server/Web/Data/Sites/Default/SE/config ~/se.encrypted.upgrade/SE/';
  538. ssh {$sshArgs} {$sshHostUsr} 'rm /Library/Server/Web/Data/Sites/Default/se.encrypted.upgrade'
  539. ssh {$sshArgs} {$sshHostUsr} 'ln -s ~/se.encrypted.upgrade/SE /Library/Server/Web/Data/Sites/Default/se.encrypted.upgrade'
  540. ";
  541. // --dry-run \
  542. V::exec($cmd, $out, $ret);
  543. DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  544. if (0 !== $ret) throw new Exception("Cannot run remote command using rsa key! #{$ret}");
  545. }
  546. public function upgradeRemoteFromTestDirAction() {
  547. session_write_close();
  548. $args = array();
  549. $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int');
  550. UI::gora();
  551. //UI::menu();
  552. //$this->menu($args['licence_id']);// TODO: GO BACK BTN
  553. try {
  554. $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']);
  555. $this->_upgradeRemoteFromTestDir($appLicenceInfo);
  556. echo "Test online: ";
  557. echo UI::h('a', ['target'=>"_blank", 'href'=>"https://{$appLicenceInfo->mainServer}/SE/"], "https://{$appLicenceInfo->mainServer}/SE/");
  558. } catch (Exception $e) {
  559. $this->_endWithException($e);
  560. }
  561. UI::dol();
  562. }
  563. public function _upgradeRemoteFromTestDir($appLicenceInfo) {
  564. $cmd = ''; $out = ''; $ret = '';
  565. $this->_assertRsaKeyExists($appLicenceInfo);
  566. $dateStr = date("Y-m-d_H-i-s");
  567. // $remoteHomeDir = "/Users/{$appLicenceInfo->rootLogin}";// BUG: alias like in ams - login = prezes is alias for arkadiuszbinder
  568. $remoteHomeDir = $this->_fetchRemoteHomeDir($appLicenceInfo);
  569. $cmd = "
  570. rm -rf /Library/Server/Web/Data/Sites/Default/SE.test 2>&1
  571. cp -r {$remoteHomeDir}/se.encrypted.upgrade/SE /Library/Server/Web/Data/Sites/Default/SE.test 2>&1
  572. [ ! -d {$remoteHomeDir}/bup.se.upgrade ] && mkdir {$remoteHomeDir}/bup.se.upgrade || echo 1
  573. [ ! -d {$remoteHomeDir}/bup.se.upgrade ] && exit 1
  574. [ ! -d {$remoteHomeDir}/bup.se.upgrade-testttttt ] && exit 1
  575. [ ! -f /Library/Server/Web/Data/Sites/Default/SE.test/VERSION ] && echo \"Error: plik VERSION nie istnieje\" || echo \"check VERSION OK\"
  576. [ ! -f /Library/Server/Web/Data/Sites/Default/SE.test/VERSION ] && exit 1
  577. [ ! -f /Library/Server/Web/Data/Sites/Default/SE.test/index.php ] && echo \"Error: plik index.php nie istnieje\" || echo \"check index.php OK\"
  578. [ ! -f /Library/Server/Web/Data/Sites/Default/SE.test/index.php ] && exit 1
  579. [ ! -d /Library/Server/Web/Data/Sites/Default/SE.test/se-lib ] && echo \"Error: plik se-lib nie istnieje\" || echo \"check se-lib OK\"
  580. [ ! -d /Library/Server/Web/Data/Sites/Default/SE.test/se-lib ] && exit 1
  581. exit 0
  582. ";
  583. V::execRootRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort);
  584. $cmd = "
  585. mv /Library/Server/Web/Data/Sites/Default/SE {$remoteHomeDir}/bup.se.upgrade/bup.{$dateStr} 2>&1
  586. mv /Library/Server/Web/Data/Sites/Default/SE.test /Library/Server/Web/Data/Sites/Default/SE 2>&1
  587. exit 0
  588. ";
  589. V::execRootRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort);
  590. DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  591. if (0 !== $ret) throw new Exception("Cannot run remote command as root! #{$ret}");
  592. // TODO: SE/bash_install_check.php requires $domain!
  593. // $cmd = "/usr/bin/php /Library/Server/Web/Data/Sites/Default/SE/bash_install_check.php {$domain}";
  594. // V::execRootRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort);
  595. // DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  596. // if (0 !== $ret) throw new Exception("Cannot run remote command as root! #{$ret}");
  597. }
  598. public function _assertRsaKeyExists($appLicenceInfo) {
  599. $cmd = ''; $out = ''; $ret = '';
  600. $cmd = "echo ~ && pwd";// /Library/WebServer
  601. $cmd = "ls -1 ~/.ssh/";
  602. //$cmd = "rm /tmp/id_rsa";
  603. //$cmd = "rm /tmp/id_rsa.pub";
  604. //$cmd = "ssh-keygen -t rsa -N '' -C '_www@biuro.biall-net.pl' -f /tmp/id_rsa";
  605. //$cmd = "ssh-keygen -t rsa -N '' -C '_www@biuro.biall-net.pl' -f /tmp/id_rsa";
  606. V::exec($cmd, $out, $ret);
  607. DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  608. if (0 !== $ret) {// no ~/.ssh directory
  609. $rsaKeyPath = "~/.ssh";
  610. $cmds = array();
  611. $cmds[] = "mkdir {$rsaKeyPath}";
  612. $cmds[] = "ssh-keygen -t rsa -N '' -C '_www@biuro.biall-net.pl' -f {$rsaKeyPath}/id_rsa 2>&1";
  613. $cmds[] = "ls -1 $rsaKeyPath";
  614. foreach ($cmds as $cmd) {
  615. V::exec($cmd, $out, $ret);
  616. DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  617. if (0 !== $ret) throw new Exception("Error '{$ret}' cmd({$cmd}): " . implode("\n", $out));
  618. }
  619. }
  620. $cmd = "cat ~/.ssh/id_rsa.pub";
  621. V::exec($cmd, $out, $ret);
  622. DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  623. if (0 !== $ret || empty($out) || empty($out[0])) throw new Exception("Cannot read rsa public key");
  624. $rsaPubKey = $out[0];
  625. $cmd = 'ls -1a';
  626. $cmd = "
  627. [ ! -d ~/.ssh ] && mkdir ~/.ssh;
  628. [ ! -d ~/.ssh ] && echo 'ERROR ~/.ssh not exists and cannot be created';
  629. [ ! -f ~/.ssh/authorized_keys ] && echo '{$rsaPubKey}' > ~/.ssh/authorized_keys;
  630. [ ! -f ~/.ssh/authorized_keys ] && echo 'ERROR ~/.ssh/authorized_keys not exists and cannot be created';
  631. cat ~/.ssh/authorized_keys| grep '{$rsaPubKey}' && echo 'OK' || echo '{$rsaPubKey}' >> ~/.ssh/authorized_keys;
  632. chmod 600 ~/.ssh/authorized_keys;
  633. ";
  634. V::execRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort);
  635. DBG::_(true, true, "remote cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  636. //$cmd = "ssh server@{$appLicenceInfo->mainServer} 'ls -1 .ssh/'";
  637. //$cmd = "ssh -i ~/.ssh/id_rsa server@{$appLicenceInfo->mainServer} 'ls -1'";
  638. $sshPort = (22 != $appLicenceInfo->sshPort)? "-p {$appLicenceInfo->sshPort}" : '';
  639. $cmd = "ssh {$sshPort} {$appLicenceInfo->rootLogin}@{$appLicenceInfo->mainServer} 'ls -1'";
  640. V::exec($cmd, $out, $ret);
  641. DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__);
  642. if (0 !== $ret) throw new Exception("Cannot run remote command using rsa key! #{$ret}");
  643. }
  644. }