Files

458 lines
18 KiB
PHP

<?php
/**
* fruithost | OpenSource Hosting
*
* @author Adrian Preuß
* @version 1.0.0
* @license MIT
*/
use fruithost\Accounting\Auth;
use fruithost\Localization\I18N;
use fruithost\System\Utils;
use fruithost\UI\Icon;
$template->header();
if(!Auth::hasPermission('SERVER::SERVER')) {
?>
<div class="alert alert-danger mt-4" role="alert">
<strong><?php I18N::__('Access denied!'); ?></strong>
<p class="pb-0 mb-0"><?php I18N::__('You have no permissions for this page.'); ?></p>
</div>
<?php
$template->footer();
exit();
}
?>
<div class="container-fluid mt-5">
<div class="row">
<div class="col-xl-3 col-md-6 col-sm-6">
<div class="card text-break">
<div class="card-header d-inline-flex flex-row p-0">
<?php
Icon::show('ip', [
'classes' => [
'align-self-start',
'flex-shrink-1',
'bg-dark',
'rounded',
'text-light',
'p-2',
'm-2'
],
'attributes' => [ 'style' => 'font-size: 30px' ],
'data-current' => 'theme-auto'
]);
?>
<span class="align-self-start flex-fill p-0 ml-2 mt-1">
<small><?php I18N::__('IP Address'); ?></small>
<h4 class="p-0 m-o"><?php print $network->getIPAddress(); ?></h4>
</span>
</div>
<div class="card-body p-1 text-center">
<a class="icon-link icon-link-hover text-decoration-none" style="--bs-link-hover-color-rgb: 25, 135, 84;" href="<?php print $template->url('/server/network'); ?>">
<?php
Icon::show('network', [
'classes' => [ 'mb-2' ]
]);
I18N::__('Network settings');
?>
</a>
</div>
</div>
</div>
<div class="col-xl-4 col-md-6 col-sm-6">
<div class="card text-break">
<div class="card-header d-flex flex-row p-0">
<?php
Icon::show('uptime', [
'classes' => [
'align-self-start',
'flex-shrink-1',
'bg-dark',
'rounded',
'text-light',
'p-2',
'm-2'
],
'attributes' => [ 'style' => 'font-size: 30px' ]
]);
?>
<span class="align-self-start flex-fill p-0 ml-2 mt-1">
<small><?php I18N::__('Uptime'); ?></small>
<h4 class="p-0 m-o"><?php print $uptime; ?></h4>
</span>
</div>
<div class="card-body p-1 text-center">
<a class="icon-link icon-link-hover text-decoration-none" style="--bs-link-hover-color-rgb: 25, 135, 84;" href="<?php print $template->url('/server/reboot'); ?>">
<?php
Icon::show('restart', [
'classes' => [ 'mb-1' ]
]);
I18N::__('Restart');
?>
</a>
</div>
</div>
</div>
<div class="col-xl-5 col-md-12 mt-sm-3 mt-xl-0">
<div class="card">
<div class="card-header d-flex flex-row">
<?php I18N::__('System'); ?>
</div>
<div class="card-body p-0">
<table class="table m-0 table-borderless table-striped">
<tr>
<td rowspan="4" class="text-center align-middle border-end">
<img height="50px" class="m-2" src="<?php print $template->url(sprintf('/assets/systems/%s.svg', $id)); ?>" alt="<?php print $id; ?>"/>
</td>
<td>
<strong><?php I18N::__('System'); ?></strong>
</td>
<td>
<?php print $os; ?>, <?php print $machine_type; ?>
</td>
</tr>
<tr>
<td>
<strong><?php I18N::__('Kernel'); ?></strong>
</td>
<td>
<?php print $kernel; ?>
</td>
</tr>
<tr>
<td>
<strong><?php I18N::__('System Time'); ?></strong>
</td>
<td>
<?php print $time_system; ?>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<hr/>
<div class="container">
<div class="row">
<!-- System Properties -->
<div class="col-xl-6 col-md-12 mt-sm-12 mt-2">
<div class="card">
<div class="card-header d-flex flex-row">
<?php I18N::__('System Properties'); ?>
</div>
<div class="card-body p-0">
<table class="table m-0 table-borderless table-striped">
<tr>
<td>
<strong><?php I18N::__('Hostname'); ?></strong>
</td>
<td>
<?php
print $network->getHostname();
if(sprintf('my.%s', $network->getHostname()) !== $network->getPanelHostname()) {
Icon::show('warning', [
'classes' => [
'text-warning',
'ml-1'
],
'attributes' => [
'data-bs-toggle' => 'hover',
'data-bs-content' => sprintf(I18N::get('The hostname <strong>%s</strong> does not match the panel domain (<strong>%s</strong>).'), $network->getHostname(), $network->getPanelHostname()),
'data-bs-title' => sprintf('<small class=\'text-warning fw-bolder\'>%s</small>', I18N::get('Warning!'))
]
]);
}
?>
</td>
</tr>
<tr>
<td>
<strong><?php I18N::__('System Time'); ?></strong>
</td>
<td>
<?php print $time_system; ?>
</td>
</tr>
<tr>
<td>
<strong><?php I18N::__('License Key'); ?></strong>
</td>
<td>
<?php
if(defined('DEMO') && DEMO) {
?>
<div class="alert alert-warning m-0 p-1" role="alert">
<?php
Icon::show('warning');
?> <strong><?php I18N::__('Warning'); ?></strong>
<div>
<?php I18N::__('This value is not visible in the demo version.'); ?>
</div>
</div>
<?php
} else {
print $update_license;
}
?>
</td>
</tr>
<tr>
<td>
<strong><?php I18N::__('Version'); ?></strong>
</td>
<td>
<?php
if(version_compare($version, $update_version, '>')) {
Icon::show('error', [
'classes' => [
'text-danger',
'mr-2'
]
]);
} else {
Icon::show('okay', [
'classes' => [
'text-success',
'mr-2'
]
]);
}
print ' '.$version;
if(version_compare($version, $update_version, '>')) {
Icon::show('warning', [
'classes' => [
'text-warning',
'ml-1'
],
'attributes' => [
'data-bs-toggle' => 'hover',
'data-bs-content' => sprintf(I18N::get('Please update the system to <strong>Version %s</strong> via the fruithost daemon.'), $update_version),
'data-bs-title' => sprintf('<small class=\'text-warning fw-bolder\'>%s</small>', I18N::get('Update available!'))
]
]);
}
Icon::show('clock', [
'classes' => [
'text-light',
'ml-1',
'float-end'
],
'attributes' => [
'data-bs-toggle' => 'hover',
'data-bs-title' => sprintf('%s %s', I18N::get('Last checked:'), $time_update)
]
]);
?>
</td>
</tr>
</table>
</div>
</div>
</div>
<!-- Daemon -->
<div class="col-xl-6 col-md-12 mt-sm-12 mt-2">
<div class="card">
<div class="card-header d-flex flex-row">
<?php I18N::__('Daemon'); ?>
</div>
<div class="card-body p-0">
<table class="table m-0 table-borderless table-striped">
<tr>
<td>
<strong><?php I18N::__('Status'); ?></strong>
</td>
<td>
<span class="d-inline-block badge badge-pill module-badge text-bg-<?php print ($daemon['status'] ? 'success' : 'danger'); ?>" data-toggle="tooltip" title="<?php ($daemon['status'] ? I18N::__('Running normally.') : I18N::__('Error during execution!')); ?>"></span>
<span class="d-inline-block text-<?php print ($daemon['status'] ? 'success' : 'danger fw-bolder'); ?>">
<?php
if($daemon['status']) {
I18N::__('Okay');
} else {
I18N::__('Error');
}
?>
</span>
</td>
</tr>
<tr>
<td>
<strong><?php I18N::__('Last Start'); ?></strong>
</td>
<td>
<?php print $daemon['start']; ?>
(<?php printf(I18N::get('%s ago'), Utils::getTimeDifference($daemon['started'])); ?>)
</td>
</tr>
<tr>
<td>
<strong><?php I18N::__('Last End'); ?></strong>
</td>
<td>
<?php print $daemon['end']; ?>
(<?php printf(I18N::get('%s ago'), Utils::getTimeDifference($daemon['ended'])); ?>)
</td>
</tr>
<tr>
<td>
<strong><?php I18N::__('Last Time'); ?></strong>
</td>
<td>
<?php printf(I18N::get('%d Seconds'), $daemon['time']); ?>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Storage -->
<div class="col-xl-6 col-md-12 mt-sm-12 mt-2 mb-2">
<div class="card">
<div class="card-header d-flex flex-row">
<?php I18N::__('Mounted Drives'); ?>
</div>
<div class="card-body p-3">
<?php
foreach($disks as $disk) {
?>
<div class="mb-2">
<div class="d-flex">
<div class="p-2 flex-shrink-1">
<?php
Icon::show('storage', [
'classes' => [ 'mr' ]
]);
?>
</div>
<div class="p-2 flex-fill">
<strong class="ml-2"><?php print $disk['name']; ?></strong>
</div>
</div>
<div class="bg-secondary" style="height: 15px;" data-percentage="<?php printf('%s %%', $disk['percent']); ?>">
<div class="bg-success" style="height: 100%; width: <?php print $disk['percent']; ?>%"></div>
</div>
<small class="text-muted"><?php printf(I18N::get('Type: %s | FileSystem: %s | Size: %s / %s'), $disk['type'], $disk['filesystem'], Utils::getFileSize($disk['used']), Utils::getFileSize($disk['size'])); ?></small>
</div>
<?php
}
?>
</div>
</div>
</div>
<!-- Memory Utilization -->
<div class="col-xl-6 col-md-12 mt-sm-12 mt-2">
<div class="card">
<div class="card-header d-flex flex-row">
<div class="text-start"><?php I18N::__('Memory'); ?></div>
<div class="ms-auto form-check form-switch flex-end">
<input class="form-check-input" type="checkbox" role="switch" id="live_memory" checked/>
<label class="form-check-label" for="live_memory"></label>
</div>
</div>
<div class="card-body p-3">
<div class="mb-2">
<div class="d-flex">
<div class="p-2 flex-shrink-1">
<?php
Icon::show('memory', [
'classes' => [ 'mr' ]
]);
?>
</div>
<div class="p-2 flex-fill">
<strong class="ml-2"><?php I18N::__('RAM'); ?></strong>
</div>
</div>
<div data-name="mem_visual" class="bg-secondary" style="height: 15px;" data-percentage="<?php print $memory->getPercentage(); ?> %">
<div class="bg-success" style="height: 100%; width: <?php print $memory->getPercentage(); ?>%"></div>
</div>
</div>
<div id="memory" class="bg-light-subtle overflow-hidden"></div>
<table class="mt-4">
<tr>
<td style="min-width: 150px;">
<strong><small><?php I18N::__('In use'); ?></small></strong>
</td>
<td style="min-width: 150px;">
<strong><small><?php I18N::__('Available'); ?></small></strong>
</td>
</tr>
<tr>
<td>
<h4 data-name="mem_used"><?php print Utils::getFileSize($memory->getUsed()); ?></h4>
</td>
<td>
<h4 data-name="mem_total"><?php print Utils::getFileSize($memory->getTotal()); ?></h4>
</td>
</tr>
<tr>
<td>
<strong><small><?php I18N::__('Assured'); ?></small></strong>
</td>
<td>
<strong><small><?php I18N::__('In cache'); ?></small></strong>
</td>
</tr>
<tr>
<td>
<h4 data-name="mem_assured"><?php print Utils::getFileSize($memory->getAssured()); ?></h4>
</td>
<td>
<h4 data-name="mem_cache"><?php print Utils::getFileSize($memory->getInCache()); ?></h4>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
(() => {
window.addEventListener('DOMContentLoaded', () => {
let interval = 1000;
let stats = new Statistics('#memory');
stats.setColor([200, 18, 174, 1]);
stats.render(interval);
setInterval(function () {
stats.start();
if (!document.querySelector('#live_memory').checked) {
stats.stop();
return;
}
new Ajax('<?php print $template->url('/server/server'); ?>').onSuccess(function (response) {
stats.add(response.percentage, [139, 18, 174, 0.6]);
document.querySelector('[data-name="mem_visual"]').dataset.percentage = response.percentage + ' %';
document.querySelector('[data-name="mem_visual"] .bg-success').style.width = response.percentage + '%';
document.querySelector('[data-name="mem_used"]').innerText = response.used;
document.querySelector('[data-name="mem_total"]').innerText = response.total;
document.querySelector('[data-name="mem_assured"]').innerText = response.assured;
document.querySelector('[data-name="mem_cache"]').innerText = response.cache;
}).post({
action: 'command',
command: 'get_live_usage'
});
}, interval);
});
})();
</script>
<?php
$template->footer();
?>