diff options
author | Alex <[email protected]> | 2018-12-21 20:36:50 -0800 |
---|---|---|
committer | Alex <[email protected]> | 2018-12-21 20:45:02 -0800 |
commit | 83455c53e3ba07336b85613457aa7131ea98c613 (patch) | |
tree | 6461ea720737af6e8a55470470fcfe9dd00c6b0f | |
parent | d5e5be00aca87ea39ece9c04efe7dc354b1dc3f6 (diff) |
RoadRunner CLI for binary update and config initialization
-rw-r--r-- | .rr.yaml | 67 | ||||
-rw-r--r-- | composer.json | 14 | ||||
-rwxr-xr-x | src/bin/roadrunner | 176 |
3 files changed, 255 insertions, 2 deletions
diff --git a/.rr.yaml b/.rr.yaml new file mode 100644 index 00000000..af4be374 --- /dev/null +++ b/.rr.yaml @@ -0,0 +1,67 @@ +# defines environment variables for all underlying php processes +env: + key: value + +# rpc bus allows php application and external clients to talk to rr services. +rpc: + # enable rpc server (enabled by default) + enable: true + + # rpc connection DSN. Supported TCP and Unix sockets. + listen: tcp://127.0.0.1:6001 + +# http service configuration. +http: + # http host to listen. + address: 0.0.0.0:8080 + + ssl: + # custom https port (default 443) + port: 443 + + # force redirect to https connection + redirect: true + + # ssl cert + cert: server.crt + + # ssl private key + key: server.key + + # max POST request size, including file uploads in MB. + maxRequest: 200 + + # file upload configuration. + uploads: + # list of file extensions which are forbidden for uploading. + forbid: [".php", ".exe", ".bat"] + + # http worker pool configuration. + workers: + # php worker command. + command: "php psr-worker.php pipes" + + # connection method (pipes, tcp://:9000, unix://socket.unix). default "pipes" + relay: "pipes" + + # worker pool configuration. + pool: + # number of workers to be serving. + numWorkers: 4 + + # maximum jobs per worker, 0 - unlimited. + maxJobs: 0 + + # for how long worker is allowed to be bootstrapped. + allocateTimeout: 60 + + # amount of time given to worker to gracefully destruct itself. + destroyTimeout: 60 + +# static file serving. remove this section to disable static file serving. +static: + # root directory for static file (http would not serve .php and .htaccess files). + dir: "public" + + # list of extensions for forbid for serving. + forbid: [".php", ".htaccess"] diff --git a/composer.json b/composer.json index 591a1ae8..8ff6f920 100644 --- a/composer.json +++ b/composer.json @@ -7,18 +7,28 @@ { "name": "Anton Titov / Wolfy-J", "email": "[email protected]" + }, + { + "name": "Alex Bond ", + "email": "[email protected]" } ], "require": { "php": "^7.0", + "ext-curl": "*", + "ext-zip": "*", "spiral/goridge": "^2.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.0", - "http-interop/http-factory-diactoros": "^1.0" + "http-interop/http-factory-diactoros": "^1.0", + "symfony/console": "^2.5.0 || ^3.0.0 || ^4.0.0" }, "autoload": { "psr-4": { "Spiral\\RoadRunner\\": "src/" } - } + }, + "bin": [ + "src/bin/roadrunner" + ] } diff --git a/src/bin/roadrunner b/src/bin/roadrunner new file mode 100755 index 00000000..39073149 --- /dev/null +++ b/src/bin/roadrunner @@ -0,0 +1,176 @@ +#!/usr/bin/env php +<?php +/* + * RoadRunner + * High-performance PHP process supervisor and load balancer written in Go + * + * This file responsive for cli commands + */ + +foreach ([__DIR__ . '/../../../../autoload.php', __DIR__ . '/../../vendor/autoload.php', __DIR__ . '/vendor/autoload.php'] as $file) { + if (file_exists($file)) { + define('RR_COMPOSER_INSTALL', $file); + + break; + } +} + +unset($file); + +if (!defined('RR_COMPOSER_INSTALL')) { + fwrite( + STDERR, + 'You need to set up the project dependencies using Composer:' . PHP_EOL . PHP_EOL . + ' composer install' . PHP_EOL . PHP_EOL . + 'You can learn all about Composer on https://getcomposer.org/.' . PHP_EOL + ); + + die(1); +} + +require RR_COMPOSER_INSTALL; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; + +class RoadRunnerCLIHelper +{ + public static function getVersion() + { + $file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'build.sh'; + $fh = fopen($file, 'r') or die(1); + while (!feof($fh)) { + $line = fgets($fh, 4096); + $matches = []; + if (preg_match("/^RR_VERSION=(.*)/", $line, $matches)) { + return $matches[1]; + } + } + fclose($fh); + throw new Exception("Can't find version of RoadRunner"); + } + + public static function getOsType() + { + switch (PHP_OS) { + case 'Darwin': + return 'darwin'; + case 'Linux': + return 'linux'; + case 'FreeBSD': + return 'freebsd'; + case 'WIN32': + case 'WINNT': + case 'Windows': + return 'windows'; + default: + return 'linux'; + } + } + + public static function getBinaryDownloadUrl() + { + return 'https://github.com/spiral/roadrunner/releases/download/v' . static::getVersion() . '/roadrunner-' . static::getVersion() . '-' . static::getOsType() . '-amd64.zip'; + } +} + + +(new Application('RoadRunner', RoadRunnerCLIHelper::getVersion())) + ->register('update-binaries') + ->setDescription("Install or update RoadRunner binaries in specified folder (current folder by default)") + ->addOption('location', 'l', InputArgument::OPTIONAL, 'destination folder', '.') + ->setCode(function (InputInterface $input, OutputInterface $output) { + $output->writeln('<info>Updating binary file of RoadRunner</info>'); + + $finalFile = $input->getOption('location') . DIRECTORY_SEPARATOR . 'rr'; + + if (is_file($finalFile)) { + $output->writeln('<error>RoadRunner binary file already exists!</error>'); + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('Do you want overwrite it? [Y/n]'); + + if (!$helper->ask($input, $output, $question)) { + return; + } + } + + $output->writeln('<info>Downloading RoadRunner archive for ' . RoadRunnerCLIHelper::getOsType() . '</info>'); + + $progressBar = new ProgressBar($output); + $progressBar->setFormat('verbose'); + $progressBar->start(); + + $zipFileName = tempnam('.', "rr_zip"); + $zipFile = fopen($zipFileName, "w+"); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, RoadRunnerCLIHelper::getBinaryDownloadUrl()); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_FILE, $zipFile); + curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function ($resource, $download_size, $downloaded, $upload_size, $uploaded) use ($progressBar) { + if ($download_size == 0) { + return; + } + $progressBar->setFormat('[%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% ' . intval($download_size / 1024) . 'KB'); + $progressBar->setMaxSteps($download_size); + $progressBar->setProgress($downloaded); + }); + curl_setopt($ch, CURLOPT_NOPROGRESS, false); // needed to make progress function work + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_exec($ch); + curl_close($ch); + fclose($zipFile); + + $progressBar->finish(); + $output->writeln(""); + + $output->writeln('<info>Unpacking ' . basename(RoadRunnerCLIHelper::getBinaryDownloadUrl()) . '</info>'); + + $za = new ZipArchive(); + $za->open($zipFileName); + $fp = $za->getStream('roadrunner-' . RoadRunnerCLIHelper::getVersion() . '-' . RoadRunnerCLIHelper::getOsType() . '-amd64/rr'); + $ofp = fopen($finalFile, 'w'); + + if (!$fp) { + throw new Exception('Unable to extract the file.'); + } + + while (!feof($fp)) { + fwrite($ofp, fread($fp, 8192)); + } + + fclose($fp); + fclose($ofp); + $za->extractTo('.', []); + $za->close(); + unlink($zipFileName); + + chmod($finalFile, 0755); + $output->writeln('<info>Binary file updated!</info>'); + }) + ->getApplication() + ->register("init-config") + ->setDescription("Inits default .rr.yaml config in specified folder (current folder by default)") + ->addOption('location', 'l', InputArgument::OPTIONAL, 'destination folder', '.') + ->setCode(function (InputInterface $input, OutputInterface $output) { + if (is_file($input->getOption('location') . DIRECTORY_SEPARATOR . '.rr.yaml')) { + $output->writeln('<error>Config file already exists!</error>'); + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('Do you want overwrite it? [Y/n]'); + + if (!$helper->ask($input, $output, $question)) { + return; + } + } + copy(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '.rr.yaml', $input->getOption('location') . DIRECTORY_SEPARATOR . '.rr.yaml'); + $output->writeln('<info>Config file created!</info>'); + }) + ->getApplication() + ->run(); + + |