Upgrade to Pro — share decks privately, control downloads, hide ads and more …

makebeta

 makebeta

Evgeny E. Neverov

March 17, 2023
Tweet

More Decks by Evgeny E. Neverov

Other Decks in Programming

Transcript

  1. Что это такое? Модуль makebeta автоматически создает и настраивает тестовую

    копию сайта. Для того, чтобы создать тестовую копию нужно только • создать тест в плеске • запустить makebeta и передать ей доступы
  2. Что именно делает скрипт? • Парсит nginx.conf файлы, находит все

    домены и предлагает пользователю выбрать сайт для копирования • Парсит .settings.php, чтобы получить доступы к боевой бд • Заливает и исполняет на бою тестовый скрипт, чтобы узнать версию php для WakeupBeta • Параллельно выполняет копирование файлов и таблиц • Запускает WakeupBeta и автоматически передает ей все необходимые параметры
  3. Как запустить? • Подключаемся к тесту по ssh • Переходим

    в директорию корня сайта • Запускаем Параметры: • Доступы ssh к бою • Домен • Доступы к БД на тесте • Параметры копирования файлов и таблиц • Может спросить версию php боевого сайта > cd /var/www/vhosts/example.t-dir.dev/httpdocs/ > /opt/plesk/php/8.0/bin/php -f /var/www/vhosts/makebeta.t-dir.dev/core/cli.php host: 192.168.88.113 ssh port [22]: ssh login: root ssh password: 123456 1. example.org: /home/bitrix/ext_www 2. site.org: /home/bitrix/www domain number: 2 exclude upload folder [Y]: rsync: ignore times [N]: local db name: makebeta local db login: makebeta local db password: 123456 ignore archive tables [Y]: remote php version [7.4]:
  4. Использованные пакеты • wp-cli/php-cli-tools Полезные функции для работы с консолью

    $state->sshHost = prompt('host'); $state->sshPort = prompt('ssh port', 22); • nikic/php-parser Парсер php кода • symfony/process Выполнение команд ОС. Возможность выполнять команды асинхронно, получать вывод в реальном времени и передавать данные в поток ввода. • league/flysystem-sftp-v3 Удобная работа с файловой системой через SFTP use League\Flysystem; $connection = new Flysystem\PhpseclibV3\SftpConnectionProvider( $host, $login, $password // для авторизации по паролю нужен sshpass ); $adapter = new Flysystem\PhpseclibV3\SftpAdapter( $connection, '/home/bitrix/www/' // root dir ); $filesystem = new Flysystem\Filesystem($adapter); // чтение содержимого файла $fileContent = $filesystem->read('bitrix/.settings'); // список файлов в директории $directoryFiles = $filesystem->listContents('/');
  5. Как копируется БД? # подключаемся по ssh, запускаем mysqldump #

    с помощью утилиты sshpass передаем пароль, без нее авторизация происходит по ключам # Команду для ssh передаем в кавычках. Поэтому все кавычки внутри экранируем sshpass -p "1234" ssh -q -p 22 [email protected] "mysqldump --no-tablespaces --lock-tables=false --skip-extended-insert --max_allowed_packet=128M -ubitrix0 --password=\"KIVp-8M27D{pICR2G?j)\" sitemanager > /root/mysqldump_63bd24219c0151.sql" # архивируем дамп sshpass -p "1234" ssh -q -p 22 [email protected] "gzip /root/mysqldump_63bd24219c0151.sql" # С помощью rsync скачиваем дамп # --remove-source-files - удаляем дамп на бою после скачивания sshpass -p "1234" rsync -v -e --remove-source-files "[email protected]:/root/mysqldump_63bd24219c0151.sql" . # разархивируем дамп gzip -d mysqldump_63bd24219c0151.sql.gz # импортируем таблицы mysql -umakebeta -pHqxFHwykdvn makebeta < mysqldump_63bd24219c0151.65775137.sql # удаляем дамп rm mysqldump_63bd24219c0151.65775137.sql
  6. Symfony Process Чтобы выполнить вышеперечисленные команды, собираем их в одну

    строку и создаем процесс симфони. use Symfony\Component\Process\Process as SymfonyProcess; $command = implode(PHP_EOL, $commandsList); $process = SymfonyProcess::fromShellCommandline( $command, $_SERVER['DOCUMENT_ROOT'] // рабочая директория ); $process->start(); // запускаем процесс // копируем файлы... $process->wait(); // ждем завершения выполнения
  7. Как копируются файлы? # запускаем rsync # с помощью утилиты

    sshpass передаем пароль sshpass -p "techdirector" rsync -zavpPL --chmod=D755,F644 -e --exclude "/bitrix/stack_cache" --exclude "/bitrix/cache" --exclude "/bitrix/managed_cache" --exclude "/bitrix/backup" --exclude "/bitrix/html_pages" --exclude "/node_modules" --exclude ".git" --exclude "*.tar.gz*" --exclude "*.rar*" --exclude "*.zip*" --exclude "*.tar*" --exclude "*.xml*" --exclude "*.txt*" --exclude "*.csv*" --exclude "/upload" "[email protected]:/home/bitrix/www/" "/var/www/vhosts/makebeta.t-dir.dev/httpdocs"
  8. Параллельное выполнение команд // сначала запускаем процесс копирования БД и

    оставляем его работать в фоне $processDb->start(); // запускаем процесс копирования файлов $processFiles->start(); // используя процесс как итератор, можно следить за выполнением команды в реальном времени и получать ее вывод // когда процесс завершает работу, цикл заканчивается foreach ($processFiles as $type => $buffer) { if ($type === SymfonyProcess::OUT) { echo $buffer . PHP_EOL; // выводим прогресс rsync } else { echo "\nRsync ERROR: $buffer\n"; } } // возвращаемся к фоновому процессу копирования БД и ждем его завершения $processDb->wait(); // выводим ошибки копирования бд echo $processDb->getErrorOutput();
  9. Запуск WakeupBeta • WakeupBeta во время выполнения запрашивает у пользователя

    данные для подключения к БД # версия php определяется модулем автоматически /opt/plesk/php/7.4/bin/php -f /var/www/vhosts/tdstore.t-dir.dev/wakeupbeta.t-dir.com/src/cli-run.php change database [N]: Y name: makebeta login: makebeta password: password • Процесс симфони позволяет нам писать в поток ввода. Таким образом, мы можем передать данные в WakeupBeta автоматически
  10. Запись в поток ввода use Symfony\Component\Process\InputStream; $process = SymfonyProcess::fromShellCommandline($command); $input

    = new InputStream(); $process->setInput($input); $process->start(); foreach ($process as $type => $buffer) { if ($type === SymfonyProcess::OUT) { if (str_contains($buffer, 'change database [N]:')) { $input->write('Y' . PHP_EOL); } else if (str_contains($buffer, 'name:')) { $input->write($state->dbLocalName . PHP_EOL); } else if (str_contains($buffer, 'login:')) { $input->write($state->dbLocalLogin . PHP_EOL); } else if (str_contains($buffer, 'password:')) { $input->write($state->dbLocalPassword . PHP_EOL); } } else // SymfonyProcess::ERR { echo "\nRead from stderr: " . $buffer . PHP_EOL; } }