control.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. <?php
  2. if(!DEFINED('EGP'))
  3. exit(header('Refresh: 0; URL=http://'.$_SERVER['SERVER_NAME'].'/404'));
  4. class ctrl
  5. {
  6. public static function status($status)
  7. {
  8. switch($status)
  9. {
  10. case 'working':
  11. return 'работает';
  12. case 'reboot':
  13. return 'перезагружается';
  14. case 'error':
  15. return 'не отвечает';
  16. case 'install':
  17. return 'настраивается';
  18. case 'overdue':
  19. return 'просрочен';
  20. case 'blocked':
  21. return 'заблокирован';
  22. }
  23. }
  24. public static function buttons($id, $status)
  25. {
  26. global $html;
  27. $html->arr['btn'] = '';
  28. if($status == 'working')
  29. {
  30. $html->get('restart', 'sections/control/buttons');
  31. $html->set('id', $id);
  32. $html->pack('btn');
  33. return $html->arr['btn'];
  34. }
  35. return '';
  36. }
  37. public static function resources($id)
  38. {
  39. global $sql;
  40. include(LIB.'ssh.php');
  41. $aData = array(
  42. 'cpu' => '0%',
  43. 'ram' => '0%',
  44. 'hdd' => '0%'
  45. );
  46. $sql->query('SELECT `address`, `passwd` FROM `control` WHERE `id`="'.$id.'" LIMIT 1');
  47. $ctrl = $sql->get();
  48. if(!$ssh->auth($ctrl['passwd'], $ctrl['address']))
  49. sys::outjs($aData);
  50. $data = $ssh->get('echo `cat /proc/meminfo | grep MemTotal | awk \'{print $2}\'; cat /proc/meminfo | grep MemFree | awk \'{print $2}\'; cat /proc/meminfo | grep Buffers | awk \'{print $2}\'; cat /proc/meminfo | grep Cached | grep -v SwapCached | awk \'{print $2}\'`');
  51. $aData['ram'] = ceil(ctrl::ram_load($data)).'%';
  52. $aData['hdd'] = trim($ssh->get('df -h | awk \'/rootfs/ {print $5}\''));
  53. $aData['cpu'] = ctrl::cpu_load($ssh->get('echo "`ps -A -o pcpu | tail -n+2 | paste -sd+ | bc | awk \'{print $0}\'` `cat /proc/cpuinfo | grep processor | wc -l | awk \'{print $1}\'`"')).'%';
  54. sys::outjs($aData);
  55. }
  56. public static function update_info($id)
  57. {
  58. global $sql;
  59. include(LIB.'ssh.php');
  60. $aData = array(
  61. 'cpu' => 'произошла ошибка',
  62. 'ram' => 'произошла ошибка',
  63. 'hdd' => 'произошла ошибка'
  64. );
  65. $sql->query('SELECT `address`, `passwd` FROM `control` WHERE `id`="'.$id.'" LIMIT 1');
  66. $ctrl = $sql->get();
  67. if(!$ssh->auth($ctrl['passwd'], $ctrl['address'].':22'))
  68. sys::outjs($aData);
  69. $data = $ssh->get('cat /proc/meminfo | grep MemTotal | cut -d \' \' -f 2-');
  70. $aData['ram'] = $data.' ('.(round(sys::int($data)/1024/1024, 2)).'Gb)';
  71. $aData['hdd'] = trim($ssh->get('df -h | awk \'/rootfs/ {print $2}\''));
  72. $aCPU = explode("\n", trim($ssh->get('cat /proc/cpuinfo | grep -c processor && cat /proc/cpuinfo | grep "MHz" | awk \'{print $4}\' | head -n 1')));
  73. $aData['cpu'] = $aCPU[0].'x'.round($aCPU[1], 0).' MHz ['.trim($ssh->get('cat /proc/cpuinfo | grep -m 1 "model name" | cut -d \' \' -f 3-')).']';
  74. sys::outjs($aData);
  75. }
  76. public static function update_status($id, $ssh = false)
  77. {
  78. global $cfg, $sql, $start_point, $mcache;
  79. if(!$ssh)
  80. include(LIB.'ssh.php');
  81. $sql->query('SELECT `address`, `passwd`, `time`, `overdue`, `block`, `status` FROM `control` WHERE `id`="'.$id.'" LIMIT 1');
  82. $ctrl = $sql->get();
  83. $status = $ctrl['status'];
  84. if($ctrl['status'] == 'blocked' && $ctrl['block'] < $start_point)
  85. $sql->query('UPDATE `control` set `block`="0", `status`="working" WHERE `id`="'.$id.'" LIMIT 1');
  86. if($ctrl['status'] == 'blocked')
  87. return 'blocked';
  88. // Если аренда закончилась и сервер просрочен длительное время
  89. if($ctrl['time'] < $start_point && $ctrl['status'] == 'overdue' && ($ctrl['overdue']+$cfg['control_delete']*86400) < $start_point)
  90. {
  91. $sql->query('UPDATE `control` set `user`="-1" WHERE `id`="'.$id.'" LIMIT 1');
  92. return 'delete';
  93. }
  94. // Если аренда закончилась, а услуга не просрочена
  95. if($ctrl['time'] < $start_point && !in_array($ctrl['status'], array('overdue', 'blocked')))
  96. {
  97. $sql->query('UPDATE `control` set `status`="overdue" WHERE `id`="'.$id.'" LIMIT 1');
  98. $status = 'overdue';
  99. }
  100. // Если аренда не закончилась, а услуга просрочена
  101. if($ctrl['time'] > $start_point && $ctrl['status'] == 'overdue')
  102. $sql->query('UPDATE `control` set `status`="working" WHERE `id`="'.$id.'" LIMIT 1');
  103. if(in_array($ctrl['status'], array('working', 'error')))
  104. {
  105. $status = 'working';
  106. if(!$ssh->auth($ctrl['passwd'], $ctrl['address']))
  107. $status = 'error';
  108. $sql->query('UPDATE `control` set `status`="'.$status.'" WHERE `id`="'.$id.'" LIMIT 1');
  109. }
  110. if($ctrl['status'] == 'reboot' && !$mcache->get('reboot_control_'.$id))
  111. {
  112. if($ssh->auth($ctrl['passwd'], $ctrl['address']))
  113. {
  114. $sql->query('UPDATE `control` set `status`="working" WHERE `id`="'.$id.'" LIMIT 1');
  115. $status = 'working';
  116. }
  117. }
  118. $time_end = $ctrl['status'] == 'overdue' ? 'Удаление через: '.sys::date('min', $ctrl['overdue']+$cfg['control_delete']*86400) : 'Осталось: '.sys::date('min', $ctrl['time']);
  119. $aData = array(
  120. 'time' => sys::today($ctrl['time']),
  121. 'time_end' => $time_end,
  122. 'buttons' => ctrl::buttons($id, $status),
  123. 'status' => ctrl::status($status)
  124. );
  125. return $aData;
  126. }
  127. public static function ram_load($data)
  128. {
  129. $aData = explode(' ', $data);
  130. return ceil(($aData[0]-($aData[1]+$aData[2]+$aData[3]))*100/$aData[0]);
  131. }
  132. public static function cpu_load($data)
  133. {
  134. $aData = explode(' ', $data);
  135. $load = ceil($aData[0]/$aData[1]);
  136. return $load > 100 ? 100 : $load;
  137. }
  138. public static function nav($server, $id, $sid, $active)
  139. {
  140. global $cfg, $html, $sql, $mcache, $start_point;
  141. $aUnit = array('index', 'console', 'settings', 'plugins', 'filetp', 'copy', 'boost');
  142. $html->get('gmenu', 'sections/control/servers/'.$server['game']);
  143. $html->set('id', $id);
  144. $html->set('server', $sid);
  145. $html->set('home', $cfg['http']);
  146. foreach($aUnit as $unit)
  147. if($unit == $active) $html->unit($unit, 1); else $html->unit($unit);
  148. $html->pack('main');
  149. $html->get('vmenu', 'sections/control/servers/'.$server['game']);
  150. $html->set('id', $id);
  151. $html->set('server', $sid);
  152. $html->set('home', $cfg['http']);
  153. foreach($aUnit as $unit)
  154. if($unit == $active) $html->unit($unit, 1); else $html->unit($unit);
  155. $html->pack('vmenu');
  156. return NULL;
  157. }
  158. public static function route($server, $inc, $go)
  159. {
  160. global $device, $start_point;
  161. if(in_array($server['status'], array('install', 'reinstall', 'update', 'recovery')))
  162. {
  163. if($go)
  164. sys::out('Раздел недоступен');
  165. return SEC.'control/servers/noaccess.php';
  166. }
  167. if(!file_exists(SEC.'control/servers/'.$server['game'].'/'.$inc.'.php'))
  168. return SEC.'control/servers/'.$server['game'].'/index.php';
  169. return SEC.'control/servers/'.$server['game'].'/'.$inc.'.php';
  170. }
  171. public static function cpulist($unit, $core, $count = false)
  172. {
  173. global $device, $start_point;
  174. include(LIB.'ssh.php');
  175. if(!$ssh->auth($unit['passwd'], $unit['address']))
  176. {
  177. if($count)
  178. return 1;
  179. $out = $core ? '<option value="0">Автоматическое определение</option><option value="1">1 ядро/поток</option>' : '<option value="'.$core.'">'.$core.' ядро/поток</option><option value="0">Автоматическое определение</option>';
  180. sys::outjs(array('core_fix' => $core));
  181. }
  182. $n = sys::int($ssh->get('cat /proc/cpuinfo | grep "cpu MHz" | wc -l'));
  183. if($count)
  184. return $n;
  185. $list = '<option value="0">Автоматическое определение</option>';
  186. for($i = 1; $i <= $n; $i+=1)
  187. $list .= '<option value="'.$i.'">'.$i.' ядро/поток</option>';
  188. sys::outjs(array('core_fix' => str_replace($core.'"', $core.'" selected="select"', $list)));
  189. }
  190. public static function iptables($id, $action, $source, $dest, $unit, $snw = false, $ssh = false)
  191. {
  192. global $cfg, $sql, $start_point;
  193. if(!$ssh)
  194. {
  195. $sql->query('SELECT `address`, `passwd` FROM `control` WHERE `id`="'.$unit.'" LIMIT 1');
  196. $unit = $sql->get();
  197. include(LIB.'ssh.php');
  198. if(!$ssh->auth($unit['passwd'], $unit['address']))
  199. return array('e' => sys::text('all', 'ssh'));
  200. }
  201. switch($action)
  202. {
  203. case 'block':
  204. if(sys::valid($source, 'ip'))
  205. return array('e' => sys::text('servers', 'firewall'));
  206. // Если подсеть
  207. if($snw)
  208. {
  209. $source = sys::whois($source);
  210. if($source == 'не определена')
  211. return array('e' => 'Не удалось определить подсеть для указанного адреса.');
  212. }
  213. $sql->query('SELECT `id` FROM `control_firewall` WHERE `sip`="'.$source.'" AND `server`="'.$id.'" LIMIT 1');
  214. // Если такое правило уже добавлено или указан адрес сайта (ПУ)
  215. if($sql->num() || ($source == $cfg['ip'] || $source == $cfg['subnet']))
  216. return array('s' => 'ok');
  217. $sql->query('INSERT INTO `control_firewall` set `sip`="'.$source.'", `dest`="'.$dest[0].':'.$dest[1].'", `server`="'.$id.'", `time`="'.$start_point.'"');
  218. $line = $sql->id();
  219. $rule = 'iptables -I INPUT -s '.$source.' -p udp -d '.$dest[0].' --dport '.$dest[1].' -j DROP;';
  220. $ssh->set($rule.' echo -e "#'.$line.';\n'.$rule.'" >> /root/'.$cfg['iptables']);
  221. return array('s' => 'ok');
  222. case 'unblock':
  223. if(!is_numeric($source) AND sys::valid($source, 'ip'))
  224. return array('e' => sys::text('servers', 'firewall'));
  225. if(is_numeric($source))
  226. {
  227. $sql->query('SELECT `id`, `sip` FROM `control_firewall` WHERE `id`="'.$source.'" AND `server`="'.$id.'" LIMIT 1');
  228. // Если такое правило отсутствует
  229. if(!$sql->num())
  230. return array('s' => 'ok');
  231. }else{
  232. $sql->query('SELECT `id`, `sip` FROM `control_firewall` WHERE `sip`="'.$source.'" AND `server`="'.$id.'" LIMIT 1');
  233. // Если одиночный адрес не найден, проверить на блокировку подсети
  234. if(!$sql->num())
  235. {
  236. $source = sys::whois($source);
  237. $sql->query('SELECT `id` FROM `control_firewall` WHERE `sip`="'.$source.'" AND `server`="'.$id.'" LIMIT 1');
  238. if($sql->num())
  239. {
  240. $firewall = $sql->get();
  241. return array('i' => 'Указанный адрес входит в заблокированную подсеть, разблокировать подсеть?', 'id' => $firewall['id']);
  242. }
  243. return array('s' => 'ok');
  244. }
  245. }
  246. $firewall = $sql->get();
  247. $ssh->set('iptables -D INPUT -s '.$firewall['sip'].' -p udp -d '.$dest[0].' --dport '.$dest[1].' -j DROP;'
  248. .'sed "`nl '.$cfg['iptables'].' | grep \"#'.$firewall['id'].'\" | awk \'{print $1","$1+1}\'`d" '.$cfg['iptables'].' > '.$cfg['iptables'].'_temp; cat '.$cfg['iptables'].'_temp > '.$cfg['iptables'].'; rm '.$cfg['iptables'].'_temp');
  249. $sql->query('DELETE FROM `control_firewall` WHERE `id`="'.$firewall['id'].'" LIMIT 1');
  250. return array('s' => 'ok');
  251. case 'remove':
  252. $sql->query('SELECT `id`, `sip`, `dest` FROM `control_firewall` WHERE `server`="'.$id.'"');
  253. $aRule = array();
  254. while($firewall = $sql->get())
  255. {
  256. list($ip, $port) = explode(':', $firewall['dest']);
  257. $aRule[$firewall['id']] = 'iptables -D INPUT -s '.$firewall['sip'].' -p udp -d '.$ip.' --dport '.$port.' -j DROP;';
  258. }
  259. $nRule = count($aRule);
  260. if(!$nRule)
  261. return NULL;
  262. $cmd = '';
  263. foreach($aRule as $line => $rule)
  264. $cmd .= $rule.'sed "`nl '.$cfg['iptables'].' | grep "#'.$line.'" | awk \'{print $1","$1+1}\'`d" '.$cfg['iptables'].' > '.$cfg['iptables'].'_temp; cat '.$cfg['iptables'].'_temp > '.$cfg['iptables'].'; rm '.$cfg['iptables'].'_temp';
  265. $ssh->set($cmd);
  266. $sql->query('DELETE FROM `control_firewall` WHERE `server`="'.$id.'" LIMIT '.$nRule);
  267. return array('s' => 'ok');
  268. }
  269. }
  270. public static function crontab($id, $cid, $data = array())
  271. {
  272. global $cfg;
  273. if($data['allhour'])
  274. $time = '0 * * * ';
  275. else{
  276. $hour = array(
  277. '00', '01', '02',
  278. '03', '04', '05',
  279. '06', '07', '08',
  280. '09', '10', '11',
  281. '12', '13', '14',
  282. '15', '16', '17',
  283. '18', '19', '20',
  284. '21', '22', '23'
  285. );
  286. $minute = array(
  287. '00', '05', '10',
  288. '15', '20', '25',
  289. '30', '35', '40',
  290. '45', '50', '55'
  291. );
  292. if(!in_array($data['hour'], $hour))
  293. $data['hour'] = '00';
  294. if(!in_array($data['minute'], $minute))
  295. $data['minute'] = '00';
  296. $time = $data['minute'].' '.$data['hour'].' * * ';
  297. }
  298. $week = array();
  299. $week[1] = isset($data['week']['\'1\'']) ? 1 : 0;
  300. $week[2] = isset($data['week']['\'2\'']) ? 2 : 0;
  301. $week[3] = isset($data['week']['\'3\'']) ? 3 : 0;
  302. $week[4] = isset($data['week']['\'4\'']) ? 4 : 0;
  303. $week[5] = isset($data['week']['\'5\'']) ? 5 : 0;
  304. $week[6] = isset($data['week']['\'6\'']) ? 6 : 0;
  305. $week[7] = isset($data['week']['\'7\'']) ? 7 : 0;
  306. $check = 0;
  307. foreach($week as $index => $val)
  308. $check+= $val;
  309. if($check == 28 || !$check)
  310. $week = '*';
  311. else{
  312. $weeks = $week[1].','.$week[2].','.$week[3].','.$week[4].','.$week[5].','.$week[6].','.$week[7];
  313. $weeks = str_replace(array(',0', '0'), '', $weeks);
  314. $week = $weeks{0} == ',' ? substr($weeks, 1) : $weeks;
  315. }
  316. $cron_task = $time.$week.' screen -dmS s'.$id.' bash -c \'cd /var/enginegp && php cron.php '.$cfg['cron_key'].' control_server_cron '.$id.' '.$cid.'\'';
  317. return $cron_task;
  318. }
  319. }
  320. ?>