Як я умовив 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="так"/>
</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, file not!!!';
}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, потім викликати його для перевірки вашдомен.ги/имяфайла.рһр:

<?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 і Серверного ПЗ. Думаю, з часом допрацюю його, якщо буде сенс.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.