NEW FEATURE: manual runs

This commit is contained in:
Jeroen De Meerleer 2021-06-01 17:41:10 +02:00
parent 65aa04a69a
commit 9b36474e48
Signed by: JeroenED
GPG Key ID: 28CCCB8F62BFADD6
4 changed files with 69 additions and 13 deletions

View File

@ -49,6 +49,13 @@ job_edit:
requirements:
id: \d+
job_runnow:
path: '/job/{id}/runnow'
defaults:
_controller: JeroenED\Webcron\Controller\JobController::runnowAction
requirements:
id: \d+
job_add:
path: '/job/add'
defaults:

View File

@ -4,6 +4,7 @@
namespace JeroenED\Webcron\Controller;
use JeroenED\Framework\Controller;
use JeroenED\Framework\Repository;
use JeroenED\Webcron\Repository\Job;
use JeroenED\Webcron\Repository\Run;
use Symfony\Component\HttpFoundation\JsonResponse;
@ -88,4 +89,14 @@ class JobController extends Controller
return new Response('Not implemented yet', Response::HTTP_TOO_EARLY);
}
}
public function runNowAction(int $id) {
if(!isset($_SESSION['isAuthenticated']) || !$_SESSION['isAuthenticated']) {
return new RedirectResponse($this->generateRoute('login'));
}
if($this->getRequest()->getMethod() == 'GET') {
$jobRepo = new Job($this->getDbCon());
return new JsonResponse($jobRepo->runNow($id));
}
}
}

View File

@ -232,6 +232,28 @@ class Job extends Repository
}
}
public function runNow($job) {
$job = $this->getJob($job, true);
$runRepo = new Run($this->dbcon);
if($runRepo->isSlowJob($job['id']) && $job['data']['crontype'] !== 'reboot') {
$jobsSql = "UPDATE job SET running = :status WHERE id = :id AND running IN (0,1,2)";
$jobsStmt = $this->dbcon->prepare($jobsSql);
$jobsStmt->executeQuery([':id' => $job['id'], ':status' => 2]);
return ['success' => true, 'message' => 'Job was scheduled to be run. You will find the output soon in the job details'];
} else {
$this->runJob($job['id'], true);
$output = $runRepo->getLastRun($job['id']);
return [
'output' => $output['output'],
'exitcode' => $output['exitcode'],
'runtime' => $output['runtime'],
'success' => !str_contains($output['flags'], Run::FAILED)
];
}
}
private function prepareDockerCommand(string $command, string $service, string|NULL $user): string
{
$prepend = 'docker exec ';
@ -244,11 +266,11 @@ class Job extends Repository
{
$starttime = microtime(true);
$job = $this->getJob($job, true);
if($job['data']['crontype'] == 'http') {
if ($job['data']['crontype'] == 'http') {
$result = $this->runHttpJob($job);
} elseif($job['data']['crontype'] == 'command') {
} elseif ($job['data']['crontype'] == 'command') {
$result = $this->runCommandJob($job);
} elseif($job['data']['crontype'] == 'reboot') {
} elseif ($job['data']['crontype'] == 'reboot') {
$result = $this->runRebootJob($job, $starttime, $manual);
}
$endtime = microtime(true);
@ -256,28 +278,30 @@ class Job extends Repository
// setting flags
$flags = [];
if($result['failed'] === true) {
if ($result['failed'] === true) {
$flags[] = Run::FAILED;
} else {
$flags[] = Run::SUCCESS;
}
if($manual === true) {
if ($manual === true) {
$flags[] = Run::MANUAL;
}
// saving to database
$runRepo = new Run($this->dbcon);
$runRepo->addRun($job['id'], $result['exitcode'], floor($starttime), $runtime, $result['output'], $flags);
// setting nextrun to next run
$nextrun = $job['nextrun'];
do {
$nextrun = $nextrun + $job['interval'];
} while ($nextrun < time());
if (!$manual){
// setting nextrun to next run
$nextrun = $job['nextrun'];
do {
$nextrun = $nextrun + $job['interval'];
} while ($nextrun < time());
$addRunSql = 'UPDATE job SET nextrun = :nextrun WHERE id = :id';
$addRunStmt = $this->dbcon->prepare($addRunSql);
$addRunStmt->executeQuery([':id' => $job['id'], ':nextrun' => $nextrun]);
$addRunSql = 'UPDATE job SET nextrun = :nextrun WHERE id = :id';
$addRunStmt = $this->dbcon->prepare($addRunSql);
$addRunStmt->executeQuery([':id' => $job['id'], ':nextrun' => $nextrun]);
}
}
public function unlockJob(int $id = 0): void

View File

@ -33,4 +33,18 @@ class Run extends Repository
$addRunStmt = $this->dbcon->prepare($addRunSql);
$addRunStmt->executeQuery([':job_id' => $jobid, ':exitcode' => $exitcode, 'output' => $output, 'runtime' => $runtime, ':timestamp' => $starttime, ':flags' => implode("", $flags)]);
}
public function getLastRun(int $jobid): array
{
$lastRunSql = 'SELECT * FROM run WHERE job_id = :jobid ORDER BY timestamp DESC LIMIT 1';
$lastRun = $this->dbcon->prepare($lastRunSql)->executeQuery([':jobid' => $jobid])->fetchAssociative();
return $lastRun;
}
public function isSlowJob(int $jobid, int $timelimit = 5): bool
{
$slowJobSql = 'SELECT AVG(runtime) as average FROM run WHERE job_id = :jobid LIMIT 5';
$slowJob = $this->dbcon->prepare($slowJobSql)->executeQuery([':jobid' => $jobid])->fetchAssociative();
return $slowJob['average'] > $timelimit;
}
}