diff --git a/config/inc_projects_config.php b/config/inc_projects_config.php index 9debed14af8a92e74d96f0e7e7c2e52380e6648b..f350e2de1df7c094a82184dfe461df2c39577610 100644 --- a/config/inc_projects_config.php +++ b/config/inc_projects_config.php @@ -57,6 +57,9 @@ $aConfig = array( "deploytimes" => array('/(Mon|Tue|Wed|Thu)\ 14\:/'), ), ), + 'showdebug' => array( + 'ip'=>array('10.0.2.2', '127.0.0.1', '130.92.79.49'), + ), // for available languages see ./config/lang/*.json ); // ---------------------------------------------------------------------- diff --git a/config/lang/de.json b/config/lang/de.json index aad1ebb87d116d3ff3e5fb6abdb89c1afc143ccd..b6d48c6aa38456a7b1de45d74fa806cfde23fe14 100644 --- a/config/lang/de.json +++ b/config/lang/de.json @@ -217,6 +217,7 @@ "description": "Beschreibung", "developer": "Entwickler", "dir-archive": "Archiv-Verzeichnis", + "dir-cache": "Cache-Verzeichnis", "dir-builds": "Build-Verzeichnis", "empty": "[leer]", "error": "FEHLER", diff --git a/config/lang/en.json b/config/lang/en.json index 8248e664ec1fdc67296b7fe72ed0440baad916d8..ebdaf6959dc94c6b4cdbcef76c038559d7773caf 100644 --- a/config/lang/en.json +++ b/config/lang/en.json @@ -219,6 +219,7 @@ "description": "Description", "developer": "Developer", "dir-archive": "Archive directory", + "dir-cache": "Cache directory", "dir-builds": "Build directory", "empty": "[empty]", "error": "ERROR", diff --git a/public_html/deployment/classes/logger.class.php b/public_html/deployment/classes/logger.class.php new file mode 100644 index 0000000000000000000000000000000000000000..1bc74090de16472ff21a545bcfedf28dba017615 --- /dev/null +++ b/public_html/deployment/classes/logger.class.php @@ -0,0 +1,106 @@ +<?php + +/** + * Debug logging during a client request. + * + * @author hahn + */ +class logger { + protected $aMessages=array(); + protected $bShowDebug=true; + + + /** + * constuctor + * @param string $sInitMessage init message + * @return boolean + */ + public function __construct($sInitMessage="Logger was initialized.") { + $this->add($sInitMessage); + return true; + } + + /** + * enable / disable debugging + * @param type $bEnable + * @return type + */ + public function enableDebug($bEnable=false){ + return $this->bShowDebug=$bEnable; + } + + public function enableDebugByIp($aIpArray){ + $this->enableDebug(false); + if (!$_SERVER || !is_array($_SERVER) || !array_key_exists("REMOTE_ADDR", $_SERVER)){ + return false; + } + if (array_search($_SERVER['REMOTE_ADDR'], $aIpArray)!==false){ + $this->enableDebug(true); + } + } + + /** + * add a logging message + * @param type $sMessage + * @param type $sLevel + * @return boolean + */ + public function add($sMessage, $sLevel="info"){ + if (!$this->bShowDebug){ + return false; + } + global $aCfg; + $this->aMessages[]=array( + 'time'=>microtime(true), + 'message'=>$sMessage, + 'level'=>$sLevel + ); + if ($sLevel=="MAIL"){ + mail($aCfg["emailDeveloper"], "studmed - booking tool - Logmessage", $sMessage); + } + + return true; + } + + /** + * render output of all logging messages + */ + public function render(){ + if (!$this->bShowDebug){ + return false; + } + $sOut=''; + $sStarttime=$this->aMessages[0]["time"]; + $iLasttime=$sStarttime; + foreach ($this->aMessages as $aLogentry){ + $sOut.='<tr class="'.$aLogentry["level"].'">'. + '<!-- <td>'.$aLogentry["time"].'</td> -->'. + '<td>'.sprintf("%01.4f", $aLogentry["time"]-$sStarttime).'</td>'. + '<td>'.sprintf("%01.4f", $aLogentry["time"]-$iLasttime).'</td>'. + '<td>'.$aLogentry["level"].'</td>'. + '<td>'.$aLogentry["message"].'</td>'. + '</tr>'; + $iLasttime=$aLogentry["time"]; + } + if ($sOut) $sOut=' + <br> + <br> + <br> + <br> + <br> + <h3>DEBUG</h3><br> + <table class="datatable table table-striped debugtable"> + <thead> + <tr> + <!-- <th>time</th> --> + <th>delta to start time</th> + <th>delta to previuos</th> + <th>level</th> + <th>message</th> + </tr></thead><tbody> + '.$sOut.'</tbody></table>'; + return $sOut; + } +} + +?> diff --git a/public_html/deployment/classes/project.class.php b/public_html/deployment/classes/project.class.php index 194b712739369216835c88fb184c8fb74418ecfa..46773042a0413a53e05a4fd11394b0acb579cd25 100644 --- a/public_html/deployment/classes/project.class.php +++ b/public_html/deployment/classes/project.class.php @@ -97,6 +97,17 @@ class project { // ---------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------- + /** + * add a log messsage + * @global object $oLog + * @param string $sMessage messeage text + * @param string $sLevel warnlevel of the given message + * @return bool + */ + private function log($sMessage,$sLevel="info"){ + global $oCLog; + return $oCLog->add(basename(__FILE__)." class ".__CLASS__." - ".$sMessage,$sLevel); + } /** * read default config file @@ -167,6 +178,7 @@ class project { * @return string */ private function _execAndSend($sCommand, $bFlush = false) { + $this->log(__FUNCTION__." start"); $sReturn = ''; $bUseHtml = $_SERVER ? true : false; @@ -182,7 +194,9 @@ class project { $sReturn.=$bUseHtml ? "<br>" : "\n"; $sOutput = false; + $this->log(__FUNCTION__." start $sCommand"); exec($sCommand, $aOutput, $iRc); + $this->log(__FUNCTION__." ended command $sCommand"); $sReturn.=(count($aOutput)) ? implode("\n", $aOutput) . "\n" : ""; /* $descriptorspec = array( @@ -410,15 +424,18 @@ class project { * @return string */ private function _httpGet($url, $iTimeout=5) { + $this->log(__FUNCTION__." start"); if (!function_exists("curl_init")){ die("ERROR: PHP CURL module is not installed."); } + $this->log(__FUNCTION__." url: $url"); $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_TIMEOUT, $iTimeout); $res = curl_exec($ch); curl_close($ch); + $this->log(__FUNCTION__." done url: $url"); return $res; } @@ -562,6 +579,7 @@ class project { * @return array */ public function cleanupBuilds() { + $this->log(__FUNCTION__." start"); $sDir = $this->_getBuildDir(); $aDirlist = array(); $aDelete = array(); @@ -585,6 +603,24 @@ class project { return $aDelete; } + + /** + * cleanup cache of vcs + * @param type $iAge + */ + public function cleanupVcsCache($iAge=0) { + $this->log(__FUNCTION__." start"); + $this->_initVcs(); + if ($this->_oVcs) { + if (!method_exists($this->_oVcs, "cleanupCache")) { + // the version control class does not have this method + $this->log(__FUNCTION__." soory, Methos cleanupCache does not exist in this VCS class."); + return ''; + } + return $this->_oVcs->cleanupCache($iAge); + } + + } /** * get conmplete config of the project @@ -842,6 +878,7 @@ class project { * @return string|boolean */ public function getRemoteBranches($sActiveBranchname = false) { + $this->log(__FUNCTION__." start"); $this->_initVcs(); if ($this->_oVcs) { if (!method_exists($this->_oVcs, "getRemoteBranches")) { @@ -946,6 +983,7 @@ class project { * @return array */ public function getRepoRevision($bRefresh = false) { + $this->log(__FUNCTION__." start"); // $sReturn = ""; if ( array_key_exists("source", $this->_aData["phases"]) && $this->_aData["phases"]["source"] && $bRefresh == false @@ -973,6 +1011,7 @@ class project { * @return vcs-object */ private function _initVcs() { + $this->log(__FUNCTION__." start"); if (!$this->_oVcs) { if (!$this->_aPrjConfig["build"]["type"]) { $this->_aData["phases"]["source"] = array("error" => t("class-project-error-repo-type-not-set"),); @@ -1136,6 +1175,7 @@ class project { * @return string */ public function getBox($sWarnlevel, $sMessage) { + $this->log(__FUNCTION__." start"); $aCfg = array( "error" => array("class" => "alert alert-error", "prefix" => t("error")), "success" => array("class" => "alert alert-success", "prefix" => t("success")), @@ -1160,6 +1200,7 @@ class project { * @return string */ public function getBranchname() { + $this->log(__FUNCTION__." start"); $this->_initVcs(); if ($this->_oVcs) { if (method_exists($this->_oVcs, "getCurrentBranch")) { @@ -1178,6 +1219,7 @@ class project { * @return boolean|string */ public function build($sTmpFile = false) { + $this->log(__FUNCTION__." start"); global $aParams; $sReturn = false; @@ -1569,6 +1611,7 @@ class project { * @return boolean|string */ public function deploy($sPhase, $bIgnoreDeploytimes = false) { + $this->log(__FUNCTION__." start"); $aActionList = array( 'iActive' => 0, 'label' => t("deploy"), @@ -1735,6 +1778,7 @@ class project { * @return type */ public function accept($sPhase) { + $this->log(__FUNCTION__." start"); $sReturn = "<h2>" . t("accept") . " " . $this->getLabel() . " :: $sPhase</h2>"; $this->_logaction(t('starting') . " accept($sPhase)", __FUNCTION__); @@ -1766,9 +1810,11 @@ class project { * @return boolean */ public function saveConfig($aData = false) { + $this->log(__FUNCTION__." start"); $this->_logaction(t('starting') . " saveConfig(...)", __FUNCTION__); - if (!$aData) + if (!$aData){ $aData = $_POST; + } if (!array_key_exists("id", $aData)) { $this->_logaction(t('abortet') . " no id in \$_POST", __FUNCTION__, "error"); return false; @@ -1803,6 +1849,7 @@ class project { * @return string */ public function create($sId) { + $this->log(__FUNCTION__." start"); $this->_logaction(t('starting') . " create($sId)", __FUNCTION__); if (!$sId) { $sError = t("class-project-error-create-missing-id"); @@ -1867,6 +1914,7 @@ class project { * @return boolean|string */ public function delete($aOptions = array()) { + $this->log(__FUNCTION__." start"); $sCfgfile = $this->_getConfigFile($this->_aConfig["id"]); if (!file_exists($sCfgfile)) { return t("class-project-error-delete-project-no-configfile"); diff --git a/public_html/deployment/classes/vcs.git.class.php b/public_html/deployment/classes/vcs.git.class.php index 66999944b3a537a9543de9cf4f5e68fe68f25c7a..12f8d9e0dcce3e299597db8ba9ad6ad115aaf91e 100644 --- a/public_html/deployment/classes/vcs.git.class.php +++ b/public_html/deployment/classes/vcs.git.class.php @@ -57,6 +57,18 @@ class vcs implements iVcs { $this->setConfig($aRepoConfig); $this->getRemoteBranches(); // to fill the cache } + + /** + * add a log messsage + * @global object $oLog + * @param string $sMessage messeage text + * @param string $sLevel warnlevel of the given message + * @return bool + */ + private function log($sMessage,$sLevel="info"){ + global $oCLog; + return $oCLog->add(basename(__FILE__)." class ".__CLASS__." - ".$sMessage,$sLevel); + } /** * set a config and update internal (private) variables @@ -64,7 +76,6 @@ class vcs implements iVcs { * @return boolean */ public function setConfig($aRepoConfig = array()) { - // checks // foreach (array("type", "url") as $key) { foreach (array("type") as $key) { @@ -170,10 +181,15 @@ class vcs implements iVcs { * cleanup cache data for this project (revisions, list of branches+tags) * @return bool */ - private function _cleanupCache($iAge) { + public function cleanupCache($iAge) { + $this->log(__FUNCTION__." start"); require_once 'cache.class.php'; $oCache = new AhCache($this->_getNameOfCacheModule()); - return $oCache->cleanup((int)$iAge); + ob_start(); + $oCache->cleanup((int)$iAge); + $sOut = ob_get_contents(); + ob_end_clean(); + return $sOut; } /** @@ -184,6 +200,7 @@ class vcs implements iVcs { * @return array */ private function _fetchRemoteBranches($bForceNoCache = false) { + $this->log(__FUNCTION__." start"); $aReturn = array(); if (!$this->getUrl()) { @@ -207,7 +224,9 @@ class vcs implements iVcs { $sGitCmd.='cd "' . $sWorkdir . '" 2>&1 && '; } $sGitCmd.='git ls-remote --heads --tags origin 2>&1 ;'; + $this->log(__FUNCTION__." start command $sGitCmd"); exec($sGitCmd, $aOutput, $iRc); + $this->log(__FUNCTION__." end command $sGitCmd"); if ($iRc == 0) { // use cache that getCommitmessageByBranch can access it @@ -252,6 +271,7 @@ class vcs implements iVcs { * @return array */ public function getRemoteBranches() { + $this->log(__FUNCTION__." start"); if (!$this->_aRemoteBranches) { $this->_fetchRemoteBranches(); } @@ -264,6 +284,7 @@ class vcs implements iVcs { * @return array */ public function getRepoRevision() { + $this->log(__FUNCTION__." start"); $sMessage = $this->getCommitmessageByBranch(); if ($sMessage) { $aReturn = array( @@ -284,6 +305,7 @@ class vcs implements iVcs { * @return string */ public function getCommitmessageByBranch($sBranch = false, $sVerifyRevision = false) { + $this->log(__FUNCTION__." start"); if (!$sBranch) { $sBranch = $this->_sCurrentBranch; } @@ -329,6 +351,7 @@ class vcs implements iVcs { * @return array */ public function getRevision($sWorkDir = false) { + $this->log(__FUNCTION__." start"); $aReturn = array(); if (!$this->getUrl()) { return false; @@ -354,7 +377,9 @@ class vcs implements iVcs { } $sGitCmd.='git log -1 "' . $this->_sCurrentBranch . '" 2>&1 ; '; // 0.0 s + $this->log(__FUNCTION__." start command $sGitCmd"); $sLoginfo = shell_exec($sGitCmd); + $this->log(__FUNCTION__." end command $sGitCmd"); /* * * example output: @@ -408,6 +433,7 @@ class vcs implements iVcs { * @return bool */ public function getSources($sWorkDir) { + $this->log(__FUNCTION__." start"); if (!$sWorkDir || !is_dir($sWorkDir)) { return false; } @@ -419,7 +445,9 @@ class vcs implements iVcs { $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; '; $sGitCmd .= 'echo git clone --depth 1 --recursive --branch "' . $sBranchname . '" "' . $this->getUrl() . '" "' . $sWorkDir . '" ; '; $sGitCmd .= 'git clone --depth 1 --recursive --branch "' . $sBranchname . '" "' . $this->getUrl() . '" "' . $sWorkDir . '" 2>&1; '; + $this->log(__FUNCTION__." start command $sGitCmd"); $sReturn = shell_exec($sGitCmd); + $this->log(__FUNCTION__." end command $sGitCmd"); return $sReturn; } @@ -427,6 +455,7 @@ class vcs implements iVcs { * return url to vcs sources */ public function getUrl() { + $this->log(__FUNCTION__." start"); return $this->_aCfg["url"]; } @@ -434,6 +463,7 @@ class vcs implements iVcs { * return url to view sources in webrowser to generate an infolink */ public function getWebGuiUrl() { + $this->log(__FUNCTION__." start"); return $this->_aCfg["webaccess"]; } diff --git a/public_html/deployment/index.php b/public_html/deployment/index.php index 25133e446d180b23dc677de1313c548067a8d8b8..efafd0da8d03575e983fd8149dd8f4b7708f224c 100644 --- a/public_html/deployment/index.php +++ b/public_html/deployment/index.php @@ -18,6 +18,10 @@ require_once("./classes/page.class.php"); require_once("../../config/inc_projects_config.php"); +require_once("./classes/logger.class.php"); +global $oCLog; +$oCLog = new logger(); +$oCLog->enableDebugByIp($aConfig['showdebug']['ip']); require_once("./inc_functions.php"); $sPrj = ""; @@ -33,6 +37,11 @@ if (array_key_exists("action", $aParams)) { $sAction = $aParams["action"]; } } +$oCLog->add("parsing params " + . '<pre>GET '.print_r($_GET, true).'</pre>' + . '<pre>POST '.print_r($_POST, true).'</pre>' + . '<pre>aParams: '.print_r($aParams, true).'</pre>' + ); // ------ Ausgabe @@ -50,20 +59,25 @@ $sTopAction=getAction(); $sActionFile = __DIR__ . '/pages/act_' . $sAction . ".php"; +$oCLog->add("including $sActionFile"); ob_start(); if (!@include($sActionFile)) { include("./pages/error_404.php"); } $sPhpOut = ob_get_contents(); ob_end_clean(); +$oCLog->add("including done $sActionFile"); +$oCLog->add("adding actionlog.class"); require_once("./classes/actionlog.class.php"); $oLog=new Actionlog($sPrj); $aFilter=array('limit'=>'0, 10'); if ($sPrj && $sPrj!="all")$aFilter['project']=$sPrj; $sPhpOut.='<div class="logs">' . $oLog->renderLogs($aFilter).'</div>'; +$oCLog->add("adding actionlog.class done"); +$oCLog->add("Finally: rendering page ..."); $sPhpOut = ' <div id="header" style="display: none;"> @@ -78,8 +92,7 @@ $sPhpOut = ' <div id="footer"> IML Deployment © ' . date("Y") . ' <a href="http://www.iml.unibe.ch/">Institut für medizinische Lehre; Universität Bern</a> </div> - '; - + '.$oCLog->render(); $oPage = new Page(); $oPage->addResponseHeader("Pragma: no-cache"); diff --git a/public_html/deployment/pages/act_cleanup.php b/public_html/deployment/pages/act_cleanup.php index 873cf54ef0f9c2a4d7309eec5e50236e1a07d0b2..f0259a03e099e2956a9e7d1ea8eacd40d72b9836 100644 --- a/public_html/deployment/pages/act_cleanup.php +++ b/public_html/deployment/pages/act_cleanup.php @@ -28,6 +28,10 @@ $sOut = ' <h3>' . t("dir-builds") . ': ' . $aConfig['buildDir'] . '/[project]/</h3> ' . t("page-cleanup-info-builds-left") . ':<br> <pre>' . print_r($oPrj->cleanupBuilds(), true) . '</pre> + + <h3>'.t("dir-cache").'</h3> + <pre>' . $oPrj->cleanupVcsCache() . '</pre> + <div id="navbuttom">' . aPrjHome() . '</div>'; // -- Ausgabe diff --git a/shellscripts/cron_deployment.php b/shellscripts/cron_deployment.php index 223c019730a5aceb6859badfaf1fa082a12acf0e..29b47151dfacd60daf0ef765e7afeaa5981fda99 100644 --- a/shellscripts/cron_deployment.php +++ b/shellscripts/cron_deployment.php @@ -9,6 +9,11 @@ // http://iml:deployment@ci.iml.unibe.ch/deployment/?prj=ci&action=deploy&par3=preview&confirm=1 $sDocroot = (dirname(__dir__)) . "/public_html"; + +require_once("$sDocroot/deployment/classes/logger.class.php"); +global $oCLog; +$oCLog = new logger(); + require_once("$sDocroot/../config/inc_projects_config.php"); require_once("$sDocroot/deployment/inc_functions.php"); require_once("$sDocroot/deployment/classes/project.class.php");