mirror of
https://github.com/unraid/webgui.git
synced 2026-01-10 11:40:12 -06:00
Merge remote-tracking branch 'upstream/master' into Snapshots
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -49,6 +49,9 @@ Temporary Items
|
||||
# Sublime text SFTP configuration file
|
||||
sftp-config.json
|
||||
|
||||
# VS Code SFTP configuration file
|
||||
.vscode/sftp.json
|
||||
|
||||
# =========================
|
||||
# Exclude these dirs commonly found in /usr/local
|
||||
bin/
|
||||
|
||||
@@ -2416,3 +2416,11 @@ A keepalive timer will hold the connection open, for most situations a timer val
|
||||
|
||||
Note that for mobile devices this will use more data and drain your battery faster.
|
||||
:end
|
||||
|
||||
:sysdrivers_intro_help:
|
||||
This page displays all the drivers available on this system. Filter the list according to whether the driver is Inuse or not, or search for a specific driver if desired.
|
||||
|
||||
Any 3rd party driver installed by a plugin will have a support symbol next to it, click this to get support for the plugin.
|
||||
|
||||
Click the edit button to add/modify/delete any modprobe.d config file in the config/modprobe.d directory on the flash drive.
|
||||
:end
|
||||
|
||||
@@ -87,7 +87,7 @@ if (file_exists("/var/run/apcupsd.pid")) {
|
||||
if (count($rows)%2==1) $result[] = "<td></td><td></td></tr>";
|
||||
if ($power && isset($load)) $status[5] = ($load<90 ? "<td $green>" : "<td $red>").round($power*$load/100)." W (".$status[5].")</td>";
|
||||
elseif (isset($load)) $status[5] = ($load<90 ? "<td $green>" : "<td $red>").$status[5]."</td>";
|
||||
$status[6] = $output ? ((!$volt || ($minv<$output && $output<$maxv) ? "<td $green>" : "<td $red>").$status[6].($freq ? " ~ $freq Hz" : "")."</td>") : $status[6];
|
||||
$status[6] = isset($output) ? ((!$volt || ($minv<$output && $output<$maxv) ? "<td $green>" : "<td $red>").$status[6].($freq ? " ~ $freq Hz" : "")."</td>") : $status[6];
|
||||
}
|
||||
if (empty($rows)) $result[] = "<tr><td colspan='4' style='text-align:center'>"._('No information available')."</td></tr>";
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ $include = $include6 = $address = $address6 = $gateway = $gateway6 = $unset = $p
|
||||
$wide = false;
|
||||
foreach ($custom as $network) {
|
||||
if (in_array($network,$slaves)) continue;
|
||||
$ip4 = exec("ip -4 addr show $network|awk '/inet /{print $2;exit}'");
|
||||
$ip6 = exec("ip -6 addr show $network scope global|awk '/inet6 /{print $2;exit}'");
|
||||
$ip4 = exec("ip -br -4 addr show $network scope global|awk '{print $3}'");
|
||||
$ip6 = exec("ip -br -6 addr show $network scope global|awk '{print $3}'");
|
||||
$gw4 = $ip4 ? exec("ip -4 route show dev $network default|awk '{print $3;exit}'") : '';
|
||||
$gw6 = $ip6 ? exec("ip -6 route show dev $network default|awk '{print $3;exit}'") : '';
|
||||
$route4 = $ip4 ? exec("ip -4 route show dev $network $ip4|awk '{print $1;exit}'") : '';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, 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,
|
||||
@@ -36,6 +36,10 @@ function make_link($method, $arg, $extra='') {
|
||||
$id = str_replace(['.',' ','_'],'',$plg);
|
||||
$check = $method=='remove' ? "<input type='checkbox' data='$arg' class='remove' onClick='document.getElementById(\"$id\").disabled=!this.checked;multiRemove()'>" : "";
|
||||
$disabled = $check ? ' disabled' : '';
|
||||
if ($method == 'update' && $extra) {
|
||||
$disabled = 'disabled';
|
||||
$id = $extra;
|
||||
}
|
||||
if ($method == 'delete') {
|
||||
$cmd = "plugin_rm $arg";
|
||||
$func = "refresh";
|
||||
|
||||
@@ -163,12 +163,16 @@ foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) {
|
||||
} else {
|
||||
$latest = plugin('version',$filename);
|
||||
if ($os ? version_compare($latest,$version,'>') : strcmp($latest,$version) > 0) {
|
||||
$version .= "<br><span class='red-text'>$latest</span>";
|
||||
if ($os) {
|
||||
$version = "<small>"._('I have read the release notes')."</small><input type='checkbox' onclick=\"$('#cmdUpdate').prop('disabled',!this.checked)\"><br><span class='red-text'>$latest</span>";
|
||||
} else {
|
||||
$version .= "<br><span class='red-text'>$latest</span>";
|
||||
}
|
||||
$error = null;
|
||||
if ( ! $os && (version_compare(plugin("min",$filename,$error) ?: "1.0",$Unraid['version'],">") || version_compare(plugin("max",$filename,$error) ?: "999.9.9",$Unraid['version'],"<") ) ) {
|
||||
if (!$os && (version_compare(plugin("min",$filename,$error) ?: "1.0",$Unraid['version'],">") || version_compare(plugin("max",$filename,$error) ?: "999.9.9",$Unraid['version'],"<"))) {
|
||||
$status = "<span class='warning'><i class='fa fa-exclamation-triangle' aria-hidden='true'></i> "._("Update Incompatible")."</span>";
|
||||
} else {
|
||||
$status = make_link("update",basename($plugin_file));
|
||||
$status = make_link("update",basename($plugin_file),$os?'cmdUpdate':'');
|
||||
}
|
||||
$changes_file = $filename;
|
||||
if (!$os) $updates++;
|
||||
|
||||
@@ -35,12 +35,12 @@ function showCPUs($uuid) {
|
||||
foreach ($cpus as $pair) {
|
||||
unset($cpu1,$cpu2);
|
||||
[$cpu1, $cpu2] = my_preg_split('/[,-]/',$pair);
|
||||
$check = in_array($cpu1, $vcpu) ? 'fa-circle orange-text':'fa-circle-o';
|
||||
$check = ($vcpu && in_array($cpu1, $vcpu)) ? 'fa-circle orange-text':'fa-circle-o';
|
||||
if (!$cpu2) {
|
||||
echo "<label><i class='fa fa-fw $check'></i> cpu $cpu1</label>";
|
||||
} else {
|
||||
echo "<label class='cpu1'><i class='fa fa-fw $check'></i> cpu $cpu1 / $cpu2</label>";
|
||||
$check = in_array($cpu2, $vcpu) ? 'fa-circle orange-text':'fa-circle-o';
|
||||
$check = ($vcpu && in_array($cpu2, $vcpu)) ? 'fa-circle orange-text':'fa-circle-o';
|
||||
echo "<label class='cpu2'><i class='fa fa-fw $check'></i></label>";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ _(VFIO allow unsafe interrupts)_:
|
||||
_(btrfs filesystem show)_:
|
||||
: <?="<pre id='btrfs-scrub'>".shell_exec("btrfs filesystem show /etc/libvirt")."</pre>"?>
|
||||
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareFS(this,'btrfs-scrub-vm','/etc/libvirt'>
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareFS(this,'btrfs-scrub-vm','/etc/libvirt'>">
|
||||
<?exec("$docroot/webGui/scripts/btrfs_scrub status /etc/libvirt", $scrub_status, $retval);?>
|
||||
_(btrfs scrub status)_:
|
||||
: <?="<pre>".implode("\n", $scrub_status)."</pre>"?>
|
||||
|
||||
@@ -1986,6 +1986,20 @@
|
||||
return $var;
|
||||
}
|
||||
|
||||
function domain_get_vnc_password($domain) {
|
||||
$domain_name = $this->domain_get_name($domain) ;
|
||||
$password = shell_exec("cat /etc/libvirt/qemu/'{$domain_name}.xml' | grep 'passwd'") ;
|
||||
|
||||
if (!$password)
|
||||
return '';
|
||||
|
||||
$strpos = strpos($password, "passwd=") +8 ;
|
||||
$endpos = strpos($password, "'",$strpos) ;
|
||||
$password = substr($password,$strpos, $endpos-$strpos) ;
|
||||
|
||||
return $password ;
|
||||
}
|
||||
|
||||
function domain_get_ws_port($domain) {
|
||||
$tmp = $this->get_xpath($domain, '//domain/devices/graphics/@websocket', false);
|
||||
$var = (int)$tmp[0];
|
||||
|
||||
@@ -1150,6 +1150,7 @@ private static $encoding = 'UTF-8';
|
||||
'protocol' => $lv->domain_get_vmrc_protocol($res),
|
||||
'model' => $lv->domain_get_vnc_model($res),
|
||||
'keymap' => $lv->domain_get_vnc_keymap($res),
|
||||
'password' => $lv->domain_get_vnc_password($res),
|
||||
'port' => $vmrcport,
|
||||
'wsport' => $lv->domain_get_ws_port($res),
|
||||
'autoport' => $autoport,
|
||||
|
||||
@@ -346,12 +346,12 @@
|
||||
foreach ($cpus as $pair) {
|
||||
unset($cpu1,$cpu2);
|
||||
[$cpu1, $cpu2] = my_preg_split('/[,-]/',$pair);
|
||||
$extra = in_array($cpu1, $arrConfig['domain']['vcpu']) ? ($arrConfig['domain']['vcpus'] > 1 ? 'checked' : 'checked disabled') : '';
|
||||
$extra = ($arrConfig['domain']['vcpu'] && in_array($cpu1, $arrConfig['domain']['vcpu'])) ? ($arrConfig['domain']['vcpus'] > 1 ? 'checked' : 'checked disabled') : '';
|
||||
if (!$cpu2) {
|
||||
echo "<label for='vcpu$cpu1' class='checkbox'>cpu $cpu1<input type='checkbox' name='domain[vcpu][]' class='domain_vcpu' id='vcpu$cpu1' value='$cpu1' $extra><span class='checkmark'></span></label>";
|
||||
} else {
|
||||
echo "<label for='vcpu$cpu1' class='cpu1 checkbox'>cpu $cpu1 / $cpu2<input type='checkbox' name='domain[vcpu][]' class='domain_vcpu' id='vcpu$cpu1' value='$cpu1' $extra><span class='checkmark'></span></label>";
|
||||
$extra = in_array($cpu2, $arrConfig['domain']['vcpu']) ? ($arrConfig['domain']['vcpus'] > 1 ? 'checked' : 'checked disabled') : '';
|
||||
$extra = ($arrConfig['domain']['vcpu'] && in_array($cpu2, $arrConfig['domain']['vcpu'])) ? ($arrConfig['domain']['vcpus'] > 1 ? 'checked' : 'checked disabled') : '';
|
||||
echo "<label for='vcpu$cpu2' class='cpu2 checkbox'><input type='checkbox' name='domain[vcpu][]' class='domain_vcpu' id='vcpu$cpu2' value='$cpu2' $extra><span class='checkmark'></span></label>";
|
||||
}
|
||||
}
|
||||
@@ -1044,7 +1044,7 @@
|
||||
|
||||
<tr class="vncpassword">
|
||||
<td>_(VM Console Password)_:</td>
|
||||
<td><input type="password" name="domain[password]" autocomplete='new-password' title="_(password for VNC)_" placeholder="_(password for VNC)_ (_(optional)_)" /></td>
|
||||
<td><input type="password" name="domain[password]" autocomplete='new-password' value="<?=$arrGPU['password']?>" title="_(password for VNC)_" placeholder="_(password for VNC)_ (_(optional)_)" /></td>
|
||||
</tr>
|
||||
<tr class="<?if ($arrGPU['id'] != 'virtual') echo 'was';?>advanced vnckeymap">
|
||||
<td>_(VM Console Keyboard)_:</td>
|
||||
|
||||
@@ -71,7 +71,7 @@ $parity = _var($var,'mdResync');
|
||||
$mover = file_exists('/var/run/mover.pid');
|
||||
$btrfs = exec('pgrep -cf /sbin/btrfs');
|
||||
$dot = _var($display,'number','.,')[0];
|
||||
$zfs = file_exists('/proc/spl/kstat/zfs/arcstats');
|
||||
$zfs = count(array_filter(array_column($disks,'fsType'),function($fs){return str_replace('luks:','',$fs??'')=='zfs';}));
|
||||
|
||||
foreach ($disks as $disk) {
|
||||
switch (_var($disk,'type')) {
|
||||
@@ -174,7 +174,7 @@ switch ($display['theme']) {
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/plugins/dynamix.docker.manager/styles/style-$theme.css")?>">
|
||||
<style>
|
||||
div.frame{padding-top:14px;padding-bottom:160px}
|
||||
div.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(<?=$themes1?'610px':'570px'?>,1fr));column-gap:30px}
|
||||
div.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(<?=$themes1?'610px':'580px'?>,1fr));column-gap:20px}
|
||||
div.tile,i.tile{display:none}
|
||||
div#iframe-popup{display:none;-webkit-overflow-scrolling:touch}
|
||||
div.last{padding-bottom:12px}
|
||||
@@ -182,13 +182,14 @@ div.leftside{float:left;width:66%}
|
||||
div.rightside{float:right;margin:0;text-align:center}
|
||||
div[id$=chart]{margin:-12px 8px -24px -18px}
|
||||
div.template,div#dialogWindow,input#upload{display:none}
|
||||
span.green,span.red,span.orange{padding-left:0}
|
||||
span.ctrl{float:right;margin-top:0;margin-right:10px}
|
||||
span.ctrl span{font-size:2rem!important}
|
||||
span.outer{float:left}
|
||||
span.inner{width:143px}
|
||||
span.rx{width:80px;display:inline-block}
|
||||
span.busy,i.inactive{opacity:0.5}
|
||||
span.dense{width:190px;display:inline-block}
|
||||
span.dense{width:180px;display:inline-block}
|
||||
span#ups_model{margin-right:30px}
|
||||
span#chart-toggle{float:right}
|
||||
span.header,tr.header{font-size:1.1rem!important;text-transform:uppercase;letter-spacing:1px}
|
||||
@@ -219,13 +220,16 @@ i[class^="icon-u-"]{font-size:inherit}
|
||||
i#mycase[class^="case-"]{font-size:128px}
|
||||
i#mycase[class^="fa "]{font-size:96px}
|
||||
a.cpu_close,span.hand{cursor:pointer;z-index:1001}
|
||||
tr#zfs,tr#cpu_chart,.cpu_open{display:none}
|
||||
tr#var0,tr#var1,tr#var2,tr#var3,tr#var4{cursor:alias}
|
||||
tr#var1,tr#var4,tr#cpu_chart,.cpu_open{display:none}
|
||||
td.none{text-align:center;padding-top:12px}
|
||||
input[value=Edit]{margin:12px 0 0 0;padding:5px 10px}
|
||||
.share1,.share3,.user1,.user3,.view1,.view2,.view3,.view4{display:none}
|
||||
.share1,.share3,.user1,.user3,.view1,.view2,.view3,.view4,.unused{display:none}
|
||||
.port_view,.control,#apps,#vms{z-index:10000}
|
||||
.flat{height:0;lineheight:0}
|
||||
.wrap{white-space:normal}
|
||||
.switch-button-background{margin-left:0;margin-top:4px}
|
||||
.switch-button-label{margin-top:3px}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button[disabled]{cursor:default;color:#808080;background:-webkit-gradient(linear,left top,right top,from(#404040),to(#808080)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#404040),to(#808080)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#404040),to(#404040)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#808080),to(#808080)) 100% 100% no-repeat;background:linear-gradient(90deg,#404040 0,#808080) 0 0 no-repeat,linear-gradient(90deg,#404040 0,#808080) 0 100% no-repeat,linear-gradient(0deg,#404040 0,#404040) 0 100% no-repeat,linear-gradient(0deg,#808080 0,#808080) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%}
|
||||
</style>
|
||||
<script src="<?autov('/webGui/javascript/jquery.apexcharts.js')?>"></script>
|
||||
@@ -238,8 +242,9 @@ input[value=Edit]{margin:12px 0 0 0;padding:5px 10px}
|
||||
<div class='tile' id='tile1'>
|
||||
<table id='db-box1' class='share_status dashboard'>
|
||||
<tbody class='system'>
|
||||
<tr><td><?=_var($var,'NAME')?>
|
||||
<i class='fa fa-fw fa-wrench control tile' onclick='contentMgmt()' title="_(Content Management)_"></i><a href='/Dashboard/Settings/Identification'><i class='fa fa-fw fa-cog control' title="_(Go to identification settings)_"></i></a>
|
||||
<tr><td><i class='icon-performance f32'></i><div class='section'><?=_var($var,'NAME')?><br>
|
||||
<span><?=_var($var,'COMMENT')?></span><br></div>
|
||||
<a href='/Dashboard/Settings/Identification'><i class='fa fa-fw fa-cog control' title="_(Go to identification settings)_"></i></a><i class='fa fa-fw fa-wrench control tile' onclick='contentMgmt()' title="_(Tile Management)_"></i>
|
||||
<span class='ctrl'>
|
||||
<?if ($parity||$mover||$btrfs):?>
|
||||
<span class='fa fa-fw fa-<?=$started?'stop':'play'?>-circle busy' title="<?=$started?_("Stop the array"):_("Start the array")?>"></span>
|
||||
@@ -252,7 +257,7 @@ input[value=Edit]{margin:12px 0 0 0;padding:5px 10px}
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
<div class='leftside'>
|
||||
<span class='header'><i class='indent fa fa-file-text-o'></i>_(Description)_</span><br><i class='indent'></i><?=_var($var,'COMMENT')?><br><i class='indent'></i><?=_var($var,'SYS_MODEL')?><br><br>
|
||||
<span class='header'><i class='indent fa fa-file-text-o'></i>_(Model)_</span><br><i class='indent'></i><?=_var($var,'SYS_MODEL')?:'---'?><br><br>
|
||||
<span class='header'><i class='indent fa fa-id-badge'></i>_(Registration)_</span><br><i class='indent'></i>Unraid OS <b><em><?=_var($var,'regTy')?></em></b><br><br>
|
||||
<span class='header'><i class='indent fa fa-clock-o'></i>_(Uptime)_</span><br><i class='indent'></i><span class='uptime'></span>
|
||||
</div>
|
||||
@@ -274,14 +279,14 @@ input[value=Edit]{margin:12px 0 0 0;padding:5px 10px}
|
||||
</tbody>
|
||||
|
||||
<tbody title="_(Motherboard Information)_">
|
||||
<tr><td><i class='icon-motherboard f32'></i><div class='section'>_(Motherboard)_<br><span id='mb-temp'></span><br><br></div>
|
||||
<tr><td><i class='icon-motherboard f32'></i><div class='section'>_(Motherboard)_<br><span id='mb-temp'></span><br></div>
|
||||
<a href='#' onclick='InfoButton();' title="_(Show Information)_"><i class='fa fa-fw fa-info-circle control'></i></a>
|
||||
</td></tr>
|
||||
<tr><td><?=$board?><br><?=$bios?><br><?=$biosdate?></td></tr>
|
||||
</tbody>
|
||||
|
||||
<tbody title="_(Processor Information)_">
|
||||
<tr><td><i class='icon-cpu f32'></i><div class='section'>_(Processor)_<br><span id='cpu-temp'></span><br><br></div>
|
||||
<tbody title="_(Processor Information)_" data="toggleCPU(true)">
|
||||
<tr><td><i class='icon-cpu f32'></i><div class='section'>_(Processor)_<br><span id='cpu-temp'></span><br></div>
|
||||
<a href='/Dashboard/Settings/CPUset' title="_(Go to CPU pinning settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
<tr><td><?=$cpumodel?></td></tr>
|
||||
@@ -309,20 +314,18 @@ foreach ($cpus as $pair) {
|
||||
</tbody>
|
||||
|
||||
<tbody title="_(Memory Utilization)_">
|
||||
<tr><td><i class='icon-ram f32'></i><div class='section'>_(Memory)_<br><span><i class='ups fa fa-line-chart'></i><?="$memory_installed $unit $memory_type $ecc"?></span><br><br></div>
|
||||
<tr><td><i class='icon-ram f32'></i><div class='section'>_(System)_<br><span><i class='ups fa fa-line-chart'></i>_(Memory)_: <?="$memory_installed $unit $memory_type $ecc"?></span><br></div>
|
||||
<a href='/Dashboard/Tools/Processes' title="_(View Running Processes)_"><i class='fa fa-fw fa-info-circle control'></i></a>
|
||||
</td></tr>
|
||||
<tr><td><span class='w36'><i class='ups fa fa-compress'></i>_(Usable size)_: <?=my_scale($total,$unit,1,null,1024)." $unit"?></span><i class='ups fa fa-expand'></i>_(Maximum size)_: <?="$memory_maximum $unit"?><?=$low?'*':''?></td></tr>
|
||||
<tr><td><span class='w26'><i class='ups fa fa-fw fa-microchip'></i>_(RAM)_</span><span class='w72'><span class='sys0 load'>0%</span><div class='usage-disk sys'><span id='sys0'></span><span></span></div></span></td></tr>
|
||||
<tr id='zfs'><td><span class='w26'><i class='ups fa fa-fw fa-shield'></i>_(ZFS)_</span><span class='w72'><span class='sys1 load'>0%</span><div class='usage-disk sys'><span id='sys1'></span><span></span></div></span></td></tr>
|
||||
<tr><td><span class='w26'><i class='ups fa fa-fw fa-suitcase'></i>_(Flash)_</span><span class='w72'><span class='sys2 load'>0%</span><div class='usage-disk sys'><span id='sys2'></span><span></span></div></span></td></tr>
|
||||
<tr><td><span class='w26'><i class='ups fa fa-fw fa-file-text'></i>_(Log)_</span><span class='w72'><span class='sys3 load'>0%</span><div class='usage-disk sys'><span id='sys3'></span><span></span></div></span></td></tr>
|
||||
<?if (exec("df /var/lib/docker|grep -om1 '^/'")):?>
|
||||
<tr><td><span class='w26'><i class='ups fa fa-fw fa-docker'></i>_(Docker)_</span><span class='w72'><span class='sys4 load'>0%</span><div class='usage-disk sys'><span id='sys4'></span><span></span></div></span></td></tr>
|
||||
<?endif;?>
|
||||
<tr id='var0'><td><span class='w26'><i class='ups fa fa-fw fa-microchip'></i>_(RAM)_</span><span class='w72'><span class='sys0 load'>0%</span><div class='usage-disk sys'><span id='sys0'></span><span></span></div></span></td></tr>
|
||||
<tr id='var1'><td><span class='w26'><i class='ups fa fa-fw fa-shield'></i>_(ZFS)_</span><span class='w72'><span class='sys1 load'>0%</span><div class='usage-disk sys'><span id='sys1'></span><span></span></div></span></td></tr>
|
||||
<tr id='var2'><td><span class='w26'><i class='ups fa fa-fw fa-suitcase'></i>_(Flash)_</span><span class='w72'><span class='sys2 load'>0%</span><div class='usage-disk sys'><span id='sys2'></span><span></span></div></span></td></tr>
|
||||
<tr id='var3'><td><span class='w26'><i class='ups fa fa-fw fa-file-text'></i>_(Log)_</span><span class='w72'><span class='sys3 load'>0%</span><div class='usage-disk sys'><span id='sys3'></span><span></span></div></span></td></tr>
|
||||
<tr id='var4'><td><span class='w26'><i class='ups fa fa-fw fa-docker'></i>_(Docker)_</span><span class='w72'><span class='sys4 load'>0%</span><div class='usage-disk sys'><span id='sys4'></span><span></span></div></span></td></tr>
|
||||
</tbody>
|
||||
|
||||
<tbody title="_(Interface Information)_">
|
||||
<tbody title="_(Interface Information)_" class="mixed">
|
||||
<tr><td><i class='icon-ethernet f32'></i><div class='section'>_(Interface)_<br>
|
||||
<span><span class='dense'><i class='ups fa fa-angle-double-down'></i>_(Inbound)_: <span id='inbound'>---</span></span><span class='dense'><i class='ups fa fa-angle-double-up'></i>_(Outbound)_: <span id='outbound'>---</span></span>
|
||||
<i class='ups fa fa-angle-right'></i><select name="port_select" onchange="portSelect(this.value)">
|
||||
@@ -330,7 +333,7 @@ foreach ($cpus as $pair) {
|
||||
<?=mk_option("",$port,_($port))?>
|
||||
<?endforeach;?>
|
||||
</select></span>
|
||||
<br><br></div>
|
||||
<br></div>
|
||||
<a href='/Dashboard/Settings/NetworkSettings' title="_(Go to network settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
<tr><td><span class='w26'><select name="enter_view" onchange="changeView(this.value)">
|
||||
@@ -372,7 +375,7 @@ foreach ($ports as $port) {
|
||||
|
||||
<?if ($wireguard):?>
|
||||
<tbody title="_(VPN Connections)_">
|
||||
<tr><td><i class='icon-vpn f32'></i><div class='section'>_(VPN)_<br><span><span class='dense'><i class='ups fa fa-play-circle'></i>_(Active tunnels)_: <span id='vpn-active'><?=$up?></span></span><i class='ups fa fa-pause-circle'></i>_(Inactive tunnels)_: <span id='vpn-inactive'><?=$down?></span></span><br><br></div>
|
||||
<tr><td><i class='icon-vpn f32'></i><div class='section'>_(VPN)_<br><span><span class='dense'><i class='ups fa fa-play-circle'></i>_(Active tunnels)_: <span id='vpn-active'><?=$up?></span></span><i class='ups fa fa-pause-circle'></i>_(Inactive tunnels)_: <span id='vpn-inactive'><?=$down?></span></span><br></div>
|
||||
<a href='/Settings/VPNmanager' title="_(Go to VPN settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
<?foreach ($conf as $wg):?>
|
||||
@@ -389,7 +392,7 @@ foreach ($ports as $port) {
|
||||
<?if ($apcupsd):?>
|
||||
<tbody title="_(Power Status)_">
|
||||
<tr><td><i class='icon-ups f32'></i><div class='section'>_(Power)_<br>
|
||||
<span><i class='ups fa fa-bar-chart'></i>_(UPS Model)_: </span><span id='ups_model'></span><br><br></div>
|
||||
<span><i class='ups fa fa-bar-chart'></i>_(UPS Model)_: </span><span id='ups_model'></span><br></div>
|
||||
<a href='/Dashboard/Settings/UPSsettings' title="_(Go to UPS settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
<tr><td><span class='w36'><i class='ups fa fa-fw fa-plug'></i>_(UPS status)_:</span><span id='ups_status'></span></td></tr>
|
||||
@@ -403,7 +406,7 @@ foreach ($ports as $port) {
|
||||
|
||||
<?if ($fans):?>
|
||||
<tbody title="_(Fan Information)_">
|
||||
<tr><td><i class='icon-fan f32'></i><div class='section'>_(Airflow)_<br><span><i class='ups fa fa-sort-amount-asc'></i>_(Fan count)_: <?=$fans?></span><br><br></div>
|
||||
<tr><td><i class='icon-fan f32'></i><div class='section'>_(Airflow)_<br><span><i class='ups fa fa-sort-amount-asc'></i>_(Fan count)_: <?=$fans?></span><br></div>
|
||||
|
||||
<?if ($autofan):?>
|
||||
<a href='/Dashboard/Settings/FanSettings' title="_(Go to fan settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
@@ -443,27 +446,25 @@ echo "</td></tr>";
|
||||
<table id='db-box2' class='share_status dashboard'>
|
||||
<?if ($display['dashapps']!='none'):?>
|
||||
<?if ($dockerd && ($display['dashapps']=='icons' || $display['dashapps']=='docker')):?>
|
||||
<tbody id='docker_view' title="_(Docker Containers)_">
|
||||
<tr><td>_(Docker Containers)_
|
||||
<tbody id='docker_view' title="_(Docker Containers)_" data="noApps()">
|
||||
<tr><td><i class='icon-docker f32'></i><div class='section'>_(Docker Containers)_<br>
|
||||
<span class='apps'><input type='checkbox' id='apps'></span><br></div>
|
||||
<a href='/Dashboard/Settings/DockerSettings' title="_(Go to Docker settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
<span class='info apps'><input type='checkbox' id='apps'></span>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
<?endif;?>
|
||||
<?if ($libvirtd && ($display['dashapps']=='icons' || $display['dashapps']=='vms')):?>
|
||||
<tbody id='vm_view' title="_(Virtual Machines)_">
|
||||
<tr><td>_(Virtual Machines)_
|
||||
<tbody id='vm_view' title="_(Virtual Machines)_" data="noVMs()">
|
||||
<tr><td><i class='icon-virtualization f32'></i><div class='section'>_(Virtual Machines)_<br>
|
||||
<span class='vms'><input type='checkbox' id='vms'></span><br></div>
|
||||
<a href='/Dashboard/Settings/VMSettings' title="_(Go to VM settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
<span class='info vms'><input type='checkbox' id='vms'></span>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
|
||||
<tbody title="_(Shares Information)_">
|
||||
<tr><td>_(Shares)_
|
||||
<a href='/Shares' title="_(Go to Share settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
<span class='info'><?=sprintf(_("Share count: %s with %s cache only and %s encrypted"),count($shares),$cache_only,$encrypted)?></span>
|
||||
<tbody title="_(Shares Information)_"<?if ($group):?> class="mixed"<?endif;?>>
|
||||
<tr><td><i class='icon-folder f32'></i><div class='section'>_(Shares)_
|
||||
<?if ($group):?>
|
||||
<select name="enter_share" onchange="changeMode(this.value)">
|
||||
<?if (_var($var,'shareSMBEnabled')=='yes'):?>
|
||||
@@ -474,6 +475,10 @@ echo "</td></tr>";
|
||||
<?endif;?>
|
||||
</select>
|
||||
<?endif;?>
|
||||
<br><span>
|
||||
<?=sprintf(_("Share count: %s with %s cache only and %s encrypted"),count($shares),$cache_only,$encrypted)?>
|
||||
</span><br></div>
|
||||
<a href='/Shares' title="_(Go to Share settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
<tr class='header'><td><span class='w26'>_(Name)_</span><span class='w44'>_(Description)_</span><span class='w18'>_(Security)_</span><span>_(Streams)_</span></td></tr>
|
||||
<?
|
||||
@@ -516,10 +521,22 @@ if (!$group) {
|
||||
?>
|
||||
</tbody>
|
||||
|
||||
<tbody title="_(Users Information)_">
|
||||
<tr><td>_(Users)_
|
||||
<tbody title="_(Users Information)_"<?if ($group):?> class="mixed"<?endif;?>>
|
||||
<tr><td><i class='icon-users f32'></i><div class='section'>_(Users)_
|
||||
<?if ($group):?>
|
||||
<select name="enter_user" class="unused">
|
||||
<?if (_var($var,'shareSMBEnabled')=='yes'):?>
|
||||
<?=mk_option("", "0", "SMB")?>
|
||||
<?endif;?>
|
||||
<?if (_var($var,'shareNFSEnabled')=='yes'):?>
|
||||
<?=mk_option("", "2", "NFS")?>
|
||||
<?endif;?>
|
||||
</select>
|
||||
<?endif;?>
|
||||
<br><span>
|
||||
<?=sprintf(_("User count: %s with %s unprotected"),count($users),$nopass)?>
|
||||
</span><br></div>
|
||||
<a href='/Users' title="_(Go to User settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
<span class='info'><?=sprintf(_("User count: %s with %s unprotected"),count($users),$nopass)?></span>
|
||||
</td></tr>
|
||||
<tr class='header'><td><span class='w26'>_(Name)_</span><span class='w44'>_(Description)_</span><span class='w18'>_(Write)_</span><span>_(Read)_</span></td></tr>
|
||||
<?
|
||||
@@ -584,15 +601,19 @@ if (!$group) {
|
||||
<div class='tile' id='tile3'>
|
||||
<table id='db-box3' class='share_status dashboard'>
|
||||
<tbody title="_(Parity Information)_">
|
||||
<tr><td>_(Parity)_<a href='/Dashboard/Settings/Scheduler' title="_(Go to scheduler settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
<span class='info title'></span></td></tr>
|
||||
<tr><td><i class='icon-health f32'></i><div class='section'>_(Parity)_<br>
|
||||
<span class='parity'></span><br></div>
|
||||
<a href='/Dashboard/Settings/Scheduler' title="_(Go to scheduler settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
</td></tr>
|
||||
<tr><td id='parity' class="wrap"></td></tr>
|
||||
<tr><td id='program' class="wrap"></td></tr>
|
||||
</tbody>
|
||||
|
||||
<tbody id='array_list' title="_(Array Information)_">
|
||||
<tr><td>_(Array)_<?if (!$started):?> (_(stopped)_)<?endif;?><a href='/Dashboard/Settings/DiskSettings' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
<?if ($started):?><span class='info'><?=sprintf(_("%s used of %s (%s %%)"),my_scale($array_used*1024,$unit)." $unit",my_scale($array_size*1024,$unit,-1,-1)." $unit",$array_percent)?></span><?endif;?>
|
||||
<tr><td><i class='icon-disks f32'></i><div class='section'>_(Array)_<?if (!$started):?> (_(stopped)_)<?endif;?><br>
|
||||
<span><?if ($started):?><?=sprintf(_("%s used of %s (%s %%)"),my_scale($array_used*1024,$unit)." $unit",my_scale($array_size*1024,$unit,-1,-1)." $unit",$array_percent)?><?endif;?></span><br></div>
|
||||
<a href='/Dashboard/Settings/DiskSettings' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
<tr><td id='array_info'></td></tr>
|
||||
<tr class='header'><td><span class='w26'>_(Device)_</span><span class='w18'>_(Status)_</span><span class='w18'>_(Temp)_</span><span class='w18'>_(SMART)_</span><span class='w18'>_(Utilization)_</span></td></tr>
|
||||
@@ -601,8 +622,9 @@ if (!$group) {
|
||||
<?$i=0?>
|
||||
<?foreach ($pools as $pool):?>
|
||||
<tbody id='pool_list<?=$i?>' title="_(<?=ucfirst($pool)?> Information)_">
|
||||
<tr><td><?=ucfirst($pool)?><?if (!$started):?> (_(stopped)_)<?endif;?><a href='/Dashboard/Settings/Device?name=<?=$pool?>' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
<?if ($started):?><span class='info'><?=sprintf(_("%s used of %s (%s %%)"),my_scale($cache_used[$pool]*1024,$unit)." $unit",my_scale($cache_size[$pool]*1024,$unit,-1,-1)." $unit",$cache_rate[$pool])?></span><?endif;?>
|
||||
<tr><td><i class='icon-disk f32'></i><div class='section'><?=ucfirst($pool)?><?if (!$started):?> (_(stopped)_)<?endif;?><br>
|
||||
<span><?if ($started):?><?=sprintf(_("%s used of %s (%s %%)"),my_scale($cache_used[$pool]*1024,$unit)." $unit",my_scale($cache_size[$pool]*1024,$unit,-1,-1)." $unit",$cache_rate[$pool])?><?endif;?></span><br></div>
|
||||
<a href='/Dashboard/Settings/Device?name=<?=$pool?>' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
<tr><td id='pool_info<?=$i++?>'></td></tr>
|
||||
<tr class='header'><td><span class='w26'>_(Device)_</span><span class='w18'>_(Status)_</span><span class='w18'>_(Temp)_</span><span class='w18'>_(SMART)_</span><span class='w18'>_(Utilization)_</span></td></tr>
|
||||
@@ -611,7 +633,10 @@ if (!$group) {
|
||||
|
||||
<?if ($devs):?>
|
||||
<tbody id='devs_list' title="_(Unassigned Devices)_">
|
||||
<tr><td>_(Unassigned)_<span class='info'></span></td></tr>
|
||||
<tr><td><i class='icon-disc f32'></i><div class='section'>_(Unassigned)_<?if (!$started):?> (_(stopped)_)<?endif;?><br>
|
||||
<span></span><br></div>
|
||||
<a href='/Dashboard/Settings/DiskSettings' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
<tr><td id='devs_info'></td></tr>
|
||||
<tr class='header'><td><span class='w26'>_(Device)_</span><span class='w18'>_(Status)_</span><span class='w18'>_(Temp)_</span><span class='w18'>_(SMART)_</span><span class='w18'>_(Utilization)_</span></td></tr>
|
||||
</tbody>
|
||||
@@ -678,18 +703,84 @@ function hideShow() {
|
||||
Number.prototype.pad = function(size){var s=String(this);while(s.length<(size||2)){s='0'+s;}return s;}
|
||||
Array.prototype.tail = function(t){return this.slice(-t).map(function(o){return o.y;}).join(';');}
|
||||
String.prototype.build = function(){return this.replace(/\n(<!--!|!-->)\n/g,'');}
|
||||
String.prototype.marker = function(){return this.substr(0,12).replace(/ /g,'').toLowerCase();}
|
||||
String.prototype.md5 = function() {
|
||||
// Original copyright (c) Paul Johnston & Greg Holt.
|
||||
var hc = '0123456789abcdef';
|
||||
function rh(n){var j,s='';for(j=0;j<=3;j++) s+=hc.charAt((n>>(j*8+4))&0x0F)+hc.charAt((n>>(j*8))&0x0F);return s;}
|
||||
function ad(x,y){var l=(x&0xFFFF)+(y&0xFFFF);var m=(x>>16)+(y>>16)+(l>>16);return (m<<16)|(l&0xFFFF);}
|
||||
function rl(n,c){return (n<<c)|(n>>>(32-c));}
|
||||
function cm(q,a,b,x,s,t){return ad(rl(ad(ad(a,q),ad(x,t)),s),b);}
|
||||
function ff(a,b,c,d,x,s,t){return cm((b&c)|((~b)&d),a,b,x,s,t);}
|
||||
function gg(a,b,c,d,x,s,t){return cm((b&d)|(c&(~d)),a,b,x,s,t);}
|
||||
function hh(a,b,c,d,x,s,t){return cm(b^c^d,a,b,x,s,t);}
|
||||
function ii(a,b,c,d,x,s,t){return cm(c^(b|(~d)),a,b,x,s,t);}
|
||||
function sb(x) {
|
||||
var i;var nblk=((x.length+8)>>6)+1;var blks=new Array(nblk*16);for(i=0;i<nblk*16;i++) blks[i]=0;
|
||||
for(i=0;i<x.length;i++) blks[i>>2]|=x.charCodeAt(i)<<((i%4)*8);
|
||||
blks[i>>2]|=0x80<<((i%4)*8);blks[nblk*16-2]=x.length*8;return blks;
|
||||
}
|
||||
var i,x=sb(''+this),a=1732584193,b=-271733879,c=-1732584194,d=271733878,olda,oldb,oldc,oldd;
|
||||
for(i=0;i<x.length;i+=16) {olda=a;oldb=b;oldc=c;oldd=d;
|
||||
a=ff(a,b,c,d,x[i+ 0], 7, -680876936);d=ff(d,a,b,c,x[i+ 1],12, -389564586);c=ff(c,d,a,b,x[i+ 2],17, 606105819);
|
||||
b=ff(b,c,d,a,x[i+ 3],22,-1044525330);a=ff(a,b,c,d,x[i+ 4], 7, -176418897);d=ff(d,a,b,c,x[i+ 5],12, 1200080426);
|
||||
c=ff(c,d,a,b,x[i+ 6],17,-1473231341);b=ff(b,c,d,a,x[i+ 7],22, -45705983);a=ff(a,b,c,d,x[i+ 8], 7, 1770035416);
|
||||
d=ff(d,a,b,c,x[i+ 9],12,-1958414417);c=ff(c,d,a,b,x[i+10],17, -42063);b=ff(b,c,d,a,x[i+11],22,-1990404162);
|
||||
a=ff(a,b,c,d,x[i+12], 7, 1804603682);d=ff(d,a,b,c,x[i+13],12, -40341101);c=ff(c,d,a,b,x[i+14],17,-1502002290);
|
||||
b=ff(b,c,d,a,x[i+15],22, 1236535329);a=gg(a,b,c,d,x[i+ 1], 5, -165796510);d=gg(d,a,b,c,x[i+ 6], 9,-1069501632);
|
||||
c=gg(c,d,a,b,x[i+11],14, 643717713);b=gg(b,c,d,a,x[i+ 0],20, -373897302);a=gg(a,b,c,d,x[i+ 5], 5, -701558691);
|
||||
d=gg(d,a,b,c,x[i+10], 9, 38016083);c=gg(c,d,a,b,x[i+15],14, -660478335);b=gg(b,c,d,a,x[i+ 4],20, -405537848);
|
||||
a=gg(a,b,c,d,x[i+ 9], 5, 568446438);d=gg(d,a,b,c,x[i+14], 9,-1019803690);c=gg(c,d,a,b,x[i+ 3],14, -187363961);
|
||||
b=gg(b,c,d,a,x[i+ 8],20, 1163531501);a=gg(a,b,c,d,x[i+13], 5,-1444681467);d=gg(d,a,b,c,x[i+ 2], 9, -51403784);
|
||||
c=gg(c,d,a,b,x[i+ 7],14, 1735328473);b=gg(b,c,d,a,x[i+12],20,-1926607734);a=hh(a,b,c,d,x[i+ 5], 4, -378558);
|
||||
d=hh(d,a,b,c,x[i+ 8],11,-2022574463);c=hh(c,d,a,b,x[i+11],16, 1839030562);b=hh(b,c,d,a,x[i+14],23, -35309556);
|
||||
a=hh(a,b,c,d,x[i+ 1], 4,-1530992060);d=hh(d,a,b,c,x[i+ 4],11, 1272893353);c=hh(c,d,a,b,x[i+ 7],16, -155497632);
|
||||
b=hh(b,c,d,a,x[i+10],23,-1094730640);a=hh(a,b,c,d,x[i+13], 4, 681279174);d=hh(d,a,b,c,x[i+ 0],11, -358537222);
|
||||
c=hh(c,d,a,b,x[i+ 3],16, -722521979);b=hh(b,c,d,a,x[i+ 6],23, 76029189);a=hh(a,b,c,d,x[i+ 9], 4, -640364487);
|
||||
d=hh(d,a,b,c,x[i+12],11, -421815835);c=hh(c,d,a,b,x[i+15],16, 530742520);b=hh(b,c,d,a,x[i+ 2],23, -995338651);
|
||||
a=ii(a,b,c,d,x[i+ 0], 6, -198630844);d=ii(d,a,b,c,x[i+ 7],10, 1126891415);c=ii(c,d,a,b,x[i+14],15,-1416354905);
|
||||
b=ii(b,c,d,a,x[i+ 5],21, -57434055);a=ii(a,b,c,d,x[i+12], 6, 1700485571);d=ii(d,a,b,c,x[i+ 3],10,-1894986606);
|
||||
c=ii(c,d,a,b,x[i+10],15, -1051523);b=ii(b,c,d,a,x[i+ 1],21,-2054922799);a=ii(a,b,c,d,x[i+ 8], 6, 1873313359);
|
||||
d=ii(d,a,b,c,x[i+15],10, -30611744);c=ii(c,d,a,b,x[i+ 6],15,-1560198380);b=ii(b,c,d,a,x[i+13],21, 1309151649);
|
||||
a=ii(a,b,c,d,x[i+ 4], 6, -145523070);d=ii(d,a,b,c,x[i+11],10,-1120210379);c=ii(c,d,a,b,x[i+ 2],15, 718787259);
|
||||
b=ii(b,c,d,a,x[i+ 9],21, -343485551);a=ad(a,olda);b=ad(b,oldb);c=ad(c,oldc);d=ad(d,oldd);
|
||||
}
|
||||
return rh(a)+rh(b)+rh(c)+rh(d);
|
||||
}
|
||||
jQuery.prototype.hideMe = function() {
|
||||
var hidden = $.cookie('hidden_content');
|
||||
hidden = hidden==null ? [] : hidden.split(';');
|
||||
if (hidden.indexOf(this.attr('sort'))>=0) this.find('tr:gt(0)').hide();
|
||||
}
|
||||
jQuery.prototype.mixedView = function(s) {
|
||||
if (s==0) {
|
||||
this.find('tr:gt(0)').hide();
|
||||
return;
|
||||
}
|
||||
this.find('tr:gt(0)').show();
|
||||
if (this.attr('data')) {
|
||||
setTimeout(this.attr('data'));
|
||||
}
|
||||
if (this.hasClass('mixed')) {
|
||||
var select = this.find('select[name^="enter"]');
|
||||
select = parseInt(select.val())+1;
|
||||
this.find('tr:gt(0)').each(function(){
|
||||
var names = ($(this).attr('class')||'').split(' ');
|
||||
for (var n=0,name; name=names[n]; n++) if (/[0-9]/.test(name.slice(-1)) && name.slice(-1)!=select) $(this).hide();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var ports = [<?=implode(',',array_map('escapestring',$ports))?>];
|
||||
var cpu = [];
|
||||
var rxd = [];
|
||||
var txd = [];
|
||||
var cputime = 0;
|
||||
var nettime = 0;
|
||||
var cpuline = $.cookie('cpuline')||30;
|
||||
var netline = $.cookie('netline')||30;
|
||||
var update2 = true;
|
||||
var box = null;
|
||||
var ports = [<?=implode(',',array_map('escapestring',$ports))?>];
|
||||
var cpu = [];
|
||||
var rxd = [];
|
||||
var txd = [];
|
||||
var cputime = 0;
|
||||
var nettime = 0;
|
||||
var cpuline = $.cookie('cpuline')||30;
|
||||
var netline = $.cookie('netline')||30;
|
||||
var update2 = true;
|
||||
var box = null;
|
||||
var startup = true;
|
||||
|
||||
var options_cpu = {
|
||||
series:[{name:'load', data:cpu.slice()}],
|
||||
@@ -879,8 +970,8 @@ function noVMs() {
|
||||
}
|
||||
function loadlist(init) {
|
||||
if (init) {
|
||||
$('#apps').switchButton({labels_placement:'left', off_label:"_(All Apps)_", on_label:"_(Started only)_", checked:$.cookie('my_apps')=='startedOnly'});
|
||||
$('#vms').switchButton({labels_placement:'left', off_label:"_(All VMs)_", on_label:"_(Started only)_", checked:$.cookie('my_vms')=='startedOnly'});
|
||||
$('#apps').switchButton({labels_placement:'right', off_label:"_(All Apps)_", on_label:"_(Started only)_", checked:$.cookie('my_apps')=='startedOnly'});
|
||||
$('#vms').switchButton({labels_placement:'right', off_label:"_(All VMs)_", on_label:"_(Started only)_", checked:$.cookie('my_vms')=='startedOnly'});
|
||||
$('#apps').change(function(){
|
||||
$('span.outer.apps.stopped').finish().toggle('fast',function(){noApps();})
|
||||
$('#apps').is(':checked') ? $.cookie('my_apps','startedOnly',{expires:3650}) : $.removeCookie('my_apps');
|
||||
@@ -893,9 +984,9 @@ function loadlist(init) {
|
||||
$.post('/webGui/include/DashboardApps.php',{display:'<?=$display['dashapps']?>',docker:'<?=$dockerd?>',vms:'<?=$libvirtd?>'},function(d) {
|
||||
var data = d.split('\0');
|
||||
$('#docker_view tr.updated').remove();
|
||||
$('#docker_view').append(data[0]);
|
||||
$('#docker_view').append(data[0]).hideMe();
|
||||
$('#vm_view tr.updated').remove();
|
||||
$('#vm_view').append(data[1]);
|
||||
$('#vm_view').append(data[1]).hideMe();
|
||||
if ($.cookie('my_apps')!=null) $('span.apps.stopped').hide(0,noApps());
|
||||
if ($.cookie('my_vms')!=null) $('span.vms.stopped').hide(0,noVMs());
|
||||
});
|
||||
@@ -915,13 +1006,22 @@ function getCase() {
|
||||
function changeMode(item) {
|
||||
if (item==0) $.removeCookie('enter_share'); else $.cookie('enter_share',item,{expires:3650});
|
||||
<?if (_var($var,'shareSMBEnabled')=='yes'):?>
|
||||
if (item==0) $('.smb.user1').show(); else $('.smb.user1').hide();
|
||||
if (item==0) $('.smb.share1').show(); else $('.smb.share1').hide();
|
||||
if (startup || $('.smb.share1').parent().find('tr:eq(1)').is(':visible')) {
|
||||
if (item==0) $('.smb.share1').show(); else $('.smb.share1').hide();
|
||||
}
|
||||
if (startup || $('.smb.user1').parent().find('tr:eq(1)').is(':visible')) {
|
||||
if (item==0) $('.smb.user1').show(); else $('.smb.user1').hide();
|
||||
}
|
||||
<?endif;?>
|
||||
<?if (_var($var,'shareNFSEnabled')=='yes'):?>
|
||||
if (item==2) $('.nfs.user3').show(); else $('.nfs.user3').hide();
|
||||
if (item==2) $('.nfs.share3').show(); else $('.nfs.share3').hide();
|
||||
if ($('.nfs.share3').parent().find('tr:eq(1)').is(':visible')) {
|
||||
if (item==2) $('.nfs.share3').show(); else $('.nfs.share3').hide();
|
||||
}
|
||||
if ($('.nfs.user3').parent().find('tr:eq(1)').is(':visible')) {
|
||||
if (item==2) $('.nfs.user3').show(); else $('.nfs.user3').hide();
|
||||
}
|
||||
<?endif;?>
|
||||
$('select[name="enter_user"]').val(item);
|
||||
}
|
||||
function changeView(item) {
|
||||
if (item==0) $.removeCookie('enter_view'); else $.cookie('enter_view',item,{expires:3650});
|
||||
@@ -1016,7 +1116,7 @@ function dropdown(menu) {
|
||||
var select = 'select[name="'+menu+'"]';
|
||||
var size = $(select+' option').length;
|
||||
var option = $.cookie(menu)||0;
|
||||
if (option >= size) option = size - 1;
|
||||
if (option >= size) option = 0;
|
||||
$(select+' option')[option].selected = true;
|
||||
$(select).change();
|
||||
}
|
||||
@@ -1036,8 +1136,15 @@ function toggleChart(init) {
|
||||
$('#cpu_main').removeClass('last');
|
||||
$('.cpu_open:last').removeClass('last');
|
||||
if ($.cookie('cpu-chart')==null) {
|
||||
$('#cpu_chart').show();
|
||||
$('#cpuline').show();
|
||||
var hidden = $.cookie('hidden_content');
|
||||
hidden = hidden==null ? [] : hidden.split(';');
|
||||
if (hidden.indexOf($('#cpu_main').parent().attr('sort'))==-1) {
|
||||
$('#cpu_chart').show();
|
||||
$('#cpuline').show();
|
||||
} else {
|
||||
$('#cpu_chart').hide();
|
||||
$('#cpuline').hide();
|
||||
}
|
||||
} else {
|
||||
$('#cpu_chart').hide();
|
||||
$('#cpuline').hide();
|
||||
@@ -1124,24 +1231,47 @@ function sortTables() {
|
||||
});
|
||||
}
|
||||
function addProperties() {
|
||||
$('div.frame').find('tbody.system').addClass('sortable').attr('sort','_system_information_');
|
||||
$('div.frame').find('tbody').not('.system').each(function(){
|
||||
$(this).addClass('sortable').attr('sort',$(this).attr('title').marker());
|
||||
$('div.frame tbody.system').addClass('sortable').attr('sort','_system_information_'.md5());
|
||||
$('div.frame tbody.system').find('td:first').prepend("<i class='fa fa-fw fa-eject control' onclick='openClose()' title=\"_(Show/Hide All Content)_\"></i>");
|
||||
$('div.frame tbody').each(function(){
|
||||
$(this).find('td:first').prepend("<i class='fa fa-fw fa-chevron-up control openclose' onclick='openClose($(this))' title=\"_(Show/Hide Content)_\"></i>");
|
||||
});
|
||||
$('div.frame tbody').not('.system').each(function(){
|
||||
$(this).addClass('sortable').attr('sort',$(this).attr('title').md5());
|
||||
$(this).find('td:first').prepend("<i class='fa fa-fw fa-close control tile' onclick='dismiss($(this))' title=\"_(Close Tile)_\"></i>");
|
||||
});
|
||||
$('div.frame tr').attr('title','');
|
||||
$('tr#var0').hover(function(){$.post('/webGui/include/DashboardApps.php',{sys:0},function(val){$('.sys0').text(val);})});
|
||||
<?if ($zfs):?>
|
||||
$('tr#var1').show().hover(function(){$.post('/webGui/include/DashboardApps.php',{sys:1},function(val){$('.sys1').text(val);})});
|
||||
<?endif;?>
|
||||
$('tr#var2').hover(function(){$.post('/webGui/include/DashboardApps.php',{sys:2},function(val){$('.sys2').text(val);})});
|
||||
$('tr#var3').hover(function(){$.post('/webGui/include/DashboardApps.php',{sys:3},function(val){$('.sys3').text(val);})});
|
||||
<?if ($dockerd):?>
|
||||
$('tr#var4').show().hover(function(){$.post('/webGui/include/DashboardApps.php',{sys:4},function(val){$('.sys4').text(val);})});
|
||||
<?endif;?>
|
||||
}
|
||||
function showContent() {
|
||||
var count = {'db-box1':$('table#db-box1 tbody').length, 'db-box2':$('table#db-box2 tbody').length, 'db-box3':$('table#db-box3 tbody').length}
|
||||
var inactive = $.cookie('inactive_content');
|
||||
if (inactive) {
|
||||
inactive = inactive.split(';');
|
||||
for (var n=0,x; x=inactive[n]; n++) {
|
||||
var tbody = $('table.dashboard tbody[sort="'+x+'"]');
|
||||
for (var n=0,md5; md5=inactive[n]; n++) {
|
||||
var tbody = $('table.dashboard tbody[sort="'+md5+'"]');
|
||||
var id = tbody.parent().prop('id');
|
||||
count[id]--;
|
||||
tbody.hide();
|
||||
}
|
||||
}
|
||||
var hidden = $.cookie('hidden_content');
|
||||
if (hidden) {
|
||||
hidden = hidden.split(';');
|
||||
for (var n=0,md5; md5=hidden[n]; n++) {
|
||||
var tbody = $('div.frame tbody[sort="'+md5+'"]');
|
||||
tbody.find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-down');
|
||||
tbody.find('tr:gt(0)').hide();
|
||||
}
|
||||
}
|
||||
if (count['db-box1']>0) $('div#tile1').show();
|
||||
if (count['db-box2']>0) $('div#tile2').show();
|
||||
if (count['db-box3']>0) $('div#tile3').show();
|
||||
@@ -1152,8 +1282,42 @@ function setColor(l, t1, t2) {
|
||||
case (t2 > 0 && l >= t2): return 'orangebar';
|
||||
default: return '';}
|
||||
}
|
||||
function dismiss(close) {
|
||||
var tbody = close.closest('tbody');
|
||||
function openClose(button) {
|
||||
var hidden = $.cookie('hidden_content');
|
||||
hidden = hidden==null ? [] : hidden.split(';');
|
||||
if (button) {
|
||||
// show/hide single tile content
|
||||
var tbody = button.closest('tbody');
|
||||
if (button.hasClass('fa-chevron-up')) {
|
||||
button.removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-down');
|
||||
tbody.mixedView(0);
|
||||
hidden.push(tbody.attr('sort'));
|
||||
} else {
|
||||
button.removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-up');
|
||||
tbody.mixedView(1);
|
||||
hidden.splice(hidden.indexOf(tbody.attr('sort')),1);
|
||||
}
|
||||
$.cookie('hidden_content',hidden.join(';'),{expires:3650});
|
||||
} else {
|
||||
// show/hide all tiles content
|
||||
if (hidden.length==0) {
|
||||
$('div.frame tbody').each(function(){
|
||||
$(this).find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-down');
|
||||
$(this).mixedView(0);
|
||||
hidden.push($(this).attr('sort'));
|
||||
});
|
||||
$.cookie('hidden_content',hidden.join(';'),{expires:3650});
|
||||
} else {
|
||||
$('div.frame tbody').each(function(){
|
||||
$(this).find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-up');
|
||||
$(this).mixedView(1);
|
||||
});
|
||||
$.removeCookie('hidden_content');
|
||||
}
|
||||
}
|
||||
}
|
||||
function dismiss(button) {
|
||||
var tbody = button.closest('tbody');
|
||||
var table = tbody.parent();
|
||||
var tile = table.parent();
|
||||
var inactive = $.cookie('inactive_content');
|
||||
@@ -1167,7 +1331,7 @@ function contentMgmt() {
|
||||
box = $("#iframe-popup");
|
||||
box.html($("#templateContentMgmt").html().build());
|
||||
box.dialog({
|
||||
title: "_(Content Management)_",
|
||||
title: "_(Tile Management)_",
|
||||
height: 350,
|
||||
width: 900,
|
||||
resizable: false,
|
||||
@@ -1180,8 +1344,9 @@ function contentMgmt() {
|
||||
$.removeCookie('db-box2');
|
||||
$.removeCookie('db-box3');
|
||||
$.removeCookie('inactive_content');
|
||||
$.removeCookie('hidden_content');
|
||||
box.dialog('close');
|
||||
refresh();
|
||||
location.reload();
|
||||
},
|
||||
"_(All)_": function(){
|
||||
$('input.checker').each(function(){$(this).prop('checked',true);});
|
||||
@@ -1267,7 +1432,7 @@ dashboard.on('message',function(msg,meta) {
|
||||
// memory & disk load
|
||||
$.each(part[0].split('\0'),function(k,v) {
|
||||
var load = v.slice(0,-1);
|
||||
var color = setColor(load,<?=_var($display,'critical',0)?>,<?=_var($display,'warning',0)?>);
|
||||
var color = k==1 ? '' : setColor(load,<?=_var($display,'critical',0)?>,<?=_var($display,'warning',0)?>);
|
||||
$('.sys'+k).text(v);
|
||||
$('#sys'+k).finish().animate({width:v},{step:function(){$('#sys'+k).css('overflow','visible').removeClass().addClass(color);}});
|
||||
});
|
||||
@@ -1288,7 +1453,7 @@ dashboard.on('message',function(msg,meta) {
|
||||
var info = moreInfo(data,"_(Array)_");
|
||||
// array devices
|
||||
$('#array_list tr.updated').remove();
|
||||
$('#array_list').append(data[0]);
|
||||
$('#array_list').append(data[0]).hideMe();
|
||||
$('#array_info').parent().css('display',info?'':'none');
|
||||
$('#array_info').html(info);
|
||||
smartMenu('#array_list');
|
||||
@@ -1298,7 +1463,7 @@ dashboard.on('message',function(msg,meta) {
|
||||
var data = t.split('\0');
|
||||
var info = moreInfo(data,"_(Pool)_");
|
||||
$('#pool_list'+i+' tr.updated').remove();
|
||||
$('#pool_list'+i).append(t);
|
||||
$('#pool_list'+i).append(t).hideMe();
|
||||
$('#pool_info'+i).parent().css('display',info?'':'none');
|
||||
$('#pool_info'+i).html(info);
|
||||
smartMenu('#pool_list'+i);
|
||||
@@ -1308,13 +1473,13 @@ dashboard.on('message',function(msg,meta) {
|
||||
var data = part[2].split('\0');
|
||||
var info = moreInfo(data,"_(Unassigned)_");
|
||||
$('#devs_list tr.updated').remove();
|
||||
$('#devs_list').append(data[0]);
|
||||
$('#devs_list').append(data[0]).hideMe();
|
||||
$('#devs_info').parent().css('display',info?'':'none');
|
||||
$('#devs_info').html(info);
|
||||
smartMenu('#devs_list');
|
||||
<?endif;?>
|
||||
// parity status
|
||||
$('span.info.title').html(part[3]);
|
||||
$('span.parity').html(part[3]);
|
||||
// parity schedule
|
||||
var data = part[4].split('\0');
|
||||
$('#parity').html(data[0]);
|
||||
@@ -1383,13 +1548,11 @@ $(function() {
|
||||
cpuchart.render();
|
||||
netchart.render();
|
||||
addProperties();
|
||||
<?if ($zfs):?>
|
||||
$('tr#zfs').show();
|
||||
<?endif;?>
|
||||
<?if ($group):?>
|
||||
dropdown('enter_share');
|
||||
<?endif;?>
|
||||
dropdown('enter_view');
|
||||
startup = false;
|
||||
dashboard.start();
|
||||
<?if ($apcupsd):?>
|
||||
apcups.start();
|
||||
|
||||
@@ -31,6 +31,7 @@ function sanitize(&$val) {
|
||||
$data = explode('.',str_replace([' ',','],['','.'],$val));
|
||||
$last = array_pop($data);
|
||||
$val = count($data) ? implode($data).".$last" : $last;
|
||||
$val = preg_replace('/[^0-9.]/','',$val);
|
||||
}
|
||||
function presetSpace($val) {
|
||||
global $disk,$display;
|
||||
@@ -38,13 +39,10 @@ function presetSpace($val) {
|
||||
sanitize($val);
|
||||
$size = _var($disk,'fsSize',0);
|
||||
$size = $size>0 ? round(100*$val/$size,1) : 0;
|
||||
$unit = '%';
|
||||
if ($size < 1) {
|
||||
$units = ['KB','MB','GB','TB','PB','EB','ZB','YB'];
|
||||
$base = $val>0 ? floor(log($val,1000)) : 0;
|
||||
$size = round($val/pow(1000,$base),1);
|
||||
$unit = _var($units,$base);
|
||||
}
|
||||
$units = ['KB','MB','GB','TB','PB','EB','ZB','YB'];
|
||||
$base = $val>0 ? floor(log($val,1000)) : 0;
|
||||
$size = round($val/pow(1000,$base),1);
|
||||
$unit = _var($units,$base);
|
||||
[$dot,$comma] = str_split(_var($display,'number','.,'));
|
||||
return $size>0 ? number_format($size,$size-floor($size)?1:0,$dot,$comma).' '.$unit : '';
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ function selectProtocol(form,port,index) {
|
||||
}
|
||||
if ($(form).find('select[name="USE_DHCP:'+i+'"]').val()) more4.show(); else more4.hide();
|
||||
if ($(form).find('select[name="USE_DHCP6:'+i+'"]').val()) more6.show(); else more6.hide();
|
||||
checkNetworkSettings(form,i,true);
|
||||
checkNetworkSettings(form,i);
|
||||
});
|
||||
} else {
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+index+'"]').val() || 'ipv4';
|
||||
@@ -241,16 +241,12 @@ function selectProtocol(form,port,index) {
|
||||
if ($(form).find('select[name="USE_DHCP:'+index+'"]').val()) more4.show(); else more4.hide();
|
||||
if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()) more6.show(); else more6.hide();
|
||||
checkNetworkSettings(form,index);
|
||||
if (index==0) {
|
||||
checkDNSSettings(form);
|
||||
checkDNSSettings6(form);
|
||||
}
|
||||
}
|
||||
}
|
||||
function checkNetworkSettings(form,index,start) {
|
||||
function checkNetworkSettings(form,index) {
|
||||
var disabled4 = $(form).find('select[name="USE_DHCP:'+index+'"]').val()!='no';
|
||||
var disabled6 = $(form).find('select[name="USE_DHCP6:'+index+'"]').val()!='no';
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+index+'"]').val() || 'ipv4';
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+index+'"]').val() || 'ipv4';
|
||||
if (protocol != 'ipv6') {
|
||||
$(form).find('input[name="IPADDR:'+index+'"]').prop('disabled',disabled4).prop('required',!disabled4);
|
||||
$(form).find('select[name="NETMASK:'+index+'"]').prop('disabled',disabled4);
|
||||
@@ -264,19 +260,17 @@ function checkNetworkSettings(form,index,start) {
|
||||
privacy.prop('disabled',!disabled6);
|
||||
}
|
||||
if (index==0) {
|
||||
if (form.DHCP_KEEPRESOLV !== undefined) {
|
||||
if (!start) form.DHCP_KEEPRESOLV.value = disabled4 ? 'no' : 'yes';
|
||||
form.DHCP_KEEPRESOLV.disabled = !disabled4;
|
||||
checkDNSSettings(form);
|
||||
}
|
||||
if (form.DHCP6_KEEPRESOLV !== undefined) {
|
||||
if (!start) form.DHCP6_KEEPRESOLV.value = disabled6 ? 'no' : 'yes';
|
||||
form.DHCP6_KEEPRESOLV.disabled = !disabled6;
|
||||
checkDNSSettings6(form);
|
||||
}
|
||||
if (form.DHCP_KEEPRESOLV !== undefined) checkDNSSettings(form);
|
||||
if (form.DHCP6_KEEPRESOLV !== undefined) checkDNSSettings6(form);
|
||||
}
|
||||
}
|
||||
function checkDNSSettings(form) {
|
||||
if ($(form).find('select[name="USE_DHCP:0"]').val()=='no') {
|
||||
form.DHCP_KEEPRESOLV.value = 'yes';
|
||||
form.DHCP_KEEPRESOLV.disabled = true;
|
||||
} else {
|
||||
form.DHCP_KEEPRESOLV.disabled = false;
|
||||
}
|
||||
var disabled = form.DHCP_KEEPRESOLV.value=='no';
|
||||
var protocol = $(form).find('select[name="PROTOCOL:0"]').val() || 'ipv4';
|
||||
if (protocol != 'ipv6') {
|
||||
@@ -289,6 +283,12 @@ function checkDNSSettings(form) {
|
||||
}
|
||||
}
|
||||
function checkDNSSettings6(form) {
|
||||
if ($(form).find('select[name="USE_DHCP6:0"]').val()=='no') {
|
||||
form.DHCP6_KEEPRESOLV.value = 'yes';
|
||||
form.DHCP6_KEEPRESOLV.disabled = true;
|
||||
} else {
|
||||
form.DHCP6_KEEPRESOLV.disabled = false;
|
||||
}
|
||||
var disabled = form.DHCP6_KEEPRESOLV.value=='no';
|
||||
var protocol = $(form).find('select[name="PROTOCOL:0"]').val() || 'ipv4';
|
||||
if (protocol != 'ipv4') {
|
||||
|
||||
@@ -54,7 +54,7 @@ function acceptableCert($certFile, $hostname, $expectedURL) {
|
||||
$tasks = find_tasks();
|
||||
$nginx = @parse_ini_file('/var/local/emhttp/nginx.ini') ?: [];
|
||||
$addr = _var($nginx,'NGINX_LANIP') ?: _var($nginx,'NGINX_LANIP6');
|
||||
$keyfile = @file_get_contents(_var($var,'regFILE'));
|
||||
$keyfile = empty(_var($var,'regFILE')) ? false : @file_get_contents(_var($var,'regFILE'));
|
||||
$cert2Issuer = '';
|
||||
$isLEcert = false;
|
||||
if ($keyfile !== false) $keyfile = base64_encode($keyfile);
|
||||
|
||||
@@ -96,7 +96,7 @@ $(function(){
|
||||
<input type="hidden" name="exclude_interfaces" value="">
|
||||
|
||||
_(Current listening interfaces)_:
|
||||
: <?=exec("$docroot/webGui/scripts/show_interfaces")?:_('Any')?>
|
||||
: <?=exec("$docroot/webGui/scripts/show_interfaces")?:_('Any')?><span class="red-text" style="margin-left:30px"><?=exec("$docroot/webGui/scripts/error_interfaces")?></span>
|
||||
<hr>
|
||||
|
||||
_(Include listening interfaces)_:
|
||||
|
||||
@@ -76,7 +76,7 @@ _(Security)_:
|
||||
<form markdown="1" method="POST" name="otherForm" action="/update.htm" target="progressFrame">
|
||||
<input type="hidden" name="shareName" value="<?=htmlspecialchars($name)?>">
|
||||
_(Rule)_:
|
||||
: <input type="text" name="shareHostListNFS" maxlength="256" value="<?=htmlspecialchars($sec_nfs[$name]['hostList'])?>">
|
||||
: <input type="text" name="shareHostListNFS" maxlength="512" value="<?=htmlspecialchars($sec_nfs[$name]['hostList'])?>">
|
||||
|
||||
|
||||
: <input type="submit" name="changeShareAccessNFS" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
@@ -62,13 +62,10 @@ function presetSpace($val) {
|
||||
$pool = _var($shares[$name],'cachePool');
|
||||
$size = _var($fsSize,$pool,0);
|
||||
$size = $size>0 ? round(100*$val/$size,1) : 0;
|
||||
$unit = '%';
|
||||
if ($size < 1) {
|
||||
$units = ['KB','MB','GB','TB','PB','EB','ZB','YB'];
|
||||
$base = $val>0 ? floor(log($val,1000)) : 0;
|
||||
$size = round($val/pow(1000,$base),1);
|
||||
$unit = _var($units,$base);
|
||||
}
|
||||
$units = ['KB','MB','GB','TB','PB','EB','ZB','YB'];
|
||||
$base = $val>0 ? floor(log($val,1000)) : 0;
|
||||
$size = round($val/pow(1000,$base),1);
|
||||
$unit = _var($units,$base);
|
||||
[$dot,$comma] = str_split(_var($display,'number','.,'));
|
||||
return $size>0 ? number_format($size,$size-floor($size)?1:0,$dot,$comma).' '.$unit : '';
|
||||
}
|
||||
@@ -148,9 +145,6 @@ foreach ($rows as $row) echo $row;
|
||||
<input type="hidden" name="shareSplitLevel" value="">
|
||||
<input type="hidden" name="shareInclude" value="">
|
||||
<input type="hidden" name="shareExclude" value="">
|
||||
<?if (_var($share,'exclusive')!="no"):?>
|
||||
<input type="hidden" name="shareFloor" value="">
|
||||
<?endif;?>
|
||||
|
||||
<div markdown="1" class="shade-<?=$display['theme']?>">
|
||||
_(Share name)_:
|
||||
@@ -163,7 +157,6 @@ _(Comments)_:
|
||||
|
||||
:share_edit_comments_help:
|
||||
|
||||
<?if (_var($share,'exclusive')=="no"):?>
|
||||
<div markdown="1">
|
||||
_(Minimum free space)_:
|
||||
: <span class="input"><input type="text" name="shareFloor" maxlength="16" autocomplete="off" spellcheck="false" class="narrow" value="<?=presetSpace($share['floor'])?>" placeholder="0"></span><span id="autosize"><i class="fa fa-info i"></i>_(Calculated free space value)_</span>
|
||||
@@ -171,7 +164,6 @@ _(Minimum free space)_:
|
||||
:share_edit_free_space_help:
|
||||
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?if ($name):?>
|
||||
<div markdown="1" class="empty">
|
||||
_(Share status)_:
|
||||
|
||||
182
emhttp/plugins/dynamix/SysDrivers.page
Normal file
182
emhttp/plugins/dynamix/SysDrivers.page
Normal file
@@ -0,0 +1,182 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="System Drivers"
|
||||
Icon="fa-sitemap"
|
||||
Tag="server"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
global $var ;
|
||||
$theme = $display['theme'] ;
|
||||
?>
|
||||
|
||||
<style>
|
||||
table.t1{margin-top:0; border-collapse: collapse; border-spacing: 0;}
|
||||
table tr td{padding:0 0 3px 0;margin:0}
|
||||
table tr td.thin{line-height:8px;height:8px}
|
||||
table.t1 tr>td{width: 1%; ; text-align:centre ;white-space: nowrap;}
|
||||
table.t1 tr>td+td{width: 1%; white-space: nowrap; }
|
||||
table.t1 tr>td+td+td{width:auto ; text-align:left;}
|
||||
table.t1 tr>td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td+td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td+td+td+td+td+td+td{text-align:left;}
|
||||
table.t1 tr>td+td+td+td+td+td+td+td+td+td+td+td+td{text-align:left;}
|
||||
.tablesorter .filtered {
|
||||
display: none;
|
||||
}
|
||||
<?if ($theme == "black"):?>
|
||||
table.tablesorter tbody tr.alt-row {background-color:#212121;}
|
||||
table.tablesorter tbody tr.normal-row {background-color:#1c1b1b;}
|
||||
input.search {color:#f2f2f2;background-color:#1c1b1b;}
|
||||
<?endif;?>
|
||||
<?if ($theme == "white"):?>
|
||||
table.tablesorter tbody tr.alt-row {background-color:#ededed;}
|
||||
table.tablesorter tbody tr.normal-row {background-color:#f2f2f2;}
|
||||
input.search {color:#1c1b1b;background-color:#f2f2f2;}
|
||||
<?endif;?>
|
||||
<?if ($theme == "gray"):?>
|
||||
table.tablesorter tbody tr.alt-row {solid #0c0f0b;}
|
||||
table.tablesorter tbody tr.normal-row {background-color:#1b1d1b;}
|
||||
input.search {color:#606e7f;background-color:#1b1d1b;}
|
||||
table.tablesorter thead th {color:#606e7f;background-color:#1b1d1b;}
|
||||
div.tablesorter-header-inner {color:#606e7f;background-color:#1b1d1b;}
|
||||
<?endif;?>
|
||||
<?if ($theme == "azure"):?>
|
||||
table.tablesorter tbody tr.alt-row {background-color:#e4e2e4; }
|
||||
table.tablesorter tbody tr.normal-row {solid #f3f0f4;}
|
||||
input.search {color:#606e7f;background-color:#e4e2e4;}
|
||||
table.tablesorter thead th {color:#606e7f;background-color:#e4e2e4;}
|
||||
div.tablesorter-header-inner {color:#606e7f;background-color:#e4e2e4;}
|
||||
<?endif;?>
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="/webGui/javascript/jquery.tablesorter.widgets.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function showDrivers(options, init = false) {
|
||||
option = options ;
|
||||
if (init) {
|
||||
$('#driversearch').prop('disabled', true);
|
||||
$('#select').prop('disabled', true);
|
||||
$('#rebuild').prop('disabled', true);
|
||||
|
||||
$.post('/webGui/include/SysDrivers.php',{table:'t1load',option:"all"},function(data){
|
||||
clearTimeout(timers.refresh);
|
||||
$("#t1").trigger("destroy");
|
||||
$('#t1').html(data.html);
|
||||
$('#t1').tablesorter({
|
||||
sortList:[[0,0]],
|
||||
sortAppend:[[0,0]],
|
||||
widgets: ['stickyHeaders','filter', 'zebra'],
|
||||
widgetOptions: {
|
||||
// on black and white, offset is height of #menu
|
||||
// on azure and gray, offset is height of #header
|
||||
stickyHeaders_offset: ( $('#menu').height() < 50 ) ? $('#menu').height() : $('#header').height(),
|
||||
filter_columnFilters: false,
|
||||
zebra : [ "normal-row", "alt-row" ]
|
||||
}
|
||||
|
||||
});
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
$('#driversearch').prop('disabled', false);
|
||||
$('#select').prop('disabled', false);
|
||||
$('#rebuild').prop('disabled', data.init);
|
||||
|
||||
},"json");
|
||||
} else {
|
||||
|
||||
filter = [];
|
||||
filterDrivers() ;
|
||||
}
|
||||
}
|
||||
|
||||
function filterDrivers() {
|
||||
var totalColumns = $('#t1')[0].config.columns;
|
||||
var filter = [];
|
||||
filter[2] = ($('#select').val() === "inuse") ? "System|Inuse|Custom|Disabled|'Kernel - Inuse'" : "";
|
||||
filter[totalColumns] = $('#driversearch').val(); // this searches all columns
|
||||
$('#t1').trigger('search', [ filter ]);
|
||||
}
|
||||
|
||||
function showDriversupdate() {
|
||||
$('#rebuild').prop('disabled', true);
|
||||
$('#t1').html("");
|
||||
$('#driversearch').prop('disabled', true);
|
||||
$('#select').prop('disabled', true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
$.post('/webGui/include/SysDrivers.php',{table:'t1create',option:"all"},function(data){
|
||||
$('#rebuild').prop('disabled', false);
|
||||
showDrivers("all",true) ;
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
}) ;
|
||||
}
|
||||
|
||||
function textedit(module) {
|
||||
var i=module ;
|
||||
$('#text'+module).prop('disabled', false);
|
||||
$('#save'+module).attr('hidden', false);
|
||||
$('#text'+module).attr('hidden', false);
|
||||
|
||||
}
|
||||
|
||||
function removecfg(module)
|
||||
{
|
||||
swal({title:"_(Proceed)_?",text:"_(Remove custom modprobe.d configuration?)_: "+module,type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(p){if (p) textsave(module, true); else return false;});
|
||||
}
|
||||
|
||||
function textsave(module,remove = false) {
|
||||
var i=module ;
|
||||
$('#text'+module).prop('disabled', true);
|
||||
$('#save'+module).attr('hidden', true);
|
||||
if (remove) x = "" ; else var x = document.getElementById("text" + module).value;
|
||||
$.post('/webGui/include/SysDrivers.php',{table:'update',module:module,conf:x},function(data){
|
||||
if(data) {
|
||||
formHasUnsavedChanges=false;
|
||||
$('#text'+module).val(data.modprobe) ;
|
||||
$('#status'+module).html(data.state) ;
|
||||
if (data.state == "Custom") {
|
||||
$('#bin'+module).show();
|
||||
} else {
|
||||
$('#bin'+module).hide();
|
||||
}
|
||||
if (data.modprobe == "") $('#text'+module).attr('hidden', true); else $('#text'+module).attr('rows', 3);
|
||||
if (data.supportpage == true) {
|
||||
if (data.support == true) {
|
||||
document.getElementById("link" + module).innerHTML = "<a href='" + data.supporturl + "'target='_blank'><i title='" + _("Support page")_ + "' class='fa fa-phone-square'></i></a>" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
$('#t1').trigger("updateCell",[document.getElementById('text'+module), false, null]);
|
||||
$('#t1').trigger("updateCell",[document.getElementById('status'+module), false, null]);
|
||||
var message = "_(System Drivers)_: _(A reboot is required to apply changes)_";
|
||||
addRebootNotice(message);
|
||||
},"json");
|
||||
}
|
||||
|
||||
$('.tabs').append("<span class='status'><span class='lite label'>_(Select View)_:</span><select id='select' onchange='showDrivers(this.value)'><option value='all' >All Drivers</option><option value='inuse' selected >Inuse Drivers</option></select>");
|
||||
showDrivers("all",true) ;
|
||||
|
||||
</script>
|
||||
|
||||
:sysdrivers_intro_help:
|
||||
|
||||
<form autocomplete="off" onsubmit="return false;"><span><input class="search" id="driversearch" type="search" placeholder="Search..." onchange="filterDrivers();"></span></form>
|
||||
<pre><form id="sysdrivers" class="js-confirm-leave" onsubmit="return false"><table id='t1' class="t1 disk_status tablesorter " ><tr><td><div class="spinner"></div></td></tr></table></form></pre><br>
|
||||
<input type="button" value="_(Done)_" onclick="done()"><input type="button" id="rebuild" value="_(Rebuild Modules)_" onclick="showDriversupdate()">
|
||||
|
||||
@@ -20,10 +20,10 @@ $etc = '/etc/wireguard';
|
||||
$tmp = '/tmp/list.tmp';
|
||||
|
||||
unset($subnets,$hosts,$subnets6,$hosts6,$vtuns,$filter,$docker);
|
||||
exec("ip -4 route show scope link|awk '/^[^d].+ dev (eth|br|bond)[0-9]+/{print \$1}'",$subnets);
|
||||
exec("ip -4 addr show scope global|awk '/inet .+ (eth|br|bond)[0-9]+/{split(\$2,ip,\"/\");print ip[1]}'",$hosts);
|
||||
exec("ip -6 route show type unicast|grep -Pv 'expires|shim-'|awk '/^[^dfm:]/{print \$1}'",$subnets6);
|
||||
exec("ip -6 addr show scope global|grep -PA2 ': (eth|br|bond)\d+'|awk '/inet6 .+ (global|noprefixroute) \$/{split(\$2,ip,\"/\");print ip[1]}'",$hosts6);
|
||||
exec("ip -4 route show scope link|awk '/^[^d].+ dev (eth|br|bond)[0-9]+(\\.[0-9]+)?/{print \$1}'",$subnets);
|
||||
exec("ip -6 route show type unicast|awk '\$0 !~ \"expires\" && \$3 !~ \"^shim-\" && /^[^dfm:]/{print \$1}'",$subnets6);
|
||||
exec("ip -br -4 addr show scope global|awk '/^(br|bond|eth)[0-9]+(\\.[0-9]+)?/{split(\$3,ip,\"/\");print ip[1]}'",$hosts);
|
||||
exec("ip -br -6 addr show scope global|awk '/^(br|bond|eth)[0-9]+(\\.[0-9]+)?/{split(\$3,ip,\"/\");print ip[1]}'",$hosts6);
|
||||
exec("ls --indicator-style=none $etc/wg*.conf*|grep -Po wg[0-9]+",$vtuns);
|
||||
exec("docker network ls --filter driver='macvlan' --filter driver='ipvlan' --format='{{.Name}}' 2>/dev/null",$filter);
|
||||
|
||||
@@ -130,7 +130,7 @@ $active = explode(' ',exec('wg show interfaces'));
|
||||
$autostart = explode(' ',@file_get_contents("$etc/autostart")?:'');
|
||||
$build = false;
|
||||
$script = "$docroot/webGui/scripts/upnp_port";
|
||||
$services = "$docroot/webGui/scripts/reload_services";
|
||||
$services = "$docroot/webGui/scripts/update_services";
|
||||
$template = "$docroot/webGui/WGX.page";
|
||||
$tower = _var($var,'NAME');
|
||||
$ethX = 'eth0';
|
||||
@@ -160,7 +160,7 @@ $validDNS = "([0-9a-z]([0-9a-z\-]{0,61}[0-9a-z])?\.)+($tld)";
|
||||
$validIP4 = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}";
|
||||
$validIP6 = "(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(:|([0-9a-fA-F]{1,4}:)+):(([0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4})?)";
|
||||
$maskIP4 = "([0-9]|[12][0-9]|3[0-2])?";
|
||||
$maskIP6 = "([0-9]|[1-9][[0-9]|1[01][0-9]|12[0-8])?";
|
||||
$maskIP6 = "([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8])?";
|
||||
|
||||
$validText = "^($validDNS|$validIP4|$validIP6)$";
|
||||
$validList = "^(($validIP4/?$maskIP4|$validIP6/?$maskIP6)(, *)?)+$";
|
||||
|
||||
3
emhttp/plugins/dynamix/event/driver_loaded/SysDriversBuild
Executable file
3
emhttp/plugins/dynamix/event/driver_loaded/SysDriversBuild
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
/usr/bin/logger "Submitting SysDrivers Build"
|
||||
/usr/local/emhttp/plugins/dynamix/include/SysDriversInit.php &> /dev/null &
|
||||
@@ -39,8 +39,8 @@ function create($id, $name, $vcpu) {
|
||||
for ($n = 0; $n < $max; $n++) {
|
||||
unset($cpu1,$cpu2);
|
||||
[$cpu1, $cpu2] = my_preg_split('/[,-]/',$cpus[$c*32+$n]);
|
||||
$check1 = in_array($cpu1, $vcpu) ? 'checked':'';
|
||||
$check2 = $cpu2 ? (in_array($cpu2, $vcpu) ? 'checked':''):'';
|
||||
$check1 = ($vcpu && in_array($cpu1, $vcpu)) ? 'checked':'';
|
||||
$check2 = $cpu2 ? ($vcpu && (in_array($cpu2, $vcpu)) ? 'checked':''):'';
|
||||
if (empty($text[$n])) $text[$n] = '';
|
||||
$text[$n] .="<label class='checkbox'><input type='checkbox' name='$name:$cpu1' $check1><span class='checkmark'></span></label><br>";
|
||||
if ($cpu2) $text[$n] .= "<label class='checkbox'><input type='checkbox' name='$name:$cpu2' $check2><span class='checkmark'></span></label><br>";
|
||||
|
||||
@@ -20,6 +20,19 @@ require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
|
||||
if (isset($_POST['sys'])) {
|
||||
switch ($_POST['sys']) {
|
||||
case 0: $size = exec("awk '/^MemTotal/{t=$2}/^MemAvailable/{a=$2}END{print (t-a)*1024}' /proc/meminfo 2>/dev/null"); break;
|
||||
case 1: $size = exec("awk '/^size/{print \$3;exit}' /proc/spl/kstat/zfs/arcstats 2>/dev/null"); break;
|
||||
case 2: $size = exec("df --output=used /boot 2>/dev/null|awk '$1!=\"Used\" {print $1*1024}'"); break;
|
||||
case 3: $size = exec("df --output=used /var/log 2>/dev/null|awk '$1!=\"Used\" {print $1*1024}'"); break;
|
||||
case 4: $size = exec("df --output=used /var/lib/docker 2>/dev/null|awk '$1!=\"Used\" {print $1*1024}'"); break;
|
||||
default: $size = 0;
|
||||
}
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
die(my_scale($size,$unit,null,-1,1024)." $unit");
|
||||
}
|
||||
|
||||
$display = $_POST['display'];
|
||||
|
||||
if ($_POST['docker'] && ($display=='icons' || $display=='docker')) {
|
||||
@@ -33,7 +46,7 @@ if ($_POST['docker'] && ($display=='icons' || $display=='docker')) {
|
||||
foreach ($containers as $ct) $sort[] = array_search($ct['Name'],$prefs) ?? 999;
|
||||
array_multisort($sort,SORT_NUMERIC,$containers);
|
||||
}
|
||||
echo "<tr class='updated'><td>";
|
||||
echo "<tr title='' class='updated'><td>";
|
||||
foreach ($containers as $ct) {
|
||||
$name = $ct['Name'];
|
||||
$id = $ct['Id'];
|
||||
@@ -74,7 +87,7 @@ if ($_POST['vms'] && ($display=='icons' || $display=='vms')) {
|
||||
} else {
|
||||
natcasesort($vms);
|
||||
}
|
||||
echo "<tr class='updated'><td>";
|
||||
echo "<tr title='' class='updated'><td>";
|
||||
foreach ($vms as $vm) {
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
$uuid = libvirt_domain_get_uuid_string($res);
|
||||
|
||||
@@ -26,7 +26,7 @@ function my_scale($value, &$unit, $decimals=NULL, $scale=NULL, $kilo=1000) {
|
||||
$decimals = 0;
|
||||
$unit = '';
|
||||
} else {
|
||||
$base = $value ? floor(log($value, $kilo)) : 0;
|
||||
$base = $value ? intval(floor(log($value, $kilo))) : 0;
|
||||
if ($scale>0 && $base>$scale) $base = $scale;
|
||||
if ($base>$size) $base = $size-1;
|
||||
$value /= pow($kilo, $base);
|
||||
@@ -117,8 +117,8 @@ function my_usage() {
|
||||
function usage_color(&$disk, $limit, $free) {
|
||||
global $display;
|
||||
if (_var($display,'text',0)==1 || intval(_var($display,'text',0)/10)==1) return '';
|
||||
$critical = _var($disk,'critical') ? $disk['critical'] : (_var($display,'critical') ? $display['critical'] : 0);
|
||||
$warning = _var($disk,'warning') ? $disk['warning'] : (_var($display,'warning') ? $display['warning'] : 0);
|
||||
$critical = _var($disk,'critical')>=0 ? $disk['critical'] : (_var($display,'critical')>=0 ? $display['critical'] : 0);
|
||||
$warning = _var($disk,'warning')>=0 ? $disk['warning'] : (_var($display,'warning')>=0 ? $display['warning'] : 0);
|
||||
if (!$free) {
|
||||
if ($critical>0 && $limit>=$critical) return 'redbar';
|
||||
if ($warning>0 && $limit>=$warning) return 'orangebar';
|
||||
|
||||
@@ -61,7 +61,7 @@ if ($certPresent) {
|
||||
}
|
||||
$endpoint = ($certPresent && $isLegacyCert) ? "provisioncert" : "provisionwildcard";
|
||||
|
||||
$keyfile = @file_get_contents($var['regFILE']);
|
||||
$keyfile = empty($var['regFILE']) ? false : @file_get_contents($var['regFILE']);
|
||||
if ($keyfile === false) {
|
||||
response_complete(406, '{"error":"'._('License key required').'"}');
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ default:
|
||||
$route = $cell[0];
|
||||
$gateway = $cell[2];
|
||||
if ($route=='default') $gateway .= " via {$cell[4]}";
|
||||
$metric = '1';
|
||||
$metric = '0';
|
||||
for ($i=5; $i<count($cell); $i++) if ($cell[$i]=='metric') {$metric = $cell[$i+1]; break;}
|
||||
echo "<tr><td>IPv4</td><td>$route</td><td>$gateway</td><td>$metric</td><td style='text-align:center'><a href='#' onclick='deleteRoute(\"$gateway\",\"$route\",\"$metric\");return false'><i class='fa fa-trash-o'></i></a></td></tr>";
|
||||
}
|
||||
|
||||
119
emhttp/plugins/dynamix/include/SysDrivers.php
Normal file
119
emhttp/plugins/dynamix/include/SysDrivers.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'tools';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/SysDriversHelpers.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
$kernel = shell_exec("uname -r") ;
|
||||
$kernel = trim($kernel,"\n") ;
|
||||
$lsmod = shell_exec("lsmod") ;
|
||||
$supportpage = true;
|
||||
$modtoplgfile = "/tmp/modulestoplg.json" ;
|
||||
$sysdrvfile = "/tmp/sysdrivers.json" ;
|
||||
$sysdrvinit = "/tmp/sysdrivers.init" ;
|
||||
if (!is_file($modtoplgfile) || !is_file($sysdrvfile)) { modtoplg() ; createlist() ;}
|
||||
$arrModtoPlg = json_decode(file_get_contents("/tmp/modulestoplg.json") ,TRUE) ;
|
||||
|
||||
switch ($_POST['table']) {
|
||||
|
||||
case 't1create':
|
||||
if (is_file("/tmp/sysdrvbuild.running")) break ;
|
||||
touch("/tmp/sysdrvbuild.running") ;
|
||||
modtoplg() ;
|
||||
createlist() ;
|
||||
unlink("/tmp/sysdrvbuild.running") ;
|
||||
break;
|
||||
|
||||
case 't1load':
|
||||
$list = file_get_contents($sysdrvfile) ;
|
||||
$arrModules = json_decode($list,TRUE) ;
|
||||
$init = file_get_contents($sysdrvinit) ;
|
||||
$html = "<thead><tr><th><b>"._("Driver")."</th><th><b>"._("Description")."</th><th data-value='System|Inuse|Custom|Disabled|\"Kernel - Inuse\"'><b>"._("State")."</th><th><b>"._("Type")."</th><th><b>"._("Modprobe.d config file")."</th></tr></thead>";
|
||||
$html .= "<tbody>" ;
|
||||
|
||||
if (is_array($arrModules)) ksort($arrModules) ;
|
||||
foreach($arrModules as $modname => $module) {
|
||||
if ($modname == "") continue ;
|
||||
|
||||
if (is_file("/boot/config/modprobe.d/$modname.conf")) {
|
||||
$modprobe = file_get_contents("/boot/config/modprobe.d/$modname.conf") ;
|
||||
$state = strpos($modprobe, "blacklist");
|
||||
$modprobe = explode(PHP_EOL,$modprobe) ;
|
||||
if($state !== false) {$state = "Disabled" ;} else $state="Custom" ;
|
||||
$module['state'] = $state ;
|
||||
$module['modprobe'] = $modprobe ;
|
||||
} else {
|
||||
if (is_file("/etc/modprobe.d/$modname.conf")) {
|
||||
$modprobe = file_get_contents("/etc/modprobe.d/$modname.conf") ;
|
||||
$state = strpos($modprobe, "blacklist");
|
||||
$modprobe = explode(PHP_EOL,$modprobe) ;
|
||||
if($state !== false) {$state = "Disabled" ;} else $state="System" ;
|
||||
$module['state'] = $state ;
|
||||
$module['modprobe'] = $modprobe ;
|
||||
}
|
||||
}
|
||||
|
||||
$html .= "<tr id='row$modname'>" ;
|
||||
if ($supportpage) {
|
||||
if ($module['support'] == false) {
|
||||
$supporthtml = "" ;
|
||||
} else {
|
||||
$supporturl = $module['supporturl'] ;
|
||||
$pluginname = $module['plugin'] ;
|
||||
$supporthtml = "<span id='link$modname'><a href='$supporturl' target='_blank'><i title='"._("Support page $pluginname")."' class='fa fa-phone-square'></i></a></span>" ;
|
||||
}
|
||||
}
|
||||
$html .= "<td>$modname$supporthtml</td>" ;
|
||||
$html .= "<td>{$module['description']}</td><td id=\"status$modname\">{$module['state']}</td><td>{$module['type']}</td>";
|
||||
|
||||
$text = "" ;
|
||||
if (is_array($module["modprobe"])) {
|
||||
$text = implode("\n",$module["modprobe"]) ;
|
||||
$html .= "<td><span><a class='info' href=\"#\"><i title='"._("Edit Modprobe config")."' onclick=\"textedit('".$modname."');return false;\" id=\"icon'.$modname.'\" class='fa fa-edit'></i></a>" ;
|
||||
$hidden = "" ;
|
||||
if ($module['state'] == "System") $hidden = "hidden" ;
|
||||
$html .= " <a class='info' href=\"#\" id=\"bin$modname\" $hidden><i title='"._("Delete Modprobe config")."' onclick=\"removecfg('".$modname."',true);return false;\" class='fa fa-trash'></i></a><span>" ;
|
||||
$html .= "<span><textarea id=\"text".$modname."\" rows=3 disabled>$text</textarea><span id=\"save$modname\" hidden onclick=\"textsave('".$modname."');return false;\" ><a class='info' href=\"#\"><i title='"._("Save Modprobe config")."' class='fa fa-save' ></i></a></span></td></tr>";
|
||||
} else {
|
||||
$html .= "<td><span><a class='info' href=\"#\"><i title='"._("Edit Modprobe config")."' onclick=\"textedit('".$modname."');return false;\" id=\"icon'.$modname.'\" class='fa fa-edit'></i></a>" ;
|
||||
$html .= " <a class='info' href=\"#\" id=\"bin$modname\" hidden><i title='"._("Delete Modprobe config")."' onclick=\"removecfg('".$modname."',true);return false;\" class='fa fa-trash'></i></a><span>" ;
|
||||
$html .= "<textarea id=\"text".$modname."\" rows=1 hidden disabled >$text</textarea><span id=\"save$modname\" hidden onclick=\"textsave('".$modname."');return false;\" ><a class='info' href=\"#\"><i title='"._("Save Modprobe config")."' class='fa fa-save' ></i></a></span></td></tr>";
|
||||
}
|
||||
|
||||
}
|
||||
$html .= "</tbody>" ;
|
||||
$rtn = array() ;
|
||||
$rtn['html'] = $html ;
|
||||
if ($init !== false) {$init = true ; unlink($sysdrvinit) ;}
|
||||
$rtn['init'] = $init ;
|
||||
echo json_encode($rtn) ;
|
||||
break;
|
||||
|
||||
case "update":
|
||||
$conf = $_POST['conf'] ;
|
||||
$module = $_POST['module'] ;
|
||||
if ($conf == "") $error = unlink("/boot/config/modprobe.d/$module.conf") ; else $error = file_put_contents("/boot/config/modprobe.d/$module.conf",$conf) ;
|
||||
getmodules($module) ;
|
||||
$return = $arrModules[$module] ;
|
||||
$return['supportpage'] = $supportpage ;
|
||||
if (is_array($return["modprobe"]))$return["modprobe"] = implode("\n",$return["modprobe"]) ;
|
||||
if ($error !== false) $return["error"] = false ; else $return["error"] = true ;
|
||||
echo json_encode($return) ;
|
||||
break ;
|
||||
}
|
||||
?>
|
||||
178
emhttp/plugins/dynamix/include/SysDriversHelpers.php
Normal file
178
emhttp/plugins/dynamix/include/SysDriversHelpers.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
function getplugin($in) {
|
||||
$plugins = "/var/log/plugins/";
|
||||
$plugin_link = $plugins.$in ;
|
||||
$plugin_file = @readlink($plugin_link);
|
||||
$support = plugin('support',$plugin_file) ?: "";
|
||||
return($support) ;
|
||||
}
|
||||
|
||||
function getmodules($line) {
|
||||
global $arrModules,$lsmod,$kernel,$arrModtoPlg,$modplugins ;
|
||||
$modprobe = "" ;
|
||||
$desc = $file = $pluginfile = $option = $filename = $depends = $support = $supporturl = $dir = $state = null ;
|
||||
$name = $line ;
|
||||
$modname = shell_exec("modinfo $name > /dev/null") ;
|
||||
if ($modname != null) $modname = trim($modname,"\n") ;
|
||||
$output=null ;
|
||||
exec("modinfo $name",$output,$error) ;
|
||||
$parms = array() ;
|
||||
foreach($output as $outline) {
|
||||
$data = explode(":",$outline) ;
|
||||
$support = false ; $supporturl = null ;
|
||||
switch ($data[0])
|
||||
{
|
||||
case "name":
|
||||
$modname = trim($data[1]) ;
|
||||
break ;
|
||||
case "depends":
|
||||
$depends = trim($data[1]) ;
|
||||
break ;
|
||||
case "filename":
|
||||
$filename = trim($data[1]) ;
|
||||
break ;
|
||||
case "description":
|
||||
$desc = trim($data[1]) ;
|
||||
break ;
|
||||
case "parm":
|
||||
$parms[] = trim(str_replace("parm:","",$outline)) ;
|
||||
break ;
|
||||
case "file":
|
||||
$file = trim(str_replace("file:","",$outline)) ;
|
||||
break ;
|
||||
case "alias":
|
||||
case "author":
|
||||
case "firmware":
|
||||
case "intree":
|
||||
case "vermagic":
|
||||
case "retpoline":
|
||||
case "import_ns":
|
||||
case "license":
|
||||
break ;
|
||||
default:
|
||||
$parms[] = trim($outline) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ($modname != null) {
|
||||
if (strpos($lsmod, $modname,0)) $state = "Inuse" ; else $state = "Available";
|
||||
if (isset($arrModtoPlg[$modname])) { $support = true ; $supporturl = plugin("support", $modplugins[$arrModtoPlg[$modname]]) ; $pluginfile = "Plugin name: {$arrModtoPlg[$modname]}" ; } else { $support = false ; $supporturl = null ; }
|
||||
}
|
||||
if (is_file("/boot/config/modprobe.d/$modname.conf")) {
|
||||
$modprobe = file_get_contents("/boot/config/modprobe.d/$modname.conf") ;
|
||||
$state = strpos($modprobe, "blacklist");
|
||||
$modprobe = explode(PHP_EOL,$modprobe) ;
|
||||
if($state !== false) {$state = "Disabled" ;}
|
||||
else $state="Custom" ;
|
||||
} else {
|
||||
if (is_file("/etc/modprobe.d/$modname.conf")) {
|
||||
$modprobe = file_get_contents("/etc/modprobe.d/$modname.conf") ;
|
||||
$state = strpos($modprobe, "blacklist");
|
||||
$modprobe = explode(PHP_EOL,$modprobe) ;
|
||||
if($state !== false) {$state = "Disabled" ;} else $state="System" ;
|
||||
$module['state'] = $state ;
|
||||
$module['modprobe'] = $modprobe ;
|
||||
}
|
||||
}
|
||||
|
||||
if ($filename != "(builtin)") {
|
||||
if ($filename != null) {
|
||||
$type = pathinfo($filename) ;
|
||||
$dir = $type['dirname'] ;
|
||||
|
||||
$dir = str_replace("/lib/modules/$kernel/kernel/drivers/", "" ,$dir) ;
|
||||
$dir = str_replace("/lib/modules/$kernel/kernel/", "" ,$dir) ;
|
||||
}
|
||||
} else {
|
||||
$dir = $file ;
|
||||
$dir = str_replace("drivers/", "" ,$dir) ;
|
||||
if ($state == "Inuse") $state= "Kernel - Inuse"; else $state="Kernel" ;
|
||||
}
|
||||
if ($desc != null) $description = substr($desc , 0 ,60) ; else $description = null ;
|
||||
$arrModules[$modname] = [
|
||||
'modname' => $modname,
|
||||
'dependacy' => $depends,
|
||||
'parms' => $parms,
|
||||
'file' => $file,
|
||||
'modprobe' => $modprobe,
|
||||
'plugin' => $pluginfile ,
|
||||
'state' => $state,
|
||||
'type' => $dir,
|
||||
'support' => $support,
|
||||
'supporturl' => $supporturl,
|
||||
'description' => $description ,
|
||||
] ;
|
||||
}
|
||||
|
||||
function modtoplg() {
|
||||
global $modtoplgfile,$kernel ;
|
||||
|
||||
$files = array();
|
||||
$kernelsplit = explode('-',$kernel) ;
|
||||
$kernelvers = trim($kernelsplit[0],"\n") ;
|
||||
|
||||
$list = array() ;
|
||||
$files = glob('/boot/config/plugins/*/packages/' . $kernelvers . '/*.{txz,tgz}', GLOB_BRACE);
|
||||
foreach ($files as $f) {
|
||||
$plugin = str_replace("/boot/config/plugins/", "", $f) ;
|
||||
$plugin = substr($plugin,0,strpos($plugin,'/') ) ;
|
||||
$tar = [] ;
|
||||
exec("tar -tf $f | grep -E '.ko.xz|.ko' ",$tar) ;
|
||||
foreach ($tar as $t) {
|
||||
$p = pathinfo($t) ;
|
||||
$filename = str_replace(".ko","",$p["filename"]) ;
|
||||
$list[$filename] = $plugin ;
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($modtoplgfile,json_encode($list,JSON_PRETTY_PRINT)) ;
|
||||
|
||||
}
|
||||
|
||||
function createlist() {
|
||||
global $modtoplgfile, $sysdrvfile, $lsmod, $kernel,$arrModules, $modplugins,$arrModtoPlg ;
|
||||
$arrModtoPlg = json_decode(file_get_contents($modtoplgfile) ,TRUE) ;
|
||||
$builtinmodules = file_get_contents("/lib/modules/$kernel/modules.builtin") ;
|
||||
$builtinmodules = explode(PHP_EOL,$builtinmodules) ;
|
||||
$procmodules =file_get_contents("/lib/modules/$kernel/modules.order") ;
|
||||
$procmodules = explode(PHP_EOL,$procmodules) ;
|
||||
$arrModules = array() ;
|
||||
|
||||
$list = scandir('/var/log/plugins/') ;
|
||||
foreach($list as $f) $modplugins[plugin("name" , @readlink("/var/log/plugins/$f"))] = @readlink("/var/log/plugins/$f") ;
|
||||
|
||||
foreach($builtinmodules as $bultin)
|
||||
{
|
||||
if ($bultin == "") continue ;
|
||||
getmodules(pathinfo($bultin)["filename"]) ;
|
||||
}
|
||||
|
||||
foreach($procmodules as $line) {
|
||||
if ($line == "") continue ;
|
||||
getmodules(pathinfo($line)["filename"]) ;
|
||||
}
|
||||
|
||||
$lsmod2 = explode(PHP_EOL,$lsmod) ;
|
||||
foreach($lsmod2 as $line) {
|
||||
if ($line == "") continue ;
|
||||
$line2 = explode(" ",$line) ;
|
||||
getmodules($line2['0']) ;
|
||||
}
|
||||
|
||||
unset($arrModules['null']);
|
||||
file_put_contents($sysdrvfile,json_encode($arrModules,JSON_PRETTY_PRINT)) ;
|
||||
}
|
||||
|
||||
?>
|
||||
33
emhttp/plugins/dynamix/include/SysDriversInit.php
Executable file
33
emhttp/plugins/dynamix/include/SysDriversInit.php
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
function SysDriverslog($m, $type = "NOTICE") {
|
||||
|
||||
if ($type == "DEBUG" ) return NULL;
|
||||
$m = print_r($m,true);
|
||||
$m = str_replace("\n", " ", $m);
|
||||
$m = str_replace('"', "'", $m);
|
||||
$cmd = "/usr/bin/logger ".'"'.$m.'"'." -tSysDrivers";
|
||||
exec($cmd);
|
||||
}
|
||||
|
||||
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
// add translations
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/SysDriversHelpers.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
$kernel = shell_exec("uname -r") ;
|
||||
$kernel = trim($kernel,"\n") ;
|
||||
$lsmod = shell_exec("lsmod") ;
|
||||
$supportpage = true;
|
||||
$modtoplgfile = "/tmp/modulestoplg.json" ;
|
||||
$sysdrvfile = "/tmp/sysdrivers.json" ;
|
||||
$arrModtoPlg = json_decode(file_get_contents("/tmp/modulestoplg.json") ,TRUE) ;
|
||||
file_put_contents("/tmp/sysdrivers.init","1") ;
|
||||
SysDriverslog("SysDrivers Build Starting") ;
|
||||
modtoplg() ;
|
||||
createlist() ;
|
||||
SysDriverslog("SysDrivers Build Complete") ;
|
||||
?>
|
||||
3184
emhttp/plugins/dynamix/javascript/jquery.tablesorter.widgets.js
Normal file
3184
emhttp/plugins/dynamix/javascript/jquery.tablesorter.widgets.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -17,16 +17,15 @@ $varroot = '/var/local/emhttp';
|
||||
require_once "$docroot/webGui/include/publish.php";
|
||||
|
||||
while (true) {
|
||||
unset($memory,$sys,$rpms,$lsof);
|
||||
unset($memory,$sys,$zfs,$rpms,$lsof);
|
||||
exec("grep -Po '^Mem(Total|Available):\s+\K\d+' /proc/meminfo",$memory);
|
||||
exec("df /boot /var/log /var/lib/docker|grep -Po '\d+%'",$sys);
|
||||
exec("sensors -uA 2>/dev/null|grep -Po 'fan\d_input: \K\d+'",$rpms);
|
||||
exec("awk '/^c_max|^size/{print \$3}' /proc/spl/kstat/zfs/arcstats 2>/dev/null",$zfs);
|
||||
[$total,$free] = $memory;
|
||||
$used = $total-$free;
|
||||
$zfs = (exec("awk '/^size/{print \$3;exit}' /proc/spl/kstat/zfs/arcstats 2>/dev/null")?:0)/1024;
|
||||
$info = max(round(100*(1-$free/$total)),0)."%\0".round(100*$zfs/$used)."%\0".implode("\0",$sys);
|
||||
$info = max(round(100*(1-$free/$total)),0)."%\0".min(100,round(100*($zfs[1]??0)/($zfs[0]??1)))."%\0".implode("\0",$sys);
|
||||
$rpms = count($rpms) ? implode(" RPM\0",$rpms).' RPM' : '';
|
||||
|
||||
$names = array_keys((array)parse_ini_file("$varroot/shares.ini"));
|
||||
exec("LANG='en_US.UTF8' lsof -Owl /mnt/disk[0-9]* 2>/dev/null|awk '/^shfs/ && \$0!~/\.AppleD(B|ouble)/ && \$5==\"REG\"'|awk -F/ '{print \$4}'",$lsof);
|
||||
$counts = array_count_values($lsof); $count = [];
|
||||
|
||||
@@ -159,8 +159,8 @@ function device_temp(&$disk, &$red, &$orange) {
|
||||
global $display;
|
||||
$spin = strpos(_var($disk,'color'),'blink')===false;
|
||||
$temp = _var($disk,'temp','*');
|
||||
$max = _var($disk,'maxTemp') ? $disk['maxTemp'] : (_var($display,'max') ? $display['max'] : 0);
|
||||
$hot = _var($disk,'hotTemp') ? $disk['hotTemp'] : (_var($display,'hot') ? $display['hot'] : 0);
|
||||
$max = _var($disk,'maxTemp')>=0 ? $disk['maxTemp'] : (_var($display,'max')>=0 ? $display['max'] : 0);
|
||||
$hot = _var($disk,'hotTemp')>=0 ? $disk['hotTemp'] : (_var($display,'hot')>=0 ? $display['hot'] : 0);
|
||||
$top = $display['top'] ?? 120;
|
||||
$heat = false; $color = 'green';
|
||||
if (exceed($temp,$max,$top)) {
|
||||
@@ -208,8 +208,8 @@ function device_usage(&$disk, &$full, &$high) {
|
||||
if ($used) {
|
||||
if ($text==2 || $text==21) {
|
||||
$load = substr($used,0,-1);
|
||||
$critical = _var($disk,'critical') ? $disk['critical'] : (_var($display,'critical') ? $display['critical'] : 0);
|
||||
$warning = _var($disk,'warning') ? $disk['warning'] : (_var($display,'warning') ? $display['warning'] : 0);
|
||||
$critical = _var($disk,'critical')>=0 ? $disk['critical'] : (_var($display,'critical')>=0 ? $display['critical'] : 0);
|
||||
$warning = _var($disk,'warning')>=0 ? $disk['warning'] : (_var($display,'warning')>=0 ? $display['warning'] : 0);
|
||||
if ($critical>0 && $load>=$critical) {$class = 'redbar'; $full++;}
|
||||
elseif ($warning>0 && $load>=$warning) {$class = 'orangebar'; $high++;}
|
||||
else $class = 'greenbar';
|
||||
|
||||
@@ -58,9 +58,14 @@ function run($cmd, &$save=null) {
|
||||
exec("timeout -s9 30 $cmd", $save);
|
||||
return implode("\n",$save);
|
||||
}
|
||||
|
||||
function newline($file) {
|
||||
exec("echo|todos >>".escapeshellarg($file));
|
||||
$tmp_file = "/tmp/".basename($file);
|
||||
copy($file, $tmp_file);
|
||||
exec("/usr/bin/todos < ".escapeshellarg($tmp_file)." > ".escapeshellarg($file));
|
||||
unlink($tmp_file);
|
||||
}
|
||||
|
||||
function shareDisks($share) {
|
||||
return str_replace(',',', ',exec("shopt -s dotglob; getfattr --no-dereference --absolute-names --only-values -n system.LOCATIONS ".escapeshellarg("/mnt/user/$share")." 2>/dev/null") ?: "");
|
||||
}
|
||||
@@ -97,6 +102,19 @@ function anonymize($text, $select) {
|
||||
return dirname($text)."/$name.cfg";
|
||||
}
|
||||
}
|
||||
|
||||
function maskIP($file) {
|
||||
global $all;
|
||||
|
||||
if ($all) return;
|
||||
|
||||
// anonymize public IPv4 addresses
|
||||
$rfc1918 = "(127|10|172\.1[6-9]|172\.2[0-9]|172\.3[0-1]|192\.168)((\.[0-9]{1,3}){2,3}([/\" .]|$))";
|
||||
run("sed -ri 's/([\"\[ ]){$rfc1918}/\\1@@@\\2\\3/g; s/([\"\[ ][0-9]{1,3}\.)([0-9]{1,3}\.){2}([0-9]{1,3})([/\" .]|$)/\\1XXX.XXX.\\3\\4/g; s/@@@//g' ".escapeshellarg($file)." 2>/dev/null");
|
||||
// anonymize full IPv6 addresses
|
||||
run("sed -ri 's/([\"\[ ]([0-9a-f]{1,4}:){4})(([0-9a-f]{1,4}:){3}|:)([0-9a-f]{1,4})([/\" .]|$)/\\1XXXX:XXXX:XXXX:\\5\\6/g' ".escapeshellarg($file)." 2>/dev/null");
|
||||
}
|
||||
|
||||
function prefix($key) {
|
||||
return preg_replace('/\d+$/','',$key);
|
||||
}
|
||||
@@ -333,6 +351,24 @@ file_put_contents("/$diag/unraid-".$unraid['version'].".txt",$unraid['version'].
|
||||
// add bz*.sha256 values
|
||||
run("tail /boot/bz*.sha256 >> ".escapeshellarg("/$diag/unraid-".$unraid['version'].".txt"));
|
||||
|
||||
// Get the previous version of Unraid from the previous directory on flash
|
||||
$changes = '/boot/previous/changes.txt';
|
||||
|
||||
if (file_exists($changes)) {
|
||||
exec("head -n4 $changes",$rows);
|
||||
foreach ($rows as $row) {
|
||||
$i = stripos($row, 'version');
|
||||
if ($i !== false) {
|
||||
[$version,$date] = explode(' ', trim(substr($row,$i+7)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
$previous_version = "Previous Version: ".$version;
|
||||
file_put_contents("/$diag/unraid-".$unraid['version'].".txt", "\r\n".$previous_version."\r\n", FILE_APPEND);
|
||||
} else {
|
||||
file_put_contents("/$diag/unraid-".$unraid['version'].".txt", "\r\nNo Previous Version Found\r\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
// copy ini variables
|
||||
foreach (glob("$path/*.ini") as $file) {
|
||||
$ini = basename($file,".ini");
|
||||
@@ -367,7 +403,7 @@ run("ps -auxf --sort=-pcpu 2>/dev/null|todos >".escapeshellarg("/$diag/system/ps
|
||||
run("lsof -Pni 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsof.txt"));
|
||||
run("lsmod|sort 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsmod.txt"));
|
||||
run("df -h 2>/dev/null|todos >".escapeshellarg("/$diag/system/df.txt"));
|
||||
run("ifconfig -a -s 2>/dev/null|grep -Po '^(eth|bond)[0-9]+'", $ports);
|
||||
run("ip -br a|awk '/^(eth|bond)[0-9]+ /{print \$1}'|sort",$ports);
|
||||
run("dmidecode -qt2|awk -F: '/^\tManufacturer:/{m=\$2};/^\tProduct Name:/{p=\$2} END{print m\" -\"p}' 2>/dev/null|todos >".escapeshellarg("/$diag/system/motherboard.txt"));
|
||||
run("dmidecode -qt0 2>/dev/null|todos >>".escapeshellarg("/$diag/system/motherboard.txt"));
|
||||
run("cat /proc/meminfo 2>/dev/null|todos >".escapeshellarg("/$diag/system/meminfo.txt"));
|
||||
@@ -380,7 +416,8 @@ foreach ($ports as $port) {
|
||||
run("ethtool -i ".escapeshellarg($port)." 2>/dev/null|todos >>".escapeshellarg("/$diag/system/ethtool.txt"));
|
||||
file_put_contents("/$diag/system/ethtool.txt", "--------------------------------\r\n", FILE_APPEND);
|
||||
}
|
||||
run("ifconfig -a 2>/dev/null|todos >".escapeshellarg("/$diag/system/ifconfig.txt"));
|
||||
run("ip -br a|todos >".escapeshellarg("/$diag/system/ifconfig.txt"));
|
||||
if (!$all) maskIP("/$diag/system/ifconfig.txt");
|
||||
|
||||
// create system information (suppress errors)
|
||||
run("find /sys/kernel/iommu_groups/ -type l 2>/dev/null|sort -V|todos >".escapeshellarg("/$diag/system/iommu_groups.txt"));
|
||||
@@ -397,15 +434,19 @@ run("cp /boot/config/*.{cfg,conf,dat} ".escapeshellarg("/$diag/config")." 2>/dev
|
||||
run("cp /boot/config/go ".escapeshellarg("/$diag/config/go.txt")." 2>/dev/null");
|
||||
|
||||
// anonymize go file
|
||||
if (!$all)
|
||||
if (!$all) {
|
||||
run("sed -i -e '/password/c ***line removed***' -e '/user/c ***line removed***' -e '/pass/c ***line removed***' ".escapeshellarg("/$diag/config/go.txt"));
|
||||
|
||||
}
|
||||
// anonymize configuration files
|
||||
if (!$all)
|
||||
if (!$all) {
|
||||
run("sed -ri 's/^((disk|flash)(Read|Write)List.*=\")[^\"]+/\\1.../' ".escapeshellarg("/$diag/config/*.cfg")." 2>/dev/null");
|
||||
|
||||
// anonymize IP addresses
|
||||
maskIP("/$diag/config/network.cfg");
|
||||
}
|
||||
// include listening interfaces
|
||||
run("$docroot/webGui/scripts/show_interfaces ip|tr -d ' '|tr '#' ' '|tr ',' '\n' >".escapeshellarg("/$diag/config/listen.txt"));
|
||||
run("$docroot/webGui/scripts/error_interfaces|sed 's/<i.*i>//' >>".escapeshellarg("/$diag/config/listen.txt"));
|
||||
if (!$all) maskIP("/$diag/config/listen.txt");
|
||||
|
||||
// copy share information (anonymize if applicable)
|
||||
$files = glob("/boot/config/shares/*.cfg");
|
||||
@@ -580,6 +621,7 @@ foreach (glob("/var/log/syslog*") as $file) {
|
||||
run("grep -Po 'file: \K[^\"\\x27]+' ".escapeshellarg("$log.txt")." 2>/dev/null|sort|uniq", $titles);
|
||||
run("sed -ri 's|\b\S+@\S+\.\S+\b|email@removed.com|;s|\b(username\|password)([=:])\S+\b|\\1\\2xxx|;s|(GUID: \S)\S+(\S) |\\1..\\2 |;s|(moving \"\S\|\"/mnt/user/\S).*(\S)\"|\\1..\\2\"|' ".escapeshellarg("$log.txt"));
|
||||
run("sed -ri 's|(server: ).+(\.(my)?unraid\.net(:[0-9]+)?,)|\\1hash\\2|;s|(host: \").+(\.(my)?unraid\.net(:[0-9]+)?\")|\\1hash\\2|;s|(referrer: \"https?://).+(\.(my)?unraid\.net)|\\1hash\\2|' ".escapeshellarg("$log.txt"));
|
||||
maskIP("$log.txt");
|
||||
foreach ($titles as $mover) {
|
||||
if (!$mover) continue;
|
||||
$title = "/{$mover[0]}..".substr($mover,-1)."/...";
|
||||
@@ -603,6 +645,7 @@ $dhcplog = "/var/log/dhcplog";
|
||||
if (file_exists($dhcplog)) {
|
||||
$log = "/$diag/logs/dhcplog.txt";
|
||||
run("todos <$dhcplog >".escapeshellarg($log));
|
||||
if (!$all) maskIP($log);
|
||||
}
|
||||
|
||||
// copy graphql-api.log
|
||||
@@ -637,6 +680,23 @@ $testparm = run("testparm -s 2>/dev/null");
|
||||
if (!$all)
|
||||
$testparm = preg_replace("/(?<=\[.)(.*)(?=.\])|(?<=(write list = .)|(comment = .)|(valid users = .)|(path = \/mnt\/addons\/.)|(path = \/mnt\/remotes\/.)|(path = \/mnt\/disks\/.)|(path = \/mnt\/user\/.)).*(?=.)/","...",$testparm);
|
||||
file_put_contents("/$diag/system/testparm.txt",str_replace("\n","\r\n",$testparm));
|
||||
maskIP("/$diag/system/testparm.txt");
|
||||
|
||||
// copy ntp.conf
|
||||
copy("/etc/ntp.conf", "/$diag/system/ntp.txt");
|
||||
maskIP("/$diag/system/ntp.txt");
|
||||
newline("/$diag/system/ntp.txt");
|
||||
|
||||
// copy sshd_config
|
||||
copy("/etc/ssh/sshd_config", "/$diag/system/sshd.txt");
|
||||
maskIP("/$diag/system/sshd.txt");
|
||||
newline("/$diag/system/sshd.txt");
|
||||
|
||||
// copy servers.conf
|
||||
copy("/etc/nginx/conf.d/servers.conf", "/$diag/system/servers.conf.txt");
|
||||
maskIP("/$diag/system/servers.conf.txt");
|
||||
run("sed -Ei 's/[01234567890abcdef]+\.((my)?unraid\.net)/hash.\\1/gm;t' ".escapeshellarg("/$diag/system/servers.conf.txt")." 2>/dev/null");
|
||||
newline("/$diag/system/servers.conf.txt");
|
||||
|
||||
// BEGIN - third party plugins diagnostics
|
||||
// list third party packages in /boot/config/plugins/*/packages/
|
||||
|
||||
15
emhttp/plugins/dynamix/scripts/error_interfaces
Executable file
15
emhttp/plugins/dynamix/scripts/error_interfaces
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
nets=()
|
||||
while IFS='\n' read -r net; do
|
||||
net=${net%/*}
|
||||
net4=$(ip -br -4 addr show to $net 2>/dev/null|awk '$1 !~ "^shim" {print $1}'|tr '\n' ','|sed 's/,$//')
|
||||
[[ -n $net4 ]] && nets+=("$net4 = $net;")
|
||||
done <<< $(ip -br -4 addr|awk '/^(br|bond|eth|wg)[0-9]+(\.[0-9]+)?/ {print $3}'|uniq -d)
|
||||
|
||||
while IFS='\n' read -r net; do
|
||||
net=${net%/*}
|
||||
net6=$(ip -br -6 addr show to $net 2>/dev/null|awk '$1 !~ "^shim" {print $1}'|tr '\n' ','|sed 's/,$//')
|
||||
[[ -n $net6 ]] && nets+=("$net6 = $net;")
|
||||
done <<< $(ip -br -6 addr|awk '/^(br|bond|eth|wg)[0-9]+(\.[0-9]+)?/ && $3 !~ "^fe80" {print $3}'|uniq -d)
|
||||
|
||||
[[ -n $nets ]] && echo "<i class='fa fa-warning' style='margin-right:8px'></i>${nets[@]}"|sed 's/;$//'
|
||||
@@ -10,170 +10,206 @@
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
extract(parse_plugin_cfg('dynamix', true));
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = '';
|
||||
$login_locale = _var($display,'locale');
|
||||
$login_locale = _var($display, 'locale');
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
$var = parse_ini_file('state/var.ini');
|
||||
$unraid = parse_ini_file('/etc/unraid-version');
|
||||
$keyfile = trim(base64_encode(@file_get_contents($var['regFILE'])));
|
||||
$width = in_array($display['theme'],['azure','gray']) ? '98.4%' : '100%';
|
||||
|
||||
$style = ["<style>"];
|
||||
$style[] = "div.spinner.fixed{z-index:100000}";
|
||||
$style[] = "div#control_panel{position:absolute;left:0;right:0;top:0;padding-top:8px;line-height:24px;white-space:nowrap}";
|
||||
$style[] = "div.divide{text-align:center;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}";
|
||||
$style[] = "div.divide label:first-child{margin-left:0}";
|
||||
$style[] = "div.divide label{margin-left:2%;cursor:pointer}";
|
||||
$style[] = "div.allpanels{display:none;position:absolute;left:0;right:0;top:40px;bottom:0;overflow:auto}";
|
||||
$style[] = "div#footer_panel{position:absolute;left:0;right:0;bottom:0;height:30px;line-height:30px;text-align:center}";
|
||||
$style[] = "textarea.feedback{width:$width;height:530px;margin:0;resize:none}";
|
||||
$style[] = "@media (max-width:960px){textarea.feedback{height:330px}}";
|
||||
$style[] = "@media (max-height:768px){textarea.feedback{height:330px}}";
|
||||
$style[] = "input.submit[type=button]{margin-right:0;float:right}";
|
||||
$style[] = "input.submit[type=email]{margin-top:10px;float:left}";
|
||||
$style[] = "p.note,label.note{font-size:1.1rem!important;display:block}";
|
||||
$style[] = "p.success{text-align:center!important;margin-top:20px}";
|
||||
$style[] = "span.spacer{margin:0 4px}";
|
||||
$style[] = "</style>";
|
||||
|
||||
$html = ["<div>"];
|
||||
$html[] = "<div id='control_panel' class='divide'>";
|
||||
$html[] = "<label for='optFeatureRequest'><input type='radio' name='mode' id='optFeatureRequest' value='featurerequest' checked='checked'/> "._('Product Suggestion')."</label>";
|
||||
$html[] = "<label for='optBugReport'><input type='radio' name='mode' id='optBugReport' value='bugreport'/> "._('Bug Report')."</label>";
|
||||
$html[] = "<label for='optComment'><input type='radio' name='mode' id='optComment' value='comment'/> "._('Other Comment')."</label>";
|
||||
$html[] = "<hr>";
|
||||
$html[] = "</div>";
|
||||
$html[] = "<div id='thanks_panel' class='allpanels'></div>";
|
||||
$html[] = "<div id='featurerequest_panel' class='allpanels'>";
|
||||
$html[] = "<textarea id='featureDescription' class='feedback' placeholder=\""._('Please summarize your suggestion here').".\"></textarea>";
|
||||
$html[] = "<br>";
|
||||
$html[] = "<input type='email' id='featureEmail' class='submit' autocomplete='off' spellcheck='false' placeholder=\""._('Contact Email Address').' ('._('optional').")\"><input type='button' id='featureSubmit' class='submit' value=\""._('Submit')."\"/>";
|
||||
$html[] = "</div>";
|
||||
$html[] = "<div id='bugreport_panel' class='allpanels'>";
|
||||
$html[] = "<textarea id='bugDescription' class='feedback'></textarea>";
|
||||
$html[] = "<input type='email' id='bugEmail' class='submit' autocomplete='off' spellcheck='false' placeholder=\""._('Contact Email Address').". ("._('optional').")\"><input type='button' id='bugSubmit' class='submit' value=\""._('Submit')."\"/>";
|
||||
$html[] = "<label class='note' for='anonymize'><input type='checkbox' id='anonymize' value='1' />"._('Anonymize diagnostics (may make troubleshooting more difficult)')."</label>";
|
||||
$html[] = "<p class='note'><b>"._('NOTE').":</b> <i>"._('Submission of this bug report will automatically send your system diagnostics to Lime Technology').".</i></p>";
|
||||
$html[] = "</div>";
|
||||
$html[] = "<div id='comment_panel' class='allpanels'>";
|
||||
$html[] = "<textarea id='commentDescription' class='feedback' placeholder=\""._('Type your question or comment to Lime Technology here').".\"></textarea>";
|
||||
$html[] = "<br>";
|
||||
$html[] = "<input type='email' id='commentEmail' class='submit' autocomplete='off' spellcheck='false' placeholder=\""._('Contact Email Address')." ("._('optional').")\"><input type='button' id='commentSubmit' class='submit' value=\""._('Submit')."\"/>";
|
||||
$html[] = "</div>";
|
||||
$html[] = "<div id='footer_panel'>";
|
||||
$html[] = "<a href='https://unraid.net' target='_blank'>"._('Website')."</a><span class='spacer blue-text'>|</span>";
|
||||
$html[] = "<a href='https://forums.unraid.net' target='_blank'>"._('Forum')."</a><span class='spacer blue-text'>|</span>";
|
||||
$html[] = "<a href='https://docs.unraid.net/' target='_blank'>"._('Docs')."</a>";
|
||||
$html[] = "</div>";
|
||||
$html[] = "</div>";
|
||||
|
||||
$script = ["<script>"];
|
||||
$script[] = "var inkeyfile = '$keyfile';";
|
||||
$script[] = "var unraid_osversion = '{$unraid['version']}';";
|
||||
$script[] = "var unraid_timestamp = ".time().";";
|
||||
$script[] = "var inpageurl = window.top.location.href;";
|
||||
|
||||
$script[] = "function featurerequest_reset() {";
|
||||
$script[] = " \$('#featureDescription').val('');";
|
||||
$script[] = " \$('#featureEmail').val('');";
|
||||
$script[] = "}";
|
||||
|
||||
$script[] = "function bugreport_reset() {";
|
||||
$script[] = " \$('#bugDescription').val(\""._('Bug Description').": \\n\\n\\n\\n"._('How to reproduce').": \\n\\n\\n\\n"._('Expected results').": \\n\\n\\n\\n"._('Actual results').": \\n\\n\\n\\n"._('Other information').": \\n\");";
|
||||
$script[] = " \$('#bugEmail').val('');";
|
||||
$script[] = "}";
|
||||
|
||||
$script[] = "function comment_reset() {";
|
||||
$script[] = " \$('#commentDescription').val('');";
|
||||
$script[] = " \$('#commentEmail').val('');";
|
||||
$script[] = "}";
|
||||
|
||||
$script[] = "function form_submit(url, params, panel, diagnostics) {";
|
||||
$script[] = " panel.find('textarea,input').prop('disabled',true);";
|
||||
$script[] = " \$('div.spinner.fixed').show();";
|
||||
$script[] = " if (diagnostics) {";
|
||||
$script[] = " var anonymize = \$('#anonymize').is(':checked') ? '1' : '';";
|
||||
$script[] = " \$.get('/webGui/include/Feedback.php',{getdiagnostics:1,anonymize:anonymize},function(data) {";
|
||||
$script[] = " params.diagnostics = data;";
|
||||
$script[] = " form_submit(url, params, panel);";
|
||||
$script[] = " }).fail(function() {";
|
||||
$script[] = " \$('div.spinner.fixed').hide();";
|
||||
$script[] = " panel.fadeOut('fast').find('textarea,input').prop('disabled', false);";
|
||||
$script[] = " var failure_message = \"<p class='red-text' style='text-align:center;'>"._('Sorry, an error occurred')." ("._('Unable to generate system diagnostics')." "._('Please try again later').".</p>\";";
|
||||
$script[] = " \$('#thanks_panel').html(failure_message).fadeIn('fast');";
|
||||
$script[] = " });";
|
||||
$script[] = " return;";
|
||||
$script[] = " }";
|
||||
$script[] = " params.timestamp = unraid_timestamp;";
|
||||
$script[] = " params.osversion = unraid_osversion;";
|
||||
$script[] = " params.keyfile = inkeyfile;";
|
||||
$script[] = " params.pageurl = inpageurl;";
|
||||
$script[] = " \$.post(url,params,function(data) {";
|
||||
$script[] = " \$('div.spinner.fixed').hide();";
|
||||
$script[] = " if (data.error) {";
|
||||
$script[] = " var failure_message = \"<p class='red-text' style='text-align:center;'>"._('Sorry, an error occurred').". "._('Please try again later').".</p>\";";
|
||||
$script[] = " \$('#thanks_panel').html(failure_message).fadeIn('fast');";
|
||||
$script[] = " } else {";
|
||||
$script[] = " data.message = data.message || '';";
|
||||
$script[] = " var url_parts = url.split('/');";
|
||||
$script[] = " var success_message = '<div style=\"text-align:center\"><h2 style=\"color:#4f8a10!important\">"._("Thank You")."!</h2><img src=\"/webGui/images/feedback_'+url_parts[4]+'.png\"/><p class=\"success\">'+data.message+'</p></div>';";
|
||||
$script[] = " \$('#thanks_panel').html(success_message).fadeIn('fast', function() {";
|
||||
$script[] = " var resetfunction = window[url_parts[4]+'_reset'];";
|
||||
$script[] = " if (typeof resetfunction !== 'undefined' && \$.isFunction(resetfunction)) {";
|
||||
$script[] = " resetfunction();";
|
||||
$script[] = " }";
|
||||
$script[] = " });";
|
||||
$script[] = " }";
|
||||
$script[] = " }).fail(function(jqXHR, textStatus, errorThrown) {";
|
||||
$script[] = " if (jqXHR.responseJSON && jqXHR.responseJSON.error) {";
|
||||
$script[] = " errorThrown = jqXHR.responseJSON.error;";
|
||||
$script[] = " }";
|
||||
$script[] = " var failure_message = \"<p class='red-text' style='text-align:center;'>"._('Sorry, an error occurred').". "._('Please try again later').".</p>\";";
|
||||
$script[] = " \$('#thanks_panel').html(failure_message).fadeIn('fast');";
|
||||
$script[] = " }).always(function() {";
|
||||
$script[] = " \$('#spinner_image').fadeOut('fast');";
|
||||
$script[] = " panel.fadeOut('fast').find('textarea,input').prop('disabled', false);";
|
||||
$script[] = " });";
|
||||
$script[] = "}";
|
||||
|
||||
$script[] = "\$(function() {";
|
||||
$script[] = " \$('#control_panel input[type=radio]').click(function() {";
|
||||
$script[] = " var showPanel = '#'+\$('#control_panel input[type=radio]:checked').val()+'_panel';";
|
||||
$script[] = " $('.allpanels').not(showPanel).fadeOut('fast');";
|
||||
$script[] = " var loadfunction = window[\$('#control_panel input[type=radio]:checked').val()+'_load'];";
|
||||
$script[] = " if (typeof loadfunction !== 'undefined' && \$.isFunction(loadfunction)) {";
|
||||
$script[] = " loadfunction();";
|
||||
$script[] = " } else {";
|
||||
$script[] = " \$(showPanel).fadeIn('fast');";
|
||||
$script[] = " }";
|
||||
$script[] = " });";
|
||||
$script[] = " \$('#featureSubmit').click(function featureSubmitClick(){";
|
||||
$script[] = " if (\$('#featureDescription').val() === '') return;";
|
||||
$script[] = " form_submit('https://keys.lime-technology.com/feedback/featurerequest',{description:\$('#featureDescription').val(),email:\$('#featureEmail').val()},\$('#featurerequest_panel'));";
|
||||
$script[] = " });";
|
||||
$script[] = " \$('#bugSubmit').click(function bugSubmitClick(){";
|
||||
$script[] = " if (\$('#bugDescription').val() === '') return;";
|
||||
$script[] = " form_submit('https://keys.lime-technology.com/feedback/bugreport',{description:\$('#bugDescription').val(),email:\$('#bugEmail').val()},\$('#bugreport_panel'),true);";
|
||||
$script[] = " });";
|
||||
$script[] = " \$('#commentSubmit').click(function commentSubmitClick(){";
|
||||
$script[] = " if (\$('#commentDescription').val() === '') return;";
|
||||
$script[] = " form_submit('https://keys.lime-technology.com/feedback/comment',{description:\$('#commentDescription').val(),email:\$('#commentEmail').val()},\$('#comment_panel'));";
|
||||
$script[] = " });";
|
||||
$script[] = " featurerequest_reset();";
|
||||
$script[] = " bugreport_reset();";
|
||||
$script[] = " comment_reset();";
|
||||
$script[] = " \$('#optFeatureRequest').click();";
|
||||
$script[] = "});";
|
||||
$script[] = "</script>";
|
||||
|
||||
echo implode($style),implode($html),implode($script);
|
||||
$var = parse_ini_file('state/var.ini');
|
||||
$unraid = parse_ini_file('/etc/unraid-version');
|
||||
$keyfile = !empty(_var($var, 'regFILE')) ? trim(base64_encode(@file_get_contents($var['regFILE']))) : '';
|
||||
$width = in_array($display['theme'], ['azure', 'gray']) ? '98.4%' : '100%';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Feedback Form</title>
|
||||
<style>
|
||||
div.spinner.fixed { z-index: 100000; }
|
||||
div#control_panel { position: absolute; left: 0; right: 0; top: 0; padding-top: 8px; line-height: 24px; white-space: nowrap; }
|
||||
div.divide { text-align: center; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; }
|
||||
div.divide label:first-child { margin-left: 0; }
|
||||
div.divide label { margin-left: 2%; cursor: pointer; }
|
||||
div.allpanels { display: none; position: absolute; left: 0; right: 0; top: 40px; bottom: 0; overflow: auto; }
|
||||
div#footer_panel { position: absolute; left: 0; right: 0; bottom: 0; height: 30px; line-height: 30px; text-align: center; }
|
||||
textarea.feedback { width: <?php echo $width; ?>; height: 530px; margin: 0; resize: none; }
|
||||
@media (max-width: 960px) { textarea.feedback { height: 330px; } }
|
||||
@media (max-height: 768px) { textarea.feedback { height: 330px; } }
|
||||
input.submit[type=button] { margin-right: 0; float: right; position: relative; z-index: 1; }
|
||||
input.submit[type=email] { margin-top: 10px; float: left; position: relative; z-index: 1; }
|
||||
p.note, label.note { font-size: 1.1rem !important; display: block; position: relative; z-index: 0; }
|
||||
p.success { text-align: center !important; margin-top: 20px; }
|
||||
span.spacer { margin: 0 4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div id="control_panel" class="divide">
|
||||
<label for="optFeatureRequest"><input type="radio" name="mode" id="optFeatureRequest" value="featurerequest" checked="checked"/> <?php echo _('Product Suggestion'); ?></label>
|
||||
<label for="optBugReport"><input type="radio" name="mode" id="optBugReport" value="bugreport"/> <?php echo _('Bug Report'); ?></label>
|
||||
<label for="optTroubleshoot"><input type="radio" name="mode" id="optTroubleshoot" value="troubleshoot"/> <?php echo _('Troubleshoot'); ?></label>
|
||||
<label for="optComment"><input type="radio" name="mode" id="optComment" value="comment"/> <?php echo _('Other Comment'); ?></label>
|
||||
<hr>
|
||||
</div>
|
||||
<div id="thanks_panel" class="allpanels"></div>
|
||||
<div id="featurerequest_panel" class="allpanels">
|
||||
<textarea id="featureDescription" class="feedback" placeholder="<?php echo _('Please summarize your suggestion here'); ?>."></textarea>
|
||||
<br>
|
||||
<input type="email" id="featureEmail" class="submit" autocomplete="off" spellcheck="false" placeholder="<?php echo _('Contact Email Address'); ?> (<?php echo _('optional'); ?>)"><input type="button" id="featureSubmit" class="submit" value="<?php echo _('Submit'); ?>"/>
|
||||
</div>
|
||||
<div id="bugreport_panel" class="allpanels">
|
||||
<textarea id="bugDescription" class="feedback"></textarea>
|
||||
<input type="email" id="bugEmail" class="submit" autocomplete="off" spellcheck="false" placeholder="<?php echo _('Contact Email Address'); ?>. (<?php echo _('optional'); ?>)"><input type="button" id="bugSubmit" class="submit" value="<?php echo _('Submit'); ?>"/>
|
||||
<label class="note" for="anonymize_bugReport"><input type="checkbox" id="anonymize_bugReport" class="anonymize" value="1" /> <?php echo _('Anonymize diagnostics (may make troubleshooting more difficult)'); ?></label>
|
||||
<p class="note"><b><?php echo _('NOTE'); ?>:</b> <i><?php echo _('Submission of this bug report will automatically send your system diagnostics to Lime Technology'); ?>.</i></p>
|
||||
</div>
|
||||
<div id="troubleshoot_panel" class="allpanels">
|
||||
<textarea id="troubleshootDescription" class="feedback"></textarea>
|
||||
<textarea id="troubleshootDetails" style="display: none;"></textarea>
|
||||
<input type="email" id="troubleshootEmail" class="submit" autocomplete="off" spellcheck="false" placeholder="<?php echo _('Contact Email Address'); ?>"><input type="button" id="troubleshootSubmit" class="submit" value="<?php echo _('Submit'); ?>"/>
|
||||
<label class="note" for="anonymize_troubleshoot"><input type="checkbox" id="anonymize_troubleshoot" class="anonymize" value="1" /> <?php echo _('Anonymize diagnostics (may make troubleshooting more difficult)'); ?></label>
|
||||
<p class="note"><b><?php echo _('NOTE'); ?>:</b> <i><?php echo _('Submission of this troulbeshooting request will automatically send your system diagnostics to Lime Technology'); ?>.</i></p>
|
||||
</div>
|
||||
<div id="comment_panel" class="allpanels">
|
||||
<textarea id="commentDescription" class="feedback" placeholder="<?php echo _('Type your question or comment to Lime Technology here'); ?>."></textarea>
|
||||
<br>
|
||||
<input type="email" id="commentEmail" class="submit" autocomplete="off" spellcheck="false" placeholder="<?php echo _('Contact Email Address'); ?> (<?php echo _('optional'); ?>)"><input type="button" id="commentSubmit" class="submit" value="<?php echo _('Submit'); ?>"/>
|
||||
</div>
|
||||
<div id="footer_panel">
|
||||
<a href="https://unraid.net" target="_blank"><?php echo _('Website'); ?></a><span class="spacer blue-text">|</span>
|
||||
<a href="https://forums.unraid.net" target="_blank"><?php echo _('Forum'); ?></a><span class="spacer blue-text">|</span>
|
||||
<a href="https://docs.unraid.net/" target="_blank"><?php echo _('Docs'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var inkeyfile = '<?php echo $keyfile; ?>' ?? '';
|
||||
var unraid_osversion = '<?php echo $unraid['version']; ?>';
|
||||
var unraid_timestamp = <?php echo time(); ?>;
|
||||
var inpageurl = window.top.location.href;
|
||||
|
||||
function featurerequest_reset() {
|
||||
$('#featureDescription').val('');
|
||||
$('#featureEmail').val('');
|
||||
}
|
||||
|
||||
function bugreport_reset() {
|
||||
$('#bugDescription').val("<?php echo _('Bug Description'); ?>: \n\n\n\n<?php echo _('How to reproduce'); ?>: \n\n\n\n<?php echo _('Expected results'); ?>: \n\n\n\n<?php echo _('Actual results'); ?>: \n\n\n\n<?php echo _('Other information'); ?>: \n");
|
||||
$('#bugEmail').val('');
|
||||
}
|
||||
|
||||
function troubleshoot_reset() {
|
||||
$('#troubleshootDescription').val("<?php echo _('Description'); ?>: \n\n\n\n<?php echo _('How to reproduce'); ?>: \n\n\n\n<?php echo _('Expected results'); ?>: \n\n\n\n<?php echo _('Actual results'); ?>: \n\n\n\n<?php echo _('Other information'); ?>: \n");
|
||||
$('#troubleshootEmail').val('');
|
||||
}
|
||||
|
||||
function comment_reset() {
|
||||
$('#commentDescription').val('');
|
||||
$('#commentEmail').val('');
|
||||
}
|
||||
|
||||
function form_submit(url, params, panel, diagnostics) {
|
||||
panel.find('textarea,input').prop('disabled', true);
|
||||
$('div.spinner.fixed').show();
|
||||
if (diagnostics) {
|
||||
var anonymize = $('#anonymize').is(':checked') ? '1' : '';
|
||||
$.get('/webGui/include/Feedback.php', { getdiagnostics: 1, anonymize: anonymize }, function(data) {
|
||||
params.diagnostics = data;
|
||||
form_submit(url, params, panel);
|
||||
}).fail(function() {
|
||||
$('div.spinner.fixed').hide();
|
||||
panel.fadeOut('fast').find('textarea,input').prop('disabled', false);
|
||||
var failure_message = "<p class='red-text' style='text-align:center;'><?php echo _('Sorry, an error occurred'); ?> (<?php echo _('Unable to generate system diagnostics'); ?> <?php echo _('Please try again later'); ?>).</p>";
|
||||
$('#thanks_panel').html(failure_message).fadeIn('fast');
|
||||
});
|
||||
return;
|
||||
}
|
||||
params.timestamp = unraid_timestamp;
|
||||
params.osversion = unraid_osversion;
|
||||
params.keyfile = inkeyfile;
|
||||
params.pageurl = inpageurl;
|
||||
$.post(url, params, function(data) {
|
||||
$('div.spinner.fixed').hide();
|
||||
if (data.error) {
|
||||
var failure_message = "<p class='red-text' style='text-align:center;'><?php echo _('Sorry, an error occurred'); ?>. <?php echo _('Please try again later'); ?>.</p>";
|
||||
$('#thanks_panel').html(failure_message).fadeIn('fast');
|
||||
} else {
|
||||
data.message = data.message || '';
|
||||
var url_parts = url.split('/');
|
||||
var success_message = '<div style="text-align:center"><h2 style="color:#4f8a10!important"><?php echo _("Thank You"); ?>!</h2><img src="/webGui/images/feedback_' + url_parts[4] + '.png"/><p class="success">' + data.message + '</p></div>';
|
||||
$('#thanks_panel').html(success_message).fadeIn('fast', function() {
|
||||
var resetfunction = window[url_parts[4] + '_reset'];
|
||||
if (typeof resetfunction !== 'undefined' && $.isFunction(resetfunction)) {
|
||||
resetfunction();
|
||||
}
|
||||
});
|
||||
}
|
||||
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.responseJSON && jqXHR.responseJSON.error) {
|
||||
errorThrown = jqXHR.responseJSON.error;
|
||||
}
|
||||
var failure_message = "<p class='red-text' style='text-align:center;'><?php echo _('Sorry, an error occurred'); ?>. <?php echo _('Please try again later'); ?>.</p>";
|
||||
$('#thanks_panel').html(failure_message).fadeIn('fast');
|
||||
}).always(function() {
|
||||
$('#spinner_image').fadeOut('fast');
|
||||
panel.fadeOut('fast').find('textarea,input').prop('disabled', false);
|
||||
});
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$('#control_panel input[type=radio]').click(function() {
|
||||
var showPanel = '#' + $('#control_panel input[type=radio]:checked').val() + '_panel';
|
||||
$('.allpanels').not(showPanel).fadeOut('fast');
|
||||
var loadfunction = window[$('#control_panel input[type=radio]:checked').val() + '_load'];
|
||||
if (typeof loadfunction !== 'undefined' && $.isFunction(loadfunction)) {
|
||||
loadfunction();
|
||||
} else {
|
||||
$(showPanel).fadeIn('fast');
|
||||
}
|
||||
});
|
||||
|
||||
$('#featureSubmit').click(function featureSubmitClick() {
|
||||
if ($('#featureDescription').val() === '') return;
|
||||
form_submit('https://keys.lime-technology.com/feedback/featurerequest', { description: $('#featureDescription').val(), email: $('#featureEmail').val() }, $('#featurerequest_panel'));
|
||||
});
|
||||
|
||||
$('#bugSubmit').click(function bugSubmitClick() {
|
||||
if ($('#bugDescription').val() === '') return;
|
||||
form_submit('https://keys.lime-technology.com/feedback/bugreport', { description: $('#bugDescription').val(), email: $('#bugEmail').val() }, $('#bugreport_panel'), true);
|
||||
});
|
||||
|
||||
$('#troubleshootSubmit').click(function bugSubmitClick() {
|
||||
if ($('#troubleshootDescription').val() === '') return;
|
||||
if ($('#troubleshootEmail').val() === '') return alert('Email is required for troubleshooting requests');
|
||||
// @todo - update this to use a new troubleshoot endpoint
|
||||
form_submit(
|
||||
'https://keys.lime-technology.com/feedback/bugreport',
|
||||
{
|
||||
description: $('#troubleshootDescription').val() + '\n\n' + $('#troubleshootDetails').val(),
|
||||
email: $('#troubleshootEmail').val()
|
||||
},
|
||||
$('#troubleshoot_panel'),
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
$('#commentSubmit').click(function commentSubmitClick() {
|
||||
if ($('#commentDescription').val() === '') return;
|
||||
form_submit('https://keys.lime-technology.com/feedback/comment', { description: $('#commentDescription').val(), email: $('#commentEmail').val() }, $('#comment_panel'));
|
||||
});
|
||||
|
||||
featurerequest_reset();
|
||||
bugreport_reset();
|
||||
troubleshoot_reset();
|
||||
comment_reset();
|
||||
$('#optFeatureRequest').click();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -46,8 +46,8 @@ function check_temp(&$disk,$text,$info) {
|
||||
global $notify,$saved,$server,$display,$top;
|
||||
$name = _var($disk,'name');
|
||||
$temp = _var($disk,'temp','*');
|
||||
$max = _var($disk,'maxTemp') ? $disk['maxTemp'] : (_var($display,'max') ? $display['max'] : 0);
|
||||
$hot = _var($disk,'hotTemp') ? $disk['hotTemp'] : (_var($display,'hot') ? $display['hot'] : 0);
|
||||
$max = _var($disk,'maxTemp')>=0 ? $disk['maxTemp'] : (_var($display,'max')>=0 ? $display['max'] : 0);
|
||||
$hot = _var($disk,'hotTemp')>=0 ? $disk['hotTemp'] : (_var($display,'hot')>=0 ? $display['hot'] : 0);
|
||||
$warn = exceed($temp,$max,$top) ? 'alert' : (exceed($temp,$hot,$top) ? 'warning' : false);
|
||||
$item = 'temp';
|
||||
$last = $saved[$item][$name] ?? 0;
|
||||
@@ -123,8 +123,8 @@ function check_usage(&$disk,$used,$text,$info) {
|
||||
global $notify,$saved,$server,$display;
|
||||
if ($used == -1) return;
|
||||
$name = _var($disk,'name');
|
||||
$critical = _var($disk,'critical') ? $disk['critical'] : (_var($display,'critical') ? $display['critical'] : 0);
|
||||
$warning = _var($disk,'warning') ? $disk['warning'] : (_var($display,'warning') ? $display['warning'] : 0);
|
||||
$critical = _var($disk,'critical')>=0 ? $disk['critical'] : (_var($display,'critical')>=0 ? $display['critical'] : 0);
|
||||
$warning = _var($disk,'warning')>=0 ? $disk['warning'] : (_var($display,'warning')>=0 ? $display['warning'] : 0);
|
||||
$warn = exceed($used,$critical) ? 'alert' : (exceed($used,$warning) ? 'warning' : false);
|
||||
$item = 'used';
|
||||
$last = $saved[$item][$name] ?? 0;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#!/bin/bash
|
||||
SERVICES="sshd avahidaemon samba rpc nfsd ntpd nginx"
|
||||
SERVICES="rpc nfsd ntpd nginx sshd avahidaemon samba"
|
||||
|
||||
if [[ -n $1 ]]; then
|
||||
[[ ! -e $1 ]] && touch $1 || exit 0
|
||||
fi
|
||||
for cmd in $SERVICES; do
|
||||
[[ $cmd == $1 ]] && option=renew || option=reload
|
||||
if /etc/rc.d/rc.$cmd update; then
|
||||
/etc/rc.d/rc.$cmd $option >/dev/null 2>&1
|
||||
logger -t network "reload service: $cmd"
|
||||
/etc/rc.d/rc.$cmd reload >/dev/null 2>&1
|
||||
fi
|
||||
done
|
||||
exit 0
|
||||
|
||||
@@ -1,99 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
SYSTEM="/sys/class/net"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
CALLER="show"
|
||||
|
||||
link() {
|
||||
grep -Pom1 "^$1=\"\K[^\"]+" $NETWORK_INI.eth
|
||||
}
|
||||
# library functions
|
||||
. /etc/rc.d/rc.library.source
|
||||
|
||||
zero() {
|
||||
data=;
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && data=$1
|
||||
done
|
||||
echo $data
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip addr show to $1 2>/dev/null|grep -Pom1 '^\d+: \K[^:]+';;
|
||||
2) ip addr show $1 $2 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
3) ip $1 addr show $2 $3 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
esac
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ $# -eq 0 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
|
||||
extra() {
|
||||
source <(/usr/bin/fromdos <$EXTRA)
|
||||
for net in $include_interfaces; do
|
||||
if [[ -z ${net//[^.:]} ]]; then
|
||||
# net is an interface name, validate
|
||||
[[ -n $(show dev $net) && -z $(zero $net) ]] && bind+=($net)
|
||||
else
|
||||
# net is an IP address, convert to name
|
||||
net=$(show $net)
|
||||
[[ -n $net && -z $(zero $net) ]] && bind+=($net)
|
||||
fi
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if [[ -z ${net//[^.:]} ]]; then
|
||||
# net is an interface name, remove
|
||||
remove $net
|
||||
else
|
||||
# net is an IP address, convert to name and remove
|
||||
remove $(show $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
bind=();
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
# get interface and vlan configurations
|
||||
for eth in $(grep -Po '^\[\K[^\]]+' $NETWORK_INI); do
|
||||
# main interface
|
||||
if [[ -e $SYSTEM/$eth ]]; then
|
||||
sed -n "/^\[$eth\]/,/^\[eth/p" $NETWORK_INI >$NETWORK_INI.eth
|
||||
net=$eth
|
||||
[[ $(link BONDING) == yes ]] && net=${eth/eth/bond}
|
||||
[[ $(link BRIDGING) == yes ]] && net=${eth/eth/br}
|
||||
net4=$(link IPADDR:0)
|
||||
net6=$(link IPADDR6:0)
|
||||
[[ -n $net4 || -n $net6 ]] && bind+=($net)
|
||||
if [[ $(link TYPE) == trunk ]]; then
|
||||
# vlan interface
|
||||
for vlan in $(grep -Po '^VLANID:\K\d+' $NETWORK_INI.eth); do
|
||||
net4=$(link IPADDR:$vlan)
|
||||
net6=$(link IPADDR6:$vlan)
|
||||
[[ -n $net4 || -n $net6 ]] && bind+=($net.$vlan)
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# add active WG tunnels
|
||||
for wg in $(wg show interfaces); do
|
||||
net4=$(show -4 dev $wg)
|
||||
net6=$(show -6 dev $wg)
|
||||
[[ -n $net4 || -n $net6 ]] && bind+=($wg)
|
||||
done
|
||||
# add user defined interfaces
|
||||
[[ -f $EXTRA ]] && extra
|
||||
# remove temporary file
|
||||
rm -f $NETWORK_INI.eth
|
||||
fi
|
||||
bind=${bind[@]}
|
||||
if [[ $1 == ip ]]; then
|
||||
# include IP addresses?
|
||||
if check && [[ $1 == ip ]]; then
|
||||
ip=()
|
||||
for net in $bind; do
|
||||
ip+=("$net#[$(show -4 dev $net)#$(show -6 dev $net)]")
|
||||
done
|
||||
bind=${ip[@]}
|
||||
fi
|
||||
|
||||
# return list
|
||||
echo ${bind// /, }
|
||||
|
||||
@@ -93,10 +93,10 @@ function my_clock($time) {
|
||||
function my_array(&$disk) {
|
||||
global $data,$display,$error0,$error1,$error2,$error3;
|
||||
$name = _var($disk,'name');
|
||||
$max = $disk['maxTemp'] ?? $display['max'] ?? 0;
|
||||
$hot = $disk['hotTemp'] ?? $display['hot'] ?? 0;
|
||||
$max = _var($disk,'maxTemp')>=0 ? $disk['maxTemp'] : (_var($display,'max')>=0 ? $display['max'] : 0);
|
||||
$hot = _var($disk,'hotTemp')>=0 ? $disk['hotTemp'] : (_var($display,'hot')>=0 ? $display['hot'] : 0);
|
||||
if (strpos(_var($disk,'status'),'_NP')!==false) return false;
|
||||
$temp = _var($disk,'temp','*');
|
||||
$temp = _var($disk,'temp');
|
||||
if ($max>0 && $temp>=$max) {
|
||||
$fail = ' (disk is overheated';
|
||||
$error0++;
|
||||
|
||||
@@ -10,23 +10,12 @@ if [[ -a /boot/config/ident.cfg ]]; then
|
||||
fi
|
||||
|
||||
# preset default values
|
||||
[[ -z $BIND_MGT ]] && BIND_MGT=no
|
||||
[[ -z $USE_TELNET ]] && USE_TELNET=yes
|
||||
[[ -z $USE_TELNET ]] && USE_TELNET=no
|
||||
[[ -z $PORTTELNET ]] && PORTTELNET=23
|
||||
[[ -z $USE_SSH ]] && USE_SSH=yes
|
||||
[[ -z $USE_SSH ]] && USE_SSH=no
|
||||
[[ -z $PORTSSH ]] && PORTSSH=22
|
||||
[[ -z $USE_UPNP ]] && USE_UPNP=no
|
||||
|
||||
# get management IP addresses
|
||||
if [[ $BIND_MGT == yes ]]; then
|
||||
ETH=eth0
|
||||
[[ -e /sys/class/net/bond0 ]] && ETH=bond0
|
||||
[[ -e /sys/class/net/br0 ]] && ETH=br0
|
||||
IPV4=$(ip -4 addr show $ETH|awk '/inet /{gsub(/\/.+$/,"",$2);print $2;exit}')
|
||||
IPV6=$(ip -6 addr show $ETH noprefixroute|awk '/inet6 /{gsub(/\/.+$/,"",$2);print $2;exit}')
|
||||
[[ -z $IPV6 ]] && IPV6=$(ip -6 addr show $ETH scope global permanent|awk '/inet6 /{gsub(/\/.+$/,"",$2);print $2;exit}')
|
||||
fi
|
||||
|
||||
# update SSH listening port
|
||||
if [[ $PORTSSH == 22 ]]; then
|
||||
sed -ri 's/^#?Port [0-9]+$/#Port 22/' $CONF
|
||||
@@ -34,18 +23,6 @@ else
|
||||
sed -ri "s/^#?Port [0-9]+\$/Port ${PORTSSH}/" $CONF
|
||||
fi
|
||||
|
||||
# bind/unbind SSH service
|
||||
if [[ -n $IPV4 ]]; then
|
||||
sed -ri "s/^#?(ListenAddress) 0.0.0.0\$/\1 ${IPV4}/" $CONF
|
||||
else
|
||||
sed -ri 's/^#?(ListenAddress) [0-9]{1,3}\..+$/#\1 0.0.0.0/' $CONF
|
||||
fi
|
||||
if [[ -n $IPV6 ]]; then
|
||||
sed -ri "s/^#?(ListenAddress) ::\$/\1 ${IPV6}/" $CONF
|
||||
else
|
||||
sed -ri 's/^#?(ListenAddress) [A-Fa-f0-9]{1,4}:.+$/#\1 ::/' $CONF
|
||||
fi
|
||||
|
||||
# enable/disable SSH service
|
||||
if [[ $USE_SSH == yes ]]; then
|
||||
if [[ -r /var/run/sshd.pid ]]; then
|
||||
|
||||
7
emhttp/plugins/dynamix/scripts/update_services
Executable file
7
emhttp/plugins/dynamix/scripts/update_services
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
lock=/tmp/atlock.tmp
|
||||
|
||||
logger -t network "update services: ${1:-1}s"
|
||||
rm -f $lock
|
||||
echo "sleep ${1:-1};/usr/local/emhttp/webGui/scripts/reload_services $lock"|at -M now 2>/dev/null
|
||||
exit 0
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/sh
|
||||
#!/bin/sh
|
||||
#
|
||||
# apcupsd This shell script takes care of starting and stopping
|
||||
# the apcupsd UPS monitoring daemon.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# This file is part of avahi.
|
||||
#
|
||||
# avahi is free software; you can redistribute it and/or modify it
|
||||
@@ -14,8 +14,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with avahi; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA.
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# limetech - 'status' modified to exit with correct status
|
||||
# limetech - 'start' modified to enable/disable ipv4/ipv6
|
||||
@@ -23,58 +22,14 @@
|
||||
|
||||
# Start/stop/restart the avahi daemon:
|
||||
|
||||
CALLER="avahi"
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
DESC="Avahi mDNS/DNS-SD Daemon"
|
||||
AVAHI="/usr/sbin/avahi-daemon"
|
||||
CONF="/etc/avahi/avahi-daemon.conf"
|
||||
WIREGUARD="/etc/wireguard"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
SYSTEM="/sys/class/net"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
|
||||
IPv() {
|
||||
type=${1//[^:]}
|
||||
[[ ${#type} -le ${2:-0} ]] && echo 4 || echo 6
|
||||
}
|
||||
|
||||
scan() {
|
||||
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
||||
}
|
||||
|
||||
link() {
|
||||
grep -Pom1 "^$1=\"\K[^\"]+" $NETWORK_INI.eth
|
||||
}
|
||||
|
||||
this() {
|
||||
grep -Pom1 "^$1=\K.*" $CONF
|
||||
}
|
||||
|
||||
take() {
|
||||
data=;
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 || ${1:0:7} == 169.254 || ${1:0:4} == fe80 ]] && data=$1
|
||||
done
|
||||
echo $data
|
||||
}
|
||||
|
||||
good() {
|
||||
[[ -n $1 && ${1:0:7} != 169.254 && ${1:0:4} != fe80 ]] && echo $1
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip addr show to $1 2>/dev/null|grep -Pom1 '^\d+: \K[^:]+';;
|
||||
2) ip addr show $1 $2 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
3) ip $1 addr show $2 $3 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
esac
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ $# -eq 0 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
# library functions
|
||||
. /etc/rc.d/rc.library.source
|
||||
|
||||
allow() {
|
||||
sed -ri "s/^#?(allow-interfaces)=.*/\1=$*/" $CONF
|
||||
@@ -88,88 +43,12 @@ disable() {
|
||||
sed -ri "s/^#?(use-$1)=.*/\1=no/" $CONF
|
||||
}
|
||||
|
||||
extra() {
|
||||
source <(/usr/bin/fromdos <$EXTRA)
|
||||
for net in $include_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, validate
|
||||
[[ -n $(show dev $net) && -z $(take $net) ]] && bind+=($net)
|
||||
else
|
||||
# net is an IP address, convert to name
|
||||
net=$(show $net)
|
||||
[[ -n $net && -z $(take $net) ]] && bind+=($net)
|
||||
fi
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, remove
|
||||
remove $net
|
||||
else
|
||||
# net is an IP address, convert to name and remove
|
||||
remove $(show $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check() {
|
||||
# quick check
|
||||
[[ -n $bind ]] && return 0;
|
||||
# preset return values
|
||||
reply=1; bind=(); ipv4=no; ipv6=no;
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
# get interface and vlan configurations
|
||||
for eth in $(grep -Po '^\[\K[^\]]+' $NETWORK_INI); do
|
||||
# main interface
|
||||
if [[ -e $SYSTEM/$eth ]]; then
|
||||
sed -n "/^\[$eth\]/,/^\[eth/p" $NETWORK_INI >$NETWORK_INI.eth
|
||||
net=$eth
|
||||
[[ $(link BONDING) == yes ]] && net=${eth/eth/bond}
|
||||
[[ $(link BRIDGING) == yes ]] && net=${eth/eth/br}
|
||||
net4=$(link IPADDR:0)
|
||||
net6=$(link IPADDR6:0)
|
||||
[[ -n $(good $net4) || -n $(good $net6) ]] && bind+=($net)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes
|
||||
[[ -n $(good $net6) ]] && ipv6=yes
|
||||
if [[ $(link TYPE) == trunk ]]; then
|
||||
# vlan interface
|
||||
for vlan in $(grep -Po '^VLANID:\K\d+' $NETWORK_INI.eth); do
|
||||
net4=$(link IPADDR:$vlan)
|
||||
net6=$(link IPADDR6:$vlan)
|
||||
[[ -n $(good $net4) || -n $(good $net6) ]] && bind+=($net.$vlan)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes
|
||||
[[ -n $(good $net6) ]] && ipv6=yes
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# add active WG tunnels
|
||||
for wg in $(wg show interfaces); do
|
||||
net4=$(show -4 dev $wg)
|
||||
net6=$(show -6 dev $wg)
|
||||
[[ -n $(good $net4) || -n $(good $net6) ]] && bind+=($wg)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes
|
||||
[[ -n $(good $net6) ]] && ipv6=yes
|
||||
done
|
||||
# add user defined interfaces
|
||||
[[ -f $EXTRA ]] && extra
|
||||
# convert array to string with commas
|
||||
bind=${bind[@]}
|
||||
bind=${bind// /,}
|
||||
reply=0
|
||||
# remove temporary file
|
||||
rm -f $NETWORK_INI.eth
|
||||
fi
|
||||
return $reply
|
||||
}
|
||||
|
||||
avahid_start() {
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
if check && [[ -n $bind ]]; then
|
||||
# bind avahi service
|
||||
if check; then
|
||||
[[ -n $bind ]] && allow $bind
|
||||
[[ $ipv4 == yes ]] && enable ipv4 || disable ipv4
|
||||
[[ $ipv6 == yes ]] && enable ipv6 || disable ipv6
|
||||
fi
|
||||
[[ -n $bind ]] && allow $bind || allow br0
|
||||
[[ $ipv4 == no ]] && disable ipv4 || enable ipv4
|
||||
[[ $ipv6 == no ]] && disable ipv6 || enable ipv6
|
||||
else
|
||||
# default interface with no configuration
|
||||
allow br0
|
||||
@@ -206,7 +85,7 @@ avahid_reload() {
|
||||
|
||||
avahid_update() {
|
||||
if ! avahid_status; then exit 1; fi # not running
|
||||
if check && [[ "$(this allow-interfaces)" == "$bind" && $(this use-ipv4) == $ipv4 && $(this use-ipv6) == $ipv6 ]]; then
|
||||
if check && [[ "$(this allow-interfaces)" == "$bind" ]]; then
|
||||
# no action required
|
||||
exit 1
|
||||
else
|
||||
|
||||
@@ -15,9 +15,9 @@ SYSTEM=/sys/class/net
|
||||
CONF6=/proc/sys/net/ipv6/conf
|
||||
ACTIVE=$(ls --indicator-style=none $SYSTEM|awk '/^(bond|br|eth)[0-9]/' ORS=' ')
|
||||
|
||||
BASE=dockerd
|
||||
DOCKER=/usr/bin/$BASE
|
||||
DOCKER_PIDFILE=/var/run/$BASE.pid
|
||||
DOCKERD=dockerd
|
||||
DOCKER=/usr/bin/$DOCKERD
|
||||
DOCKER_PIDFILE=/var/run/$DOCKERD.pid
|
||||
DOCKER_LOG=/var/log/docker.log
|
||||
DOCKER_ROOT=/var/lib/docker
|
||||
STOCK="eth br bond"
|
||||
@@ -85,15 +85,20 @@ fi
|
||||
|
||||
export DOCKER_RAMDISK=true
|
||||
|
||||
# Get docker daemon PID (if existing)
|
||||
docker_pid() {
|
||||
cat $DOCKER_PIDFILE 2>/dev/null
|
||||
}
|
||||
|
||||
# Verify if docker daemon running
|
||||
is_docker_running(){
|
||||
[[ -S /var/run/docker.sock ]] || return 1
|
||||
[[ $(docker info 2>&1) =~ "Cannot connect to the Docker daemon" ]] && return 1 || return 0
|
||||
}
|
||||
|
||||
# Wait max 15s to daemon start
|
||||
# Wait max 30s to daemon start
|
||||
wait_daemon(){
|
||||
for n in {1..15}; do
|
||||
for n in {1..30}; do
|
||||
if is_docker_running; then return 0; else sleep 1; fi
|
||||
done
|
||||
return 1
|
||||
@@ -110,6 +115,46 @@ running_containers(){
|
||||
docker ps --format='{{.Names}}' 2>/dev/null
|
||||
}
|
||||
|
||||
max6() {
|
||||
# ipv6 addresses in long notation
|
||||
f=:ffff:
|
||||
for x in $*; do
|
||||
read a m < <(IFS=/; echo $x)
|
||||
[[ $a =~ $f && $a =~ '.' ]] && b=${a#*$f} a=${a%$f*}$f:0 || b=
|
||||
c=${a//[^:]/}
|
||||
[[ ${a:0:1} == : ]] && a=0${a}
|
||||
[[ ${a:${#a}-1} == : ]] && a=${a}0
|
||||
a=${a/::/:$(for((i=1;i<=$((8-${#c}));i++)); do printf "0:"; done)}
|
||||
d= a=$(for q in ${a//:/ }; do printf "$d%04x" "0x$q"; d=:; done)
|
||||
[[ -n $b ]] && d= a=${a%$f*}${f}$(for q in ${b//./ }; do printf "$d%03x" "0x$q"; d=.; done)
|
||||
[[ -z $m ]] && echo $a || echo $a/$m
|
||||
done
|
||||
}
|
||||
|
||||
min6() {
|
||||
# ipv6 address in short notation
|
||||
f=:ffff:
|
||||
[[ -n $1 ]] && read a m < <(IFS=/; echo $1) || return
|
||||
[[ $a =~ $f && $a =~ '.' ]] && b=${a#*$f} a=${a%$f*}$f || b=
|
||||
d= a=:$(for q in ${a//:/ }; do printf "$d%x" "0x$q"; d=:; done)
|
||||
a=${a/$(grep -Po ':(0(:|$)){2,8}' <<< $a|sort|tail -1)/::}
|
||||
[[ ${a:0:2} != :: ]] && a=${a:1}
|
||||
[[ -n $b ]] && d= a=${a%$f*}:$(for q in ${b//./ }; do printf "$d%x" "0x$q"; d=.; done)
|
||||
[[ -z $m ]] && echo $a || echo $a/$m
|
||||
}
|
||||
|
||||
wipe() {
|
||||
wet=($*)
|
||||
# remove temporary (privacy extensions) ipv6 addresses
|
||||
for tmp in $(ip -br -6 addr show scope global temporary dev $wet 2>/dev/null|awk '{$1=$2="";print}'); do
|
||||
for i in ${!wet[@]}; do
|
||||
[[ ${wet[$i]} == $tmp ]] && unset 'wet[i]'
|
||||
done
|
||||
done
|
||||
# return cleaned-up list without interface name
|
||||
echo ${wet[@]/$wet}
|
||||
}
|
||||
|
||||
# Custom networks
|
||||
network(){
|
||||
docker network ls --filter driver="$1" --format='{{.Name}}' 2>/dev/null|tr '\n' ' '
|
||||
@@ -196,7 +241,7 @@ start_network(){
|
||||
THIS_IP=
|
||||
while read_dom; do
|
||||
[[ $ENTITY == Network ]] && THIS_NETWORK=$CONTENT
|
||||
[[ $ENTITY == MyIP ]] && THIS_IP=${CONTENT// /} && THIS_IP=${THIS_IP//,/;}
|
||||
[[ $ENTITY == MyIP ]] && THIS_IP=${CONTENT// /,} && THIS_IP=$(echo "${THIS_IP}" | tr -s "," ";")
|
||||
done <$XMLFILE
|
||||
# only restore valid networks
|
||||
if [[ -n $THIS_NETWORK ]]; then
|
||||
@@ -267,18 +312,17 @@ start_network(){
|
||||
fi
|
||||
if [[ -n $IPV4 ]]; then
|
||||
SUBNET=$(ip -4 route show dev $NETWORK $IPV4|awk '{print $1;exit}')
|
||||
SERVER=${IPV4%%/*}
|
||||
SERVER=${IPV4%/*}
|
||||
DHCP=${NETWORK/./_}
|
||||
DHCP=DOCKER_DHCP_${DHCP^^}
|
||||
RANGE=${!DHCP}
|
||||
GATEWAY=$(ip -4 route show dev $NETWORK default|awk '{print $3;exit}')
|
||||
fi
|
||||
SUBNET6=; GATEWAY6=; SERVER6=; RANGE6=;
|
||||
IPV6=$(ip -6 addr show $NETWORK mngtmpaddr|awk '/^ +inet6 /{print $2;exit}')
|
||||
[[ -z $IPV6 ]] && IPV6=$(ip -6 addr show $NETWORK scope global permanent|awk '/^ +inet6 /{print $2;exit}')
|
||||
IPV6=$(min6 $(max6 $(wipe $(ip -br -6 addr show $NETWORK scope global|awk '{$2="";print;exit}'))|sort|head -1))
|
||||
if [[ -n $IPV6 ]]; then
|
||||
SUBNET6=$(ip -6 route show dev $NETWORK $IPV6|awk '{print $1;exit}')
|
||||
SERVER6=${IPV6%%/*}
|
||||
SERVER6=${IPV6%/*}
|
||||
DHCP6=${NETWORK/./_}
|
||||
DHCP6=DOCKER_DHCP6_${DHCP6^^}
|
||||
RANGE6=${!DHCP6}
|
||||
@@ -367,7 +411,7 @@ start_network(){
|
||||
THIS_TT=${CONNECT#*,}
|
||||
THIS_IP=
|
||||
for IP in ${THIS_TT//;/ }; do
|
||||
[[ $IP =~ '.' ]] && THIS_IP="$THIS_IP --ip $IP" || THIS_IP="$THIS_IP --ip6 $IP"
|
||||
[[ $IP =~ ':' ]] && THIS_IP="$THIS_IP --ip6 $IP" || THIS_IP="$THIS_IP --ip $IP"
|
||||
done
|
||||
docker network connect $THIS_IP $NETWORK $THIS_ID >/dev/null
|
||||
done
|
||||
@@ -400,8 +444,17 @@ shim_network(){
|
||||
ip -4 route flush dev $LINK
|
||||
ip -4 route add $2 src $1 dev $LINK
|
||||
ip -4 route add $3 src $1 dev $LINK
|
||||
DEFAULT=$(ip -4 route show dev $NETWORK default|awk '{print $3}')
|
||||
[[ -n $DEFAULT ]] && ip -4 route add default via $DEFAULT dev $LINK metric 0
|
||||
DEFAULT=($(ip -4 route show dev $NETWORK default|awk '{print $3,$5}'))
|
||||
if [[ -n $DEFAULT ]]; then
|
||||
if [[ -z ${DEFAULT[1]} ]]; then
|
||||
METRIC=1
|
||||
METRICS=$(ip -4 route show default|grep -Po 'metric \K\d+')
|
||||
while [[ " $METRICS " =~ " $METRIC " ]]; do ((METRIC++)); done
|
||||
ip -4 route del default via $DEFAULT dev $NETWORK
|
||||
ip -4 route add default via $DEFAULT dev $NETWORK metric $METRIC
|
||||
fi
|
||||
ip -4 route add default via $DEFAULT dev $LINK metric 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove custom networks
|
||||
@@ -459,11 +512,11 @@ start_docker(){
|
||||
echo "no image mounted at $DOCKER_ROOT"
|
||||
exit 1
|
||||
fi
|
||||
echo "starting $BASE ..."
|
||||
echo "starting $DOCKERD ..."
|
||||
if [[ -x $DOCKER ]]; then
|
||||
# If there is an old PID file (no docker running), clean it up:
|
||||
if [[ -r $DOCKER_PIDFILE ]]; then
|
||||
if ! ps axc|grep docker 1>/dev/null 2>&1; then
|
||||
if ! is_docker_running; then
|
||||
echo "Cleaning up old $DOCKER_PIDFILE."
|
||||
rm -f $DOCKER_PIDFILE
|
||||
fi
|
||||
@@ -474,30 +527,26 @@ start_docker(){
|
||||
|
||||
# Stop docker
|
||||
stop_docker(){
|
||||
echo "stopping $BASE ..."
|
||||
echo "stopping $DOCKERD ..."
|
||||
# If there is no PID file, ignore this request...
|
||||
if [[ -r $DOCKER_PIDFILE ]]; then
|
||||
kill $(cat $DOCKER_PIDFILE)
|
||||
# must ensure daemon has stopped before unmounting image volume
|
||||
sleep 1
|
||||
kill $(docker_pid) 2>/dev/null
|
||||
# must ensure daemon has exited
|
||||
for n in {1..15}; do
|
||||
if is_docker_running; then
|
||||
echo "waiting for docker to die ..."
|
||||
sleep 1
|
||||
sleep 1
|
||||
if [[ $(ps -p $(docker_pid) -o comm= 2>/dev/null) != $DOCKERD ]]; then
|
||||
rm -f $DOCKER_PIDFILE
|
||||
# tear down the bridge
|
||||
if ip link show docker0 >/dev/null 2>&1; then
|
||||
ip link set docker0 down
|
||||
ip link del docker0
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
echo "waiting for docker to die ..."
|
||||
done
|
||||
if is_docker_running; then
|
||||
echo "docker will not die!"
|
||||
exit 1
|
||||
elif [[ -r $DOCKER_PIDFILE ]]; then
|
||||
echo "Cleaning up old $DOCKER_PIDFILE."
|
||||
rm -f $DOCKER_PIDFILE
|
||||
fi
|
||||
fi
|
||||
# tear down the bridge
|
||||
if ip link show docker0 >/dev/null 2>&1; then
|
||||
ip link set docker0 down
|
||||
ip link del docker0
|
||||
echo "docker will not die!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -527,11 +576,11 @@ restart)
|
||||
disown
|
||||
;;
|
||||
status)
|
||||
if [[ -f $DOCKER_PIDFILE ]] && ps -o cmd $(cat $DOCKER_PIDFILE)|grep -q $BASE; then
|
||||
echo "status of $BASE: running"
|
||||
if is_docker_running; then
|
||||
echo "status of $DOCKERD: running"
|
||||
echo "running containers:" $(running_containers)
|
||||
else
|
||||
echo "status of $BASE: stopped"
|
||||
echo "status of $DOCKERD: stopped"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/sh
|
||||
#!/bin/sh
|
||||
# /etc/rc.d/rc.inet1
|
||||
# This script is used to bring up the various network interfaces.
|
||||
#
|
||||
@@ -45,13 +45,18 @@
|
||||
# Adapted by Bergware for use in unRAID - May 2023
|
||||
# - added iptables and ip6tables and arp-tables inclusion to bridge interfaces
|
||||
# - fixed ipv4 and ipv6 DNS assignment
|
||||
# - suppress errors
|
||||
|
||||
# Adapted by Bergware for use in unRAID - July 2023
|
||||
# - reverted iptables and ip6tables and arp-tables inclusion to bridge interfaces
|
||||
# - removed promiscuous mode setting for bridge interfaces
|
||||
|
||||
############################
|
||||
# READ NETWORK CONFIG FILE #
|
||||
############################
|
||||
|
||||
# get the configuration information from rc.inet1.conf
|
||||
source /etc/rc.d/rc.inet1.conf
|
||||
. /etc/rc.d/rc.inet1.conf
|
||||
|
||||
# system network reference
|
||||
SYSTEM=/sys/class/net
|
||||
@@ -69,7 +74,7 @@ alias log=run
|
||||
run(){
|
||||
# log command in /var/log/syslog and execute
|
||||
logger -t rc.inet1 "$*"
|
||||
[[ -n $2 ]] && $*
|
||||
[[ -n $2 ]] && $* 2>/dev/null
|
||||
}
|
||||
|
||||
############################
|
||||
@@ -183,7 +188,7 @@ br_up(){
|
||||
# convert legacy no/yes
|
||||
BRSTP[$i]=${BRSTP[$i]/no/0}
|
||||
BRSTP[$i]=${BRSTP[$i]/yes/1}
|
||||
run ip link add name $BRIDGE type bridge stp_state ${BRSTP[$i]} forward_delay ${BRFD[$i]} nf_call_iptables 1 nf_call_ip6tables 1 nf_call_arptables 1
|
||||
run ip link add name $BRIDGE type bridge stp_state ${BRSTP[$i]} forward_delay ${BRFD[$i]}
|
||||
run ip link set $BRIDGE up
|
||||
# loop thru assigned interfaces in bridge
|
||||
for BRNIC in ${BRNICS[$i]}; do
|
||||
@@ -195,7 +200,7 @@ br_up(){
|
||||
run ip link set $BRIF down
|
||||
[[ $IP != ipv6 ]] && run ip -4 addr flush dev $BRIF
|
||||
[[ $IP != ipv4 ]] && run ip -6 addr flush dev $BRIF
|
||||
run ip link set $BRIF promisc on master $BRIDGE up
|
||||
run ip link set $BRIF master $BRIDGE up
|
||||
else
|
||||
[[ $DEBUG_ETH_UP == yes ]] && log "interface $BRIF not present, can't add to $BRIDGE"
|
||||
fi
|
||||
@@ -211,7 +216,7 @@ br_down(){
|
||||
if [[ -e $SYSTEM/$BRIDGE ]]; then
|
||||
# loop thru attached interfaces in bridge
|
||||
for BRIF in $(ls --indicator-style=none $SYSTEM/$BRIDGE/brif); do
|
||||
run ip link set $BRIF promisc off nomaster
|
||||
run ip link set $BRIF nomaster
|
||||
done
|
||||
run ip link set $BRIDGE down
|
||||
run ip link del $BRIDGE
|
||||
|
||||
246
etc/rc.d/rc.library.source
Normal file
246
etc/rc.d/rc.library.source
Normal file
@@ -0,0 +1,246 @@
|
||||
# Library file: /etc/rc.d/rc.library.source
|
||||
# Used by nfsd, ntpd, rpc, samba, nginx, sshd, avahidaemon, show_interfaces
|
||||
#
|
||||
# bergware - updated for Unraid, June 2023
|
||||
|
||||
WIREGUARD="/etc/wireguard"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
|
||||
IPv() {
|
||||
t=${1//[^:]}
|
||||
[[ ${#t} -le 1 ]] && echo 4 || echo 6
|
||||
}
|
||||
|
||||
this() {
|
||||
case $CALLER in
|
||||
'avahi')
|
||||
grep -Pom1 "^$1=\K.*" $CONF
|
||||
;;
|
||||
'smb')
|
||||
grep -Pom1 "^$1 = \K.*" $CONF
|
||||
;;
|
||||
'ntp'|'ssh')
|
||||
grep -Po "^$1 \K\S+" $CONF|tr '\n' ' '|sed 's/ $//'
|
||||
;;
|
||||
'nfs')
|
||||
grep -Pom1 "^RPC_NFSD_OPTS=\"$OPTIONS \K[^\"]+" $NFS
|
||||
;;
|
||||
'rpc')
|
||||
grep -Pom1 "^RPCBIND_OPTS=\"\K[^\"]+" $RPC
|
||||
;;
|
||||
'nginx')
|
||||
now=();
|
||||
for addr in $(awk '$1=="listen" && $2~/^[0-9]|\[/ && $0~/http2; #.*$/{print $2}' $SERVERS 2>/dev/null); do
|
||||
# extract ipv4 / ipv6 address
|
||||
[[ $(IPv $addr) == 4 ]] && addr=${addr%:*} || addr=${addr#*[} addr=${addr%]*}
|
||||
now+=($addr)
|
||||
done
|
||||
# return addresses
|
||||
echo ${now[@]}
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
scan() {
|
||||
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
||||
}
|
||||
|
||||
good() {
|
||||
data=;
|
||||
for i in ${bind[@]}; do
|
||||
[[ $i == $1 || ${1:0:4} == fe80 ]] && data=$1
|
||||
done
|
||||
if [[ -n $2 ]]; then
|
||||
for i in ${nets[@]}; do
|
||||
[[ $i == $2 || ${2:0:4} == fe80 ]] && data=$2
|
||||
done
|
||||
fi
|
||||
echo $data
|
||||
}
|
||||
|
||||
max6() {
|
||||
# ipv6 addresses in long notation
|
||||
f=:ffff:
|
||||
for x in $*; do
|
||||
read a m < <(IFS=/; echo $x)
|
||||
[[ $a =~ $f && $a =~ '.' ]] && b=${a#*$f} a=${a%$f*}$f:0 || b=
|
||||
c=${a//[^:]/}
|
||||
[[ ${a:0:1} == : ]] && a=0${a}
|
||||
[[ ${a:${#a}-1} == : ]] && a=${a}0
|
||||
a=${a/::/:$(for((i=1;i<=$((8-${#c}));i++)); do printf "0:"; done)}
|
||||
d= a=$(for q in ${a//:/ }; do printf "$d%04x" "0x$q"; d=:; done)
|
||||
[[ -n $b ]] && d= a=${a%$f*}${f}$(for q in ${b//./ }; do printf "$d%03x" "0x$q"; d=.; done)
|
||||
[[ -z $m ]] && echo $a || echo $a/$m
|
||||
done
|
||||
}
|
||||
|
||||
min6() {
|
||||
# ipv6 address in short notation
|
||||
f=:ffff:
|
||||
[[ -n $1 ]] && read a m < <(IFS=/; echo $1) || return
|
||||
[[ $a =~ $f && $a =~ '.' ]] && b=${a#*$f} a=${a%$f*}$f || b=
|
||||
d= a=:$(for q in ${a//:/ }; do printf "$d%x" "0x$q"; d=:; done)
|
||||
a=${a/$(grep -Po ':(0(:|$)){2,8}' <<< $a|sort|tail -1)/::}
|
||||
[[ ${a:0:2} != :: ]] && a=${a:1}
|
||||
[[ -n $b ]] && d= a=${a%$f*}:$(for q in ${b//./ }; do printf "$d%x" "0x$q"; d=.; done)
|
||||
[[ -z $m ]] && echo $a || echo $a/$m
|
||||
}
|
||||
|
||||
wipe() {
|
||||
wet=($*)
|
||||
# remove temporary (privacy extensions) ipv6 addresses
|
||||
for tmp in $(ip -br -6 addr show scope global temporary dev $wet 2>/dev/null|awk '{$1=$2="";print}'); do
|
||||
for i in ${!wet[@]}; do
|
||||
[[ ${wet[$i]} == $tmp ]] && unset 'wet[i]'
|
||||
done
|
||||
done
|
||||
# return cleaned-up list without interface name
|
||||
echo ${wet[@]/$wet}
|
||||
}
|
||||
|
||||
main() {
|
||||
min6 $(max6 $(wipe $*)|sort|head -1)
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip -br addr show scope global to $1 2>/dev/null|awk '{print $1;exit}';;
|
||||
2) ip -br addr show scope global $1 $2 2>/dev/null|awk '{print $3;exit}';;
|
||||
3) if [[ $1 == -6 ]]; then main $(ip -br -6 addr show scope global $2 $3 2>/dev/null|awk '{$2="";print;exit}'); else ip -br -4 addr show scope global $2 $3 2>/dev/null|awk '{print $3;exit}'; fi;;
|
||||
esac
|
||||
}
|
||||
|
||||
sub() {
|
||||
[[ -z $1 ]] && return
|
||||
if [[ $CALLER == smb && -z $deny6 ]]; then
|
||||
# replace netmask
|
||||
[[ $(IPv $1) == 4 ]] && echo ${1/\/32/\/24} || echo ${1/\/128/\/64}
|
||||
else
|
||||
# remove netmask
|
||||
echo ${1/\/*}
|
||||
fi
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ -z $1 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
|
||||
isname() {
|
||||
[[ -z ${1//[^.:]} || ${1//[^.:]} == . ]] && return 0 || return 1
|
||||
}
|
||||
|
||||
extra_name() {
|
||||
for net in $include_interfaces; do
|
||||
if $(isname $net); then
|
||||
# net is an interface name, validate
|
||||
[[ $CALLER != ntp && -n $(show dev $net) && -z $(good $net) ]] && bind+=($net)
|
||||
else
|
||||
# net is an IP address, convert to name
|
||||
net=$(show $net)
|
||||
[[ $CALLER != ntp && -n $net && -z $(good $net) ]] && bind+=($net)
|
||||
fi
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if $(isname $net); then
|
||||
# net is an interface name, remove
|
||||
remove $net
|
||||
else
|
||||
# net is an IP address, convert to name and remove
|
||||
remove $(show $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
extra_addr() {
|
||||
for net in $include_interfaces; do
|
||||
if $(isname $net); then
|
||||
# net is an interface name, get IP addresses
|
||||
net4=$(sub $(show -4 dev $net))
|
||||
net6=$(sub $(show -6 dev $net))
|
||||
else
|
||||
# net is an IP address, validate
|
||||
net4=$(sub $(show -4 to $net))
|
||||
net6=$(sub $(show -6 to $net))
|
||||
fi
|
||||
[[ $CALLER != ntp && -n $net4 && -z $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ $CALLER != ntp && -n $net6 && -z $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if $(isname $net); then
|
||||
# net is an interface name, get IP addresses
|
||||
remove $(sub $(show -4 dev $net))
|
||||
remove $(sub $(show -6 dev $net))
|
||||
else
|
||||
# net is an IP address
|
||||
remove $(sub $(show to $net))
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check() {
|
||||
# quick check
|
||||
[[ -n $bind ]] && return 0;
|
||||
# preset return values
|
||||
bind=(); ipv4=no; ipv6=no; family=any;
|
||||
# active ipv4 interfaces (including wireguard)
|
||||
nets=()
|
||||
while IFS='\n' read -r net; do
|
||||
net=($net)
|
||||
# exclude wireguard tunnels for ntp
|
||||
[[ ${net:0:2} == wg && $CALLER == ntp ]] && continue
|
||||
# exclude wireguard VPN docker tunnels
|
||||
[[ ${net:0:2} == wg && $(grep -Pom1 '^TYPE:1="\K[^"]+' $WIREGUARD/$net.cfg) == 8 ]] && continue
|
||||
net1=$(sub ${net[1]})
|
||||
if [[ "avahi show" =~ $CALLER ]]; then
|
||||
[[ -n $net && -n $net1 && -z $(good $net $net1) ]] && bind+=($net)
|
||||
[[ -n $net1 ]] && ipv4=yes nets+=($net1)
|
||||
else
|
||||
[[ -n $net1 && -z $(good $net1) ]] && ipv4=yes bind+=($net1)
|
||||
fi
|
||||
done <<< $(ip -br -4 addr show scope global|awk '/^(br|bond|eth|wg)[0-9]+(\.[0-9]+)?/ {print $1,$3}'|sort)
|
||||
# active ipv6 interfaces (including wireguard)
|
||||
nets=()
|
||||
while IFS='\n' read -r net; do
|
||||
net=($net)
|
||||
# exclude wireguard tunnels for ntp
|
||||
[[ ${net:0:2} == wg && $CALLER == ntp ]] && continue
|
||||
# exclude wireguard VPN docker tunnels
|
||||
[[ ${net:0:2} == wg && $(grep -Pom1 '^TYPE:1="\K[^"]+' $WIREGUARD/$net.cfg) == 8 ]] && continue
|
||||
net1=$(sub $(main ${net[@]}))
|
||||
if [[ "avahi show" =~ $CALLER ]]; then
|
||||
[[ -n $net && -n $net1 && -z $(good $net $net1) ]] && bind+=($net)
|
||||
[[ -n $net1 ]] && ipv6=yes nets+=($net1)
|
||||
else
|
||||
[[ -z $deny6 && -n $net1 && -z $(good $net1) ]] && ipv6=yes bind+=($net1)
|
||||
fi
|
||||
done <<< $(ip -br -6 addr show scope global|awk '/^(br|bond|eth|wg)[0-9]+(\.[0-9]+)?/{$2="";print}'|sort)
|
||||
# add loopback interface
|
||||
if [[ "smb nfs" =~ $CALLER ]]; then
|
||||
[[ $ipv4 == yes ]] && bind+=(127.0.0.1)
|
||||
[[ $ipv6 == yes ]] && bind+=(::1)
|
||||
fi
|
||||
# add user defined interfaces
|
||||
if [[ -f $EXTRA ]]; then
|
||||
. <(/usr/bin/fromdos <$EXTRA)
|
||||
if [[ "avahi show" =~ $CALLER ]]; then
|
||||
extra_name
|
||||
else
|
||||
extra_addr
|
||||
fi
|
||||
fi
|
||||
if [[ $CALLER == ssh ]]; then
|
||||
# bind stays array
|
||||
bind=(${bind[@]})
|
||||
[[ $ipv4 == yes && $ipv6 == no ]] && family=inet
|
||||
[[ $ipv6 == yes && $ipv4 == no ]] && family=inet6
|
||||
else
|
||||
# convert array to string
|
||||
bind=${bind[@]}
|
||||
[[ $CALLER == avahi ]] && bind=${bind// /,}
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -142,6 +142,22 @@ test() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
waitstop() {
|
||||
# wait for daemon to exit
|
||||
PIDFILE=$1
|
||||
PNAME=$2
|
||||
for n in {1..15}; do
|
||||
sleep 1
|
||||
if [[ ! -f "$PIDFILE" || $(ps -p $(cat "$PIDFILE") -o comm= 2>/dev/null) != "$PNAME" ]]; then
|
||||
rm -f "$PIDFILE"
|
||||
return 0
|
||||
fi
|
||||
echo "waiting for $PNAME to die ..."
|
||||
done
|
||||
echo "$PNAME will not die!"
|
||||
return 1
|
||||
}
|
||||
|
||||
start_libvirtd() {
|
||||
if [ -f $LIBVIRTD_PIDFILE ];then
|
||||
echo "libvirt is already running..."
|
||||
@@ -181,7 +197,7 @@ stop_libvirtd() {
|
||||
/usr/sbin/virsh net-destroy $network
|
||||
done
|
||||
kill -TERM $(cat $LIBVIRTD_PIDFILE)
|
||||
sleep 3
|
||||
waitstop $LIBVIRTD_PIDFILE "libvirtd"
|
||||
check_processor
|
||||
/sbin/modprobe -ra $MODULE $MODULES 2>/dev/null
|
||||
}
|
||||
@@ -203,7 +219,7 @@ stop_virtlogd() {
|
||||
fi
|
||||
echo "Stopping virtlogd..."
|
||||
kill -TERM $(cat $VIRTLOGD_PIDFILE)
|
||||
sleep 1
|
||||
waitstop $VIRTLOGD_PIDFILE "virtlogd"
|
||||
}
|
||||
|
||||
start_virtlockd() {
|
||||
@@ -223,7 +239,7 @@ stop_virtlockd() {
|
||||
fi
|
||||
echo "Stopping virtlockd..."
|
||||
kill -TERM $(cat $VIRTLOCKD_PIDFILE)
|
||||
sleep 1
|
||||
waitstop $VIRTLOCKD_PIDFILE "virtlockd"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
# limetech - set default zfs arc size to 1/8 total memory
|
||||
# (MemTotal is reported in units of 1024, SIZE needs to be bytes)
|
||||
SIZE=$(awk '/MemTotal/{print $(NF-1)*128}' /proc/meminfo)
|
||||
echo "options zfs zfs_arc_max=$SIZE" > /etc/modprobe.d/zfs.conf
|
||||
echo "# limetech - Default ARC size is MemTotal/8 (in bytes)" > /etc/modprobe.d/zfs.conf
|
||||
echo "options zfs zfs_arc_max=$SIZE" >> /etc/modprobe.d/zfs.conf
|
||||
|
||||
# limetech - grab any user defined module conf files
|
||||
if [ -d /boot/config/modprobe.d ]; then
|
||||
|
||||
146
etc/rc.d/rc.nfsd
146
etc/rc.d/rc.nfsd
@@ -9,6 +9,7 @@
|
||||
#
|
||||
# bergware - added interface bind functionality
|
||||
|
||||
CALLER="nfs"
|
||||
NFSD="/usr/sbin/rpc.nfsd"
|
||||
EXPORTFS="/usr/sbin/exportfs"
|
||||
RQUOTAD="/usr/sbin/rpc.rquotad"
|
||||
@@ -16,140 +17,17 @@ MOUNTD="/usr/sbin/rpc.mountd"
|
||||
OPTIONS="-u -s"
|
||||
RPC="/etc/default/rpc"
|
||||
NFS="/etc/default/nfs"
|
||||
WIREGUARD="/etc/wireguard"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
SYSTEM="/sys/class/net"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
|
||||
IPv() {
|
||||
type=${1//[^:]}
|
||||
[[ ${#type} -le ${2:-0} ]] && echo 4 || echo 6
|
||||
}
|
||||
|
||||
scan() {
|
||||
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
||||
}
|
||||
|
||||
link() {
|
||||
grep -Pom1 "^$1=\"\K[^\"]+" $NETWORK_INI.eth
|
||||
}
|
||||
|
||||
this() {
|
||||
grep -Pom1 "^RPC_NFSD_OPTS=\"$OPTIONS \K[^\"]+" $NFS
|
||||
}
|
||||
|
||||
take() {
|
||||
data=;
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 || ${1:0:7} == 169.254 || ${1:0:4} == fe80 ]] && data=$1
|
||||
done
|
||||
echo $data
|
||||
}
|
||||
|
||||
good() {
|
||||
[[ -n $1 && ${1:0:7} != 169.254 && ${1:0:4} != fe80 ]] && echo $1
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip addr show to $1 2>/dev/null|grep -Pom1 '^\d+: \K[^:]+';;
|
||||
2) ip addr show $1 $2 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
3) ip $1 addr show $2 $3 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
esac
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ $# -eq 0 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
|
||||
extra() {
|
||||
source <(/usr/bin/fromdos <$EXTRA)
|
||||
for net in $include_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
net4=$(show -4 dev $net)
|
||||
net6=$(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address, validate
|
||||
net4=$(show -4 to $net)
|
||||
net6=$(show -6 to $net)
|
||||
fi
|
||||
[[ -n $net4 && -z $(take $net4) ]] && bind+=($net4)
|
||||
[[ -n $net6 && -z $(take $net6) ]] && bind+=($net6)
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
remove $(show -4 dev $net)
|
||||
remove $(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address
|
||||
remove $(show to $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check() {
|
||||
# quick check
|
||||
[[ -n $bind ]] && return 0;
|
||||
# preset return values
|
||||
reply=1; bind=();
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
# add interfaces and vlans
|
||||
for eth in $(grep -Po '^\[\K[^\]]+' $NETWORK_INI); do
|
||||
if [[ -e $SYSTEM/$eth ]]; then
|
||||
# main interface
|
||||
sed -n "/^\[$eth\]/,/^\[eth/p" $NETWORK_INI >$NETWORK_INI.eth
|
||||
net4=$(link IPADDR:0)
|
||||
net6=$(link IPADDR6:0)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
if [[ $(link TYPE) == trunk ]]; then
|
||||
# vlan interface
|
||||
for vlan in $(grep -Po '^VLANID:\K\d+' $NETWORK_INI.eth); do
|
||||
net4=$(link IPADDR:$vlan)
|
||||
net6=$(link IPADDR6:$vlan)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# add active WG tunnels
|
||||
for wg in $(wg show interfaces); do
|
||||
net4=$(show -4 dev $wg)
|
||||
net6=$(show -6 dev $wg)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
# add loopback interface
|
||||
[[ $ipv4 == yes ]] && bind+=(127.0.0.1)
|
||||
[[ $ipv6 == yes ]] && bind+=(::1)
|
||||
# add user defined interfaces
|
||||
[[ -f $EXTRA ]] && extra
|
||||
# convert array to string
|
||||
bind=${bind[@]}
|
||||
reply=0
|
||||
# remove temporary file
|
||||
rm -f $NETWORK_INI.eth
|
||||
fi
|
||||
return $reply
|
||||
}
|
||||
# library functions
|
||||
. /etc/rc.d/rc.library.source
|
||||
|
||||
# get bind addresses
|
||||
if check && [[ -n $bind ]]; then
|
||||
RPC_NFSD_OPTS="$OPTIONS -H ${bind// / -H }"
|
||||
fi
|
||||
|
||||
# update default settings
|
||||
sed -ri "s/^(RPC_NFSD_OPTS)=.*/\1=\"$RPC_NFSD_OPTS\"/" $NFS 2>/dev/null
|
||||
|
||||
# source default settings:
|
||||
[[ -r $RPC ]] && . $RPC
|
||||
[[ -r $NFS ]] && . $NFS
|
||||
|
||||
nfsd_start() {
|
||||
# There used to be "sanity checks" here to exit without starting if various
|
||||
@@ -162,14 +40,12 @@ nfsd_start() {
|
||||
if [[ ! -r /proc/1/net/rpc/nfsd ]]; then
|
||||
/sbin/modprobe nfsd 2>/dev/null
|
||||
fi
|
||||
|
||||
# mount the nfsd filesystem:
|
||||
if awk '$NF == "nfsd"' /proc/filesystems | grep -q . ; then
|
||||
if ! awk '$3 == "nfsd" && $2 == "/proc/fs/nfs"' /proc/mounts | grep -q . ; then
|
||||
/sbin/mount -t nfsd nfsd /proc/fs/nfs 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# if basic RPC services are not running, start them:
|
||||
if ! ps axc | grep -q rpc.statd; then
|
||||
if [[ -r /etc/rc.d/rc.rpc ]]; then
|
||||
@@ -181,27 +57,25 @@ nfsd_start() {
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Starting NFS server daemons:"
|
||||
|
||||
if [[ -x $EXPORTFS ]]; then
|
||||
echo " $EXPORTFS -r"
|
||||
$EXPORTFS -r 2>/dev/null
|
||||
fi
|
||||
|
||||
if [[ -x $RQUOTAD ]]; then
|
||||
[[ -n $RPC_RQUOTAD_PORT ]] && RPC_RQUOTAD_OPTS="$RPC_RQUOTAD_OPTS -p $RPC_RQUOTAD_PORT"
|
||||
echo " $RQUOTAD $RPC_RQUOTAD_OPTS"
|
||||
$RQUOTAD $RPC_RQUOTAD_OPTS 2>/dev/null
|
||||
fi
|
||||
|
||||
# update default settings
|
||||
sed -ri "s/^(RPC_NFSD_OPTS)=.*/\1=\"$RPC_NFSD_OPTS\"/" $NFS 2>/dev/null
|
||||
[[ -r $NFS ]] && . $NFS
|
||||
# start nfsd servers - 8 if not set extrawise (an old Sun standard):
|
||||
if [[ -x $NFSD ]]; then
|
||||
[[ -z $RPC_NFSD_COUNT ]] && RPC_NFSD_COUNT=8
|
||||
echo " $NFSD $RPC_NFSD_OPTS $RPC_NFSD_COUNT"
|
||||
$NFSD $RPC_NFSD_OPTS $RPC_NFSD_COUNT 2>/dev/null
|
||||
fi
|
||||
|
||||
if [[ -x $MOUNTD ]]; then
|
||||
[[ -n $RPC_MOUNTD_PORT ]] && RPC_MOUNTD_OPTS="$RPC_MOUNTD_OPTS -p $RPC_MOUNTD_PORT"
|
||||
echo " $MOUNTD $RPC_MOUNTD_OPTS"
|
||||
@@ -225,14 +99,12 @@ nfsd_restart() {
|
||||
}
|
||||
|
||||
nfsd_reload() {
|
||||
killall -9 nfsd 2>/dev/null
|
||||
sleep 1
|
||||
[[ -z $RPC_NFSD_COUNT ]] && RPC_NFSD_COUNT=8
|
||||
$NFSD $RPC_NFSD_OPTS $RPC_NFSD_COUNT 2>/dev/null
|
||||
# restart without info
|
||||
nfsd_restart 1>/dev/null 2>&1
|
||||
}
|
||||
|
||||
nfsd_update() {
|
||||
[[ $(pgrep -c nfsd) -le 1 ]] && exit 1 # not running
|
||||
if ! ps axc | grep -q rpc.mountd; then exit 1; fi # not running
|
||||
if check && [[ "$(this)" == "-H ${bind// / -H }" ]]; then
|
||||
# no action required
|
||||
exit 1
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
# WANFQDN 'www.hash.unraid.net' (legacy)
|
||||
# WG0FQDN 'wg0-ip.hash.myunraid.net' (wildcard cert)
|
||||
|
||||
CALLER="nginx"
|
||||
NGINX="/usr/sbin/nginx"
|
||||
PID="/var/run/nginx.pid"
|
||||
SSL="/boot/config/ssl"
|
||||
@@ -22,21 +23,15 @@ CONF="/etc/nginx/nginx.conf"
|
||||
IDENT="/boot/config/ident.cfg"
|
||||
SERVERS="/etc/nginx/conf.d/servers.conf"
|
||||
LOCATIONS="/etc/nginx/conf.d/locations.conf"
|
||||
NEW="/var/local/emhttp/nginx.ini.new"
|
||||
WIREGUARD="/etc/wireguard"
|
||||
INI="/var/local/emhttp/nginx.ini.new"
|
||||
CERTPATH="$SSL/certs/certificate_bundle.pem"
|
||||
MYSERVERS="/boot/config/plugins/dynamix.my.servers/myservers.cfg"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
SYSTEM="/sys/class/net"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
|
||||
# hold server names
|
||||
SERVER_NAMES=()
|
||||
|
||||
# read settings
|
||||
if [[ -a $IDENT ]]; then
|
||||
source <(/usr/bin/fromdos <$IDENT)
|
||||
fi
|
||||
# read Unraid settings
|
||||
[[ -r $IDENT ]] && . <(/usr/bin/fromdos <$IDENT)
|
||||
|
||||
# preset default values
|
||||
[[ -z $START_PAGE ]] && START_PAGE=Main
|
||||
@@ -54,149 +49,33 @@ if ! find /boot/config/*.key &>/dev/null; then
|
||||
START_PAGE="Tools/Registration"
|
||||
fi
|
||||
|
||||
IPv() {
|
||||
type=${1//[^:]}
|
||||
[[ ${#type} -le ${2:-0} ]] && echo 4 || echo 6
|
||||
}
|
||||
|
||||
scan() {
|
||||
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
||||
}
|
||||
|
||||
link() {
|
||||
grep -Pom1 "^$1=\"\K[^\"]+" $NETWORK_INI.eth
|
||||
}
|
||||
|
||||
this() {
|
||||
now=();
|
||||
for addr in $(awk '$1=="listen" && $2~/^[0-9]|\[/ && $0~/http2;$/{print $2}' $SERVERS 2>/dev/null); do
|
||||
# extract ipv4 / ipv6 address
|
||||
[[ $(IPv $addr 1) == 4 ]] && addr=${addr%:*} || addr=${addr#*[} addr=${addr%]*}
|
||||
now+=($addr)
|
||||
done
|
||||
# return addresses
|
||||
echo ${now[@]}
|
||||
}
|
||||
|
||||
take() {
|
||||
data=;
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 || ${1:0:7} == 169.254 || ${1:0:4} == fe80 ]] && data=$1
|
||||
done
|
||||
echo $data
|
||||
}
|
||||
|
||||
good() {
|
||||
[[ -n $1 && ${1:0:7} != 169.254 && ${1:0:4} != fe80 ]] && echo $1
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip addr show to $1 2>/dev/null|grep -Pom1 '^\d+: \K[^:]+';;
|
||||
2) ip addr show $1 $2 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
3) ip $1 addr show $2 $3 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
esac
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ $# -eq 0 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
# library functions
|
||||
. /etc/rc.d/rc.library.source
|
||||
|
||||
fqdn() {
|
||||
echo ${CERTNAME/'*'/${1//[.:]/-}}
|
||||
}
|
||||
|
||||
extra() {
|
||||
source <(/usr/bin/fromdos <$EXTRA)
|
||||
for net in $include_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
net4=$(show -4 dev $net)
|
||||
net6=$(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address, validate
|
||||
net4=$(show -4 to $net)
|
||||
net6=$(show -6 to $net)
|
||||
fi
|
||||
[[ -n $net4 && -z $(take $net4) ]] && bind+=($net4)
|
||||
[[ -n $net6 && -z $(take $net6) ]] && bind+=($net6)
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
remove $(show -4 dev $net)
|
||||
remove $(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address
|
||||
remove $(show to $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check() {
|
||||
# quick check
|
||||
[[ -n $bind ]] && return 0;
|
||||
# preset return values
|
||||
reply=1; bind=(); ipv4=no; ipv6=no;
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
# add interfaces and vlans
|
||||
for eth in $(grep -Po '^\[\K[^\]]+' $NETWORK_INI); do
|
||||
if [[ -e $SYSTEM/$eth ]]; then
|
||||
# main interface
|
||||
sed -n "/^\[$eth\]/,/^\[eth/p" $NETWORK_INI >$NETWORK_INI.eth
|
||||
net4=$(link IPADDR:0)
|
||||
net6=$(link IPADDR6:0)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
if [[ $(link TYPE) == trunk ]]; then
|
||||
# vlan interface
|
||||
for vlan in $(grep -Po '^VLANID:\K\d+' $NETWORK_INI.eth); do
|
||||
net4=$(link IPADDR:$vlan)
|
||||
net6=$(link IPADDR6:$vlan)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# add active WG tunnels
|
||||
for wg in $(wg show interfaces); do
|
||||
net4=$(show -4 dev $wg)
|
||||
net6=$(show -6 dev $wg)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
# add user defined interfaces
|
||||
[[ -f $EXTRA ]] && extra
|
||||
# convert array to string
|
||||
bind=${bind[@]}
|
||||
reply=0
|
||||
# remove temporary file
|
||||
rm -f $NETWORK_INI.eth
|
||||
fi
|
||||
return $reply
|
||||
}
|
||||
|
||||
# create listening ports
|
||||
listen() {
|
||||
t=' '
|
||||
if [[ $1 == lo ]]; then
|
||||
echo "${t}listen 127.0.0.1:$PORT; # lo"
|
||||
[[ $USE_SSL != no ]] && echo "${t}listen 127.0.0.1:$PORTSSL; # lo"
|
||||
echo "${t}listen [::1]:$PORT; # lo"
|
||||
[[ $USE_SSL != no ]] && echo "${t}listen [::1]:$PORTSSL; # lo"
|
||||
elif check && [[ -n $bind ]]; then
|
||||
if check && [[ $1 == lo ]]; then
|
||||
if [[ $ipv4 == yes ]]; then
|
||||
echo "${t}listen 127.0.0.1:$PORT; # lo"
|
||||
echo "${t}listen 127.0.0.1:$PORTSSL; # lo"
|
||||
fi
|
||||
if [[ $ipv6 == yes ]]; then
|
||||
echo "${t}listen [::1]:$PORT; # lo"
|
||||
echo "${t}listen [::1]:$PORTSSL; # lo"
|
||||
fi
|
||||
elif [[ -n $bind ]]; then
|
||||
for addr in $bind; do
|
||||
[[ $(IPv $addr) == 4 ]] && echo "${t}listen $addr:$*; # $(show $addr)"
|
||||
[[ $(IPv $addr) == 6 ]] && echo "${t}listen [$addr]:$*; # $(show $addr)"
|
||||
done
|
||||
else
|
||||
# default listen on any interface and any protocol
|
||||
# default listen on any interface with ipv4 protocol
|
||||
echo "${t}listen $*;"
|
||||
echo "${t}listen [::]:$*;"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -227,7 +106,7 @@ redirect() {
|
||||
if [[ -n $host ]]; then
|
||||
echo "server {"
|
||||
echo "${t}listen $host:$*; # $(show $addr)"
|
||||
echo "${t}return 302 https://$(fqdn $addr):$PORTSSL\$request_uri;"
|
||||
echo "${t}return 302 https://$(fqdn $addr)$PORTSSL_URL\$request_uri;"
|
||||
echo "}"
|
||||
fi
|
||||
done
|
||||
@@ -665,36 +544,36 @@ build_ssl() {
|
||||
DEFAULTURL="http://$LANMDNS$PORT_URL"
|
||||
fi
|
||||
|
||||
mkdir -p $(dirname "$NEW")
|
||||
mkdir -p $(dirname "$INI")
|
||||
# always defined:
|
||||
echo "NGINX_LANIP=\"$LANIP\"" >$NEW
|
||||
echo "NGINX_LANIP6=\"$LANIP6\"" >>$NEW
|
||||
echo "NGINX_LANNAME=\"$LANNAME\"" >>$NEW
|
||||
echo "NGINX_LANMDNS=\"$LANMDNS\"" >>$NEW
|
||||
echo "NGINX_CERTPATH=\"$CERTPATH\"" >>$NEW
|
||||
echo "NGINX_USESSL=\"$USE_SSL\"" >>$NEW
|
||||
echo "NGINX_PORT=\"$PORT\"" >>$NEW
|
||||
echo "NGINX_PORTSSL=\"$PORTSSL\"" >>$NEW
|
||||
echo "NGINX_DEFAULTURL=\"$DEFAULTURL\"" >>$NEW
|
||||
echo "NGINX_LANIP=\"$LANIP\"" >$INI
|
||||
echo "NGINX_LANIP6=\"$LANIP6\"" >>$INI
|
||||
echo "NGINX_LANNAME=\"$LANNAME\"" >>$INI
|
||||
echo "NGINX_LANMDNS=\"$LANMDNS\"" >>$INI
|
||||
echo "NGINX_CERTPATH=\"$CERTPATH\"" >>$INI
|
||||
echo "NGINX_USESSL=\"$USE_SSL\"" >>$INI
|
||||
echo "NGINX_PORT=\"$PORT\"" >>$INI
|
||||
echo "NGINX_PORTSSL=\"$PORTSSL\"" >>$INI
|
||||
echo "NGINX_DEFAULTURL=\"$DEFAULTURL\"" >>$INI
|
||||
# defined if certificate_bundle.pem present:
|
||||
echo "NGINX_CERTNAME=\"$CERTNAME\"" >>$NEW
|
||||
echo "NGINX_LANFQDN=\"$LANFQDN\"" >>$NEW
|
||||
echo "NGINX_LANFQDN6=\"$LANFQDN6\"" >>$NEW
|
||||
echo "NGINX_CERTNAME=\"$CERTNAME\"" >>$INI
|
||||
echo "NGINX_LANFQDN=\"$LANFQDN\"" >>$INI
|
||||
echo "NGINX_LANFQDN6=\"$LANFQDN6\"" >>$INI
|
||||
# defined if remote access enabled:
|
||||
echo "NGINX_WANACCESS=\"$WANACCESS\"" >>$NEW
|
||||
echo "NGINX_WANIP=\"$WANIP\"" >>$NEW
|
||||
echo "NGINX_WANIP6=\"$WANIP6\"" >>$NEW
|
||||
echo "NGINX_WANFQDN=\"$WANFQDN\"" >>$NEW
|
||||
echo "NGINX_WANFQDN6=\"$WANFQDN6\"" >>$NEW
|
||||
echo "NGINX_WANACCESS=\"$WANACCESS\"" >>$INI
|
||||
echo "NGINX_WANIP=\"$WANIP\"" >>$INI
|
||||
echo "NGINX_WANIP6=\"$WANIP6\"" >>$INI
|
||||
echo "NGINX_WANFQDN=\"$WANFQDN\"" >>$INI
|
||||
echo "NGINX_WANFQDN6=\"$WANFQDN6\"" >>$INI
|
||||
# add included interfaces
|
||||
for NET in ${!NET_FQDN[@]}; do
|
||||
echo "NGINX_${NET^^}FQDN=\"${NET_FQDN[$NET]}\"" >>$NEW
|
||||
echo "NGINX_${NET^^}FQDN=\"${NET_FQDN[$NET]}\"" >>$INI
|
||||
done
|
||||
for NET in ${!NET_FQDN6[@]}; do
|
||||
echo "NGINX_${NET^^}FQDN6=\"${NET_FQDN6[$NET]}\"" >>$NEW
|
||||
echo "NGINX_${NET^^}FQDN6=\"${NET_FQDN6[$NET]}\"" >>$INI
|
||||
done
|
||||
# atomically update file
|
||||
/usr/bin/mv $NEW ${NEW%.*}
|
||||
/usr/bin/mv $INI ${INI%.*}
|
||||
}
|
||||
|
||||
nginx_status() {
|
||||
@@ -818,7 +697,7 @@ nginx_renew() {
|
||||
}
|
||||
|
||||
nginx_update() {
|
||||
[[ $(pgrep -cf $NGINX) -eq 0 ]] && exit 1 # not running
|
||||
if ! nginx_status; then exit 1; fi # not running
|
||||
if check && [[ "$(this)" == "$bind" ]]; then
|
||||
# no action required
|
||||
exit 1
|
||||
|
||||
144
etc/rc.d/rc.ntpd
144
etc/rc.d/rc.ntpd
@@ -4,132 +4,14 @@
|
||||
# limetech - modified to initialize ntp.conf file from config
|
||||
# bergware - added interface bind functionality
|
||||
|
||||
CALLER="ntp"
|
||||
NTPD="/usr/sbin/ntpd"
|
||||
OPTIONS="-g -u ntp:ntp"
|
||||
CONF="/etc/ntp.conf"
|
||||
IDENT="/boot/config/ident.cfg"
|
||||
WIREGUARD="/etc/wireguard"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
SYSTEM="/sys/class/net"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
|
||||
IPv() {
|
||||
type=${1//[^:]}
|
||||
[[ ${#type} -le ${2:-0} ]] && echo 4 || echo 6
|
||||
}
|
||||
|
||||
scan() {
|
||||
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
||||
}
|
||||
|
||||
link() {
|
||||
grep -Pom1 "^$1=\"\K[^\"]+" $NETWORK_INI.eth
|
||||
}
|
||||
|
||||
this() {
|
||||
grep -Po "^$1 \K.*" $CONF|tr '\n' ' '|sed 's/ $//'
|
||||
}
|
||||
|
||||
take() {
|
||||
data=;
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 || ${1:0:7} == 169.254 || ${1:0:4} == fe80 ]] && data=$1
|
||||
done
|
||||
echo $data
|
||||
}
|
||||
|
||||
good() {
|
||||
[[ -n $1 && ${1:0:7} != 169.254 && ${1:0:4} != fe80 ]] && echo $1
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip addr show to $1 2>/dev/null|grep -Pom1 '^\d+: \K[^:]+';;
|
||||
2) ip addr show $1 $2 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
3) ip $1 addr show $2 $3 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
esac
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ $# -eq 0 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
|
||||
extra() {
|
||||
source <(/usr/bin/fromdos <$EXTRA)
|
||||
for net in $include_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
net4=$(show -4 dev $net)
|
||||
net6=$(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address, validate
|
||||
net4=$(show -4 to $net)
|
||||
net6=$(show -6 to $net)
|
||||
fi
|
||||
[[ -n $net4 && -z $(take $net4) ]] && bind+=($net4)
|
||||
[[ -n $net6 && -z $(take $net6) ]] && bind+=($net6)
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
remove $(show -4 dev $net)
|
||||
remove $(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address
|
||||
remove $(show to $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check() {
|
||||
# quick check
|
||||
[[ -n $bind ]] && return 0;
|
||||
# preset return values
|
||||
reply=1; bind=(); ipv4=no; ipv6=no;
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
# get interface and vlan configurations
|
||||
for eth in $(grep -Po '^\[\K[^\]]+' $NETWORK_INI); do
|
||||
if [[ -e $SYSTEM/$eth ]]; then
|
||||
# main interface
|
||||
sed -n "/^\[$eth\]/,/^\[eth/p" $NETWORK_INI >$NETWORK_INI.eth
|
||||
net4=$(link IPADDR:0)
|
||||
net6=$(link IPADDR6:0)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
# vlan interface
|
||||
if [[ $(link TYPE) == trunk ]]; then
|
||||
for vlan in $(grep -Po '^VLANID:\K\d+' $NETWORK_INI.eth); do
|
||||
net4=$(link IPADDR:$vlan)
|
||||
net6=$(link IPADDR6:$vlan)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# add active WG tunnels
|
||||
for wg in $(wg show interfaces); do
|
||||
net4=$(show -4 dev $wg)
|
||||
net6=$(show -6 dev $wg)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
# add loopback interface
|
||||
[[ $ipv4 == yes ]] && bind+=(127.0.0.1)
|
||||
[[ $ipv6 == yes ]] && bind+=(::1)
|
||||
# add user defined interfaces
|
||||
[[ -f $EXTRA ]] && extra
|
||||
# convert array to string
|
||||
bind=${bind[@]}
|
||||
reply=0
|
||||
# remove temporary file
|
||||
rm -f $NETWORK_INI.eth
|
||||
fi
|
||||
return $reply
|
||||
}
|
||||
# library functions
|
||||
. /etc/rc.d/rc.library.source
|
||||
|
||||
build_ntp() {
|
||||
cp $CONF- $CONF
|
||||
@@ -139,12 +21,10 @@ build_ntp() {
|
||||
# ignore unused protocol
|
||||
[[ $ipv4 == no ]] && echo "interface ignore ipv4" >>$CONF
|
||||
[[ $ipv6 == no ]] && echo "interface ignore ipv6" >>$CONF
|
||||
# for now do not bind interfaces
|
||||
# it is not clear why NTP is started several times and fails to bind on occasion
|
||||
# add listen interfaces
|
||||
#for net in $bind; do
|
||||
# echo "interface listen $net" >>$CONF
|
||||
#done
|
||||
for net in $bind; do
|
||||
echo "interface listen $net # $(show $net)" >>$CONF
|
||||
done
|
||||
fi
|
||||
# add configured NTP servers
|
||||
[[ -n $NTP_SERVER1 ]] && echo "server $NTP_SERVER1 iburst" >>$CONF
|
||||
@@ -159,12 +39,8 @@ ntpd_start() {
|
||||
echo "ntpd already running, not starting again"
|
||||
return
|
||||
fi
|
||||
# if our config file not present, don't start ntp
|
||||
if [[ ! -f $IDENT ]]; then
|
||||
echo "Missing file: $IDENT"
|
||||
return
|
||||
fi
|
||||
source <(/usr/bin/fromdos <$IDENT)
|
||||
# read Unraid settings
|
||||
[[ -r $IDENT ]] && . <(/usr/bin/fromdos <$IDENT)
|
||||
# if ntp not enabled, don't start ntp
|
||||
if [[ $USE_NTP != yes ]]; then
|
||||
echo "NTP not enabled"
|
||||
@@ -209,14 +85,14 @@ ntpd_status() {
|
||||
|
||||
ntpd_reload() {
|
||||
killall -HUP -q ntpd
|
||||
source <(/usr/bin/fromdos <$IDENT)
|
||||
. <(/usr/bin/fromdos <$IDENT)
|
||||
build_ntp
|
||||
$NTPD $OPTIONS 2>/dev/null
|
||||
}
|
||||
|
||||
ntpd_update() {
|
||||
[[ $(pgrep -cf $NTPD) -eq 0 ]] && exit 1 # not running
|
||||
if check && [[ -z "$(this 'interface listen')" || "$(this 'interface listen')" == "$bind" ]]; then
|
||||
if check && [[ "$(this 'interface listen')" == "$bind" ]]; then
|
||||
# no action required
|
||||
exit 1
|
||||
else
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/sh
|
||||
#!/bin/sh
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: php-fpm
|
||||
|
||||
149
etc/rc.d/rc.rpc
149
etc/rc.d/rc.rpc
@@ -12,144 +12,24 @@
|
||||
# limetech - get rid of chatty '-l' rpcbind option
|
||||
# bergware - added interface bind functionality
|
||||
|
||||
CALLER="rpc"
|
||||
RPCBIND="/sbin/rpcbind"
|
||||
STATD="/sbin/rpc.statd"
|
||||
RPC="/etc/default/rpc"
|
||||
WIREGUARD="/etc/wireguard"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
SYSTEM="/sys/class/net"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
|
||||
IPv() {
|
||||
type=${1//[^:]}
|
||||
[[ ${#type} -le ${2:-0} ]] && echo 4 || echo 6
|
||||
}
|
||||
|
||||
scan() {
|
||||
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
||||
}
|
||||
|
||||
link() {
|
||||
grep -Pom1 "^$1=\"\K[^\"]+" $NETWORK_INI.eth
|
||||
}
|
||||
|
||||
this() {
|
||||
grep -Pom1 "^RPCBIND_OPTS=\"\K[^\"]+" $RPC
|
||||
}
|
||||
|
||||
take() {
|
||||
data=;
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 || ${1:0:7} == 169.254 || ${1:0:4} == fe80 ]] && data=$1
|
||||
done
|
||||
echo $data
|
||||
}
|
||||
|
||||
good() {
|
||||
[[ -n $1 && ${1:0:7} != 169.254 && ${1:0:4} != fe80 ]] && echo $1
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip addr show to $1 2>/dev/null|grep -Pom1 '^\d+: \K[^:]+';;
|
||||
2) ip addr show $1 $2 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
3) ip $1 addr show $2 $3 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
esac
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ $# -eq 0 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
|
||||
extra() {
|
||||
source <(/usr/bin/fromdos <$EXTRA)
|
||||
for net in $include_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
net4=$(show -4 dev $net)
|
||||
net6=$(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address, validate
|
||||
net4=$(show -4 to $net)
|
||||
net6=$(show -6 to $net)
|
||||
fi
|
||||
[[ -n $net4 && -z $(take $net4) ]] && bind+=($net4)
|
||||
[[ -n $net6 && -z $(take $net6) ]] && bind+=($net6)
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
remove $(show -4 dev $net)
|
||||
remove $(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address
|
||||
remove $(show to $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check() {
|
||||
# quick check
|
||||
[[ -n $bind ]] && return 0;
|
||||
# preset return values
|
||||
reply=1; bind=();
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
# add interfaces and vlans
|
||||
for eth in $(grep -Po '^\[\K[^\]]+' $NETWORK_INI); do
|
||||
if [[ -e $SYSTEM/$eth ]]; then
|
||||
# main interface
|
||||
sed -n "/^\[$eth\]/,/^\[eth/p" $NETWORK_INI >$NETWORK_INI.eth
|
||||
net4=$(link IPADDR:0)
|
||||
net6=$(link IPADDR6:0)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
if [[ $(link TYPE) == trunk ]]; then
|
||||
# vlan interface
|
||||
for vlan in $(grep -Po '^VLANID:\K\d+' $NETWORK_INI.eth); do
|
||||
net4=$(link IPADDR:$vlan)
|
||||
net6=$(link IPADDR6:$vlan)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# add active WG tunnels
|
||||
for wg in $(wg show interfaces); do
|
||||
net4=$(show -4 dev $wg)
|
||||
net6=$(show -6 dev $wg)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
# add loopback interface
|
||||
[[ $ipv4 == yes ]] && bind+=(127.0.0.1)
|
||||
[[ $ipv6 == yes ]] && bind+=(::1)
|
||||
# add user defined interfaces
|
||||
[[ -f $EXTRA ]] && extra
|
||||
# convert array to string
|
||||
bind=${bind[@]}
|
||||
reply=0
|
||||
# remove temporary file
|
||||
rm -f $NETWORK_INI.eth
|
||||
fi
|
||||
return $reply
|
||||
}
|
||||
# library functions
|
||||
. /etc/rc.d/rc.library.source
|
||||
|
||||
# get bind addresses
|
||||
if check && [[ -n $bind ]]; then
|
||||
RPCBIND_OPTS="-h ${bind// / -h }"
|
||||
fi
|
||||
|
||||
# update default settings
|
||||
sed -ri "s/^#?(RPCBIND_OPTS)=.*/\1=\"$RPCBIND_OPTS\"/" $RPC 2>/dev/null
|
||||
|
||||
# source default settings:
|
||||
[[ -r $RPC ]] && . $RPC
|
||||
|
||||
rpc_start() {
|
||||
if [[ -x $RPCBIND && -x /sbin/rpc.statd ]]; then
|
||||
if [[ -x $RPCBIND && -x $STATD ]]; then
|
||||
# update default settings
|
||||
sed -ri "s/^#?(RPCBIND_OPTS)=.*/\1=\"$RPCBIND_OPTS\"/" $RPC 2>/dev/null
|
||||
[[ -r $RPC ]] && . $RPC
|
||||
# Set up port for lockd:
|
||||
if [[ -n $LOCKD_TCP_PORT ]]; then
|
||||
/sbin/sysctl -w "fs.nfs.nlm_tcpport=$LOCKD_TCP_PORT" 2>/dev/null
|
||||
@@ -165,15 +45,15 @@ rpc_start() {
|
||||
[[ -n $RPC_STATD_HOSTNAME ]] && RPC_STATD_OPTS="$RPC_STATD_OPTS -n $RPC_STATD_HOSTNAME"
|
||||
[[ -n $RPC_STATD_PORT ]] && RPC_STATD_OPTS="$RPC_STATD_OPTS -p $RPC_STATD_PORT"
|
||||
[[ -n $RPC_STATD_OUTGOING_PORT ]] && RPC_STATD_OPTS="$RPC_STATD_OPTS -o $RPC_STATD_OUTGOING_PORT"
|
||||
echo "Starting RPC NSM (Network Status Monitor): /sbin/rpc.statd $RPC_STATD_OPTS"
|
||||
/sbin/rpc.statd $RPC_STATD_OPTS 2>/dev/null
|
||||
echo "Starting RPC NSM (Network Status Monitor): $STATD $RPC_STATD_OPTS"
|
||||
$STATD $RPC_STATD_OPTS 2>/dev/null
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Cannot start RPC daemons needed for NFS. One or more of"
|
||||
echo " these required daemons is not executable or is not present"
|
||||
echo " on your system:"
|
||||
echo
|
||||
echo " $RPCBIND or /sbin/rpc.statd"
|
||||
echo " $RPCBIND or $STATD"
|
||||
echo
|
||||
fi
|
||||
}
|
||||
@@ -195,13 +75,12 @@ rpc_restart() {
|
||||
}
|
||||
|
||||
rpc_reload() {
|
||||
killall -9 rpcbind 2>/dev/null
|
||||
sleep 1
|
||||
$RPCBIND -w $RPCBIND_OPTS 2>/dev/null
|
||||
# restart without info
|
||||
rpc_restart 1>/dev/null 2>&1
|
||||
}
|
||||
|
||||
rpc_update() {
|
||||
[[ $(pgrep -cf $RPCBIND) -eq 0 ]] && exit 1; # not running
|
||||
if ! ps axc | grep -q rpcbind; then exit 1; fi # not running
|
||||
if check && [[ "$(this)" == "-h ${bind// / -h }" ]]; then
|
||||
# no action required
|
||||
exit 1
|
||||
|
||||
@@ -10,142 +10,26 @@
|
||||
# limetech - modified to initialize smb-names.conf file from config
|
||||
# bergware - added interface bind functionality
|
||||
|
||||
CALLER="smb"
|
||||
SMBD="/usr/sbin/smbd"
|
||||
NMBD="/usr/sbin/nmbd"
|
||||
WINBINDD="/usr/sbin/winbindd"
|
||||
WSDD2="/usr/sbin/wsdd2"
|
||||
SMBCONF="/etc/samba/smb.conf"
|
||||
CONF="/etc/samba/smb-names.conf"
|
||||
IDENT="/boot/config/ident.cfg"
|
||||
BOOT="/boot/config"
|
||||
PRIVATE="/var/lib/samba/private"
|
||||
WIREGUARD="/etc/wireguard"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
SYSTEM="/sys/class/net"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
|
||||
IPv() {
|
||||
type=${1//[^:]}
|
||||
[[ ${#type} -le ${2:-0} ]] && echo 4 || echo 6
|
||||
}
|
||||
# library functions
|
||||
. /etc/rc.d/rc.library.source
|
||||
|
||||
scan() {
|
||||
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
||||
}
|
||||
|
||||
link() {
|
||||
grep -Pom1 "^$1=\"\K[^\"]+" $NETWORK_INI.eth
|
||||
}
|
||||
|
||||
this() {
|
||||
grep -Pom1 "^$1 = \K.*" $CONF
|
||||
}
|
||||
|
||||
take() {
|
||||
data=;
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 || ${1:0:7} == 169.254 || ${1:0:4} == fe80 ]] && data=$1
|
||||
done
|
||||
echo $data
|
||||
}
|
||||
|
||||
good() {
|
||||
[[ -n $1 && ${1:0:7} != 169.254 && ${1:0:4} != fe80 ]] && echo $1
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip addr show to $1 2>/dev/null|grep -Pom1 '^\d+: \K[^:]+';;
|
||||
2) ip addr show $1 $2 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
3) ip $1 addr show $2 $3 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
esac
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ $# -eq 0 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
|
||||
extra() {
|
||||
source <(/usr/bin/fromdos <$EXTRA)
|
||||
for net in $include_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
net4=$(show -4 dev $net)
|
||||
net6=$(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address, validate
|
||||
net4=$(show -4 to $net)
|
||||
net6=$(show -6 to $net)
|
||||
fi
|
||||
[[ -n $net4 && -z $(take $net4) ]] && bind+=($net4)
|
||||
[[ -n $net6 && -z $(take $net6) ]] && bind+=($net6)
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
remove $(show -4 dev $net)
|
||||
remove $(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address
|
||||
remove $(show to $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check() {
|
||||
# quick check
|
||||
[[ -n $bind ]] && return 0;
|
||||
# preset return values
|
||||
reply=1; bind=(); ipv4=no; ipv6=no;
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
# get interface and vlan configurations
|
||||
for eth in $(grep -Po '^\[\K[^\]]+' $NETWORK_INI); do
|
||||
# main interface
|
||||
if [[ -e $SYSTEM/$eth ]]; then
|
||||
sed -n "/^\[$eth\]/,/^\[eth/p" $NETWORK_INI >$NETWORK_INI.eth
|
||||
net4=$(link IPADDR:0)
|
||||
net6=$(link IPADDR6:0)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) && $USE_NETBIOS == no ]] && ipv6=yes bind+=($net6)
|
||||
if [[ $(link TYPE) == trunk ]]; then
|
||||
# vlan interface
|
||||
for vlan in $(grep -Po '^VLANID:\K\d+' $NETWORK_INI.eth); do
|
||||
net4=$(link IPADDR:$vlan)
|
||||
net6=$(link IPADDR6:$vlan)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) && $USE_NETBIOS == no ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# add active WG tunnels
|
||||
for wg in $(wg show interfaces); do
|
||||
net4=$(show -4 dev $wg)
|
||||
net6=$(show -6 dev $wg)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) && $USE_NETBIOS == no ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
# add loopback interface
|
||||
[[ $ipv4 == yes ]] && bind+=(127.0.0.1)
|
||||
[[ $ipv6 == yes && $USE_NETBIOS == no ]] && bind+=(::1)
|
||||
# add user defined interfaces
|
||||
[[ -f $EXTRA ]] && extra
|
||||
# convert array to string
|
||||
bind=${bind[@]}
|
||||
reply=0
|
||||
# remove temporary file
|
||||
rm -f $NETWORK_INI.eth
|
||||
fi
|
||||
return $reply
|
||||
}
|
||||
# read Unraid settings
|
||||
[[ -r $IDENT ]] && . <(/usr/bin/fromdos <$IDENT)
|
||||
# disable ipv6 when netbios is used
|
||||
[[ $USE_NETBIOS == yes ]] && deny6=1
|
||||
|
||||
samba_settings() {
|
||||
# read Unraid settings
|
||||
if [[ -e $BOOT/ident.cfg ]]; then
|
||||
source <(/usr/bin/fromdos < $BOOT/ident.cfg)
|
||||
fi
|
||||
[[ -z $COMMENT ]] && COMMENT=""
|
||||
[[ -z $SECURITY ]] && SECURITY="user"
|
||||
[[ -z $WORKGROUP ]] && WORKGROUP="WORKGROUP"
|
||||
@@ -161,7 +45,6 @@ samba_settings() {
|
||||
echo "hide dot files = $hideDotFiles" >>$CONF
|
||||
echo "server multi channel support = $serverMultiChannel" >>$CONF
|
||||
echo "max open files = $(ulimit -n)" >>$CONF
|
||||
|
||||
# fixme: samba can now auto-register with avahi but conflicts with emhttp, so disable for now
|
||||
echo "multicast dns register = No" >>$CONF
|
||||
|
||||
@@ -178,7 +61,6 @@ samba_settings() {
|
||||
echo "disable netbios = yes" >>$CONF
|
||||
echo "server min protocol = SMB2" >>$CONF
|
||||
fi
|
||||
|
||||
if [[ $SECURITY == ads ]]; then
|
||||
echo "security = ADS" >>$CONF
|
||||
if [[ -z $DOMAIN_SHORT ]]; then
|
||||
@@ -210,7 +92,6 @@ samba_settings() {
|
||||
echo "create mask = 0777" >>$CONF
|
||||
echo "directory mask = 0777" >>$CONF
|
||||
fi
|
||||
|
||||
# bind samba service
|
||||
if check; then
|
||||
if [[ -n $bind ]]; then
|
||||
@@ -229,7 +110,7 @@ samba_start() {
|
||||
|
||||
# restore previously stored samba 'secrets' file (for better AD integration)
|
||||
if [[ -e $BOOT/secrets.tdb ]]; then
|
||||
mv $BOOT/secrets.tdb $PRIVATE
|
||||
cp -f $BOOT/secrets.tdb $PRIVATE
|
||||
fi
|
||||
|
||||
# create settings
|
||||
@@ -254,7 +135,7 @@ samba_stop() {
|
||||
killall smbd nmbd wsdd2 winbindd >/dev/null 2>&1
|
||||
# save samba 'secrets' file
|
||||
if [[ -e $PRIVATE/secrets.tdb ]]; then
|
||||
cp $PRIVATE/secrets.tdb $BOOT
|
||||
cp -f $PRIVATE/secrets.tdb $BOOT
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -265,12 +146,14 @@ samba_restart() {
|
||||
}
|
||||
|
||||
samba_reload() {
|
||||
killall smbd nmbd wsdd2 winbindd >/dev/null 2>&1
|
||||
# update settings
|
||||
samba_settings
|
||||
# restart services
|
||||
/usr/bin/smbcontrol smbd reload-config
|
||||
[[ $USE_NETBIOS == yes ]] && /usr/bin/smbcontrol nmbd reload-config
|
||||
/usr/bin/smbcontrol winbindd reload-config
|
||||
$SMBD -D 2>/dev/null
|
||||
[[ $USE_NETBIOS == yes ]] && $NMBD -D 2>/dev/null
|
||||
[[ $USE_WSD == yes ]] && $WSDD2 -d ${WSD2_OPT## } 2>/dev/null
|
||||
$WINBINDD -D 2>/dev/null
|
||||
}
|
||||
|
||||
samba_update() {
|
||||
|
||||
133
etc/rc.d/rc.sshd
133
etc/rc.d/rc.sshd
@@ -2,132 +2,15 @@
|
||||
# Start/stop/restart the secure shell server:
|
||||
# bergware - added interface bind functionality
|
||||
|
||||
CALLER="ssh"
|
||||
SSHD="/usr/sbin/sshd"
|
||||
CONF="/etc/ssh/sshd_config"
|
||||
PID="/var/run/sshd.pid"
|
||||
SSH_BOOT="/boot/config/ssh"
|
||||
SSH_ETC="/etc/ssh"
|
||||
WIREGUARD="/etc/wireguard"
|
||||
NETWORK_INI="/var/local/emhttp/network.ini"
|
||||
SYSTEM="/sys/class/net"
|
||||
EXTRA="/boot/config/network-extra.cfg"
|
||||
|
||||
IPv() {
|
||||
type=${1//[^:]}
|
||||
[[ ${#type} -le ${2:-0} ]] && echo 4 || echo 6
|
||||
}
|
||||
|
||||
scan() {
|
||||
grep -Pom1 "^$1=\"?\K[^\"]+" $2
|
||||
}
|
||||
|
||||
link() {
|
||||
grep -Pom1 "^$1=\"\K[^\"]+" $NETWORK_INI.eth
|
||||
}
|
||||
|
||||
this() {
|
||||
grep -Po "^$1 \K.*" $CONF|tr '\n' ' '|sed 's/ $//'
|
||||
}
|
||||
|
||||
take() {
|
||||
data=;
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 || ${1:0:7} == 169.254 || ${1:0:4} == fe80 ]] && data=$1
|
||||
done
|
||||
echo $data
|
||||
}
|
||||
|
||||
good() {
|
||||
[[ -n $1 && ${1:0:7} != 169.254 && ${1:0:4} != fe80 ]] && echo $1
|
||||
}
|
||||
|
||||
show() {
|
||||
case $# in
|
||||
1) ip addr show to $1 2>/dev/null|grep -Pom1 '^\d+: \K[^:]+';;
|
||||
2) ip addr show $1 $2 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
3) ip $1 addr show $2 $3 2>/dev/null|grep -Pom1 'inet6? \K[^\/]+';;
|
||||
esac
|
||||
}
|
||||
|
||||
remove() {
|
||||
[[ $# -eq 0 ]] && return
|
||||
for i in ${!bind[@]}; do
|
||||
[[ ${bind[$i]} == $1 ]] && unset 'bind[i]'
|
||||
done
|
||||
}
|
||||
|
||||
extra() {
|
||||
source <(/usr/bin/fromdos <$EXTRA)
|
||||
for net in $include_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
net4=$(show -4 dev $net)
|
||||
net6=$(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address, validate
|
||||
net4=$(show -4 to $net)
|
||||
net6=$(show -6 to $net)
|
||||
fi
|
||||
[[ -n $net4 && -z $(take $net4) ]] && bind+=($net4)
|
||||
[[ -n $net6 && -z $(take $net6) ]] && bind+=($net6)
|
||||
done
|
||||
for net in $exclude_interfaces; do
|
||||
if [[ -z ${net//[^.:]} || ${net//[^.:]} == . ]]; then
|
||||
# net is an interface name, get IP addresses
|
||||
remove $(show -4 dev $net)
|
||||
remove $(show -6 dev $net)
|
||||
else
|
||||
# net is an IP address
|
||||
remove $(show to $net)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check() {
|
||||
# quick check
|
||||
[[ -n $bind ]] && return 0;
|
||||
# preset return values
|
||||
reply=1; bind=(); ipv4=no; ipv6=no; family=any;
|
||||
if [[ -f $NETWORK_INI ]]; then
|
||||
# get interface and vlan configurations
|
||||
for eth in $(grep -Po '^\[\K[^\]]+' $NETWORK_INI); do
|
||||
if [[ -e $SYSTEM/$eth ]]; then
|
||||
# main interface
|
||||
sed -n "/^\[$eth\]/,/^\[eth/p" $NETWORK_INI >$NETWORK_INI.eth
|
||||
net4=$(link IPADDR:0)
|
||||
net6=$(link IPADDR6:0)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
if [[ $(link TYPE) == trunk ]]; then
|
||||
# vlan interface
|
||||
for vlan in $(grep -Po '^VLANID:\K\d+' $NETWORK_INI.eth); do
|
||||
net4=$(link IPADDR:$vlan)
|
||||
net6=$(link IPADDR6:$vlan)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# add active WG tunnels
|
||||
for wg in $(wg show interfaces); do
|
||||
net4=$(show -4 dev $wg)
|
||||
net6=$(show -6 dev $wg)
|
||||
[[ -n $(good $net4) ]] && ipv4=yes bind+=($net4)
|
||||
[[ -n $(good $net6) ]] && ipv6=yes bind+=($net6)
|
||||
done
|
||||
# add user defined interfaces
|
||||
[[ -f $EXTRA ]] && extra
|
||||
# bind stays array
|
||||
bind=(${bind[@]})
|
||||
[[ $ipv4 == yes && $ipv6 == no ]] && family=inet
|
||||
[[ $ipv6 == yes && $ipv4 == no ]] && family=inet6
|
||||
reply=0
|
||||
# remove temporary file
|
||||
rm -f $NETWORK_INI.eth
|
||||
fi
|
||||
return $reply
|
||||
}
|
||||
# library functions
|
||||
. /etc/rc.d/rc.library.source
|
||||
|
||||
build_ssh() {
|
||||
if check && [[ -n $bind ]]; then
|
||||
@@ -135,7 +18,7 @@ build_ssh() {
|
||||
sed -ri '/^#?(ListenAddress|AddressFamily) /d' $CONF
|
||||
# create new entries (in reverse order)
|
||||
for i in $(seq $((${#bind[@]}-1)) -1 0); do
|
||||
sed -ri "/^#?Port /a ListenAddress ${bind[$i]}" $CONF
|
||||
sed -ri "/^#?Port /a ListenAddress ${bind[$i]} # $(show ${bind[$i]})" $CONF
|
||||
done
|
||||
sed -ri "/^#?Port /a AddressFamily $family" $CONF
|
||||
fi
|
||||
@@ -144,18 +27,14 @@ build_ssh() {
|
||||
sshd_start() {
|
||||
# make sure ssh dir exists on flash
|
||||
mkdir -p $SSH_BOOT
|
||||
|
||||
# restore saved keys, config file, etc. (but not subdirs)
|
||||
cp $SSH_BOOT/* $SSH_ETC &>/dev/null
|
||||
chmod 600 $SSH_ETC/* &>/dev/null
|
||||
|
||||
# create host keys if needed and copy any newly generated key(s) back to flash
|
||||
ssh-keygen -A
|
||||
cp -n $SSH_ETC/ssh_host*_key* $SSH_BOOT/
|
||||
|
||||
# bind ssh service
|
||||
# build configuration
|
||||
build_ssh
|
||||
|
||||
# start daemon
|
||||
$SSHD 2>/dev/null
|
||||
}
|
||||
@@ -193,7 +72,7 @@ sshd_reload() {
|
||||
|
||||
sshd_update() {
|
||||
[[ $(pgrep -cf $SSHD) -eq 0 ]] && exit 1 # not running
|
||||
if check && [[ "$(this ListenAddress)" == "${bind[@]}" && $(this AddressFamily) == $family ]]; then
|
||||
if check && [[ "$(this ListenAddress)" == "${bind[@]}" ]]; then
|
||||
# no action required
|
||||
exit 1
|
||||
else
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
#
|
||||
# create initial network.ini file on system start
|
||||
# create system welcome message
|
||||
# update files on DHCP events 'BOUND[6] IPV4LL ROUTERADVERT'
|
||||
# update files on DHCP events 'BOUND[6] IPV4LL'
|
||||
# update services listening interfaces / addresses
|
||||
|
||||
[[ (-z $reason && -z $1) || (-n $reason && ! "BOUND6 IPV4LL ROUTERADVERT" =~ $reason) ]] && exit 0
|
||||
[[ (-z $reason && -z $1) || (-n $reason && ! "BOUND6 IPV4LL" =~ $reason) ]] && exit 0
|
||||
|
||||
ini=/var/local/emhttp/network.ini.new
|
||||
cfg=/boot/config/network.cfg
|
||||
reload=/usr/local/emhttp/webGui/scripts/reload_services
|
||||
|
||||
declare -A VLANID USE_DHCP IPADDR NETMASK GATEWAY METRIC USE_DHCP6 IPADDR6 NETMASK6 GATEWAY6 PRIVACY6 METRIC6 DESCRIPTION PROTOCOL
|
||||
|
||||
@@ -44,13 +43,6 @@ fi
|
||||
echo -n >$ini
|
||||
# clear update information
|
||||
data=
|
||||
dhcp=
|
||||
# get interface name
|
||||
if [[ -n $1 ]]; then
|
||||
tag=$1
|
||||
else
|
||||
tag=$interface
|
||||
fi
|
||||
|
||||
# loop thru all defined interfaces (=1 in case of legacy)
|
||||
for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
@@ -123,10 +115,9 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
echo "DESCRIPTION:0=\"${DESCRIPTION[$i]}\"" >>$ini
|
||||
echo "PROTOCOL:0=\"${PROTOCOL[$i]}\"" >>$ini
|
||||
echo "USE_DHCP:0=\"${USE_DHCP[$i]}\"" >>$ini
|
||||
flag=
|
||||
if [[ ${USE_DHCP[$i]} == yes ]]; then
|
||||
# get dhcp assigned ipv4 address & mask
|
||||
NET=($(ip -4 addr show $IFACE|awk '/inet /{sub("/"," ",$2);print $2;exit}'))
|
||||
NET=($(ip -br -4 addr show $IFACE|awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW=$(ip -4 route show default dev $IFACE|awk '{print $3;exit}')
|
||||
echo "IPADDR:0=\"${NET[0]}\"" >>$ini
|
||||
echo "NETMASK:0=\"$(mask ${NET[1]})\"" >>$ini
|
||||
@@ -140,7 +131,6 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
((x++))
|
||||
done
|
||||
fi
|
||||
[[ "${PROTOCOL[$i]}" == *"ipv4"* ]] && flag=1
|
||||
else
|
||||
# get static assigned ipv4 address & mask
|
||||
echo "IPADDR:0=\"${IPADDR[$i]}\"" >>$ini
|
||||
@@ -151,7 +141,7 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
echo "USE_DHCP6:0=\"${USE_DHCP6[$i]}\"" >>$ini
|
||||
if [[ ${USE_DHCP6[$i]} == yes ]]; then
|
||||
# get auto assigned ipv6 address & prefix
|
||||
NET6=($(ip -6 addr show $IFACE noprefixroute|awk '/inet6 /{sub("/"," ",$2);print $2;exit}'))
|
||||
NET6=($(ip -br -6 addr show $IFACE scope global|awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW6=$(ip -6 route show default dev $IFACE|awk '{print $3;exit}')
|
||||
echo "IPADDR6:0=\"${NET6[0]}\"" >>$ini
|
||||
echo "NETMASK6:0=\"${NET6[1]}\"" >>$ini
|
||||
@@ -166,7 +156,6 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
((x++))
|
||||
done
|
||||
fi
|
||||
[[ "${PROTOCOL[$i]}" == *"ipv6"* ]] && flag=1
|
||||
else
|
||||
# get static assigned ipv6 address & prefix
|
||||
echo "IPADDR6:0=\"${IPADDR6[$i]}\"" >>$ini
|
||||
@@ -175,7 +164,6 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
echo "METRIC6:0=\"${METRIC6[$i]}\"" >>$ini
|
||||
echo "PRIVACY6:0=\"\"" >>$ini
|
||||
fi
|
||||
[[ -n $flag && ($tag == $IFACE || $tag == init) ]] && dhcp=1
|
||||
echo "MTU=\"${MTU[$i]}\"" >>$ini
|
||||
if [[ -n ${VLANS[$i]} ]]; then
|
||||
# process VLAN interfaces
|
||||
@@ -185,18 +173,16 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
echo "DESCRIPTION:$j=\"${DESCRIPTION[$i,$j]}\"" >>$ini
|
||||
echo "PROTOCOL:$j=\"${PROTOCOL[$i,$j]}\"" >>$ini
|
||||
echo "USE_DHCP:$j=\"${USE_DHCP[$i,$j]}\"" >>$ini
|
||||
flag=
|
||||
if [[ ${USE_DHCP[$i,$j]} == yes ]]; then
|
||||
DEV=$IFACE.${VLANID[$i,$j]}
|
||||
# get dhcp assigned ipv4 address & mask
|
||||
NET=($(ip -4 addr show $DEV|awk '/inet /{sub("/"," ",$2);print $2;exit}'))
|
||||
NET=($(ip -br -4 addr show $DEV|awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW=$(ip -4 route show default dev $DEV|awk '{print $3;exit}')
|
||||
echo "IPADDR:$j=\"${NET[0]}\"" >>$ini
|
||||
echo "NETMASK:$j=\"$(mask ${NET[1]})\"" >>$ini
|
||||
echo "GATEWAY:$j=\"$GW\"" >>$ini
|
||||
echo "METRIC:$j=\"${METRIC[$i,$j]}\"" >>$ini
|
||||
data="${data}${ETH}_I_IPADDR:$j=${NET[0]} ${ETH}_S_NETMASK:$j=$(mask ${NET[1]}) ${ETH}_I_GATEWAY:$j=$GW "
|
||||
[[ "${PROTOCOL[$i,$j]}" == *"ipv4"* ]] && flag=1
|
||||
else
|
||||
# get static assigned ipv4 address & mask
|
||||
echo "IPADDR:$j=\"${IPADDR[$i,$j]}\"" >>$ini
|
||||
@@ -208,7 +194,7 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
if [[ ${USE_DHCP6[$i,$j]} == yes ]]; then
|
||||
DEV=$IFACE.${VLANID[$i,$j]}
|
||||
# get auto assigned ipv6 address & prefix
|
||||
NET6=($(ip -6 addr show $DEV noprefixroute|awk '/inet6 /{sub("/"," ",$2);print $2;exit}'))
|
||||
NET6=($(ip -br -6 addr show $DEV scope global|awk '{sub("/"," ",$3);print $3;exit}'))
|
||||
GW6=$(ip -6 route show default dev $DEV|awk '{print $3;exit}')
|
||||
echo "IPADDR6:$j=\"${NET6[0]}\"" >>$ini
|
||||
echo "NETMASK6:$j=\"${NET6[1]}\"" >>$ini
|
||||
@@ -216,7 +202,6 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
echo "METRIC6:$j=\"${METRIC6[$i,$j]}\"" >>$ini
|
||||
echo "PRIVACY6:$j=\"${PRIVACY6[$i,$j]}\"" >>$ini
|
||||
data="${data}${ETH}_I_IPADDR6:$j=${NET6[0]} ${ETH}_I_NETMASK6:$j=${NET6[1]} ${ETH}_I_GATEWAY6:$j=$GW6 "
|
||||
[[ "${PROTOCOL[$i,$j]}" == *"ipv6"* ]] && flag=1
|
||||
else
|
||||
# get static assigned ipv6 address & prefix
|
||||
echo "IPADDR6:$j=\"${IPADDR6[$i,$j]}\"" >>$ini
|
||||
@@ -225,7 +210,6 @@ for ((i=0;i<${SYSNICS:-1};i++)); do
|
||||
echo "METRIC6:$j=\"${METRIC6[$i,$j]}\"" >>$ini
|
||||
echo "PRIVACY6:$j=\"\"" >>$ini
|
||||
fi
|
||||
[[ -n $flag && ($tag == $IFACE || $tag == init) ]] && dhcp=1
|
||||
done
|
||||
else
|
||||
# interface without VLANs
|
||||
@@ -235,29 +219,26 @@ done
|
||||
# atomically update file
|
||||
/usr/bin/mv $ini ${ini%.*}
|
||||
|
||||
# the following section is executed on static only or on dhcp hook
|
||||
if [[ (-n $1 && -z $dhcp) || (-z $1 && -n $dhcp) ]]; then
|
||||
$reload >/dev/null 2>&1 &
|
||||
fi
|
||||
logger -t network "hook services: interface=${interface:-$1}, reason=$reason, protocol=$protocol"
|
||||
# delayed execution
|
||||
/usr/local/emhttp/webGui/scripts/update_services 30
|
||||
|
||||
# send update information
|
||||
if [[ -n $interface && -n $data && -e /var/run/nginx.socket ]]; then
|
||||
curl -sfd "$data" --unix-socket /var/run/nginx.socket http://localhost/pub/dhcp?buffer_length=0 >/dev/null 2>&1
|
||||
if [[ -n $data && -e /var/run/nginx.socket ]]; then
|
||||
curl -sfd "$data" --unix-socket /var/run/nginx.socket http://localhost/pub/dhcp?buffer_length=1 >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# generate our welcome text (management interface only)
|
||||
if [[ -z $interface || "eth0 br0 bond0" =~ $interface ]]; then
|
||||
source /etc/unraid-version
|
||||
. /etc/unraid-version
|
||||
echo -e "unRAID Server OS version: $version" >/etc/issue
|
||||
# find management interface
|
||||
ETH=eth0
|
||||
[[ -e /sys/class/net/bond0 ]] && ETH=bond0
|
||||
[[ -e /sys/class/net/br0 ]] && ETH=br0
|
||||
IPv4=$(ip -4 addr show $ETH|awk '/inet /{print $2;exit}')
|
||||
IPv6=$(ip -6 addr show $ETH noprefixroute|awk '/inet6 /{print $2;exit}')
|
||||
[[ -z $IPv6 ]] && IPv6=$(ip -6 addr show $ETH scope global permanent|awk '/inet6 /{print $2;exit}')
|
||||
[[ -n $IPv4 ]] && echo " IPv4 address: ${IPv4%%/*}">>/etc/issue || echo " IPv4 address: not set">>/etc/issue
|
||||
[[ -n $IPv6 ]] && echo " IPv6 address: ${IPv6%%/*}">>/etc/issue || echo " IPv6 address: not set">>/etc/issue
|
||||
[[ -e /sys/class/net/bond0 ]] && dev=bond0 || dev=eth0
|
||||
[[ -e /sys/class/net/br0 ]] && dev=br0
|
||||
IPv4=$(ip -br -4 addr show $dev scope global|awk '{print $3}')
|
||||
IPv6=$(ip -br -6 addr show $dev scope global|awk '{print $3}')
|
||||
[[ -n $IPv4 ]] && echo " IPv4 address: ${IPv4%/*}">>/etc/issue || echo " IPv4 address: not set">>/etc/issue
|
||||
[[ -n $IPv6 ]] && echo " IPv6 address: ${IPv6%/*}">>/etc/issue || echo " IPv6 address: not set">>/etc/issue
|
||||
echo >>/etc/issue
|
||||
fi
|
||||
exit 0
|
||||
|
||||
@@ -15,7 +15,8 @@ while :; do
|
||||
# steady state?
|
||||
subs=$(curl --unix-socket $nginx $status 2>/dev/null|grep -Pom1 'subscribers: \K\d+')
|
||||
if [[ -z $subs || $subs -eq 0 ]]; then
|
||||
# kill GUI registered nchan processes
|
||||
logger -t monitor "Stop running nchan processes"
|
||||
# kill GUI registered nchan processes
|
||||
while IFS=$'\n' read -r running; do
|
||||
pkill -f $docroot/${running/:stop/}
|
||||
done < $nchan_pid
|
||||
@@ -27,3 +28,4 @@ while :; do
|
||||
# check every 30 seconds
|
||||
sleep 30
|
||||
done &
|
||||
disown %%
|
||||
|
||||
Reference in New Issue
Block a user