2013-06-09 18:42:50 +02:00
|
|
|
<?php
|
2015-04-09 08:51:45 +02:00
|
|
|
|
2013-06-09 18:42:50 +02:00
|
|
|
/**
|
2014-05-12 18:26:17 +02:00
|
|
|
* PHPCI - Continuous Integration for PHP
|
|
|
|
*
|
|
|
|
* @copyright Copyright 2014, Block 8 Limited.
|
|
|
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
|
|
|
* @link https://www.phptesting.org/
|
|
|
|
*/
|
2013-06-09 18:42:50 +02:00
|
|
|
|
|
|
|
namespace PHPCI\Command;
|
|
|
|
|
2013-11-02 16:52:55 +01:00
|
|
|
use Monolog\Logger;
|
2015-04-09 08:51:45 +02:00
|
|
|
use PHPCI\ProcessControl\Factory;
|
|
|
|
use PHPCI\ProcessControl\ProcessControlInterface;
|
2013-06-09 18:42:50 +02:00
|
|
|
use Symfony\Component\Console\Command\Command;
|
|
|
|
use Symfony\Component\Console\Input\InputArgument;
|
|
|
|
use Symfony\Component\Console\Input\InputInterface;
|
2015-04-09 08:51:45 +02:00
|
|
|
use Symfony\Component\Console\Input\InputOption;
|
2013-06-09 18:42:50 +02:00
|
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
|
|
|
|
|
/**
|
2015-04-09 08:51:45 +02:00
|
|
|
* Daemon that loops and call the run-command.
|
|
|
|
* @author Gabriel Baker <gabriel.baker@autonomicpilot.co.uk>
|
|
|
|
* @package PHPCI
|
|
|
|
* @subpackage Console
|
|
|
|
*/
|
2013-06-09 18:42:50 +02:00
|
|
|
class DaemonCommand extends Command
|
|
|
|
{
|
2015-04-09 08:51:45 +02:00
|
|
|
|
2013-11-02 16:52:55 +01:00
|
|
|
/**
|
2015-04-09 08:51:45 +02:00
|
|
|
* @var Logger
|
2013-11-02 16:52:55 +01:00
|
|
|
*/
|
|
|
|
protected $logger;
|
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $pidFilePath;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $logFilePath;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var ProcessControlInterface
|
|
|
|
*/
|
|
|
|
protected $processControl;
|
|
|
|
|
|
|
|
public function __construct(Logger $logger, ProcessControlInterface $processControl = null, $name = null)
|
2013-11-02 16:52:55 +01:00
|
|
|
{
|
|
|
|
parent::__construct($name);
|
|
|
|
$this->logger = $logger;
|
2015-04-09 08:51:45 +02:00
|
|
|
$this->processControl = $processControl ?: Factory::getInstance();
|
2013-11-02 16:52:55 +01:00
|
|
|
}
|
|
|
|
|
2013-06-09 18:42:50 +02:00
|
|
|
protected function configure()
|
|
|
|
{
|
|
|
|
$this
|
2013-06-09 21:11:22 +02:00
|
|
|
->setName('phpci:daemon')
|
|
|
|
->setDescription('Initiates the daemon to run commands.')
|
|
|
|
->addArgument(
|
2015-04-09 08:51:45 +02:00
|
|
|
'state', InputArgument::REQUIRED, 'start|stop|status'
|
|
|
|
)
|
|
|
|
->addOption(
|
|
|
|
'pid-file', 'p', InputOption::VALUE_REQUIRED,
|
|
|
|
'Path of the PID file',
|
|
|
|
implode(DIRECTORY_SEPARATOR,
|
|
|
|
array(PHPCI_DIR, 'daemon', 'daemon.pid'))
|
|
|
|
)
|
|
|
|
->addOption(
|
|
|
|
'log-file', 'l', InputOption::VALUE_REQUIRED,
|
|
|
|
'Path of the log file',
|
|
|
|
implode(DIRECTORY_SEPARATOR,
|
|
|
|
array(PHPCI_DIR, 'daemon', 'daemon.log'))
|
|
|
|
);
|
2013-06-09 18:42:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-04-09 08:51:45 +02:00
|
|
|
* Loops through running.
|
|
|
|
*/
|
2013-06-09 18:42:50 +02:00
|
|
|
protected function execute(InputInterface $input, OutputInterface $output)
|
|
|
|
{
|
2015-04-09 08:51:45 +02:00
|
|
|
$this->pidFilePath = $input->getOption('pid-file');
|
|
|
|
$this->logFilePath = $input->getOption('log-file');
|
|
|
|
|
2013-06-09 21:11:22 +02:00
|
|
|
$state = $input->getArgument('state');
|
2013-06-09 18:42:50 +02:00
|
|
|
|
2013-06-09 21:11:22 +02:00
|
|
|
switch ($state) {
|
|
|
|
case 'start':
|
|
|
|
$this->startDaemon();
|
|
|
|
break;
|
|
|
|
case 'stop':
|
|
|
|
$this->stopDaemon();
|
|
|
|
break;
|
|
|
|
case 'status':
|
2015-04-09 08:51:45 +02:00
|
|
|
$this->statusDaemon($output);
|
2013-06-09 21:11:22 +02:00
|
|
|
break;
|
|
|
|
default:
|
2015-04-09 08:51:45 +02:00
|
|
|
$this->output->writeln("<error>Not a valid choice, please use start, stop or status</error>");
|
2013-06-09 21:11:22 +02:00
|
|
|
break;
|
2013-06-09 18:42:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-09 21:11:22 +02:00
|
|
|
protected function startDaemon()
|
|
|
|
{
|
2015-04-09 08:51:45 +02:00
|
|
|
$pid = $this->getRunningPid();
|
|
|
|
if ($pid) {
|
|
|
|
$this->logger->notice("Daemon already started", array('pid' => $pid));
|
2013-06-09 21:11:22 +02:00
|
|
|
return "alreadystarted";
|
|
|
|
}
|
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
$this->logger->info("Trying to start the daemon");
|
|
|
|
|
2013-06-09 21:11:22 +02:00
|
|
|
$cmd = "nohup %s/daemonise phpci:daemonise > %s 2>&1 &";
|
2015-04-09 08:51:45 +02:00
|
|
|
$command = sprintf($cmd, PHPCI_DIR, $this->logFilePath);
|
|
|
|
$output = $exitCode = null;
|
|
|
|
exec($command, $output, $exitCode);
|
2013-06-09 21:11:22 +02:00
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
if ($exitCode !== 0) {
|
|
|
|
$this->logger->error(sprintf("daemonise exited with status %d", $exitCode));
|
|
|
|
return "notstarted";
|
|
|
|
}
|
2013-06-09 21:11:22 +02:00
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
for ($i = 0; !($pid = $this->getRunningPid()) && $i < 5; $i++) {
|
|
|
|
sleep(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$pid) {
|
|
|
|
$this->logger->error("Could not start the daemon");
|
2013-06-09 21:11:22 +02:00
|
|
|
return "notstarted";
|
|
|
|
}
|
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
$this->logger->notice("Daemon started", array('pid' => $pid));
|
|
|
|
return "started";
|
2013-06-09 21:11:22 +02:00
|
|
|
}
|
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
protected function stopDaemon()
|
2013-06-09 21:11:22 +02:00
|
|
|
{
|
2015-04-09 08:51:45 +02:00
|
|
|
$pid = $this->getRunningPid();
|
|
|
|
if (!$pid) {
|
|
|
|
$this->logger->notice("Cannot stop the daemon as it is not started");
|
|
|
|
return "notstarted";
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->logger->info("Trying to terminate the daemon", array('pid' => $pid));
|
|
|
|
$this->processControl->kill($pid);
|
2013-06-09 21:11:22 +02:00
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) {
|
|
|
|
sleep(1);
|
2013-06-09 21:11:22 +02:00
|
|
|
}
|
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
if ($pid) {
|
|
|
|
$this->logger->warning("The daemon is resiting, trying to kill it", array('pid' => $pid));
|
|
|
|
$this->processControl->kill($pid, true);
|
|
|
|
|
|
|
|
for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) {
|
|
|
|
sleep(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$pid) {
|
|
|
|
$this->logger->notice("Daemon stopped");
|
|
|
|
return "stopped";
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->logger->error("Could not stop the daemon");
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function statusDaemon(OutputInterface $output)
|
|
|
|
{
|
|
|
|
$pid = $this->getRunningPid();
|
|
|
|
if ($pid) {
|
|
|
|
$output->writeln(sprintf('The daemon is running, PID: %d', $pid));
|
2013-06-09 21:11:22 +02:00
|
|
|
return "running";
|
|
|
|
}
|
|
|
|
|
2015-04-09 08:51:45 +02:00
|
|
|
$output->writeln('The daemon is not running');
|
2013-06-09 21:11:22 +02:00
|
|
|
return "notrunning";
|
|
|
|
}
|
2015-04-09 08:51:45 +02:00
|
|
|
|
|
|
|
/** Check if there is a running daemon
|
|
|
|
*
|
|
|
|
* @return int|null
|
|
|
|
*/
|
|
|
|
protected function getRunningPid()
|
|
|
|
{
|
|
|
|
if (!file_exists($this->pidFilePath)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$pid = intval(trim(file_get_contents($this->pidFilePath)));
|
|
|
|
|
|
|
|
if($this->processControl->isRunning($pid, true)) {
|
|
|
|
return $pid;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Not found, remove the stale PID file
|
|
|
|
unlink($this->pidFilePath);
|
|
|
|
}
|
2013-06-09 18:42:50 +02:00
|
|
|
}
|