mirror of
https://github.com/unraid/webgui.git
synced 2026-01-01 15:10:19 -06:00
1826 lines
79 KiB
Plaintext
1826 lines
79 KiB
Plaintext
Menu="Dashboard"
|
|
Nchan="wg_poller,update_1,update_2,update_3,ups_status:stop,vm_dashusage"
|
|
---
|
|
<?PHP
|
|
/* Copyright 2005-2025, Lime Technology
|
|
* Copyright 2012-2025, Bergware International.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License version 2,
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*/
|
|
?>
|
|
<?
|
|
function export_settings($protocol,$share) {
|
|
if ($protocol!='yes' || $share['export']=='-') return "-";
|
|
if ($share['export']=='e') return _(ucfirst($share['security']));
|
|
return '<em>'._(ucfirst($share['security'])).'</em>';
|
|
}
|
|
function vpn_peers($file) {
|
|
$peers = [];
|
|
$entries = array_filter(array_map('trim',preg_split('/\[(Interface|Peer)\]/',file_get_contents($file))));
|
|
foreach($entries as $key => $entry) {
|
|
$noname = true;
|
|
foreach (explode("\n",$entry) as $row) {
|
|
if ($key>1 && $row[0]=='#') {$peers[$key-1] = substr($row,1); $noname = false;}
|
|
}
|
|
if ($key>1 && $noname) $peers[$key-1] = "Peer ".($key-1);
|
|
}
|
|
return $peers;
|
|
}
|
|
function customTiles($column) {
|
|
global $mytiles;
|
|
if (isset($mytiles)) foreach ($mytiles as $tile) if (!empty($tile[$column])) echo $tile[$column];
|
|
}
|
|
|
|
// adjust the text color in log window
|
|
$themeHelper->updateDockerLogColor($docroot); // $themeHelper set in DefaultPageLayout.php
|
|
exec("/etc/rc.d/rc.docker status >/dev/null",$dummy,$dockerd);
|
|
exec("/etc/rc.d/rc.libvirt status >/dev/null",$dummy,$libvirtd);
|
|
|
|
$dockerd = $dockerd==0;
|
|
$libvirtd = $libvirtd==0;
|
|
$apcupsd = file_exists('/var/run/apcupsd.pid');
|
|
$cookie = '/boot/config/dashboard_settings.json';
|
|
$conf = glob('/etc/wireguard/wg*.conf');
|
|
$wireguard = is_executable('/usr/bin/wg') && count($conf);
|
|
$started = _var($var,'fsState')=='Started';
|
|
$sleep = isset($display['sleep']);
|
|
$poolsOnly = (_var($var,'SYS_ARRAY_SLOTS') == 0 ) ? true : false;
|
|
$array_size = $array_used = 0;
|
|
$extra_size = $extra_used = 0;
|
|
$cache_size = $cache_used = [];
|
|
$cache_type = $cache_rate = [];
|
|
$parity = _var($var,'mdResync');
|
|
$mover = file_exists('/var/run/mover.pid');
|
|
$btrfs = exec('pgrep --ns $$ -cf /sbin/btrfs');
|
|
$vdisk = exec("grep -Pom1 '^DOCKER_IMAGE_TYPE=\"\\K[^\"]+' /boot/config/docker.cfg 2>/dev/null")!='folder' ? _('Docker vdisk') : _('Docker folder');
|
|
$dot = _var($display,'number','.,')[0];
|
|
$zfs = count(array_filter(array_column($disks,'fsType'),function($fs){return str_replace('luks:','',$fs??'')=='zfs';}));
|
|
|
|
$domain_cfgfile = "/boot/config/domain.cfg";
|
|
$domain_cfg = parse_ini_file($domain_cfgfile);
|
|
$vmusage = isset($domain_cfg['USAGE']) ? $domain_cfg['USAGE'] : 'N';
|
|
|
|
// enable/disable graph elements by making hook script executable or not
|
|
chmod("$docroot/webGui/system/VM",$libvirtd ? 0755 : 0644);
|
|
chmod("$docroot/webGui/system/ZFS_cache",$zfs ? 0755 : 0644);
|
|
|
|
foreach ($disks as $disk) {
|
|
switch (_var($disk,'type')) {
|
|
case 'Data':
|
|
if (isset($disk['fsFree'])) {
|
|
$array_size += _var($disk,'fsSize',0);
|
|
$array_used += _var($disk,'fsSize',0)-_var($disk,'fsFree',0);
|
|
}
|
|
break;
|
|
case 'Cache':
|
|
$name = _var($disk,'name');
|
|
if (in_array($name,$pools)) {
|
|
$cache_size[$name] = _var($disk,'fsSize',0);
|
|
$cache_used[$name] = _var($disk,'fsSize',0)-_var($disk,'fsFree',0);
|
|
$cache_type[$name] = _var($disk,'rotational') ? (_var($disk,'luksState') ? 'disk-encrypted' : 'disk') : 'nvme';
|
|
$cache_rate[$name] = number_format(100*$cache_used[$name]/($cache_size[$name] ?: 1),1,$dot,'');
|
|
if (empty($disks[$name]['devices'])) unset($pools[array_search($name,$pools)]);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach ($devs as $disk) {
|
|
$extra_size += _var($disk,'sectors',0)*_var($disk,'sector_size',0);
|
|
}
|
|
|
|
$array_percent = number_format(100*$array_used/($array_size ?: 1),1,$dot,'');
|
|
exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list|sort -nu', $cpus);
|
|
$wg_up = $wireguard ? exec("wg show interfaces") : '';
|
|
$wg_up = $wg_up ? explode(' ',$wg_up) : [];
|
|
$up = count($wg_up);
|
|
$down = max(count($conf)-$up,0);
|
|
$fans = exec("sensors -uA 2>/dev/null|grep -c 'fan[0-9]_input'");
|
|
$autofan = is_executable("$docroot/plugins/dynamix.system.autofan/scripts/rc.autofan");
|
|
$group = _var($var,'shareSMBEnabled')=='yes' | _var($var,'shareNFSEnabled')=='yes';
|
|
$names = [];
|
|
$SMBpublic = $NFSpublic= 0;
|
|
foreach ($sec as $share => $prop) {
|
|
if ( $prop['export'] == "-") continue;
|
|
if ( $prop['security'] == "public") {
|
|
if ( $share == "flash" || (! isset($disks[$share]) || (isset($disks[$share]) && ($var['shareDisk']??"") == "yes" && $share !=="flash") ) )
|
|
$SMBpublic++;
|
|
}
|
|
if ( ($var['shareDisk']??"") !== "yes" && $share !=="flash" ) continue;
|
|
if ( ! $started && isset($disks[$share]) && $share !=="flash" ) continue;
|
|
if ( (! isset($shares[$share]) && isset($disks[$share]) && ($var['shareDisk']??"") == "yes" ) || $share == "flash" ) {$shares[$share]=$disks[$share]; $shares[$share]['diskexport'] = true;}
|
|
}
|
|
if ($var['shareNFSEnabled']=='yes') {
|
|
foreach ($sec_nfs as $share => $prop) {
|
|
if ( $prop['export'] == "-") continue;
|
|
if ( $prop['security'] == "public") {
|
|
if ( $share == "flash" || (! isset($disks[$share]) || (isset($disks[$share]) && ($var['shareDisk']??"") == "yes" && $share !== "flash" ) ) )
|
|
$NFSpublic++;
|
|
}
|
|
if ( ($var['shareDisk']??"") == "no" && $share !=="flash" ) continue;
|
|
if ( ! $started && isset($disks[$share]) && $share !=="flash" ) continue;
|
|
if ( ( ! isset($shares[$share]) && isset($disks[$share]) && ($var['shareDisk']??"") == "yes") || $share == "flash" ) {$shares[$share]=$disks[$share]; $shares[$share]['diskexport'] = true;}
|
|
}
|
|
}
|
|
|
|
$passwd = $nopass = 0;
|
|
foreach ($users as $user) if ($user['passwd']=='yes') $passwd++; else $nopass++;
|
|
|
|
$boot = "/boot/config/plugins/dynamix";
|
|
$myfile = "case-model.cfg";
|
|
$mycase = file_exists("$boot/$myfile") ? file_get_contents("$boot/$myfile") : false;
|
|
|
|
$board = dmidecode('Base Board Information','2',0);
|
|
$serial = _("s/n").": ".($board['Serial Number'] ?? "--");
|
|
$board = ($board['Manufacturer'] ?? "").' '.($board['Product Name'] ?? "").' '.(isset($board['Version']) ? ", "._("Version")." ".$board['Version'] : "");
|
|
|
|
$bios = dmidecode('BIOS Information','0',0);
|
|
$biosdate = _("BIOS dated").": "._(my_time(strtotime($bios['Release Date'] ?? ""),$display['date']),0);
|
|
$bios = $bios['Vendor'].(isset($bios['Version']) ? ", "._("Version")." ".$bios['Version'] : "");
|
|
|
|
$cpu = dmidecode('Processor Information','4',0);
|
|
$cpumodel = str_ireplace(["Processor","(C)","(R)","(TM)"],["","©","®","™"],exec("grep -Pom1 '^model name\s+:\s*\K.+' /proc/cpuinfo") ?: $cpu['Version']);
|
|
$cpumodel .= (strpos($cpumodel,'@')===false && !empty($cpu['Current Speed']) ? " @ {$cpu['Current Speed']}" : "");
|
|
$cpu_vendor = $cpu['Manufacturer'] ?? "";
|
|
|
|
$total = exec("awk '/^MemTotal/{print $2*1024}' /proc/meminfo");
|
|
unset($ports); exec("ls --indicator-style=none /sys/class/net|grep -Po '^(bond|eth|wlan)\d+$'",$ports);
|
|
$ports[] = 'lo';
|
|
|
|
$sizes = ['MB','GB','TB'];
|
|
$memory_type = $ecc = '';
|
|
$memory_installed = $memory_maximum = 0;
|
|
$memory_devices = dmidecode('Memory Device','17');
|
|
foreach ($memory_devices as $device) {
|
|
if (!is_numeric($device['Size'][0])) continue;
|
|
[$size, $unit] = my_explode(' ',$device['Size']??'');
|
|
$base = array_search($unit,$sizes);
|
|
if ($base!==false) $memory_installed += $size*pow(1024,$base);
|
|
if (!$memory_type && isset($device['Type']) && $device['Type']!='Unknown') $memory_type = $device['Type'];
|
|
}
|
|
$memory_array = dmidecode('Physical Memory Array','16');
|
|
foreach ($memory_array as $device) {
|
|
[$size, $unit] = my_explode(' ',$device['Maximum Capacity']??'');
|
|
$base = array_search($unit,$sizes);
|
|
if ($base>=1) $memory_maximum += $size*pow(1024,$base);
|
|
if (!$ecc && isset($device['Error Correction Type']) && $device['Error Correction Type']!='None') $ecc = "{$device['Error Correction Type']} ";
|
|
}
|
|
if ($memory_installed >= 1024) {
|
|
$memory_installed = round($memory_installed/1024);
|
|
$memory_maximum = round($memory_maximum/1024);
|
|
$unit = 'GiB';
|
|
} else $unit = 'MiB';
|
|
|
|
// get system resources size
|
|
exec("df --output=size /boot /var/log /var/lib/docker 2>/dev/null|awk '(NR>1){print $1*1024}'",$df);
|
|
$flashsize = my_scale($df[0],$unit,0,-1,1024)." $unit";
|
|
$logsize = my_scale($df[1],$unit,0,-1,1024)." $unit";
|
|
$dockersize = my_scale($df[2],$unit,0,-1,1024)." $unit";
|
|
$ramsize = my_scale($total,$unit,0,-1,1024)." $unit";
|
|
|
|
// If maximum < installed then roundup maximum to the next power of 2 size of installed. E.g. 6 -> 8 or 12 -> 16
|
|
$low = $memory_maximum < $memory_installed;
|
|
if ($low) $memory_maximum = pow(2,ceil(log($memory_installed)/log(2)));
|
|
|
|
switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout.php
|
|
case 'white': $color = '#1c1b1b'; $grid = '#e3e3e3'; $c0 = '#a8a8a8'; $c1 = '#dcdcdc'; break;
|
|
case 'black': $color = '#f2f2f2'; $grid = '#2b2b2b'; $c0 = '#787878'; $c1 = '#444444'; break;
|
|
case 'azure': $color = '#606e7f'; $grid = '#f3f0f4'; $c0 = '#606e7f'; $c1 = '#eceaec'; break;
|
|
case 'gray' : $color = '#606e7f'; $grid = '#0c0f0b'; $c0 = '#606e7f'; $c1 = '#232523'; break;
|
|
default : $color = '#1c1b1b'; $grid = '#e3e3e3'; $c0 = '#a8a8a8'; $c1 = '#dcdcdc'; break;
|
|
}
|
|
?>
|
|
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
|
|
|
<script src="<?autov('/webGui/javascript/jquery.apexcharts.js')?>"></script>
|
|
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
|
<script src="<?autov('/plugins/dynamix.docker.manager/javascript/docker.js')?>"></script>
|
|
<script src="<?autov('/plugins/dynamix.vm.manager/javascript/vmmanager.js')?>"></script>
|
|
|
|
<div class='frame'>
|
|
<div class='grid'>
|
|
<div class='tile' id='tile1'>
|
|
<table id='db_box1' class='dashboard'>
|
|
<tbody class='system'>
|
|
<tr><td><i class='icon-performance f32'></i><div class='section'><?=_var($var,'NAME')?><br>
|
|
<span><?=htmlspecialchars(_var($var,'COMMENT'))?></span><span id="current_time_" class="switch head_time"></span><br></div>
|
|
<a href='/Dashboard/Settings/Identification'><i class='fa fa-fw fa-cog control' title="_(Go to identification settings)_"></i></a><i class='fa fa-fw fa-wrench control tile' onclick='contentMgmt()' title="_(Tile Management)_"></i>
|
|
<span class='ctrl'>
|
|
<?if ($parity||$mover||$btrfs):?>
|
|
<span class='fa fa-fw fa-<?=$started?'stop':'play'?>-circle busy' title="<?=$started?_("Stop the array"):_("Start the array")?>"></span>
|
|
<?else:?>
|
|
<span class='fa fa-fw fa-<?=$started?'stop':'play'?>-circle hand' title="<?=$started?_("Stop the array"):_("Start the array")?>" onclick='<?=$started?'Stop':'Start'?>Array()'></span>
|
|
<?endif;?>
|
|
<?if ($sleep):?><span class='fa fa-fw fa-moon-o hand' title="_(Put system to sleep)_" onclick='Sleep()'></span><?endif;?>
|
|
<span class='fa fa-fw fa-refresh hand' title="_(Reboot the system)_" onclick='Reboot()'></span>
|
|
<span class='fa fa-fw fa-power-off hand' title="_(Shutdown the system)_" onclick='Shutdown()'></span></span>
|
|
</td></tr>
|
|
<tr><td>
|
|
<div class='leftside'>
|
|
<a href="/Settings/DateTime" class="hand none"><span id="current_time"></span></a><br><span id="current_date"></span><br><br>
|
|
<span class='header'><i class='indent fa fa-file-text-o'></i>_(Model)_</span><br><i class='indent'></i><?=htmlspecialchars(_var($var,'SYS_MODEL'))?:'---'?><br><br>
|
|
<span class='header'><i class='indent fa fa-id-badge'></i>_(Registration)_</span><br><i class='indent'></i>Unraid OS <b><em><?=_var($var,'regTy')?></em></b><br><br>
|
|
<span class='header'><i class='indent fa fa-clock-o'></i>_(Uptime)_</span><br><i class='indent'></i><span class='uptime'></span>
|
|
</div>
|
|
<div class='rightside'>
|
|
<span id='casing'>
|
|
<?if ($mycase):?>
|
|
<?if (substr($mycase,-4)!='.png'):?>
|
|
<i id='mycase' class='case-<?=$mycase?>'></i><br>
|
|
<?else:?>
|
|
<img id='mycase' src='<?=autov("/webGui/images/$mycase")?>'><br>
|
|
<?endif;?>
|
|
<?else:?>
|
|
<i id='mycase' class='fa fa-hdd-o'></i><br>
|
|
<?endif;?>
|
|
</span>
|
|
<input type='button' value="_(Edit)_" style="margin-right:0" onclick='openChanges("select_case <?=$myfile?>", "_(Select Case Model)_", "selectcase")'>
|
|
</div>
|
|
</td></tr>
|
|
</tbody>
|
|
|
|
<tbody title="_(Motherboard Information)_">
|
|
<tr><td><i class='icon-motherboard f32'></i><div class='section'>_(Motherboard)_<br><span id='mb-temp'></span><br></div>
|
|
<a href='#' onclick='InfoButton();' title="_(Show Information)_"><i class='fa fa-fw fa-info-circle control'></i></a>
|
|
</td></tr>
|
|
<tr><td><?=$board?><br><?=$bios?><br><?=$biosdate?></td></tr>
|
|
</tbody>
|
|
<?
|
|
$is_intel_cpu = is_intel_cpu();
|
|
$core_types = $is_intel_cpu ? get_intel_core_types() : [];
|
|
?>
|
|
|
|
<tbody title="_(Processor Information)_" data="toggleCPU(true)">
|
|
<tr><td><i class='icon-cpu f32'></i><div class='section'>_(Processor)_<br>
|
|
<span class="head_info"><span id='cpu-temp'></span></span>
|
|
<span class="switch">_(Load)_:<span class="head_bar"><span class='cpu_ load'>0%</span><div class='usage-disk sys'><span id='cpu_'></span><span></span></div></span></span><br></div>
|
|
<a href='/Dashboard/Settings/CPUset' title="_(Go to CPU pinning settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr><td><?=$cpumodel?></td></tr>
|
|
<tr><td><span class='w26'>_(Overall Load)_:</span><span class='w72'><span class='cpu load resize'>0%</span><div class='usage-disk sys'><span id='cpu'></span><span></span></div></span></td></tr>
|
|
<tr id='cpu_main'><td><a onclick='toggleCPU()' title="_(Click to toggle details)_" class='cpu_close'>_(Show details)_</a><span id='chart-toggle'>
|
|
<span><select id='cpuline' class='auto' title="_(Select time frame)_" onchange='changeCPUline(this.value)'>
|
|
<?=mk_option("","10", _("10 s"));?>
|
|
<?=mk_option("","30", _("30 s"));?>
|
|
<?=mk_option("","60", _("1 m"));?>
|
|
<?=mk_option("","120", _("2 m"));?>
|
|
<?=mk_option("","300", _("5 m"));?>
|
|
</select></span><a onclick='toggleChart()' title="_(Click to toggle CPU chart)_"><span class="fa fa-fw fa-bar-chart hand"></span></a></span></td></tr>
|
|
|
|
<?
|
|
foreach ($cpus as $pair) {
|
|
[$cpu1, $cpu2] = my_preg_split('/[,-]/',$pair);
|
|
echo "<tr class='cpu_open'>";
|
|
if ($is_intel_cpu && count($core_types) > 0) $core_type = "({$core_types[$cpu1]})"; else $core_type = "";
|
|
if ($cpu2)
|
|
echo "<td><span class='w26'>CPU $cpu1 $core_type - HT $cpu2 </span><span class='dashboard w36'><span class='cpu$cpu1 load resize'>0%</span><div class='usage-disk sys'><span id='cpu$cpu1'></span><span></span></div></span><span class='dashboard w36'><span class='cpu$cpu2 load resize'>0%</span><div class='usage-disk sys'><span id='cpu$cpu2'></span><span></span></div></span></td>";
|
|
else
|
|
echo "<td><span class='w26'>CPU $cpu1 $core_type</span><span class='w72'><span class='cpu$cpu1 load resize'>0%</span><div class='usage-disk sys'><span id='cpu$cpu1'></span><span></span></div></span></td>";
|
|
echo "</tr>";
|
|
}
|
|
?>
|
|
<tr id='cpu_chart'><td><div id='cpuchart'></div></td></tr>
|
|
</tbody>
|
|
|
|
<tbody title="_(Memory Utilization)_">
|
|
<tr><td><i class='icon-ram f32'></i><div class='section'>_(System)_<br>
|
|
<span class="head_info"><span><i class='ups fa fa-line-chart'></i>_(Memory)_: <?="$memory_installed $unit $memory_type $ecc"?></span></span>
|
|
<span class="switch">_(RAM)_:<span class="head_bar"><span class='sys0_ load'>0%</span><div class='usage-disk sys'><span id='sys0_'></span><span></span></div></span></span><br></div>
|
|
<a href='/Dashboard/Tools/Processes' title="_(View Running Processes)_"><i class='fa fa-fw fa-info-circle control'></i></a>
|
|
</td></tr><tr><td>
|
|
<span class='w26'><i class='ups fa fa-compress'></i>_(Usable size)_: <?=$ramsize?><br><i class='ups fa fa-expand'></i>_(Maximum size)_: <?="$memory_maximum $unit"?><?=$low?'*':''?></span>
|
|
<span class='w18 center static'><a class='info hand none'>_(RAM usage)_<span>_(Percent of total used memory)_ (<?=$ramsize?>)</span></a></span>
|
|
<span class='w18 center static'><a class='info hand none'>_(Flash device)_<span>_(Percent usage of flash usb device)_ (<?=$flashsize?>)</span></a></span>
|
|
<span class='w18 center static'><a class='info hand none'>_(Log filesystem)_<span>_(Percent usage of LOG file system)_ (<?=$logsize?>)</span></a></span>
|
|
<span class='w18 center static'><a class='info hand none'><?=$vdisk?><span><?=_("Percent usage of $vdisk")?> (<?=$dockersize?>)</span></a></span>
|
|
</td></tr><tr><td>
|
|
<span class='w26'><legend>_(Legend)_</legend><span id='dynamic'></span></span>
|
|
<span class='w18 center'><div class='pie' id='sys0'><span class='sys0'></span><span class='var0'></span></div></span>
|
|
<span class='w18 center'><div class='pie' id='sys1'><span class='sys1'></span><span class='var1'></span></div></span>
|
|
<span class='w18 center'><div class='pie' id='sys2'><span class='sys2'></span><span class='var2'></span></div></span>
|
|
<span class='w18 center'><div class='pie' id='sys3'><span class='sys3'></span><span class='var3'></span></div></span>
|
|
</td></tr>
|
|
</tbody>
|
|
|
|
<tbody title="_(Interface Information)_" class="mixed">
|
|
<tr><td><i class='icon-ethernet f32'></i><div class='section'>_(Interface)_
|
|
<span class="head_gap"><i class='ups fa fa-angle-double-right'></i><select name="port_select" onchange="portSelect(this.value)">
|
|
<?foreach ($ports as $port):?>
|
|
<?=mk_option("",$port,_($port))?>
|
|
<?endforeach;?>
|
|
</select></span><br>
|
|
<span class='head_info'><i class='ups fa fa-angle-double-down'></i>_(Inbound)_: <span id='inbound'>---</span></span><span><i class='ups fa fa-angle-double-up'></i>_(Outbound)_: <span id='outbound'>---</span></span><br></div>
|
|
<a href='/Dashboard/Settings/NetworkSettings' title="_(Go to network settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr><td><span class='w26'><select name="enter_view" onchange="changeView(this.value)">
|
|
<?=mk_option("", "0", _("General info"))?>
|
|
<?=mk_option("", "1", _("Counters info"))?>
|
|
<?=mk_option("", "2", _("Errors info"))?>
|
|
<?=mk_option("", "3", _("Network traffic"))?>
|
|
</select></span>
|
|
<span class='w36'><i class='view1'>_(Mode of operation)_</i><i class='view2'>_(Received packets)_</i><i class='view3'>_(Receive counters)_</i><i class='fa fa-fw fa-arrow-down view4 red-text'></i> <i class='view4 red-text'>_(Inbound)_</i></span>
|
|
<span class='w36'><i class='view1'></i><i class='view2'>_(Transmitted packets)_</i><i class='view3'>_(Transmit counters)_</i><i class='fa fa-fw fa-arrow-up view4 orange-text'></i> <i class='view4 orange-text'>_(Outbound)_</i>
|
|
<span class='view4' style='float:right'><select id='netline' class='auto' title="_(Select time frame)_" onchange='changeNetline(this.value)'>
|
|
<?=mk_option("","10", _("10 s"))?>
|
|
<?=mk_option("","30", _("30 s"))?>
|
|
<?=mk_option("","60", _("1 m"))?>
|
|
<?=mk_option("","120", _("2 m"))?>
|
|
<?=mk_option("","300", _("5 m"))?>
|
|
</select></span></span></td></tr>
|
|
<?
|
|
$c = 0;
|
|
foreach ($ports as $port) {
|
|
$last = $port=='lo' ? ' last' : '';
|
|
echo "<tr class='view1{$last}'><td><span class='w26'>$port</span><span class='w72' id='main".($c++)."'></span></td></tr>";
|
|
}
|
|
$c = 0;
|
|
foreach ($ports as $port) {
|
|
$last = $port=='lo' ? ' last' : '';
|
|
echo "<tr class='view2{$last}'><td><span class='w26'>$port</span><span class='w36' id='port{$c}'></span><span class='w36' id='port".($c+1)."'></span></td></tr>";
|
|
$c += 2;
|
|
}
|
|
$c = 0;
|
|
foreach ($ports as $port) {
|
|
$last = $port=='lo' ? ' last' : '';
|
|
echo "<tr class='view3{$last}'><td><span class='w26'>$port</span><span class='w36' id='link{$c}'></span><span class='w36' id='link".($c+1)."'></span></td></tr>";
|
|
$c += 2;
|
|
}
|
|
?>
|
|
<tr class="view4"><td><div id="netchart"></div></td></tr>
|
|
</tbody>
|
|
|
|
<?if ($wireguard):?>
|
|
<tbody title="_(VPN Connections)_">
|
|
<tr><td><i class='icon-vpn f32'></i><div class='section'>_(VPN)_<br><span><span class='head_info'><i class='ups fa fa-play-circle'></i>_(Active tunnels)_: <span id='vpn-active'><?=$up?></span></span><i class='ups fa fa-pause-circle'></i>_(Inactive tunnels)_: <span id='vpn-inactive'><?=$down?></span></span><br></div>
|
|
<a href='/Settings/VPNmanager' title="_(Go to VPN settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<?foreach ($conf as $wg):?>
|
|
<?$vpn = basename($wg,'.conf'); $peers = vpn_peers($wg);?>
|
|
<tr><td class='vpn'><span class='w26'><i class='icon-vpn vpn<?=in_array($vpn,$wg_up)?'':' inactive'?>' onclick="toggleVPN($(this),'<?=$vpn?>')" title="Toggle tunnel state"></i><?="Tunnel $vpn"?></span>
|
|
<span class='w36 vpn right'>_(Activity)_</span><span class='w36 vpn right'>_(Handshake)_</span></td></tr>
|
|
<?foreach ($peers as $i => $peer):?>
|
|
<tr><td><span class='w26 wg1'><?=$peer?></span><span class='w36 wg2' id='<?="$vpn-rx-".($i-1)?>'>---</span><span class='w36 wg2' id='<?="$vpn-hs-".($i-1)?>'>_(inactive)_</span></td></tr>
|
|
<?endforeach;?>
|
|
<?endforeach;?>
|
|
</tbody>
|
|
<?endif;?>
|
|
|
|
<?if ($apcupsd):?>
|
|
<tbody title="_(Power Status)_">
|
|
<tr><td><i class='icon-ups f32'></i><div class='section'>_(Power)_<span class='switch head_gap' id='ups_status_'></span><br>
|
|
<span class="head_info"><span><i class='ups fa fa-bar-chart'></i>_(UPS Model)_: </span><span id='ups_model'></span></span>
|
|
<span class="switch"><span>_(Load)_:</span><span class="head_gap" id='ups_loadpct_'></span></span></span><br></div>
|
|
<a href='/Dashboard/Settings/UPSsettings' title="_(Go to UPS settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr><td><span class='w36'><i class='ups fa fa-fw fa-plug'></i>_(UPS status)_:</span><span id='ups_status'></span></td></tr>
|
|
<tr><td><span class='w36'><i class='ups fa fa-fw fa-bars'></i>_(UPS Load)_: </span><span id='ups_loadpct'></span></td></tr>
|
|
<tr><td><span class='w36'><i class='ups fa fa-fw fa-battery'></i>_(Battery charge)_:</span><span id='ups_bcharge'></span></td></tr>
|
|
<tr><td><span class='w36'><i class='ups fa fa-fw fa-clock-o'></i>_(Runtime left)_:</span><span id='ups_timeleft'></span></td></tr>
|
|
<tr><td><span class='w36'><i class='ups fa fa-fw fa-bolt'></i>_(Nominal power)_:</span><span id='ups_nompower'></span></td></tr>
|
|
<tr><td><span class='w36'><i class='ups fa fa-fw fa-ellipsis-h'></i>_(Output voltage)_:</span><span id='ups_outputv'></span></td></tr>
|
|
</tbody>
|
|
<?endif;?>
|
|
|
|
<?if ($fans):?>
|
|
<tbody title="_(Fan Information)_">
|
|
<tr><td><i class='icon-fan f32'></i><div class='section'>_(Airflow)_<br><span><i class='ups fa fa-sort-amount-asc'></i>_(Fan count)_: <?=$fans?></span><br></div>
|
|
|
|
<?if ($autofan):?>
|
|
<a href='/Dashboard/Settings/FanSettings' title="_(Go to fan settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
<?endif;?>
|
|
</td></tr>
|
|
<?
|
|
$label = $value = [];
|
|
$i = 0;
|
|
for ($fan=0; $fan<$fans; $fan++) {
|
|
if ($fan > 0 && $fan % 3 == 0) $i++;
|
|
$class = $fan % 3 == 2 ? "" : " class='fan'";
|
|
$label[$i][] = "<span{$class}>"._('FAN')." ".($fan+1)."</span>";
|
|
}
|
|
$i = 0;
|
|
for ($fan=0; $fan<$fans; $fan++) {
|
|
if ($fan > 0 && $fan % 3 == 0) $i++;
|
|
$class = $fan % 3 == 2 ? "" : " class='fan'";
|
|
$value[$i][] = "<span{$class} id='fan$fan'>--</span>";
|
|
}
|
|
echo "<tr><td>";
|
|
for ($i = 0; $i < count($label); $i++) {
|
|
foreach ($label[$i] as $data) echo $data;
|
|
echo "<br>";
|
|
foreach ($value[$i] as $data) echo $data;
|
|
echo "<br>";
|
|
if ($i < count($value)-1) echo "<br>";
|
|
}
|
|
echo "</td></tr>";
|
|
?>
|
|
</tbody>
|
|
<?endif;?>
|
|
<?customTiles('column1');?>
|
|
</table>
|
|
</div>
|
|
|
|
<div class='tile' id='tile2'>
|
|
<table id='db_box2' class='dashboard'>
|
|
<?if ($dockerd):?>
|
|
<tbody id='docker_view' title="_(Docker Containers)_" data="noApps()">
|
|
<tr><td><i class='icon-docker f32'></i><div class='section'>_(Docker Containers)_<br>
|
|
<span class='apps button'><input type='checkbox' id='apps'></span>
|
|
<span class='apps switch'></span><br></div>
|
|
<a href='/Dashboard/Settings/DockerSettings' title="_(Go to Docker settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
</tbody>
|
|
<?endif;?>
|
|
<?if ($libvirtd):?>
|
|
<tbody id='vm_view' title="_(Virtual Machines)_" data="noVMs()">
|
|
<tr><td><i class='icon-virtualization f32'></i><div class='section'>_(Virtual Machines)_<br>
|
|
<span class='vms button'><input type='checkbox' id='vms'></span>
|
|
<span class='vms switch'></span><br></div>
|
|
<a href='/Dashboard/Settings/VMSettings' title="_(Go to VM settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
</tbody>
|
|
<?if ($vmusage == "Y"):?>
|
|
<tbody id='vm_view_usage' title="_(Virtual Machines Usage)_" >
|
|
<tr><td><i class='icon-virtualization f32'></i><div class='section'>_(Virtual Machines Usage)_</div>
|
|
<a href='/Dashboard/Settings/VMSettings' title="_(Go to VM settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
</tbody>
|
|
<?endif;?>
|
|
<?endif;?>
|
|
|
|
<tbody title="_(Shares Information)_"<?if ($group):?> class="mixed"<?endif;?>>
|
|
<tr><td><i class='icon-folder f32'></i><div class='section'>_(Shares)_
|
|
<?if ($group):?>
|
|
<span class="head_gap"><i class='ups fa fa-angle-double-right'></i><select name="enter_share" onchange="changeMode(this.value)">
|
|
<?if (_var($var,'shareSMBEnabled')=='yes'):?>
|
|
<?=mk_option("", "0", "SMB")?>
|
|
<?endif;?>
|
|
<?if (_var($var,'shareNFSEnabled')=='yes'):?>
|
|
<?=mk_option("", "2", "NFS")?>
|
|
<?endif;?>
|
|
</select></span>
|
|
<?endif;?>
|
|
<br><span>
|
|
<?=sprintf(_("Share count: %s with %s public SMB and %s public NFS"),count($shares),$SMBpublic,$NFSpublic)?>
|
|
</span><br></div>
|
|
<a href='/Shares' title="_(Go to Share settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr class='header'><td><span class='w26'>_(Name)_</span><span class='w44'>_(Description)_</span><span class='w18'>_(Security)_</span><span>_(Streams)_</span></td></tr>
|
|
<?
|
|
if (_var($var,'shareSMBEnabled')=='yes') {
|
|
$i = 0;
|
|
foreach ($shares as $name => $share) {
|
|
$list = "<a href=\"/Dashboard/Shares/".(isset($share['diskexport']) ? "Disk" : "Share")."?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
|
|
$comment = $share['comment'] ?: '-';
|
|
$security = export_settings(_var($var,'shareSMBEnabled'), $sec[$name]);
|
|
$last = $name==array_key_last($shares) ? ' last' : '';
|
|
echo "<tr class='smb share share1{$last}'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>".htmlspecialchars($comment)."</span><span class='w18'>$security</span><span id='share",$i++,"'>0</span></td></tr>";
|
|
}
|
|
if (!count($shares)) echo "<tr class='smb share share1'><td class='none'>"._("No shares present")."</td></tr>";
|
|
}
|
|
if (_var($var,'shareNFSEnabled')=='yes') {
|
|
foreach ($shares as $name => $share) {
|
|
if ( ! isset($sec_nfs[$name]) ) continue;
|
|
$list = "<a href=\"/Dashboard/Shares/".(isset($share['diskexport']) ? "Disk" : "Share")."?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
|
|
$comment = $share['comment'] ?: '-';
|
|
$security = export_settings(_var($var,'shareNFSEnabled'), $sec_nfs[$name]);
|
|
$last = $name==array_key_last($shares) ? ' last' : '';
|
|
echo "<tr class='nfs share share3{$last}'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>".htmlspecialchars($comment)."</span><span class='w18'>$security</span><span>-</span></td></tr>";
|
|
}
|
|
if (!count($shares)) echo "<tr class='nfs share share3'><td class='none'>"._("No shares present")."</td></tr>";
|
|
}
|
|
if (!$group) {
|
|
foreach ($shares as $name => $share) {
|
|
$list = "<a href=\"/Dashboard/Shares/".(isset($share['diskexport']) ? "Disk" : "Share")."?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
|
|
$comment = $share['comment'] ?: '-';
|
|
echo "<tr class='share'><td><span class='w26'><i class='icon-folder f14'></i>$list</span><span class='w44'>".htmlspecialchars($comment)."</span><span class='w18'>-</span><span>-</span></td></tr>";
|
|
}
|
|
if (!count($shares)) echo "<tr class='share'><td class='none'>"._("No shares present")."</td></tr>";
|
|
}
|
|
?>
|
|
</tbody>
|
|
|
|
<tbody title="_(Users Information)_"<?if ($group):?> class="mixed"<?endif;?>>
|
|
<tr><td><i class='icon-users f32'></i><div class='section'>_(Users)_
|
|
<?if ($group):?>
|
|
<span class="head_gap"><i class='ups fa fa-angle-double-right unused'></i><select name="enter_user" class="unused">
|
|
<?if (_var($var,'shareSMBEnabled')=='yes'):?>
|
|
<?=mk_option("", "0", "SMB")?>
|
|
<?endif;?>
|
|
<?if (_var($var,'shareNFSEnabled')=='yes'):?>
|
|
<?=mk_option("", "2", "NFS")?>
|
|
<?endif;?>
|
|
</select></span>
|
|
<?endif;?>
|
|
<br><span>
|
|
<?=sprintf(_("User count: %s with %s unprotected"),count($users),$nopass)?>
|
|
</span><br></div>
|
|
<a href='/Users' title="_(Go to User settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr class='header'><td><span class='w26'>_(Name)_</span><span class='w44'>_(Description)_</span><span class='w18'>_(Write)_</span><span>_(Read)_</span></td></tr>
|
|
<?
|
|
if (_var($var,'shareSMBEnabled')=='yes') {
|
|
foreach ($users as $user) {
|
|
$name = $user['name'];
|
|
$list = "<a href=\"/Dashboard/Users/UserEdit?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
|
|
$desc = $user['desc'] ?: '-';
|
|
if ($name=='root') {
|
|
$write = $read = '-';
|
|
} else {
|
|
$write = $read = 0;
|
|
foreach ($shares as $share) {
|
|
$access = $sec[$share['name']];
|
|
if ($access['export']=='-') continue;
|
|
switch ($access['security']) {
|
|
case 'public':
|
|
$write++;
|
|
$read++;
|
|
break;
|
|
case 'secure':
|
|
if (in_array($name,explode(',',$access['writeList']))) {$write++; $read++;} else $read++;
|
|
break;
|
|
case 'private':
|
|
if (in_array($name,explode(',',$access['writeList']))) {$write++; $read++;}
|
|
if (in_array($name,explode(',',$access['readList']))) $read++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ($user['passwd']!='yes') $list = str_replace('blue-text','orange-text',$list);
|
|
$last = $name==array_key_last($users) ? ' last' : '';
|
|
echo "<tr class='smb user user1{$last}'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>".htmlspecialchars($desc)."</span><span class='w18'>$write</span><span>$read</span></td></tr>";
|
|
}
|
|
}
|
|
if (_var($var,'shareNFSEnabled')=='yes') {
|
|
foreach ($users as $user) {
|
|
$name = $user['name'];
|
|
$list = "<a href=\"/Dashboard/Users/UserEdit?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
|
|
$desc = $user['desc'] ?: '-';
|
|
$write = '-'; $read = '-';
|
|
if ($user['passwd']!='yes') $list = str_replace('blue-text','orange-text',$list);
|
|
$last = $name==array_key_last($users) ? ' last' : '';
|
|
echo "<tr class='nfs user user3{$last}'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>".htmlspecialchars($desc)."</span><span class='w18'>$write</span><span>$read</span></td></tr>";
|
|
}
|
|
}
|
|
if (!$group) {
|
|
foreach ($users as $user) {
|
|
$name = $user['name'];
|
|
$list = "<a href=\"/Dashboard/Users/UserEdit?name=".urlencode($name)."\" class=\"blue-text\" title=\"$name settings\">$name</a>";
|
|
$desc = $user['desc'] ?: '-';
|
|
if ($user['passwd']!='yes') $list = str_replace('blue-text','orange-text',$list);
|
|
echo "<tr class='user'><td><span class='w26'><i class='icon-user f14'></i>$list</span><span class='w44'>".htmlspecialchars($desc)."</span><span class='w18'>-</span><span>-</span></td></tr>";
|
|
}
|
|
}
|
|
?>
|
|
</tbody>
|
|
<?customTiles('column2');?>
|
|
</table>
|
|
</div>
|
|
|
|
<div class='tile' id='tile3'>
|
|
<table id='db_box3' class='dashboard'>
|
|
<?if (!$poolsOnly):?>
|
|
<tbody title="_(Parity Information)_">
|
|
<tr><td><i class='icon-health f32'></i><div class='section'>_(Parity)_<br>
|
|
<span class='parity'></span><br></div>
|
|
<a href='/Dashboard/Settings/Scheduler' title="_(Go to scheduler settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr><td id='parity' class="wrap"></td></tr>
|
|
<tr><td id='program' class="wrap"></td></tr>
|
|
</tbody>
|
|
|
|
<?$power = _var($display,'power') && in_array('nvme',array_column(main_filter($disks),'transport')) ? ' / '._('Power') : '';?>
|
|
<tbody id='array_list' title="_(Array Information)_">
|
|
<tr><td><i class='icon-disks f32'></i><div class='section'>_(Array)_<?if (!$started):?> (_(stopped)_)<?endif;?><br>
|
|
<span><?if ($started):?><?=sprintf(_("%s used of %s (%s %%)"),my_scale($array_used*1024,$unit)." $unit",my_scale($array_size*1024,$unit,-1,-1)." $unit",$array_percent)?><?endif;?></span><br></div>
|
|
<a href='/Dashboard/Settings/DiskSettings' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr><td id='array_info'></td></tr>
|
|
<tr class='header'><td><span class='w26'>_(Device)_</span><span class='w18'>_(Status)_</span><span class='w18'>_(Temp)_<?=$power?></span><span class='w18'>_(SMART)_</span><span class='w18'>_(Utilization)_</span></td></tr>
|
|
</tbody>
|
|
<?endif;?>
|
|
|
|
<?$i=0?>
|
|
<?foreach ($pools as $pool):
|
|
$cache = array_filter(cache_filter($disks),function($disk) use ($pool){return prefix($disk['name'])==$pool;});
|
|
$power = _var($display,'power') && in_array('nvme',array_column($cache,'transport')) ? ' / '._('Power') : '';
|
|
?>
|
|
<tbody id='pool_list<?=$i?>' title="_(<?=ucfirst($pool)?> Information)_">
|
|
<tr><td><i class='icon-disk f32'></i><div class='section'><?=_(native($pool),3).($started ? '' : ' ('._('stopped').')')?><br>
|
|
<span><?if ($started):?><?=sprintf(_("%s used of %s (%s %%)"),my_scale($cache_used[$pool]*1024,$unit)." $unit",my_scale($cache_size[$pool]*1024,$unit,-1,-1)." $unit",$cache_rate[$pool])?><?endif;?></span><br></div>
|
|
<a href='/Dashboard/Settings/Device?name=<?=$pool?>' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr><td id='pool_info<?=$i++?>'></td></tr>
|
|
<tr class='header'><td><span class='w26'>_(Device)_</span><span class='w18'>_(Status)_</span><span class='w18'>_(Temp)_<?=$power?></span><span class='w18'>_(SMART)_</span><span class='w18'>_(Utilization)_</span></td></tr>
|
|
</tbody>
|
|
<?endforeach;?>
|
|
|
|
<?if ($devs):?>
|
|
<?$power = _var($display,'power') && in_array('nvme',array_column($devs,'transport')) ? ' / '._('Power') : '';?>
|
|
<tbody id='devs_list' title="_(Unassigned Devices)_">
|
|
<tr><td><i class='icon-disc f32'></i><div class='section'>_(Unassigned)_<?if (!$started):?> (_(stopped)_)<?endif;?><br>
|
|
<span></span><br></div>
|
|
<a href='/Dashboard/Settings/DiskSettings' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
|
</td></tr>
|
|
<tr><td id='devs_info'></td></tr>
|
|
<tr class='header'><td><span class='w26'>_(Device)_</span><span class='w18'>_(Status)_</span><span class='w18'>_(Temp)_<?=$power?></span><span class='w18'>_(SMART)_</span><span class='w18'>_(Utilization)_</span></td></tr>
|
|
</tbody>
|
|
<?endif;?>
|
|
<?customTiles('column3');?>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form name='boot' method='POST' action='/webGui/include/Boot.php'>
|
|
<input type='hidden' name='cmd' value=''>
|
|
</form>
|
|
|
|
<div id="iframe-popup"></div>
|
|
|
|
<div id="templateContentMgmt" class="template">
|
|
<!--!
|
|
<style>
|
|
.item{display:inline-block;width:210px;float:left;height:4rem}
|
|
</style>
|
|
<script>
|
|
var table = $('table.dashboard');
|
|
var index = [], sort = [], checked = [];
|
|
table.find('tbody').not('.system').each(function(){
|
|
index.push($(this).attr('title'));
|
|
sort.push($(this).attr('sort'));
|
|
checked.push($(this).is(':visible') ? 'checked' : '');
|
|
});
|
|
for (let n=0,x; x=index[n]; n++) {
|
|
$('div#list').append("<span class='item'><input class='checker' type='checkbox' "+checked[n]+">"+x+"</span>");
|
|
}
|
|
function hideShow() {
|
|
let n = 0, inactive = [];
|
|
var count = {'db_box1':0, 'db_box2':0, 'db_box3':0};
|
|
$('input.checker').each(function(){
|
|
var tbody = $('table.dashboard').find('tbody[sort="'+sort[n]+'"]');
|
|
var id = tbody.parent().prop('id');
|
|
if ($(this).prop('checked')) {
|
|
tbody.show();
|
|
tbody.prev().show();
|
|
count[id]++;
|
|
} else {
|
|
tbody.hide();
|
|
tbody.prev().hide();
|
|
inactive.push(sort[n]);
|
|
}
|
|
n++;
|
|
});
|
|
count[table.find('tbody.system').parent().prop('id')]++;
|
|
if (count['db_box1']>0) $('div#tile1').show(); else $('div#tile1').hide();
|
|
if (count['db_box2']>0) $('div#tile2').show(); else $('div#tile2').hide();
|
|
if (count['db_box3']>0) $('div#tile3').show(); else $('div#tile3').hide();
|
|
if (inactive.length>0) {
|
|
cookie.inactive_content = inactive.join(';');
|
|
} else {
|
|
delete cookie.inactive_content;
|
|
}
|
|
saveCookie();
|
|
}
|
|
</script>
|
|
<div id="list"></div>
|
|
!-->
|
|
</div>
|
|
|
|
<div id="templateClone" class="template">
|
|
<table class="snapshot">
|
|
<tr><td>_(VM Being Cloned)_:</td><td><span id="VMBeingCloned"></span></td></tr>
|
|
<tr><td>_(New VM)_:</td><td><input type="text" id="target" autocomplete="off" spellcheck="false" value="" onclick="this.select()"></td></tr>
|
|
<tr><td>_(Overwrite)_:</td><td><input type="checkbox" id="Overwrite" value="" ></td></tr>
|
|
<tr hidden><td>_(Start Cloned VM)_:</td><td><input type="checkbox" id="Start" value="" ></td></tr>
|
|
<tr hidden><td>_(Edit VM after clone)_:</td><td><input type="checkbox" id="Edit" value="" ></td></tr>
|
|
<tr><td>_(Check free space)_:</td><td><input type="checkbox" id="Free" value="" ></td></tr>
|
|
</table>
|
|
</div>
|
|
|
|
<div id="templatesnapshotcreate" class="template">
|
|
<table id="snapshot" class="snapshot">
|
|
<tr><td>_(VM Name)_:</td><td><label id="VMName"></label></td></tr>
|
|
<tr><td>_(Snapshot Name)_:</td><td><input type="text" id="targetsnap" autocomplete="off" spellcheck="false" value="--generate" onclick="this.select()">_(Check free space)_:<input type="checkbox" id="targetsnapfspc" checked></td></tr>
|
|
<tr><td>_(Description)_:</td><td><input type="text" id="targetsnapdesc" autocomplete="off" spellcheck="false" value="" onclick="this.select()"></td></tr>
|
|
<tr id="memoryline"><td>_(Memory dump)_:</td><td><input type="checkbox" id="targetsnapmem" checked></td></tr>
|
|
<tr id="fstypeline"><td>_(FS Native Snapshot)_:</td><td><label id="fstype"></label><input type="checkbox" id="targetsnapfstype">_(Unchecked will use QEMU External Snapshot)_</td></tr>
|
|
</table>
|
|
</div>
|
|
|
|
<script>
|
|
Number.prototype.pad = function(size){var s=String(this);while(s.length<(size||2)){s='0'+s;}return s;}
|
|
Array.prototype.tail = function(t){return this.slice(-t).map(function(o){return o.y;}).join(';');}
|
|
String.prototype.build = function(){return this.replace(/\n(<!--!|!-->)\n/g,'');}
|
|
jQuery.prototype.alive = function(width,color){return this.finish().animate({width:width},{step:function(){$(this).css({'overflow':'visible'}).removeClass().addClass(color);}});}
|
|
String.prototype.md5 = function(){
|
|
// Original copyright (c) Paul Johnston & Greg Holt.
|
|
var hc = '0123456789abcdef';
|
|
function rh(n){var j,s='';for (j=0;j<=3;j++) s+=hc.charAt((n>>(j*8+4))&0x0F)+hc.charAt((n>>(j*8))&0x0F);return s;}
|
|
function ad(x,y){var l=(x&0xFFFF)+(y&0xFFFF);var m=(x>>16)+(y>>16)+(l>>16);return (m<<16)|(l&0xFFFF);}
|
|
function rl(n,c){return (n<<c)|(n>>>(32-c));}
|
|
function cm(q,a,b,x,s,t){return ad(rl(ad(ad(a,q),ad(x,t)),s),b);}
|
|
function ff(a,b,c,d,x,s,t){return cm((b&c)|((~b)&d),a,b,x,s,t);}
|
|
function gg(a,b,c,d,x,s,t){return cm((b&d)|(c&(~d)),a,b,x,s,t);}
|
|
function hh(a,b,c,d,x,s,t){return cm(b^c^d,a,b,x,s,t);}
|
|
function ii(a,b,c,d,x,s,t){return cm(c^(b|(~d)),a,b,x,s,t);}
|
|
function sb(x) {
|
|
var i;var nblk=((x.length+8)>>6)+1;var blks=new Array(nblk*16);for (i=0;i<nblk*16;i++) blks[i]=0;
|
|
for (i=0;i<x.length;i++) blks[i>>2]|=x.charCodeAt(i)<<((i%4)*8);
|
|
blks[i>>2]|=0x80<<((i%4)*8);blks[nblk*16-2]=x.length*8;return blks;
|
|
}
|
|
var i,x=sb(''+this),a=1732584193,b=-271733879,c=-1732584194,d=271733878,olda,oldb,oldc,oldd;
|
|
for (i=0;i<x.length;i+=16) {olda=a;oldb=b;oldc=c;oldd=d;
|
|
a=ff(a,b,c,d,x[i+ 0], 7, -680876936);d=ff(d,a,b,c,x[i+ 1],12, -389564586);c=ff(c,d,a,b,x[i+ 2],17, 606105819);
|
|
b=ff(b,c,d,a,x[i+ 3],22,-1044525330);a=ff(a,b,c,d,x[i+ 4], 7, -176418897);d=ff(d,a,b,c,x[i+ 5],12, 1200080426);
|
|
c=ff(c,d,a,b,x[i+ 6],17,-1473231341);b=ff(b,c,d,a,x[i+ 7],22, -45705983);a=ff(a,b,c,d,x[i+ 8], 7, 1770035416);
|
|
d=ff(d,a,b,c,x[i+ 9],12,-1958414417);c=ff(c,d,a,b,x[i+10],17, -42063);b=ff(b,c,d,a,x[i+11],22,-1990404162);
|
|
a=ff(a,b,c,d,x[i+12], 7, 1804603682);d=ff(d,a,b,c,x[i+13],12, -40341101);c=ff(c,d,a,b,x[i+14],17,-1502002290);
|
|
b=ff(b,c,d,a,x[i+15],22, 1236535329);a=gg(a,b,c,d,x[i+ 1], 5, -165796510);d=gg(d,a,b,c,x[i+ 6], 9,-1069501632);
|
|
c=gg(c,d,a,b,x[i+11],14, 643717713);b=gg(b,c,d,a,x[i+ 0],20, -373897302);a=gg(a,b,c,d,x[i+ 5], 5, -701558691);
|
|
d=gg(d,a,b,c,x[i+10], 9, 38016083);c=gg(c,d,a,b,x[i+15],14, -660478335);b=gg(b,c,d,a,x[i+ 4],20, -405537848);
|
|
a=gg(a,b,c,d,x[i+ 9], 5, 568446438);d=gg(d,a,b,c,x[i+14], 9,-1019803690);c=gg(c,d,a,b,x[i+ 3],14, -187363961);
|
|
b=gg(b,c,d,a,x[i+ 8],20, 1163531501);a=gg(a,b,c,d,x[i+13], 5,-1444681467);d=gg(d,a,b,c,x[i+ 2], 9, -51403784);
|
|
c=gg(c,d,a,b,x[i+ 7],14, 1735328473);b=gg(b,c,d,a,x[i+12],20,-1926607734);a=hh(a,b,c,d,x[i+ 5], 4, -378558);
|
|
d=hh(d,a,b,c,x[i+ 8],11,-2022574463);c=hh(c,d,a,b,x[i+11],16, 1839030562);b=hh(b,c,d,a,x[i+14],23, -35309556);
|
|
a=hh(a,b,c,d,x[i+ 1], 4,-1530992060);d=hh(d,a,b,c,x[i+ 4],11, 1272893353);c=hh(c,d,a,b,x[i+ 7],16, -155497632);
|
|
b=hh(b,c,d,a,x[i+10],23,-1094730640);a=hh(a,b,c,d,x[i+13], 4, 681279174);d=hh(d,a,b,c,x[i+ 0],11, -358537222);
|
|
c=hh(c,d,a,b,x[i+ 3],16, -722521979);b=hh(b,c,d,a,x[i+ 6],23, 76029189);a=hh(a,b,c,d,x[i+ 9], 4, -640364487);
|
|
d=hh(d,a,b,c,x[i+12],11, -421815835);c=hh(c,d,a,b,x[i+15],16, 530742520);b=hh(b,c,d,a,x[i+ 2],23, -995338651);
|
|
a=ii(a,b,c,d,x[i+ 0], 6, -198630844);d=ii(d,a,b,c,x[i+ 7],10, 1126891415);c=ii(c,d,a,b,x[i+14],15,-1416354905);
|
|
b=ii(b,c,d,a,x[i+ 5],21, -57434055);a=ii(a,b,c,d,x[i+12], 6, 1700485571);d=ii(d,a,b,c,x[i+ 3],10,-1894986606);
|
|
c=ii(c,d,a,b,x[i+10],15, -1051523);b=ii(b,c,d,a,x[i+ 1],21,-2054922799);a=ii(a,b,c,d,x[i+ 8], 6, 1873313359);
|
|
d=ii(d,a,b,c,x[i+15],10, -30611744);c=ii(c,d,a,b,x[i+ 6],15,-1560198380);b=ii(b,c,d,a,x[i+13],21, 1309151649);
|
|
a=ii(a,b,c,d,x[i+ 4], 6, -145523070);d=ii(d,a,b,c,x[i+11],10,-1120210379);c=ii(c,d,a,b,x[i+ 2],15, 718787259);
|
|
b=ii(b,c,d,a,x[i+ 9],21, -343485551);a=ad(a,olda);b=ad(b,oldb);c=ad(c,oldc);d=ad(d,oldd);
|
|
}
|
|
return rh(a)+rh(b)+rh(c)+rh(d);
|
|
}
|
|
jQuery.prototype.hideMe = function() {
|
|
var hidden = cookie.hidden_content;
|
|
hidden = hidden ? hidden.split(';') : [];
|
|
if (hidden.indexOf(this.attr('sort'))>=0) this.find('tr:gt(0)').hide();
|
|
}
|
|
jQuery.prototype.mixedView = function(s) {
|
|
if (s==0) {
|
|
this.find('tr:gt(0)').hide();
|
|
this.find('span.switch').show();
|
|
this.find('span.button').hide();
|
|
return;
|
|
}
|
|
this.find('tr:gt(0)').show();
|
|
this.find('span.switch').hide();
|
|
this.find('span.button').show();
|
|
if (this.attr('data')) {
|
|
setTimeout(this.attr('data'));
|
|
}
|
|
if (this.hasClass('mixed')) {
|
|
var select = this.find('select[name^="enter"]');
|
|
select = parseInt(select.val())+1;
|
|
this.find('tr:gt(0)').each(function(){
|
|
var names = ($(this).attr('class')||'').split(' ');
|
|
for (let n=0,name; name=names[n]; n++) if (/[0-9]/.test(name.slice(-1)) && name.slice(-1)!=select) $(this).hide();
|
|
});
|
|
}
|
|
}
|
|
|
|
<?
|
|
$cookie_content = @file_get_contents($cookie);
|
|
if ( @json_decode($cookie_content,true) ):?>
|
|
var cookie = JSON.parse('<?=trim($cookie_content);?>');
|
|
<?else:?>
|
|
var cookie = {};
|
|
<?endif;?>
|
|
var colors = ['<?=$c0?>','<?=$c1?>','#d77e0d','#d4ac0d','#cd5c5c','#ffc0cb','#e6e6fa','#9370db','#7cfc00','#228b22','#00ffff','#4682b4'];
|
|
var blue = '#486dba'; // fallback color when too many graph elements exist
|
|
var ports = [<?=implode(',',array_map('escapestring',$ports))?>];
|
|
var cpu = [];
|
|
var rxd = [];
|
|
var txd = [];
|
|
var cputime = 0;
|
|
var nettime = 0;
|
|
var cpuline = cookie.cpuline||30;
|
|
var netline = cookie.netline||30;
|
|
var update2 = true;
|
|
var box = null;
|
|
var startup = true;
|
|
var stopgap = '<thead class="stopgap"><tr><td class="stopgap"></td></tr></thead>';
|
|
var recall = null;
|
|
var recover = null;
|
|
|
|
var options_cpu = {
|
|
series:[{name:'load', data:cpu.slice()}],
|
|
chart:{height:120, type:'line', fontFamily:'clear-sans', animations:{enabled:true, easing:'linear', dynamicAnimation:{speed:1000}}, toolbar:{show:false}, zoom:{enabled:false}},
|
|
dataLabels:{enabled:false},
|
|
tooltip:{enabled:false},
|
|
stroke:{curve:'smooth', width:1},
|
|
colors:['#ff8c2f'],
|
|
markers:{size:0},
|
|
xaxis:{type:'datetime', range:cpuline-1, labels:{show:false}, axisTicks:{show:false}, axisBorder:{show:false}},
|
|
yaxis:{max:100, min:0, tickAmount:4, labels:{formatter:function(v,i){return v.toFixed(0)+' %';}, style:{colors:'<?=$color?>'}}, axisBorder:{show:false}, axisTicks:{show:false}},
|
|
grid:{show:true, borderColor:'<?=$grid?>'},
|
|
legend:{show:false}
|
|
};
|
|
var options_net = {
|
|
series:[{name:'receive', data:rxd.slice()},{name:'transmit', data:txd.slice()}],
|
|
chart:{height:120, type:'line', fontFamily:'clear-sans', animations:{enabled:true, easing:'linear', dynamicAnimation:{speed:1000}}, toolbar:{show:false}, zoom:{enabled:false}},
|
|
dataLabels:{enabled:false},
|
|
tooltip:{enabled:false},
|
|
stroke:{curve:'smooth', width:1},
|
|
colors:['#e22828','#ff8c2f'],
|
|
markers:{size:0},
|
|
xaxis:{type:'datetime', range:netline-1, labels:{show:false}, axisTicks:{show:false}, axisBorder:{show:false}},
|
|
yaxis:{tickAmount:4, labels:{formatter:function(v,i){return autoscale(v,'bps',1);}, style:{colors:'<?=$color?>'}}, axisBorder:{show:false}, axisTicks:{show:false}},
|
|
grid:{show:true, borderColor:'<?=$grid?>'},
|
|
legend:{show:false}
|
|
};
|
|
|
|
var cpuchart = new ApexCharts(document.querySelector('#cpuchart'), options_cpu);
|
|
var netchart = new ApexCharts(document.querySelector('#netchart'), options_net);
|
|
|
|
if (cookie.port_select && !ports.includes(cookie.port_select)) {
|
|
delete cookie.port_select;
|
|
saveCookie();
|
|
}
|
|
var port_select = cookie.port_select||ports[0];
|
|
|
|
function saveCookie() {
|
|
$.post('/webGui/include/InitCharts.php',{cmd:'cookie',data:JSON.stringify(cookie)});
|
|
}
|
|
|
|
function sanitizeMultiCookie(cookieName, delimiter, removeDuplicates=false) {
|
|
// Some browser states leave multi-value cookies with nulls, empties or duplicates.
|
|
// This function cleans up any such cookies so that they do not break functionality.
|
|
try {
|
|
var uncleanCookie = $.cookie(cookieName);
|
|
if (uncleanCookie) {
|
|
uncleanCookie = uncleanCookie.split(delimiter);
|
|
var cleanCookie = uncleanCookie.filter(n => n);
|
|
if (removeDuplicates) { cleanCookie = [...new Set(cleanCookie)]; }
|
|
if (JSON.stringify(uncleanCookie) !== JSON.stringify(cleanCookie)) {
|
|
$.cookie(cookieName,cleanCookie.join(delimiter),{expires:3650});
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
} catch (ex) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function initCharts(clear) {
|
|
// initialize graphs entries
|
|
var data = [];
|
|
data.cpu = data.rxd = data.txd ="";
|
|
var now = new Date().getTime();
|
|
if (!clear) {
|
|
var c = data.cpu.split(';');
|
|
var r = data.rxd.split(';');
|
|
var t = data.txd.split(';');
|
|
for (var i=0; i < cpuline; i++) {
|
|
var x = now + i;
|
|
var y = c[i]||0; cpu.push({x,y});
|
|
}
|
|
cputime = x + 1;
|
|
} else {
|
|
// clear network graph
|
|
var r = ''; var t = '';
|
|
rxd = []; txd = [];
|
|
}
|
|
for (var i=0; i < netline; i++) {
|
|
var x = now + i;
|
|
var y = r[i]||0; rxd.push({x,y});
|
|
var y = t[i]||0; txd.push({x,y});
|
|
}
|
|
nettime = x + 1;
|
|
}
|
|
|
|
function resetCharts() {
|
|
// prevent unlimited graph growing
|
|
cpu = cpu.slice(-cpuline);
|
|
rxd = rxd.slice(-netline);
|
|
txd = txd.slice(-netline);
|
|
}
|
|
|
|
function addChartCpu(load) {
|
|
cputime++;
|
|
var i = cpu.length - cpuline;
|
|
if (i > 0) { // clear value outside graph
|
|
i = i - 1;
|
|
cpu[i].x = cputime - cpuline;
|
|
cpu[i].y = 0;
|
|
}
|
|
cpu.push({x:cputime, y:load});
|
|
}
|
|
|
|
function addChartNet(rx, tx) {
|
|
nettime++;
|
|
var i = rxd.length - netline;
|
|
if (i > 0) { // clear value outside graph
|
|
i = i - 1;
|
|
rxd[i].x = nettime - netline;
|
|
rxd[i].y = 0;
|
|
txd[i].x = nettime - netline;
|
|
txd[i].y = 0;
|
|
}
|
|
rxd.push({x:nettime, y:rx});
|
|
txd.push({x:nettime, y:tx});
|
|
}
|
|
|
|
<?if ($wireguard):?>
|
|
function toggleVPN(id,vtun) {
|
|
var up = $('#vpn-active');
|
|
var down = $('#vpn-inactive');
|
|
if (id.hasClass('inactive')) {
|
|
$.post('/webGui/include/update.wireguard.php',{'#cmd':'toggle','#wg':'start','#vtun':vtun},function(on){if (on){
|
|
id.removeClass('inactive');
|
|
up.text(up.text()*1+1);
|
|
if (down.text()>0) down.text(down.text()*1-1);
|
|
}});
|
|
} else {
|
|
$.post('/webGui/include/update.wireguard.php',{'#cmd':'toggle','#wg':'stop','#vtun':vtun});
|
|
id.addClass('inactive');
|
|
down.text(down.text()*1+1);
|
|
if (up.text()>0) up.text(up.text()*1-1);
|
|
$('span[id^="'+vtun+'-hs"]').text('inactive');
|
|
$('span[id^="'+vtun+'-rx"]').text('---');
|
|
}
|
|
}
|
|
<?endif;?>
|
|
|
|
function noApps() {
|
|
if ($('span.outer.apps:visible').length==0) $('#no_apps').show(); else $('#no_apps').hide();
|
|
}
|
|
|
|
function noVMs() {
|
|
if ($('span.outer.vms:visible').length==0) $('#no_vms').show(); else $('#no_vms').hide();
|
|
}
|
|
|
|
function loadlist(init) {
|
|
if (init) {
|
|
$('#apps').switchButton({labels_placement:'right', off_label:"_(All Apps)_", on_label:"_(Started only)_", checked:cookie.my_apps=='startedOnly'});
|
|
$('#vms').switchButton({labels_placement:'right', off_label:"_(All VMs)_", on_label:"_(Started only)_", checked:cookie.my_vms=='startedOnly'});
|
|
$('#apps').change(function(){
|
|
$('span.outer.apps.stopped').finish().toggle('fast',function(){noApps();})
|
|
$('#apps').is(':checked') ? cookie.my_apps = 'startedOnly' : delete cookie.my_apps;
|
|
saveCookie();
|
|
});
|
|
$('#vms').change(function(){
|
|
$('span.outer.vms.stopped').finish().toggle('fast',function(){noVMs();});
|
|
$('#vms').is(':checked') ? cookie.my_vms = 'startedOnly' : delete cookie.my_vms;
|
|
saveCookie();
|
|
});
|
|
}
|
|
$.post('/webGui/include/DashboardApps.php',{docker:'<?=$dockerd?>',vms:'<?=$libvirtd?>',vmusage:'<?=$vmusage?>'},function(d) {
|
|
var data = d.split('\0');
|
|
$('#docker_view tr.updated').remove();
|
|
$('#docker_view').append(data[0]).hideMe();
|
|
$('#vm_view tr.updated').remove();
|
|
$('#vm_view').append(data[1]).hideMe();
|
|
var started_apps = $('#docker_view').find('span.outer.apps.started').length;
|
|
var stopped_apps = $('#docker_view').find('span.outer.apps.stopped').length;
|
|
var paused_apps = $('#docker_view').find('span.outer.apps.paused').length;
|
|
var started_vms = $('#vm_view').find('span.outer.vms.started').length;
|
|
var stopped_vms = $('#vm_view').find('span.outer.vms.stopped').length;
|
|
var paused_vms = $('#vm_view').find('span.outer.vms.paused').length;
|
|
$('#vm_view_usage tr.useupdated').remove();
|
|
$('#vm_view_usage').append(data[2]).hideMe();
|
|
$('.apps.switch').html("_(Containers)_ -- _(Started)_: "+started_apps+", _(Stopped)_: "+stopped_apps+", _(Paused)_: "+paused_apps);
|
|
$('.vms.switch').html("_(VMs)_ -- _(Started)_: "+started_vms+", _(Stopped)_: "+stopped_vms+", _(Paused)_: "+paused_vms);
|
|
if (cookie.my_apps!=null) $('span.apps.stopped').hide(0,noApps());
|
|
if (cookie.my_vms!=null) $('span.vms.stopped').hide(0,noVMs());
|
|
});
|
|
}
|
|
|
|
function getCase() {
|
|
$.post('/webGui/include/SelectCase.php',{mode:'get',file:'<?=$myfile?>'},function(model){
|
|
if (!model) {
|
|
$('#casing').html("<i id='mycase' class='fa fa-hdd-o'></i><br>");
|
|
} else if (model.indexOf('.png')<0) {
|
|
$('#casing').html("<i id='mycase' class='case-"+model+"'></i><br>");
|
|
} else {
|
|
var now = new Date();
|
|
$('#casing').html("<img id='mycase' src='/webGui/images/"+model+"?v="+now.getTime()+"'><br>");
|
|
}
|
|
});
|
|
}
|
|
|
|
function changeMode(item) {
|
|
if (item==0) delete cookie.enter_share; else cookie.enter_share = item;
|
|
if (!startup) saveCookie();
|
|
<?if (_var($var,'shareSMBEnabled')=='yes'):?>
|
|
if (startup || $('.smb.share1').parent().find('tr:eq(1)').is(':visible')) {
|
|
if (item==0) $('.smb.share1').show(); else $('.smb.share1').hide();
|
|
}
|
|
if (startup || $('.smb.user1').parent().find('tr:eq(1)').is(':visible')) {
|
|
if (item==0) $('.smb.user1').show(); else $('.smb.user1').hide();
|
|
}
|
|
<?endif;?>
|
|
<?if (_var($var,'shareNFSEnabled')=='yes'):?>
|
|
if ($('.nfs.share3').parent().find('tr:eq(1)').is(':visible')) {
|
|
if (item==2) $('.nfs.share3').show(); else $('.nfs.share3').hide();
|
|
}
|
|
if ($('.nfs.user3').parent().find('tr:eq(1)').is(':visible')) {
|
|
if (item==2) $('.nfs.user3').show(); else $('.nfs.user3').hide();
|
|
}
|
|
<?endif;?>
|
|
$('select[name="enter_user"]').val(item);
|
|
}
|
|
|
|
function changeView(item) {
|
|
if (item==0) delete cookie.enter_view; else cookie.enter_view = item;
|
|
if (!startup) saveCookie();
|
|
if (item==0) $('.view1').show(); else $('.view1').hide();
|
|
if (item==1) $('.view2').show(); else $('.view2').hide();
|
|
if (item==2) $('.view3').show(); else $('.view3').hide();
|
|
if (item==3) $('.view4').show(); else $('.view4').hide();
|
|
}
|
|
|
|
function changeCPUline(val) {
|
|
cpuline = val;
|
|
if (val==30) delete cookie.cpuline; else cookie.cpuline = val;
|
|
saveCookie();
|
|
cpuchart.updateOptions({xaxis:{range:cpuline-1}});
|
|
}
|
|
|
|
function changeNetline(val) {
|
|
netline = val;
|
|
if (val==30) delete cookie.netline; else cookie.netline = val;
|
|
saveCookie();
|
|
netchart.updateOptions({xaxis:{range:netline-1}});
|
|
}
|
|
|
|
function smartMenu(table) {
|
|
$(table).find('[id^="smart-"]').each(function() {
|
|
var opts = [];
|
|
var id = '#'+$(this).attr('id');
|
|
var page = $(this).attr('name');
|
|
var view = $(this).attr('class');
|
|
var disk = id.substr(id.indexOf('-')+1);
|
|
opts.push({text:"_(Attributes)_",icon:'fa-sitemap',action:function(e){e.preventDefault();attributes(page,disk);}});
|
|
opts.push({divider:true});
|
|
opts.push({text:"_(Capabilities)_",icon:'fa-user',action:function(e){e.preventDefault();capabilities(page,disk);}});
|
|
opts.push({divider:true});
|
|
opts.push({text:"_(Identity)_",icon:'fa-home',action:function(e){e.preventDefault();identity(page,disk);}});
|
|
if (view.search('green-text') == -1) {
|
|
opts.push({divider:true});
|
|
opts.push({text:"_(Acknowledge)_",icon:'fa-check-square-o',action:function(e){e.preventDefault();acknowledge(id,disk);}});
|
|
}
|
|
$(id).bind('click',function(){update2=false;}).bind('mouseout',function(){setTimeout(function(){update2=true;},15000);});
|
|
context.destroy(id);
|
|
context.attach(id,opts);
|
|
});
|
|
}
|
|
|
|
function portMenu() {
|
|
var select = 'select[name="port_select"]';
|
|
var option = $(select+' option');
|
|
for (var i=0; i < option.length; i++) {
|
|
if (option[i].value == port_select) {option[i].selected = true; break;}
|
|
}
|
|
}
|
|
|
|
function portSelect(name) {
|
|
cookie.port_select = name;
|
|
saveCookie();
|
|
initCharts(true);
|
|
port_select = name;
|
|
}
|
|
|
|
function moreInfo(data,table) {
|
|
var info = [];
|
|
if (data[1]>0) info.push(data[1]+' '+(data[1]==1 ? "_(device warning)_" : "_(device warnings)_"));
|
|
if (data[2]>0) info.push(data[2]+' '+(data[2]==1 ? "_(heat warning)_" : "_(heat warnings)_"));
|
|
if (data[3]>0) info.push(data[3]+' '+(data[3]==1 ? "_(SMART error)_" : "_(SMART errors)_"));
|
|
if (data[4]>0) info.push(data[4]+' '+(data[4]==1 ? "_(utilization warning)_" : "_(utilization warnings)_"));
|
|
return info.length ? "<div class='last'><i class='icon-u-triangle failed'></i><span class='failed'>"+table+" _(has)_ "+info.join('. ')+".</span></div>" : "";
|
|
}
|
|
|
|
function autoscale(value,text,size,kilo) {
|
|
if (kilo==null) kilo = 1000;
|
|
var unit = kilo==1024 ? ['','ki','Mi','Gi','Ti','Pi','Ei'] : ['','k','M','G','T','P','E'];
|
|
var base = value>1?Math.floor(Math.log(value)/Math.log(kilo)):0;
|
|
var data = base<unit.length?value/Math.pow(kilo, base):0;
|
|
var scale = (data<100?100:10)/size;
|
|
if (data==0) base=0;
|
|
return ((Math.round(scale*data)/scale)+' '+unit[base]+text).replace(".","<?=_var($display,'number','.,')[0]?>");
|
|
}
|
|
|
|
function update900() {
|
|
// prevent chart overflowing, reset every 15 minutes
|
|
resetCharts();
|
|
setTimeout(update900,900000);
|
|
}
|
|
|
|
function attributes(page,disk) {
|
|
var tab = page=='New' ? 'tab2' : 'tab3';
|
|
$.cookie('one',tab);
|
|
location.replace('/Dashboard/'+page+'?name='+disk);
|
|
}
|
|
|
|
function capabilities(page,disk) {
|
|
var tab = page=='New' ? 'tab3' : 'tab4';
|
|
$.cookie('one',tab);
|
|
location.replace('/Dashboard/'+page+'?name='+disk);
|
|
}
|
|
|
|
function identity(page,disk) {
|
|
var tab = page=='New' ? 'tab4' : 'tab5';
|
|
$.cookie('one',tab);
|
|
location.replace('/Dashboard/'+page+'?name='+disk);
|
|
}
|
|
|
|
function acknowledge(id,disk) {
|
|
$.post('/webGui/include/Acknowledge.php',{disk:disk},function(){
|
|
$(id).removeClass('fa-thumbs-o-down orange-text').addClass('fa-thumbs-o-up green-text');$(id.replace('smart','text')).text("<?=_('healthy')?>");
|
|
});
|
|
}
|
|
|
|
function dropdown(menu) {
|
|
var select = 'select[name="'+menu+'"]';
|
|
var size = $(select+' option').length;
|
|
var option = cookie[menu]||0;
|
|
if (option >= size) option = 0;
|
|
$(select+' option')[option].selected = true;
|
|
$(select).change();
|
|
}
|
|
|
|
function toggleCPU(init) {
|
|
if (!init) {
|
|
if (!cookie.cpu) cookie.cpu = 'close'; else delete cookie.cpu;
|
|
saveCookie();
|
|
}
|
|
if (!cookie.cpu) {
|
|
$('.cpu_open').show();
|
|
$('.cpu_close').text("_(Hide details)_");
|
|
} else {
|
|
$('.cpu_open').hide();
|
|
$('.cpu_close').text("_(Show details)_");
|
|
}
|
|
setTimeout(function(){toggleChart(true);});
|
|
}
|
|
|
|
function toggleChart(init) {
|
|
if (!init) {
|
|
if (!cookie.cpu_chart) cookie.cpu_chart = 'close'; else delete cookie.cpu_chart;
|
|
saveCookie();
|
|
}
|
|
$('#cpu_main').removeClass('last');
|
|
$('.cpu_open:last').removeClass('last');
|
|
if (!cookie.cpu_chart) {
|
|
var hidden = cookie.hidden_content;
|
|
hidden = hidden ? hidden.split(';') : [];
|
|
if (hidden.indexOf($('#cpu_main').parent().attr('sort'))==-1) {
|
|
$('#cpu_chart').show();
|
|
$('#cpuline').show();
|
|
} else {
|
|
$('#cpu_chart').hide();
|
|
$('#cpuline').hide();
|
|
}
|
|
} else {
|
|
$('#cpu_chart').hide();
|
|
$('#cpuline').hide();
|
|
if ($('.cpu_open').is(':visible')) $('.cpu_open:last').addClass('last'); else $('#cpu_main').addClass('last');
|
|
}
|
|
}
|
|
|
|
function StopArray() {
|
|
<?if ($confirm['stop']):?>
|
|
swal({title:"_(Proceed)_?",text:"_(This will stop the array)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){StopArrayNow();});
|
|
<?else:?>
|
|
StopArrayNow();
|
|
<?endif;?>
|
|
}
|
|
|
|
function StopArrayNow() {
|
|
$('span.hand').prop('onclick',null).off('click').addClass('busy').css({'cursor':'default'});
|
|
$.post('/update.htm',{startState:'<?=htmlspecialchars(_var($var,'mdState'))?>', cmdStop:'Stop'},function(){refresh();});
|
|
}
|
|
|
|
function StartArray() {
|
|
<?if ($confirm['stop']):?>
|
|
swal({title:"_(Proceed)_?",text:"_(This will start the array)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){StartArrayNow();});
|
|
<?else:?>
|
|
StartArrayNow();
|
|
<?endif;?>
|
|
}
|
|
|
|
function StartArrayNow() {
|
|
$('span.hand').prop('onclick',null).off('click').addClass('busy').css({'cursor':'default'});
|
|
$.post('/update.htm',{startState:'<?=htmlspecialchars(_var($var,'mdState'))?>', cmdStart:'Start'},function(){refresh();});
|
|
}
|
|
|
|
function Reboot() {
|
|
<?if ($confirm['down']):?>
|
|
swal({title:"_(Proceed)_?",text:"_(This will reboot the system)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){RebootNow();});
|
|
<?else:?>
|
|
RebootNow();
|
|
<?endif;?>
|
|
}
|
|
|
|
function RebootNow() {
|
|
document.boot.cmd.value = 'reboot';
|
|
document.boot.submit();
|
|
}
|
|
|
|
function Shutdown() {
|
|
<?if ($confirm['down']):?>
|
|
swal({title:"_(Proceed)_?",text:"_(This will shutdown the system)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){ShutdownNow();});
|
|
<?else:?>
|
|
ShutdownNow();
|
|
<?endif;?>
|
|
}
|
|
|
|
function ShutdownNow() {
|
|
document.boot.cmd.value = 'shutdown';
|
|
document.boot.submit();
|
|
}
|
|
|
|
<?if ($sleep):?>
|
|
function Sleep() {
|
|
<?if ($confirm['sleep']):?>
|
|
swal({title:"_(Proceed)_?",text:"_(This will put the system to sleep)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){SleepNow();});
|
|
<?else:?>
|
|
SleepNow();
|
|
<?endif;?>
|
|
}
|
|
|
|
function SleepNow() {
|
|
$('#statusraid').append(' • <span class="warning" style="font-weight:bold">System in sleep mode</span>');
|
|
$.get('/plugins/dynamix.s3.sleep/include/SleepMode.php',function(){refresh();});
|
|
}
|
|
<?endif;?>
|
|
|
|
function sortTables() {
|
|
$('table.dashboard').each(function(){
|
|
var table = $(this);
|
|
var index = cookie[table.prop('id')];
|
|
// sorting list exists
|
|
if (index != null) {
|
|
index = index.split(';');
|
|
for (var i=0,n; n=index[i]; i++) {
|
|
var tbody = table.find('tbody[sort="'+n+'"]');
|
|
// element not in this table?
|
|
if (tbody.length==0) {
|
|
// search the other tables to find the element
|
|
$('table.dashboard').not(table).each(function(){
|
|
var other = $(this).find('tbody[sort="'+n+'"]');
|
|
if (other.length) tbody = other;
|
|
});
|
|
}
|
|
tbody.appendTo(table);
|
|
}
|
|
}
|
|
});
|
|
$('table.dashboard tbody').before(stopgap);
|
|
}
|
|
|
|
function addProperties() {
|
|
$('div.frame tbody.system').addClass('sortable').attr('sort','_system_information_'.md5());
|
|
$('div.frame tbody.system').find('td:first').prepend("<i class='fa fa-fw fa-eject control' onclick='openClose()' title=\"_(Show/Hide All Content)_\"></i>");
|
|
$('div.frame tbody').each(function(){
|
|
$(this).find('td:first').prepend("<i class='fa fa-fw fa-chevron-up control openclose' onclick='openClose($(this))' title=\"_(Show/Hide Content)_\"></i>");
|
|
});
|
|
$('div.frame tbody').not('.system').each(function(){
|
|
$(this).addClass('sortable').attr('sort',$(this).attr('title').md5());
|
|
$(this).find('td:first').prepend("<i class='fa fa-fw fa-close control tile' onclick='dismiss($(this))' title=\"_(Close Tile)_\"></i>");
|
|
});
|
|
$('div.frame tr').attr('title','');
|
|
$('div#sys0').hover(function(){$('.sys0').hide();$('.var0').show();},function(){$('.sys0').show();$('.var0').hide();});
|
|
$('div#sys1').hover(function(){$('.sys1').hide();$('.var1').show();},function(){$('.sys1').show();$('.var1').hide();});
|
|
$('div#sys2').hover(function(){$('.sys2').hide();$('.var2').show();},function(){$('.sys2').show();$('.var2').hide();});
|
|
$('div#sys3').hover(function(){$('.sys3').hide();$('.var3').show();},function(){$('.sys3').show();$('.var3').hide();});
|
|
$('#current_time').hover(function(){$.post('/webGui/include/DashboardApps.php',{ntp:'ntp'},function(ntp){$('#current_time').prop('title',ntp+"\n_(Go to date and time settings)_");});});
|
|
// make truncated descriptions fully visible when hovering over them
|
|
$('span.w18').not('.static').hover(
|
|
function(){if ($(this)[0].offsetWidth < $(this)[0].scrollWidth) {recall = $(this).next(); recover=recall.html(); recall.html(' ');}},
|
|
function(){if ($(this)[0].offsetWidth < $(this)[0].scrollWidth) {recall.html(recover); recall=null;}}
|
|
);
|
|
}
|
|
|
|
function showContent() {
|
|
var count = {'db_box1':$('table#db_box1 tbody').length, 'db_box2':$('table#db_box2 tbody').length, 'db_box3':$('table#db_box3 tbody').length}
|
|
var inactive = cookie.inactive_content;
|
|
if (inactive) {
|
|
inactive = inactive.split(';');
|
|
for (let n=0,md5; md5=inactive[n]; n++) {
|
|
var tbody = $('table.dashboard tbody[sort="'+md5+'"]');
|
|
var id = tbody.parent().prop('id');
|
|
count[id]--;
|
|
tbody.hide();
|
|
tbody.prev().hide();
|
|
}
|
|
}
|
|
var hidden = cookie.hidden_content;
|
|
if (hidden) {
|
|
hidden = hidden.split(';');
|
|
for (let n=0,md5; md5=hidden[n]; n++) {
|
|
var tbody = $('div.frame tbody[sort="'+md5+'"]');
|
|
tbody.find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-down');
|
|
tbody.find('tr:gt(0)').hide();
|
|
tbody.find('span.switch').show();
|
|
tbody.find('span.button').hide();
|
|
}
|
|
}
|
|
if (count['db_box1']>0) $('div#tile1').show();
|
|
if (count['db_box2']>0) $('div#tile2').show();
|
|
if (count['db_box3']>0) $('div#tile3').show();
|
|
}
|
|
|
|
function setColor(l, t1, t2) {
|
|
switch (true) {
|
|
case (t1 > 0 && l >= t1): return 'redbar';
|
|
case (t2 > 0 && l >= t2): return 'orangebar';
|
|
default: return '';}
|
|
}
|
|
|
|
function fontColor(l, t1, t2) {
|
|
switch (true) {
|
|
case (t1 > 0 && l >= t1): return '#f0000c';
|
|
case (t2 > 0 && l >= t2): return '#e68a00';
|
|
default: return '#4f8a10';}
|
|
}
|
|
|
|
function openClose(button) {
|
|
var hidden = cookie.hidden_content;
|
|
hidden = hidden ? hidden.split(';') : [];
|
|
if (button) {
|
|
// show/hide single tile content
|
|
var tbody = button.closest('tbody');
|
|
if (button.hasClass('fa-chevron-up')) {
|
|
button.removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-down');
|
|
tbody.mixedView(0);
|
|
hidden.push(tbody.attr('sort'));
|
|
} else {
|
|
button.removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-up');
|
|
tbody.mixedView(1);
|
|
hidden.splice(hidden.indexOf(tbody.attr('sort')),1);
|
|
}
|
|
cookie.hidden_content = hidden.join(';');
|
|
} else {
|
|
// show/hide all tiles content
|
|
if (hidden.length==0) {
|
|
$('div.frame tbody').each(function(){
|
|
$(this).find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-down');
|
|
$(this).mixedView(0);
|
|
hidden.push($(this).attr('sort'));
|
|
});
|
|
cookie.hidden_content = hidden.join(';');
|
|
} else {
|
|
$('div.frame tbody').each(function(){
|
|
$(this).find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-up');
|
|
$(this).mixedView(1);
|
|
});
|
|
delete cookie.hidden_content;
|
|
}
|
|
}
|
|
saveCookie();
|
|
}
|
|
|
|
function dismiss(button) {
|
|
var tbody = button.closest('tbody');
|
|
var table = tbody.parent();
|
|
var tile = table.parent();
|
|
var inactive = cookie.inactive_content;
|
|
tbody.hide();
|
|
tbody.prev().hide();
|
|
if (table.find('tbody:visible').length>0) tile.show(); else tile.hide();
|
|
inactive = inactive ? inactive.split(';') : [];
|
|
inactive.push(tbody.attr('sort'));
|
|
cookie.inactive_content = inactive.join(';');
|
|
saveCookie();
|
|
}
|
|
|
|
function dialogStyle() {
|
|
$('.ui-dialog-titlebar-close').css({'display':'none'});
|
|
$('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'});
|
|
$('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'});
|
|
$('.ui-button-text').css({'padding':'0px 5px'});
|
|
}
|
|
|
|
function contentMgmt() {
|
|
box = $("#iframe-popup");
|
|
box.html($("#templateContentMgmt").html().build());
|
|
box.dialog({
|
|
title: "_(Tile Management)_",
|
|
height: 'auto',
|
|
width: 900,
|
|
resizable: false,
|
|
modal: true,
|
|
buttons: {
|
|
"_(Reset)_": function(){
|
|
cookie = {};
|
|
saveCookie();
|
|
box.dialog('close');
|
|
location.reload();
|
|
},
|
|
"_(All)_": function(){
|
|
$('input.checker').each(function(){$(this).prop('checked',true);});
|
|
},
|
|
"_(None)_": function(){
|
|
$('input.checker').each(function(){$(this).prop('checked',false);});
|
|
},
|
|
"_(Apply)_": function(){
|
|
hideShow();
|
|
box.dialog('close');
|
|
},
|
|
"_(Cancel)_": function(){
|
|
box.dialog('close');
|
|
}
|
|
}
|
|
});
|
|
dialogStyle();
|
|
}
|
|
|
|
function VMClone(uuid, name){
|
|
box = $("#iframe-popup");
|
|
box.html($("#templateClone").html());
|
|
box.find('#VMBeingCloned').html(name).change();
|
|
box.find('#target').val(name + "_clone");
|
|
document.getElementById("Free").checked = true;
|
|
document.getElementById("Overwrite").checked = true;
|
|
box.dialog({
|
|
title: "_(VM Clone)_",
|
|
height: 'auto',
|
|
width: 600,
|
|
resizable: false,
|
|
modal: true,
|
|
buttons: {
|
|
"_(Clone)_": function(){
|
|
var target = box.find('#target');
|
|
if (target.length) {
|
|
target = target.val();
|
|
//if (!target) {errorTarget(); return;}
|
|
} else target = '';
|
|
var clone = box.find("#target").prop('value');
|
|
var start = box.find('#Start').prop('checked') ? 'yes' : 'no';
|
|
var edit = box.find('#Edit').prop('checked') ? 'yes' : 'no';
|
|
var overwrite = box.find('#Overwrite').prop('checked') ? 'yes' : 'no';
|
|
var free = box.find('#Free').prop('checked') ? 'yes' : 'no';
|
|
var scripturl = "VMClone.php " + encodeURIComponent("/usr/local/emhttp/plugins/dynamix.vm.manager/include/VMClone.php&" + $.param({action:"clone", name:name, clone:clone, overwrite:overwrite, edit:edit, start:start, free:free}));
|
|
openVMAction((scripturl),"VM Clone", "dynamix.vm.manager", "loadlist");
|
|
box.dialog('close');
|
|
},
|
|
"_(Cancel)_": function(){
|
|
box.dialog('close');
|
|
}
|
|
}
|
|
});
|
|
dialogStyle();
|
|
}
|
|
|
|
function selectsnapshot(uuid, name ,snaps, opt, getlist, state,fstype){
|
|
box = $("#iframe-popup");
|
|
box.html($("#templatesnapshot"+opt).html());
|
|
const capopt = opt.charAt(0).toUpperCase() + opt.slice(1);
|
|
var optiontext = capopt + " _(Snapshot)_";
|
|
box.find('#VMName').html(name);
|
|
box.find('#fstype').html(fstype);
|
|
if (fstype == "QEMU") box.find('#fstypeline').prop('hidden',true);
|
|
box.find('#targetsnap').val(snaps);
|
|
box.find('#targetsnapl').html(snaps);
|
|
if (getlist) {
|
|
var only = (opt == "remove") ? 0 : 1;
|
|
$.post("/plugins/dynamix.vm.manager/include/VMajax.php",{action:"snap-images",uuid:uuid,snapshotname:snaps,only:only},function(data){if (data.html) box.find('#targetsnapimages').html(data.html);},'json');
|
|
}
|
|
var memorydump = "no";
|
|
document.getElementById("targetsnapfspc").checked = true;
|
|
if (fstype == "ZFS") {
|
|
box.find('#targetsnaprmv').prop('disabled',true);
|
|
box.find('#targetsnaprmvmeta').prop('disabled',true);
|
|
}
|
|
if (state != "running") {
|
|
box.find('#memoryline').prop('hidden',true);
|
|
box.find('#targetsnapmem').prop('hidden',true);
|
|
box.find('#targetsnapmem').prop('checked',false);
|
|
} else {
|
|
box.find('#memoryline').prop('hidden',false);
|
|
box.find('#targetsnapmem').prop('hidden',false);
|
|
box.find('#targetsnapmem').prop('checked',true);
|
|
}
|
|
box.dialog({
|
|
title: optiontext,
|
|
height: 'auto',
|
|
width: 600,
|
|
resizable: false,
|
|
modal: true,
|
|
buttons: {
|
|
"_(Proceed)_": function(){
|
|
var target = box.find('#targetsnap');
|
|
if (target.length) {
|
|
target = target.val();
|
|
if (!target) {errorTarget(); return;}
|
|
} else target = '';
|
|
var remove = 'yes';
|
|
var removemeta = 'yes';
|
|
var keep = 'yes';
|
|
var free = 'yes';
|
|
var desc = '';
|
|
box.find('#targetsnap').prop('disabled',true);
|
|
if (opt == "revert") {
|
|
remove = box.find('#targetsnaprmv').prop('checked') ? 'yes' : 'no';
|
|
removemeta = box.find('#targetsnaprmvmeta').prop('checked') ? 'yes' : 'no';
|
|
keep = box.find('#targetsnapkeep').prop('checked') ? 'yes' : 'no';
|
|
}
|
|
if (opt == "create") {
|
|
free = box.find('#targetsnapfspc').prop('checked') ? 'yes' : 'no';
|
|
desc = box.find("#targetsnapdesc").prop('value');
|
|
memorydump = box.find('#targetsnapmem').prop('checked') ? 'yes' : 'no';
|
|
fstypeuse = box.find('#targetsnapfstype').prop('checked') ? 'yes' : 'no';
|
|
if (fstypeuse == "no") fstype ="QEMU";
|
|
}
|
|
ajaxVMDispatch({action:"snap-" + opt +'-external', uuid:uuid, snapshotname:target, remove:remove, free:free, desc:desc, fstype:fstype,memorydump:memorydump}, "loadlist");
|
|
box.dialog('close');
|
|
},
|
|
"_(Cancel)_": function(){
|
|
box.dialog('close');
|
|
}
|
|
}
|
|
});
|
|
dialogStyle();
|
|
}
|
|
|
|
var sortableHelper = function(e,ui){
|
|
ui.prev().remove();
|
|
ui.find('tr:first').children().each(function(){$(this).width($(this).width());});
|
|
return ui;
|
|
};
|
|
|
|
function LockButton() {
|
|
if ($.cookie('lockbutton') == null) {
|
|
$.cookie('lockbutton','lockbutton');
|
|
<?if ($themeHelper->isTopNavTheme()):?>
|
|
$('div.nav-item.LockButton a').prop('title',"_(Lock sortable items)_");
|
|
$('div.nav-item.LockButton b').removeClass('icon-u-lock green-text').addClass('icon-u-lock-open red-text');
|
|
<?endif;?>
|
|
$('i.tile').show();
|
|
$('tbody.sortable').css({'cursor':'move'});
|
|
$('div.nav-item.LockButton span').text("_(Lock sortable items)_");
|
|
$('#db_box1,#db_box2,#db_box3').sortable({connectWith:'#db_box1,#db_box2,#db_box3'});
|
|
$('table.dashboard').sortable({helper:sortableHelper,items:'.sortable',cursor:'grab',opacity:0.6,placeholder:'dashboard-sortable',zIndex:9999,forceHelperSize:true,forcePlaceholderSize:true,
|
|
receive:function(e,ui){
|
|
var table = ui.sender, index = [];
|
|
var tile = table.parent();
|
|
var gap = ui.item.prev();
|
|
if (table.find('tbody:visible').length > 0) {
|
|
tile.show();
|
|
gap.show();
|
|
} else {
|
|
tile.hide();
|
|
gap.hide();
|
|
}
|
|
table.find('tbody').each(function(){index.push($(this).attr('sort'));});
|
|
cookie[table.prop('id')] = index.join(';');
|
|
},
|
|
stop:function(e,ui){
|
|
var table = ui.item.parent(), index = [];
|
|
if (ui.item.prev().html().search('stopgap')>0) ui.item.after(stopgap); else ui.item.before(stopgap);
|
|
table.find('tbody').each(function(){index.push($(this).attr('sort'));});
|
|
cookie[table.prop('id')] = index.join(';');
|
|
saveCookie();
|
|
}});
|
|
} else {
|
|
$.removeCookie('lockbutton');
|
|
<?if ($themeHelper->isTopNavTheme()):?>
|
|
$('div.nav-item.LockButton a').prop('title',"_(Unlock sortable items)_");
|
|
$('div.nav-item.LockButton b').removeClass('icon-u-lock-open red-text').addClass('icon-u-lock green-text');
|
|
<?endif;?>
|
|
$('i.tile').hide();
|
|
$('tbody.sortable').css({'cursor':'default'});
|
|
$('div.nav-item.LockButton span').text("_(Unlock sortable items)_");
|
|
$('table.dashboard').sortable('destroy');
|
|
}
|
|
}
|
|
|
|
function cpu_parse(msg) {
|
|
var parse = {}, section = '';
|
|
msg.split('\n').forEach(function(row) {
|
|
if (row.substr(0,1) == '[') {
|
|
section = row.substr(1,row.length-2);
|
|
parse[section] = {};
|
|
} else {
|
|
var data = row.split('=');
|
|
parse[section][data[0]] = data[1];
|
|
}
|
|
});
|
|
return parse;
|
|
}
|
|
|
|
<?if ($vmusage == "Y"):?>
|
|
var vmdashusage = new NchanSubscriber('/sub/vm_dashusage',{subscriber:'websocket', reconnectTimeout:5000});
|
|
vmdashusage.on('message', function(msg){
|
|
var data = JSON.parse(msg);
|
|
for (const [vm, vmdata] of Object.entries(data)) {
|
|
for (const [displayitem, value] of Object.entries(vmdata)) {
|
|
$('#vmmetrics-'+displayitem + '-' + vm ).html(value);
|
|
}
|
|
}
|
|
});
|
|
<?endif;?>
|
|
|
|
var dashboard = new NchanSubscriber('/sub/cpuload,update1,update2,update3<?=$wireguard?",wireguard":""?>',{subscriber:'websocket', reconnectTimeout:5000});
|
|
dashboard.on('message',function(msg,meta) {
|
|
switch (meta.id.channel()) {
|
|
case 0:
|
|
var get = cpu_parse(msg);
|
|
// cpu load
|
|
$.each(get,function(k,v) {
|
|
var load = v.host;
|
|
var color = setColor(load, 90, 70);
|
|
if (k=='cpu') {
|
|
addChartCpu(load);
|
|
cpuchart.updateSeries([{data:cpu}]);
|
|
$('.cpu_').text(load+'%');
|
|
$('#cpu_').alive(load+'%',color);
|
|
}
|
|
$('.'+k).text(load+'%');
|
|
$('#'+k).alive(load+'%',color);
|
|
});
|
|
break;
|
|
case 1:
|
|
var get = JSON.parse(msg);
|
|
// memory & disk load
|
|
var load = get.ram[0].slice(0,-1);
|
|
$('.sys0').text(get.ram[0]).css({'color':fontColor(load,<?=$display['critical']?>,<?=$display['warning']?>)});
|
|
$('.var0').text(get.ram[1]);
|
|
var color = setColor(load,<?=$display['critical']?>,<?=$display['warning']?>);
|
|
$('.sys0_').text(get.ram[0]);
|
|
$('#sys0_').alive(get.ram[0],color);
|
|
var start = 0;
|
|
var end = parseInt(get.ram[4]);
|
|
var ring = [colors[0]+' '+start+'% '+end+'%']
|
|
// create individual elements of the RAM graph
|
|
for (var i=6; i < get.ram.length; i=i+2) {
|
|
start = end;
|
|
end += parseInt(get.ram[i]);
|
|
ring.push((colors[(i-2)/2]||blue)+' '+start+'% '+end+'%');
|
|
}
|
|
ring.push(colors[1]+' '+get.ram[0]+' 100%');
|
|
$('#sys0').css({'background':'conic-gradient('+ring.join(',')+')'});
|
|
// dynamic info from hook scripts
|
|
var html = [];
|
|
for (var i=0,name; name=get.name[i]; i++) if (i!=1) html.push("<i class='ups fa fa-circle' style='color:"+(colors[i]||blue)+"'></i>"+name+": "+(i==0?get.ram[5]:get.ram[i*2+3]));
|
|
html.push("<i class='ups fa fa-circle' style='color:"+colors[1]+"'></i>"+get.name[1]+": "+get.ram[3]);
|
|
$('#dynamic').html(html.join('<br>'));
|
|
// flash, Log & Docker graphs
|
|
for (var k=1,sys; sys=get.sys[k-1]; k++) {
|
|
var load = sys[0].slice(0,-1);
|
|
$('.sys'+k).text(sys[0]).css({'color':fontColor(load,<?=$display['critical']?>,<?=$display['warning']?>)});
|
|
$('.var'+k).text(sys[1]);
|
|
$('#sys'+k).css({'background':'conic-gradient('+colors[0]+' 0% '+sys[0]+','+colors[1]+' '+sys[0]+' 100%)'});
|
|
}
|
|
<?if ($fans):?>
|
|
// fans rpm
|
|
for (var k=0; k < get.fan.length; k++) $('#fan'+k).html(get.fan[k]);
|
|
<?endif;?>
|
|
<?if (_var($var,'fsState')=='Started' && $group):?>
|
|
// stream counters (smb only)
|
|
if ($('.smb').is(':visible')) for (var k=0; k < get.stream.length; k++) {$('#share'+k).html(get.stream[k]); $('#share'+k).removeClass(); if (get.stream[k]>0) $('#share'+k).addClass('orange-text');}
|
|
<?endif;?>
|
|
break;
|
|
case 2:
|
|
if (!update2) break;
|
|
var get = JSON.parse(msg);
|
|
if(document.getElementById('array_list') != null) {
|
|
var info = moreInfo(get.disk,"_(Array)_");
|
|
// array devices
|
|
$('#array_list tr.updated').remove();
|
|
$('#array_list').append(get.disk[0]).hideMe();
|
|
$('#array_info').parent().css({'display':info?'':'none'});
|
|
$('#array_info').html(info);
|
|
smartMenu('#array_list');
|
|
}
|
|
// pool devices
|
|
if(get.pool) {
|
|
for (let i=0; i < get.pool.length; i++) {
|
|
var info = moreInfo(get.pool[i],"_(Pool)_");
|
|
$('#pool_list'+i+' tr.updated').remove();
|
|
$('#pool_list'+i).append(get.pool[i][0]).hideMe();
|
|
$('#pool_info'+i).parent().css({'display':info?'':'none'});
|
|
$('#pool_info'+i).html(info);
|
|
smartMenu('#pool_list'+i);
|
|
}
|
|
}
|
|
<?if ($devs):?>
|
|
// unassigned devices
|
|
var info = moreInfo(get.open,"_(Unassigned)_");
|
|
$('#devs_list tr.updated').remove();
|
|
$('#devs_list').append(get.open[0]).hideMe();
|
|
$('#devs_info').parent().css({'display':info?'':'none'});
|
|
$('#devs_info').html(info);
|
|
smartMenu('#devs_list');
|
|
<?endif;?>
|
|
// parity status
|
|
$('span.parity').html(get.parity);
|
|
// parity schedule
|
|
$('#parity').html(get.schedule[0]);
|
|
$('#program').html(get.schedule[1]);
|
|
break;
|
|
case 3:
|
|
var get = JSON.parse(msg);
|
|
// rx & tx speeds
|
|
for (let i=0,port; port=get.port[i]; i++) {
|
|
if (port[0] == port_select) {
|
|
$('#inbound').text(port[1]);
|
|
$('#outbound').text(port[2]);
|
|
addChartNet(port[3], port[4]);
|
|
netchart.updateSeries([{data:rxd},{data:txd}]);
|
|
break;
|
|
}
|
|
}
|
|
// port counters
|
|
for (let k=0; k < get.mode.length; k++) $('#main'+k).html(get.mode[k]);
|
|
for (let k=0; k < get.rxtx.length; k++) $('#port'+k).html(get.rxtx[k]);
|
|
for (let k=0; k < get.stat.length; k++) $('#link'+k).html(get.stat[k]);
|
|
// current date and time
|
|
$('#current_time').html(get.time[0]);
|
|
$('#current_time_').html(get.time[0]);
|
|
$('#current_date').html(get.time[1]);
|
|
break;
|
|
case 4:
|
|
// wireguard tunnels
|
|
var get = JSON.parse(msg);
|
|
let n = {};
|
|
for (var i=0,info; info=get[i]; i++) {
|
|
var vtun = info[0];
|
|
if (typeof n[vtun]=='undefined') n[vtun]=0; else n[vtun]++;
|
|
if (info[1] == 0) {
|
|
$('span#'+vtun+'-hs-'+n[vtun]).text("_(not received)_");
|
|
} else if (info[1] > 86400) {
|
|
var d = parseInt(info[1]/86400);
|
|
var s = d==1 ? " _(day)_" : " _(days)_";
|
|
$('span#'+vtun+'-hs-'+n[vtun]).text(sprintf("_(%s ago)_",d+s));
|
|
} else {
|
|
var h = parseInt(info[1]/3600).pad();
|
|
var m = parseInt(info[1]/60%60).pad();
|
|
var s = parseInt(info[1]%60).pad();
|
|
$('span#'+vtun+'-hs-'+n[vtun]).text(sprintf("_(%s ago)_",h+':'+m+':'+s));
|
|
}
|
|
$('span#'+vtun+'-rx-'+n[vtun]).html('<span class="rx"><i class="fa fa-fw fa-arrow-down"></i> '+info[2]+'</span><span><i class="fa fa-fw fa-arrow-up"></i> '+info[3]+'</span>');
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
|
|
<?if ($apcupsd):?>
|
|
var apcups = new NchanSubscriber('/sub/apcups',{subscriber:'websocket', reconnectTimeout:5000});
|
|
apcups.on('message',function(msg) {
|
|
var get = JSON.parse(msg);
|
|
$('#ups_model').html(get[0]);
|
|
$('#ups_status').html(get[1]);
|
|
$('#ups_status_').html(get[1]);
|
|
$('#ups_bcharge').html(get[2]);
|
|
$('#ups_timeleft').html(get[3]);
|
|
$('#ups_nompower').html(get[4]);
|
|
$('#ups_loadpct').html(get[5]);
|
|
$('#ups_loadpct_').html(get[5]);
|
|
$('#ups_outputv').html(get[6]);
|
|
});
|
|
<?endif;?>
|
|
|
|
$(function() {
|
|
initCharts();
|
|
cpuchart.render();
|
|
netchart.render();
|
|
addProperties();
|
|
<?if ($group):?>
|
|
dropdown('enter_share');
|
|
<?endif;?>
|
|
dropdown('enter_view');
|
|
startup = false;
|
|
dashboard.start().monitor();
|
|
<?if ($vmusage == "Y"):?>
|
|
vmdashusage.start().monitor();
|
|
<?endif;?>
|
|
<?if ($apcupsd):?>
|
|
apcups.start().monitor();
|
|
<?endif;?>
|
|
update900();
|
|
toggleChart(true);
|
|
toggleCPU(true);
|
|
portMenu();
|
|
loadlist(true);
|
|
sortTables();
|
|
showContent();
|
|
$('#cpuline').val(cpuline);
|
|
$('#netline').val(netline);
|
|
$.removeCookie('lockbutton');
|
|
// remember latest graph values
|
|
});
|
|
|
|
// Start graphs over again when window back in focus
|
|
function pageFocusFunction() {
|
|
cpu = [];
|
|
rxd = [];
|
|
txd = [];
|
|
}
|
|
|
|
</script>
|