mirror of
https://github.com/unraid/webgui.git
synced 2026-03-15 15:30:40 -05:00
Merge branch '6.4-wip' of github.com:limetech/webgui into 6.4-wip
This commit is contained in:
@@ -4,8 +4,8 @@ Cond="(pgrep('dockerd')!==false)"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2014-2016, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2014-2017, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -4,8 +4,8 @@ Icon="dynamix.docker.manager.png"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2014-2016, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2014-2017, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -299,7 +299,7 @@ $(function() {
|
||||
$.cookie('dockersettings_view_mode', $('.advancedview').is(':checked') ? 'advanced' : 'basic', { expires: 3650 });
|
||||
});
|
||||
|
||||
showStatus('pid','docker');
|
||||
showStatus('pid','dockerd');
|
||||
|
||||
<?if ($var['fsState'] == "Started"):?>
|
||||
$("#DOCKER_APP_CONFIG_PATH").fileTreeAttach();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2015-2016, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2015-2017, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* Adaptations by Bergware International (May 2016)
|
||||
*
|
||||
@@ -13,7 +13,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = @$docroot ?: $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot = $docroot ?: $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
ignore_user_abort(true);
|
||||
|
||||
@@ -32,6 +32,10 @@ $DockerTemplates = new DockerTemplates();
|
||||
|
||||
$echo = function($m){ echo "<pre>".print_r($m, true)."</pre>"; };
|
||||
|
||||
exec("docker network ls --filter driver='macvlan' --format='{{.Name}}'", $custom);
|
||||
$subnet = ['bridge'=>'', 'host'=>'', 'none'=>''];
|
||||
foreach ($custom as $network) $subnet[$network] = exec("docker network inspect --format='{{range .IPAM.Config}}{{.Subnet}}{{end}}' $network");
|
||||
|
||||
function stopContainer($name) {
|
||||
global $DockerClient;
|
||||
$waitID = mt_rand();
|
||||
@@ -189,6 +193,7 @@ function postToXML($post, $setOwnership = false) {
|
||||
$xml->Repository = xml_encode(trim($post['contRepository']));
|
||||
$xml->Registry = xml_encode(trim($post['contRegistry']));
|
||||
$xml->Network = xml_encode($post['contNetwork']);
|
||||
$xml->MyIP = xml_encode($post['contMyIP']);
|
||||
$xml->Privileged = (strtolower($post["contPrivileged"]) == 'on') ? 'true' : 'false';
|
||||
$xml->Support = xml_encode($post['contSupport']);
|
||||
$xml->Overview = xml_encode($post['contOverview']);
|
||||
@@ -251,6 +256,7 @@ function xmlToVar($xml) {
|
||||
$out['Repository'] = xml_decode($xml->Repository);
|
||||
$out['Registry'] = xml_decode($xml->Registry);
|
||||
$out['Network'] = (isset($xml->Network)) ? xml_decode($xml->Network) : xml_decode($xml->Network['Default']);
|
||||
$out['MyIP'] = isset($xml->MyIP) ? xml_decode($xml->MyIP) : '';
|
||||
$out['Privileged'] = xml_decode($xml->Privileged);
|
||||
$out['Support'] = xml_decode($xml->Support);
|
||||
$out['Overview'] = stripslashes(xml_decode($xml->Overview));
|
||||
@@ -362,6 +368,7 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
$cmdName = (strlen($xml['Name'])) ? '--name="'.$xml['Name'].'"' : "";
|
||||
$cmdPrivileged = (strtolower($xml['Privileged']) == 'true') ? '--privileged="true"' : "";
|
||||
$cmdNetwork = '--net="'.strtolower($xml['Network']).'"';
|
||||
$cmdMyIP = $xml['MyIP'] ? '--ip="'.$xml['MyIP'].'"' : '';
|
||||
$Volumes = [''];
|
||||
$Ports = [''];
|
||||
$Variables = [''];
|
||||
@@ -386,10 +393,10 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
}
|
||||
} elseif ($confType == 'port') {
|
||||
# Export ports as variable if Network is set to host
|
||||
if (strtolower($xml['Network']) == 'host') {
|
||||
if (preg_match('/^(host|eth[0-9]|br[0-9]|bond[0-9])/',strtolower($xml['Network']))) {
|
||||
$Variables[] = strtoupper(sprintf('"%s_PORT_%s"="%s"', $Mode, $containerConfig, $hostConfig));
|
||||
# Export ports as port if Network is set to bridge
|
||||
} elseif (strtolower($xml['Network']) == 'bridge') {
|
||||
} elseif (strtolower($xml['Network'])== 'bridge') {
|
||||
$Ports[] = sprintf("%s:%s/%s", $hostConfig, $containerConfig, $Mode);
|
||||
# No export of ports if Network is set to none
|
||||
}
|
||||
@@ -399,9 +406,10 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
$Devices[] = '"'.$hostConfig.'"';
|
||||
}
|
||||
}
|
||||
$cmd = sprintf('/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s',
|
||||
$cmd = sprintf('/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s %s',
|
||||
$cmdName,
|
||||
$cmdNetwork,
|
||||
$cmdMyIP,
|
||||
$cmdPrivileged,
|
||||
implode(' -e ', $Variables),
|
||||
implode(' -p ', $Ports),
|
||||
@@ -1041,7 +1049,7 @@ $showAdditionalInfo = '';
|
||||
} else {
|
||||
targetDiv.hide();
|
||||
}
|
||||
if (network==0 || network==1) {
|
||||
if (network==0 || network==1 || network>2) {
|
||||
valueDiv.find('#dt2').text('Host Port:');
|
||||
valueDiv.show();
|
||||
} else {
|
||||
@@ -1355,13 +1363,20 @@ $showAdditionalInfo = '';
|
||||
<tr <?=$showAdditionalInfo?>>
|
||||
<td>Network Type:</td>
|
||||
<td>
|
||||
<select name="contNetwork" class="narrow">
|
||||
<option value="bridge">Bridge</option>
|
||||
<option value="host">Host</option>
|
||||
<option value="none">None</option>
|
||||
<select name="contNetwork" class="narrow" onchange="showSubnet(this.value)">
|
||||
<?=mk_option(0,'bridge','Bridge')?>
|
||||
<?=mk_option(0,'host','Host')?>
|
||||
<?=mk_option(0,'none','None')?>
|
||||
<?foreach ($custom as $network):?>
|
||||
<?=mk_option(0,$network,$network)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="myIP" style="display:none">
|
||||
<td>Fixed IP address (optional):</td>
|
||||
<td><input type="text" name="contMyIP" class="textPath"><span id="myIP"></span></td>
|
||||
</tr>
|
||||
<tr <?=$showAdditionalInfo?>>
|
||||
<td colspan="2" class="inline_help">
|
||||
<blockquote class="inline_help">
|
||||
@@ -1519,6 +1534,20 @@ $showAdditionalInfo = '';
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var subnet = {};
|
||||
<?foreach ($subnet as $network => $value):?>
|
||||
subnet['<?=$network?>'] = '<?=$value?>';
|
||||
<?endforeach;?>
|
||||
|
||||
function showSubnet(bridge) {
|
||||
if (bridge.match(/^(br|eth|bond)[0-9]/) !== null) {
|
||||
$('.myIP').show();
|
||||
$('#myIP').html('Subnet: '+subnet[bridge]);
|
||||
} else {
|
||||
$('.myIP').hide();
|
||||
$('input[name="contMyIP"]').val('');
|
||||
}
|
||||
}
|
||||
function reloadTriggers() {
|
||||
$(".basic").toggle(!$(".advanced-switch:first").is(":checked"));
|
||||
$(".advanced").toggle($(".advanced-switch:first").is(":checked"));
|
||||
@@ -1607,6 +1636,9 @@ $showAdditionalInfo = '';
|
||||
$('#canvas').find('#Overview:first').hide();
|
||||
}
|
||||
|
||||
// Show associated subnet with fixed IP (if existing)
|
||||
showSubnet($('select[name="contNetwork"]').val());
|
||||
|
||||
// Add list of deployed host ports
|
||||
$("#configLocationPorts").html(makeUsedPorts(UsedPorts,$('input[name="contName"]').val()));
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2014-2016, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2014-2017, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?: @$_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot = $docroot ?: $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$dockerManPaths = [
|
||||
'plugin' => '/usr/local/emhttp/plugins/dynamix.docker.manager',
|
||||
@@ -260,9 +260,14 @@ class DockerTemplates {
|
||||
}
|
||||
|
||||
$WebUI = $this->getTemplateValue($Repository, "WebUI");
|
||||
|
||||
$myIP = $this->getTemplateValue($Repository, "MyIP");
|
||||
$network = $this->getTemplateValue($Repository, "Network");
|
||||
if (!$myIP && preg_match('%^(br|eth|bond)[0-9]%',$network)) {
|
||||
$name = $this->getTemplateValue($Repository, "Name");
|
||||
$myIP = exec("docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $name");
|
||||
}
|
||||
if (preg_match("%\[IP\]%", $WebUI)) {
|
||||
$WebUI = preg_replace("%\[IP\]%", $eth0["IPADDR:0"], $WebUI);
|
||||
$WebUI = preg_replace("%\[IP\]%", $myIP ?: $eth0["IPADDR:0"], $WebUI);
|
||||
}
|
||||
if (preg_match("%\[PORT:(\d+)\]%", $WebUI, $matches)) {
|
||||
$ConfigPort = $matches[1];
|
||||
|
||||
@@ -94,7 +94,7 @@ var UI;
|
||||
UI.initSetting('resize', 'scale'); // LT: default was 'off' before
|
||||
UI.initSetting('shared', true);
|
||||
UI.initSetting('view_only', false);
|
||||
UI.initSetting('path', 'websockify');
|
||||
UI.initSetting('path', '');
|
||||
UI.initSetting('repeaterID', '');
|
||||
UI.initSetting('token', '');
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
<li><label><input id="noVNC_shared" type="checkbox" checked> Shared Mode</label></li>
|
||||
<li><label><input id="noVNC_view_only" type="checkbox"> View Only</label></li>
|
||||
<hr>
|
||||
<li><input id="noVNC_path" type="input" value="websockify"> Path</li>
|
||||
<li><input id="noVNC_path" type="input" value=""> Path</li>
|
||||
<li><label>
|
||||
<select id="noVNC_resize" name="vncResize">
|
||||
<option value="off">None</option>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Menu="NetworkSettings"
|
||||
Menu="NetworkSettings:100"
|
||||
Title="Interface eth0"
|
||||
Png="ethernet.png"
|
||||
---
|
||||
@@ -15,6 +15,8 @@ Png="ethernet.png"
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$members = parse_ini_file('state/network.ini',true);
|
||||
|
||||
$build = false;
|
||||
$template = "$docroot/webGui/EthX.page";
|
||||
$ini = '/var/local/emhttp/network.ini';
|
||||
@@ -22,8 +24,17 @@ $validIP4 = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[
|
||||
$validIP6 = '((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4}))*::((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4}))*|((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4})){7}';
|
||||
|
||||
// get available ethernet ports (excluding eth0)
|
||||
exec("ip -br addr|awk '/^eth[0-9]+\s/{print $1}'|grep -v '^eth0$'",$ports);
|
||||
exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[1-9][0-9]*$'",$ports);
|
||||
|
||||
function locked($source,$port) {
|
||||
global $members;
|
||||
foreach ($members as $member => $value) {
|
||||
if ($member == $source) continue;
|
||||
if ($value['BONDING']=='yes' && in_array($port,explode(',',$value['BONDNICS']))) return $value['BONDNAME'].' '.$member;
|
||||
if ($value['BRIDGING']=='yes' && in_array($port,explode(',',$value['BRNICS']))) return $value['BRNAME'].' '.$member;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// remove non-existing ethernet ports
|
||||
foreach (glob("$docroot/webGui/Eth[1-9]*.page",GLOB_NOSORT) as $port) {
|
||||
if (!in_array(strtolower(basename($port,'.page')), $ports)) {
|
||||
@@ -32,11 +43,16 @@ foreach (glob("$docroot/webGui/Eth[1-9]*.page",GLOB_NOSORT) as $port) {
|
||||
}
|
||||
}
|
||||
// add new ethernet ports
|
||||
foreach ($ports as $port) {
|
||||
$file = "$docroot/webGui/".ucfirst($port).".page";
|
||||
foreach ($ports as $ethX) {
|
||||
$file = "$docroot/webGui/".ucfirst($ethX).".page";
|
||||
if (!file_exists($file)) {
|
||||
$X = filter_var($ethX,FILTER_SANITIZE_NUMBER_INT);
|
||||
$nnn = 100 + $X;
|
||||
$tabX = 'tab'.($X+1);
|
||||
$bondX = 'bond'.$X;
|
||||
$brX = 'br'.$X;
|
||||
copy($template, $file);
|
||||
exec("sed -i 's/x-settings/NetworkSettings/;s/ethX/$port/g' $file");
|
||||
exec("sed -i 's/parentname:nnn/NetworkSettings:$nnn/;s/tabX/$tabX/;s/bondX/$bondX/g;s/brX/$brX/g;s/ethX/$ethX/g' $file");
|
||||
$build = true;
|
||||
}
|
||||
}
|
||||
@@ -48,8 +64,9 @@ $service .= exec("pgrep docker") ? ($service ? ' and ' : '').'Docker service' :
|
||||
$no_eth0 = exec("ip link show eth0|grep -Pom1 '(NO-CARRIER|state DOWN)'");
|
||||
|
||||
// get VLAN interfaces
|
||||
$vlan_id = 'VLANID:';
|
||||
$vlan_eth0 = [0];
|
||||
if (isset($eth0)) foreach ($eth0 as $key => $val) if (substr($key,0,6)=='VLANID') $vlan_eth0[] = substr($key,7);
|
||||
if (isset($eth0)) foreach ($eth0 as $key => $val) if (strpos($key,$vlan_id)===0) $vlan_eth0[] = substr($key,strlen($vlan_id));
|
||||
?>
|
||||
<style>
|
||||
span.pin i{font-size:16px;cursor:pointer;}
|
||||
@@ -85,7 +102,6 @@ function prepareSettings(form) {
|
||||
$(form).find('select[name^="GATEWAY:"]').not('select[name$=":0"]').prop('disabled',true);
|
||||
$(form).find('input[name^="GATEWAY6:"]').not('input[name$=":0"]').prop('disabled',true);
|
||||
$(form).find('input[name^="METRIC:"]').not('input[name$=":0"]').prop('disabled',true);
|
||||
$(form).find('input[name^="METRIC6:"]').not('input[name$=":0"]').prop('disabled',true);
|
||||
$(form).find('select[name^="PRIVACY6:"]').not('select[name$=":0"]').prop('disabled',true);
|
||||
} else {
|
||||
var vlans = [];
|
||||
@@ -95,36 +111,34 @@ function prepareSettings(form) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (form.BONDING !== undefined) {
|
||||
var member = '';
|
||||
for (var i=0,item; item=form.BONDNICS.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (member.length) member += ',';
|
||||
member += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
var member = '';
|
||||
for (var i=0,item; item=form.BONDNICS.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (member.length) member += ',';
|
||||
member += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
item = form.BONDNICS.options[0];
|
||||
item.value = member;
|
||||
item.selected = true;
|
||||
item.disabled = false;
|
||||
var member = '';
|
||||
for (var i=0,item; item=form.BRNICS.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (member.length) member += ',';
|
||||
member += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.BRNICS.options[0];
|
||||
item.value = form.BONDING.value=='yes' ? form.BONDNAME.value : member;
|
||||
item.selected = true;
|
||||
item.disabled = false;
|
||||
if (member.indexOf(',')>0) form.BRSTP.value = 'yes';
|
||||
}
|
||||
item = form.BONDNICS.options[0];
|
||||
item.value = member;
|
||||
item.selected = true;
|
||||
item.disabled = false;
|
||||
var member = '';
|
||||
for (var i=0,item; item=form.BRNICS.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (member.length) member += ',';
|
||||
member += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.BRNICS.options[0];
|
||||
item.value = form.BONDING.value=='yes' ? form.BONDNAME.value : member;
|
||||
item.selected = true;
|
||||
item.disabled = false;
|
||||
if (member.indexOf(',')>0) form.BRSTP.value = 'yes';
|
||||
$(form).find('select[name^="PROTOCOL:"]').each(function() {
|
||||
var protocol = $(this).val() || 'ipv4';
|
||||
var i = $(this).attr('name').substr(9);
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if (protocol == 'ipv6') {
|
||||
$(form).find('input[name="IPADDR:'+i+'"]').prop('disabled',true);
|
||||
$(form).find('select[name="NETMASK:'+i+'"]').prop('disabled',true);
|
||||
@@ -136,7 +150,6 @@ function prepareSettings(form) {
|
||||
$(form).find('input[name="IPADDR6:'+i+'"]').prop('disabled',true);
|
||||
$(form).find('input[name="NETMASK6:'+i+'"]').prop('disabled',true);
|
||||
$(form).find('input[name="GATEWAY6:'+i+'"]').prop('disabled',true);
|
||||
$(form).find('input[name="METRIC6:'+i+'"]').prop('disabled',true);
|
||||
$(form).find('select[name="PRIVACY6:'+i+'"]').prop('disabled',true);
|
||||
if (i==0) $(form).find('input[name^="DNS6_SERVER"]').prop('disabled',true);
|
||||
}
|
||||
@@ -145,14 +158,9 @@ function prepareSettings(form) {
|
||||
var gateway = $(form).find('input[name="GATEWAY:'+i+'"]');
|
||||
if (metric) gateway.val(gateway.val()+'#'+metric);
|
||||
}
|
||||
if (protocol != 'ipv4') {
|
||||
var metric6 = $(form).find('input[name="METRIC6:'+i+'"]').val();
|
||||
var gateway6 = $(form).find('input[name="GATEWAY6:'+i+'"]');
|
||||
if (metric6) gateway6.val(gateway6.val()+'#'+metric6);
|
||||
}
|
||||
});
|
||||
$(form).find('select[name^="USE_DHCP:"]').each(function() {
|
||||
var i = $(this).attr('name').substr(9);
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if ($(this).prop('disabled')==false && $(this).val()=='yes') {
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4';
|
||||
if (protocol != 'ipv6') {
|
||||
@@ -172,14 +180,13 @@ function prepareSettings(form) {
|
||||
if (protocol != 'ipv6') $(form).find('input[name^="DNS_SERVER"]').val('Obtaining DNSv4 server...');
|
||||
if (protocol != 'ipv4') $(form).find('input[name^="DNS6_SERVER"]').val('Obtaining DNSv6 server...');
|
||||
}
|
||||
form.BRNAME.value = 'br'+$(form).find('input[name="#section"]').val().substr(3);
|
||||
return true;
|
||||
}
|
||||
function selectProtocol(form,port,index) {
|
||||
if (index == null) {
|
||||
$(form).find('select[name^="PROTOCOL:"]').each(function() {
|
||||
var protocol = $(this).val() || 'ipv4';
|
||||
var i = $(this).attr('name').substr(9);
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
var net4 = $('.'+port+'-ipv4-'+i);
|
||||
var net6 = $('.'+port+'-ipv6-'+i);
|
||||
switch (protocol) {
|
||||
@@ -229,7 +236,6 @@ function checkNetworkSettings(form,index,open) {
|
||||
}
|
||||
if (dns && index==0) {
|
||||
if (!open) form.DHCP_KEEPRESOLV.value = disabled ? 'no' : 'yes';
|
||||
form.DHCP_KEEPRESOLV.disabled = !disabled;
|
||||
checkDNSSettings(form);
|
||||
}
|
||||
}
|
||||
@@ -253,28 +259,29 @@ function checkDNSSettings(form) {
|
||||
if (!form.DNS6_SERVER3.value && disabled) $('#dns6server3').hide(); else $('#dns6server3').show();
|
||||
}
|
||||
}
|
||||
function checkBondingSettings(form,ctrl) {
|
||||
function checkBondingSettings(form,ctrl,port) {
|
||||
var disabled = form.BONDING.value=='no';
|
||||
var mode = form.BONDING_MODE.value;
|
||||
if (ctrl>=0) {
|
||||
var me = ctrl==0 ? null : 'slow';
|
||||
if (disabled) {
|
||||
$('#bond-members').hide(me);
|
||||
$('#bond-members-'+port).hide(me);
|
||||
} else {
|
||||
$('#bond-members').show(me);
|
||||
$('#bond0').dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bond-members-'+port).show(me);
|
||||
$('#bond-'+port).dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
}
|
||||
if (ctrl==1) checkBridgingSettings(form,1);
|
||||
if (ctrl==1) checkBridgingSettings(form,1,port);
|
||||
}
|
||||
if (mode==1 || mode>4 || disabled) {$('#attention0').hide();} else {$('#attention0').show();}
|
||||
}
|
||||
function checkBridgingSettings(form,ctrl) {
|
||||
function checkBridgingSettings(form,ctrl,port) {
|
||||
var me = ctrl==0 ? null : 'slow';
|
||||
var i = 0;
|
||||
if (form.BRIDGING.value=='yes' && form.BONDING.value=='no') {
|
||||
$('#bridge-members').show(me);
|
||||
$('#bridge0').dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bridge-members-'+port).show(me);
|
||||
$('#bridge-'+port).dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
} else {
|
||||
$('#bridge-members').hide(me);
|
||||
$('#bridge-members-'+port).hide(me);
|
||||
}
|
||||
}
|
||||
function checkNetworkAccess(form,port) {
|
||||
@@ -332,20 +339,20 @@ $(function() {
|
||||
var form = document.eth0_settings;
|
||||
<?if ($tabbed && !$service):?>
|
||||
$('#tab1').bind({click:function(){
|
||||
$('#bond0').dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bridge0').dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bond-eth0').dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bridge-eth0').dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
}});
|
||||
<?endif;?>
|
||||
$('#bond0').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bridge0').dropdownchecklist({emptyText:'None', width:131});
|
||||
checkBondingSettings(form,0);
|
||||
checkBridgingSettings(form,0);
|
||||
$('#bond-eth0').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bridge-eth0').dropdownchecklist({emptyText:'None', width:131});
|
||||
checkBondingSettings(form,0,'eth0');
|
||||
checkBridgingSettings(form,0,'eth0');
|
||||
checkNetworkAccess(form,'eth0');
|
||||
selectProtocol(form,'eth0');
|
||||
<?if ($service):?>
|
||||
disableForm(form);
|
||||
$('#bond0').dropdownchecklist('disable');
|
||||
$('#bridge0').dropdownchecklist('disable');
|
||||
$('#bond-eth0').dropdownchecklist('disable');
|
||||
$('#bridge-eth0').dropdownchecklist('disable');
|
||||
if (form.DNS_SERVER2.value) $('#dnsserver2').show(); else $('#dnsserver2').hide();
|
||||
if (form.DNS_SERVER3.value) $('#dnsserver3').show(); else $('#dnsserver3').hide();
|
||||
<?else:?>
|
||||
@@ -367,20 +374,20 @@ $(function() {
|
||||
<input type="hidden" name="#arg[1]" value="">
|
||||
<input type="hidden" name="BONDNAME" value="bond0">
|
||||
<input type="hidden" name="BONDING_MIIMON" value="100">
|
||||
<input type="hidden" name="BRNAME" value="">
|
||||
<input type="hidden" name="BRNAME" value="br0">
|
||||
<input type="hidden" name="BRSTP" value="no">
|
||||
<input type="hidden" name="BRFD" value="0">
|
||||
<?foreach ($vlan_eth0 as $i):?>
|
||||
<div id="index-eth0-<?=$i?>" markdown="1">
|
||||
<?if ($i==0):?>
|
||||
MAC address:
|
||||
: <?=strtoupper(exec("ip link show eth0|grep -Pom1 'ether \K\S+'"))?>
|
||||
: <span class='big'><?=strtoupper(exec("ip link show eth0|grep -Pom1 'ether \K\S+'"))?></span>
|
||||
|
||||
> This is the hardware address of the interface.
|
||||
> When tagging is enabled all VLANs on this interface will share the same hardware address.
|
||||
|
||||
Enable bonding:
|
||||
: <select name="BONDING" size="1" onchange="checkBondingSettings(this.form,1)">
|
||||
: <select name="BONDING" size="1" onchange="checkBondingSettings(this.form,1,'eth0')">
|
||||
<?=mk_option($eth0['BONDING'], "no", "No");?>
|
||||
<?=mk_option($eth0['BONDING'], "yes", "Yes");?>
|
||||
</select>
|
||||
@@ -389,9 +396,9 @@ Enable bonding:
|
||||
> This can be used to improve the connection redundancy and/or throughput of the system.
|
||||
> Different bonding modes are supported (see below), but some modes require proper switch support.
|
||||
|
||||
<div id="bond-members" style="display:none" markdown="1">
|
||||
<div id="bond-members-eth0" style="display:none" markdown="1">
|
||||
Bonding mode:
|
||||
: <select name="BONDING_MODE" size="1" onchange="checkBondingSettings(this.form,-1)">
|
||||
: <select name="BONDING_MODE" size="1" onchange="checkBondingSettings(this.form,-1,'eth0')">
|
||||
<?=mk_option($eth0['BONDING_MODE'], "0", "balance-rr (0)");?>
|
||||
<?=mk_option($eth0['BONDING_MODE'], "1", "active-backup (1)",isset($eth0['BONDING_MODE'])?'':'selected');?>
|
||||
<?=mk_option($eth0['BONDING_MODE'], "2", "balance-xor (2)");?>
|
||||
@@ -405,11 +412,11 @@ Bonding mode:
|
||||
> Mode 1 (active-backup) is the recommended default. Other modes allow you to set up a specific environment, but may require proper switch support.
|
||||
> Choosing a unsupported mode can result in a disrupted communication. Use with caution.
|
||||
|
||||
Bonding members:
|
||||
: <select id="bond0" name="BONDNICS" size="1" multiple="multiple" style="display:none">
|
||||
Bonding members of bond0:
|
||||
: <select id="bond-eth0" name="BONDNICS" size="1" multiple="multiple" style="display:none">
|
||||
<?=mk_option($eth0['BONDNICS'],'eth0','eth0','selected disabled')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?=mk_option_check($eth0['BONDNICS'],$port,$port)?>
|
||||
<?if (!locked('eth0',$port)) echo mk_option_check($eth0['BONDNICS'],$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
@@ -417,7 +424,7 @@ Bonding members:
|
||||
|
||||
</div>
|
||||
Enable bridging:
|
||||
: <select name="BRIDGING" size="1" onchange="checkBridgingSettings(this.form,1)">
|
||||
: <select name="BRIDGING" size="1" onchange="checkBridgingSettings(this.form,1,'eth0')">
|
||||
<?=mk_option($eth0['BRIDGING'], "no", "No");?>
|
||||
<?=mk_option($eth0['BRIDGING'], "yes", "Yes");?>
|
||||
</select>
|
||||
@@ -425,12 +432,12 @@ Enable bridging:
|
||||
> Bridging is a feature which creates a virtual bridge and allows VMs to communicate directly with the physical Ethernet port.
|
||||
> Both bonding and bridging can be combined to let VMs communicate over a *bonded* interface.
|
||||
|
||||
<div id="bridge-members" style="display:none" markdown="1">
|
||||
Bridging members:
|
||||
: <select id="bridge0" name="BRNICS" size="1" multiple="multiple" style="display:none">
|
||||
<div id="bridge-members-eth0" style="display:none" markdown="1">
|
||||
Bridging members of br0:
|
||||
: <select id="bridge-eth0" name="BRNICS" size="1" multiple="multiple" style="display:none">
|
||||
<?=mk_option($eth0['BRNICS'],'eth0','eth0','selected disabled')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?=mk_option_check($eth0['BRNICS'],$port,$port)?>
|
||||
<?if (!locked('eth0',$port)) echo mk_option_check($eth0['BRNICS'],$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
@@ -485,7 +492,7 @@ IPv4 network mask:
|
||||
|
||||
IPv4 default gateway:
|
||||
: <input type="text" name="GATEWAY:<?=$i?>" maxlength="15" value="<?=$eth0["GATEWAY:$i"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">
|
||||
<input type="text" name="METRIC:<?=$i?>" min="1" max="9999" value="<?=$eth0["METRIC:$i"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
<input type="text" name="METRIC:<?=$i?>" min="1" max="9999" value="<?=$eth0["METRIC:$i"]?>" class="trim"><i class="fa fa-sort-numeric-asc"></i> <em>optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv4 address of your router.
|
||||
|
||||
@@ -503,7 +510,6 @@ IPv6 prefix:
|
||||
|
||||
IPv6 default gateway:
|
||||
: <input type="text" name="GATEWAY6:<?=$i?>" maxlength="39" value="<?=$eth0["GATEWAY6:$i"]?>" pattern="<?=$validIP6?>" title="IPv6 address nnnn:xxxx::yyyy">
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="1" max="9999" value="<?=$eth0["METRIC6:$i"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv6 address of your router.
|
||||
|
||||
@@ -642,7 +648,7 @@ IPv4 network mask:
|
||||
|
||||
IPv4 default gateway:
|
||||
: <input type="text" name="GATEWAY:<?=$i?>" maxlength="15" value="<?=$eth0["GATEWAY:$i"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">
|
||||
<input type="text" name="METRIC:<?=$i?>" min="1" max="9999" value="<?=$eth0["METRIC:$i"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
<input type="text" name="METRIC:<?=$i?>" min="1" max="9999" value="<?=$eth0["METRIC:$i"]?>" class="trim"><i class="fa fa-sort-numeric-asc"></i> <em>optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv4 address of your router.
|
||||
|
||||
@@ -660,7 +666,6 @@ IPv6 prefix:
|
||||
|
||||
IPv6 default gateway:
|
||||
: <input type="text" name="GATEWAY6:<?=$i?>" maxlength="39" value="<?=$eth0["GATEWAY6:$i"]?>" pattern="<?=$validIP6?>" title="IPv6 address nnnn:xxxx::yyyy">
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="1" max="9999" value="<?=$eth0["METRIC6:$i"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv6 address of your router.
|
||||
|
||||
@@ -735,7 +740,7 @@ IPv4 network mask:
|
||||
|
||||
IPv4 default gateway:
|
||||
: <input type="text" name="GATEWAY:INDEX" maxlength="15" value="<?=$eth0["GATEWAY:INDEX"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" value="<?=$eth0["METRIC:INDEX"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" value="<?=$eth0["METRIC:INDEX"]?>" class="trim"><i class="fa fa-sort-numeric-asc"></i> <em>optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv4 address of your router.
|
||||
|
||||
@@ -753,7 +758,6 @@ IPv6 prefix:
|
||||
|
||||
IPv6 default gateway:
|
||||
: <input type="text" name="GATEWAY6:INDEX" maxlength="39" value="<?=$eth0["GATEWAY6:INDEX"]?>" pattern="<?=$validIP6?>" title="IPv6 address nnnn:xxxx::yyyy">
|
||||
<input type="text" name="METRIC6:INDEX" min="1" max="9999" value="<?=$eth0["METRIC6:INDEX"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv6 address of your router.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Menu="x-settings"
|
||||
Menu="parentname:nnn"
|
||||
Title="Interface ethX"
|
||||
Png="ethernet.png"
|
||||
---
|
||||
@@ -15,38 +15,28 @@ Png="ethernet.png"
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
// get bond membership
|
||||
$bond_ethX = $eth0['BONDING']=='yes' ? in_array('ethX',explode(',',$eth0['BONDNICS'])) : false;
|
||||
|
||||
// get bridge membership
|
||||
$bridge_ethX = $eth0['BRIDGING']=='yes' ? in_array('ethX',explode(',',$eth0['BRNICS'])) : false;
|
||||
|
||||
$locked = $bond_ethX || $bridge_ethX ;
|
||||
$locked = locked('ethX','ethX');
|
||||
|
||||
// get VLAN interfaces
|
||||
$vlan_ethX = [0];
|
||||
if (!$locked && isset($ethX)) foreach ($ethX as $key => $val) if (substr($key,0,6)=='VLANID') $vlan_ethX[] = substr($key,7);
|
||||
if (!$locked && isset($ethX)) foreach ($ethX as $key => $val) if (strpos($key,$vlan_id)===0) $vlan_ethX[] = substr($key,strlen($vlan_id));
|
||||
|
||||
$cmd = 'Down';
|
||||
$more = true;
|
||||
if (!exec("ip link show ethX|grep -om1 'UP>'")) {
|
||||
$more = true;
|
||||
$reason = "Interface is shutdown (inactive)";
|
||||
$class = 'blue';
|
||||
$class = 'big blue';
|
||||
$cmd = 'Up';
|
||||
} elseif ($bond_ethX) {
|
||||
$more = true;
|
||||
$reason = "Interface is member of ".$eth0['BONDNAME']." (see interface eth0)";
|
||||
$class = 'green';
|
||||
} elseif ($bridge_ethX) {
|
||||
$more = true;
|
||||
$reason = "Interface is member of ".$eth0['BRNAME']." (see interface eth0)";
|
||||
$class = 'green';
|
||||
} elseif (strpos($locked,'bond')===0 || strpos($locked,'br')===0) {
|
||||
$root = explode(' ',$locked);
|
||||
$reason = "Interface is member of ".$root[0]." (see interface ".$root[1].")";
|
||||
$class = 'big green';
|
||||
} elseif (empty($ethX)) {
|
||||
$more = true;
|
||||
$reason = "Interface is not configured";
|
||||
$class = 'red';
|
||||
$class = 'big red';
|
||||
} else {
|
||||
$more = false;
|
||||
$class = 'big';
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
@@ -64,6 +54,16 @@ function portcheck_ethX() {
|
||||
}
|
||||
$(function() {
|
||||
var form = document.ethX_settings;
|
||||
<?if ($tabbed && !$service):?>
|
||||
$('#tabX').bind({click:function(){
|
||||
$('#bond-ethX').dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bridge-ethX').dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:131});
|
||||
}});
|
||||
<?endif;?>
|
||||
$('#bond-ethX').dropdownchecklist({emptyText:'None', width:131});
|
||||
$('#bridge-ethX').dropdownchecklist({emptyText:'None', width:131});
|
||||
checkBondingSettings(form,0,'ethX');
|
||||
checkBridgingSettings(form,0,'ethX');
|
||||
checkNetworkAccess(form,'ethX');
|
||||
selectProtocol(form,'ethX');
|
||||
<?if (!$tabbed):?>
|
||||
@@ -86,29 +86,78 @@ $(function() {
|
||||
<input type="hidden" name="#section" value="ethX">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/netconfig">
|
||||
<input type="hidden" name="#arg[1]" value="">
|
||||
<input type="hidden" name="BRNAME" value="">
|
||||
<input type="hidden" name="BRNICS" value="ethX">
|
||||
<input type="hidden" name="BONDNAME" value="bondX">
|
||||
<input type="hidden" name="BONDING_MIIMON" value="100">
|
||||
<input type="hidden" name="BRNAME" value="brX">
|
||||
<input type="hidden" name="BRSTP" value="no">
|
||||
<input type="hidden" name="BRFD" value="0">
|
||||
<?foreach ($vlan_ethX as $i):?>
|
||||
<div id="index-ethX-<?=$i?>" markdown="1">
|
||||
<?if ($i==0):?>
|
||||
MAC address:
|
||||
: <?if ($more):?><span class="<?=$class?>"><?endif;?><?=strtoupper(exec("ip link show ethX|grep -Pom1 'ether \K\S+'"))?><?if ($more):?> - <?=$reason?></span><?endif;?>
|
||||
: <span class="<?=$class?>"><?=strtoupper(exec("ip link show ethX|grep -Pom1 'ether \K\S+'"))?><?if ($more):?> - <?=$reason?><?endif;?></span>
|
||||
|
||||
> This is the hardware address of the interface.
|
||||
> When tagging is enabled all VLANs on this interface will share the same hardware address.
|
||||
|
||||
<?if (!$locked):?>
|
||||
Enable bonding:
|
||||
: <select name="BONDING" size="1" onchange="checkBondingSettings(this.form,1,'ethX')">
|
||||
<?=mk_option($ethX['BONDING'], "no", "No");?>
|
||||
<?=mk_option($ethX['BONDING'], "yes", "Yes");?>
|
||||
</select>
|
||||
|
||||
> Bonding is a feature that combines multiple physical Ethernet interfaces into a single *bonded* interface named **bond0**.
|
||||
> This can be used to improve the connection redundancy and/or throughput of the system.
|
||||
> Different bonding modes are supported (see below), but some modes require proper switch support.
|
||||
|
||||
<div id="bond-members-ethX" style="display:none" markdown="1">
|
||||
Bonding mode:
|
||||
: <select name="BONDING_MODE" size="1" onchange="checkBondingSettings(this.form,-1,'ethX')">
|
||||
<?=mk_option($ethX['BONDING_MODE'], "0", "balance-rr (0)");?>
|
||||
<?=mk_option($ethX['BONDING_MODE'], "1", "active-backup (1)",isset($ethX['BONDING_MODE'])?'':'selected');?>
|
||||
<?=mk_option($ethX['BONDING_MODE'], "2", "balance-xor (2)");?>
|
||||
<?=mk_option($ethX['BONDING_MODE'], "3", "broadcast (3)");?>
|
||||
<?=mk_option($ethX['BONDING_MODE'], "4", "802.3ad (4)");?>
|
||||
<?=mk_option($ethX['BONDING_MODE'], "5", "balance-tlb (5)");?>
|
||||
<?=mk_option($ethX['BONDING_MODE'], "6", "balance-alb (6)");?>
|
||||
</select>
|
||||
<span id="attention0" style="display:none"><b>Attention:</b> this mode requires a network switch with proper setup and support...</span>
|
||||
|
||||
> Mode 1 (active-backup) is the recommended default. Other modes allow you to set up a specific environment, but may require proper switch support.
|
||||
> Choosing a unsupported mode can result in a disrupted communication. Use with caution.
|
||||
|
||||
Bonding members of bondX:
|
||||
: <select id="bond-ethX" name="BONDNICS" size="1" multiple="multiple" style="display:none">
|
||||
<?=mk_option($ethX['BONDNICS'],'ethX','ethX','selected disabled')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?if ($port!='ethX' && !locked('ethX',$port)) echo mk_option_check($ethX['BONDNICS'],$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
> Select which interfaces are member of the *bonded* interface. By default ethX is a member, while other interfaces are optional.
|
||||
|
||||
</div>
|
||||
|
||||
Enable bridging:
|
||||
: <select name="BRIDGING" size="1">
|
||||
: <select name="BRIDGING" size="1" onchange="checkBridgingSettings(this.form,1,'ethX')">
|
||||
<?=mk_option($ethX['BRIDGING'], "no", "No");?>
|
||||
<?=mk_option($ethX['BRIDGING'], "yes", "Yes");?>
|
||||
</select>
|
||||
|
||||
> Bridging is a feature which creates a virtual bridge and allows VMs to communicate directly with the physical Ethernet port.
|
||||
|
||||
<?endif;?>
|
||||
<div id="bridge-members-ethX" style="display:none" markdown="1">
|
||||
Bridging members of brX:
|
||||
: <select id="bridge-ethX" name="BRNICS" size="1" multiple="multiple" style="display:none">
|
||||
<?=mk_option($ethX['BRNICS'],'ethX','ethX','selected disabled')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?if ($port!='ethX' && !locked('ethX',$port)) echo mk_option_check($ethX['BRNICS'],$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
> Select which interfaces are member of the *bridged* interface. By default ethX is a member, while other interfaces are optional.
|
||||
|
||||
</div>
|
||||
Interface description:
|
||||
: <input type="text" name="DESCRIPTION:<?=$i?>" maxlength="80" value="<?=htmlspecialchars($ethX["DESCRIPTION:$i"])?>" onchange="exitCode(this.form,true)">
|
||||
|
||||
@@ -158,7 +207,7 @@ IPv4 network mask:
|
||||
|
||||
IPv4 default gateway:
|
||||
: <input type="text" name="GATEWAY:<?=$i?>" maxlength="15" value="<?=$ethX["GATEWAY:$i"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">
|
||||
<input type="text" name="METRIC:<?=$i?>" min="1" max="9999" value="<?=$ethX["METRIC:$i"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
<input type="text" name="METRIC:<?=$i?>" min="1" max="9999" value="<?=$ethX["METRIC:$i"]?>" class="trim"><i class="fa fa-sort-numeric-asc"></i> <em>optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv4 address of your router.
|
||||
|
||||
@@ -176,7 +225,6 @@ IPv6 prefix:
|
||||
|
||||
IPv6 default gateway:
|
||||
: <input type="text" name="GATEWAY6:<?=$i?>" maxlength="39" value="<?=$ethX["GATEWAY6:$i"]?>" pattern="<?=$validIP6?>" title="IPv6 address nnnn:xxxx::yyyy">
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="1" max="9999" value="<?=$ethX["METRIC6:$i"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv6 address of your router.
|
||||
|
||||
@@ -190,7 +238,7 @@ IPv6 privacy extensions:
|
||||
|
||||
</div>
|
||||
Desired MTU:
|
||||
: <input type="number" name="MTU" min="68" max="9198" value="<?=$locked?$eth0['MTU']:$ethX['MTU']?>" class="narrow">
|
||||
: <input type="number" name="MTU" min="68" max="9198" value="<?=$locked?$ethX['MTU']:$ethX['MTU']?>" class="narrow">
|
||||
|
||||
> 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).
|
||||
@@ -258,7 +306,7 @@ IPv4 network mask:
|
||||
|
||||
IPv4 default gateway:
|
||||
: <input type="text" name="GATEWAY:<?=$i?>" maxlength="15" value="<?=$ethX["GATEWAY:$i"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">
|
||||
<input type="text" name="METRIC:<?=$i?>" min="1" max="9999" value="<?=$ethX["METRIC:$i"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
<input type="text" name="METRIC:<?=$i?>" min="1" max="9999" value="<?=$ethX["METRIC:$i"]?>" class="trim"><i class="fa fa-sort-numeric-asc"></i> <em>optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv4 address of your router.
|
||||
|
||||
@@ -276,7 +324,6 @@ IPv6 prefix:
|
||||
|
||||
IPv6 default gateway:
|
||||
: <input type="text" name="GATEWAY6:<?=$i?>" maxlength="39" value="<?=$ethX["GATEWAY6:$i"]?>" pattern="<?=$validIP6?>" title="IPv6 address nnnn:xxxx::yyyy">
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="1" max="9999" value="<?=$ethX["METRIC6:$i"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv6 address of your router.
|
||||
|
||||
@@ -351,7 +398,7 @@ IPv4 network mask:
|
||||
|
||||
IPv4 default gateway:
|
||||
: <input type="text" name="GATEWAY:INDEX" maxlength="15" value="<?=$ethX["GATEWAY:INDEX"]?>" class="narrow" pattern="<?=$validIP4?>" title="IPv4 address A.B.C.D">
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" value="<?=$ethX["METRIC:INDEX"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" value="<?=$ethX["METRIC:INDEX"]?>" class="trim"><i class="fa fa-sort-numeric-asc"></i> <em>optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv4 address of your router.
|
||||
|
||||
@@ -369,7 +416,6 @@ IPv6 prefix:
|
||||
|
||||
IPv6 default gateway:
|
||||
: <input type="text" name="GATEWAY6:INDEX" maxlength="39" value="<?=$ethX["GATEWAY6:INDEX"]?>" pattern="<?=$validIP6?>" title="IPv6 address nnnn:xxxx::yyyy">
|
||||
<input type="text" name="METRIC6:INDEX" min="1" max="9999" value="<?=$ethX["METRIC6:INDEX"]?>" class="trim"><em><i class="fa fa-sort-numeric-asc"></i> optional metric (lowest is preferred)</em>
|
||||
|
||||
> Greyed out when using automatic IP assignment. Otherwise specify here the IPv6 address of your router.
|
||||
|
||||
|
||||
@@ -245,21 +245,6 @@ function closeNotifier(filter) {
|
||||
function viewHistory(filter) {
|
||||
location.replace('/Tools/NotificationsArchive?filter='+filter);
|
||||
}
|
||||
function watchdog() {
|
||||
$.post('/webGui/include/Watchdog.php',{mode:<?=$display['refresh']?>,dot:'<?=$display['number'][0]?>'},function(data) {
|
||||
if (data) {
|
||||
$.each(data.split('#'),function(k,v) {
|
||||
<?if ($update):?>
|
||||
if (v!='stop') $('#statusbar').html(v); else setTimeout(refresh,0);
|
||||
});
|
||||
timers.watchdog = setTimeout(watchdog,<?=abs($display['refresh'])?>);
|
||||
<?else:?>
|
||||
if (v!='stop') $('#statusbar').html(v);
|
||||
});
|
||||
<?endif;?>
|
||||
}
|
||||
});
|
||||
}
|
||||
function countDown() {
|
||||
counting--;
|
||||
if (counting==0) counting = update;
|
||||
@@ -419,7 +404,6 @@ $(function() {
|
||||
form.find('input[value="Apply"],input[name="cmdEditShare"],input[name="cmdUserEdit"]').removeAttr('disabled');
|
||||
form.find('input[value="Done"]').val('Reset').prop('onclick',null).click(function(){refresh(form.offset().top)});
|
||||
});});
|
||||
timers.watchdog = setTimeout(watchdog,50);
|
||||
var top = ($.cookie('top')||0) - $('.tabs').offset().top - 75;
|
||||
if (top>0) {$('html,body').scrollTop(top);}
|
||||
$.removeCookie('top',{path:'/'});
|
||||
@@ -486,7 +470,10 @@ $(function() {
|
||||
}
|
||||
|
||||
$('form').append($('<input>').attr({type:'hidden', name:'csrf_token', value:'<?=$var['csrf_token']?>'}));
|
||||
var watchdog = new NchanSubscriber('/sub/watchdog');
|
||||
watchdog.on('message', function(data){$('#statusbar').html(data);});
|
||||
watchdog.start();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2012-2016, Bergware International.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, 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,
|
||||
@@ -12,14 +12,18 @@
|
||||
?>
|
||||
<?
|
||||
if ($_POST['#arg'][1] != 'none') {
|
||||
$ethX = $_POST['#section'];
|
||||
if ($_POST['BONDING']=='yes') {
|
||||
$nics = explode(',',str_replace('eth0','',$_POST['BONDNICS']));
|
||||
$nics = explode(',',str_replace($ethX,'',$_POST['BONDNICS']));
|
||||
// prepare 'other' interfaces which are part of the bond
|
||||
foreach ($nics as $nic) if ($nic) unset($keys[$nic]);
|
||||
}
|
||||
if ($_POST['BRIDGING']=='yes') {
|
||||
$nics = explode(',',str_replace('eth0','',$_POST['BRNICS']));
|
||||
$nics = explode(',',str_replace($ethX,'',$_POST['BRNICS']));
|
||||
// prepare 'other' interfaces which are part of the bridge
|
||||
foreach ($nics as $nic) if ($nic) unset($keys[$nic]);
|
||||
}
|
||||
unset($keys[$_POST['#section']]);
|
||||
// prepare interface to be changed
|
||||
unset($keys[$ethX]);
|
||||
}
|
||||
?>
|
||||
@@ -26,59 +26,63 @@ function ifname($name) {
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
if ($run && file_exists($cfg)) {
|
||||
$old = parse_ini_string(preg_replace('/^#/m',';',file_get_contents($cfg)));
|
||||
if (isset($old['SYSNICS'])) {
|
||||
// new syntax
|
||||
$ifname = ifname($set);
|
||||
} else {
|
||||
// legacy syntax
|
||||
if ($set=='eth0') $ifname = $old['BRIDGING']=='yes' ? ($old['BRNAME'] ?: 'br0') : ($old['BONDING']=='yes' ? ($old['BONDNAME'] ?: 'bond0') : $set);
|
||||
}
|
||||
function bond_nics(&$bond,$nic) {
|
||||
$bond['BONDNICS'] = str_replace(',',' ',$bond['BONDNICS']);
|
||||
return explode(' ',preg_replace("/$nic ?/","",$bond['BONDNICS']));
|
||||
}
|
||||
function bridge_nics(&$bridge,$nic) {
|
||||
$bridge['BRNICS'] = str_replace(',',' ',$bridge['BRNICS']);
|
||||
return explode(' ',preg_replace("/$nic ?/","",$bridge['BRNICS']));
|
||||
}
|
||||
|
||||
// stop interface with existing (old) configuration
|
||||
// don't execute when only interface description has changed
|
||||
if ($run) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_stop")." >/dev/null");
|
||||
|
||||
if ($bonding = $ini['eth0']['BONDING']=='yes') {
|
||||
$ini['eth0']['BONDNICS'] = str_replace(',',' ',$ini['eth0']['BONDNICS']);
|
||||
$bond0 = explode(' ',trim(str_replace('eth0','',$ini['eth0']['BONDNICS'])));
|
||||
// ensure additional NICs in bond are set free
|
||||
if ($run && $set=='eth0') foreach ($bond0 as $nic) {
|
||||
if (isset($old['SYSNICS'])) $nic = ifname($nic);
|
||||
if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null");
|
||||
if ($run) {
|
||||
$old = [];
|
||||
if (file_exists($cfg)) {
|
||||
$old = parse_ini_string(preg_replace('/^#/m',';',file_get_contents($cfg)));
|
||||
if (isset($old['SYSNICS'])) {
|
||||
// new syntax
|
||||
$ifname = ifname($set);
|
||||
} else {
|
||||
// legacy syntax
|
||||
if ($set=='eth0') $ifname = $old['BRIDGING']=='yes' ? ($old['BRNAME'] ?: 'br0') : ($old['BONDING']=='yes' ? ($old['BONDNAME'] ?: 'bond0') : $set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($bridging = $ini['eth0']['BRIDGING']=='yes') {
|
||||
$ini['eth0']['BRNICS'] = str_replace(',',' ',$ini['eth0']['BRNICS']);
|
||||
$br0 = explode(' ',trim(str_replace('eth0','',$ini['eth0']['BRNICS'])));
|
||||
// ensure additional NICs in bridge are set free
|
||||
if ($run && $set=='eth0' && !$bonding) foreach ($br0 as $nic) {
|
||||
if (isset($old['SYSNICS'])) $nic = ifname($nic);
|
||||
if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null");
|
||||
exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_stop")." >/dev/null");
|
||||
if ($ini[$set]['BONDING']=='yes') {
|
||||
// release additional NICs in bond
|
||||
foreach (bond_nics($ini[$set],$set) as $nic) {
|
||||
if (isset($old['SYSNICS'])) $nic = ifname($nic);
|
||||
if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null");
|
||||
}
|
||||
} elseif ($ini[$set]['BRIDGING']=='yes') {
|
||||
// release additional NICs in bridge
|
||||
foreach (bridge_nics($ini[$set],$set) as $nic) {
|
||||
if (isset($old['SYSNICS'])) $nic = ifname($nic);
|
||||
if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create configuration file for all available interfaces
|
||||
$i = 0; $new = []; $new[] = "# Generated settings:";
|
||||
foreach ($ini as $name => $port) {
|
||||
if ($bonding && in_array($name,$bond0)) continue;
|
||||
if ($bridging && in_array($name,$br0)) continue;
|
||||
$bridge = $port['BRIDGING']=='yes';
|
||||
$bonding = $port['BONDING']=='yes';
|
||||
$bridging = $port['BRIDGING']=='yes';
|
||||
if ($bonding && in_array($name,bond_nics($port,$name))) continue;
|
||||
if ($bridging && in_array($name,bridge_nics($port,$name))) continue;
|
||||
$trunk = $port['TYPE']=='trunk';
|
||||
$j = 0; $x0 = 0;
|
||||
$iface = $bridge ? $port['BRNAME'] : ($bonding && $name=='eth0' ? $port['BONDNAME'] : $name);
|
||||
$iface = $bridging ? $port['BRNAME'] : ($bonding ? $port['BONDNAME'] : $name);
|
||||
$new[] = "IFNAME[$i]=\"$iface\"";
|
||||
if ($set==$name) $ifname = $iface;
|
||||
foreach ($port as $key => $val) {
|
||||
if (preg_match('/^(TYPE|BONDING$|BRIDGING)/',$key)) continue;
|
||||
if (!$bonding && preg_match('/^(BONDING_MODE|BONDING_MIIMON|BONDNICS|BONDNAME)/',$key)) continue;
|
||||
if (!$bridge && preg_match('/^(BRSTP|BRFD|BRNICS|BRNAME)/',$key)) continue;
|
||||
if (!$bridging && preg_match('/^(BRSTP|BRFD|BRNICS|BRNAME)/',$key)) continue;
|
||||
list($item,$x) = explode(':',$key,2);
|
||||
if ($trunk && $x>0 && preg_match('/^(VLANID|USE_DHCP|IPADDR6?|NETMASK6?|GATEWAY6?|METRIC6?|PRIVACY6|DESCRIPTION|PROTOCOL)/',$key)) {
|
||||
if ($trunk && $x>0 && preg_match('/^(VLANID|USE_DHCP|IPADDR6?|NETMASK6?|GATEWAY6?|METRIC|PRIVACY6|DESCRIPTION|PROTOCOL)/',$key)) {
|
||||
if ($x0 != $x) {$x0 = $x; $j++;}
|
||||
$vlan = ",$j]";
|
||||
} else $vlan = '';
|
||||
@@ -95,6 +99,7 @@ file_put_contents($cfg,implode("\r\n",$new)."\r\n");
|
||||
// don't execute when only interface description has changed
|
||||
if ($run) {
|
||||
exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_start")." >/dev/null");
|
||||
sleep(1);
|
||||
exec("/usr/local/sbin/create_network_ini >/dev/null");
|
||||
}
|
||||
exit(0);
|
||||
|
||||
36
plugins/dynamix/scripts/watchdog
Executable file
36
plugins/dynamix/scripts/watchdog
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
PREV=
|
||||
while :; do
|
||||
. /var/local/emhttp/var.ini
|
||||
case $fsState in
|
||||
Stopped)
|
||||
DATA="<span class='red strong'>Array Stopped</span>"
|
||||
;;
|
||||
Starting)
|
||||
DATA="<span class='orange strong'>Array Starting</span>"
|
||||
;;
|
||||
*)
|
||||
DATA="<span class='green strong'>Array Started</span>"
|
||||
;;
|
||||
esac
|
||||
if [[ $mdResync -gt 0 ]]; then
|
||||
MODE=
|
||||
if [[ $mdResyncAction =~ recon ]]; then
|
||||
MODE='Parity-Sync / Data-Rebuild'
|
||||
elif [[ $mdResyncAction =~ clear ]]; then
|
||||
MODE='Clearing'
|
||||
elif [[ $mdResyncAction == check ]]; then
|
||||
MODE='Read-Check'
|
||||
elif [[ $mdResyncAction =~ check ]]; then
|
||||
MODE='Parity-Check'
|
||||
fi
|
||||
p=$((mdResyncPos*1000/mdResync)); w=${p:0:-1}
|
||||
DATA="$DATA•<span class='orange strong'>$MODE ${w:-0}.${p: -1} %</span>"
|
||||
fi
|
||||
if [[ $DATA != $PREV ]]; then
|
||||
curl -s -X POST -d "$DATA" http://127.0.0.1/pub/watchdog?buffer_length=1 &>/dev/null
|
||||
PREV=$DATA
|
||||
fi
|
||||
sleep 3
|
||||
done &
|
||||
@@ -1,5 +1,5 @@
|
||||
html,body{font-family:arimo;font-size:12px;color:#808080;background-color:#000000;padding:0;margin:0;}
|
||||
#template{min-width:1070px;max-width:1270px;margin:0 auto;}
|
||||
#template{min-width:1080px;margin:0 10px;}
|
||||
img{border:0;text-decoration:none;vertical-align:middle;}
|
||||
p{text-align:justify;}
|
||||
p.centered{text-align:left;}
|
||||
@@ -36,7 +36,7 @@ select.slot{min-width:400px;max-width:400px;}
|
||||
input.narrow{width:132px;}
|
||||
input.trim{width:50px;}
|
||||
#header{height:90px;}
|
||||
#header.image{background-size:1270px 90px; border-radius:5px;color:#D0D0D0;}
|
||||
#header.image{background-size:100% 90px; border-radius:5px;color:#D0D0D0;}
|
||||
#header .logo{float:left;margin-top:20px;margin-left:20px;}
|
||||
#header .logo img{margin:0 0 2px 1px;}
|
||||
#header .logo a{color:#478406;font-size:18px;}
|
||||
@@ -156,13 +156,13 @@ table.share_status tbody tr.warn{color:#E68A00;background-color:#FEEFB3;}
|
||||
table.share_status.share tr td:last-child{width:4%;text-align:right;padding-right:10px;}
|
||||
table.share_status.fixed{border:1px solid #202020;}
|
||||
table.share_status.fixed thead tr>td+td{font-size:11px;}
|
||||
table.share_status.fixed tr>td+td{width:38px;text-align:center;padding:0;}
|
||||
table.share_status.fixed tr>td+td{min-width:30px;text-align:center;padding:0;}
|
||||
table.share_status.fixed tbody tr{border-bottom:1px #202020 dotted;}
|
||||
table.share_status.fixed tbody tr:nth-child(even){background-color:#000000;}
|
||||
table.share_status.fixed tbody tr td:nth-child(even){background-color:#0C0C0C;}
|
||||
table.share_status.table{margin-top:36px;}
|
||||
table.share_status.table tr>td{width:50%;}
|
||||
table.share_status.dash{float:left;width:33%;margin-top:36px;margin-right:6px;border:1px solid #202020;}
|
||||
table.share_status.dash{float:left;width:33%;margin-top:36px;border:1px solid #202020;}
|
||||
table.share_status.dash thead tr:last-child>td{font-weight:bold;border-bottom:1px solid #202020;}
|
||||
table.share_status.dash tbody td.blue{color:#3B5998;}
|
||||
table.share_status.dash.line {table-layout:fixed;}
|
||||
@@ -176,10 +176,10 @@ table.share_status.dash.line tr>td[colspan="4"]{width:100%;}
|
||||
table.share_status.dash.line tr>td:last-child{white-space:normal;}
|
||||
table.share_status.dash tr.h48{height:48px;}
|
||||
table.share_status.dash td:first-child{width:25%;}
|
||||
table.share_status.m36{width:36%;margin-right:0;}
|
||||
table.share_status.m36{width:36%;float:right;}
|
||||
table.share_status.m36 tr>td+td+td{width:14%;}
|
||||
table.share_status.m36 tr>td+td+td+td{width:8%;text-align:center;}
|
||||
table.share_status.m0{width:30%;}
|
||||
table.share_status.m0{width:30%;margin-left:0.5%;}
|
||||
table.share_status.m0 tr>td+td+td{width:12%;text-align:center;}
|
||||
[name=arrayOps]{margin-top:12px;}
|
||||
span.error{color:#F0000C;background-color:#FF9E9E;display:block;width:100%;}
|
||||
@@ -210,7 +210,7 @@ img.icon{margin:-3px 4px 0 0;}
|
||||
div.content{position:absolute;top:45px;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both;}
|
||||
div.content.shift{margin-top:-70px;}
|
||||
div.tabs{position:relative;margin:24px 0 0 0;}
|
||||
div.tab{float:left;}
|
||||
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;}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
html,body{font-family:arimo;font-size:12px;color:#303030;background-color:#FFFFFF;padding:0;margin:0;}
|
||||
#template{min-width:1070px;max-width:1270px;margin:0 auto;}
|
||||
#template{min-width:1080px;margin:0 10px;}
|
||||
img{border:0;text-decoration:none;vertical-align:middle;}
|
||||
p{text-align:justify;}
|
||||
p.centered{text-align:left;}
|
||||
@@ -35,7 +35,7 @@ select.slot{min-width:400px;max-width:400px;}
|
||||
input.narrow{width:132px;}
|
||||
input.trim{width:50px;}
|
||||
#header{height:90px;}
|
||||
#header.image{background-size:1270px 90px; border-radius:5px;color:#202020;}
|
||||
#header.image{background-size:100% 90px; border-radius:5px;color:#202020;}
|
||||
#header .logo{float:left;margin-top:20px;margin-left:20px;}
|
||||
#header .logo img{margin:0 0 2px 1px;}
|
||||
#header .logo a{color:#478406;font-size:18px;}
|
||||
@@ -154,13 +154,13 @@ table.share_status tbody tr.warn{color:#E68A00;background-color:#FEEFB3;}
|
||||
table.share_status.share tr td:last-child{width:4%;text-align:right;padding-right:10px;}
|
||||
table.share_status.fixed{border:1px solid #D0D0D0;}
|
||||
table.share_status.fixed thead tr>td+td{font-size:11px;}
|
||||
table.share_status.fixed tr>td+td{width:38px;text-align:center;padding:0;}
|
||||
table.share_status.fixed tr>td+td{min-width:30px;text-align:center;padding:0;}
|
||||
table.share_status.fixed tbody tr{border-bottom:1px #D0D0D0 dotted;}
|
||||
table.share_status.fixed tbody tr:nth-child(even){background-color:#FFFFFF;}
|
||||
table.share_status.fixed tbody tr td:nth-child(even){background-color:#F8F8F8;}
|
||||
table.share_status.table{margin-top:36px;}
|
||||
table.share_status.table tr>td{width:50%;}
|
||||
table.share_status.dash{float:left;width:33%;margin-top:36px;margin-right:6px;border:1px solid #D0D0D0;}
|
||||
table.share_status.dash{float:left;width:33%;margin-top:36px;border:1px solid #D0D0D0;}
|
||||
table.share_status.dash thead tr:last-child>td{font-weight:bold;border-bottom:1px solid #D0D0D0;}
|
||||
table.share_status.dash tbody td.blue{color:#3B5998;}
|
||||
table.share_status.dash.line {table-layout:fixed;}
|
||||
@@ -174,10 +174,10 @@ table.share_status.dash.line tr>td[colspan="4"]{width:100%;}
|
||||
table.share_status.dash.line tr>td:last-child{white-space:normal;}
|
||||
table.share_status.dash tr.h48{height:48px;}
|
||||
table.share_status.dash td:first-child{width:25%;}
|
||||
table.share_status.m36{width:36%;margin-right:0;}
|
||||
table.share_status.m36{width:36%;float:right;}
|
||||
table.share_status.m36 tr>td+td+td{width:14%;}
|
||||
table.share_status.m36 tr>td+td+td+td{width:8%;text-align:center;}
|
||||
table.share_status.m0{width:30%;}
|
||||
table.share_status.m0{width:30%;margin-left:0.5%;}
|
||||
table.share_status.m0 tr>td+td+td{width:12%;text-align:center;}
|
||||
[name=arrayOps]{margin-top:12px;}
|
||||
span.error{color:#F0000C;background-color:#FF9E9E;display:block;width:100%;}
|
||||
@@ -208,7 +208,7 @@ img.icon{margin:-3px 4px 0 0;}
|
||||
div.content{position:absolute;top:45px;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both;}
|
||||
div.content.shift{margin-top:-70px;}
|
||||
div.tabs{position:relative;margin:24px 0 0 0;}
|
||||
div.tab{float:left;}
|
||||
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;}
|
||||
|
||||
Reference in New Issue
Block a user