mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-31 01:34:12 +02:00
Deployment: add Info class, refactor LogRenderer
No more view script, based on ipl
This commit is contained in:
parent
406bc8bd72
commit
31d65fadc2
@ -4,8 +4,7 @@ namespace Icinga\Module\Director\Controllers;
|
|||||||
|
|
||||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||||
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
|
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
|
use Icinga\Module\Director\Web\Widget\DeploymentInfo;
|
||||||
use Icinga\Module\Director\Util;
|
|
||||||
|
|
||||||
class DeploymentController extends ActionController
|
class DeploymentController extends ActionController
|
||||||
{
|
{
|
||||||
@ -16,30 +15,14 @@ class DeploymentController extends ActionController
|
|||||||
|
|
||||||
public function indexAction()
|
public function indexAction()
|
||||||
{
|
{
|
||||||
$this->view->title = $this->translate('Deployment details');
|
$info = new DeploymentInfo(DirectorDeploymentLog::load(
|
||||||
|
$this->params->get('id'),
|
||||||
$deploymentId = $this->params->get('id');
|
|
||||||
$this->view->deployment = $deployment = DirectorDeploymentLog::load(
|
|
||||||
$deploymentId,
|
|
||||||
$this->db()
|
$this->db()
|
||||||
);
|
));
|
||||||
$this->view->config_checksum = Util::binary2hex($deployment->config_checksum);
|
$this->addTitle($this->translate('Deployment details'));
|
||||||
$this->view->config = IcingaConfig::load($deployment->config_checksum, $this->db());
|
$this->tabs(
|
||||||
|
$info->getTabs($this->getAuth(), $this->getRequest())
|
||||||
$tabs = $this->getTabs()->add('deployment', array(
|
)->activate('deployment');
|
||||||
'label' => $this->translate('Deployment'),
|
$this->content()->add($info);
|
||||||
'url' => $this->getRequest()->getUrl()
|
|
||||||
))->activate('deployment');
|
|
||||||
|
|
||||||
if ($deployment->config_checksum !== null && $this->hasPermission('director/showconfig')) {
|
|
||||||
$tabs->add('config', array(
|
|
||||||
'label' => $this->translate('Config'),
|
|
||||||
'url' => 'director/config/files',
|
|
||||||
'urlParams' => array(
|
|
||||||
'checksum' => $this->view->config_checksum,
|
|
||||||
'deployment_id' => $deploymentId
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Icinga\Util\Format;
|
|
||||||
use Icinga\Module\Director\StartupLogRenderer;
|
|
||||||
|
|
||||||
?><div class="controls">
|
|
||||||
<?= $this->tabs ?>
|
|
||||||
<h1><?= $this->escape($this->title) ?></h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
<table class="name-value-table">
|
|
||||||
<tr>
|
|
||||||
<th><?= $this->translate('Deployment time') ?></th>
|
|
||||||
<td><?= $deployment->start_time ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><?= $this->translate('Sent to') ?></th>
|
|
||||||
<td><?= $deployment->peer_identity ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><?= $this->translate('Configuration') ?></th>
|
|
||||||
<td><?= $this->qlink(
|
|
||||||
sprintf(
|
|
||||||
$this->translate('%d files'),
|
|
||||||
$this->config->getFileCount()
|
|
||||||
),
|
|
||||||
'director/config/files',
|
|
||||||
array(
|
|
||||||
'checksum' => $config_checksum,
|
|
||||||
'deployment_id' => $deployment->id
|
|
||||||
)
|
|
||||||
) ?>, <?= sprintf(
|
|
||||||
$this->translate('%d objects, %d templates, %d apply rules'),
|
|
||||||
$config->getObjectCount(),
|
|
||||||
$config->getTemplateCount(),
|
|
||||||
$config->getApplyCount()
|
|
||||||
)?>, <?= Format::bytes($config->getSize()) ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><?= $this->translate('Duration') ?></th>
|
|
||||||
<td><?= sprintf(
|
|
||||||
$this->translate('Rendered in %0.2fs, deployed in %0.2fs'),
|
|
||||||
$config->getDuration() / 1000,
|
|
||||||
$deployment->duration_dump / 1000
|
|
||||||
) ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><?= $this->translate('Stage name') ?></th>
|
|
||||||
<td><?= $deployment->stage_name ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><?= $this->translate('Startup') ?></th>
|
|
||||||
<td><?php
|
|
||||||
|
|
||||||
if ($deployment->startup_succeeded === null) {
|
|
||||||
if ($deployment->stage_collected === null) {
|
|
||||||
echo $this->translate('Unknown, still waiting for config check outcome') . ' ' . $this->icon('spinner');
|
|
||||||
} else {
|
|
||||||
echo $this->translate('Unknown, failed to collect related information') . ' ' . $this->icon('help');
|
|
||||||
}
|
|
||||||
} elseif ($deployment->startup_succeeded === 'y') {
|
|
||||||
echo '<div style="color: green">';
|
|
||||||
echo $this->translate('Succeeded') . ' ' . $this->icon('ok');
|
|
||||||
echo '</div>';
|
|
||||||
} else {
|
|
||||||
echo '<div style="color: red">';
|
|
||||||
echo $this->translate('Failed') . ' ' . $this->icon('cancel');
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
?></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<?php if ($deployment->startup_succeeded !== null): ?>
|
|
||||||
<h2>Startup log</h2>
|
|
||||||
<pre class="logfile">
|
|
||||||
<?= StartupLogRenderer::beautify($deployment, $this) ?>
|
|
||||||
</pre>
|
|
||||||
<?php endif ?>
|
|
||||||
</div>
|
|
@ -3,13 +3,24 @@
|
|||||||
namespace Icinga\Module\Director;
|
namespace Icinga\Module\Director;
|
||||||
|
|
||||||
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
|
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
|
||||||
use Icinga\Web\View;
|
use ipl\Html\Link;
|
||||||
|
use ipl\Html\Util;
|
||||||
|
use ipl\Html\ValidHtml;
|
||||||
|
|
||||||
class StartupLogRenderer
|
class StartupLogRenderer implements ValidHtml
|
||||||
{
|
{
|
||||||
public static function beautify(DirectorDeploymentLog $deploymentLog, View $view)
|
/** @var DirectorDeploymentLog */
|
||||||
|
protected $deployment;
|
||||||
|
|
||||||
|
public function __construct(DirectorDeploymentLog $deployment)
|
||||||
{
|
{
|
||||||
$log = $view->escape($deploymentLog->get('startup_log'));
|
$this->deployment = $deployment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$deployment = $this->deployment;
|
||||||
|
$log = Util::escapeForHtml($deployment->get('startup_log'));
|
||||||
$lines = array();
|
$lines = array();
|
||||||
$severity = 'information';
|
$severity = 'information';
|
||||||
$sevPattern = '/^(debug|notice|information|warning|critical)\/(\w+)/';
|
$sevPattern = '/^(debug|notice|information|warning|critical)\/(\w+)/';
|
||||||
@ -35,11 +46,12 @@ class StartupLogRenderer
|
|||||||
$line = preg_replace('/([\^]{2,})/', '<span class="error-hint">\1</span>', $line);
|
$line = preg_replace('/([\^]{2,})/', '<span class="error-hint">\1</span>', $line);
|
||||||
$markPattern = null;
|
$markPattern = null;
|
||||||
|
|
||||||
|
$self = $this;
|
||||||
if (preg_match($filePatternHint, $line, $m)) {
|
if (preg_match($filePatternHint, $line, $m)) {
|
||||||
$line = preg_replace_callback(
|
$line = preg_replace_callback(
|
||||||
$filePatternHint,
|
$filePatternHint,
|
||||||
function ($matches) use ($severity, $view, $deploymentLog) {
|
function ($matches) use ($severity, $self) {
|
||||||
return StartupLogRenderer::logLink($matches, $severity, $deploymentLog, $view);
|
return $self->logLink($matches, $severity);
|
||||||
},
|
},
|
||||||
$line
|
$line
|
||||||
);
|
);
|
||||||
@ -51,8 +63,8 @@ class StartupLogRenderer
|
|||||||
|
|
||||||
$line = preg_replace_callback(
|
$line = preg_replace_callback(
|
||||||
$filePatternDetail,
|
$filePatternDetail,
|
||||||
function ($matches) use ($severity, $view, $deploymentLog) {
|
function ($matches) use ($severity, $self) {
|
||||||
return StartupLogRenderer::logLink($matches, $severity, $deploymentLog, $view);
|
return $self->logLink($matches, $severity);
|
||||||
},
|
},
|
||||||
$line
|
$line
|
||||||
);
|
);
|
||||||
@ -63,7 +75,7 @@ class StartupLogRenderer
|
|||||||
return implode("\n", $lines);
|
return implode("\n", $lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function logLink($match, $severity, DirectorDeploymentLog $deploymentLog, View $view)
|
protected function logLink($match, $severity)
|
||||||
{
|
{
|
||||||
$stageDir = $match[1];
|
$stageDir = $match[1];
|
||||||
$filename = $match[2];
|
$filename = $match[2];
|
||||||
@ -74,9 +86,10 @@ class StartupLogRenderer
|
|||||||
$lineNumber = null;
|
$lineNumber = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$deployment = $this->deployment;
|
||||||
$params = array(
|
$params = array(
|
||||||
'config_checksum' => $deploymentLog->getConfigHexChecksum(),
|
'config_checksum' => $deployment->getConfigHexChecksum(),
|
||||||
'deployment_id' => $deploymentLog->get('id'),
|
'deployment_id' => $deployment->get('id'),
|
||||||
'file_path' => $filename,
|
'file_path' => $filename,
|
||||||
'backTo' => 'deployment'
|
'backTo' => 'deployment'
|
||||||
);
|
);
|
||||||
@ -85,13 +98,13 @@ class StartupLogRenderer
|
|||||||
$params['highlightSeverity'] = $severity;
|
$params['highlightSeverity'] = $severity;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $view->qlink(
|
return Link::create(
|
||||||
'[stage]/' . $filename,
|
'[stage]/' . $filename,
|
||||||
'director/config/file',
|
'director/config/file',
|
||||||
$params,
|
$params,
|
||||||
array(
|
[
|
||||||
'title' => $stageDir . $filename
|
'title' => $stageDir . $filename
|
||||||
)
|
]
|
||||||
) . $suffix;
|
) . $suffix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
151
library/Director/Web/Widget/DeploymentInfo.php
Normal file
151
library/Director/Web/Widget/DeploymentInfo.php
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Web\Widget;
|
||||||
|
|
||||||
|
use Icinga\Authentication\Auth;
|
||||||
|
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
|
||||||
|
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
|
||||||
|
use Icinga\Module\Director\StartupLogRenderer;
|
||||||
|
use Icinga\Util\Format;
|
||||||
|
use Icinga\Web\Request;
|
||||||
|
use ipl\Html\Html;
|
||||||
|
use ipl\Html\Icon;
|
||||||
|
use ipl\Html\Link;
|
||||||
|
use ipl\Translation\TranslationHelper;
|
||||||
|
use ipl\Web\Widget\NameValueTable;
|
||||||
|
use ipl\Web\Widget\Tabs;
|
||||||
|
|
||||||
|
class DeploymentInfo extends Html
|
||||||
|
{
|
||||||
|
use TranslationHelper;
|
||||||
|
|
||||||
|
/** @var DirectorDeploymentLog */
|
||||||
|
protected $deployment;
|
||||||
|
|
||||||
|
/** @var IcingaConfig */
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
public function __construct(DirectorDeploymentLog $deployment)
|
||||||
|
{
|
||||||
|
$this->deployment = $deployment;
|
||||||
|
$this->config = IcingaConfig::load(
|
||||||
|
$deployment->config_checksum,
|
||||||
|
$deployment->getConnection()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTabs(Auth $auth, Request $request)
|
||||||
|
{
|
||||||
|
$dep = $this->deployment;
|
||||||
|
$tabs = new Tabs();
|
||||||
|
$tabs->add('deployment', array(
|
||||||
|
'label' => $this->translate('Deployment'),
|
||||||
|
'url' => $request->getUrl()
|
||||||
|
))->activate('deployment');
|
||||||
|
|
||||||
|
if ($dep->config_checksum !== null && $auth->hasPermission('director/showconfig')) {
|
||||||
|
$tabs->add('config', array(
|
||||||
|
'label' => $this->translate('Config'),
|
||||||
|
'url' => 'director/config/files',
|
||||||
|
'urlParams' => array(
|
||||||
|
'checksum' => $this->config->getHexChecksum(),
|
||||||
|
'deployment_id' => $dep->id
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createInfoTable()
|
||||||
|
{
|
||||||
|
$dep = $this->deployment;
|
||||||
|
$table = new NameValueTable();
|
||||||
|
$table->addNameValuePairs([
|
||||||
|
$this->translate('Deployment time') => $dep->start_time,
|
||||||
|
$this->translate('Sent to') => $dep->peer_identity,
|
||||||
|
$this->translate('Configuration') => $this->getConfigDetails(),
|
||||||
|
$this->translate('Duration') => $this->getDurationInfo(),
|
||||||
|
$this->translate('Stage name') => $dep->stage_name,
|
||||||
|
$this->translate('Startup') => $this->getStartupInfo()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDurationInfo()
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
$this->translate('Rendered in %0.2fs, deployed in %0.2fs'),
|
||||||
|
$this->config->getDuration() / 1000,
|
||||||
|
$this->deployment->duration_dump / 1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getConfigDetails()
|
||||||
|
{
|
||||||
|
$cfg = $this->config;
|
||||||
|
$dep = $this->deployment;
|
||||||
|
|
||||||
|
return [
|
||||||
|
Link::create(
|
||||||
|
sprintf($this->translate('%d files'), $cfg->getFileCount()),
|
||||||
|
'director/config/files',
|
||||||
|
[
|
||||||
|
'checksum' => $cfg->getHexChecksum(),
|
||||||
|
'deployment_id' => $dep->id
|
||||||
|
]
|
||||||
|
),
|
||||||
|
', ',
|
||||||
|
sprintf(
|
||||||
|
$this->translate('%d objects, %d templates, %d apply rules'),
|
||||||
|
$cfg->getObjectCount(),
|
||||||
|
$cfg->getTemplateCount(),
|
||||||
|
$cfg->getApplyCount()
|
||||||
|
),
|
||||||
|
', ',
|
||||||
|
Format::bytes($cfg->getSize())
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getStartupInfo()
|
||||||
|
{
|
||||||
|
$dep = $this->deployment;
|
||||||
|
if ($dep->startup_succeeded === null) {
|
||||||
|
if ($dep->stage_collected === null) {
|
||||||
|
return [$this->translate('Unknown, still waiting for config check outcome'), new Icon('spinner')];
|
||||||
|
} else {
|
||||||
|
return [$this->translate('Unknown, failed to collect related information'), new Icon('help')];
|
||||||
|
}
|
||||||
|
} elseif ($dep->startup_succeeded === 'y') {
|
||||||
|
return $this->colored('green', [$this->translate('Succeeded'), new Icon('ok')]);
|
||||||
|
} else {
|
||||||
|
return $this->colored('red', [$this->translate('Failed'), new Icon('cancel')]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function colored($color, array $content)
|
||||||
|
{
|
||||||
|
return Html::tag('div', ['style' => "color: $color;"], $content)->setSeparator(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$this->add($this->createInfoTable());
|
||||||
|
if ($this->deployment->get('startup_succeeded') !== null) {
|
||||||
|
$this->addStartupLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::render();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addStartupLog()
|
||||||
|
{
|
||||||
|
$this->add(Html::h2($this->translate('Startup Log')));
|
||||||
|
$this->add(
|
||||||
|
Html::tag('pre', [
|
||||||
|
'class' => 'logfile'
|
||||||
|
], new StartupLogRenderer($this->deployment))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user