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

makebeta

 makebeta

Avatar for Evgeny E. Neverov

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; } }