Как я уговорил BILL и ISPmanager Lite 5 менять оперативную память на тарифе виртуального хостинга

от автора

До недавних пор я создавал сайты и плагины на WordPress, арендуя виртуальные хостинги у провайдеров. Для себя еще давно выделил панель ISP за удобность и практичность. Так случилось, что все время работал на Windows, следовательно, Linux для меня — темный лес с диким животными. Сайты со временем «росли» и становились более требовательны, как минимум к дисковому пространству и иногда к оперативной памяти.

Пару месяцев назад по некоторым соображениям решил арендовать виртуальный сервер на Linux и самостоятельно установить туда ISP и BILL для создания и управления услугами.

Поколдовав несколько часов с документацией и SSH консолью, я запустил свой первый сервер на CentOS. В течение недели выяснил: почему gmail.ru и mail.ru не хотят принимать письма с моего хостинга, как устанавливать ограничения на дисковое пространство, контролировать настройки php для каждого виртуального хостинга и что BILL, имея в своем арсенале возможность покупки дополнительных параметров, включая пункт «Оперативная память», не может на самом деле устанавливать ее.

image

И дело тут не в самом BILL, а именно в ISP Lite — как мне ответила техподдержка от ISP System:

Настройки дополнения «Оперативная память» в биллинге влияет на оперативную память, выделяемую пользователю в ISPmanager. Но у вас используется ISPmanager Lite, где нет ограничений на оперативную память. Ограничение на оперативную память есть только в ISPmanager Business.

Печалька. Поторчав часик-другой в гугле, ничего путного и бесплатного не нашел. В свою очередь, есть только возможность «ручками» менять параметр:

1. Изменяя файл php.ini в папке пользователя:

image

2. Открыть возможность клиенту в ISPmanager самостоятельно менять параметры PHP, что по сути меняет тот же файл php.ini и к тому же на усмотрение клиента:

image

Эти способы «убивали» всю автоматику покупки и обслуживания хостинга. Вообщем так «не айс». Раз у меня теперь свой сервер, то и есть возможность «залезть» в программу, перехватить событие и переписать в файлах заветный пункт memory_limit на необходимое значение.

Альфа-решение

В первую очередь был простой план: найти в БД билла установленные данные для каждого пользователя и переписать их в файлах php.ini простеньким скриптом PHP. А сам PHP запускать через CRON. Но вспоминая ситуации, когда для сайта вложенных 128Мб не хватало, понимал следующее: данные случаи происходили случайно и требовали чуть ли не мгновенного решения. Заставить CRON каждые 5 минут запускать этот скрипт — слишком безграмотное решение задачи с холостой работой 99% времени.

Бета-решение

Стал искать способ повесить скрипт на событие смены доп-услуг виртуального хостинга. Мучения только начинались, так как документация на сайте ISPsystem ну совсем не обновляется, о чем на собственном форуме сами же администраторы и модераторы признаются. Погуглив, я нашел способ создать обработчик событий на PHP — что просто волшебно! Ну, во всяком случае, для меня, так как 90% моего рабочего времени уходит именно за написанием скриптов именно на этом языке. Была поставлена цель, чтобы скрипт выполнялся сразу после изменения доп-услуг клиентом в BILL-панеле и значение ограничения записывалось в файл php.ini для текущего виртуального хостинга. Вся работа шла «методом тыка, проб и ошибок». В итоге был найден достаточно рабочий способ менять значения в файле INI в момент обновления доп-услуг виртуального хостинга в BILLmanager. В документации данный эвент называется «vhost.edit», который возникает в момент открытия установок хостинга и сразу после нажатия на кнопку «ОК».

Скрипт работал на событие и справлялся с поставленной задачей, но с чем я не разобрался, так это с папками php-bin, и вложенным в них файлом php.ini. А именно: сначала данные папки находились и прекрасно работали по пути /var/www/{user}/data/php-bin/, но время спустя после моих «издевательств» над ISP и сервером в целом, они сменили местоположение на /var/www/php-bin/{user}/… По гуглу и вышеупомянутой не-до-документации от ISP для этого есть опция DisableSecurePhpBin, но она не влияла никак. В следствие чего я добавил в свой плагинчик поиск файла php.ini в обоих местах, а так же поиск и файла с именем /var/www/{user}/data/php-bin/.php.ini(с точкой вначале).

Что нужно сделать

Долго расписывать не буду, дам просто готовую инструкцию по использованию моего мини-плагинчика для BILLmanager 5:

1. Нужно создать 2 файла с правами root и следующим содержанием:

1.1. /usr/local/mgr5/etc/xml/billmgr_mod_hiweb_vhostram.xml

<?xml version="1.0" encoding="UTF-8"?> <mgrdata>     <handler name="hiweb_vhostram.php" type="cgi">         <event name="vhost.edit" after="yes"/>     </handler> </mgrdata> 

1.2. /usr/local/mgr5/addon/hiweb_vhostram.php

#!/usr/bin/php <?php  	$logFile = '/var/www/log/hiweb_vhostram.log'; 	$logInfo = array();  	//////// 	//Получение данных для подключения к ДБ Билла 	$fileSettings = dirname( dirname( __FILE__ ) ) . '/etc/billmgr.conf.d/db.conf'; 	if( file_exists( $fileSettings ) ){  		$fileSettingsContent = file( $fileSettings, FILE_IGNORE_NEW_LINES ); 		foreach( $fileSettingsContent as $line ){ 			$arr = explode( ' ', trim( $line ) ); 			if( count( $arr ) != 2 ) 				continue; 			list( $lineKey, $lineValue ) = $arr; 			if( $lineKey == 'DBHost' ) 				$DBHost = $lineValue; 			if( $lineKey == 'DBUser' ) 				$DBUser = $lineValue; 			if( $lineKey == 'DBPassword' ) 				$DBPassword = $lineValue; 			if( $lineKey == 'DBName' ) 				$DBName = $lineValue; 		}  		$mysql = new mysqli( $DBHost, $DBUser, $DBPassword, $DBName ); 		//$R = array($_GET, $_POST, $_SERVER);  		if( $mysql ){  			//Поиск индификатора купленной опции RAM 			$priceListResult = $mysql->query( 'SELECT id FROM pricelist WHERE itemtype=(SELECT id FROM itemtype WHERE name="RAM" AND statparam != "")' ); 			$priceList = reset( $priceListResult->fetch_assoc() ); 			 			///Поиск мегабайт памяти 			if(!isset($_SERVER['PARAM_addon_'.$priceList])){ 				$logInfo[] = 'error: no parameter [PARAM_addon_'.$priceList.'] in $_SERVER'; 			}else{ 				$additionMemory = $_SERVER['PARAM_addon_'.$priceList]; 				///Поиск пользователя 				$userLogin = $_SERVER['PARAM_username']; 				if( trim( $userLogin ) == '' ){ 					//do nothing 				} 				else{ 					$logInfo[] = 'select user ['.$userLogin.']'; 					/// 					//$userResult = $mysql->query( 'SELECT * FROM itemparam WHERE intname="username" AND item="' . $userId . '"' ); 					//$userData = $userResult->fetch_assoc(); 					//$userLogin = $userData['value']; 					/// 					///Файлы установок 					$phpIniFiles = array( 						'/var/www/php-bin/' . $userLogin . '/php.ini', '/var/www/' . $userLogin . '/data/php-bin/.php.ini', '/var/www/' . $userLogin . '/data/php-bin/php.ini' 					); 					//Перебор файлов 					foreach( $phpIniFiles as $phpIni ){ 						$B = ''; 						if( !file_exists( $phpIni ) ){ 							$logInfo[] = 'error: file not exists!'; 						}elseif( !is_readable( $phpIni ) ){ 							$logInfo[] = 'error: file not readable!'; 						}elseif( !is_file( $phpIni ) ){ 							$logInfo[] = 'error: this is dir, not file!!!'; 						}else{ 							$content = file_get_contents( $phpIni ); 							preg_match('/^memory_limit = (\d){1,4}[a-zA-Z]?$/im',$content, $match); 							if(count($match) > 0){ 								$line = trim(reset($match)); 								//Получение строки с новыми значениями 								$lineExplode = explode( ' = ', $line ); 								$lineExplode[1] = $additionMemory . 'M'; 								$newLine = implode( ' = ', $lineExplode ); 								//Сравнение на изменение и запись в файл новых значений 								if( trim( $line ) != trim( $newLine ) ){ 									$logInfo[] = file_put_contents($phpIni, str_replace($line,$newLine,$content)) ? $line.' → '.$newLine : 'error: file_put_content'; 								}else{ 									$logInfo[] = 'not change: '.$line.' → '.$newLine; 								} 							}else{ 								$add = 'memory_limit = ' . $additionMemory.'M'; 								$content .= chr( 13 ) . chr( 10 ) . $add . chr( 13 ) . chr( 10 ); 								$logInfo[] = file_put_contents($phpIni, $content) ? '+ '.$add : 'error add: file_put_content'; 							} 						} 					} 				} 			} 		} else { 			$logInfo[] = 'error: mysql not connected!'; 		} 	} 	file_put_contents($logFile, print_r( $logInfo, 1 ) );  	echo '<?xml version="1.0" encoding="UTF-8"?><doc>';  	echo '</doc>';  ?> 

2. Добавить к необходимому тарифу дополнительную опцию «Оперативная память» — у меня она была доступна сразу после установки ISP, затем BILL менеджеров. Осталось ее только включить в тариф, указав пару данных:

image

image

3. Также необходимо перевести WWW-домен → PHP в режим работы «CGI»:

image

4. Попробовать «докупить» оперативной памяти для виртуального хостинга в BILLmanager и нажать «ОК»:

image

5. На всякий случай, файлик PHP для проверки работы смены ограничения оперативной памяти на виртуальном хостинге. Создайте его в корне нужного хоста, рядом с файлом index.php, затем вызвать его для проверки вашдомен.ru/имяфайла.php:

<?php  	function return_bytes( $val ){ 		$val = trim( $val ); 		$last = strtolower( $val[ strlen( $val ) - 1 ] ); 		switch( $last ){ 			// The 'G' modifier is available since PHP 5.1.0 			case 'g': 				$val *= 1024; 			case 'm': 				$val *= 1024; 			case 'k': 				$val *= 1024; 		} 		return $val; 	}  	/** 	 * Возвращает форматированный вид размера файла из байтов 	 * @param $size - INT килобайты 	 * @return string 	 */ 	function size_format( $size ){ 		$size = intval( $size ); 		if( $size < 1024 ){ 			return $size . " bytes"; 		}else if( $size < ( 1024 * 1024 ) ){ 			$size = round( $size / 1024, 1 ); 			return $size . " KB"; 		}else if( $size < ( 1024 * 1024 * 1024 ) ){ 			$size = round( $size / ( 1024 * 1024 ), 1 ); 			return $size . " MB"; 		}else{ 			$size = round( $size / ( 1024 * 1024 * 1024 ), 1 ); 			return $size . " GB"; 		} 	}  	$memory = size_format( return_bytes( ini_get( 'memory_limit' ) ) );  	echo '<phpmem>'; 	echo '<val>' . $memory . '</val>'; 	echo '</phpmem>'; 

Вывод

Актуальная документация позволяет сэкономить уйму времени! )) Данный плагинчик — первый мой опыт написания подобных дополнений и не факт, что будет работать корректно или вообще работать, так как я только разбираюсь в сложносплетениях Linux и Серверного ПО. Думаю, со временем доработаю его, если будет смысл.
ссылка на оригинал статьи https://habrahabr.ru/post/316264/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *