diff --git a/src/app/cli/include-cli_simple_launcher.php b/src/app/cli/include-launcher.php similarity index 83% rename from src/app/cli/include-cli_simple_launcher.php rename to src/app/cli/include-launcher.php index f836351..7a79024 100644 --- a/src/app/cli/include-cli_simple_launcher.php +++ b/src/app/cli/include-launcher.php @@ -1,5 +1,5 @@ __DIR__ . '/..', + "appcode" => \app\config\bootstrap::APPCODE, +]); $app = $argv[1]; if (class_exists($app)) { # la configuration est celle actuellement chargée diff --git a/src/app/cli/template-bg-launcher.php b/src/app/cli/template-bg-launcher.php new file mode 100755 index 0000000..bf4000a --- /dev/null +++ b/src/app/cli/template-bg-launcher.php @@ -0,0 +1,19 @@ +#!/usr/bin/php + __DIR__ . '/..', + "appcode" => \app\config\bootstrap::APPCODE, +]); +BgLauncherApp::run(); diff --git a/src/app/cli/template-cli_simple_wrapper.sh b/src/app/cli/template-wrapper.sh similarity index 92% rename from src/app/cli/template-cli_simple_wrapper.sh rename to src/app/cli/template-wrapper.sh index 5bbee98..9c92553 100755 --- a/src/app/cli/template-cli_simple_wrapper.sh +++ b/src/app/cli/template-wrapper.sh @@ -2,7 +2,7 @@ # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 # s'assurer que le script PHP est lancé avec l'utilisateur www-data -# Faire une copie de ce script dans un répertoire de l'application web +# TODO Faire une copie de ce script dans un répertoire de l'application web # (par défaut c'est le répertoire _cli/) et paramétrer les variables suivantes: # ce sont tous des chemins relatif au répertoire qui contient ce script @@ -10,7 +10,7 @@ PROJPATH=.. # Chemin relatif vers le lanceur PHP -LAUNCHERPATH=_cli_simple_launcher.php +LAUNCHERPATH=_launcher.php # Chemin relatif des scripts PHP wrappés WRAPPEDPATH= diff --git a/src/app/launcher.php b/src/app/launcher.php index c3d69cf..b85530e 100644 --- a/src/app/launcher.php +++ b/src/app/launcher.php @@ -10,6 +10,7 @@ use nur\sery\StateException; use nur\sery\str; use nur\sery\wip\app\app; +#XXX sera obsolète quand cli\bg_launcher sera mis en prod class launcher { /** * transformer une liste d'argument de la forme diff --git a/src/tools/BgLauncherApp.php b/src/tools/BgLauncherApp.php index f3bf360..b689824 100644 --- a/src/tools/BgLauncherApp.php +++ b/src/tools/BgLauncherApp.php @@ -36,7 +36,7 @@ class BgLauncherApp extends Application { static function show_infos(RunFile $runfile, ?int $level=null): void { msg::print($runfile->getDesc(), $level); - msg::print(yaml::with(["data" => $runfile->read()]), -1); + msg::print(yaml::with(["data" => $runfile->read()]), ($level ?? 0) - 1); } function main() { @@ -60,7 +60,7 @@ class BgLauncherApp extends Application { switch ($this->action) { case self::ACTION_START: $appClass::_manage_runfile(count($args), $args, $runfile); - if ($runfile->warnIfLocked()) return; + if ($runfile->warnIfLocked()) self::exit(app2::EC_LOCKED); array_splice($args, 0, 0, [ PHP_BINARY, path::abspath(NULIB_APP_app_launcher), @@ -70,7 +70,7 @@ class BgLauncherApp extends Application { break; case self::ACTION_STOP: bg_launcher::_stop($runfile); - self::show_infos($runfile); + self::show_infos($runfile, -1); break; case self::ACTION_INFOS: self::show_infos($runfile); diff --git a/src/tools/SteamTrainApp.php b/src/tools/SteamTrainApp.php index 20725a1..fe00715 100644 --- a/src/tools/SteamTrainApp.php +++ b/src/tools/SteamTrainApp.php @@ -21,14 +21,14 @@ EOT, ["-c", "--count", "args" => 1, "help" => "spécifier le nombre d'étapes", ], - ["-s", "--install-signal-handler", "value" => true, - "help" => "installer un gestionnaire de signaux", + ["-n", "--no-install-signal-handler", "value" => false, + "help" => "ne pas installer le gestionnaire de signaux", ], ]; protected $count = 100; - protected bool $installSignalHandler = false; + protected bool $installSignalHandler = true; function main() { if ($this->installSignalHandler) app2::install_signal_handler(); diff --git a/wip/app/RunFile.php b/wip/app/RunFile.php index b429d63..81550ba 100644 --- a/wip/app/RunFile.php +++ b/wip/app/RunFile.php @@ -5,6 +5,7 @@ use nur\sery\A; use nur\sery\cl; use nur\sery\file\SharedFile; use nur\sery\os\path; +use nur\sery\os\sh; use nur\sery\output\msg; use nur\sery\php\time\DateTime; use nur\sery\php\time\Elapsed; @@ -70,6 +71,16 @@ class RunFile { ]; } + function reset(bool $delete=false) { + $file = $this->file; + if ($delete) { + $file->close(); + unlink($file->getFile()); + } else { + $file->ftruncate(); + } + } + function read(): array { $data = $this->file->unserialize(); if (!is_array($data)) $data = $this->initData(); @@ -274,6 +285,59 @@ class RunFile { }); } + private static function kill(int $pid, int $signal, ?string &$reason=null): bool { + if (!posix_kill($pid, $signal)) { + switch (posix_get_last_error()) { + case PCNTL_ESRCH: + $reason = "process inexistant"; + break; + case PCNTL_EPERM: + $reason = "process non accessible"; + break; + case PCNTL_EINVAL: + $reason = "signal invalide"; + break; + } + return false; + } + return true; + } + + function wfKill(?string &$reason=null): bool { + $data = $this->read(); + $pid = $this->_getCid($data); + $stopped = false; + $timeout = 10; + $delay = 300000; + while (--$timeout >= 0) { + if (!self::kill($pid, SIGTERM, $reason)) return false; + usleep($delay); + $delay = 1000000; // attendre 1 seconde à partir de la deuxième fois + if (!$this->_isRunning($data)) { + $stopped = true; + break; + } + } + if (!$stopped) { + $timeout = 3; + $delay = 300000; + while (--$timeout >= 0) { + if (!self::kill($pid, SIGKILL, $reason)) return false; + usleep($delay); + $delay = 1000000; // attendre 1 seconde à partir de la deuxième fois + if (!$this->_isRunning($data)) { + $stopped = true; + break; + } + } + } + if ($stopped) { + sh::_waitpid($pid, $exitcode); + $this->wfReaped($exitcode); + } + return $stopped; + } + /** * vérifier si on est dans le cas où la tâche devrait tourner mais en réalité * ce n'est pas le cas diff --git a/wip/app/cli/Application.php b/wip/app/cli/Application.php index 6851ef7..4fb105c 100644 --- a/wip/app/cli/Application.php +++ b/wip/app/cli/Application.php @@ -14,6 +14,7 @@ use nur\sery\ValueException; use nur\sery\wip\app\app2; use nur\sery\wip\app\RunFile; use nur\sery\wip\web\content\v; +use nur\yaml; /** * Class Application: application de base @@ -82,11 +83,21 @@ abstract class Application { /** @var bool faut-il installer le gestionnaire de signaux? */ const INSTALL_SIGNAL_HANDLER = false; + private static function _error(string $message, int $ec=1): int { + fwrite(STDERR, "ERROR: $message\n"); + return $ec; + } + static function _manage_runfile(int $argc, array $argv, RunFile $runfile): void { if ($argc <= 1 || $argv[1] !== "//") return; array_splice($argv, 1, 1); $ec = 0; switch ($argv[1] ?? "infos") { + case "kill": + case "k": + if ($runfile->isRunning()) $runfile->wfKill(); + else $ec = self::_error("not running"); + break; case "release-lock": case "release": case "rl": @@ -104,9 +115,17 @@ abstract class Application { $ec = 1; } break; + case "dump": + case "d": + yaml::dump($runfile->read()); + break; + case "reset": + case "z": + if (!$runfile->isRunning()) $runfile->reset(); + else $ec = self::_error("cannot reset while running"); + break; default: - fwrite(STDERR, "$argv[1]: unexpected command\n"); - $ec = app2::EC_BAD_COMMAND; + $ec = self::_error("$argv[1]: unexpected command", app2::EC_BAD_COMMAND); } exit($ec); } diff --git a/wip/app/cli/bg_launcher.php b/wip/app/cli/bg_launcher.php index c0148a9..3948e99 100644 --- a/wip/app/cli/bg_launcher.php +++ b/wip/app/cli/bg_launcher.php @@ -32,66 +32,16 @@ class bg_launcher { } } - private static function kill(int $pid, int $signal): bool { - if (!posix_kill($pid, $signal)) { - switch (posix_get_last_error()) { - case PCNTL_ESRCH: - msg::afailure("process inexistant"); - break; - case PCNTL_EPERM: - msg::afailure("process non accessible"); - break; - case PCNTL_EINVAL: - msg::afailure("signal invalide"); - break; - } - return false; - } - return true; - } - static function _stop(Runfile $runfile): bool { $data = $runfile->read(); $pid = $runfile->_getCid($data); - $stopped = false; - msg::action("term $pid"); - $timeout = 10; - $delay = 300000; - while (--$timeout >= 0) { - if (!self::kill($pid, SIGTERM)) { - msg::afailure(); - return false; - } - usleep($delay); - $delay = 1000000; // attendre 1 seconde à partir de la deuxième fois - if (!$runfile->_isRunning($data)) { - msg::asuccess(); - $stopped = true; - break; - } + msg::action("stop $pid"); + if ($runfile->wfKill($reason)) { + msg::asuccess(); + return true; + } else { + msg::afailure($reason); + return false; } - if (!$stopped) { - msg::action("kill $pid"); - $timeout = 3; - $delay = 300000; - while (--$timeout >= 0) { - if (!self::kill($pid, SIGKILL)) { - msg::afailure(); - return false; - } - usleep($delay); - $delay = 1000000; // attendre 1 seconde à partir de la deuxième fois - if (!$runfile->_isRunning($data)) { - msg::asuccess(); - $stopped = true; - break; - } - } - } - if ($stopped) { - sh::_waitpid($pid, $exitcode); - $runfile->wfReaped($exitcode); - } - return $stopped; } }