sshArgsSkipHostKey = ' -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '; } public function handleAuth() { if (!User::logged()) { throw new HttpException('Unauthorized', 401); } if (!User::isAdmin()) { throw new HttpException('Unauthorized - only for administrators', 401); } } public function defaultAction() { UI::gora(); UI::menu(); $this->menu(); UI::setTitleJsTag("Install"); UI::dol(); } public function menu() { $serversList = $this->fetchActiveLicences(); ?>
"static/vendor.js", 'type'=>"text/javascript"]); // echo UI::h('script', ['src'=>"https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js", 'type'=>"text/javascript"]); // echo UI::h('script', ['src'=>"https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js", 'type'=>"text/javascript"]); // echo UI::h('script', ['src'=>"https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap-typeahead/0.10.4/react-bootstrap-typeahead.js", 'type'=>"text/javascript"]); $jsonServersList = array_values(array_map( function ($srv) { return [ 'id' => $srv->ID, 'label' => "{$srv->domain} [{$srv->ID}]" ]; }, $serversList )); echo UI::h('script', ['type'=>"text/javascript"], " (function(global){ if (!global.p5VendorJs) { console.warn('Brak p5VendorJs'); return; } if (!global.p5VendorJs.React) { console.warn('Brak p5VendorJs.React'); return; } if (!global.p5VendorJs.ReactDOM) { console.warn('Brak p5VendorJs.ReactDOM'); return; } if (!global.p5VendorJs.Typeahead) { console.warn('Brak p5VendorJs.Typeahead'); return; } const React = global.p5VendorJs.React; const ReactDOM = global.p5VendorJs.ReactDOM; const Typeahead = global.p5VendorJs.Typeahead; var options = ".json_encode($jsonServersList)."; var selected = []; var onInputChange = function (query) { // console.log('onInputChange:: query', query); } var onChange = function (value) { // console.log('onChange:: value', value); if (value.length > 0) { var id = value[0]['id']; if (id > 0) { document.getElementById('servers_list').value = id; } } } ReactDOM.render( React.createElement(Typeahead, { options: options, emptyLabel: 'Brak danych', placeholder: 'Wybierz serwer', selected: selected, // onInputChange: onInputChange, onChange: onChange, }, null), document.getElementById('servers_list_react') ); })(window); "); } public function createAppAction() { session_write_close(); $args = array(); $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int'); UI::gora(); UI::menu(); UI::setTitleJsTag("Install"); //$this->menu($args['licence_id']);// TODO: GO BACK BTN try { $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']); $this->validateAppLicenceInfo($appLicenceInfo); } catch (Exception $e) { $this->_endWithException($e); } // $this->generateApp($appLicenceInfo->installPath, $appLicenceInfo->domains); //DBG::_(true, true, "appLicenceInfo", $appLicenceInfo, __CLASS__, __FUNCTION__, __LINE__); if ('_generateEncryptedSource' === V::get('_postTask', '', $_POST)) { echo '
'; echo '

' . "Generowanie..." . '

'; echo '
'; try { $this->validateAppLicenceInfo($appLicenceInfo); $this->generateApp($appLicenceInfo->installPath, $appLicenceInfo->domains); // TODO: $this->configGenerate(...); } catch (Exception $e) { echo '
';// .container/ scroll $this->_endWithException($e); } echo '';// .container UI::alert('success', "Gotowe Aplikacja znajduje się w katalogu {$appLicenceInfo->installFolderName}"); $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']); } if ('newGenerateApp' === V::get('_postTask', '', $_POST)) { $this->newGenerateApp($appLicenceInfo); } if ('updateAndSendToRemoteTestDir' === V::get('_postTask', '', $_POST)) { echo '
aktualizuj werjsę, szyfruj i wyślij do testowego katalogu na serwerze'; try { $idLicence = V::get('licence_id', 0, $_POST, 'int'); $appLicenceInfo = $this->getAppLicenceInfo($idLicence); $this->validateAppLicenceInfo($appLicenceInfo); $this->gitResetHard($appLicenceInfo->installPath, $appLicenceInfo->projects); flush(); $this->_encodeSource($appLicenceInfo->installPath, $appLicenceInfo->domains); flush(); $this->_sendToRemoteTestDir($appLicenceInfo); } catch (Exception $e) { DBG::log($e); UI::alert('danger', $e->getMessage()); } echo '
'; $testDirUrl = "https://{$appLicenceInfo->mainServer}/se.encrypted.upgrade/"; UI::alert('info', UI::h('p', [], [ "testowy katalog zaktualizowany - ", UI::h('a', [ 'href' => $testDirUrl, 'target' => "_blank" ], $testDirUrl), ])); flush(); } // echo UI::hButtonPost("TODO: Generuj z p5.git", [ // 'class' => "btn btn-md btn-primary", // 'data' => [ // '_postTask' => "newGenerateApp", // 'licence_id' => $appLicenceInfo->ID, // ], // ]); echo UI::h('div', [ 'class' => "jumbotron" ], [ UI::h('div', [ 'class' => "container" ], [ UI::h('h3', [], "Generowanie aplikacji dla licencji {$appLicenceInfo->ID}"), UI::h('p', [], "Licencja dla domen: " . implode(', ', $appLicenceInfo->domains)), UI::h('p', [], "Katalog z zakodowanymi plikami: {$appLicenceInfo->installFolderName}"), UI::hButtonPost("Generuj", [ 'class' => "btn btn-primary", 'data' => [ '_postTask' => '_generateEncryptedSource', 'licence_id' => $appLicenceInfo->ID, ] ]), (!$appLicenceInfo->installFolderGitExists) ? UI::h('div', [ 'class' => "alert alert-info" ], "Katalog nie istnieje - wygeneruj aplikację") : UI::h('div', [ 'class' => "alert alert-info", 'style' => "margin-top:10px" ], [ UI::h('p', [], "Katalog istnieje i zawiera już repozytorium git: "), UI::h('p', [], [ UI::hButtonPost("aktualizuj werjsę, szyfruj i wyślij do testowego katalogu na serwerze", [ 'class' => "btn btn-xs btn-primary", 'data' => [ '_postTask' => "updateAndSendToRemoteTestDir", 'licence_id' => $appLicenceInfo->ID, ], ]), ]), UI::h('p', [ 'style' => "margin-left:20px" ], [ UI::h('a', [ 'href' => "index.php?_route=Install&_task=gitResetHard&licence_id={$appLicenceInfo->ID}", 'target' => "_blank", 'class' => "btn btn-xs btn-default" ], "aktualizuj werjsę"), " (git reset --hard, git pull, set SE/VERSION - tak samo co 'rm -rf; git clone', ale szybciej)", ]), UI::h('p', [ 'style' => "margin-left:20px" ], [ UI::h('a', [ 'href' => "index.php?_route=Install&_task=configGenerate&licence_id={$appLicenceInfo->ID}", 'target' => "_blank", 'class' => "btn btn-xs btn-default" ], "generuj pliki konfiguracyjne"), ]), UI::h('p', [ 'style' => "margin-left:20px" ], [ UI::h('a', [ 'href' => "index.php?_route=Install&_task=encodeSource&licence_id={$appLicenceInfo->ID}", 'target' => "_blank", 'class' => "btn btn-xs btn-default" ], "encode files"), ]), UI::h('p', [ 'style' => "margin-left:20px" ], [ UI::h('a', [ 'href' => "index.php?_route=Install&_task=sendToRemoteTestDir&licence_id={$appLicenceInfo->ID}", 'target' => "_blank", 'class' => "btn btn-xs btn-default" ], "send encoded files to remote server test folder (generates ssh key if not set)"), ]), UI::h('p', [ 'style' => "margin-left:20px" ], [ UI::h('a', [ 'href' => "index.php?_route=Install&_task=generateUpgradeScript&licence_id={$appLicenceInfo->ID}", 'target' => "_blank", 'class' => "btn btn-xs btn-warning" ], "generuj skrypt aktualizacji"), ]), UI::h('p', [ 'style' => "margin-top:30px" ], [ "Test online: ", UI::h('a', [ 'target' => "_blank", 'href' => "https://{$appLicenceInfo->mainServer}/se.encrypted.upgrade/" ], "https://{$appLicenceInfo->mainServer}/se.encrypted.upgrade/"), ]), "
- ", UI::h('a', [ 'href' => "index.php?_route=Install&_task=upgradeRemoteFromTestDir&licence_id={$appLicenceInfo->ID}", 'onclick' => "return confirm('Uruchomić aktualizację SE na https://{$appLicenceInfo->mainServer}/SE/?')", 'target' => "_blank", 'class' => "btn btn-xs btn-warning" ], "UPGRADE Production folder from uploaded dir: ~/se.encrypted.upgrade/"), ]), ]), ]); ?> menu($args['licence_id']);// TODO: GO BACK BTN try { $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']); $this->validateAppLicenceInfo($appLicenceInfo); UI::startContainer(); $this->generateUpgradeScript($appLicenceInfo); UI::endContainer(); } catch (Exception $e) { $this->_endWithException($e); } UI::dol(); } public function generateUpgradeScript($appLicenceInfo) { $cmds = []; // $cmds[] = "# TODO: commands from remote upgrade"; $cmds[] = "# cp -r {UPDATE_ZIP_PATH_SE} {public_html}/se.encrypted.upgrade"; $cmds[] = "# rm -rf {public_html}/se.encrypted.upgrade"; // '[ ! -d ~/se.encrypted.upgrade ] && mkdir ~/se.encrypted.upgrade || echo 1'; // 'rm -rf ~/se.encrypted.upgrade/SE'; // 'cp -r /Library/Server/Web/Data/Sites/Default/SE ~/se.encrypted.upgrade/SE'; // 'rm -rf ~/se.encrypted.upgrade/SE/config'; // rsync --archive --times --delete --compress --one-file-system --omit-dir-times --no-g --no-perms {$dryRunOnly} \ // --verbose {$rsyncSshPort} \ // --exclude='schema/default_db.instance.xml' \ // --exclude='schema/default_db.instance.xml/**' \ // '{$appLicenceInfo->installPath}/SE/' {$sshHostUsr}:~/se.encrypted.upgrade/SE/; // 'cp -r /Library/Server/Web/Data/Sites/Default/SE/config ~/se.encrypted.upgrade/SE/'; // 'rm /Library/Server/Web/Data/Sites/Default/se.encrypted.upgrade' // 'ln -s ~/se.encrypted.upgrade/SE /Library/Server/Web/Data/Sites/Default/se.encrypted.upgrade' // scp {$this->sshArgsSkipHostKey} {$scpArgs} /Library/Server/Web/Data/Sites/SE-production-git/SE/config/.config_base_structure.php {$sshHostUsr}: // 'mv ~/.config_base_structure.php /Library/Server/Web/Data/Sites/Default/se.encrypted.upgrade/config' // config // $cmds[] = "TODO cp -r from {SE}/config"; $cmds[] = "rm ~/se.encrypted.upgrade/.*.inc.php"; $cmds[] = "cp -r {UPDATE_ZIP_PATH_SE}/.*.inc.php ~/se.encrypted.upgrade/"; // $domainList = INSTALL_SES_PROCESY_A::fetch_same_domains_for_install($SERVER_ADDRESS_SHORT, $SERVER_ADDRESS);// [ $SERVER_ADDRESS, localhost, 127.0.0.1, ... ] DBG::nicePrint($appLicenceInfo, '$appLicenceInfo'); $mainDomain = $appLicenceInfo->mainServer; $additionalDomains = array_filter($appLicenceInfo->domains, function ($domain) use ($mainDomain) { return ($mainDomain != $domain); }); foreach ($additionalDomains as $domain) { if ('localhost' == $domain) continue;// skip localhost (127.0.0.1) $cmds[] = ' test -f /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--default_db-'.$domain.'.ini.php || ln -s /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--default_db-'.$mainDomain.'.inc.php /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--default_db-'.$domain.'.inc.php'; $cmds[] = ' test -f /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--zasob_2-'.$domain.'.inc.php || ln -s /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--zasob_2-'.$mainDomain.'.inc.php /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--zasob_2-'.$domain.'.inc.php'; // $cmds[] = ' test -f /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--import_db-'.$domain.'.inc.php || ln -s /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--import_db-'.$mainDomain.'.inc.php /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--import_db-'.$domain.'.inc.php'; $cmds[] = ' test -f /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--folders-'.$domain.'.inc.php || ln -s /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--folders-'.$mainDomain.'.inc.php /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--folders-'.$domain.'.inc.php'; $cmds[] = ' test -f /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--default_ldap-'.$domain.'.inc.php || ln -s /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--default_ldap-'.$mainDomain.'.inc.php /Library/Server/Web/Data/Sites/Default/SE/config/.cnf--default_ldap-'.$domain.'.inc.php'; } DBG::nicePrint($cmds, "\$cmds"); } public function configGenerateAction() { session_write_close(); $args = array(); $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int'); UI::gora(); UI::menu(); //$this->menu($args['licence_id']);// TODO: GO BACK BTN try { $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']); $this->validateAppLicenceInfo($appLicenceInfo); UI::startContainer(); $this->configGenerate($appLicenceInfo->configPath, $appLicenceInfo->mainServer, $appLicenceInfo->domains, $appLicenceInfo->rootPassword , $appLicenceInfo->ldapUser, $appLicenceInfo->ldapPass, $appLicenceInfo->ldapBaseDN ); UI::endContainer(); } catch (Exception $e) { $this->_endWithException($e); } UI::dol(); } public function configGenerate($configPath, $mainServer, $domains, $rootPassword, $ldapUser, $ldapPass, $ldapBaseDN) { if (empty($configPath)) throw new Exception("Install path not found"); $cmds = array(); $cmds[] = "if [ -d {$configPath} ] ; then rm -rf '{$configPath}'; fi"; $cmds[] = "mkdir {$configPath}"; $REMOTE_FOLDER_ROOT = str_replace([ ".", "-" ], '_', $mainServer); $cmds[] = ' echo "' . V::quoteBashEcho( Config::generateDefaultDbConfigFile( [ 'database' => $REMOTE_FOLDER_ROOT, 'password' => $rootPassword, ], $outputFormat = 'inc' ) ) . '" > ' . $configPath . '/.cnf--default_db-' . $mainServer . '.inc.php'; $cmds[] = ' echo "' . V::quoteBashEcho( Config::generateDefaultDbConfigFile( [ 'database' => $REMOTE_FOLDER_ROOT, 'password' => $rootPassword, ], $outputFormat = 'inc' ) ) . '" > ' . $configPath . '/.cnf--zasob_2-' . $mainServer . '.inc.php'; $cmds[] = ' echo "' . V::quoteBashEcho( Config::generateDefaultLdapConfigFile( [ 'user' => $ldapUser, 'pass' => $ldapPass, 'base_dn' => $ldapBaseDN, ], $outputFormat = 'inc' ) ) . '" > ' . $configPath . '/.cnf--default_ldap-' . $mainServer . '.inc.php'; $cmds[] = ' echo "' . V::quoteBashEcho( Config::generateDefaultFoldersConfigFile( [ 'remote_folder_root' => str_replace([ '.', '-' ], '_', $mainServer), 'server_address' => $mainServer, ], $outputFormat = 'ini' ) ) . '" > ' . $configPath . '/.cnf--folders-' . $mainServer . '.ini.php'; $additionalDomains = array_filter($domains, function ($domain) use ($mainServer) { return ($mainServer != $domain); }); foreach ($additionalDomains as $domain) { if ('localhost' == $domain) continue;// skip localhost (127.0.0.1) $cmds[] = "cd {$configPath} && ln -s .cnf--default_db-{$mainServer}.inc.php .cnf--default_db-{$domain}.inc.php"; $cmds[] = "cd {$configPath} && ln -s .cnf--zasob_2-{$mainServer}.inc.php .cnf--zasob_2-{$domain}.inc.php"; // $cmds[] = "cd {$configPath} && ln -s .cnf--import_db-{$mainServer}.inc.php .cnf--import_db-{$domain}.inc.php"; $cmds[] = "cd {$configPath} && ln -s .cnf--default_ldap-{$mainServer}.inc.php .cnf--default_ldap-{$domain}.inc.php"; switch ($domain) { case '127.0.0.1': // alias for mainServer case "{$mainServer}.procesy5.pl": // alias for mainServer { $cmds[] = ' echo "' . V::quoteBashEcho( Config::generateDefaultFoldersConfigFile( [ 'remote_folder_root' => str_replace([ '.', '-' ], '_', $mainServer), 'server_address' => $domain, ], $outputFormat = 'ini' ) ) . '" > ' . $configPath . '/.cnf--folders-' . $domain . '.ini.php'; } break; default: $cmds[] = ' echo "' . V::quoteBashEcho( Config::generateDefaultFoldersConfigFile( [ 'remote_folder_root' => str_replace([ '.', '-' ], '_', $domain), 'server_address' => $domain, ], $outputFormat = 'ini' ) ) . '" > ' . $configPath . '/.cnf--folders-' . $domain . '.ini.php'; } } $hasError = false; foreach ($cmds as $cmd) { V::exec($cmd, $out, $ret); if (0 !== $ret) $hasError = true; DBG::nicePrint(array_merge([ "CMD: {$cmd}", "OUTPUT:" ], $out), "cmd: `" . htmlspecialchars(V::strShort($cmd, 20)) . "` (return:{$ret})"); } if (!$hasError) { UI::alert('success', "OK"); } else { UI::alert('danger', "errors"); } } public function gitResetHardAction() { session_write_close(); $args = array(); $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int'); UI::gora(); UI::menu(); //$this->menu($args['licence_id']);// TODO: GO BACK BTN try { $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']); $this->validateAppLicenceInfo($appLicenceInfo); UI::startContainer(); $this->gitResetHard($appLicenceInfo->installPath, $appLicenceInfo->projects); UI::endContainer(); } catch (Exception $e) { $this->_endWithException($e); } UI::dol(); } public function gitResetHard($installPath, $projects = []) { if (empty($installPath)) throw new Exception("Install path not found"); $cmds = array(); $cmds[] = "git reset --hard"; $cmds[] = "git pull"; $cmds[] = "echo `git show-ref --head|head -1|head -c 8` > SE/VERSION "; $hasError = false; foreach ($cmds as $cmd) { V::exec("cd {$installPath} && {$cmd}", $out, $ret); if (0 !== $ret) $hasError = true; DBG::nicePrint($out, "cmd: `{$cmd}` (return:{$ret})"); } foreach ($projects as $projectName) { $cmd = "ls -l SE/projects/{$projectName} | wc -l"; V::exec("cd {$installPath} && {$cmd}", $out, $ret); DBG::nicePrint([ 'cmd' => $cmd, 'output' => $out ], "return: {$ret}"); if (!empty($out) && '0' !== trim($out[0])) { // $cmd = "git submodule update SE/projects/{$projectName}"; $cmd = "cd SE/projects/{$projectName} && git reset --hard"; // revert encode source - checkout to last commit (need update) V::exec("cd {$installPath} && {$cmd}", $out, $ret); DBG::nicePrint([ 'cmd' => $cmd, 'output' => $out ], "return: {$ret}"); } $cmd = "git submodule update --init SE/projects/{$projectName}"; // checkout to current commit V::exec("cd {$installPath} && {$cmd}", $out, $ret); DBG::nicePrint([ 'cmd' => $cmd, 'output' => $out ], "return: {$ret}"); } if (!$hasError) { UI::alert('success', "OK"); } else { UI::alert('danger', "errors"); } } public function encodeSourceAction() { session_write_close(); $args = array(); $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int'); UI::gora(); UI::menu(); //$this->menu($args['licence_id']);// TODO: GO BACK BTN try { $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']); $this->validateAppLicenceInfo($appLicenceInfo); $this->_encodeSource($appLicenceInfo->installPath, $appLicenceInfo->domains); $this->_encodeConfigs($appLicenceInfo->configPath); } catch (Exception $e) { $this->_endWithException($e); } UI::dol(); } public function _encodeSource($installPath, $domains) { UI::startContainer(); $this->encodeSourceFiles($installPath, $domains, $dbg = true); // try { // $this->encodeSourceFiles($appLicenceInfo->installPath, $appLicenceInfo->domains, $dbg = false); // UI::alert('success', "OK"); // } catch (Exception $e) { // UI::alert('danger', $e->getMessage()); // } UI::endContainer(); } // @usage: Router::getRoute('Install')->encodeSourceFiles($installPath = '/path_to_git_repo', $domains = [ 'domain.com', 'localhost' ], $dbg = false); public function encodeSourceFiles($installPath, $domains, $dbg = false) { if (empty($installPath)) throw new Exception("Install path not found"); if (empty($domains)) throw new Exception("Domains not found"); $phpVersionsForSgencoder = '--phpversion 5.5 --phpversion 5.6';// encode for PHP 5.x (currently supported PHP 5.0-5.6) if ('1' == V::get('DBG_ENCODER_HELP', '', $_REQUEST)) {// encoder help $cmd = "cd {$installPath}/SE && /Applications/SourceGuardian.app/Contents/MacOS/sgencoder --help "; $out = ''; $ret = ''; V::exec($cmd, $out, $ret); DBG::nicePrint($out, "cmd: `{$cmd}` (return:{$ret})"); exit; } $domainEncodePhpFiles = [ 'ant.php', 'api.php', 'budynki.php', 'index-ajax.php', 'index.php', 'procesy5.php', 'session-expire.php', 'test-sync.php', 'wfs-data.php', 'wfs-qgis.php', 'wfs.php', ]; $cmd = "find . -name '*.php' "; $out = ''; $ret = ''; V::exec("cd {$installPath}/SE && {$cmd}", $out, $ret); if ($dbg) DBG::nicePrint($out, "cmd: `{$cmd}` (return:{$ret})"); else DBG::log($out, 'array', "cmd: `{$cmd}` (return:{$ret})"); if (0 !== $ret) throw new Exception("Error at find php files"); if (empty($out)) throw new Exception("No php files found"); $allPhpFiles = array_map(function ($phpFilePath) { return ('./' == substr($phpFilePath, 0, 2))? substr($phpFilePath, 2) : $phpFilePath; }, $out); $freeEncodePhpFiles = array_filter($allPhpFiles, function ($phpFilePath) use ($domainEncodePhpFiles) { if ('se-lib/Vendor/' === substr($phpFilePath, 0, strlen('se-lib/Vendor/'))) return false; // SKIP se-lib/Vendor/* if ('.ini.php' === substr($phpFilePath, -1 * strlen('.ini.php'))) return false; // SKIP *.ini.php return (!in_array($phpFilePath, $domainEncodePhpFiles)); }); DBG::log($freeEncodePhpFiles, 'array', "\$freeEncodePhpFiles"); if (empty($freeEncodePhpFiles)) throw new Exception("No php files to encode"); $cmdTempl = "cd {$installPath}/SE && /Applications/SourceGuardian.app/Contents/MacOS/sgencoder {$phpVersionsForSgencoder} -b- "; $cmdDomainEncodeDomainsTempl = " --domain " . implode(" --domain ", $domains); $cmdDomainEncodeFilesTempl = " " . implode(" ", $domainEncodePhpFiles); $cmdFreeEncodeFilesTempl = " " . implode(" ", $freeEncodePhpFiles); $cmds = [ $cmdTempl . $cmdDomainEncodeDomainsTempl . $cmdDomainEncodeFilesTempl, $cmdTempl . $cmdFreeEncodeFilesTempl, ]; $returnValues = []; foreach ($cmds as $cmd) { $out = ''; $ret = ''; V::exec($cmd, $out, $ret); $encoderSummaryLine = end($out); $returnValues[] = $encoderSummaryLine; if ($dbg) { DBG::nicePrint([$cmd], "cmd"); DBG::nicePrint($out, "return: '{$ret}'"); // DBG::nicePrint([$encoderSummaryLine], "cmd last line"); } else DBG::log([$cmd, $out], 'array', "cmd return:'{$ret}'"); // if (0 !== $ret) throw new Exception("Error at encode files"); if (empty($out)) throw new Exception("No output for encode files command"); } $statusInfo = array_reduce($returnValues, function ($ret, $encoderSummaryLine) { DBG::log([$ret, $encoderSummaryLine], 'array', "DBG reduce [\$ret, \$encoderSummaryLine]"); $matches = []; preg_match_all('/(\d+) files, (\d+) encoded, (\d+) skipped, (\d+) errors/', $encoderSummaryLine, $matches, PREG_SET_ORDER, 0); return [ 'files' => $ret['files'] + (int)$matches[0][1], 'encoded' => $ret['encoded'] + (int)$matches[0][2], 'skipped' => $ret['skipped'] + (int)$matches[0][3], 'errors' => $ret['errors'] + (int)$matches[0][4], ]; }, [ 'files' => 0, 'encoded' => 0, 'skipped' => 0, 'errors' => 0, ]); if ($statusInfo['errors'] === 0 && $statusInfo['files'] > 0) { if ($dbg) UI::alert('success', "{$statusInfo['files']} files, {$statusInfo['encoded']} encoded, {$statusInfo['skipped']} skipped, {$statusInfo['errors']} errors"); } else { if ($dbg) UI::alert('danger', "{$statusInfo['files']} files, {$statusInfo['encoded']} encoded, {$statusInfo['skipped']} skipped, {$statusInfo['errors']} errors"); else throw new Exception("{$statusInfo['files']} files, {$statusInfo['encoded']} encoded, {$statusInfo['skipped']} skipped, {$statusInfo['errors']} errors"); } } public function _encodeConfigs($configPath) { $cmd = "find . -name '*.inc.php' "; $out = ''; $ret = ''; V::exec("cd {$configPath} && {$cmd}", $out, $ret); DBG::nicePrint($out, "cmd: `{$cmd}` (return:{$ret})"); $freeEncodePhpFiles = $out; $phpVersionsForSgencoder = '--phpversion 5.5 --phpversion 5.6';// encode for PHP 5.x (currently supported PHP 5.0-5.6) $cmdTempl = "cd {$configPath} && /Applications/SourceGuardian.app/Contents/MacOS/sgencoder {$phpVersionsForSgencoder} -b- "; $cmdDomainEncodeDomainsTempl = " --domain " . implode(" --domain ", array_merge($domains, ['localhost'])); // $cmdDomainEncodeFilesTempl = " " . implode(" ", $domainEncodePhpFiles); $cmdFreeEncodeFilesTempl = " " . implode(" ", $freeEncodePhpFiles); $cmds = [ // $cmdTempl . $cmdDomainEncodeDomainsTempl . $cmdDomainEncodeFilesTempl, $cmdTempl . $cmdFreeEncodeFilesTempl, ]; $dbg = true; $returnValues = []; foreach ($cmds as $cmd) { $out = ''; $ret = ''; V::exec($cmd, $out, $ret); $encoderSummaryLine = end($out); $returnValues[] = $encoderSummaryLine; if ($dbg) { DBG::nicePrint([$cmd], "cmd"); DBG::nicePrint($out, "return: '{$ret}'"); // DBG::nicePrint([$encoderSummaryLine], "cmd last line"); } else DBG::log([$cmd, $out], 'array', "cmd return:'{$ret}'"); // if (0 !== $ret) throw new Exception("Error at encode files"); if (empty($out)) throw new Exception("No output for encode files command"); } $statusInfo = array_reduce($returnValues, function ($ret, $encoderSummaryLine) { DBG::log([$ret, $encoderSummaryLine], 'array', "DBG reduce [\$ret, \$encoderSummaryLine]"); $matches = []; preg_match_all('/(\d+) files, (\d+) encoded, (\d+) skipped, (\d+) errors/', $encoderSummaryLine, $matches, PREG_SET_ORDER, 0); return [ 'files' => $ret['files'] + (int)$matches[0][1], 'encoded' => $ret['encoded'] + (int)$matches[0][2], 'skipped' => $ret['skipped'] + (int)$matches[0][3], 'errors' => $ret['errors'] + (int)$matches[0][4], ]; }, [ 'files' => 0, 'encoded' => 0, 'skipped' => 0, 'errors' => 0, ]); if ($statusInfo['errors'] === 0 && $statusInfo['files'] > 0) { if ($dbg) UI::alert('success', "{$statusInfo['files']} files, {$statusInfo['encoded']} encoded, {$statusInfo['skipped']} skipped, {$statusInfo['errors']} errors"); } else { if ($dbg) UI::alert('danger', "{$statusInfo['files']} files, {$statusInfo['encoded']} encoded, {$statusInfo['skipped']} skipped, {$statusInfo['errors']} errors"); else throw new Exception("{$statusInfo['files']} files, {$statusInfo['encoded']} encoded, {$statusInfo['skipped']} skipped, {$statusInfo['errors']} errors"); } } public function getAppLicenceInfo($idLicence) { $idLicence = intval($idLicence); if (empty($idLicence)) throw new Exception("Nie wybrano serwera/licencji."); //DBG::_(true, true, 'idLicence', $idLicence, __CLASS__, __FUNCTION__, __LINE__); $appLicenceInfo = (object)$this->fetchAppLicenceInfo($idLicence); $appLicenceInfo->domains = $this->fetchDomainsByLicenceId($idLicence); $installRootPath = '/Library/Server/Web/Data/Sites/Default/PLIKI/SES_PROCESY5_A'; $appLicenceInfo->installFolderName = "{$idLicence}_upgrade_SE_source_encrypted"; $appLicenceInfo->configFolderName = "{$idLicence}_upgrade_SE_config_encrypted"; $appLicenceInfo->installPath = "{$installRootPath}/{$appLicenceInfo->installFolderName}"; $appLicenceInfo->configPath = "{$installRootPath}/{$appLicenceInfo->configFolderName}"; //DBG::_(true, true, 'appLicenceInfo', $appLicenceInfo, __CLASS__, __FUNCTION__, __LINE__); if (empty($appLicenceInfo->domains)) throw new Exception("Domains not found."); // TODO: mv to validate $appLicenceInfo->installFolderExists = file_exists("{$appLicenceInfo->installPath}/SE"); $appLicenceInfo->installFolderGitExists = file_exists("{$appLicenceInfo->installPath}/.git"); $appLicenceInfo->projects = []; // TODO: get from db if (!empty($appLicenceInfo->project)) { $appLicenceInfo->projects = [ $appLicenceInfo->project ]; } else if (79 == $idLicence) { // bravecom.procesy5.pl $appLicenceInfo->projects = [ 'bravecare' ]; } else if (80 == $idLicence) { // bravecom.yellowgroup.pl $appLicenceInfo->projects = [ 'bocian' ]; } else if (81 == $idLicence) { // bocian.procesy5.pl $appLicenceInfo->projects = [ 'bocian' ]; } else if (67 == $idLicence) { // bocian.procesy5.pl $appLicenceInfo->projects = [ 'bocian' ]; } else if (82 == $idLicence) { // bocian-energa.procesy5.pl $appLicenceInfo->projects = [ 'bocian' ]; } else if (4 == $idLicence) { // bzyk.procesy5.pl $appLicenceInfo->projects = [ 'bocian' ]; } return $appLicenceInfo; } public function validateAppLicenceInfo($appLicenceInfo) { if (empty($appLicenceInfo->ID)) throw new Exception("Nie wybrano serwera/licencji."); if (empty($appLicenceInfo->domains)) throw new Exception("Domains not found"); if (empty($appLicenceInfo->installPath)) throw new Exception("Install path not found"); } public function generateApp($installPath, $domains, $projects = []) { $cmds = array(); $cmds[] = "if [ -d {$installPath} ] ; then rm -rf '{$installPath}'; fi"; $cmds[] = "mkdir {$installPath}"; $cmds[] = "cd {$installPath} && git clone --depth 1 ssh://git@biuro.biall-net.pl:2222/plabudda/se.git ."; $cmds[] = "cd {$installPath} && echo `git show-ref --head|head -1|head -c 8` > SE/VERSION "; foreach ($cmds as $cmd) { V::exec($cmd, $out, $ret); DBG::nicePrint([ 'cmd' => $cmd, 'output' => $out ], "return: {$ret}"); } foreach ($projects as $projectName) { $cmd = "ls -l SE/projects/{$projectName} | wc -l"; V::exec("cd {$installPath} && {$cmd}", $out, $ret); DBG::nicePrint([ 'cmd' => $cmd, 'output' => $out ], "return: {$ret}"); if (!empty($out) && '0' !== trim($out[0])) { // $cmd = "git submodule update SE/projects/{$projectName}"; $cmd = "cd SE/projects/{$projectName} && git reset --hard"; // revert encode source - checkout to last commit (need update) V::exec("cd {$installPath} && {$cmd}", $out, $ret); DBG::nicePrint([ 'cmd' => $cmd, 'output' => $out ], "return: {$ret}"); } $cmd = "git submodule update --init SE/projects/{$projectName}"; // checkout to current commit V::exec("cd {$installPath} && {$cmd}", $out, $ret); DBG::nicePrint([ 'cmd' => $cmd, 'output' => $out ], "return: {$ret}"); } $this->_encodeSource($installPath, $domains); $this->configGenerate($appLicenceInfo->configPath, $appLicenceInfo->mainServer, $appLicenceInfo->domains, $appLicenceInfo->rootPassword , $appLicenceInfo->ldapUser, $appLicenceInfo->ldapPass, $appLicenceInfo->ldapBaseDN ); $this->_encodeConfigs($appLicenceInfo->configPath); // 1763: $exec='cd '.$installer_dir.' && /Applications/SourceGuardian.app/Contents/MacOS/sgencoder -b- // '.INSTALL_SES_PROCESY_A::get_same_domains_for_install($h->SERVER_ADDRESS_SHORT).' // -r *.php // -x superedit-DB_PROCEDURES_CREATE.php // -x INI.php // -x .config_base_structure.php // '; // // INSTALL_SES_PROCESY_A::get_same_domains_for_install($h->SERVER_ADDRESS_SHORT): // $res2=DB::query("select SERVER_ADDRESS_SHORT from SES_PROCESY5_A where SERVER_ADDRESS_IP='".$h->SERVER_ADDRESS_IP."'"); // while($h2=DB::fetch($res2)) { // $domain[]=' --domain '.$h2->SERVER_ADDRESS_SHORT; // ssh server@biuro.galeriaprzymorze.eu: PHP 5.5.20 // ssh server@biuro.biall-net.pl // cd /Users/plabudda/procesy5-install-galeriaprzymorze.eu/ // sudo chown -R server:admin SE/ // /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 } public function fetchActiveLicences() { $activeLic = array(); $sql = " select l.`ID` , l.`SERVER_ADDRESS` , l.`SERVER_ADDRESS_SHORT` as domain -- domain for sgencoder , l.`SERVER_ADDRESS_IP` from `SES_PROCESY5_A` l where 1=1 -- TODO: and l.`A_STATUS` in('NORMAL','WAITING') order by l.`ID` DESC "; $rows = DB::getPDO()->fetchAll($sql); foreach ($rows as $row) { $r = (object)$row; $activeLic[$r->ID] = $r; } return $activeLic; } public function fetchDomainsByLicenceId($licenceId) { $domains = array(); $sql = " select g.ID, g.`SERVER_ADDRESS_SHORT`, g.`SERVER_ADDRESS` from `SES_PROCESY5_A` g where g.`SERVER_ADDRESS_IP`=(select l.`SERVER_ADDRESS_IP` from `SES_PROCESY5_A` l where l.`ID`='{$licenceId}' -- TODO: and l.`A_STATUS` in('NORMAL','WAITING') ) -- TODO: and g.`A_STATUS` in('NORMAL','WAITING') "; $rows = DB::getPDO()->fetchAll($sql); $mainDomain = null; foreach ($rows as $row) { if ($licenceId == $row['ID']) $mainDomain = $row['SERVER_ADDRESS']; } foreach ($rows as $row) { $r = (object)$row; $domains[] = $r->SERVER_ADDRESS_SHORT; if ($r->SERVER_ADDRESS != $r->SERVER_ADDRESS_SHORT) { $domains[] = $r->SERVER_ADDRESS; } } if ($mainDomain && (!preg_match('/^(.*)\.procesy5\.pl$/', $mainDomain))) { $subDomainP5 = '' . $mainDomain . '.procesy5.pl'; if (!in_array($subDomainP5, $domains)) $domains[] = $subDomainP5; } $domains[] = '127.0.0.1'; $domains[] = 'localhost'; return $domains; } public function fetchMainServerByLicenceId($licenceId) { return DB::getPDO()->fetchValue(" select g.`SERVER_ADDRESS` from `SES_PROCESY5_A` g where g.`ID`='{$licenceId}' -- TODO: and g.`A_STATUS` in('NORMAL','WAITING') "); } public function fetchAppLicenceInfo($licenceId) { $licenceInfo = null; $sql = " select g.ID , g.SERVER_ADDRESS as mainServer , g.ADMIN_USERNAME as rootLogin , g.ADMIN_USERNAME_PASSWD as rootPassword , g.SSH_PORT as sshPort , g.VERSION_GIT as project , g.ADMIN_USERNAME_DIRECTORY as ldapUser , g.ADMIN_USERNAME_PASSWD as ldapPass , g.SERVER_ADDRESS_LDAP_DC as ldapBaseDN , g.VERSION_GIT as project from SES_PROCESY5_A g where g.`ID`=:id_licence -- TODO: and g.A_STATUS in('NORMAL','WAITING') "; $all = DB::getPDO()->fetchAll($sql, [ ':id_licence' => $licenceId ]); if (empty($all)) throw new Exception("Brak licencji o nr '{$licenceId}'"); $licenceInfo = reset($all); if (!$licenceInfo['sshPort']) $licenceInfo['sshPort'] = 22; return $licenceInfo; } public function _endWithException($e) { echo UI::h('div', ['class'=>"container"], [ UI::h('div', ['class' => "alert alert-danger"], "#" . $e->getLine() . ": " . $e->getMessage()), UI::h('p', [], [ "Wróć do ", UI::h('a', ['href'=>"index.php?_route=Install"], "menu") ]) ]); UI::dol(); exit; } public function sendToRemoteTestDirAction() { session_write_close(); $args = array(); $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int'); UI::gora(); //UI::menu(); //$this->menu($args['licence_id']);// TODO: GO BACK BTN try { $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']); $this->validateAppLicenceInfo($appLicenceInfo); // TODO: if (59 ) => baratosz.sledz - na lokalnym kompie // bn:~/$ scp -r SE server@192.168.61.153:~/se.encrypted.upgrade // remote SE.git = '/Users/bartoszsledz/Desktop/production-se' // remote:~/$ mv SE ~/SE.bup.2017-07-03 // remote:~/$ mv ~/se.encrypted.upgrade/SE SE // remote:~/$ cp -r ~/SE.bup.2017-07-03/config SE/ // remote:~/$ sudo chown -R bartoszsledz:staff SE/ $this->_sendToRemoteTestDir($appLicenceInfo); echo "Test online: "; echo UI::h('a', ['target'=>"_blank", 'href'=>"https://{$appLicenceInfo->mainServer}/se.encrypted.upgrade/"], "https://{$appLicenceInfo->mainServer}/se.encrypted.upgrade/"); } catch (Exception $e) { $this->_endWithException($e); } UI::dol(); } public function _fetchRemoteHomeDir($appLicenceInfo) { $this->_assertRsaKeyExists($appLicenceInfo); $sshHostUsr = "{$appLicenceInfo->rootLogin}@{$appLicenceInfo->mainServer}"; $sshArgs = (22 != $appLicenceInfo->sshPort)? "-p {$appLicenceInfo->sshPort}" : ''; $scpArgs = (22 != $appLicenceInfo->sshPort)? "-P {$appLicenceInfo->sshPort}" : ''; $rsyncSshPort = (22 != $appLicenceInfo->sshPort)? "-e 'ssh -p {$appLicenceInfo->sshPort}'" : ''; if (V::get('DBG_REMOTE', '', $_GET)) {// DBG $cmd = "echo ~"; V::exec("ssh {$sshArgs} {$sshHostUsr} '{$cmd}'", $out, $ret); DBG::log([ 'cmd-remote' => $cmd, 'output' => $out ], 'array', "return: {$ret}"); V::execRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort); DBG::log([ 'cmd-remote' => $cmd, 'output' => $out ], 'array', "return: {$ret}"); V::execRootRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort); DBG::log([ 'cmd-remote' => $cmd, 'output' => $out ], 'array', "return: {$ret}"); } $cmd = "echo ~"; V::exec("ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} '{$cmd}'", $out, $ret); DBG::log([ 'cmd-remote' => $cmd, 'output' => $out ], 'array', "return: {$ret}"); if (empty($out) || empty($out[0])) throw new Exception("Cannot fetch remote home dir"); return $out[0]; } public function _sendToRemoteTestDir($appLicenceInfo) { $cmd = ''; $out = ''; $ret = ''; $dryRunOnly = (V::get('dry-run', '', $_REQUEST)) ? "--dry-run" : ""; $this->_assertRsaKeyExists($appLicenceInfo); $sshHostUsr = "{$appLicenceInfo->rootLogin}@{$appLicenceInfo->mainServer}"; $sshArgs = (22 != $appLicenceInfo->sshPort)? "-p {$appLicenceInfo->sshPort}" : ''; $rsyncSshPort = (22 != $appLicenceInfo->sshPort)? "-e 'ssh -p {$appLicenceInfo->sshPort}'" : ''; $scpArgs = (22 != $appLicenceInfo->sshPort)? "-P {$appLicenceInfo->sshPort}" : ''; // $appLicenceInfo->sshPort /* rsync options: -a, --archive archive mode; same as -rlptgoD (no -H) -u, --update skip files that are newer on the receiver -t, --times preserve times --delete delete extraneous files from dest dirs */ $remoteDir = $this->_fetchRemoteHomeDir($appLicenceInfo); DBG::log($remoteDir, 'array', "remote home dir:"); $cmd = " ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} '[ ! -d ~/se.encrypted.upgrade ] && mkdir ~/se.encrypted.upgrade || echo 1'; ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'rm -rf ~/se.encrypted.upgrade/SE'; ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'cp -r /Library/Server/Web/Data/Sites/Default/SE ~/se.encrypted.upgrade/SE'; ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'rm -rf ~/se.encrypted.upgrade/SE/config'; rsync --archive --times --delete --compress --one-file-system --omit-dir-times --no-g --no-perms {$dryRunOnly} \ --verbose {$rsyncSshPort} \ --exclude='schema/default_db.instance.xml' \ --exclude='schema/default_db.instance.xml/**' \ '{$appLicenceInfo->installPath}/SE/' {$sshHostUsr}:~/se.encrypted.upgrade/SE/; ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'cp -r /Library/Server/Web/Data/Sites/Default/SE/config ~/se.encrypted.upgrade/SE/'; ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'rm /Library/Server/Web/Data/Sites/Default/se.encrypted.upgrade' ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'ln -s ~/se.encrypted.upgrade/SE /Library/Server/Web/Data/Sites/Default/se.encrypted.upgrade' scp {$this->sshArgsSkipHostKey} {$scpArgs} /Library/Server/Web/Data/Sites/SE-production-git/SE/config/.config_base_structure.php {$sshHostUsr}: ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'mv ~/.config_base_structure.php /Library/Server/Web/Data/Sites/Default/se.encrypted.upgrade/config' ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'cp /Users/server/se.encrypted.upgrade/SE/stuff/SourceGuardian/Loaders/Mac\ OS\ X/ixed.5.6.dar /opt/local/lib/php56/extensions/no-debug-non-zts-20131226/' "; //todo rsync ... -e \"{$this->sshArgsSkipHostKey}\" - maybe not working // --exclude='schema/default_db_xml_cache.public' \ // --exclude='stuff' \ // --exclude='stuff/**' \ //--exclude='schema/default_db_xml_cache.public/**' \ //TODO @2018-02-09 - check if ssh {$sshArgs} {$this->sshArgsSkipHostKey} {$sshHostUsr} 'cp /Applications/SourceGuardian.app/Contents/MacOS/Loaders/Mac\ OS\ X/ixed.5.6.dar /opt/local/lib/php56/extensions/no-debug-non-zts-20131226/' //IS WORKING WELL! V::exec("$cmd 2>&1", $out, $ret); DBG::log([ 'cmd-remote' => $cmd, 'output' => $out ], 'array', "return: {$ret}"); if (0 !== $ret) throw new Exception("Cannot run remote command using rsa key! #{$ret}. cmd: {$cmd} . out: {$out}"); } public function upgradeRemoteFromTestDirAction() { session_write_close(); $args = array(); $args['licence_id'] = V::get('licence_id', 0, $_REQUEST, 'int'); UI::gora(); //UI::menu(); //$this->menu($args['licence_id']);// TODO: GO BACK BTN try { $appLicenceInfo = $this->getAppLicenceInfo($args['licence_id']); $this->validateAppLicenceInfo($appLicenceInfo); $this->_upgradeRemoteFromTestDir($appLicenceInfo); echo "Test online: "; echo UI::h('a', ['target'=>"_blank", 'href'=>"https://{$appLicenceInfo->mainServer}/SE/"], "https://{$appLicenceInfo->mainServer}/SE/"); } catch (Exception $e) { $this->_endWithException($e); } UI::dol(); } public function _upgradeRemoteFromTestDir($appLicenceInfo) { $cmd = ''; $out = ''; $ret = ''; $this->_assertRsaKeyExists($appLicenceInfo); $dateStr = date("Y-m-d_H-i-s"); // $remoteHomeDir = "/Users/{$appLicenceInfo->rootLogin}";// BUG: alias like in ams - login = prezes is alias for arkadiuszbinder $remoteHomeDir = $this->_fetchRemoteHomeDir($appLicenceInfo); $cmd = " rm -rf /Library/Server/Web/Data/Sites/Default/SE.test 2>&1 cp -r {$remoteHomeDir}/se.encrypted.upgrade/SE /Library/Server/Web/Data/Sites/Default/SE.test 2>&1 [ ! -d {$remoteHomeDir}/bup.se.upgrade ] && mkdir {$remoteHomeDir}/bup.se.upgrade || echo 1 [ ! -d {$remoteHomeDir}/bup.se.upgrade ] && exit 1 [ ! -d {$remoteHomeDir}/bup.se.upgrade-testttttt ] && exit 1 [ ! -f /Library/Server/Web/Data/Sites/Default/SE.test/VERSION ] && echo \"Error: plik VERSION nie istnieje\" || echo \"check VERSION OK\" [ ! -f /Library/Server/Web/Data/Sites/Default/SE.test/VERSION ] && exit 1 [ ! -f /Library/Server/Web/Data/Sites/Default/SE.test/index.php ] && echo \"Error: plik index.php nie istnieje\" || echo \"check index.php OK\" [ ! -f /Library/Server/Web/Data/Sites/Default/SE.test/index.php ] && exit 1 [ ! -d /Library/Server/Web/Data/Sites/Default/SE.test/se-lib ] && echo \"Error: plik se-lib nie istnieje\" || echo \"check se-lib OK\" [ ! -d /Library/Server/Web/Data/Sites/Default/SE.test/se-lib ] && exit 1 exit 0 "; V::execRootRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort); $cmd = " mv /Library/Server/Web/Data/Sites/Default/SE {$remoteHomeDir}/bup.se.upgrade/bup.{$dateStr} 2>&1 mv /Library/Server/Web/Data/Sites/Default/SE.test /Library/Server/Web/Data/Sites/Default/SE 2>&1 exit 0 "; V::execRootRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort); DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__); if (0 !== $ret) throw new Exception("Cannot run remote command as root! #{$ret}"); // TODO: SE/bash_install_check.php requires $domain! // $cmd = "/usr/bin/php /Library/Server/Web/Data/Sites/Default/SE/bash_install_check.php {$domain}"; // V::execRootRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort); // DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__); // if (0 !== $ret) throw new Exception("Cannot run remote command as root! #{$ret}"); } public function _assertRsaKeyExists($appLicenceInfo) { $cmd = ''; $out = ''; $ret = ''; $cmd = "echo ~ && pwd";// /Library/WebServer $cmd = "ls -1 ~/.ssh/"; //$cmd = "rm /tmp/id_rsa"; //$cmd = "rm /tmp/id_rsa.pub"; //$cmd = "ssh-keygen -t rsa -N '' -C '_www@biuro.biall-net.pl' -f /tmp/id_rsa"; //$cmd = "ssh-keygen -t rsa -N '' -C '_www@biuro.biall-net.pl' -f /tmp/id_rsa"; V::exec($cmd, $out, $ret); DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__); if (0 !== $ret) {// no ~/.ssh directory $rsaKeyPath = "~/.ssh"; $cmds = array(); $cmds[] = "mkdir {$rsaKeyPath}"; $cmds[] = "ssh-keygen -t rsa -N '' -C '_www@biuro.biall-net.pl' -f {$rsaKeyPath}/id_rsa 2>&1"; $cmds[] = "ls -1 $rsaKeyPath"; foreach ($cmds as $cmd) { V::exec($cmd, $out, $ret); DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__); if (0 !== $ret) throw new Exception("Error '{$ret}' cmd({$cmd}): " . implode("\n", $out)); } } $cmd = "cat ~/.ssh/id_rsa.pub"; V::exec($cmd, $out, $ret); DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__); if (0 !== $ret || empty($out) || empty($out[0])) throw new Exception("Cannot read rsa public key"); $rsaPubKey = $out[0]; $cmd = 'ls -1a'; $cmd = " [ ! -d ~/.ssh ] && mkdir ~/.ssh; [ ! -d ~/.ssh ] && echo 'ERROR ~/.ssh not exists and cannot be created'; [ ! -f ~/.ssh/authorized_keys ] && echo '{$rsaPubKey}' > ~/.ssh/authorized_keys; [ ! -f ~/.ssh/authorized_keys ] && echo 'ERROR ~/.ssh/authorized_keys not exists and cannot be created'; cat ~/.ssh/authorized_keys| grep '{$rsaPubKey}' && echo 'OK' || echo '{$rsaPubKey}' >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys; "; V::execRemote($appLicenceInfo->mainServer, $appLicenceInfo->rootLogin, $appLicenceInfo->rootPassword, $cmd, $out, $ret, $appLicenceInfo->sshPort); DBG::_(true, true, "remote cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__); //$cmd = "ssh server@{$appLicenceInfo->mainServer} 'ls -1 .ssh/'"; //$cmd = "ssh -i ~/.ssh/id_rsa server@{$appLicenceInfo->mainServer} 'ls -1'"; $sshPort = (22 != $appLicenceInfo->sshPort)? "-p {$appLicenceInfo->sshPort}" : ''; $cmd = "ssh {$sshPort} {$this->sshArgsSkipHostKey} {$appLicenceInfo->rootLogin}@{$appLicenceInfo->mainServer} 'ls -1'"; V::exec("$cmd 2>&1", $out, $ret); // http://php.net/manual/pl/function.exec.php says I saw the exec, system, shell_exec and passthru functions, //and deduced that the solution was to //redirect the standard error (stderr) to the standard output (stdout). It's not very clean, since it mixes stderr with stdout, and I only wanted to log the stderr. //But it seems to be the only solution (suggestions are welcome). DBG::_(true, true, "cmd: {$cmd} (return: {$ret})", $out, __CLASS__, __FUNCTION__, __LINE__); if (0 !== $ret) throw new Exception("Cannot run remote command using rsa key! #{$ret}; Out: ".implode($out)."; Cmd: {$cmd};"); } public function newGenerateApp($appLicenceInfo) { if (empty($appLicenceInfo->ID)) throw new Exception("Nie wybrano serwera/licencji."); if (empty($appLicenceInfo->domains)) throw new Exception("Domains not found"); $installPath = $appLicenceInfo->installPath; if (empty($installPath)) throw new Exception("Install path not found"); $installPath .= '-p5'; $cmds = array(); $cmds[] = "if [ -d {$installPath} ] ; then rm -rf '{$installPath}'; fi"; $cmds[] = "mkdir {$installPath}"; $cmds[] = "cd {$installPath} && git clone --depth 1 ssh://git@biuro.biall-net.pl:2222/p5/p5.git ."; $cmds[] = "cd {$installPath} && echo `git show-ref --head|head -1|head -c 8` > SE/VERSION "; // TODO: fetch from DB { foreach ($appLicenceInfo->projects as $projectName) { $cmds[] = "cd {$installPath} && git submodule update --init SE/projects/{$projectName}"; } } foreach ($cmds as $cmd) { $out = ''; $ret = ''; V::exec($cmd, $out, $ret); DBG::nicePrint([ 'cmd' => $cmd, 'output' => $out ], "return: {$ret}"); } // $this->_encodeSource($appLicenceInfo->installPath, $appLicenceInfo->domains); } }