PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/app/CliTools/Console/Command/System/BannerCommand.php

https://gitlab.com/vectorci/clitools
PHP | 334 lines | 189 code | 64 blank | 81 comment | 12 complexity | f3532c4f2fa3aa35ccdc2dd3f98f5158 MD5 | raw file
  1. <?php
  2. namespace CliTools\Console\Command\System;
  3. /*
  4. * CliTools Command
  5. * Copyright (C) 2016 WebDevOps.io
  6. * Copyright (C) 2015 Markus Blaschke <markus@familie-blaschke.net>
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. use CliTools\Utility\FormatUtility;
  22. use CliTools\Utility\UnixUtility;
  23. use Symfony\Component\Console\Input\InputInterface;
  24. use Symfony\Component\Console\Output\OutputInterface;
  25. class BannerCommand extends \CliTools\Console\Command\AbstractCommand implements
  26. \CliTools\Console\Filter\OnlyRootFilterInterface
  27. {
  28. /**
  29. * Enable automatic terminal title
  30. *
  31. * @var bool
  32. */
  33. protected $automaticTerminalTitle = false;
  34. /**
  35. * Configure command
  36. */
  37. protected function configure()
  38. {
  39. $this->setName('system:banner')
  40. ->setDescription('Banner generator for /etc/issue');
  41. }
  42. /**
  43. * Execute command
  44. *
  45. * @param InputInterface $input Input instance
  46. * @param OutputInterface $output Output instance
  47. *
  48. * @return int|null|void
  49. */
  50. public function execute(InputInterface $input, OutputInterface $output)
  51. {
  52. $clearScreen = "\033[H" . "\033[2J";
  53. $normalFont = "\033[0m";
  54. $banner = $clearScreen;
  55. $banner .= $this->generateBannerHeader();
  56. $banner .= "\n";
  57. $banner .= "\n";
  58. $banner .= $this->generateSystemInfo();
  59. $banner .= "\n";
  60. $banner .= "\n" . $normalFont;
  61. echo $banner;
  62. return 0;
  63. }
  64. /**
  65. * Generate banner header
  66. *
  67. * @return string
  68. */
  69. protected function generateBannerHeader()
  70. {
  71. // INFO: you can use figlet command for generating ascii-art-text
  72. $logo = '
  73. ____ _______ __________ ____ ____ __ __________ ________ _ ____ ___
  74. / __ \\/ ____/ | / / ____/ / / __ \\/ __ \\/ |/ / ____/ | / /_ __/ | | / / |/ /
  75. / / / / __/ | | / / __/ / / / / / / /_/ / /|_/ / __/ / |/ / / / | | / / /|_/ /
  76. / /_/ / /___ | |/ / /___/ /___/ /_/ / ____/ / / / /___/ /| / / / | |/ / / / /
  77. /_____/_____/ |___/_____/_____/\\____/_/ /_/ /_/_____/_/ |_/ /_/ |___/_/ /_/
  78. ';
  79. $subline = ' Development VM :: ' . UnixUtility::lsbSystemDescription();
  80. // add color
  81. $lines = explode("\n", $logo);
  82. foreach ($lines as &$line) {
  83. $line = "\033[1;32m" . $line;
  84. }
  85. $logo = implode("\n", $lines);
  86. $ret = $logo . "\n\033[1;35m" . $subline;
  87. return $ret;
  88. }
  89. /**
  90. * Generate system info
  91. *
  92. * @return string
  93. */
  94. protected function generateSystemInfo()
  95. {
  96. $ret = array();
  97. $leftCol = array();
  98. $rightCol = array();
  99. // ##################
  100. // Left: System info
  101. // ##################
  102. $labelLength = 12;
  103. $bytesPadding = 10;
  104. $cpuCount = UnixUtility::cpuCount();
  105. $memSize = FormatUtility::bytes(UnixUtility::memorySize());
  106. $kernelVersion = UnixUtility::kernelVersion();
  107. $dockerVersion = UnixUtility::dockerVersion();
  108. $mountInfoList = UnixUtility::mountInfoList();
  109. $mailCount = $this->getMailCount();
  110. // Padding
  111. $memSize = str_pad($memSize, $bytesPadding, ' ', STR_PAD_LEFT);
  112. // Basic sys informations
  113. $leftCol[] = str_pad('Linux', $labelLength, ' ', STR_PAD_LEFT) . ': ' . $kernelVersion;
  114. if (!empty($dockerVersion)) {
  115. $leftCol[] = str_pad('Docker', $labelLength, ' ', STR_PAD_LEFT) . ': ' . $dockerVersion;
  116. }
  117. $leftCol[] = str_pad('CPU', $labelLength, ' ', STR_PAD_LEFT) . ': ' . $cpuCount . ' Cores';
  118. $leftCol[] = str_pad('Memory', $labelLength, ' ', STR_PAD_LEFT) . ': ' . $memSize;
  119. // Mount info list
  120. foreach ($mountInfoList as $mount => $stats) {
  121. $capacity = FormatUtility::bytes($stats['capacity']);
  122. $usage = $stats['usage'];
  123. if ($mount === '/') {
  124. $mount = 'root';
  125. }
  126. // padding
  127. $mount = str_pad($mount, $labelLength, ' ', STR_PAD_LEFT);
  128. $capacity = str_pad($capacity, $bytesPadding, ' ', STR_PAD_LEFT);
  129. $leftCol[] = $mount . ': ' . $capacity . ' (' . $usage . ' in use)';
  130. }
  131. // ##################
  132. // Right: Network interfaces
  133. // ##################
  134. $labelLength = 6;
  135. // Network list (but not docker interfaces)
  136. $netInterfaceList = UnixUtility::networkInterfaceList('/^((?!docker).)*$/i');
  137. foreach ($netInterfaceList as $netName => $netConf) {
  138. $netName = str_pad($netName, $labelLength, ' ', STR_PAD_LEFT);
  139. $rightCol[] = str_pad($netName, $labelLength, ' ', STR_PAD_LEFT) . ': ' . $netConf['ipaddress'];
  140. }
  141. $rightCol[] = '';
  142. if ($mailCount !== null) {
  143. $rightCol[] = str_pad('Mails', $labelLength, ' ', STR_PAD_LEFT) . ': ' . $mailCount;
  144. }
  145. // ##################
  146. // Build output
  147. // ##################
  148. // Get max number of rows
  149. $maxLines = max(count($leftCol), count($rightCol));
  150. $colLeftWidth = 54;
  151. $colRightWidth = 30;
  152. for ($i = 0; $i < $maxLines; $i++) {
  153. $leftColLine = '';
  154. $rightColLine = '';
  155. // Get col-cell if available
  156. if (isset($leftCol[$i])) {
  157. $leftColLine = $leftCol[$i];
  158. }
  159. // Get col-cell if available
  160. if (isset($rightCol[$i])) {
  161. $rightColLine = $rightCol[$i];
  162. }
  163. // Fill with required length
  164. $leftColLine = str_pad($leftColLine, $colLeftWidth, ' ', STR_PAD_RIGHT);
  165. $rightColLine = str_pad($rightColLine, $colRightWidth, ' ', STR_PAD_RIGHT);
  166. // Fix max length
  167. $leftColLine = substr($leftColLine, 0, $colLeftWidth);
  168. $rightColLine = substr($rightColLine, 0, $colRightWidth);
  169. // Build table row
  170. $ret[] = $leftColLine . $rightColLine;
  171. }
  172. return implode("\n", $ret);
  173. }
  174. /**
  175. * Get mail count
  176. */
  177. protected function getMailCount()
  178. {
  179. $ret = null;
  180. $mailboxUri = $this->getApplication()->getConfigValue('banner', 'mailbox');
  181. if (!empty($mailboxUri) && function_exists('imap_open')) {
  182. try {
  183. $mailboxConf = parse_url($mailboxUri);
  184. $hostname = $this->buildMailboxServerString($mailboxConf);
  185. $username = $mailboxConf['user'];
  186. $password = $mailboxConf['pass'];
  187. $mail = imap_open($hostname, $username, $password);
  188. $res = imap_check($mail);
  189. imap_close($mail);
  190. if (!empty($res)) {
  191. $ret = $res->Nmsgs;
  192. } else {
  193. throw new \RuntimeException('Mailcheck failed');
  194. }
  195. } catch (\Exception $e) {
  196. $ret = 'error';
  197. }
  198. }
  199. return $ret;
  200. }
  201. /**
  202. * Build imap connection string
  203. *
  204. * @param array $mailboxConf Mailbox configuration
  205. * @return string
  206. */
  207. protected function buildMailboxServerString(array $mailboxConf)
  208. {
  209. $hostname = $mailboxConf['host'];
  210. $path = ltrim($mailboxConf['path'],'/');
  211. switch ($mailboxConf['scheme']) {
  212. case 'imap-insecure':
  213. $port = !empty($mailboxConf['port']) ? $mailboxConf['port'] : 143;
  214. $ret = sprintf(
  215. '{%s:%s/novalidate-cert/norsh}%s',
  216. $hostname,
  217. $port,
  218. $path
  219. );
  220. break;
  221. case 'imap':
  222. $port = !empty($mailboxConf['port']) ? $mailboxConf['port'] : 143;
  223. $ret = sprintf(
  224. '{%s:%s}%s',
  225. $hostname,
  226. $port,
  227. $path
  228. );
  229. break;
  230. case 'imap':
  231. $port = !empty($mailboxConf['port']) ? $mailboxConf['port'] : 993;
  232. $ret = sprintf(
  233. '{%s:%s/imap/ssl}%s',
  234. $hostname,
  235. $port,
  236. $path
  237. );
  238. break;
  239. case 'pop3':
  240. $port = !empty($mailboxConf['port']) ? $mailboxConf['port'] : 110;
  241. $ret = sprintf(
  242. '{%s:%s/pop3}%s',
  243. $hostname,
  244. $port,
  245. $path
  246. );
  247. break;
  248. default:
  249. throw new \RuntimeException('Mailbox scheme "' . $mailboxConf['scheme'] . '"" is not supported');
  250. break;
  251. }
  252. return $ret;
  253. }
  254. /**
  255. * Build imap connection options
  256. *
  257. * @param array $mailboxConf Mailbox configuration
  258. * @return integer
  259. */
  260. protected function buildMailboxServerOptions(array $mailboxConf)
  261. {
  262. $ret = 0;
  263. switch ($mailboxConf['scheme']) {
  264. case 'imap-insecure':
  265. break;
  266. }
  267. return $ret;
  268. }
  269. }