diff --git a/public_html/deployment/index.php b/public_html/deployment/index.php index fb620a3611ab019796f9d15d29fc84a3c812eada..c9a84309e2702e4442791710afb4a84c1aba8be0 100644 --- a/public_html/deployment/index.php +++ b/public_html/deployment/index.php @@ -121,6 +121,11 @@ $sPhpOut = ' <div id="footer"> '.t("menu-brand").' © 2013-' . date("Y") . ' <a href="https://git-repo.iml.unibe.ch/iml-open-source/imldeployment/" target="_blank">Institut für Medizinische Lehre; Universität Bern</a> </div> + + <!-- + <script src="/deployment/plugins/shellcmd/load/render.js" /> + --> + '.$oCLog->render(); $oPage = new Page(); diff --git a/public_html/deployment/plugins/shellcmd/getdata.php b/public_html/deployment/plugins/shellcmd/getdata.php new file mode 100644 index 0000000000000000000000000000000000000000..12b260e86700c3dbb0e1cd3a20868ea1bd3fdd4c --- /dev/null +++ b/public_html/deployment/plugins/shellcmd/getdata.php @@ -0,0 +1,139 @@ +<?php +/* + * script to be used as ajax poll request to get current status of an action + */ + +header('Content-Type: application/json'); +require_once('plugins_shellcmd.class.php'); + +$oShell=new shellcmd(); +$oShell->sendResponse(); + +/* + +// width of load=1 +$iMaxWidth=100; + +$sPlugin=isset($_GET['plugin']) && $_GET['plugin'] ? preg_replace('/^a-z0-9/', '', $_GET['plugin']) : false; + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +function execCommand($sCmd){ + echo "DEBUG: ".__FUNCTION__ . "($sCmd)<br>"; + exec($sCmd, $aOut, $iResult); + return [ + 'command'=>$sCmd, + 'exitcode'=>$iResult, + 'output'=>$aOut, + ]; +} + + +if (!$sPlugin){ + echo "DEBUG: Missing param for a plugin.<br>"; + return [ 'error' => 'Missing param for a plugin.' ]; +} + +$sPluginfile=$sPlugin.'/command.php'; +$sPluginclass='shellplugin_'.$sPlugin; + +echo "DEBUG: sPluginfile=$sPluginfile<br>"; + +if (!file_exists($sPluginfile)){ + echo "DEBUG: Plugin seems to be corrupt. File not found: '. $sPluginfile.'<br>"; + return [ 'error' => 'Plugin seems to be corrupt. File not found: '. $sPluginfile ]; +} + + +include($sPluginfile); + +$oPlugin=new $sPluginclass(); + +echo "DEBUG: sCmd=$sCmd<br>"; + +$aResult=execCommand($sCmd); +if (function_exists("parsedata")){ + $aResult=parsedata($aResult); +} + +echo '<pre>$aResult = '.print_r($aResult, 1).'<pre>'; +return $aResult; + + +// ---------------------------------------------------------------------- +function getLoad(){ + $sCmd='uptime'; + $aResult=execCommand($sCmd); + $aTmp1=explode(',', $aResult['output'][0]); + $aResult['data']=[ + 'uptime'=>$aTmp1[0], + 'users'=>$aTmp1[1], + 'load'=>preg_replace('/^.*:/', '', $aTmp1[2]), + 'load5'=>$aTmp1[3], + 'load15'=>$aTmp1[4], + ]; + return $aResult; +} + +function getProcesses($sFilter){ + $sRegex=$sFilter ? $sFilter : 'SomethingThatWontMatchInProcessList'; + $sCmd="ps -f --forest | egrep -v '($sRegex)' | fgrep -v 'ps -f' | fgrep -v grep"; + return execCommand($sCmd); +} + + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +function load(){ + global $iMaxWidth; + $sReturn=''; + + $aData=getLoad()['data']; + + $iMaxLoad=round(max($aData['load'], $aData['load5'], $aData['load15']))+1; + $iScale=$iMaxWidth/$iMaxLoad; + + $sScalaPart=str_repeat('_', (round($iScale)-1)).'|'; + $sScala=str_repeat($sScalaPart, $iMaxLoad).$iMaxLoad; + + + $sBar1=str_repeat('#', (int)($aData['load']*$iScale)); + $sBar5=str_repeat(' ', (int)($aData['load5']*$iScale - 1)).'|'; + $sBar15=str_repeat(' ', (int)($aData['load15']*$iScale - 1)).'^'; + + $sReturn.= 'LOAD '.$aData['load'].' .. '.$aData['load5'].' .. '.$aData['load15'].'<br>' + . $sScala.'<br>' + . substr($sBar1, 0, $iMaxWidth).'<br>' + . substr($sBar5, 0, $iMaxWidth).'<br>' + . substr($sBar15, 0, $iMaxWidth).'<br>' + ; + + return $sReturn; +} + + +function processes(){ + + return 'PROCESSES:<br>' + .shell_exec("ps -f --forest | egrep -v '(apache|httpd)' | fgrep -v 'ps -f' | fgrep -v grep") + .'<hr>all processes:<br>' + .shell_exec("ps -f --forest") + ; +} + +// ---------------------------------------------------------------------- +// MAIN +// ---------------------------------------------------------------------- + +$sRemove='apache|httpd|php-fpm'; + +echo '<pre>' + . load() + // .'<hr size="1">' + + .'<hr size="1">' + .'API DATA' + .'<pre>getLoad()='.print_r(getLoad(), 1).'</pre>' + .'<pre>getProcesses(\''.$sRemove.'\')='.print_r(getProcesses($sRemove), 1).'</pre>' + ; +*/ \ No newline at end of file diff --git a/public_html/deployment/plugins/shellcmd/load/plugin.php b/public_html/deployment/plugins/shellcmd/load/plugin.php new file mode 100644 index 0000000000000000000000000000000000000000..ec9338047ae1d60dbb39120bad91a5ad9da444b6 --- /dev/null +++ b/public_html/deployment/plugins/shellcmd/load/plugin.php @@ -0,0 +1,70 @@ +<?php +/** + * + * SHELLCMD PLUGIN :: LOAD + * + * ---------------------------------------------------------------------- + * 2022-08-05 axel.hahn@iml.unibe.ch + */ +class shellcmd_load { + /** + * @var command line to exectute + */ + protected $_command='uptime'; + + + /** + * constructor ... returns command + * @return string + */ + public function __constructor(){ + return $this->getCommand(); + } + + /** + * get command + * @return string + */ + public function getCommand(){ + return $this->_command; + } + + + /** + * parse output and extract wanted values in section "data" + * @return array + */ + public function parsedata($aResult){ + $aTmp1=array_reverse(explode(',', $aResult['output'][0])); + // print_r($aTmp1); + $aResult['data']=[ + 'uptime'=>trim($aTmp1[4]), + 'users'=>trim(str_replace(' users', '', $aTmp1[3])), + 'load'=>trim(preg_replace('/^.*:/', '', $aTmp1[2])), + 'load5'=>trim($aTmp1[1]), + 'load15'=>trim($aTmp1[0]), + ]; + return $aResult; + } + +} +/* + +EXAMPLE OUTPUT + +{ + "command": "uptime", + "exitcode": 0, + "output": [ + " 13:36:54 up 1 day, 7:39, 0 users, load average: 1.18, 1.29, 1.33" + ], + "data": { + "uptime": "7:39", + "users": "0", + "load": "1.18", + "load5": "1.29", + "load15": "1.33" + } +} + +*/ \ No newline at end of file diff --git a/public_html/deployment/plugins/shellcmd/load/render.js b/public_html/deployment/plugins/shellcmd/load/render.js new file mode 100644 index 0000000000000000000000000000000000000000..f4d310608589579e60c7cdb0171f53e5b7ba5d79 --- /dev/null +++ b/public_html/deployment/plugins/shellcmd/load/render.js @@ -0,0 +1,7 @@ +function load_render(aData){ + var sReturn=''; + sReturn+=aData['command']+"<br>" + + "Load: "+aData["data"]['load']+"<br>" + ; + return sReturn; +} \ No newline at end of file diff --git a/public_html/deployment/plugins/shellcmd/plugins_shellcmd.class.php b/public_html/deployment/plugins/shellcmd/plugins_shellcmd.class.php new file mode 100644 index 0000000000000000000000000000000000000000..938c8c57c96560ba70d7b45f6f418571983140a5 --- /dev/null +++ b/public_html/deployment/plugins/shellcmd/plugins_shellcmd.class.php @@ -0,0 +1,103 @@ +<?php + +class shellcmd { + + protected $_sPlugin=false; + protected $_oPlugin=false; + protected $_aReturn=false; + + protected $_debug=false; + + /** + * constructor + * @return bool + */ + public function __construct(){ + return $this->detectPlugin(); + } + + + /** + * write debug output ... if enabled + */ + protected function _wd($s){ + echo $this->_debug ? 'DEBUG '.__CLASS__ . ' '.$s."<br>\n" : ''; + } + + /** + * detect plugin name to load from GET param "plugin" + */ + public function detectPlugin(){ + $this->_sPlugin=isset($_GET['plugin']) && $_GET['plugin'] ? preg_replace('/^a-z0-9/', '', $_GET['plugin']) : false; + $this->_wd("detected plugin: ".$this->_sPlugin); + return true; + } + + + /** + * initialize the shellcmd plugin + * @returm boolean + */ + protected function _loadPlugin(){ + $this->_oPlugin=false; + if (!$this->_sPlugin){ + $this->_wd("Missing param for a plugin"); + $this->_aReturn=[ 'error' => 'Missing param for a plugin.' ]; + return false; + } + $sPluginfile=$this->_sPlugin.'/plugin.php'; + $sPluginclass='shellcmd_'.$this->_sPlugin; + + if (!file_exists($sPluginfile)){ + $this->_wd("Plugin seems to be corrupt. File not found: '. $sPluginfile."); + $this->_aReturn=[ 'error' => 'Plugin seems to be corrupt. File not found: '. $sPluginfile ]; + return false; + } + include($sPluginfile); + $this->_oPlugin=new $sPluginclass(); + return true; + } + /** + * helper execute a given command and return array with executed + * command, returncode, output + * @return + */ + protected function _execCommand($sCmd){ + exec($sCmd, $aOut, $iResult); + return [ + 'command'=>$sCmd, + 'exitcode'=>$iResult, + 'output'=>$aOut, + ]; + } + + /** + * get data from plugin command and return array with executed + * command, returncode, output, parsed data + * @return array + */ + public function get(){ + $this->_loadPlugin(); + if (!$this->_oPlugin){ + return $this->_aReturn; + } + + $sCmd=$this->_oPlugin->getCommand(); + $this->_wd("sCmd=$sCmd"); + + $this->_aResult=$this->_execCommand($sCmd); + if (method_exists($this->_oPlugin, "parsedata")){ + $this->_aResult=$this->_oPlugin->parsedata($this->_aResult); + } + return $this->_aResult; + } + + /** + * send response as json + */ + public function sendResponse(){ + header('Content-Type: application/json'); + echo json_encode($this->get(), JSON_PRETTY_PRINT); + } + +} diff --git a/public_html/deployment/plugins/shellcmd/processes/command.php b/public_html/deployment/plugins/shellcmd/processes/command.php new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391