mirror of
https://github.com/unraid/webgui.git
synced 2026-03-12 22:09:53 -05:00
@@ -17,37 +17,39 @@ Markdown="false"
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.ui.css">
|
||||
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.switchbutton.css">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.ui.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<style>
|
||||
.basic{display:block}
|
||||
.advanced{display:none;white-space:nowrap}
|
||||
body{-webkit-overflow-scrolling:touch}
|
||||
img.started{opacity:1.0}
|
||||
img.stopped{opacity:0.3}
|
||||
img.paused{opacity:0.6}
|
||||
.log{cursor:zoom-in}
|
||||
.exec{cursor:pointer}
|
||||
.fa-custom{font-size:1.3em}
|
||||
.iconstatus{position:absolute;z-index:2;bottom:-4px;right:-4px;font-size:1.2em;text-shadow:0 0 2px #FFF}
|
||||
.iconstatus.started{font-size:1.3em}
|
||||
.iconstatus.stopped{font-size:1.2em}
|
||||
.iconstatus{position:absolute;z-index:2;bottom:-4px;right:-4px;font-size:1.3em;text-shadow:0 0 2px #FFF}
|
||||
.started{color:#009900}
|
||||
.stopped{color:#EF3D47}
|
||||
.paused{color:#F0DD33}
|
||||
.switch-button-label.off{color:inherit}
|
||||
th.five{width:5%}
|
||||
th.eight{width:8%}
|
||||
tbody > tr.sortable:hover{cursor:move}
|
||||
</style>
|
||||
<div id="dialog-confirm" style="display:none;" title="Dialog Title"></div>
|
||||
<div id="iframe-popup" style="display:none;-webkit-overflow-scrolling:touch;"></div>
|
||||
<span class="status" style="margin-top:-44px"><span><input type="checkbox" class="advancedview"></span></span>
|
||||
<div class="spinner fixed"></div>
|
||||
<table class="tablesorter shift" id="docker_containers">
|
||||
<thead><tr><th></th><th>Application</th><th>Version</th><th>Network</th><th>Port Mappings <small>(App to Host)</small></th><th>Volume Mappings <small>(App to Host)</small></th><th class="eight">Autostart</th><th class="five">Log</th><th class="five" style="text-align:right;padding-right:24px"><a href="#" style="cursor:hand" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-sort"></i></a></th></tr></thead>
|
||||
<table id="docker_containers" class="tablesorter shift">
|
||||
<thead><tr><th><a href="#" style="cursor:hand;margin-left:12px" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-th-list"></i></a></th><th>Application</th><th>Version</th><th>Network</th><th>Port Mappings <small>(App to Host)</small></th><th>Volume Mappings <small>(App to Host)</small></th><th class="eight">Autostart</th><th class="five">Log</th></tr></thead>
|
||||
<tbody id="docker_list"><tr><td colspan='8'><div class="spinner"></div></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" onclick="addContainer()" value="Add Container" style="display:none">
|
||||
<input type="button" onclick="startAll()" value="Start all Containers" style="display:none">
|
||||
<input type="button" onclick="stopAll()" value="Stop all Containers" style="display:none">
|
||||
<input type="button" onclick="pauseAll()" value="Pause all Containers" style="display:none">
|
||||
<input type="button" onclick="resumeAll()" value="Resume all Containers" style="display:none">
|
||||
<input type="button" onclick="checkAll()" value="Check for Updates" id="checkAll" style="display:none">
|
||||
<input type="button" onclick="updateAll()" value="Update all Containers" id="updateAll" style="display:none">
|
||||
|
||||
@@ -78,11 +80,22 @@ function listview() {
|
||||
$('.docker_readmore').readmore({maxHeight:32,moreLink:"<a href='#' style='text-align:center'><i class='fa fa-chevron-down'></i></a>",lessLink:"<a href='#' style='text-align:center'><i class='fa fa-chevron-up'></i></a>"});
|
||||
}
|
||||
}
|
||||
var sortableHelper = function(e,i){
|
||||
i.children().each(function(){
|
||||
$(this).width($(this).width());
|
||||
});
|
||||
return i;
|
||||
};
|
||||
function loadlist(update) {
|
||||
$.get('/plugins/dynamix.docker.manager/include/DockerContainers.php',function(d) {
|
||||
var data = d.split(/\0/);
|
||||
$('div.spinner').hide('slow');
|
||||
$('#docker_list').html(data[0]);
|
||||
$('#docker_list').html(data[0]).sortable({helper:sortableHelper,items:'tr.sortable',opacity:0.4,update:function(e,i){
|
||||
var row = $('#docker_list').find('tr:first');
|
||||
var names = ''; var index = '';
|
||||
row.parent().children().find('td.ct-name').each(function(){names+=$(this).text().replace(/Container ID.*$/,'')+';';index+=$(this).parent().parent().children().index($(this).parent())+';';});
|
||||
$.post('/plugins/dynamix.docker.manager/include/UserPrefs.php',{names:names,index:index});
|
||||
}});
|
||||
$('head').append('<script>'+data[1]+'<\/script>');
|
||||
<?if ($display['resize']):?>
|
||||
resize();
|
||||
@@ -97,24 +110,6 @@ function loadlist(update) {
|
||||
context.init({preventDoubleContext:false});
|
||||
$('input[type=button]').prop('disabled',false).show('slow');
|
||||
if (!update) $('input#updateAll').hide();
|
||||
$('i.up,i.down').click(function() {
|
||||
var row = $(this).parents('tr:first');
|
||||
var color1 = row.css('background-color');
|
||||
if ($(this).is('.up')) {
|
||||
var color2 = row.prev().css('background-color');
|
||||
row.prev().css('background-color',color1);
|
||||
row.css('background-color',color2);
|
||||
row.insertBefore(row.prev());
|
||||
} else {
|
||||
var color2 = row.next().css('background-color');
|
||||
row.next().css('background-color',color1);
|
||||
row.css('background-color',color2);
|
||||
row.insertAfter(row.next());
|
||||
}
|
||||
var names = ''; var index = '';
|
||||
row.parent().children().find('td.ct-name').each(function(){names+=$(this).text().replace(/Container ID.*$/,'')+';';index+=$(this).parent().parent().children().index($(this).parent())+';';});
|
||||
$.post('/plugins/dynamix.docker.manager/include/UserPrefs.php',{names:names,index:index});
|
||||
});
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
|
||||
@@ -17,7 +17,7 @@ require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
$user_prefs = $dockerManPaths['user-prefs'];
|
||||
$action = $_POST['action'];
|
||||
$status = $action=='start' ? 'exited' : 'running';
|
||||
$status = $action=='start' ? 'exited' : ($action=='unpause' ? 'paused' : 'running');
|
||||
$containers = DockerUtil::docker("ps -a --filter status='$status' --format='{{.Names}}'",true);
|
||||
|
||||
if (file_exists($user_prefs)) {
|
||||
|
||||
@@ -29,8 +29,9 @@ $DockerTemplates = new DockerTemplates();
|
||||
# ██║ ╚██████╔╝██║ ╚████║╚██████╗ ██║ ██║╚██████╔╝██║ ╚████║███████║
|
||||
# ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝
|
||||
|
||||
$custom = DockerUtil::docker("network ls --filter driver='macvlan' --format='{{.Name}}'",true);
|
||||
$custom = DockerUtil::docker("network ls --filter driver='bridge' --filter driver='macvlan' --format='{{.Name}}'|grep -v '^bridge$'",true);
|
||||
$subnet = ['bridge'=>'', 'host'=>'', 'none'=>''];
|
||||
|
||||
foreach ($custom as $network) $subnet[$network] = substr(DockerUtil::docker("network inspect --format='{{range .IPAM.Config}}{{.Subnet}}, {{end}}' $network"),0,-1);
|
||||
|
||||
function stopContainer($name) {
|
||||
@@ -189,6 +190,7 @@ function postToXML($post, $setOwnership=false) {
|
||||
$xml->Networking->addChild("Publish");
|
||||
$xml->addChild("Data");
|
||||
$xml->addChild("Environment");
|
||||
$xml->addChild("Labels");
|
||||
|
||||
$size = is_array($post['confName']) ? count($post['confName']) : 0;
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
@@ -219,6 +221,11 @@ function postToXML($post, $setOwnership=false) {
|
||||
$variable->Value = $post['confValue'][$i];
|
||||
$variable->Name = $post['confTarget'][$i];
|
||||
$variable->Mode = $post['confMode'][$i];
|
||||
} elseif ($Type == 'Label') {
|
||||
$label = $xml->Labels->addChild("Label");
|
||||
$label->Value = $post['confValue'][$i];
|
||||
$label->Name = $post['confTarget'][$i];
|
||||
$label->Mode = $post['confMode'][$i];
|
||||
}
|
||||
}
|
||||
$dom = new DOMDocument('1.0');
|
||||
@@ -343,6 +350,25 @@ function xmlToVar($xml) {
|
||||
];
|
||||
}
|
||||
}
|
||||
if (isset($xml->Labels->Variable)) {
|
||||
$varNum = 0;
|
||||
foreach ($xml->Labels->Variable as $varitem) {
|
||||
if (empty(xml_decode($varitem->Name))) continue;
|
||||
$varNum += 1;
|
||||
$out['Config'][] = [
|
||||
'Name' => "Label ${varNum}",
|
||||
'Target' => xml_decode($varitem->Name),
|
||||
'Default' => xml_decode($varitem->Value),
|
||||
'Value' => xml_decode($varitem->Value),
|
||||
'Mode' => '',
|
||||
'Description' => 'Container Label: '.xml_decode($varitem->Name),
|
||||
'Type' => 'Label',
|
||||
'Display' => 'always',
|
||||
'Required' => 'false',
|
||||
'Mask' => 'false'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlSecurity($out);
|
||||
return $out;
|
||||
@@ -366,8 +392,7 @@ function xmlSecurity(&$template) {
|
||||
}
|
||||
|
||||
function xmlToCommand($xml, $create_paths=false) {
|
||||
global $var;
|
||||
global $docroot;
|
||||
global $docroot, $var, $driver;
|
||||
$xml = xmlToVar($xml);
|
||||
$cmdName = strlen($xml['Name']) ? '--name='.escapeshellarg($xml['Name']) : '';
|
||||
$cmdPrivileged = strtolower($xml['Privileged'])=='true' ? '--privileged=true' : '';
|
||||
@@ -376,6 +401,7 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
$Volumes = [''];
|
||||
$Ports = [''];
|
||||
$Variables = [''];
|
||||
$Labels = [''];
|
||||
$Devices = [''];
|
||||
// Bind Time
|
||||
$Variables[] = 'TZ="' . $var['timeZone'] . '"';
|
||||
@@ -396,14 +422,21 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
@chgrp($hostConfig, 100);
|
||||
}
|
||||
} elseif ($confType == 'port') {
|
||||
// Export ports as variable if Network is set to host
|
||||
if (preg_match('/^(host|eth[0-9]|br[0-9]|bond[0-9])/',strtolower($xml['Network']))) {
|
||||
switch ($driver[$xml['Network']]) {
|
||||
case 'host':
|
||||
case 'macvlan':
|
||||
// Export ports as variable if network is set to host or macvlan
|
||||
$Variables[] = strtoupper(escapeshellarg($Mode.'_PORT_'.$containerConfig).'='.escapeshellarg($hostConfig));
|
||||
// Export ports as port if Network is set to bridge
|
||||
} elseif (strtolower($xml['Network'])== 'bridge') {
|
||||
break;
|
||||
case 'bridge':
|
||||
// Export ports as port if network is set to (custom) bridge
|
||||
$Ports[] = escapeshellarg($hostConfig.':'.$containerConfig.'/'.$Mode);
|
||||
// No export of ports if Network is set to none
|
||||
break;
|
||||
case 'none':
|
||||
// No export of ports if network is set to none
|
||||
}
|
||||
} elseif ($confType == "label") {
|
||||
$Labels[] = escapeshellarg($containerConfig).'='.escapeshellarg($hostConfig);
|
||||
} elseif ($confType == "variable") {
|
||||
$Variables[] = escapeshellarg($containerConfig).'='.escapeshellarg($hostConfig);
|
||||
} elseif ($confType == "device") {
|
||||
@@ -411,8 +444,8 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
}
|
||||
}
|
||||
$postArgs = explode(";",$xml['PostArgs']);
|
||||
$cmd = sprintf($docroot.'/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s %s %s',
|
||||
$cmdName, $cmdNetwork, $cmdMyIP, $cmdPrivileged, implode(' -e ', $Variables), implode(' -p ', $Ports), implode(' -v ', $Volumes), implode(' --device=', $Devices), $xml['ExtraParams'], escapeshellarg($xml['Repository']), $postArgs[0]);
|
||||
$cmd = sprintf($docroot.'/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s %s %s %s',
|
||||
$cmdName, $cmdNetwork, $cmdMyIP, $cmdPrivileged, implode(' -e ', $Variables), implode(' -l ', $Labels), implode(' -p ', $Ports), implode(' -v ', $Volumes), implode(' --device=', $Devices), $xml['ExtraParams'], escapeshellarg($xml['Repository']), $postArgs[0]);
|
||||
return [preg_replace('/\s+/', ' ', $cmd), $xml['Name'], $xml['Repository']];
|
||||
}
|
||||
|
||||
@@ -557,9 +590,7 @@ if (isset($_POST['contName'])) {
|
||||
// remove old template
|
||||
@unlink("$userTmplDir/my-$existing.xml");
|
||||
}
|
||||
if ($startContainer) {
|
||||
$cmd = str_replace('/plugins/dynamix.docker.manager/scripts/docker create ', '/plugins/dynamix.docker.manager/scripts/docker run -d ', $cmd);
|
||||
}
|
||||
if ($startContainer) $cmd = str_replace('/docker create ', '/docker run -d ', $cmd);
|
||||
execCommand($cmd);
|
||||
echo '<div style="text-align:center"><button type="button" onclick="done()">Done</button></div><br>';
|
||||
goto END;
|
||||
@@ -1026,7 +1057,11 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t
|
||||
targetDiv.find('#dt1').text('Key:');
|
||||
valueDiv.find('#dt2').text('Value:');
|
||||
break;
|
||||
case 3: // Device
|
||||
case 3: // Label
|
||||
targetDiv.find('#dt1').text('Key:');
|
||||
valueDiv.find('#dt2').text('Value:');
|
||||
break;
|
||||
case 4: // Device
|
||||
targetDiv.hide();
|
||||
defaultDiv.hide();
|
||||
valueDiv.find('#dt2').text('Value:');
|
||||
@@ -1443,7 +1478,7 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t
|
||||
<table class="settings wide">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><a href="javascript:addConfigPopup()"><i class="fa fa-plus"></i> Add another Path, Port, Variable or Device</a></td>
|
||||
<td><a href="javascript:addConfigPopup()"><i class="fa fa-plus"></i> Add another Path, Port, Variable, Label or Device</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
@@ -1476,6 +1511,7 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t
|
||||
<option value="Path">Path</option>
|
||||
<option value="Port">Port</option>
|
||||
<option value="Variable">Variable</option>
|
||||
<option value="Label">Label</option>
|
||||
<option value="Device">Device</option>
|
||||
</select>
|
||||
</dd>
|
||||
|
||||
@@ -28,9 +28,12 @@ $dockerManPaths = [
|
||||
];
|
||||
|
||||
// load network variables if needed.
|
||||
if (!isset($eth0) && is_file("$docroot/state/network.ini")) extract(parse_ini_file("$docroot/state/network.ini",true));
|
||||
if (!isset($eth0)) extract(parse_ini_file("$docroot/state/network.ini",true));
|
||||
$host = $eth0['IPADDR:0'] ?? '0.0.0.0';
|
||||
|
||||
// get network drivers
|
||||
$driver = DockerUtil::driver();
|
||||
|
||||
// Docker configuration file - guaranteed to exist
|
||||
$docker_cfgfile = '/boot/config/docker.cfg';
|
||||
$dockercfg = parse_ini_file($docker_cfgfile);
|
||||
@@ -72,6 +75,7 @@ class DockerTemplates {
|
||||
foreach ($iter as $path => $fileinfo) {
|
||||
$fext = $fileinfo->getExtension();
|
||||
if ($ext && $ext != $fext) continue;
|
||||
if (substr(basename($path),0,1) == ".") continue;
|
||||
if ($fileinfo->isFile()) $paths[] = ['path' => $path, 'prefix' => basename(dirname($path)), 'name' => $fileinfo->getBasename(".$fext")];
|
||||
}
|
||||
return $paths;
|
||||
@@ -259,6 +263,7 @@ class DockerTemplates {
|
||||
$image = $ct['Image'];
|
||||
$tmp = &$info[$name] ?? [];
|
||||
$tmp['running'] = $ct['Running'];
|
||||
$tmp['paused'] = $ct['Paused'];
|
||||
$tmp['autostart'] = in_array($name, $autoStart);
|
||||
if (!is_file($tmp['icon']) || $reload) $tmp['icon'] = $this->getIcon($image);
|
||||
if ($ct['Running']) {
|
||||
@@ -627,12 +632,24 @@ class DockerClient {
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function pauseContainer($id) {
|
||||
$this->getDockerJSON("/containers/$id/pause", 'POST', $code);
|
||||
$this->flushCache($this::$containersCache);
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function stopContainer($id) {
|
||||
$this->getDockerJSON("/containers/$id/stop", 'POST', $code);
|
||||
$this->flushCache($this::$containersCache);
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function resumeContainer($id) {
|
||||
$this->getDockerJSON("/containers/$id/unpause", 'POST', $code);
|
||||
$this->flushCache($this::$containersCache);
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function restartContainer($id) {
|
||||
$this->getDockerJSON("/containers/$id/restart", 'POST', $code);
|
||||
$this->flushCache($this::$containersCache);
|
||||
@@ -684,6 +701,7 @@ class DockerClient {
|
||||
}
|
||||
|
||||
public function getDockerContainers() {
|
||||
global $driver;
|
||||
// Return cached values
|
||||
if (is_array($this::$containersCache)) return $this::$containersCache;
|
||||
$this::$containersCache = [];
|
||||
@@ -695,6 +713,7 @@ class DockerClient {
|
||||
$c['Name'] = substr($info['Name'], 1);
|
||||
$c['Status'] = $ct['Status'] ?: 'None';
|
||||
$c['Running'] = $info['State']['Running'];
|
||||
$c['Paused'] = $info['State']['Paused'];
|
||||
$c['Cmd'] = $ct['Command'];
|
||||
$c['Id'] = $this->extractID($ct['Id']);
|
||||
$c['Volumes'] = $info['HostConfig']['Binds'];
|
||||
@@ -702,7 +721,7 @@ class DockerClient {
|
||||
$c['NetworkMode'] = $ct['HostConfig']['NetworkMode'];
|
||||
$c['BaseImage'] = $ct['Labels']['BASEIMAGE'] ?? false;
|
||||
$c['Ports'] = [];
|
||||
if (!empty($info['HostConfig']['PortBindings'])) {
|
||||
if ($driver[$c['NetworkMode']]=='bridge') {
|
||||
$ports = &$info['HostConfig']['PortBindings'];
|
||||
$nat = true;
|
||||
} else {
|
||||
@@ -710,6 +729,7 @@ class DockerClient {
|
||||
$nat = false;
|
||||
}
|
||||
$ip = $ct['NetworkSettings']['Networks'][$c['NetworkMode']]['IPAddress'];
|
||||
$ports = is_array($ports) ? $ports : array();
|
||||
foreach ($ports as $port => $value) {
|
||||
list($PrivatePort, $Type) = explode('/', $port);
|
||||
$c['Ports'][] = ['IP' => $ip, 'PrivatePort' => $PrivatePort, 'PublicPort' => $nat ? $value[0]['HostPort']:$PrivatePort, 'NAT' => $nat, 'Type' => $Type ];
|
||||
@@ -803,5 +823,10 @@ class DockerUtil {
|
||||
$ipaddr = $version==4 ? 'IPAddress' : 'GlobalIPv6Address';
|
||||
return static::docker("inspect --format='{{range .NetworkSettings.Networks}}{{.$ipaddr}}{{end}}' $name");
|
||||
}
|
||||
public static function driver() {
|
||||
$list = [];
|
||||
foreach (static::docker("network ls --format='{{.Name}}={{.Driver}}'",true) as $network) {list($name,$driver) = explode('=',$network); $list[$name] = $driver;}
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -43,18 +43,19 @@ $n = 0;
|
||||
foreach ($containers as $ct) {
|
||||
$name = $ct['Name'];
|
||||
$id = $ct['Id'];
|
||||
$running = $ct['Running'] ? 1 : 0;
|
||||
$info = &$allInfo[$name];
|
||||
$running = $info['running'] ? 1 : 0;
|
||||
$paused = $info['paused'] ? 1 : 0;
|
||||
$is_autostart = $info['autostart'] ? 'true':'false';
|
||||
$updateStatus = $info['updated']=='true'||$info['updated']=='undef' ? 'true':'false';
|
||||
$template = $info['template'];
|
||||
$webGui = html_entity_decode($info['url']);
|
||||
$support = html_entity_decode($info['Support']);
|
||||
$project = html_entity_decode($info['Project']);
|
||||
$menu[] = sprintf("addDockerContainerContext('%s','%s','%s',%s,%s,%s,'%s','%s','%s','%s');", addslashes($name), addslashes($ct['ImageId']), addslashes($template), $running, $updateStatus, $is_autostart, addslashes($webGui), $id, addslashes($support), addslashes($project));
|
||||
$docker[] = "docker.push({name:'$name',id:'$id',state:$running,update:'$updateStatus'});";
|
||||
$shape = $running ? 'play':'square';
|
||||
$status = $running ? 'started':'stopped';
|
||||
$menu[] = sprintf("addDockerContainerContext('%s','%s','%s',%s,%s,%s,%s,'%s','%s','%s','%s');", addslashes($name), addslashes($ct['ImageId']), addslashes($template), $running, $paused, $updateStatus, $is_autostart, addslashes($webGui), $id, addslashes($support), addslashes($project));
|
||||
$docker[] = "docker.push({name:'$name',id:'$id',state:$running,pause:$paused,update:'$updateStatus'});";
|
||||
$shape = $running ? ($paused ? 'pause' : 'play') : 'square';
|
||||
$status = $running ? ($paused ? 'paused' : 'started') : 'stopped';
|
||||
$icon = $info['icon'] ?: '/plugins/dynamix.docker.manager/images/question.png';
|
||||
$ports = [];
|
||||
foreach ($ct['Ports'] as $port) {
|
||||
@@ -67,17 +68,17 @@ foreach ($containers as $ct) {
|
||||
list($host_path,$container_path,$access_mode) = explode(':',$mount);
|
||||
$paths[] = sprintf('%s<i class="fa fa-%s" style="margin:0 6px"></i>%s', htmlspecialchars($container_path), $access_mode=='ro'?'long-arrow-left':'arrows-h', htmlspecialchars($host_path));
|
||||
}
|
||||
echo "<tr><td style='width:48px;padding:4px'>";
|
||||
echo "<tr class='sortable'><td style='width:48px;padding:4px'>";
|
||||
echo "<div id='$id' style='display:block; cursor:pointer'><div style='position:relative;width:48px;height:48px;margin:0px auto'>";
|
||||
echo "<img src='".htmlspecialchars($icon)."' class='".htmlspecialchars($status)."' style='position:absolute;top:0;bottom:0;left:0;right:0;width:48px;height:48px'>";
|
||||
echo "<i class='fa iconstatus fa-$shape $status' title='".htmlspecialchars($status)."'></i></div></div>";
|
||||
echo "<img src='".htmlspecialchars($icon)."' class='$status' style='position:absolute;top:0;bottom:0;left:0;right:0;width:48px;height:48px'>";
|
||||
echo "<i class='fa iconstatus fa-$shape $status' title='$status'></i></div></div>";
|
||||
echo "</td><td class='ct-name'>";
|
||||
if ($template) {
|
||||
echo "<a class='exec' onclick=\"editContainer('".addslashes(htmlspecialchars($name))."','".addslashes(htmlspecialchars($template))."')\">".htmlspecialchars($name)."</a>";
|
||||
} else {
|
||||
echo htmlspecialchars($name);
|
||||
}
|
||||
echo "<div class='advanced' style='width:160px'>Container ID: ".htmlspecialchars($id)."</div>";
|
||||
echo "<div class='advanced' style='width:160px'>Container ID: $id</div>";
|
||||
if ($ct['BaseImage']) echo "<div class='advanced' style='width:160px;'><i class='fa fa-cubes' style='margin-right:5px'></i>".htmlspecialchars(${ct['BaseImage']})."</div>";
|
||||
echo "<div class='advanced' style='width:160px'>By:";
|
||||
$registry = $info['registry'];
|
||||
@@ -101,8 +102,7 @@ foreach ($containers as $ct) {
|
||||
echo "<td style='word-break:break-all'><span class='docker_readmore'>".implode('<br>',$paths)."</span></td>";
|
||||
echo "<td><input type='checkbox' class='autostart' container='".htmlspecialchars($name)."'".($info['autostart'] ? ' checked':'')."></td>";
|
||||
echo "<td><a class='log' onclick=\"containerLogs('".addslashes(htmlspecialchars($name))."','$id',false,false)\"><img class='basic' src='/plugins/dynamix/icons/log.png'><div class='advanced'>";
|
||||
echo htmlspecialchars(str_replace('Up','Uptime',$ct['Status']))."</div><div class='advanced' style='margin-top:4px'>Created ".htmlspecialchars($ct['Created'])."</div></a></td>";
|
||||
echo "<td style='text-align:right;padding-right:12px'><a href='#' title='Move row up'><i class='fa fa-arrow-up up'></i></a> <a href='#' title='Move row down'><i class='fa fa-arrow-down down'></i></a></td></tr>";
|
||||
echo htmlspecialchars(str_replace('Up','Uptime',$ct['Status']))."</div><div class='advanced' style='margin-top:4px'>Created ".htmlspecialchars($ct['Created'])."</div></a></td></tr>";
|
||||
}
|
||||
foreach ($images as $image) {
|
||||
if (count($image['usedBy'])) continue;
|
||||
@@ -115,7 +115,7 @@ foreach ($images as $image) {
|
||||
echo "</div></div></td>";
|
||||
echo "<td><i>(orphan image)</i><div style='width:160px;'>Image ID: $id</div>";
|
||||
echo "<div style='width:160px'>".implode('<br>',array_map('htmlspecialchars',$image['Tags']))."</div></td>";
|
||||
echo "<td colspan=4'> </td>";
|
||||
echo "<td colspan='5'></td>";
|
||||
echo "<td><div class='advanced' style='width:124px'>Created ".htmlspecialchars($image['Created'])."</div></td></tr>";
|
||||
}
|
||||
echo "\0".implode($menu).implode($docker);
|
||||
|
||||
@@ -27,9 +27,15 @@ switch ($action) {
|
||||
case 'start':
|
||||
if ($container) $arrResponse = ['success' => $DockerClient->startContainer($container)];
|
||||
break;
|
||||
case 'pause':
|
||||
if ($container) $arrResponse = ['success' => $DockerClient->pauseContainer($container)];
|
||||
break;
|
||||
case 'stop':
|
||||
if ($container) $arrResponse = ['success' => $DockerClient->stopContainer($container)];
|
||||
break;
|
||||
case 'resume':
|
||||
if ($container) $arrResponse = ['success' => $DockerClient->resumeContainer($container)];
|
||||
break;
|
||||
case 'restart':
|
||||
if ($container) $arrResponse = ['success' => $DockerClient->restartContainer($container)];
|
||||
break;
|
||||
@@ -85,8 +91,14 @@ switch ($action) {
|
||||
exit;
|
||||
}
|
||||
break;
|
||||
case 'terminal':
|
||||
$pid = exec("pgrep -a ttyd|awk '/\\/$name\\.sock/{print \$1}'");
|
||||
if ($pid) exec("kill $pid");
|
||||
@unlink("/var/tmp/$name.sock");
|
||||
exec("exec ttyd -o -d0 -i '/var/tmp/$name.sock' docker exec -it '$name' sh &>/dev/null &");
|
||||
break;
|
||||
default:
|
||||
$arrResponse = ['error' => 'Unknown action \'' . $action . '\''];
|
||||
$arrResponse = ['error' => "Unknown action '$action'"];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
var eventURL = '/plugins/dynamix.docker.manager/include/Events.php';
|
||||
|
||||
function addDockerContainerContext(container, image, template, started, update, autostart, webui, id, Support, Project) {
|
||||
function addDockerContainerContext(container, image, template, started, paused, update, autostart, webui, id, Support, Project) {
|
||||
var opts = [{header:container, image:'/plugins/dynamix.docker.manager/images/dynamix.docker.manager.png'}];
|
||||
if (started && (webui !== '' && webui != '#')) {
|
||||
opts.push({text:'WebUI', icon:'fa-globe', href:webui, target:'_blank'});
|
||||
if (started && !paused) {
|
||||
if (webui !== '' && webui != '#') opts.push({text:'WebUI', icon:'fa-globe', href:webui, target:'_blank'});
|
||||
opts.push({text:'Console', icon:'fa-terminal', action:function(e){e.preventDefault(); dockerTerminal(container);}});
|
||||
opts.push({divider:true});
|
||||
}
|
||||
if (!update) {
|
||||
@@ -11,7 +12,12 @@ function addDockerContainerContext(container, image, template, started, update,
|
||||
opts.push({divider:true});
|
||||
}
|
||||
if (started) {
|
||||
opts.push({text:'Stop', icon:'fa-stop', action:function(e){e.preventDefault(); eventControl({action:'stop', container:id}, 'loadlist');}});
|
||||
if (paused) {
|
||||
opts.push({text:'Resume', icon:'fa-play', action:function(e){e.preventDefault(); eventControl({action:'resume', container:id}, 'loadlist');}});
|
||||
} else {
|
||||
opts.push({text:'Stop', icon:'fa-stop', action:function(e){e.preventDefault(); eventControl({action:'stop', container:id}, 'loadlist');}});
|
||||
opts.push({text:'Pause', icon:'fa-pause', action:function(e){e.preventDefault(); eventControl({action:'pause', container:id}, 'loadlist');}});
|
||||
}
|
||||
opts.push({text:'Restart', icon:'fa-refresh', action:function(e){e.preventDefault(); eventControl({action:'restart', container:id}, 'loadlist');}});
|
||||
} else {
|
||||
opts.push({text:'Start', icon:'fa-play', action:function(e){e.preventDefault(); eventControl({action:'start', container:id}, 'loadlist');}});
|
||||
@@ -39,6 +45,14 @@ function addDockerImageContext(image, imageTag) {
|
||||
opts.push({text:'Remove', icon:'fa-trash', action:function(e){e.preventDefault(); rmImage(image, imageTag);}});
|
||||
context.attach('#'+image, opts);
|
||||
}
|
||||
function dockerTerminal(container) {
|
||||
var height = 600;
|
||||
var width = 900;
|
||||
var top = (screen.height-height)/2;
|
||||
var left = (screen.width-width)/2;
|
||||
$.get(eventURL,{action:'terminal',name:container});
|
||||
setTimeout(function(){window.open('/dockerterminal/'+container+'/', container, 'resizeable=yes,scrollbars=yes,height='+height+',width='+width+',top='+top+',left='+left).focus();},180);
|
||||
}
|
||||
function execUpContainer(container) {
|
||||
var title = 'Updating the container: '+container;
|
||||
var address = '/plugins/dynamix.docker.manager/include/CreateDocker.php?updateContainer=true&ct[]='+encodeURIComponent(container);
|
||||
@@ -135,7 +149,7 @@ function rmImage(image, imageName) {
|
||||
});
|
||||
}
|
||||
function eventControl(params, spin) {
|
||||
if (spin) $('#'+params['container']).find('i').removeClass('fa-play fa-square').addClass('fa-refresh fa-spin');
|
||||
if (spin) $('#'+params['container']).find('i').removeClass('fa-play fa-square fa-pause').addClass('fa-refresh fa-spin');
|
||||
$.post(eventURL, params, function(data) {
|
||||
if (data.success === true) {
|
||||
if (spin) setTimeout(spin+'()',500); else location=window.location.href;
|
||||
@@ -156,9 +170,19 @@ function startAll() {
|
||||
}
|
||||
function stopAll() {
|
||||
$('input[type=button]').prop('disabled',true);
|
||||
for (var i=0,ct; ct=docker[i]; i++) if (ct.state==1) $('#'+ct.id).find('i').removeClass('fa-play').addClass('fa-refresh fa-spin');
|
||||
for (var i=0,ct; ct=docker[i]; i++) if (ct.state==1) $('#'+ct.id).find('i').removeClass('fa-play fa-pause').addClass('fa-refresh fa-spin');
|
||||
$.post('/plugins/dynamix.docker.manager/include/ContainerManager.php',{action:'stop'},function(){loadlist();});
|
||||
}
|
||||
function pauseAll() {
|
||||
$('input[type=button]').prop('disabled',true);
|
||||
for (var i=0,ct; ct=docker[i]; i++) if (ct.state==1 && ct.pause==0) $('#'+ct.id).find('i').removeClass('fa-play').addClass('fa-refresh fa-spin');
|
||||
$.post('/plugins/dynamix.docker.manager/include/ContainerManager.php',{action:'pause'},function(){loadlist();});
|
||||
}
|
||||
function resumeAll() {
|
||||
$('input[type=button]').prop('disabled',true);
|
||||
for (var i=0,ct; ct=docker[i]; i++) if (ct.state==1 && ct.pause==1) $('#'+ct.id).find('i').removeClass('fa-pause').addClass('fa-refresh fa-spin');
|
||||
$.post('/plugins/dynamix.docker.manager/include/ContainerManager.php',{action:'unpause'},function(){loadlist();});
|
||||
}
|
||||
function checkAll() {
|
||||
$('input[type=button]').prop('disabled',true);
|
||||
$('.updatecolumn').html('<span style="color:#267CA8"><i class="fa fa-refresh fa-spin"></i> checking...</span>');
|
||||
@@ -168,7 +192,7 @@ function updateAll() {
|
||||
$('input[type=button]').prop('disabled',true);
|
||||
$('div.spinner').show('slow');
|
||||
var list = '';
|
||||
for (var i=0,ct; ct=docker[i]; i++) if (ct.update=='false') list += '&ct[]='+ct.name;
|
||||
for (var i=0,ct; ct=docker[i]; i++) if (ct.update=='false') list += '&ct[]='+encodeURI(ct.name);
|
||||
var address = '/plugins/dynamix.docker.manager/include/CreateDocker.php?updateContainer=true'+list;
|
||||
popupWithIframe('Updating all Containers', address, true, 'loadlist');
|
||||
}
|
||||
|
||||
@@ -17,14 +17,16 @@ Code="f1e6"
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
?>
|
||||
|
||||
<?
|
||||
// Remove stale /tmp/plugin/*.plg entries
|
||||
foreach (glob("/tmp/plugins/*.{plg,txt}", GLOB_NOSORT+GLOB_BRACE) as $entry) if (!file_exists("/var/log/plugins/".basename($entry))) @unlink($entry);
|
||||
$check = $notify['version'] ? 0 : 1;
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.filetree.css">
|
||||
<style>#plugin_tree{width:33%;height:200px;overflow-y:scroll}</style>
|
||||
|
||||
<style>
|
||||
#plugin_tree{width:33%;height:200px;overflow-y:scroll}
|
||||
</style>
|
||||
<script src="<?autov('/webGui/javascript/jquery.filetree.js')?>"></script>
|
||||
<script>
|
||||
<?if ($display['resize']):?>
|
||||
|
||||
@@ -16,7 +16,7 @@ Tag="thumbs-up"
|
||||
?>
|
||||
<?
|
||||
$empty = "<tr><td colspan='6'><div class='spinner'></div></td><tr>";
|
||||
$version = $date = 'unknown';
|
||||
$version = $branch = $date = 'unknown';
|
||||
$bzroot = file_exists('/boot/previous/bzroot');
|
||||
$check = $notify['unraidos'] ? 0 : 1;
|
||||
|
||||
@@ -29,8 +29,10 @@ if (file_exists('/boot/previous/changes.txt')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$branch = strpos($version,'rc')===false ? 'Stable' : 'Next';
|
||||
}
|
||||
?>
|
||||
<style>input[value='Install'],input[value='Update'],input[value='Restore']{margin:0}</style>
|
||||
<script>
|
||||
var original = null;
|
||||
|
||||
@@ -85,6 +87,6 @@ $(function() {
|
||||
<thead><tr><th></th><th>Component</th><th>Author</th><th>Version</th><th>Status</th><th>Branch</th></tr></thead>
|
||||
<tbody id="os_list"><?=$empty?></tbody>
|
||||
<?if ($bzroot):?>
|
||||
<tbody id="previous" style="display:none"><tr><td><img src="/plugins/unRAIDServer/images/unRAIDServer.png"></td><td><b>unRAID Server OS (previous)</b></td><td>LimeTech</td><td><?=$version?></td><td><?=$date?></td><td><input type="button" value="Downgrade" onclick="downgrade()"></td></tbody>
|
||||
<tbody id="previous" style="display:none"><tr><td><img src="/plugins/unRAIDServer/images/unRAIDServer.png"></td><td><b>unRAID Server OS (previous)</b></td><td>LimeTech</td><td><?=$version?></td><td><input type="button" value="Restore" onclick="downgrade()"></td><td><?=$branch?></td></tbody>
|
||||
<?endif;?>
|
||||
</table>
|
||||
|
||||
@@ -55,6 +55,8 @@ function icon($name) {
|
||||
if (file_exists($icon)) return $icon;
|
||||
$icon = "plugins/{$plugin}/{$name}.png";
|
||||
if (file_exists($icon)) return $icon;
|
||||
$icon = "plugins/{$name}.png";
|
||||
if (file_exists($icon)) return $icon;
|
||||
// last resort - plugin manager icon
|
||||
return "plugins/dynamix.plugin.manager/images/dynamix.plugin.manager.png";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, 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,
|
||||
@@ -23,7 +23,9 @@ require_once "$docroot/webGui/include/Markdown.php";
|
||||
<body style="margin:14px 10px">
|
||||
<?
|
||||
$file = $_GET['file'];
|
||||
if (file_exists($file) && strpos(realpath($file), '/tmp/plugins/') === 0 && substr($file, -4) == '.txt') echo Markdown(file_get_contents($file)); else echo Markdown("*No release notes available!*");
|
||||
$tmp = $_GET['tmp'] ? '/var/tmp' : '/tmp/plugins/';
|
||||
|
||||
if (file_exists($file) && strpos(realpath($file),$tmp)===0 && substr($file,-4)=='.txt') echo Markdown(file_get_contents($file)); else echo Markdown("*No release notes available!*");
|
||||
?>
|
||||
<br><div style="text-align:center"><input type="button" value="Done" onclick="top.Shadowbox.close()"></div>
|
||||
</body>
|
||||
|
||||
@@ -550,6 +550,7 @@ if ($method == "remove") {
|
||||
// remove the plugin file
|
||||
move($installed_plugin_file, "/boot/config/plugins-removed");
|
||||
echo "plugin: removed\n";
|
||||
exec("/usr/local/sbin/update_cron");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ if (empty($vms)) {
|
||||
}
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/plugins/dynamix.vm.manager/styles/dynamix.vm.manager.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.ui.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.filetree.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<style type="text/css">
|
||||
@@ -109,11 +110,12 @@ div.Panel{float:unset;margin:4px;height:inherit;border:none;}
|
||||
div.Panel:hover{background-color:unset;}
|
||||
div.PanelText{display:none;}
|
||||
th.five{width:5%}
|
||||
tbody > tr.sortable:hover{cursor:move}
|
||||
</style>
|
||||
<div class="spinner fixed"></div>
|
||||
<table id="kvm_table" class="tablesorter shift">
|
||||
<thead><tr><th><i class="fa fa-th-list"></i></th><th>Name</th><th>Description</th><th>CPUs</th><th>Memory</th><th>vDisks</th><th>Graphics</th><th class="five">Autostart</th><th class="five" style="text-align:right;padding-right:24px"><a href="#" style="cursor:hand" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-sort"></i></a></th></tr></thead>
|
||||
<tbody id="kvm_list"><tr><td colspan='9'><div class="spinner"></div></td></tr></tbody>
|
||||
<table id="kvm_table" class="tablesorter four shift">
|
||||
<thead><tr><th><a href="#" style="cursor:hand;margin-left:12px" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-th-list"></i></a></th><th>Name</th><th>Description</th><th>CPUs</th><th>Memory</th><th>vDisks</th><th>Graphics</th><th class="five">Autostart</th></tr></thead>
|
||||
<tbody id="kvm_list"><tr><td colspan='8'><div class="spinner"></div></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" onclick="addVM()" id="btnAddVM" value="Add VM" style="display:none">
|
||||
<input type="button" onclick="startAll()" value="Start all VMs" style="display:none">
|
||||
@@ -141,11 +143,27 @@ function resetSorting() {
|
||||
$('input[type=button]').prop('disabled',true);
|
||||
$.post('/plugins/dynamix.vm.manager/include/UserPrefs.php',{reset:true},function(){loadlist();});
|
||||
}
|
||||
var sortableHelper = function(e,i){
|
||||
i.children().each(function(){
|
||||
$(this).width($(this).width());
|
||||
});
|
||||
return i;
|
||||
};
|
||||
function loadlist() {
|
||||
$.get('/plugins/dynamix.vm.manager/include/VMMachines.php',{show:$.cookie('vmshow')},function(d) {
|
||||
var data = d.split(/\0/);
|
||||
$('div.spinner').hide('slow');
|
||||
$('#kvm_list').html(data[0]);
|
||||
$('#kvm_list').html(data[0]).sortable({helper:sortableHelper,items:'tr.sortable',opacity:0.4,update:function(e,i){
|
||||
$('#kvm_list').find('tr.sortable').each(function(){
|
||||
var parent = $(this).attr('parent-id');
|
||||
var child = $('tr[child-id="'+parent+'"]');
|
||||
child.detach().insertAfter($(this));
|
||||
});
|
||||
var row = $('#kvm_list').find('tr:first');
|
||||
var names = ''; var index = '';
|
||||
row.parent().children().find('td.vm-name').each(function(){names+=$(this).text()+';';index+=$(this).parent().parent().children().index($(this).parent())+';';});
|
||||
$.post('/plugins/dynamix.vm.manager/include/UserPrefs.php',{names:names,index:index});
|
||||
}});
|
||||
$('head').append('<script>'+data[1]+'<\/script>');
|
||||
<?if ($display['resize']):?>
|
||||
resize();
|
||||
@@ -175,27 +193,6 @@ function loadlist() {
|
||||
$('input[type=button]').prop('disabled',false).show('slow');
|
||||
$('.text').click(showInput);
|
||||
$('.input').blur(hideInput);
|
||||
$('i.up,i.down').click(function() {
|
||||
var row1 = $(this).parents('tr:first');
|
||||
var row2 = row1.next();
|
||||
var color1 = row1.css('background-color');
|
||||
if ($(this).is('.up')) {
|
||||
var color2 = row1.prev().prev().css('background-color');
|
||||
row1.prev().prev().css('background-color',color1);
|
||||
row1.css('background-color',color2);
|
||||
row1.insertBefore(row1.prev().prev());
|
||||
row2.insertBefore(row2.prev().prev());
|
||||
} else {
|
||||
var color2 = row1.next().next().css('background-color');
|
||||
row1.next().next().css('background-color',color1);
|
||||
row1.css('background-color',color2);
|
||||
row2.insertAfter(row2.next().next());
|
||||
row1.insertAfter(row1.next().next());
|
||||
}
|
||||
var names = ''; var index = '';
|
||||
row1.parent().children().find('td.vm-name').each(function(){names+=$(this).text()+';';index+=$(this).parent().parent().children().index($(this).parent())+';';});
|
||||
$.post('/plugins/dynamix.vm.manager/include/UserPrefs.php',{names:names,index:index});
|
||||
});
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
|
||||
@@ -81,21 +81,21 @@ foreach ($vms as $vm) {
|
||||
unset($dom);
|
||||
$menu[] = sprintf("addVMContext('%s','%s','%s','%s','%s','%s');", addslashes($vm),addslashes($uuid),addslashes($template),$state,addslashes($vnc),addslashes($log));
|
||||
$kvm[] = "kvm.push({id:'$uuid',state:'$state'});";
|
||||
|
||||
/* VM information */
|
||||
echo "<tr style='background-color:".bcolor($i)."'>";
|
||||
echo "<tr parent-id='$i' class='sortable'>";
|
||||
echo "<td style='width:48px;padding:4px'>".renderVMContentIcon($uuid, $vm, $vmicon, $state)."</td>";
|
||||
echo "<td class='vm-name'><a href='#' onclick='return toggle_id(\"name{$i}\")' title='click for more VM info'>$vm</a></td>";
|
||||
echo "<td class='vm-name'><a href='#' onclick='return toggle_id(\"name-$i\")' title='click for more VM info'>$vm</a></td>";
|
||||
echo "<td>$desc</td>";
|
||||
echo "<td><a class='vcpu-$uuid' style='cursor:pointer'>$vcpu</a></td>";
|
||||
echo "<td>$mem</td>";
|
||||
echo "<td title='$diskdesc'>$disks</td>";
|
||||
echo "<td>$graphics</td>";
|
||||
echo "<td><input class='autostart' type='checkbox' name='auto_{$vm}' title='Toggle VM auostart' uuid='$uuid' $auto></td>";
|
||||
echo "<td style='text-align:right;padding-right:12px'><a href='#' title='Move row up'><i class='fa fa-arrow-up up'></i></a> <a href='#' title='Move row down'><i class='fa fa-arrow-down down'></i></a></td></tr>";
|
||||
echo "<td><input class='autostart' type='checkbox' name='auto_{$vm}' title='Toggle VM auostart' uuid='$uuid' $auto></td></tr>";
|
||||
|
||||
/* Disk device information */
|
||||
echo "<tr id='name{$i}".(in_array('name'.$i++,$show) ? "'>" : "' style='display:none'>");
|
||||
echo "<td colspan='7' style='overflow:hidden'>";
|
||||
echo "<tr child-id='$i' id='name-$i".(in_array('name-'.$i++,$show) ? "'>" : "' style='display:none'>");
|
||||
echo "<td colspan='8' style='overflow:hidden'>";
|
||||
echo "<table class='tablesorter domdisk' id='domdisk_table'>";
|
||||
echo "<thead><tr><th><i class='fa fa-hdd-o'></i><b> Disk devices </b></th><th>Bus</th><th>Capacity</th><th>Allocation</th></tr></thead>";
|
||||
echo "<tbody id='domdisk_list'>";
|
||||
@@ -124,7 +124,6 @@ foreach ($vms as $vm) {
|
||||
}
|
||||
echo "<td>$allocation</td></tr>";
|
||||
}
|
||||
/* end Display VM disks */
|
||||
|
||||
/* Display VM cdroms */
|
||||
foreach ($lv->get_cdrom_stats($res) as $arrCD) {
|
||||
@@ -136,7 +135,6 @@ foreach ($vms as $vm) {
|
||||
echo "<tr><td>$disk</td><td>$bus</td><td>$capacity</td><td>$allocation</td></tr>";
|
||||
}
|
||||
|
||||
/* end Display VM cdroms */
|
||||
echo "</tbody></table>";
|
||||
echo "</td></tr>";
|
||||
}
|
||||
|
||||
@@ -356,13 +356,13 @@
|
||||
$ctrl = '';
|
||||
switch ($usbmode) {
|
||||
case 'usb3':
|
||||
$ctrl = "<controller type='usb' index='0' model='nec-xhci'>
|
||||
$ctrl = "<controller type='usb' index='0' model='nec-xhci' ports='15'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
|
||||
</controller>";
|
||||
break;
|
||||
|
||||
case 'usb3-qemu':
|
||||
$ctrl = "<controller type='usb' index='0' model='qemu-xhci'>
|
||||
$ctrl = "<controller type='usb' index='0' model='qemu-xhci' ports='15'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
|
||||
</controller>";
|
||||
break;
|
||||
|
||||
@@ -663,15 +663,12 @@ table.tablesorter.domsnap td:last-child{width:96px;padding:0;}
|
||||
z-index: 2;
|
||||
bottom: -4px;
|
||||
right: -4px;
|
||||
font-size: 1.2em;
|
||||
text-shadow: 0 0 2px #FFF;
|
||||
}
|
||||
.iconstatus.started {
|
||||
font-size: 1.3em;
|
||||
text-shadow: 0 0 2px #FFF;
|
||||
}
|
||||
img.started{opacity: 1.0;}
|
||||
img.stopped{opacity: 0.3;}
|
||||
img.paused{opacity: 1.0;}
|
||||
img.paused{opacity: 0.6;}
|
||||
.started{color:#009900;}
|
||||
.stopped{color:#EF3D47;}
|
||||
.paused{color:#F0DD33;}
|
||||
|
||||
@@ -34,8 +34,8 @@ list($memory_maximum,$ecc_support) = array_map('trim',explode('#',exec("dmidecod
|
||||
if ($memory_installed >= 1024) {
|
||||
$memory_installed = round($memory_installed/1024);
|
||||
$memory_maximum = round($memory_maximum/1024);
|
||||
$unit = 'GB';
|
||||
} else $unit = 'MB';
|
||||
$size = 'GB';
|
||||
} else $size = 'MB';
|
||||
|
||||
// If maximum < installed then roundup maximum to the next power of 2 size of installed. E.g. 6 -> 8 or 12 -> 16
|
||||
if ($memory_maximum < $memory_installed) $memory_maximum = pow(2,ceil(log($memory_installed)/log(2)));
|
||||
@@ -110,6 +110,7 @@ function parity_status() {
|
||||
} else {
|
||||
echo "<tr><td colspan='2'><span class='red p0'><strong>Data is invalid</strong></span></td></tr>";
|
||||
}
|
||||
echo "<tr><td id='parity' colspan='2'></td></tr>";
|
||||
}
|
||||
}
|
||||
function truncate($string,$len) {
|
||||
@@ -235,7 +236,7 @@ $dck = exec("df /var/lib/docker|grep -om1 '^/'");
|
||||
<tr class='wide'><td>flash log docker</td><td><div class='usage-disk sys'><span id='sys1' style='width:0'></span></div></td><td><div class='usage-disk sys'><span id='sys2' style='width:0'></span></div></td>
|
||||
<td><?if ($dck):?><div class='usage-disk sys'><span id='sys3' style='width:0'></span></div><?else:?>Not available<?endif;?></td></tr>
|
||||
<tr><td rowspan='2'>Memory size</td><td>allocated</td><td colspan='2' class='blue'><?=my_scale($total,$unit,3)." $unit"?></td></tr>
|
||||
<tr><td>installed</td><td colspan='2' class='blue'><?="$memory_installed $unit ".($ecc_support=='None'?'':$ecc_support)."<br>max. installable capacity $memory_maximum $unit"?></td></tr>
|
||||
<tr><td>installed</td><td colspan='2' class='blue'><?="$memory_installed $size ".($ecc_support=='None'?'':$ecc_support)."<br>max. installable capacity $memory_maximum $size"?></td></tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
<?if (count($ports)>1):?><tr class='view1'><td rowspan='<?=count($ports)?>'><?else:?><tr class='view1 wide'><td><?endif;?>Network</td>
|
||||
@@ -522,7 +523,7 @@ function toggle_CPU(init) {
|
||||
}
|
||||
$.cookie('cpu')===undefined ? $('.cpu_open').show() : $('.cpu_open').hide();
|
||||
}
|
||||
var cpuload = new NchanSubscriber('/sub/cpuload');
|
||||
var cpuload = new NchanSubscriber('/sub/cpuload', /^((?!chrome|android).)*safari/i.test(navigator.userAgent) ? {subscriber:'longpoll'} : {});
|
||||
cpuload.on('message',function(data) {
|
||||
/*
|
||||
message should be something like: {"cpuload": {"cpu":[0,0],"cpu0":[0,0],"cpu1":[0,0],"cpu2":[0,0],"cpu3":[0,0]}}
|
||||
|
||||
@@ -11,14 +11,13 @@ body{-webkit-overflow-scrolling:touch}
|
||||
label{display:inline}
|
||||
iframe{overflow:scroll;-webkit-overflow-scrolling:touch}
|
||||
h2{color:#625D5D;letter-spacing:0;font-family:arimo;font-size:32px;line-height:1.2em;font-weight:300;padding:0 0 20px;margin:0}
|
||||
.iconstatus{position:absolute;z-index:2;bottom:-4px;right:-4px;font-size:1.2em;text-shadow:0 0 2px #FFF}
|
||||
.iconstatus.started{font-size:1.3em}
|
||||
.iconstatus{position:absolute;z-index:2;bottom:-4px;right:-4px;font-size:1.3em;text-shadow:0 0 2px #FFF}
|
||||
img.started{opacity:1.0}
|
||||
img.stopped{opacity:0.3}
|
||||
img.paused{opacity:1.0}
|
||||
img.paused{opacity:0.6}
|
||||
.started{color:#009900}
|
||||
.paused{color:#F0DD33}
|
||||
.stopped{color:#EF3D47}
|
||||
.paused{color:#F0DD33}
|
||||
.update{color:#3300FF}
|
||||
.show{display:block}
|
||||
div.Panel{float:none;display:inline-block;margin:0 18px 15px 0;height:90px;overflow:hidden;vertical-align:top;width:94px;word-wrap:break-word;border:none}
|
||||
@@ -38,7 +37,7 @@ div.Panel:hover{overflow:visible;z-index:10;background-color:unset}
|
||||
</form>
|
||||
<div id="dialog-confirm" style="display:none;" title="Dialog Title"></div>
|
||||
<div id="iframe-popup" style="display:none;-webkit-overflow-scrolling:touch;"></div>
|
||||
<span class="status" style="margin-top:-44px; margin-right:<?= ($display['refresh']==0 || ($display['refresh']<0 && $var['mdResync']>0)) ? '60' : '0' ?>px"><input type="checkbox" class="appview"></span>
|
||||
<span class="status" style="margin-top:-44px; margin-right:0"><input type="checkbox" class="appview"></span>
|
||||
<div id="apps_icons" style="display:none"></div><div id="noapps">No apps available to show</div>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
@@ -51,8 +50,8 @@ function loadlist() {
|
||||
$('#apps_icons').html(data[0]);
|
||||
$('head').append('<script>'+data[1]+'<\/script>');
|
||||
if ($.cookie('dashapps_view_mode')=='startedonly') {
|
||||
$('.Panel').not('.started').hide();
|
||||
if ($('.Panel.started').length===0) $('#noapps').show();
|
||||
$('.Panel.stopped').hide();
|
||||
if ($('.Panel.started').length===0 && $('.Panel.paused').length===0) $('#noapps').show();
|
||||
}
|
||||
if ($('.Panel').length===0) $('#noapps').show();
|
||||
$('#apps_icons').slideDown('fast');
|
||||
@@ -62,8 +61,8 @@ function loadlist() {
|
||||
$(function() {
|
||||
$('.appview').switchButton({labels_placement:"left", on_label:'Started Only', off_label:'All Apps', checked:$.cookie('dashapps_view_mode') == 'startedonly'});
|
||||
$('.appview').change(function() {
|
||||
$('.Panel').not('.started').finish().toggle('fast');
|
||||
if ($('.Panel').length===0 || ($('.appview').is(':checked') && $('.Panel.started').length===0)) {
|
||||
$('.Panel.stopped').finish().toggle('fast');
|
||||
if ($('.Panel').length===0 || ($('.appview').is(':checked') && $('.Panel.started').length===0 && $('.Panel.paused').length===0)) {
|
||||
$('#noapps').slideDown('fast');
|
||||
} else {
|
||||
$('#noapps').slideUp('fast');
|
||||
|
||||
@@ -288,6 +288,7 @@ function checkDNSSettings6(form) {
|
||||
form.DNS6_SERVER1.disabled = disabled;
|
||||
form.DNS6_SERVER2.disabled = disabled;
|
||||
form.DNS6_SERVER3.disabled = disabled;
|
||||
if (!form.DNS6_SERVER1.value && disabled) $('#dns6server1').hide(); else $('#dns6server1').show();
|
||||
if (!form.DNS6_SERVER2.value && disabled) $('#dns6server2').hide(); else $('#dns6server2').show();
|
||||
if (!form.DNS6_SERVER3.value && disabled) $('#dns6server3').hide(); else $('#dns6server3').show();
|
||||
}
|
||||
@@ -365,7 +366,7 @@ function portcheck_eth0() {
|
||||
function portToggle(port,cmd) {
|
||||
$.post('/webGui/include/PortToggle.php',{port:port,cmd:cmd},function(){refresh();});
|
||||
}
|
||||
var watchDHCP = new NchanSubscriber('/sub/dhcp');
|
||||
var watchDHCP = new NchanSubscriber('/sub/dhcp', /^((?!chrome|android).)*safari/i.test(navigator.userAgent) ? {subscriber:'longpoll'} : {});
|
||||
watchDHCP.on('message', function(data) {
|
||||
data = data.split(' ');
|
||||
for (var i=0,row; row=data[i]; i++) {
|
||||
@@ -399,6 +400,9 @@ $(function() {
|
||||
$('#bridge-eth0').dropdownchecklist('disable');
|
||||
if (form.DNS_SERVER2.value) $('#dnsserver2').show(); else $('#dnsserver2').hide();
|
||||
if (form.DNS_SERVER3.value) $('#dnsserver3').show(); else $('#dnsserver3').hide();
|
||||
if (form.DNS6_SERVER1.value) $('#dns6server1').show(); else $('#dns6server1').hide();
|
||||
if (form.DNS6_SERVER2.value) $('#dns6server2').show(); else $('#dns6server2').hide();
|
||||
if (form.DNS6_SERVER3.value) $('#dns6server3').show(); else $('#dns6server3').hide();
|
||||
<?else:?>
|
||||
checkDNSSettings(form);
|
||||
checkDNSSettings6(form);
|
||||
@@ -552,6 +556,7 @@ IPv4 address assignment:
|
||||
<div class="more-ipv4-eth0-<?=$i?>" style="display:none" markdown="1">
|
||||
IPv4 address:
|
||||
: <input type="text" name="IPADDR:<?=$i?>" maxlength="15" value="<?=$eth0["IPADDR:$i"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">/ <select name="NETMASK:<?=$i?>" size="1" class="slim">
|
||||
<?=mk_option($eth0["NETMASK:$i"], "255.0.0.0", "8");?>
|
||||
<?=mk_option($eth0["NETMASK:$i"], "255.255.0.0", "16");?>
|
||||
<?=mk_option($eth0["NETMASK:$i"], "255.255.128.0", "17");?>
|
||||
<?=mk_option($eth0["NETMASK:$i"], "255.255.192.0", "18");?>
|
||||
@@ -645,6 +650,7 @@ IPv6 privacy extensions:
|
||||
> Enable or disable the generation of a random IPv6 interface identifier according to RFC4941. This is similar to the temporary IPv6 address generation on Windows machines.
|
||||
|
||||
</div>
|
||||
<div id="dns6server1" style="display:none" markdown="1">
|
||||
IPv6 DNS server assignment:
|
||||
: <select name="DHCP6_KEEPRESOLV" size="1" onchange="checkDNSSettings6(this.form)">
|
||||
<?=mk_option($eth0['DHCP6_KEEPRESOLV'], "no", "Automatic");?>
|
||||
@@ -659,6 +665,7 @@ IPv6 DNS server:
|
||||
|
||||
> This is the primary IPv6 DNS server to use. Enter a IPv6 address.
|
||||
|
||||
</div>
|
||||
<div id="dns6server2" style="display:none" markdown="1">
|
||||
IPv6 DNS server 2:
|
||||
: <input type="text" name="DNS6_SERVER2" maxlength="39" value="<?=$eth0['DNS6_SERVER2'];?>" pattern="<?=$validIP6?>" title="IPv6 address nnnn:xxxx::yyyy">
|
||||
@@ -675,7 +682,7 @@ IPv6 DNS server 3:
|
||||
</div>
|
||||
</div>
|
||||
Desired MTU:
|
||||
: <input type="number" name="MTU" min="68" max="9198" value="<?=$eth0['MTU']?>" class="narrow">
|
||||
: <input type="number" name="MTU" min="68" max="9198" value="<?=$eth0['MTU']?>" class="narrow" placeholder="<?=exec("ip link show dev eth0|grep -Pom1 'mtu \K\d+'")?>">
|
||||
|
||||
> This is the MTU size to use on the physical Ethernet interface.
|
||||
> If left blank, the MTU will automatically be determined (by default 1500 bytes).
|
||||
@@ -724,6 +731,7 @@ IPv4 address assignment:
|
||||
<div class="more-ipv4-eth0-<?=$i?>" style="display:none" markdown="1">
|
||||
IPv4 address:
|
||||
: <input type="text" name="IPADDR:<?=$i?>" maxlength="15" value="<?=$eth0["IPADDR:$i"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">/ <select name="NETMASK:<?=$i?>" size="1" class="slim">
|
||||
<?=mk_option($eth0["NETMASK:$i"], "255.0.0.0", "8");?>
|
||||
<?=mk_option($eth0["NETMASK:$i"], "255.255.0.0", "16");?>
|
||||
<?=mk_option($eth0["NETMASK:$i"], "255.255.128.0", "17");?>
|
||||
<?=mk_option($eth0["NETMASK:$i"], "255.255.192.0", "18");?>
|
||||
@@ -831,6 +839,7 @@ IPv4 address assignment:
|
||||
<div class="more-ipv4-eth0-INDEX" style="display:none" markdown="1">
|
||||
IPv4 address:
|
||||
: <input type="text" name="IPADDR:INDEX" maxlength="15" value="<?=$eth0["IPADDR:INDEX"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">/ <select name="NETMASK:INDEX" size="1" class="slim">
|
||||
<?=mk_option($eth0["NETMASK:INDEX"], "255.0.0.0", "8");?>
|
||||
<?=mk_option($eth0["NETMASK:INDEX"], "255.255.0.0", "16");?>
|
||||
<?=mk_option($eth0["NETMASK:INDEX"], "255.255.128.0", "17");?>
|
||||
<?=mk_option($eth0["NETMASK:INDEX"], "255.255.192.0", "18");?>
|
||||
|
||||
@@ -227,6 +227,7 @@ IPv4 address assignment:
|
||||
<div class="more-ipv4-ethX-<?=$i?>" style="display:none" markdown="1">
|
||||
IPv4 address:
|
||||
: <input type="text" name="IPADDR:<?=$i?>" maxlength="15" value="<?=$ethX["IPADDR:$i"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">/ <select name="NETMASK:<?=$i?>" size="1" class="slim">
|
||||
<?=mk_option($ethX["NETMASK:$i"], "255.0.0.0", "8");?>
|
||||
<?=mk_option($ethX["NETMASK:$i"], "255.255.0.0", "16");?>
|
||||
<?=mk_option($ethX["NETMASK:$i"], "255.255.128.0", "17");?>
|
||||
<?=mk_option($ethX["NETMASK:$i"], "255.255.192.0", "18");?>
|
||||
@@ -291,7 +292,7 @@ IPv6 privacy extensions:
|
||||
</div>
|
||||
</div>
|
||||
Desired MTU:
|
||||
: <input type="number" name="MTU" min="68" max="9198" value="<?=$locked?$ethX['MTU']:$ethX['MTU']?>" class="narrow">
|
||||
: <input type="number" name="MTU" min="68" max="9198" value="<?=$locked?$ethX['MTU']:$ethX['MTU']?>" class="narrow" placeholder="<?=exec("ip link show dev ethX|grep -Pom1 'mtu \K\d+'")?>">
|
||||
|
||||
> This is the MTU size to use on the physical Ethernet interface.
|
||||
> If left blank, the MTU will automatically be determined (by default 1500 bytes).
|
||||
@@ -341,6 +342,7 @@ IPv4 address assignment:
|
||||
<div class="more-ipv4-ethX-<?=$i?>" style="display:none" markdown="1">
|
||||
IPv4 address:
|
||||
: <input type="text" name="IPADDR:<?=$i?>" maxlength="15" value="<?=$ethX["IPADDR:$i"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">/ <select name="NETMASK:<?=$i?>" size="1" class="slim">
|
||||
<?=mk_option($ethX["NETMASK:$i"], "255.0.0.0", "8");?>
|
||||
<?=mk_option($ethX["NETMASK:$i"], "255.255.0.0", "16");?>
|
||||
<?=mk_option($ethX["NETMASK:$i"], "255.255.128.0", "17");?>
|
||||
<?=mk_option($ethX["NETMASK:$i"], "255.255.192.0", "18");?>
|
||||
@@ -446,6 +448,7 @@ IPv4 address assignment:
|
||||
<div class="more-ipv4-ethX-INDEX" style="display:none" markdown="1">
|
||||
IPv4 address:
|
||||
: <input type="text" name="IPADDR:INDEX" maxlength="15" value="<?=$ethX["IPADDR:INDEX"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">/ <select name="NETMASK:INDEX" size="1" class="slim">
|
||||
<?=mk_option($ethX["NETMASK:INDEX"], "255.0.0.0", "8");?>
|
||||
<?=mk_option($ethX["NETMASK:INDEX"], "255.255.0.0", "16");?>
|
||||
<?=mk_option($ethX["NETMASK:INDEX"], "255.255.128.0", "17");?>
|
||||
<?=mk_option($ethX["NETMASK:INDEX"], "255.255.192.0", "18");?>
|
||||
|
||||
@@ -20,14 +20,21 @@ Tag="share-alt-square"
|
||||
|
||||
<?
|
||||
$file = "/boot/config/smb-extra.conf";
|
||||
$text = @file_get_contents($file);
|
||||
$text = @file_get_contents($file) ?: '';
|
||||
$text = preg_replace(["/\r\n/","/\r/"],"\n",$text);
|
||||
?>
|
||||
<script>
|
||||
$(function(){
|
||||
$('form').find('textarea').on('input change',function(){
|
||||
$(this).prop('rows',($(this).val().match(/\n/g)||[]).length+1);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.file.php">
|
||||
<input type="hidden" name="#file" value="<?=$file;?>">
|
||||
Samba extra configuration:
|
||||
|
||||
: <textarea spellcheck="false" cols="80" rows="22" maxlength="2048" name="text" style="font-family:bitstream;width:66%"><?=htmlspecialchars($text)?></textarea>
|
||||
: <textarea spellcheck="false" cols="80" rows="<?=substr_count($text,"\n")+1?>" maxlength="2048" name="text" style="resize:none;font-family:bitstream;width:65.5%"><?=htmlspecialchars($text)?></textarea>
|
||||
|
||||
|
||||
: <input type="submit" value="Apply" disabled><input type="button" value="Done" onclick="done()">
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="Syslinux Configuration"
|
||||
Tag="edit"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, 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,
|
||||
@@ -14,46 +14,227 @@ Tag="edit"
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
?>
|
||||
> Use this page to make changes to your `syslinux.cfg` file. You will
|
||||
> need to reboot your server for these changes to take effect.
|
||||
> Use this page to make changes to your `syslinux.cfg` file.
|
||||
> You will need to reboot your server for these changes to take effect.
|
||||
|
||||
<?
|
||||
$file = "/boot/syslinux/syslinux.cfg";
|
||||
$text = file_get_contents($file);
|
||||
$default_text = @file_get_contents("$file-");
|
||||
if ($default_text === false) $default_text = $text;
|
||||
function strip($area) {
|
||||
return preg_replace(["/^|(\n) /","/\n$/"],["$1",""],$area);
|
||||
}
|
||||
$file = '/boot/syslinux/syslinux.cfg';
|
||||
$current = file_get_contents($file);
|
||||
$default = @file_get_contents("$file-") ?: $current;
|
||||
$current = preg_replace(["/\r\n/","/\r/","/\n$/"],["\n","\n",""],$current);
|
||||
$default = preg_replace(["/\r\n/","/\r/","/\n$/"],["\n","\n",""],$default);
|
||||
|
||||
$title = 'Global Configuration';
|
||||
$menu = 'menu default';
|
||||
$mark = 'label ';
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.switchbutton.css">
|
||||
<style>
|
||||
div.basic{display:block}
|
||||
div.advanced{display:none}
|
||||
<?
|
||||
switch ($display['theme']) {
|
||||
case 'gray':
|
||||
case 'azure':
|
||||
echo "span.array,span.system{margin-left:33.33%;width:65.5%;padding:2px 10px;font-weight:bold;border:solid 1px #606E7F;border-bottom:none}\n";
|
||||
echo "textarea.menu{margin-left:33.33%;width:65.5%;margin-bottom:12px;font-family:bitstream;resize:none;border-top:none}\n";
|
||||
break;
|
||||
case 'white':
|
||||
echo "span.array,span.system{margin-left:33.33%;width:65.5%;padding:1px 8px;font-weight:bold;border:solid 1px #E0E0E0;border-bottom:none}\n";
|
||||
echo "textarea.menu{margin-left:33.33%;width:65.5%;margin-bottom:12px;font-family:bitstream;resize:none;border-top:none;border-radius:0}\n";
|
||||
break;
|
||||
case 'black':
|
||||
echo "span.array,span.system{margin-left:33.33%;width:65.5%;padding:1px 8px;font-weight:bold;border:solid 1px #404040;border-bottom:none}\n";
|
||||
echo "textarea.menu{margin-left:33.33%;width:65.5%;margin-bottom:12px;font-family:bitstream;resize:none;border-top:none;border-radius:0}\n";
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</style>
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
<script>
|
||||
function setArg(boot) {
|
||||
$('input[name="#arg[1]"]').val(boot?1:0);
|
||||
const menu = '<?=$menu?>';
|
||||
const title = '<?=$title?>';
|
||||
const mark = '<?=$mark?>';
|
||||
|
||||
Array.prototype.indent = function(o) {
|
||||
if (o) for (var i=0; i < this.length; i++) this[i] = ' '+this[i];
|
||||
return this;
|
||||
};
|
||||
Array.prototype.spliceArray = function(i,n,a) {
|
||||
return Array.prototype.splice.apply(this,[i,n].concat(a));
|
||||
};
|
||||
function prepareMenu(form) {
|
||||
$('input[name="#arg[1]"]').val(form.boot.checked?1:0);
|
||||
if ($('div.basic').is(':visible')) {
|
||||
form.text.value = form.basic.value+'\n';
|
||||
} else {
|
||||
var label = [], area = [];
|
||||
$(form).find('span[id^=label]').each(function(){
|
||||
label.push($(this).text());
|
||||
});
|
||||
$(form).find('textarea.menu').each(function(i){
|
||||
var start = $('#input-'+i).prop('checked') ? menu+'\n' : '';
|
||||
area.push(start+$(this).val());
|
||||
});
|
||||
var text = [];
|
||||
for (var i=0; i < label.length; i++) {
|
||||
if (i==0) {
|
||||
text.push(area[i]);
|
||||
} else {
|
||||
text.push(mark+label[i]);
|
||||
text.push(area[i].replace(/^|(\n)/g,'$1 '));
|
||||
}
|
||||
}
|
||||
form.text.value = text.join('\n')+'\n';
|
||||
}
|
||||
form.basic.disabled = true;
|
||||
}
|
||||
function setDefault(form) {
|
||||
form.elements['text'].value = <?=json_encode($default_text);?>;
|
||||
var text = <?=json_encode(array_map('strip',explode($mark,$default)))?>;
|
||||
$(form).find('textarea.menu').each(function(i){
|
||||
if (i < text.length) {
|
||||
var area = text[i].split('\n');
|
||||
var label = (i) ? area.shift():title;
|
||||
var start = (area[0]==menu);
|
||||
var checked = start ? ' checked':'';
|
||||
if (i) label += "<span style='float:right'><input type='checkbox' id='input-"+i+"' title='Set default boot menu' onchange='changeMenu(this.form,this.id,true)'"+checked+"></span>";
|
||||
$('#label-'+i).html(label).prop('class',start ? 'array':'system');
|
||||
if (start) area.shift();
|
||||
$(this).val(area.join('\n')).prop('rows',area.length).trigger('change');
|
||||
} else {
|
||||
$('#label-'+i).remove();
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
$(form).find('textarea.text').val(<?=json_encode($default)?>).prop('rows',$(this).val().match(/\n/g).length+1).trigger('change');
|
||||
}
|
||||
function changeMenu(form,id,update) {
|
||||
$(form).find('input.menu').each(function(){
|
||||
// highlight default boot menu
|
||||
var i = $(this).prop('id');
|
||||
var label = $('#'+i.replace('input','label'));
|
||||
if (i == id) {
|
||||
label.prop('class','array');
|
||||
$(this).prop('checked',true);
|
||||
} else {
|
||||
label.prop('class','system');
|
||||
$(this).prop('checked',false);
|
||||
}
|
||||
});
|
||||
if (update) {
|
||||
// advanced view -> update basic view
|
||||
var n = 0, o = null;
|
||||
var x = id.split('-')[1];
|
||||
var text = form.basic.value.split('\n');
|
||||
for (var i=0; i < text.length; i++) {
|
||||
if (text[i].indexOf(mark) >= 0) if (++n == x) o = i + 1;
|
||||
if (text[i].indexOf(menu) >= 0) text.splice(i,1);
|
||||
}
|
||||
if (o) text.splice(o,0,' '+menu);
|
||||
$(form).find('textarea.text').val(text.join('\n')).prop('rows',text.length);
|
||||
}
|
||||
}
|
||||
$(function(){
|
||||
$('form').find('textarea').each(function(){$(this).on('input change',function(event){
|
||||
$(this).prop('rows',($(this).val().match(/\n/g)||[]).length+1);
|
||||
if (event.type == 'input') return;
|
||||
// propogate changes to 'other' view mode
|
||||
var form = $(this).closest('form');
|
||||
if ($(this).prop('class')=='menu') {
|
||||
// advanced view -> update basic view
|
||||
var n = 0, o = 0, x = null;
|
||||
var id = $(this).prop('id').split('-')[1];
|
||||
var area = $(this).val().split('\n');
|
||||
var basic = form.find('textarea.text');
|
||||
var text = basic.val().split('\n');
|
||||
for (var i=0; i < text.length; i++) {
|
||||
if (text[i].indexOf(mark) >= 0) {
|
||||
if (n++ == id) x = i; else o = i + 1;
|
||||
}
|
||||
if (text[i].indexOf(menu) >= 0) o++;
|
||||
if (x) break;
|
||||
}
|
||||
text.spliceArray(o,(x||text.length)-o,area.indent(o));
|
||||
basic.val(text.join('\n')).prop('rows',text.length);
|
||||
} else {
|
||||
// basic view -> update advanced view
|
||||
var n = 0, id = null, area = [];
|
||||
var text = $(this).val().split('\n');
|
||||
for (var i=0; i < text.length; i++) {
|
||||
if (text[i].indexOf(mark) >= 0) {
|
||||
$('#text-'+(n++)).val(area.join('\n')).prop('rows',area.length);
|
||||
var label = $('#label-'+n);
|
||||
label.html(label.html().replace(/^.*(<span.*)/,text[i].replace(mark,'')+'$1'));
|
||||
area = [];
|
||||
} else {
|
||||
if (text[i].indexOf(menu) >= 0) id = 'input-'+n; else if (text[i].length) area.push(text[i].replace(/^ /,''));
|
||||
}
|
||||
}
|
||||
$('#text-'+n).val(area.join('\n')).prop('rows',area.length);
|
||||
if (id) changeMenu(form,id,false);
|
||||
}
|
||||
});});
|
||||
if ($.cookie('syslinux_viewmode')=='advanced') {
|
||||
$('.advanced').show();
|
||||
$('.basic').hide();
|
||||
}
|
||||
$('.advancedview').switchButton({
|
||||
labels_placement: 'left',
|
||||
on_label: 'Advanced View',
|
||||
off_label: 'Basic View',
|
||||
checked: $.cookie('syslinux_viewmode')=='advanced'
|
||||
});
|
||||
$('.advancedview').change(function() {
|
||||
$('.advanced').toggle('slow');
|
||||
$('.basic').toggle('slow');
|
||||
$.cookie('syslinux_viewmode', $('.advancedview').is(':checked') ? 'advanced':'basic', {expires:3650});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="setArg(this.boot.checked)">
|
||||
<span class="status" style="margin-top:-44px"><input type="checkbox" class="advancedview"></span>
|
||||
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareMenu(this)">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.file.php">
|
||||
<input type="hidden" name="#file" value="<?=$file;?>">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/bootmode">
|
||||
<input type="hidden" name="#arg[1]" value="">
|
||||
<input type="hidden" name="text" value="">
|
||||
<div markdown="1" class="basic">
|
||||
Syslinux configuration:
|
||||
: <textarea class="text" name="basic" spellcheck="false" cols="80" rows="<?=substr_count($current,"\n")+1?>" maxlength="2048" style="resize:none;font-family:bitstream;width:65.5%"><?=$current?></textarea>
|
||||
|
||||
: <textarea spellcheck="false" cols="80" rows="22" maxlength="2048" name="text" style="font-family:bitstream;width:66%"><?=$text;?></textarea>
|
||||
</div>
|
||||
<div markdown="1" class="advanced">
|
||||
Syslinux configuration:
|
||||
: <?$i=0;
|
||||
foreach (array_map('strip',explode($mark,$current)) as $area):
|
||||
$area = explode("\n", $area);
|
||||
$label = ($i) ? array_shift($area):$title;
|
||||
$start = in_array($menu,$area);
|
||||
if ($start) unset($area[array_search($menu,$area)]);
|
||||
?><span id="label-<?=$i?>" class="<?=$start?'array':'system'?>"><?=$label?>
|
||||
<?if ($i):?><span style="float:right"><input type="checkbox" id="input-<?=$i?>" class="menu" <?=$start?'checked':''?> title="Set default boot menu" onchange="changeMenu(this.form,this.id,true)"></span><?endif;?></span>
|
||||
<textarea class="menu" id="text-<?=$i++?>" spellcheck="false" cols="80" rows="<?=count($area)?>" maxlength="2048"><?=implode("\n",$area)?></textarea>
|
||||
<?endforeach;?>
|
||||
|
||||
</div>
|
||||
Server boot mode:
|
||||
: <?=is_dir('/sys/firmware/efi') ? 'UEFI' : 'Legacy'?>
|
||||
|
||||
Permit UEFI boot mode <input type="checkbox" name="boot" <?=is_dir('/boot/EFI') ? 'checked' : ''?>>
|
||||
Permit UEFI boot mode <input type="checkbox" name="boot" <?=is_dir('/boot/EFI')?'checked':''?>>
|
||||
: *Boot system in UEFI mode. Please check your system settings to support UEFI boot mode.*
|
||||
|
||||
<input type="button" value="Default" onclick="setDefault(this.form)">
|
||||
: <input type="submit" value="Apply"/><input type="button" value="Done" onclick="done()">
|
||||
: <input type="submit" value="Apply"><input type="button" value="Done" onclick="done()">
|
||||
|
||||
> Click the **Apply** button to commit the current edits. Click **Reset** to
|
||||
> undo any changes you make (before Saving). Click **Done** to exit this page.
|
||||
>
|
||||
> Click the **Default** button to initialize the edit box with the
|
||||
> factory-default contents. You still need to click **Apply** in order to
|
||||
>commit the change.
|
||||
>
|
||||
> Click the **Apply** button to commit the current edits. Click **Reset** to
|
||||
> undo any changes you make (before Saving). Click **Done** to exit this page.
|
||||
|
||||
</form>
|
||||
|
||||
@@ -123,24 +123,24 @@ function stage($i) {
|
||||
}
|
||||
} else {
|
||||
$d = $i ? ($now ? $D : today($i)) : today(last_day()-6);
|
||||
$i = $i ?: last_day()-6;
|
||||
$D = mkdate($d, $i);
|
||||
$s = $i ?: last_day()-6;
|
||||
$D = mkdate($d, $s);
|
||||
$t = mktime($h,$m,0,$M,$D,$Y)-$time; // first day
|
||||
if ($t < 0) {
|
||||
$D = mkdate(next_day($d), $i);
|
||||
$D = mkdate(next_day($d), $s);
|
||||
$t = mktime($h,$m,0,$M,$D,$Y)-$time; // next day
|
||||
}
|
||||
if ($t < 0) {
|
||||
$M = find_month($M+1);
|
||||
$i = $i ?: last_day()-6;
|
||||
$D = mkdate(today($i), $i);
|
||||
$s = $i ?: last_day()-6;
|
||||
$D = mkdate(today($s), $s);
|
||||
$t = mktime($h,$m,0,$M,$D,$Y)-$time; // next month
|
||||
}
|
||||
if ($t < 0) {
|
||||
$Y++;
|
||||
$M = find_month(1);
|
||||
$i = $i ?: last_day()-6;
|
||||
$D = mkdate(today($i), $i);
|
||||
$s = $i ?: last_day()-6;
|
||||
$D = mkdate(today($s), $s);
|
||||
$t = mktime($h,$m,0,$M,$D,$Y)-$time; // next year
|
||||
}
|
||||
}
|
||||
@@ -297,7 +297,7 @@ case 'port':
|
||||
break;
|
||||
case 'parity':
|
||||
$var = parse_ini_file("state/var.ini");
|
||||
if ($var['mdNumInvalid']==0 && $var['mdResync']>0) {
|
||||
if ($var['mdResync']>0) {
|
||||
$mode = '';
|
||||
if (strstr($var['mdResyncAction'],"recon")) {
|
||||
$mode = 'Parity-Sync / Data-Rebuild';
|
||||
@@ -309,8 +309,8 @@ case 'parity':
|
||||
$mode = 'Parity-Check';
|
||||
}
|
||||
echo "<span class='orange p0'><strong>".$mode." in progress... Completed: ".number_format(($var['mdResyncPos']/($var['mdResync']/100+1)),0)." %.</strong></span>";
|
||||
echo "<br><em>Elapsed time: ".my_clock(floor((time()-$var['sbUpdated'])/60)).". Estimated finish: ".my_clock(round(((($var['mdResyncDt']*(($var['mdResync']-$var['mdResyncPos'])/($var['mdResyncDb']/100+1)))/100)/60),0))."</em>";
|
||||
} elseif ($var['mdNumInvalid']==0) {
|
||||
echo "<br><i class='fa fa-clock-o'></i> <em>Elapsed time: ".my_clock(floor((time()-$var['sbUpdated'])/60)).". Estimated finish: ".my_clock(round(((($var['mdResyncDt']*(($var['mdResync']-$var['mdResyncPos'])/($var['mdResyncDb']/100+1)))/100)/60),0))."</em>";
|
||||
} else {
|
||||
extract(parse_plugin_cfg('dynamix', true));
|
||||
list($m,$h) = explode(' ', $parity['hour']);
|
||||
$time = time();
|
||||
@@ -378,8 +378,6 @@ case 'parity':
|
||||
echo "</strong><br><i class='fa fa-clock-o'></i> <em>Due in: ";
|
||||
echo my_clock(floor($t/60));
|
||||
echo "</em>";
|
||||
} else {
|
||||
echo "<i class='fa fa-warning'></i> Array contains {$var['mdNumInvalid']} invalid disk(s)";
|
||||
}
|
||||
break;
|
||||
case 'shares':
|
||||
|
||||
@@ -25,7 +25,7 @@ if (pgrep('dockerd')!==false && ($display=='icons' || $display=='docker')) {
|
||||
$DockerClient = new DockerClient();
|
||||
$DockerTemplates = new DockerTemplates();
|
||||
$containers = $DockerClient->getDockerContainers();
|
||||
$all_info = $DockerTemplates->getAllInfo();
|
||||
$allInfo = $DockerTemplates->getAllInfo();
|
||||
|
||||
if (file_exists($user_prefs)) {
|
||||
$prefs = parse_ini_file($user_prefs); $sort = [];
|
||||
@@ -36,17 +36,18 @@ if (pgrep('dockerd')!==false && ($display=='icons' || $display=='docker')) {
|
||||
foreach ($containers as $ct) {
|
||||
$name = $ct['Name'];
|
||||
$id = $ct['Id'];
|
||||
$running = $ct['Running'] ? 1:0;
|
||||
$info = &$all_info[$name];
|
||||
$info = &$allInfo[$name];
|
||||
$running = $info['running'] ? 1:0;
|
||||
$paused = $info['paused'] ? 1:0;
|
||||
$is_autostart = $info['autostart'] ? 'true':'false';
|
||||
$updateStatus = $info['updated']=='true'||$info['updated']=='undef' ? 'true':'false';
|
||||
$template = $info['template'];
|
||||
$webGui = html_entity_decode($info['url']);
|
||||
$support = html_entity_decode($info['Support']);
|
||||
$project = html_entity_decode($info['Project']);
|
||||
$menu[] = sprintf("addDockerContainerContext('%s','%s','%s',%s,%s,%s,'%s','%s','%s','%s');", addslashes($name), addslashes($ct['ImageId']), addslashes($template), $running, $updateStatus, $is_autostart, addslashes($webGui), $id, addslashes($support), addslashes($project));
|
||||
$shape = $running ? 'play':'square';
|
||||
$status = $running ? 'started':'stopped';
|
||||
$menu[] = sprintf("addDockerContainerContext('%s','%s','%s',%s,%s,%s,%s,'%s','%s','%s','%s');", addslashes($name), addslashes($ct['ImageId']), addslashes($template), $running, $paused, $updateStatus, $is_autostart, addslashes($webGui), $id, addslashes($support), addslashes($project));
|
||||
$shape = $running ? ($paused ? 'pause' : 'play') : 'square';
|
||||
$status = $running ? ($paused ? 'paused' : 'started') : 'stopped';
|
||||
$icon = $info['icon'] ?: '/plugins/dynamix.docker.manager/images/question.png';
|
||||
echo "<div class='Panel $status'>";
|
||||
echo "<div id='$id' style='display:block; cursor:pointer'>";
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<title><?=$var['NAME']?>/<?=$myPage['name']?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="robots" content="noindex">
|
||||
<link type="image/png" rel="shortcut icon" href="/webGui/images/<?=$var['mdColor']?>.png">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/default-fonts.css")?>">
|
||||
@@ -41,6 +42,9 @@ if (strstr('gray,azure',$display['theme'])) {
|
||||
foreach ($tasks as $page) if ($page['Code']) echo "#nav-item a[href='/{$page['name']}']:before{content:'\\{$page['Code']}'}\n";
|
||||
foreach ($buttons as $page) if ($page['Code']) echo "#nav-item.{$page['name']} a:before{content:'\\{$page['Code']}'}\n";
|
||||
}
|
||||
$notes = '/var/tmp/unRAIDServer.txt';
|
||||
if (!file_exists($notes)) file_put_contents($notes,shell_exec("$docroot/plugins/dynamix.plugin.manager/scripts/plugin changes $docroot/plugins/unRAIDServer/unRAIDServer.plg"));
|
||||
$notes = " <a href='#' title='View Release Notes' onclick=\"openBox('/plugins/dynamix.plugin.manager/include/ShowChanges.php?tmp=1&file=$notes','Release Notes',600,900);return false\"><span class='fa fa-info-circle fa-fw blue-text'></span></a>"
|
||||
?>
|
||||
</style>
|
||||
|
||||
@@ -169,17 +173,12 @@ function showFooter(data, id) {
|
||||
if (id !== undefined) $('#'+id).remove();
|
||||
$('#copyright').prepend(data);
|
||||
}
|
||||
function showNotice(data,plugin) {
|
||||
if (plugin)
|
||||
var href = "href=\"#\" onclick=\"openBox('/plugins/dynamix.plugin.manager/scripts/plugin&arg1=update&arg2="+plugin+".plg','Update Plugin',600,900,true)\"";
|
||||
else
|
||||
var href = "href=\"/Plugins\"";
|
||||
$('#user-notice').html(data.replace(/<a>(.*)<\/a>/,"<a "+href+">$1</a>"));
|
||||
function showNotice(data) {
|
||||
$('#user-notice').html(data.replace(/<a>(.*)<\/a>/,"<a href='/Plugins'>$1</a>"));
|
||||
}
|
||||
function showUpgrade(data,plugin) {
|
||||
var href = "href=\"#\" onclick=\"hideUpgrade();openBox('/plugins/dynamix.plugin.manager/scripts/plugin&arg1=update&arg2="+plugin+".plg','Update Plugin',600,900,true)\"";
|
||||
function showUpgrade(data) {
|
||||
if ($.cookie('os_upgrade')==null)
|
||||
$('.upgrade_notice').html(data.replace(/<a(.*)>(.*)<\/a>/,"<a "+href+"$1>$2</a>")+"<i class='fa fa-close' title='Close' onclick='hideUpgrade(true)'></i>").show();
|
||||
$('.upgrade_notice').html(data.replace(/<a>(.*)<\/a>/,"<a href='#' onclick='hideUpgrade();openUpgrade()'>$1</a>")+"<i class='fa fa-close' title='Close' onclick='hideUpgrade(true)'></i>").show();
|
||||
}
|
||||
function hideUpgrade(set) {
|
||||
$('.upgrade_notice').hide();
|
||||
@@ -188,6 +187,11 @@ function hideUpgrade(set) {
|
||||
else
|
||||
$.removeCookie('os_upgrade',{path:'/'});
|
||||
}
|
||||
function openUpgrade() {
|
||||
swal({title:'Update unRAID OS',text:'Do you want to update to the new version?',type:'warning',showCancelButton:true},function(){
|
||||
openBox('/plugins/dynamix.plugin.manager/scripts/plugin&arg1=update&arg2=unRAIDServer.plg','Update unRAID OS',600,900,true);
|
||||
});
|
||||
}
|
||||
function notifier() {
|
||||
var tub1 = 0, tub2 = 0, tub3 = 0;
|
||||
$.post('/webGui/include/Notify.php',{cmd:'get'},function(json) {
|
||||
@@ -296,7 +300,7 @@ $.ajaxPrefilter(function(s, orig, xhr){
|
||||
</div>
|
||||
<div class="block">
|
||||
<span class="text-left">Server<br/>Description<br/>Version<br/>Uptime</span>
|
||||
<span class="text-right"><?=$var['NAME']." • ".$eth0['IPADDR:0']?><br/><?=$var['COMMENT']?><br/><?=$var['version']?><br/><span id="uptime"></span></span>
|
||||
<span class="text-right"><?=$var['NAME']." • ".$eth0['IPADDR:0']?><br/><?=$var['COMMENT']?><br/><?=$var['version'].$notes?><br/><span id="uptime"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="back_to_top" title="Back To Top"><i class="fa fa-arrow-circle-up"></i></a>
|
||||
@@ -435,7 +439,7 @@ function parseINI(data){
|
||||
});
|
||||
return value;
|
||||
}
|
||||
var watchdog = new NchanSubscriber('/sub/var');
|
||||
var watchdog = new NchanSubscriber('/sub/var', /^((?!chrome|android).)*safari/i.test(navigator.userAgent) ? {subscriber:'longpoll'} : {});
|
||||
watchdog.on('message', function(data) {
|
||||
var ini = parseINI(data);
|
||||
var state = ini['fsState'];
|
||||
@@ -510,7 +514,7 @@ $(function() {
|
||||
<?elseif (strpos($readme,'DOWNGRADE')!==false):?>
|
||||
showUpgrade('<b>Reboot required</b> to downgrade unRAID OS');
|
||||
<?elseif ($version = plugin_update_available('unRAIDServer',true)):?>
|
||||
showUpgrade('unRAID OS v<?=$version?> is available. <a>Download Now</a>','unRAIDServer');
|
||||
showUpgrade('unRAID OS v<?=$version?> is available. <a>Update Now</a>');
|
||||
<?elseif (!$notify['system']):?>
|
||||
$('.upgrade_notice').html('System notifications are <b>disabled</b>. Click <a href="/Settings/Notifications" style="cursor:pointer">here</a> to change notification settings.').show();
|
||||
<?endif;?>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, 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,
|
||||
@@ -381,7 +381,7 @@ case 'cache':
|
||||
case 'open':
|
||||
foreach ($devs as $disk) {
|
||||
$dev = $disk['device'];
|
||||
$data = explode(' ',$diskio[$dev] ?? '0 0');
|
||||
$data = explode(' ',$diskio[$dev] ?? '0 0 0 0');
|
||||
$disk['name'] = $dev;
|
||||
$disk['type'] = 'New';
|
||||
$disk['color'] = read_disk($dev,'color');
|
||||
@@ -406,7 +406,7 @@ case 'parity':
|
||||
if ($var['mdResync']>0) {
|
||||
$data[] = my_scale($var['mdResync']*1024,$unit,-1)." $unit";
|
||||
$data[] = my_clock(floor((time()-$var['sbUpdated'])/60));
|
||||
$data[] = my_scale($var['mdResyncPos']*1024,$unit)." $unit (".number_format(($var['mdResyncPos']/($var['mdResync']/100+1)),1,substr($display['number'],0,1),'')." %)";
|
||||
$data[] = my_scale($var['mdResyncPos']*1024,$unit)." $unit (".number_format(($var['mdResyncPos']/($var['mdResync']/100+1)),1,$display['number'][0],'')." %)";
|
||||
$data[] = my_scale($var['mdResyncDb']*1024/$var['mdResyncDt'],$unit, 1)." $unit/sec";
|
||||
$data[] = my_clock(round(((($var['mdResyncDt']*(($var['mdResync']-$var['mdResyncPos'])/($var['mdResyncDb']/100+1)))/100)/60),0));
|
||||
$data[] = $var['sbSyncErrs'];
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -77,7 +77,6 @@ span.tub span[id^='txt-tub']{margin-top:7px}
|
||||
#title span.right{font-size:20px;padding-right:10px;float:right}
|
||||
#title span img,#title p{display:none}
|
||||
#title:first-child{margin-top:0}
|
||||
#apps_icons{width:90%}
|
||||
#clear{clear:both}
|
||||
#footer{position:fixed;bottom:0;left:0;color:#808080;background:#121510;padding:5px 0;width:100%;height:16px;line-height:16px;text-align:center;z-index:100}
|
||||
#statusraid{float:left;padding-left:10px}
|
||||
@@ -219,11 +218,11 @@ label+.content{margin-top:64px}
|
||||
div.tabs{position:relative;margin:110px 30px 30px 100px;background-color:#E4E2E4}
|
||||
div.tab{float:left;margin-top:23px}
|
||||
div.tab input[id^='tab']{display:none}
|
||||
div.tab [type=radio]+label:hover{background:#606E7F;color:#B0B0B0;cursor:pointer;border-color:#0072C6}
|
||||
div.tab [type=radio]:checked+label{cursor:default;background:#606E7F;color:#B0B0B0}
|
||||
div.tab [type=radio]+label:hover{cursor:pointer;border-color:#004E86;opacity:1}
|
||||
div.tab [type=radio]:checked+label{cursor:default;background:transparent;color:#606E7F;border-color:#004E86;opacity:1}
|
||||
div.tab [type=radio]+label~.content{display:none}
|
||||
div.tab [type=radio]:checked+label~.content{display:inline}
|
||||
div.tab [type=radio]+label{position:relative;padding:10px 10px;margin-right:2px;border-top-left-radius:12px;border-top-right-radius:12px;border:#004E86 1px solid;border-bottom:none}
|
||||
div.tab [type=radio]+label{position:relative;padding:10px 10px;margin-right:2px;border-top-left-radius:12px;border-top-right-radius:12px;background:#606E7F;color:#B0B0B0;border:#8B98A7 1px solid;border-bottom:none;opacity:0.5}
|
||||
div.tab [type=radio]+label img{display:none}
|
||||
div.Panel{width:25%;height:auto;float:left;margin:0;padding:5px;border-right:#F3F0F4 1px solid;border-bottom:#F3F0F4 1px solid;box-sizing:border-box}
|
||||
div.Panel:hover{background-color:#EDEAEF}
|
||||
|
||||
@@ -211,11 +211,11 @@ div.content.shift{margin-top:-70px}
|
||||
div.tabs{position:relative;margin:24px 0 0 0}
|
||||
div.tab{float:left;margin:0 0 12px 0}
|
||||
div.tab input[id^="tab"]{display:none}
|
||||
div.tab [type=radio]+label:hover{background:#000000;color:#478406;cursor:pointer}
|
||||
div.tab [type=radio]:checked+label{cursor:default;background:-webkit-radial-gradient(#303030,#505050);background:linear-gradient(#303030,#505050);color:#808080}
|
||||
div.tab [type=radio]+label:hover{background:transparent;color:#478406;cursor:pointer;opacity:1}
|
||||
div.tab [type=radio]:checked+label{cursor:default;background:transparent;color:#808080;opacity:1}
|
||||
div.tab [type=radio]+label~.content{display:none}
|
||||
div.tab [type=radio]:checked+label~.content{display:inline}
|
||||
div.tab [type=radio]+label{position:relative;font-size:14px;padding:4px 10px;margin-right:2px;border-top-left-radius:5px;border-top-right-radius:5px;border:1px solid #303030;border-bottom:1px solid #606060;background:-webkit-radial-gradient(#101010,#202020);background:linear-gradient(#101010,#202020)}
|
||||
div.tab [type=radio]+label{position:relative;font-size:14px;padding:4px 10px;margin-right:2px;border-top-left-radius:5px;border-top-right-radius:5px;border:1px solid #303030;border-bottom:none;background:-webkit-radial-gradient(#101010,#202020);background:linear-gradient(#101010,#202020);opacity:0.6}
|
||||
div.tab [type=radio]+label img{padding-right:4px}
|
||||
div.Panel{text-align:center;float:left;margin:0 30px 30px 12px;height:80px}
|
||||
div.Panel .PanelText{padding-top:10px}
|
||||
|
||||
@@ -77,7 +77,6 @@ span.tub span[id^='txt-tub']{margin-top:7px}
|
||||
#title span.right{font-size:20px;padding-right:10px;float:right}
|
||||
#title span img,#title p{display:none}
|
||||
#title:first-child{margin-top:0}
|
||||
#apps_icons{width:90%}
|
||||
#clear{clear:both}
|
||||
#footer{position:fixed;bottom:0;left:0;color:#808080;background:#121510;padding:5px 0;width:100%;height:16px;line-height:16px;text-align:center;z-index:100}
|
||||
#statusraid{float:left;padding-left:10px}
|
||||
@@ -219,11 +218,11 @@ label+.content{margin-top:64px}
|
||||
div.tabs{position:relative;margin:110px 30px 30px 100px;background-color:#1B1D1B}
|
||||
div.tab{float:left;margin-top:23px}
|
||||
div.tab input[id^='tab']{display:none}
|
||||
div.tab [type=radio]+label:hover{background:#606E7F;color:#B0B0B0;cursor:pointer;border-color:#0072C6}
|
||||
div.tab [type=radio]:checked+label{cursor:default;background:#606E7F;color:#B0B0B0}
|
||||
div.tab [type=radio]+label:hover{cursor:pointer;border-color:#0072C6;opacity:1}
|
||||
div.tab [type=radio]:checked+label{cursor:default;background:transparent;color:#606E7F;border-color:#004E86;opacity:1}
|
||||
div.tab [type=radio]+label~.content{display:none}
|
||||
div.tab [type=radio]:checked+label~.content{display:inline}
|
||||
div.tab [type=radio]+label{position:relative;padding:10px 10px;margin-right:2px;border-top-left-radius:12px;border-top-right-radius:12px;border:#004E86 1px solid;border-bottom:none}
|
||||
div.tab [type=radio]+label{position:relative;padding:10px 10px;margin-right:2px;border-top-left-radius:12px;border-top-right-radius:12px;background:#606E7F;color:#B0B0B0;border:#8B98A7 1px solid;border-bottom:none;opacity:0.5}
|
||||
div.tab [type=radio]+label img{display:none}
|
||||
div.Panel{width:25%;height:auto;float:left;margin:0;padding:5px;border-right:#0C0F0B 1px solid;border-bottom:#0C0F0B 1px solid;box-sizing:border-box}
|
||||
div.Panel:hover{background-color:#121510}
|
||||
|
||||
@@ -211,11 +211,11 @@ div.content.shift{margin-top:-70px}
|
||||
div.tabs{position:relative;margin:24px 0 0 0}
|
||||
div.tab{float:left;margin:0 0 12px 0}
|
||||
div.tab input[id^="tab"]{display:none}
|
||||
div.tab [type=radio]+label:hover{background:#FFFFFF;color:#478406;cursor:pointer}
|
||||
div.tab [type=radio]:checked+label{cursor:default;background:-webkit-radial-gradient(#F8F8F8,#E8E8E8);background:linear-gradient(#F8F8F8,#E8E8E8);color:#303030}
|
||||
div.tab [type=radio]+label:hover{background:transparent;color:#478406;cursor:pointer;opacity:1}
|
||||
div.tab [type=radio]:checked+label{cursor:default;background:transparent;color:#303030;opacity:1}
|
||||
div.tab [type=radio]+label~.content{display:none}
|
||||
div.tab [type=radio]:checked+label~.content{display:inline}
|
||||
div.tab [type=radio]+label{position:relative;font-size:14px;padding:4px 10px;margin-right:2px;border-top-left-radius:5px;border-top-right-radius:5px;border:1px solid #E8E8E8;border-bottom-color:#D8D8D8;background:-webkit-radial-gradient(#D8D8D8,#B8B8B8);background:linear-gradient(#D8D8D8,#B8B8B8)}
|
||||
div.tab [type=radio]+label{position:relative;font-size:14px;padding:4px 10px;margin-right:2px;border-top-left-radius:5px;border-top-right-radius:5px;border:1px solid #E8E8E8;border-bottom:none;background:-webkit-radial-gradient(#D8D8D8,#B8B8B8);background:linear-gradient(#D8D8D8,#B8B8B8);opacity:0.6}
|
||||
div.tab [type=radio]+label img{padding-right:4px}
|
||||
div.Panel{text-align:center;float:left;margin:0 30px 30px 12px;height:80px}
|
||||
div.Panel .PanelText{padding-top:10px}
|
||||
|
||||
@@ -54,6 +54,7 @@ table.tablesorter thead tr .tablesorter-headerAsc{background-image:url(../images
|
||||
table.tablesorter thead tr .tablesorter-headerDesc{background-image:url(../images/sort-desc.png)}
|
||||
table.tablesorter thead tr .tablesorter-headerAsc, table.tablesorter thead tr .tablesorter-headerDesc{background-color:#101010}
|
||||
table.tablesorter tbody tr:nth-child(even){background-color:#0C0C0C}
|
||||
table.tablesorter.four tbody tr:nth-child(4n-1){background-color:#0C0C0C}
|
||||
table.tablesorter tbody tr.tr_last{background:#181818;border-top:1px solid #202020;border-bottom:1px solid #202020}
|
||||
table.tablesorter tbody tr.tr_last td{padding:8px 20px 8px 6px}
|
||||
table.tablesorter tbody td{padding:4px 20px 4px 6px;vertical-align:middle;text-align:justify}
|
||||
|
||||
@@ -54,6 +54,7 @@ table.tablesorter thead tr .tablesorter-headerAsc{background-image:url(../images
|
||||
table.tablesorter thead tr .tablesorter-headerDesc{background-image:url(../images/sort-desc.png)}
|
||||
table.tablesorter thead tr .tablesorter-headerAsc, table.tablesorter thead tr .tablesorter-headerDesc{background-color:#E0E0E0}
|
||||
table.tablesorter tbody tr:nth-child(even){background-color:#F8F8F8}
|
||||
table.tablesorter.four tbody tr:nth-child(4n-1){background-color:#F8F8F8}
|
||||
table.tablesorter tbody tr.tr_last{background:#F0F0F0;border-top:1px solid #E8E8E8;border-bottom:1px solid #E8E8E8}
|
||||
table.tablesorter tbody tr.tr_last td{padding:8px 20px 8px 6px}
|
||||
table.tablesorter tbody td{padding:4px 20px 4px 6px;vertical-align:middle;text-align:justify}
|
||||
|
||||
Reference in New Issue
Block a user