NEW FEATURE: overview of runs
This commit is contained in:
parent
b80e834f68
commit
03365a1fc8
1
assets/job/view.js
Normal file
1
assets/job/view.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
import 'bootstrap';
|
1
assets/job/view.scss
Normal file
1
assets/job/view.scss
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@import "~bootstrap/dist/css/bootstrap.css";
|
|
@ -25,10 +25,11 @@ job_index:
|
||||||
_controller: JeroenED\Webcron\Controller\JobController::defaultAction
|
_controller: JeroenED\Webcron\Controller\JobController::defaultAction
|
||||||
|
|
||||||
job_view:
|
job_view:
|
||||||
path: '/job/{id}'
|
path: '/job/{id}/{all}'
|
||||||
methods: [ 'GET' ]
|
methods: [ 'GET' ]
|
||||||
defaults:
|
defaults:
|
||||||
_controller: JeroenED\Webcron\Controller\JobController::jobAction
|
_controller: JeroenED\Webcron\Controller\JobController::jobAction
|
||||||
|
all: false
|
||||||
requirements:
|
requirements:
|
||||||
id: \d+
|
id: \d+
|
||||||
|
|
||||||
|
|
17
lib/Framework/Repository.php
Normal file
17
lib/Framework/Repository.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace JeroenED\Framework;
|
||||||
|
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Connection;
|
||||||
|
|
||||||
|
class Repository
|
||||||
|
{
|
||||||
|
protected Connection $dbcon;
|
||||||
|
|
||||||
|
public function __construct(Connection $dbcon)
|
||||||
|
{
|
||||||
|
$this->dbcon = $dbcon;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ namespace JeroenED\Webcron\Controller;
|
||||||
|
|
||||||
use JeroenED\Framework\Controller;
|
use JeroenED\Framework\Controller;
|
||||||
use JeroenED\Webcron\Repository\Job;
|
use JeroenED\Webcron\Repository\Job;
|
||||||
|
use JeroenED\Webcron\Repository\Run;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
@ -21,16 +22,18 @@ class JobController extends Controller
|
||||||
return $this->render('job/index.html.twig', ['jobs' => $jobs]);
|
return $this->render('job/index.html.twig', ['jobs' => $jobs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jobAction($id)
|
public function jobAction($id, $all = false)
|
||||||
{
|
{
|
||||||
if(!isset($_SESSION['isAuthenticated']) || !$_SESSION['isAuthenticated']) {
|
if(!isset($_SESSION['isAuthenticated']) || !$_SESSION['isAuthenticated']) {
|
||||||
return new RedirectResponse($this->generateRoute('login'));
|
return new RedirectResponse($this->generateRoute('login'));
|
||||||
}
|
}
|
||||||
$jobRepo = new Job($this->getDbCon());
|
$jobRepo = new Job($this->getDbCon());
|
||||||
|
$runRepo = new Run($this->getDbCon());
|
||||||
|
|
||||||
if($this->getRequest()->getMethod() == 'GET') {
|
if($this->getRequest()->getMethod() == 'GET') {
|
||||||
$job = $jobRepo->getJob($id);
|
$job = $jobRepo->getJob($id);
|
||||||
return new Response('Not implemented, yet', Response::HTTP_NOT_IMPLEMENTED);
|
$runs = $runRepo->getRunsForJob($id, $all != 'all' ? [$job['data']['response']] : []);
|
||||||
|
return $this->render('job/view.html.twig', ['job' => $job, 'runs' => $runs, 'allruns' => $all == 'all']);
|
||||||
} elseif($this->getRequest()->getMethod() == 'DELETE') {
|
} elseif($this->getRequest()->getMethod() == 'DELETE') {
|
||||||
$success = $jobRepo->deleteJob($id);
|
$success = $jobRepo->deleteJob($id);
|
||||||
$this->addFlash('success', $success['message']);
|
$this->addFlash('success', $success['message']);
|
||||||
|
|
|
@ -5,20 +5,13 @@ namespace JeroenED\Webcron\Repository;
|
||||||
|
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\DBAL\Connection;
|
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
|
use JeroenED\Framework\Repository;
|
||||||
use phpseclib3\Crypt\PublicKeyLoader;
|
use phpseclib3\Crypt\PublicKeyLoader;
|
||||||
use phpseclib3\Net\SSH2;
|
use phpseclib3\Net\SSH2;
|
||||||
|
|
||||||
class Job
|
class Job extends Repository
|
||||||
{
|
{
|
||||||
private Connection $dbcon;
|
|
||||||
|
|
||||||
public function __construct(Connection $dbcon)
|
|
||||||
{
|
|
||||||
$this->dbcon = $dbcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllJobs()
|
public function getAllJobs()
|
||||||
{
|
{
|
||||||
$jobsSql = "SELECT * FROM job";
|
$jobsSql = "SELECT * FROM job";
|
||||||
|
|
29
src/Repository/Run.php
Normal file
29
src/Repository/Run.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace JeroenED\Webcron\Repository;
|
||||||
|
|
||||||
|
|
||||||
|
use JeroenED\Framework\Repository;
|
||||||
|
|
||||||
|
class Run extends Repository
|
||||||
|
{
|
||||||
|
public function getRunsForJob(int $id, $excludedexitcodes = [], $ordered = true): array
|
||||||
|
{
|
||||||
|
$runsSql = "SELECT * FROM run WHERE job_id = :job";
|
||||||
|
$params = [':job' => $id];
|
||||||
|
if (!empty($excludedexitcodes)) {
|
||||||
|
$runsSql .= ' AND exitcode NOT in (';
|
||||||
|
foreach($excludedexitcodes as $key => $exitcode) {
|
||||||
|
$runsSql .= ':code' . $key;
|
||||||
|
$params[':code' . $key] = $exitcode;
|
||||||
|
}
|
||||||
|
$runsSql .= ')';
|
||||||
|
}
|
||||||
|
if ($ordered) $runsSql .= ' ORDER by timestamp DESC';
|
||||||
|
$runsStmt = $this->dbcon->prepare($runsSql);
|
||||||
|
$runsRslt = $runsStmt->executeQuery($params);
|
||||||
|
$runs = $runsRslt->fetchAllAssociative();
|
||||||
|
return $runs;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,15 +5,10 @@ namespace JeroenED\Webcron\Repository;
|
||||||
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
|
use JeroenED\Framework\Repository;
|
||||||
|
|
||||||
class User
|
class User extends Repository
|
||||||
{
|
{
|
||||||
private Connection $dbcon;
|
|
||||||
|
|
||||||
public function __construct(Connection $dbcon)
|
|
||||||
{
|
|
||||||
$this->dbcon = $dbcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $user
|
* @param string $user
|
||||||
|
|
41
templates/job/view.html.twig
Normal file
41
templates/job/view.html.twig
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{% extends "base.html.twig" %}
|
||||||
|
{% block title %}Overview of run for {{ job.name }}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h2>Overview of runs for {{ job.name }}</h2>
|
||||||
|
<p>
|
||||||
|
<a href="{{ path('job_edit', { id: job.id }) }}">Edit job</a>
|
||||||
|
{% if allruns %} | <a href="{{ path('job_view', { id: job.id })}}">Only show failed runs</a>
|
||||||
|
{% elseif not allruns %} | <a href="{{ path('job_view', { id: job.id, all: 'all' })}}">Show all runs</a>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
<div id="runs" class="accordion">
|
||||||
|
{% for run in runs %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header" id="run-{{ run.id }}-header">
|
||||||
|
<h2 class="mb-0">
|
||||||
|
<button class="btn btn-link btn-block d-flex justify-content-between" type="button" data-toggle="collapse" data-target="#run-{{ run.id }}" aria-expanded="true" aria-controls="run-{{ run.id }}">
|
||||||
|
<span>{{ run.timestamp | date("d/m/Y H:i:s") }}</span>
|
||||||
|
<span>{{ run.exitcode }}</span>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div id="run-{{ run.id }}" class="collapse{% if loop.index == 1%} show{% endif %}" aria-labelledby="run-{{ run.id }}-header" data-parent="#runs">
|
||||||
|
<div class="card-body">
|
||||||
|
<pre>{{ run.output }}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<h4>No {% if not allruns %}failed {% endif %}runs found</h4>
|
||||||
|
<p><a href="{{ path('job_view', { id: job.id, all: 'all' })}}">Show all runs</a></p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block styles %}
|
||||||
|
{{ encore_entry_link_tags('job.view') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ encore_entry_script_tags('job.view') }}
|
||||||
|
{% endblock %}
|
|
@ -25,6 +25,7 @@ Encore
|
||||||
*/
|
*/
|
||||||
.addEntry('security.login', ['./assets/security/login.js', './assets/security/login.scss'])
|
.addEntry('security.login', ['./assets/security/login.js', './assets/security/login.scss'])
|
||||||
.addEntry('job.index', ['./assets/job/index.js', './assets/job/index.scss'])
|
.addEntry('job.index', ['./assets/job/index.js', './assets/job/index.scss'])
|
||||||
|
.addEntry('job.view', ['./assets/job/view.js', './assets/job/view.scss'])
|
||||||
.addEntry('job.add', ['./assets/job/add.js', './assets/job/add.scss'])
|
.addEntry('job.add', ['./assets/job/add.js', './assets/job/add.scss'])
|
||||||
//.addEntry('page1', './assets/page1.js')
|
//.addEntry('page1', './assets/page1.js')
|
||||||
//.addEntry('page2', './assets/page2.js')
|
//.addEntry('page2', './assets/page2.js')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user